execution_query_schema.bend

bendvy-ecs-core@0.1.0.3 · 119 lines · 29 definitions

1import Base
2import bendvy-ecs-core@0.1.0.3/execution_composer_layout.bend as L
3import bendvy-ecs-core@0.1.0.3/execution_query_domain.bend as D
4import bendvy-ecs-core@0.1.0.3/execution_query_matches.bend as Q
5import bendvy-ecs-core@0.1.0.3/chunk_shape.bend as Part
6import bendvy-ecs-core@0.1.0.3/chunk_column.bend as Col
7import bendvy-ecs-core@0.1.0.3/owner_product.bend as Product
8import bendvy-ecs-core@0.1.0.3/lifecycle.bend as Life
9
10# A full-layout-indexed framework Book. Ordinary lowering must construct its
11# entries from the same closed declaration that provisions H operations.
12type Entry is Data:
13  Entry{route:L.Route,recipe:Q.Recipe}
14type Book<-S:Data,-full:L.Layout> is Data:
15  Book{entries:List<&2,Entry>}
16def same_route(left:L.Route,right:L.Route) -> Bool:
17  match left right:
18    case L.AtLeaf{} L.AtLeaf{}:True{}
19    case L.InLeft{left} L.InLeft{right}:same_route(left,right)
20    case L.InRight{left} L.InRight{right}:same_route(left,right)
21    case _ _:False{}
22def access_union(left:D.Access,right:D.Access) -> D.Access:
23  match left right:
24    case D.Access{lr,lw} D.Access{rr,rw}:D.Access{D.union(lr,rr),D.union(lw,rw)}
25def access(recipe:Q.Recipe) -> D.Access:
26  match recipe:
27    case Q.Read{domain}:D.Access{domain,D.Domain{[]}}
28    case Q.Write{+domain}:D.Access{domain,domain}
29    case Q.Both{left,right}:access_union(access(left),access(right))
30def access_entry(recipe:Q.Recipe,next:D.Access,selected:Bool) -> D.Access:
31  match selected:
32    case False{}:next
33    case True{}:access_union(access(recipe),next)
34def entry_access(+route:L.Route,entries:List<&2,Entry>) -> D.Access:
35  match entries:
36    case []:D.Access{D.Domain{[]},D.Domain{[]}}
37    case Entry{at,recipe} <> rest:access_entry(recipe,entry_access(route,rest),same_route(route,at))
38def family_access(-S:Data,-full:L.Layout,book:Book<S,full>,route:L.Route) -> D.Access:
39  match book:
40    case Book{entries}:entry_access(route,entries)
41def routes_valid(~full:L.Layout,entries:List<&2,Entry>) -> Bool:
42  match entries:
43    case []:True{}
44    case Entry{route,_} <> rest:Bool.and(L.valid(full,route),routes_valid(~full,rest))
45def all_recipes_valid(+route:L.Route,+capacity:U32,entries:List<&2,Entry>) -> Bool:
46  match entries:
47    case []:True{}
48    case Entry{at,recipe} <> rest:Bool.and(Bool.or(Bool.not(same_route(route,at)),Q.validate_recipe(capacity,recipe)),all_recipes_valid(route,capacity,rest))
49
50def append_route(prefix:L.Route,+suffix:L.Route) -> L.Route:
51  match prefix:
52    case L.AtLeaf{}:suffix
53    case L.InLeft{rest}:L.InLeft{append_route(rest,suffix)}
54    case L.InRight{rest}:L.InRight{append_route(rest,suffix)}
55def cached_cell(-P:Type,-V:Data,+offset:U32,+stamp:Life.Stamp,result:Array<Maybe<&1,L.Viewed<P,V>>> & Maybe<&1,L.Viewed<P,V>>) -> Array<Maybe<&1,L.Viewed<P,V>>> & Q.Row<V>:
56  match result:
57    case (values,None{}):(values,Q.StampedRow{offset,None{},stamp})
58    case (values,Some{L.Viewed{owner,+view}}):(Array.set(Maybe<&1,L.Viewed<P,V>>,values,U32.mod(offset,8),Some{L.Viewed{owner,view}}),Q.StampedRow{offset,Some{view},stamp})
59def cached_step(-P:Type,-V:Data,rows:List<&2,Q.Row<V>>,result:Array<Maybe<&1,L.Viewed<P,V>>> & Q.Row<V>) -> Array<Maybe<&1,L.Viewed<P,V>>> & List<&2,Q.Row<V>>:
60  match result:
61    case (values,row):(values,row <> rows)
62def cache_stamp(-P:Type,-V:Data,+base:U32,+index:U32,values:Array<Maybe<&1,L.Viewed<P,V>>>,rows:List<&2,Q.Row<V>>,result:Array<Life.Stamp> & Life.Stamp) -> Array<Life.Stamp> & (Array<Maybe<&1,L.Viewed<P,V>>> & List<&2,Q.Row<V>>):
63  match result:
64    case (stamps,stamp):(stamps,cached_step(P,V,rows,cached_cell(P,V,U32.add(base,index),stamp,Array.swap(Maybe<&1,L.Viewed<P,V>>,values,index,None{}))))
65def cache_leaf(-P:Type,-V:Data,fuel:Nat,+base:U32,+index:U32,result:Array<Life.Stamp> & (Array<Maybe<&1,L.Viewed<P,V>>> & List<&2,Q.Row<V>>)) -> Array<Life.Stamp> & (Array<Maybe<&1,L.Viewed<P,V>>> & List<&2,Q.Row<V>>):
66  match fuel result:
67    case 0n result:result
68    case 1n+rest, (stamps,(values,rows)):cache_leaf(P,V,rest,base,U32.add(index,1),cache_stamp(P,V,base,index,values,rows,Array.get(Life.Stamp,stamps,index)))
69def cached_leaf(-S:Data,-P:Type,-V:Data,result:Array<Life.Stamp> & (Array<Maybe<&1,L.Viewed<P,V>>> & List<&2,Q.Row<V>>)) -> Col.Column<S,L.Viewed<P,V>> & List<&2,Q.Row<V>>:
70  match result:
71    case (stamps,(values,rows)):(Col.Leaf{values,stamps},rows)
72def cached_pair(-S:Data,-P:Type,-V:Data,half:U32,left:Col.Column<S,L.Viewed<P,V>> & List<&2,Q.Row<V>>,right:Col.Column<S,L.Viewed<P,V>> & List<&2,Q.Row<V>>) -> Col.Column<S,L.Viewed<P,V>> & List<&2,Q.Row<V>>:
73  match left right:
74    case (l,lr), (r,rr):(Col.Branch{half,l,r},List.append(&2,Q.Row<V>,lr,rr))
75def cache_column(-S:Data,-P:Type,-V:Data,column:Col.Column<S,L.Viewed<P,V>>,+base:U32) -> Col.Column<S,L.Viewed<P,V>> & List<&2,Q.Row<V>>:
76  match column:
77    case Col.Leaf{values,stamps}:cached_leaf(S,P,V,cache_leaf(P,V,8n,base,0,(stamps,(values,[]))))
78    case Col.Branch{+half,l,r}:cached_pair(S,P,V,half,cache_column(S,P,V,l,base),cache_column(S,P,V,r,U32.add(base,half)))
79def filtered_row(-V:Data,row:Q.Row<V>,rest:List<&2,Q.Row<V>>,selected:Bool) -> List<&2,Q.Row<V>>:
80  match selected:
81    case False{}:rest
82    case True{}:row <> rest
83def filter_rows(-V:Data,+domain:D.Domain,rows:List<&2,Q.Row<V>>) -> List<&2,Q.Row<V>>:
84  match rows:
85    case []:[]
86    case +row <> rest:filtered_row(V,row,filter_rows(V,domain,rest),D.contains(domain,Q.row_offset(V,row)))
87
88type Info is Data:
89  Info{route:L.Route,capacity:U32,present:D.Domain}
90type Description<-S:Data,-full:L.Layout> is Type:
91  Description{columns:L.columns(~S,full),info:List<&2,Info>,valid:Bool}
92def present_offsets(-V:Data,rows:List<&2,Q.Row<V>>) -> List<&2,U32>:
93  match rows:
94    case []:[]
95    case Q.Row{_,None{}} <> rest:present_offsets(V,rest)
96    case Q.Row{offset,Some{_}} <> rest:offset <> present_offsets(V,rest)
97    case Q.StampedRow{_,None{},_} <> rest:present_offsets(V,rest)
98    case Q.StampedRow{offset,Some{_},_} <> rest:offset <> present_offsets(V,rest)
99def described_cache(-S:Data,-P:Type,-V:Data,route:L.Route,capacity:U32,result:Col.Column<S,L.Viewed<P,V>> & List<&2,Q.Row<V>>) -> Col.Column<S,L.Viewed<P,V>> & (Info & Bool):
100  match result:
101    case (column,rows):(column,(Info{route,capacity,D.Domain{present_offsets(V,rows)}},True{}))
102def described_inspection(-S:Data,-P:Type,-V:Data,route:L.Route,result:Col.Column<S,L.Viewed<P,V>> & Part.Inspection) -> Col.Column<S,L.Viewed<P,V>> & (Info & Bool):
103  match result:
104    case (column,Part.Inspection{_,capacity,False{}}):(column,(Info{route,capacity,D.Domain{[]}},False{}))
105    case (column,Part.Inspection{_,capacity,True{}}):described_cache(S,P,V,route,capacity,cache_column(S,P,V,column,0))
106def describe_leaf(-S:Data,-P:Type,-V:Data,route:L.Route,column:Col.Column<S,L.Viewed<P,V>>) -> Col.Column<S,L.Viewed<P,V>> & (Info & Bool):
107  described_inspection(S,P,V,route,Part.inspect(S,L.Viewed<P,V>,column))
108def leaf_description(-S:Data,-P:Type,-V:Data,-Out:Type,make:Col.Column<S,L.Viewed<P,V>> -> Info -> Bool -> Out,result:Col.Column<S,L.Viewed<P,V>> & (Info & Bool)) -> Out:
109  match result:
110    case (column,(info,valid)):make(column,info,valid)
111def described_pair(~S:Data,-ll:L.Layout,-rr:L.Layout,left:Description<S,ll>,right:Description<S,rr>) -> Description<S,L.LayoutPair{ll,rr}>:
112  match left right:
113    case Description{l,li,lv} Description{r,ri,rv}:Description{Product.Owner{l,r},List.append(&2,Info,li,ri),Bool.and(lv,rv)}
114def describe(~S:Data,layout:L.Layout,+route:L.Route,columns:L.columns(~S,layout)) -> Description<S,layout>:
115  match layout columns:
116    case L.EmptyLayout{} Unit{}:Description{Unit{},[],True{}}
117    case L.LayoutLeaf{P,V,refresh,key,accessPolicy} L.ColumnSlot{column}:leaf_description(S,P,V,Description<S,L.LayoutLeaf{P,V,refresh,key,accessPolicy}>,(column => info => valid => Description{L.ColumnSlot{column},[info],valid}),describe_leaf(S,P,V,route,column))
118    case L.ClassifiedLayoutLeaf{P,V,refresh,key,kind,accessPolicy} L.ColumnSlot{column}:leaf_description(S,P,V,Description<S,L.ClassifiedLayoutLeaf{P,V,refresh,key,kind,accessPolicy}>,(column => info => valid => Description{L.ColumnSlot{column},[info],valid}),describe_leaf(S,P,V,route,column))
119    case L.LayoutPair{ll,rr} Product.Owner{l,r}:described_pair(~S,ll,rr,describe(~S,ll,append_route(route,L.InLeft{L.AtLeaf{}}),l),describe(~S,rr,append_route(route,L.InRight{L.AtLeaf{}}),r))