ordinary_condition_declaration.bend
bendvy-ecs-core@0.1.0.4 · 102 lines · 21 definitions
1import Base
2import bendvy-ecs-core@0.1.0.4/world.bend as W
3import bendvy-ecs-core@0.1.0.4/schedule.bend as Sch
4import bendvy-ecs-core@0.1.0.4/schedule_provision.bend as SP
5
6
7
8
9
10type Declaration<-S:Data,-C:Type,-R:Type,-E:Data,-predicate:W.World<S,C,R,E> -> W.World<S,C,R,E> & Bool> is Data:Declaration{name:String}
11
12
13
14type Program<-S:Data,-C:Type,-R:Type,-E:Data,-Ids:Data> is Type:
15 Program{width:Nat,build:Ids -> SP.Plan<S>,names:List<&2,String>,evaluate:W.World<S,C,R,E> -> U32 -> W.World<S,C,R,E> & Bool}
16
17
18type Entries<S:Data> is Data:Entries{width:Nat,plan:SP.Plan<S>,names:List<&2,String>}
19
20
21def named(~S:Data,~C:Type,~R:Type,~E:Data,~predicate:W.World<S,C,R,E> -> W.World<S,C,R,E> & Bool,name:String) -> Declaration<S,C,R,E,predicate>:Declaration{name}
22
23def leaf_name(~S:Data,~C:Type,~R:Type,~E:Data,~predicate:W.World<S,C,R,E> -> W.World<S,C,R,E> & Bool,leaf:Declaration<S,C,R,E,predicate>) -> String:
24 match leaf:
25 case Declaration{name}:name
26
27
28
29def system(~S:Data,~C:Type,~R:Type,~E:Data,~Ids:Data,~predicate:W.World<S,C,R,E> -> W.World<S,C,R,E> & Bool,~identify:Ids -> U32,requirements:List<&2,SP.Requirement<S>>,leaf:Declaration<S,C,R,E,predicate>) -> Program<S,C,R,E,Ids>:
30 Program{1n,ids => SP.Entry{Sch.System{identify(ids),0},requirements},[leaf_name(~S,~C,~R,~E,~predicate,leaf)],world => slot => predicate(world)}
31
32
33def phase(~S:Data,~C:Type,~R:Type,~E:Data,~Ids:Data,name:String,requirements:List<&2,SP.Requirement<S>>) -> Program<S,C,R,E,Ids>:
34 Program{0n,ids => SP.Entry{Sch.Phase{name},requirements},[],world => slot => (world,False{})}
35
36
37def barrier(~S:Data,~C:Type,~R:Type,~E:Data,~Ids:Data,requirements:List<&2,SP.Requirement<S>>) -> Program<S,C,R,E,Ids>:
38 Program{0n,ids => SP.Entry{Sch.Barrier{},requirements},[],world => slot => (world,False{})}
39def shifted(~S:Data,plan:SP.Plan<S>,+offset:U32) -> SP.Plan<S>:
40 match plan:
41 case SP.Empty{}:SP.Empty{}
42 case SP.Entry{Sch.System{id,slot},requirements}:SP.Entry{Sch.System{id,(slot + offset : U32)},requirements}
43 case SP.Entry{Sch.Phase{name},requirements}:SP.Entry{Sch.Phase{name},requirements}
44 case SP.Entry{Sch.Barrier{},requirements}:SP.Entry{Sch.Barrier{},requirements}
45 case SP.Sequence{left,right}:SP.Sequence{shifted(~S,left,offset),shifted(~S,right,offset)}
46def built_pair(~S:Data,~Ids:Data,first:Ids -> SP.Plan<S>,second:Ids -> SP.Plan<S>,offset:Nat,+ids:Ids) -> SP.Plan<S>:SP.Sequence{first(ids),shifted(~S,second(ids),U32.from_nat(offset))}
47def selected(~S:Data,~C:Type,~R:Type,~E:Data,chosen:Bool,left:W.World<S,C,R,E> -> U32 -> W.World<S,C,R,E> & Bool,right:W.World<S,C,R,E> -> U32 -> W.World<S,C,R,E> & Bool,world:W.World<S,C,R,E>,slot:U32,offset:Nat) -> W.World<S,C,R,E> & Bool:
48 match chosen:
49 case True{}:left(world,slot)
50 case False{}:right(world,(slot - U32.from_nat(offset) : U32))
51def evaluated_pair(~S:Data,~C:Type,~R:Type,~E:Data,left:W.World<S,C,R,E> -> U32 -> W.World<S,C,R,E> & Bool,right:W.World<S,C,R,E> -> U32 -> W.World<S,C,R,E> & Bool,+offset:Nat,world:W.World<S,C,R,E>,+slot:U32) -> W.World<S,C,R,E> & Bool:selected(~S,~C,~R,~E,Nat.is_lt(U32.to_nat(slot),offset),left,right,world,slot,offset)
52
53
54
55def sequence(~S:Data,~C:Type,~R:Type,~E:Data,~Ids:Data,first:Program<S,C,R,E,Ids>,second:Program<S,C,R,E,Ids>) -> Program<S,C,R,E,Ids>:
56 match first second:
57 case Program{+leftWidth,leftBuild,leftNames,leftEval} Program{rightWidth,rightBuild,rightNames,rightEval}:Program{Nat.add(leftWidth,rightWidth),ids => built_pair(~S,~Ids,leftBuild,rightBuild,leftWidth,ids),List.append(&2,String,leftNames,rightNames),world => slot => evaluated_pair(~S,~C,~R,~E,leftEval,rightEval,leftWidth,world,slot)}
58
59
60
61def evaluator(~S:Data,~C:Type,~R:Type,~E:Data,~Ids:Data,program:Program<S,C,R,E,Ids>) -> W.World<S,C,R,E> -> U32 -> W.World<S,C,R,E> & Bool:
62 match program:
63 case Program{_,_,_,evaluate}:evaluate
64def built(~S:Data,~Ids:Data,width:Nat,names:List<&2,String>,result:SP.Plan<S>) -> Entries<S>:Entries{width,result,names}
65
66
67
68def materialize(~S:Data,~C:Type,~R:Type,~E:Data,~Ids:Data,declaration:Program<S,C,R,E,Ids>,ids:Ids) -> Entries<S>:
69 match declaration:
70 case Program{width,build,names,_}:built(~S,~Ids,width,names,build(ids))
71
72
73def slots(~S:Data,plan:SP.Plan<S>,+width:Nat) -> Bool:
74 match plan:
75 case SP.Empty{}:True{}
76 case SP.Entry{Sch.System{_,slot},_}:Nat.is_lt(U32.to_nat(slot),width)
77 case SP.Entry{Sch.Phase{_},_}:True{}
78 case SP.Entry{Sch.Barrier{},_}:True{}
79 case SP.Sequence{left,right}:Bool.and(slots(~S,left,width),slots(~S,right,width))
80
81
82
83
84def valid(~S:Data,entries:Entries<S>) -> Bool:
85 match entries:
86 case Entries{+width,plan,names}:Bool.and(Nat.is_eq(width,List.length(&2,String,names)),Bool.and(Nat.is_le(width,1n+U32.to_nat(4294967295)),slots(~S,plan,width)))
87
88def plan(~S:Data,entries:Entries<S>) -> SP.Plan<S>:
89 match entries:
90 case Entries{_,plan,_}:plan
91
92
93def lookup(names:List<&2,String>,index:Nat) -> Maybe<&2,String>:
94 match names index:
95 case [] _:None{}
96 case first <> _ 0n:Some{first}
97 case _ <> rest 1n+prior:lookup(rest,prior)
98
99
100def condition_name(~S:Data,entries:Entries<S>,slot:U32) -> Maybe<&2,String>:
101 match entries:
102 case Entries{_,_,names}:lookup(names,U32.to_nat(slot))