Scheduler and control ownership for concurrent interaction #
This file adds an explicit control layer on top of the concurrent source syntax.
The key distinction is:
- at an atomic
node, some party controls the payload move itself; - at a parallel
par left right, some party may control the scheduling choice of which currently live side fires next.
So a full frontier event may be controlled by several parties in sequence:
a scheduler may first choose a live branch of par, and then a downstream node
owner may choose the payload move of the selected atomic node.
The purpose of this file is to represent that control structure directly and definitionally.
Main definitions:
Control Party S— structural control metadata for the concurrent specS;Control.residual— transport control metadata across one scheduled frontier event;Control.isLive— whether a control tree still exposes enabled frontier events;Control.scheduler?— the party who currently has a genuine scheduling choice between two live concurrent components, if any;Control.current?— the party who currently controls the next decision, whether that is a scheduler choice or an atomic payload choice;Control.controllers— the full control path of a concrete frontier event.
This is intentionally a control/ownership layer only. It does not yet prescribe how those parties compute their choices or how local endpoint programs should be assembled from that ownership data.
Control Party S records who controls the next decision at each structural
position of the concurrent spec S.
Constructors mirror the concurrent syntax:
done— there are no further decisions to control;node owner cont— at an atomic node,ownercontrols the move payload, andcont xrecords the residual control tree after choosingx;par scheduler left right— at a parallel node,schedulercontrols the choice between the two concurrently live componentsleftandright.
This is not a local-view or observation object. It records only control.
- done
{Party : Type u}
: Control Party Spec.done
Control tree for a terminated concurrent spec.
- node
{Party Moves : Type u}
{rest : Moves → Spec}
(owner : Party)
(cont : (x : Moves) → Control Party (rest x))
: Control Party (Spec.node Moves rest)
Control tree for an atomic node:
ownercontrols the move payload, and the continuation records residual control after that move. - par
{Party : Type u}
{left right : Spec}
(scheduler : Party)
(leftControl : Control Party left)
(rightControl : Control Party right)
: Control Party (left.par right)
Control tree for a parallel spec:
schedulercontrols the choice of which live side fires next while both sides remain live.
Instances For
residual control event is the control tree remaining after scheduling the
frontier event event.
This mirrors the residual concurrent spec structurally:
- atomic node control follows the chosen payload branch;
- parallel control updates only the side from which the event came.
Instances For
scheduler? control returns the party who currently has a genuine scheduling
choice between two live concurrent components.
This returns:
some schedulerat aparnode exactly when both sides are live;noneotherwise.
So this records frontier scheduling ownership, not payload ownership.
Instances For
current? control returns the party who currently controls the next
decision.
This may be:
- a scheduler at a
parnode when both sides are live; - otherwise, the controlling party of the unique live side;
- or the owner of an atomic node.
So current? collapses scheduler choice and payload choice into the one party
who is currently in control of progress.
Instances For
controllers control event is the full control path of the concrete frontier
event event.
For an atomic node, this is the singleton list containing the node owner. For a parallel node:
- if the opposite side is also live, the scheduler is prepended;
- if the chosen side is the only live side, the scheduler does not appear, because there is no genuine scheduling choice to make.
This distinction matters after residual steps such as .par .done right,
where control should immediately collapse to the right subtree rather than
crediting a vacuous scheduler choice.