ordinary_condition_composition.bend

bendvy-ecs-core@0.1.0.0 · 231 lines · 0 definitions

1import Base
2import bendvy-ecs-core@0.1.0.0/world.bend as W
3import bendvy-ecs-core@0.1.0.0/machine.bend as M
4import bendvy-ecs-core@0.1.0.0/machine_world.bend as MW
5import bendvy-ecs-core@0.1.0.0/ordinary_machine_initialization.bend as Init
6import bendvy-ecs-core@0.1.0.0/ordinary_machine_declaration.bend as OD
7import bendvy-ecs-core@0.1.0.0/ordinary_machine_condition.bend as Changed
8import bendvy-ecs-core@0.1.0.0/system.bend as Sys
9import bendvy-ecs-core@0.1.0.0/schedule.bend as Sch
10import bendvy-ecs-core@0.1.0.0/schedule_provision.bend as SP
11
12# Closed evaluator indices carry no runtime owner captures.
13type LeafDescription is Data:
14  StateChanged{namespace:U32,id:U32,name:String,access:List<&2,String>}
15  InState{name:String}
16  Constant{value:Bool}
17type Description is Data: Description{name:String,access:List<&2,String>,leaves:List<&2,LeafDescription>}
18type Evaluation<World:Type,Owner:Type> is Type:
19  Value{world:World,owner:Owner,value:Bool}
20  NoValue{world:World,owner:Owner}
21  InvalidRegistration{world:World,owner:Owner}
22  NoBinding{world:World,owner:Owner}
23type Condition<World:Type,Owner:Type,-evaluate:Owner -> World -> Evaluation<World,Owner>> is Type:
24  Condition{owner:Owner,description:Description}
25type Returned<World:Type,Owner:Type,-evaluate:Owner -> World -> Evaluation<World,Owner>> is Type:
26  Completed{world:World,condition:Condition<World,Owner,evaluate>,value:Bool}
27  Unavailable{world:World,condition:Condition<World,Owner,evaluate>}
28  RegistrationRejected{world:World,condition:Condition<World,Owner,evaluate>}
29def description(~World:Type,~Owner:Type,~evaluate:Owner -> World -> Evaluation<World,Owner>,condition:Condition<World,Owner,evaluate>) -> Condition<World,Owner,evaluate> & Description:
30  match condition:
31    case Condition{owner,+facts}:(Condition{owner,facts},facts)
32def returned(~World:Type,~Owner:Type,~evaluate:Owner -> World -> Evaluation<World,Owner>,facts:Description,result:Evaluation<World,Owner>) -> Returned<World,Owner,evaluate>:
33  match result:
34    case Value{world,owner,value}:Completed{world,Condition{owner,facts},value}
35    case InvalidRegistration{world,owner}:RegistrationRejected{world,Condition{owner,facts}}
36    case NoValue{world,owner}:Unavailable{world,Condition{owner,facts}}
37    case NoBinding{world,owner}:Unavailable{world,Condition{owner,facts}}
38def run(~World:Type,~Owner:Type,~evaluate:Owner -> World -> Evaluation<World,Owner>,condition:Condition<World,Owner,evaluate>,world:World) -> Returned<World,Owner,evaluate>:
39  match condition:
40    case Condition{owner,facts}:returned(~World,~Owner,~evaluate,facts,evaluate(owner,world))
41def constant_value(~World:Type,world:World,+value:Bool) -> Evaluation<World,Bool>:Value{world,value,value}
42def constant_run(~World:Type,value:Bool,world:World) -> Evaluation<World,Bool>:constant_value(~World,world,value)
43def constant(~World:Type,+value:Bool) -> Condition<World,Bool,constant_run(~World)>:
44  Condition{value,Description{Bool.show(value),[],[Constant{value}]}}
45
46def changed_observed(~S:Data,~K:Data,~V:Data,~R:Type,~take:R -> R & Init.State<S,K,V>,~put:R -> Init.State<S,K,V> -> R,~C:Type,~E:Data,result:Changed.Observed<S,K,V,C,R,E,take,put>) -> Evaluation<W.World<S,C,R,E>,Changed.Instance<S,K,V,C,R,E,take,put>>:
47  match result:
48    case Changed.Observed{world,instance,Some{value}}:Value{world,instance,value}
49    case Changed.Observed{world,instance,None{}}:NoValue{world,instance}
50    case Changed.RegistrationRejected{world,instance}:InvalidRegistration{world,instance}
51def changed_run(~S:Data,~K:Data,~V:Data,~R:Type,~take:R -> R & Init.State<S,K,V>,~put:R -> Init.State<S,K,V> -> R,~C:Type,~E:Data,instance:Changed.Instance<S,K,V,C,R,E,take,put>,world:W.World<S,C,R,E>) -> Evaluation<W.World<S,C,R,E>,Changed.Instance<S,K,V,C,R,E,take,put>>:
52  changed_observed(~S,~K,~V,~R,~take,~put,~C,~E,Changed.run(~S,~K,~V,~R,~take,~put,~C,~E,instance,world))
53# Registration is the existing Changed.define; no second instance is allocated.
54def state_changed(~S:Data,~K:Data,~V:Data,~R:Type,~take:R -> R & Init.State<S,K,V>,~put:R -> Init.State<S,K,V> -> R,~C:Type,~E:Data,instance:Changed.Instance<S,K,V,C,R,E,take,put>) -> Condition<W.World<S,C,R,E>,Changed.Instance<S,K,V,C,R,E,take,put>,changed_run(~S,~K,~V,~R,~take,~put,~C,~E)>:
55  match instance:
56    case Changed.Instance{Sys.Registry{+ns,+id,+name,+access,cursor},revision}:Condition{Changed.Instance{Sys.Registry{ns,id,name,access,cursor},revision},Description{name,access,[StateChanged{ns,id,name,access}]}}
57
58def current_observed(~S:Data,~K:Data,~V:Data,~R:Type,~take:R -> R & M.Slot<S,K,V>,~C:Type,~E:Data,~same:V -> V -> Bool,+wanted:V,observed:W.World<S,C,R,E> & M.Slot<S,K,V>) -> Evaluation<W.World<S,C,R,E>,V>:
59  match observed:
60    case (world,slot):Value{world,wanted,M.current_matches(~S,~K,~V,~same,slot,wanted)}
61def current_run(~S:Data,~K:Data,~V:Data,~R:Type,~take:R -> R & M.Slot<S,K,V>,~C:Type,~E:Data,~same:V -> V -> Bool,wanted:V,world:W.World<S,C,R,E>) -> Evaluation<W.World<S,C,R,E>,V>:
62  current_observed(~S,~K,~V,~R,~take,~C,~E,~same,wanted,MW.take(~S,~K,~V,~C,~R,~E,~take,world))
63def in_state(~S:Data,~K:Data,~V:Data,~R:Type,~take:R -> R & M.Slot<S,K,V>,~C:Type,~E:Data,~same:V -> V -> Bool,~declaration:OD.Declaration<S,K,V,R,take>,wanted:V) -> Condition<W.World<S,C,R,E>,V,current_run(~S,~K,~V,~R,~take,~C,~E,~same)>:
64  Condition{wanted,Description{"in_state(" ++ OD.name(~S,~K,~V,~R,~take,declaration) ++ ")",["machine." ++ OD.name(~S,~K,~V,~R,~take,declaration) ++ ".current"],[InState{OD.name(~S,~K,~V,~R,~take,declaration)}]}}
65
66def negated(~World:Type,~Owner:Type,result:Evaluation<World,Owner>) -> Evaluation<World,Owner>:
67  match result:
68    case Value{world,owner,value}:Value{world,owner,Bool.not(value)}
69    case NoValue{world,owner}:NoValue{world,owner}
70    case InvalidRegistration{world,owner}:InvalidRegistration{world,owner}
71    case NoBinding{world,owner}:NoBinding{world,owner}
72def not_run(~World:Type,~Owner:Type,~evaluate:Owner -> World -> Evaluation<World,Owner>,owner:Owner,world:World) -> Evaluation<World,Owner>:negated(~World,~Owner,evaluate(owner,world))
73def not(~World:Type,~Owner:Type,~evaluate:Owner -> World -> Evaluation<World,Owner>,condition:Condition<World,Owner,evaluate>) -> Condition<World,Owner,not_run(~World,~Owner,~evaluate)>:
74  match condition:
75    case Condition{owner,Description{name,access,leaves}}:Condition{owner,Description{"!(" ++ name ++ ")",access,leaves}}
76def right_returned(~World:Type,~Left:Type,~Right:Type,left:Left,result:Evaluation<World,Right>) -> Evaluation<World,Left & Right>:
77  match result:
78    case Value{world,right,value}:Value{world,(left,right),value}
79    case NoValue{world,right}:NoValue{world,(left,right)}
80    case InvalidRegistration{world,right}:InvalidRegistration{world,(left,right)}
81    case NoBinding{world,right}:NoBinding{world,(left,right)}
82def combined_decision(~World:Type,~Left:Type,~Right:Type,~rightRun:Right -> World -> Evaluation<World,Right>,continue:Bool,left:Left,right:Right,world:World,value:Bool) -> Evaluation<World,Left & Right>:
83  match continue:
84    case False{}:Value{world,(left,right),value}
85    case True{}:right_returned(~World,~Left,~Right,left,rightRun(right,world))
86def same_bool(a:Bool,b:Bool) -> Bool:
87  match a b:
88    case True{} True{}:True{}
89    case False{} False{}:True{}
90    case _ _:False{}
91def combined_left(~World:Type,~Left:Type,~Right:Type,~rightRun:Right -> World -> Evaluation<World,Right>,on:Bool,right:Right,result:Evaluation<World,Left>) -> Evaluation<World,Left & Right>:
92  match result:
93    case Value{world,left,+value}:combined_decision(~World,~Left,~Right,~rightRun,same_bool(value,on),left,right,world,value)
94    case NoValue{world,left}:NoValue{world,(left,right)}
95    case InvalidRegistration{world,left}:InvalidRegistration{world,(left,right)}
96    case NoBinding{world,left}:NoBinding{world,(left,right)}
97def and_run(~World:Type,~Left:Type,~Right:Type,~leftRun:Left -> World -> Evaluation<World,Left>,~rightRun:Right -> World -> Evaluation<World,Right>,owner:Left & Right,world:World) -> Evaluation<World,Left & Right>:
98  match owner:
99    case (left,right):combined_left(~World,~Left,~Right,~rightRun,True{},right,leftRun(left,world))
100def or_run(~World:Type,~Left:Type,~Right:Type,~leftRun:Left -> World -> Evaluation<World,Left>,~rightRun:Right -> World -> Evaluation<World,Right>,owner:Left & Right,world:World) -> Evaluation<World,Left & Right>:
101  match owner:
102    case (left,right):combined_left(~World,~Left,~Right,~rightRun,False{},right,leftRun(left,world))
103def and_then(~World:Type,~Left:Type,~Right:Type,~leftRun:Left -> World -> Evaluation<World,Left>,~rightRun:Right -> World -> Evaluation<World,Right>,left:Condition<World,Left,leftRun>,right:Condition<World,Right,rightRun>) -> Condition<World,Left & Right,and_run(~World,~Left,~Right,~leftRun,~rightRun)>:
104  match left right:
105    case Condition{lo,Description{ln,la,ll}} Condition{ro,Description{rn,ra,rl}}:Condition{(lo,ro),Description{"(" ++ ln ++ " && " ++ rn ++ ")",List.append(&2,String,la,ra),List.append(&2,LeafDescription,ll,rl)}}
106def or_else(~World:Type,~Left:Type,~Right:Type,~leftRun:Left -> World -> Evaluation<World,Left>,~rightRun:Right -> World -> Evaluation<World,Right>,left:Condition<World,Left,leftRun>,right:Condition<World,Right,rightRun>) -> Condition<World,Left & Right,or_run(~World,~Left,~Right,~leftRun,~rightRun)>:
107  match left right:
108    case Condition{lo,Description{ln,la,ll}} Condition{ro,Description{rn,ra,rl}}:Condition{(lo,ro),Description{"(" ++ ln ++ " || " ++ rn ++ ")",List.append(&2,String,la,ra),List.append(&2,LeafDescription,ll,rl)}}
109
110# Bindings are keyed by actual scheduled system ids, not user metadata callbacks.
111type BindingDescription is Data: BindingDescription{systemId:U32,condition:Description}
112type BoundOwner<Owner:Type> is Type: BoundOwner{id:U32,owner:Owner}
113type Bindings<World:Type,Owner:Type,-select:Owner -> World -> U32 -> Evaluation<World,Owner>> is Type:
114  Bindings{owners:Owner,descriptions:List<&2,BindingDescription>}
115def bound_returned(~World:Type,~Owner:Type,id:U32,result:Evaluation<World,Owner>) -> Evaluation<World,BoundOwner<Owner>>:
116  match result:
117    case Value{world,owner,value}:Value{world,BoundOwner{id,owner},value}
118    case NoValue{world,owner}:NoValue{world,BoundOwner{id,owner}}
119    case InvalidRegistration{world,owner}:InvalidRegistration{world,BoundOwner{id,owner}}
120    case NoBinding{world,owner}:NoBinding{world,BoundOwner{id,owner}}
121def bound_selected(~World:Type,~Owner:Type,~evaluate:Owner -> World -> Evaluation<World,Owner>,chosen:Bool,id:U32,owner:Owner,world:World) -> Evaluation<World,BoundOwner<Owner>>:
122  match chosen:
123    case False{}:NoBinding{world,BoundOwner{id,owner}}
124    case True{}:bound_returned(~World,~Owner,id,evaluate(owner,world))
125def bound_run(~World:Type,~Owner:Type,~evaluate:Owner -> World -> Evaluation<World,Owner>,bound:BoundOwner<Owner>,world:World,target:U32) -> Evaluation<World,BoundOwner<Owner>>:
126  match bound:
127    case BoundOwner{+id,owner}:bound_selected(~World,~Owner,~evaluate,U32.is_eq(id,target),id,owner,world)
128def bind(~World:Type,~Owner:Type,~evaluate:Owner -> World -> Evaluation<World,Owner>,+systemId:U32,condition:Condition<World,Owner,evaluate>) -> Bindings<World,BoundOwner<Owner>,bound_run(~World,~Owner,~evaluate)>:
129  match condition:
130    case Condition{owner,facts}:Bindings{BoundOwner{systemId,owner},[BindingDescription{systemId,facts}]}
131def selected_left(~World:Type,~Left:Type,~Right:Type,~rightRun:Right -> World -> U32 -> Evaluation<World,Right>,right:Right,id:U32,result:Evaluation<World,Left>) -> Evaluation<World,Left & Right>:
132  match result:
133    case NoBinding{world,left}:right_returned(~World,~Left,~Right,left,rightRun(right,world,id))
134    case Value{world,left,value}:Value{world,(left,right),value}
135    case NoValue{world,left}:NoValue{world,(left,right)}
136    case InvalidRegistration{world,left}:InvalidRegistration{world,(left,right)}
137def sequence_selected(~World:Type,~Left:Type,~Right:Type,~leftRun:Left -> World -> U32 -> Evaluation<World,Left>,~rightRun:Right -> World -> U32 -> Evaluation<World,Right>,owners:Left & Right,world:World,+id:U32) -> Evaluation<World,Left & Right>:
138  match owners:
139    case (left,right):selected_left(~World,~Left,~Right,~rightRun,right,id,leftRun(left,world,id))
140def sequence_run(~World:Type,~Left:Type,~Right:Type,~leftRun:Left -> World -> U32 -> Evaluation<World,Left>,~rightRun:Right -> World -> U32 -> Evaluation<World,Right>,owners:Left & Right,world:World,id:U32) -> Evaluation<World,Left & Right>:
141  sequence_selected(~World,~Left,~Right,~leftRun,~rightRun,owners,world,id)
142def sequence(~World:Type,~Left:Type,~Right:Type,~leftRun:Left -> World -> U32 -> Evaluation<World,Left>,~rightRun:Right -> World -> U32 -> Evaluation<World,Right>,left:Bindings<World,Left,leftRun>,right:Bindings<World,Right,rightRun>) -> Bindings<World,Left & Right,sequence_run(~World,~Left,~Right,~leftRun,~rightRun)>:
143  match left right:
144    case Bindings{lo,ld} Bindings{ro,rd}:Bindings{(lo,ro),List.append(&2,BindingDescription,ld,rd)}
145def descriptions(~World:Type,~Owner:Type,~select:Owner -> World -> U32 -> Evaluation<World,Owner>,bindings:Bindings<World,Owner,select>) -> Bindings<World,Owner,select> & List<&2,BindingDescription>:
146  match bindings:
147    case Bindings{owner,+facts}:(Bindings{owner,facts},facts)
148def has_binding(facts:List<&2,BindingDescription>,+id:U32) -> Bool:
149  match facts:
150    case []:False{}
151    case BindingDescription{bound,_} <> rest:Bool.or(U32.is_eq(bound,id),has_binding(rest,id))
152def unique_bindings(facts:List<&2,BindingDescription>,+seen:List<&2,U32>) -> Bool:
153  match facts:
154    case []:True{}
155    case BindingDescription{+id,_} <> rest:Bool.and(Bool.not(Sch.contains(seen,id)),unique_bindings(rest,id <> seen))
156def schedule_has(steps:List<&2,Sch.Step>,+id:U32) -> Bool:
157  match steps:
158    case []:False{}
159    case Sch.System{bound,_} <> rest:Bool.or(U32.is_eq(bound,id),schedule_has(rest,id))
160    case _ <> rest:schedule_has(rest,id)
161def binding_targets(facts:List<&2,BindingDescription>,+steps:List<&2,Sch.Step>) -> Bool:
162  match facts:
163    case []:True{}
164    case BindingDescription{id,_} <> rest:Bool.and(schedule_has(steps,id),binding_targets(rest,steps))
165# Step.condition remains the existing opaque declaration slot. Typed guards are
166# attached by system id; an absent binding is unconditional, not a false result.
167type Error<BodyError:Data> is Data:
168  SystemError{error:BodyError}
169  ConditionRegistrationRejected{}
170  ConditionUnavailable{}
171
172type Attachment<S:Data,C:Type,R:Type,E:Data,H:Type,B:Type,-select:B -> W.World<S,C,R,E> -> U32 -> Evaluation<W.World<S,C,R,E>,B>> is Type:
173  Attached{schedule:Sch.Schedule<S,C,R,E,H & Bindings<W.World<S,C,R,E>,B,select>>}
174  AttachmentRejected{schedule:Sch.Schedule<S,C,R,E,H>,bindings:Bindings<W.World<S,C,R,E>,B,select>}
175def attached(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> Evaluation<W.World<S,C,R,E>,B>,allowed:Bool,namespace:U32,name:String,+steps:List<&2,Sch.Step>,owners:H,bindings:Bindings<W.World<S,C,R,E>,B,select>,facts:List<&2,BindingDescription>) -> Attachment<S,C,R,E,H,B,select>:
176  match allowed:
177    case False{}:AttachmentRejected{Sch.Schedule{namespace,name,steps,owners},bindings}
178    case True{}:Attached{Sch.Schedule{namespace,name,steps,(owners,bindings)}}
179def attach(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> Evaluation<W.World<S,C,R,E>,B>,schedule:Sch.Schedule<S,C,R,E,H>,bindings:Bindings<W.World<S,C,R,E>,B,select>) -> Attachment<S,C,R,E,H,B,select>:
180  match schedule bindings:
181    case Sch.Schedule{namespace,name,+steps,owners} Bindings{state,+facts}:attached(~S,~C,~R,~E,~H,~B,~select,Bool.and(unique_bindings(facts,[]),binding_targets(facts,steps)),namespace,name,steps,owners,Bindings{state,facts},facts)
182
183def body_outcome(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> Evaluation<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,bindings:Bindings<W.World<S,C,R,E>,B,select>,owners:H,outcome:Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>) -> (H & Bindings<W.World<S,C,R,E>,B,select>) & Sys.Outcome<W.World<S,C,R,E>,Error<BodyError>,Unit>:
184  match outcome:
185    case Sys.Succeeded{world,value}:((owners,bindings),Sys.Succeeded{world,value})
186    case Sys.Failed{world,error}:((owners,bindings),Sys.Failed{world,SystemError{error}})
187def body_returned(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> Evaluation<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,bindings:Bindings<W.World<S,C,R,E>,B,select>,returned:H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>) -> (H & Bindings<W.World<S,C,R,E>,B,select>) & Sys.Outcome<W.World<S,C,R,E>,Error<BodyError>,Unit>:
188  match returned:
189    case (owners,outcome):body_outcome(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,bindings,owners,outcome)
190def body_dispatch(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> Evaluation<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,owners:H & Bindings<W.World<S,C,R,E>,B,select>,world:W.World<S,C,R,E>,id:U32) -> (H & Bindings<W.World<S,C,R,E>,B,select>) & Sys.Outcome<W.World<S,C,R,E>,Error<BodyError>,Unit>:
191  match owners:
192    case (gameplay,bindings):body_returned(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,bindings,dispatch(gameplay,world,id))
193def guard_decision(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> Evaluation<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,next:(H & Bindings<W.World<S,C,R,E>,B,select>) -> W.World<S,C,R,E> -> List<&2,Sch.Observation> -> Sch.RunResult<S,C,R,E,H & Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>,value:Bool,owners:H,bindings:Bindings<W.World<S,C,R,E>,B,select>,world:W.World<S,C,R,E>,+namespace:U32,+name:String,+all:List<&2,Sch.Step>,+observations:List<&2,Sch.Observation>,+id:U32) -> Sch.RunResult<S,C,R,E,H & Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>:
194  match value:
195    case False{}:next((owners,bindings),world,List.append(&2,Sch.Observation,observations,[Sch.Skipped{id}]))
196    case True{}:Sch.after_dispatch(~S,~C,~R,~E,~(H & Bindings<W.World<S,C,R,E>,B,select>),~Error<BodyError>,next,body_dispatch(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,(owners,bindings),world,id),namespace,name,all,observations,id)
197def guard_returned(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> Evaluation<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,next:(H & Bindings<W.World<S,C,R,E>,B,select>) -> W.World<S,C,R,E> -> List<&2,Sch.Observation> -> Sch.RunResult<S,C,R,E,H & Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>,facts:List<&2,BindingDescription>,owners:H,result:Evaluation<W.World<S,C,R,E>,B>,namespace:U32,name:String,all:List<&2,Sch.Step>,observations:List<&2,Sch.Observation>,id:U32) -> Sch.RunResult<S,C,R,E,H & Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>:
198  match result:
199    case Value{world,state,value}:guard_decision(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,next,value,owners,Bindings{state,facts},world,namespace,name,all,observations,id)
200    case NoBinding{world,state}:guard_decision(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,next,True{},owners,Bindings{state,facts},world,namespace,name,all,observations,id)
201    case NoValue{world,state}:Sch.Failed{Sch.Schedule{namespace,name,all,(owners,Bindings{state,facts})},world,ConditionUnavailable{},observations}
202    case InvalidRegistration{world,state}:Sch.Failed{Sch.Schedule{namespace,name,all,(owners,Bindings{state,facts})},world,ConditionRegistrationRejected{},observations}
203def guard(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> Evaluation<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,next:(H & Bindings<W.World<S,C,R,E>,B,select>) -> W.World<S,C,R,E> -> List<&2,Sch.Observation> -> Sch.RunResult<S,C,R,E,H & Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>,owners:H & Bindings<W.World<S,C,R,E>,B,select>,world:W.World<S,C,R,E>,namespace:U32,name:String,all:List<&2,Sch.Step>,observations:List<&2,Sch.Observation>,+id:U32) -> Sch.RunResult<S,C,R,E,H & Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>:
204  match owners:
205    case (gameplay,Bindings{state,facts}):guard_returned(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,next,facts,gameplay,select(state,world,id),namespace,name,all,observations,id)
206def execute(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> Evaluation<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,steps:List<&2,Sch.Step>,owners:H & Bindings<W.World<S,C,R,E>,B,select>,world:W.World<S,C,R,E>,+namespace:U32,+name:String,+all:List<&2,Sch.Step>,observations:List<&2,Sch.Observation>) -> Sch.RunResult<S,C,R,E,H & Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>:
207  match steps:
208    case []:Sch.Finished{Sch.Schedule{namespace,name,all,owners},world,observations}
209    case Sch.Phase{phase} <> rest:execute(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,rest,owners,world,namespace,name,all,List.append(&2,Sch.Observation,observations,[Sch.Entered{phase}]))
210    case Sch.Barrier{} <> rest:execute(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,rest,owners,W.barrier(~S,~C,~R,~E,world),namespace,name,all,List.append(&2,Sch.Observation,observations,[Sch.Applied{}]))
211    case Sch.System{id,_} <> rest:guard(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,h => w => obs => execute(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,rest,h,w,namespace,name,all,obs),owners,world,namespace,name,all,observations,id)
212def run_checked(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> Evaluation<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,allowed:Bool,schedule:Sch.Schedule<S,C,R,E,H & Bindings<W.World<S,C,R,E>,B,select>>,world:W.World<S,C,R,E>) -> Sch.RunResult<S,C,R,E,H & Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>:
213  match allowed schedule:
214    case False{} schedule:Sch.Rejected{schedule,world}
215    case True{} Sch.Schedule{+namespace,+name,+steps,owners}:execute(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,steps,owners,world,namespace,name,steps,[])
216def run_namespaced(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> Evaluation<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,schedule:Sch.Schedule<S,C,R,E,H & Bindings<W.World<S,C,R,E>,B,select>>,observed:W.World<S,C,R,E> & U32) -> Sch.RunResult<S,C,R,E,H & Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>:
217  match schedule observed:
218    case Sch.Schedule{+namespace,name,+steps,(gameplay,Bindings{state,+facts})}, (world,actual):run_checked(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,Bool.and(U32.is_eq(namespace,actual),Bool.and(unique_bindings(facts,[]),binding_targets(facts,steps))),Sch.Schedule{namespace,name,steps,(gameplay,Bindings{state,facts})},world)
219def run_schedule(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> Evaluation<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,schedule:Sch.Schedule<S,C,R,E,H & Bindings<W.World<S,C,R,E>,B,select>>,world:W.World<S,C,R,E>) -> Sch.RunResult<S,C,R,E,H & Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>:
220  run_namespaced(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,schedule,W.namespace(~S,~C,~R,~E,world))
221
222def provision_checked(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> Evaluation<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,missing:List<&2,SP.Requirement<S>>,schedule:Sch.Schedule<S,C,R,E,H & Bindings<W.World<S,C,R,E>,B,select>>,world:W.World<S,C,R,E>,needs:List<&2,SP.Requirement<S>>) -> SP.ProvisionResult<S,C,R,E,H & Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>:
223  match missing:
224    case first <> rest:SP.Missing{SP.Provisioned{schedule,needs},world,first <> rest}
225    case []:SP.Executed{run_schedule(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,schedule,world),needs}
226def provision_available(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> Evaluation<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,observed:W.World<S,C,R,E> & List<&2,SP.Requirement<S>>,schedule:Sch.Schedule<S,C,R,E,H & Bindings<W.World<S,C,R,E>,B,select>>,+needs:List<&2,SP.Requirement<S>>) -> SP.ProvisionResult<S,C,R,E,H & Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>:
227  match observed:
228    case (world,available):provision_checked(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,SP.missing_requirements(~S,needs,available),schedule,world,needs)
229def run_provisioned(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> Evaluation<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,~provision:W.World<S,C,R,E> -> W.World<S,C,R,E> & List<&2,SP.Requirement<S>>,schedule:SP.Provisioned<S,C,R,E,H & Bindings<W.World<S,C,R,E>,B,select>>,world:W.World<S,C,R,E>) -> SP.ProvisionResult<S,C,R,E,H & Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>:
230  match schedule:
231    case SP.Provisioned{schedule,needs}:provision_available(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,provision(world),schedule,needs)