You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@dtumad This issue records a design tension exposed while reviewing the new dynamical-system stack and proposes a canonical separation between stateful realizations, state-free behavior, finite programs, and interaction trees.
This is deliberately a design issue rather than an implementation PR: the central proposal seems strong, but the names, universe-polymorphic surface, and exact migration boundaries should be reviewed before cutting over downstream users.
PFunctor.FreeM is the upstream cslib inductive free monad, with PolyFun retaining its polynomial-specific maps, handlers, paths, displayed families, and roll bounds.
PFunctor.DynSystem S p is definitionally Lens (selfMonomial S) p, equivalently the coalgebra S → p.Obj S.
DynSystem.behavior : S → PFunctor.M p gives the unique terminal-coalgebra behavior tree.
ITree p β is the M-type with Ret, Tau, and Vis nodes.
DynSystem.toITree currently embeds a non-returning dynamical system as an all-query ITree p PEmpty.
PointedMachine p α β still stores State, expose, update, init, and a separate output : State → Option β.
structurePointedMachine (p : PFunctor) (α β : Type) where
State : Type
expose : State → p.A
update : (s : State) → p.B (expose s) → State
init : α → State
output : State → Option β
Operationally, a state with output s = some b has returned and the runner stops. Structurally, however, that state must still expose a p-position and provide updates for all its directions.
This causes several concrete problems.
1. Returned states contain unreachable interface data
An already-returned computation still needs expose and update. The clearest symptom is:
PointedMachine.pureAt :
Point p → (α → β) → PointedMachine p α β
A pure computation needs an arbitrary Point p solely to populate an interface position that execution will never inspect. If p.A is empty, the current representation cannot express a pure returned machine at all.
2. Termination lives outside the dynamical interface
The dynamical system is over p, while termination is a second observation interpreted specially by toComp and runWith. In the polynomial account, a terminal result should instead be an interface position with no directions.
Niu–Spivak’s halting automata use exactly this construction: active positions have the ordinary input directions, while a halting position has no directions. See §4.2, especially Example 4.21, of Polynomial Functors: A Mathematical Theory of Interaction.
3. The current representation contains terminal junk
There is a canonical lossy normalization:
current PointedMachine
→ initialized DynSystem State (C β + p)
by sending:
output s = some b ↦ return b
output s = none ↦ query (expose s) (update s)
This discards expose and update at returned states, because they are observationally irrelevant.
The reverse direction is not canonical: to reconstruct the old structure at a returned state, one must fabricate a p-position and update map. This is precisely the arbitrary Point p required by pureAt.
Thus the proposed representation is not merely a cosmetic rearrangement. It quotients away data that the current operational semantics already treats as unreachable.
4. We have finite approximants but no canonical returning behavior
PointedMachine.toComp k : State → FreeM p (Option β) is a useful depth-k approximation:
some b is a real result;
none marks an unresolved cutoff;
ResolvesIn k says the cutoff contains no none leaves;
fuel counts visible p-queries exactly.
What is missing is the coinductive object being approximated: the possibly infinite tree that either returns a β or makes a p-query and continues.
5. Semantic correctness and bounds are currently coupled
Implements M z k :=
∀ x, M.toComp k (M.init x) = some <$> z x
This is a good bounded operational theorem, but it simultaneously states:
behavioral correctness with respect to z;
resolution/termination;
a uniform natural-number query bound.
Once canonical coinductive behavior exists, these can be stated and composed separately.
6. “Pointed” describes only part of the data
Coalgebraically, “pointed” normally means one distinguished state 1 → State. Here init : α → State is an α-indexed family of entry states, and the terminal β-result is at least as important as initialization. The term has legitimate ancestry, but it does not expose the true computational boundary.
Proposed canonical layout
The key polynomial is:
C β + p
Its extension is, up to the evident equivalence:
(C β + p).Obj X ≃ β ⊕ p.Obj X
A node therefore either returns a β with no children, or exposes a p-query whose directions select continuation states.
The order C β + p is chosen to match the standard equation β + F X; p + C β is equivalent by the coproduct symmetry.
An element is a possibly infinite, tau-free interaction tree:
return b
query a (fun d => continuation d)
Every infinite branch performs infinitely many visible p-interactions. Silent divergence is intentionally absent.
This should be an abbreviation over the canonical M-type, not a parallel structure duplicating it.
Stateful realization: DynComputation
Schematic definition:
structurePFunctor.DynComputation
(p : PFunctor) (α : Type) (β : Type) where
State : Type
toDynSystem : DynSystem State (PFunctor.C β + p)
init : α → State
This is a hidden-state realization of an α-indexed family of returning computations. Computational accessors should expose the coalgebraic view ergonomically, e.g.:
DynComputation.view :
M.State → β ⊕ p.Obj M.State
The canonical state-free semantics is:
DynComputation.denote :
DynComputation p α β → α → Resumption p β
M.denote x := M.toDynSystem.behavior (M.init x)
Different state spaces may realize the same behavior. Raw DynComputation structures are therefore intensional presentations; equality of denotations is the canonical observational equivalence.
Conversely, any f : α → Resumption p β has the canonical realization whose states are residual resumptions, whose initialization is f, and whose transition is M.dest. Thus, morally:
DynComputation p α β / behavioral equivalence
≃
α → Resumption p β
Finite state-free programs: FreeM
FreeM p β = μ X. β ⊕ p.Obj X
This is the initial-algebra/well-founded counterpart of Resumption:
FreeM p β finite/well-founded p-trees with β-leaves
Resumption p β possibly infinite p-trees with β-leaves
There should be a canonical embedding:
FreeM.toResumption :
FreeM p β → Resumption p β
with the expected equations and laws:
toResumption (pure b) = Resumption.pure b
toResumption (liftBind a k) =
Resumption.query a (fun d => toResumption (k d))
toResumption (x >>= f) =
toResumption x >>= fun b => toResumption (f b)
It should be injective: a well-founded tree does not lose information when regarded as a possibly infinite tree.
Interaction trees
Up to a polynomial equivalence, the current ITree definition is:
ITree p β = ν X. β ⊕ X ⊕ p.Obj X
corresponding to:
Ret β | Tau X | Vis (p.Obj X)
By contrast:
Resumption p β = ν X. β ⊕ p.Obj X
Therefore Resumption p β is the tau-free fragment of ITree p β.
Required bridge:
Resumption.toITree :
Resumption p β → ITree p β
preserving pure, query, map, and bind.
A later precise characterization should be:
Resumption p β ≃ {t : ITree p β // t.TauFree}
where TauFree is formulated in the coinductively appropriate way.
There cannot be a total constructive inverse ITree p β → Resumption p β: erasing tau would need to decide whether an unbounded silent prefix eventually reaches Ret/Vis or diverges silently.
This is the semantic role of Tau, not just a representation detail. The current DynComputation proposal remains tau-free because its state advances only through visible p-directions, matching the current PointedMachine model.
The complete object matrix
FreeM p β
= μ X. β ⊕ p.Obj X
finite/well-founded programs
Resumption p β
= ν X. β ⊕ p.Obj X
possibly infinite visible behavior
ITree p β
= ν X. β ⊕ X ⊕ p.Obj X
visible behavior plus silent steps/divergence
DynComputation p α β
= State + init + a coalgebra State → β ⊕ p.Obj State
an intensional state-space realization of α → Resumption p β
Stateful presentations of FreeM
The stateful counterpart of FreeM should not initially be another foundational structure. It is a DynComputation together with well-foundedness.
A qualitative predicate should express that every query continuation eventually returns:
DynComputation.toFreeMFrom :
M.TerminatesFrom st → FreeM p β
DynComputation.toFreeM :
(∀ x, M.TerminatesFrom (M.init x)) → α → FreeM p β
This is more general than ResolvesIn k. With infinitely many possible query answers, every branch may be finite while their depths are not uniformly bounded by any k : ℕ.
The intended hierarchy is:
TerminatesFrom
qualitative well-foundedness
ResolvesIn k
uniform visible-query bound
ImplementsWithin k
semantic agreement plus a uniform bound
A bundled WellFoundedDynComputation should be added only if real consumers repeatedly need to pass the computation and proof together.
No new with-tau FreeM by default
The inductive type
μ X. β ⊕ X ⊕ p.Obj X
can already be represented by something equivalent to FreeM (X + p) β. Because it is inductive, every branch contains only finitely many tau nodes, and they can be erased structurally. Finite tau adds no denotational expressivity.
If internal steps must be counted or observed, they should be an explicit event such as Tick, Yield, or InternalStep, not a semantically invisible tau.
Tau becomes essential in the coinductive setting, where it supports guarded internal recursion and silent divergence. We should therefore keep:
FreeM tau-free;
Resumption tau-free;
full ITree with tau;
no tau-aware stateful computation until an operational-semantics consumer needs it.
Canonical operations and laws
On Resumption
We should expose:
pure / return;
query;
dest / one-step view;
corec;
map;
universe-polymorphic bind;
same-universe Functor/Monad instances where Lean’s classes permit them;
bisimulation/finality principles inherited from PFunctor.M;
transport along an interface lens.
The implementation must preserve the current universe generality. PFunctor.M itself supports independent position/direction universes, while the existing ITree surface currently aligns its universes. The Resumption core should not unnecessarily inherit that restriction; the ITree bridge may state whatever alignment it genuinely requires.
On DynComputation
Migrate or provide:
pure : (α → β) → DynComputation p α β, with no Point p;
contramapInput;
mapResult (preferred over “output” to distinguish terminal results from dynamical positions);
dimap;
interface transport/wrapping;
sequential composition;
finite truncation toComp;
run, runWith, and handler-parametric finite execution;
ResolvesIn;
behavioral equivalence through denote.
Sequential composition
Stateful composition may continue to use:
M₁.State ⊕ M₂.State
as a private two-phase realization. Its defining semantic theorem should be:
denote_seqComp :
(M₁.seqComp M₂).denote x =
M₁.denote x >>= M₂.denote
This makes behavioral associativity and identity laws consequences of the resumption monad, independent of state-sum association.
The existing fuelled sequencing theorems should then be finite-approximation/bound corollaries rather than the primary statement of correctness.
Truncation
toComp k : State → FreeM p (Option β) remains useful. It should be characterized as the depth-k truncation of denote:
a return becomes some b;
each visible query consumes one unit;
an unresolved continuation at the cutoff becomes none.
This should connect:
Resumption behavior
↓ truncate k
FreeM p (Option β)
↓ no-none / ResolvesIn k
FreeM p β
Handlers
A possibly infinite Resumption cannot in general be interpreted into an arbitrary Monad: the target needs suitable iteration/domain structure, or the computation needs a termination proof.
Therefore:
fuelled runWith into any lawful monad remains valid;
a terminating computation can first convert to FreeM, then use the existing universal handler;
genuinely infinite execution requires a complete Elgot/ωCPO/other appropriate semantic target and should not be smuggled into the base Monad API.
Restating “implements”
After this foundation lands, split semantic correctness from quantitative bounds.
Proposed shape:
defDynComputation.Implements
(M : DynComputation p α β)
(z : α → FreeM p β) : Prop :=
∀ x, M.denote x = (z x).toResumption
defDynComputation.ImplementsWithin
(M : DynComputation p α β)
(z : α → FreeM p β)
(k : ℕ) : Prop :=
∀ x, M.toComp k (M.init x) = some <$> z x
We should prove the precise relationship between them, expected to be semantic implementation plus an appropriate total-roll/query bound.
The simulation machinery from #29 should be ported, but its clauses can become more canonical: a machine state and a FreeM residue should have matching return/query one-step shapes and related continuations. Separate output_pure, output_roll, and expose_eq fields are artifacts of the current split representation.
Add Resumption without breaking current code. Define the M-type abbreviation, constructors/destructor, corecursor, map/bind, monad laws, and FreeM.toResumption.
Add the Resumption–ITree bridge. Implement toITree, prove constructor/map/bind compatibility, and document/formalize its tau-free image.
Cut over PointedMachine to DynComputation. Replace the separate output representation by DynSystem State (C β + p); migrate the operational API with no compatibility layer; replace pureAt by interface-polymorphic pure.
Make denote_seqComp the central sequencing theorem. Retain state-sum composition as one realization and derive behavioral laws from resumption bind.
Add qualitative well-foundedness. Define TerminatesFrom, toFreeM, and bridges to ResolvesIn/total roll bounds.
Adapt VCVio. Make OracleMachine a thin specialization over DynComputation; keep concrete handlers, audited definitions, computability, and polynomial-time content downstream.
The additive Resumption and ITree PRs should land before the breaking machine cutover so the new semantic target exists before the old representation is removed.
Questions to settle during implementation
Is DynComputation the best stateful name, or should it live under a DynSystem namespace? The mathematical boundary matters more than the final spelling.
Should the structure store toDynSystem directly, or store a coalgebraic view : State → β ⊕ p.Obj State and derive the lens? The former maximizes reuse; the latter may be more ergonomic for constructors.
What is the best coinductive formulation of ITree.TauFree in Lean, and should the subtype equivalence block the first bridge PR?
Which Resumption operations can remain fully universe-polymorphic, and where do Lean’s Monad classes force aligned universes?
Should semantic correctness be named Implements, Realizes, or Denotes? It should not silently include a resource bound.
Do future Iris-style consumers require silent state transitions? If so, that should be a later explicit tau-aware layer rather than complicating the default cryptographic computation model.
Proposed acceptance criteria
The design is realized when:
pure returning computations no longer require Point p;
terminal states carry no unreachable p-interaction data;
every DynComputation has canonical Resumption semantics;
FreeM embeds into Resumption, which embeds into tau-free ITree;
sequential composition denotes resumption bind;
finite unrolling is proved to be truncation of coinductive behavior;
qualitative termination and quantitative query bounds are distinct;
@dtumad This issue records a design tension exposed while reviewing the new dynamical-system stack and proposes a canonical separation between stateful realizations, state-free behavior, finite programs, and interaction trees.
This is deliberately a design issue rather than an implementation PR: the central proposal seems strong, but the names, universe-polymorphic surface, and exact migration boundaries should be reviewed before cutting over downstream users.
Repository state this issue describes
This issue is anchored to
mainat commitf1a4c4c2e8bbd3308cecc869a20f6ddefaff4e38, the squash merge of #31 (“adopt upstream cslib free monad definitions”), on 2026-07-13.At that commit:
PFunctor.FreeMis the upstream cslib inductive free monad, with PolyFun retaining its polynomial-specific maps, handlers, paths, displayed families, and roll bounds.PFunctor.DynSystem S pis definitionallyLens (selfMonomial S) p, equivalently the coalgebraS → p.Obj S.DynSystem.behavior : S → PFunctor.M pgives the unique terminal-coalgebra behavior tree.ITree p βis the M-type withRet,Tau, andVisnodes.DynSystem.toITreecurrently embeds a non-returning dynamical system as an all-queryITree p PEmpty.PointedMachine p α βstill storesState,expose,update,init, and a separateoutput : State → Option β.PointedMachine.Implementsand its simulation proof method, but is still phrased against the current representation and the pre-refactor(pfunctor): adopt upstream cslib free monad definitions #31 branch tip. Its proof ideas should be preserved and restacked after this design is settled.No existing open issue covers this proposal.
The current tension
The current definition is:
Operationally, a state with
output s = some bhas returned and the runner stops. Structurally, however, that state must still expose ap-position and provide updates for all its directions.This causes several concrete problems.
1. Returned states contain unreachable interface data
An already-returned computation still needs
exposeandupdate. The clearest symptom is:A pure computation needs an arbitrary
Point psolely to populate an interface position that execution will never inspect. Ifp.Ais empty, the current representation cannot express a pure returned machine at all.2. Termination lives outside the dynamical interface
The dynamical system is over
p, while termination is a second observation interpreted specially bytoCompandrunWith. In the polynomial account, a terminal result should instead be an interface position with no directions.Niu–Spivak’s halting automata use exactly this construction: active positions have the ordinary input directions, while a halting position has no directions. See §4.2, especially Example 4.21, of Polynomial Functors: A Mathematical Theory of Interaction.
3. The current representation contains terminal junk
There is a canonical lossy normalization:
current PointedMachine → initialized DynSystem State (C β + p)by sending:
This discards
exposeandupdateat returned states, because they are observationally irrelevant.The reverse direction is not canonical: to reconstruct the old structure at a returned state, one must fabricate a
p-position and update map. This is precisely the arbitraryPoint prequired bypureAt.Thus the proposed representation is not merely a cosmetic rearrangement. It quotients away data that the current operational semantics already treats as unreachable.
4. We have finite approximants but no canonical returning behavior
PointedMachine.toComp k : State → FreeM p (Option β)is a useful depth-kapproximation:some bis a real result;nonemarks an unresolved cutoff;ResolvesIn ksays the cutoff contains nononeleaves;p-queries exactly.What is missing is the coinductive object being approximated: the possibly infinite tree that either returns a
βor makes ap-query and continues.5. Semantic correctness and bounds are currently coupled
#29 proposes:
This is a good bounded operational theorem, but it simultaneously states:
z;Once canonical coinductive behavior exists, these can be stated and composed separately.
6. “Pointed” describes only part of the data
Coalgebraically, “pointed” normally means one distinguished state
1 → State. Hereinit : α → Stateis anα-indexed family of entry states, and the terminalβ-result is at least as important as initialization. The term has legitimate ancestry, but it does not expose the true computational boundary.Proposed canonical layout
The key polynomial is:
Its extension is, up to the evident equivalence:
A node therefore either returns a
βwith no children, or exposes ap-query whose directions select continuation states.The order
C β + pis chosen to match the standard equationβ + F X;p + C βis equivalent by the coproduct symmetry.State-free behavior:
Resumptionabbrev PFunctor.Resumption (p : PFunctor) (β : Type) := PFunctor.M (PFunctor.C β + p)Mathematically:
An element is a possibly infinite, tau-free interaction tree:
Every infinite branch performs infinitely many visible
p-interactions. Silent divergence is intentionally absent.This should be an abbreviation over the canonical M-type, not a parallel structure duplicating it.
Stateful realization:
DynComputationSchematic definition:
This is a hidden-state realization of an
α-indexed family of returning computations. Computational accessors should expose the coalgebraic view ergonomically, e.g.:The canonical state-free semantics is:
Different state spaces may realize the same behavior. Raw
DynComputationstructures are therefore intensional presentations; equality of denotations is the canonical observational equivalence.Conversely, any
f : α → Resumption p βhas the canonical realization whose states are residual resumptions, whose initialization isf, and whose transition isM.dest. Thus, morally:Finite state-free programs:
FreeMThis is the initial-algebra/well-founded counterpart of
Resumption:There should be a canonical embedding:
with the expected equations and laws:
It should be injective: a well-founded tree does not lose information when regarded as a possibly infinite tree.
Interaction trees
Up to a polynomial equivalence, the current ITree definition is:
corresponding to:
By contrast:
Therefore
Resumption p βis the tau-free fragment ofITree p β.Required bridge:
preserving
pure,query,map, andbind.A later precise characterization should be:
Resumption p β ≃ {t : ITree p β // t.TauFree}where
TauFreeis formulated in the coinductively appropriate way.There cannot be a total constructive inverse
ITree p β → Resumption p β: erasing tau would need to decide whether an unbounded silent prefix eventually reachesRet/Visor diverges silently.This is the semantic role of
Tau, not just a representation detail. The currentDynComputationproposal remains tau-free because its state advances only through visiblep-directions, matching the currentPointedMachinemodel.The complete object matrix
Stateful presentations of
FreeMThe stateful counterpart of
FreeMshould not initially be another foundational structure. It is aDynComputationtogether with well-foundedness.A qualitative predicate should express that every query continuation eventually returns:
Recursion on this proof produces:
This is more general than
ResolvesIn k. With infinitely many possible query answers, every branch may be finite while their depths are not uniformly bounded by anyk : ℕ.The intended hierarchy is:
A bundled
WellFoundedDynComputationshould be added only if real consumers repeatedly need to pass the computation and proof together.No new with-tau
FreeMby defaultThe inductive type
can already be represented by something equivalent to
FreeM (X + p) β. Because it is inductive, every branch contains only finitely many tau nodes, and they can be erased structurally. Finite tau adds no denotational expressivity.If internal steps must be counted or observed, they should be an explicit event such as
Tick,Yield, orInternalStep, not a semantically invisible tau.Tau becomes essential in the coinductive setting, where it supports guarded internal recursion and silent divergence. We should therefore keep:
FreeMtau-free;Resumptiontau-free;ITreewith tau;Canonical operations and laws
On
ResumptionWe should expose:
pure/return;query;dest/ one-step view;corec;map;bind;Functor/Monadinstances where Lean’s classes permit them;PFunctor.M;The implementation must preserve the current universe generality.
PFunctor.Mitself supports independent position/direction universes, while the existingITreesurface currently aligns its universes. TheResumptioncore should not unnecessarily inherit that restriction; the ITree bridge may state whatever alignment it genuinely requires.On
DynComputationMigrate or provide:
pure : (α → β) → DynComputation p α β, with noPoint p;contramapInput;mapResult(preferred over “output” to distinguish terminal results from dynamical positions);dimap;toComp;run,runWith, and handler-parametric finite execution;ResolvesIn;denote.Sequential composition
Stateful composition may continue to use:
as a private two-phase realization. Its defining semantic theorem should be:
denote_seqComp : (M₁.seqComp M₂).denote x = M₁.denote x >>= M₂.denoteThis makes behavioral associativity and identity laws consequences of the resumption monad, independent of state-sum association.
The existing fuelled sequencing theorems should then be finite-approximation/bound corollaries rather than the primary statement of correctness.
Truncation
toComp k : State → FreeM p (Option β)remains useful. It should be characterized as the depth-ktruncation ofdenote:some b;none.This should connect:
Handlers
A possibly infinite
Resumptioncannot in general be interpreted into an arbitraryMonad: the target needs suitable iteration/domain structure, or the computation needs a termination proof.Therefore:
runWithinto any lawful monad remains valid;FreeM, then use the existing universal handler;MonadAPI.Restating “implements”
After this foundation lands, split semantic correctness from quantitative bounds.
Proposed shape:
We should prove the precise relationship between them, expected to be semantic implementation plus an appropriate total-roll/query bound.
The simulation machinery from #29 should be ported, but its clauses can become more canonical: a machine state and a
FreeMresidue should have matching return/query one-step shapes and related continuations. Separateoutput_pure,output_roll, andexpose_eqfields are artifacts of the current split representation.Proposed migration sequence
f1a4c4cas the foundation; all new work uses upstream cslibFreeM.Resumptionwithout breaking current code. Define the M-type abbreviation, constructors/destructor, corecursor, map/bind, monad laws, andFreeM.toResumption.toITree, prove constructor/map/bind compatibility, and document/formalize its tau-free image.PointedMachinetoDynComputation. Replace the separateoutputrepresentation byDynSystem State (C β + p); migrate the operational API with no compatibility layer; replacepureAtby interface-polymorphicpure.denote_seqCompthe central sequencing theorem. Retain state-sum composition as one realization and derive behavioral laws from resumption bind.ImplementsfromImplementsWithinand state correctness throughdenote.TerminatesFrom,toFreeM, and bridges toResolvesIn/total roll bounds.OracleMachinea thin specialization overDynComputation; keep concrete handlers, audited definitions, computability, and polynomial-time content downstream.The additive Resumption and ITree PRs should land before the breaking machine cutover so the new semantic target exists before the old representation is removed.
Questions to settle during implementation
DynComputationthe best stateful name, or should it live under aDynSystemnamespace? The mathematical boundary matters more than the final spelling.toDynSystemdirectly, or store a coalgebraicview : State → β ⊕ p.Obj Stateand derive the lens? The former maximizes reuse; the latter may be more ergonomic for constructors.ITree.TauFreein Lean, and should the subtype equivalence block the first bridge PR?Resumptionoperations can remain fully universe-polymorphic, and where do Lean’sMonadclasses force aligned universes?Implements,Realizes, orDenotes? It should not silently include a resource bound.Proposed acceptance criteria
The design is realized when:
Point p;p-interaction data;DynComputationhas canonicalResumptionsemantics;FreeMembeds intoResumption, which embeds into tau-freeITree;Terminology references
Ret/Tau/Viscoinductive computations and weak equivalence up to silent steps.