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)