Finite graphs for guarded recursive item declarations.
Runtime unfolding retains references and checks every finite value. Analysis uses an upper
approximation, never a proof that a recursive target is satisfied. Cycles without a context
member or list element, and cycles through function signatures, are rejected by validate/2.
Finite function items may accept or return recursive data. Relations between different recursive
descriptors remain conservative; a structural analysis projection is not runtime signature evidence.
Summary
Functions
Whether a type contains a recursive declaration, without unfolding its graph.
Whether two descriptors have identical reachable declaration graphs up to renaming.
Materializes occurrences of a declaration, with their concrete paths from the root. Runtime constraint verification traverses incrementally instead: collecting every forward path can require quadratic space for a deep chain.
Unfolds one graph node, retaining references as finite recursive descriptors.
A structural upper approximation, bounded by repeated references and a shared node budget.
Types
Functions
@spec contains?(Feel.Type.t()) :: boolean()
Whether a type contains a recursive declaration, without unfolding its graph.
Whether two descriptors have identical reachable declaration graphs up to renaming.
Import frames can rename references and include unrelated definitions. Compare the rooted graphs with a consistent one-to-one renaming, retaining constructors, constraints and sharing. This does not prove subtyping between different recursive shapes or unfold aliases away.
@spec parts(Feel.Value.t(), String.t(), String.t(), graph()) :: [ {Feel.Value.t(), list()} ]
Materializes occurrences of a declaration, with their concrete paths from the root. Runtime constraint verification traverses incrementally instead: collecting every forward path can require quadratic space for a deep chain.
@spec unfold(t()) :: Feel.Type.t()
Unfolds one graph node, retaining references as finite recursive descriptors.
@spec upper(Feel.Type.t()) :: Feel.Type.t()
A structural upper approximation, bounded by repeated references and a shared node budget.