1 import Base 2 import ./dependency_plan.bend as Plan 3 import ./dependency_executor.bend as Exec 4 import ./execution_owner_continuation.bend as Continuation 5 6 type Registry<-World:Type,-Owners:Type,-Error:Data,-Out:Data,-dispatch:Owners -> World -> U32 -> Owners & (World & Exec.Invocation)> is Type: 7 Registry{owners:Owners,nodes:List<&2,Plan.Node>} 8 9 type Product is Type: 10 Product{left:L,right:R,leftIds:List<&2,U32>} 11 def ids(nodes:List<&2,Plan.Node>) -> List<&2,U32>: 12 match nodes: 13 case []:[] 14 case Plan.Node{id,_} <> rest:id <> ids(rest) 15 def contains(ids:List<&2,U32>,+id:U32) -> Bool: 16 match ids: 17 case []:False{} 18 case first <> rest:Bool.or(U32.is_eq(first,id),contains(rest,id)) 19 20 def left_returned(~World:Type,~L:Type,~R:Type,~Error:Data,~Out:Data,~leftDispatch:L -> World -> U32 -> L & (World & Exec.Invocation),~rightDispatch:R -> World -> U32 -> R & (World & Exec.Invocation),pair:(R & List<&2,U32>) & (L & (World & Exec.Invocation))) -> Product & (World & Exec.Invocation): 21 match pair: 22 case ((right,leftIds),(left,(world,status))):(Product{left,right,leftIds},(world,status)) 23 def right_returned(~World:Type,~L:Type,~R:Type,~Error:Data,~Out:Data,~leftDispatch:L -> World -> U32 -> L & (World & Exec.Invocation),~rightDispatch:R -> World -> U32 -> R & (World & Exec.Invocation),pair:(L & List<&2,U32>) & (R & (World & Exec.Invocation))) -> Product & (World & Exec.Invocation): 24 match pair: 25 case ((left,leftIds),(right,(world,status))):(Product{left,right,leftIds},(world,status)) 26 def paired_selected(~World:Type,~L:Type,~R:Type,~Error:Data,~Out:Data,~leftDispatch:L -> World -> U32 -> L & (World & Exec.Invocation),~rightDispatch:R -> World -> U32 -> R & (World & Exec.Invocation),selected:Bool,left:L,right:R,leftIds:List<&2,U32>,world:World,id:U32) -> Product & (World & Exec.Invocation): 27 match selected: 28 case True{}: 29 continuation:Continuation.PairedHeader<(L & (World & Exec.Invocation)),(Product & (World & Exec.Invocation))> = Continuation.PairedHeader{R & List<&2,U32>,(right,leftIds),left_returned(~World,~L,~R,~Error,~Out,~leftDispatch,~rightDispatch)} 30 Continuation.paired_returned(L & (World & Exec.Invocation),Product & (World & Exec.Invocation),continuation,leftDispatch(left,world,id)) 31 case False{}: 32 continuation:Continuation.PairedHeader<(R & (World & Exec.Invocation)),(Product & (World & Exec.Invocation))> = Continuation.PairedHeader{L & List<&2,U32>,(left,leftIds),right_returned(~World,~L,~R,~Error,~Out,~leftDispatch,~rightDispatch)} 33 Continuation.paired_returned(R & (World & Exec.Invocation),Product & (World & Exec.Invocation),continuation,rightDispatch(right,world,id)) 34 def paired_dispatch_actual(~World:Type,~L:Type,~R:Type,~Error:Data,~Out:Data,~leftDispatch:L -> World -> U32 -> L & (World & Exec.Invocation),~rightDispatch:R -> World -> U32 -> R & (World & Exec.Invocation),owners:Product,world:World,+id:U32) -> Product & (World & Exec.Invocation): 35 match owners: 36 case Product{left,right,+leftIds}:paired_selected(~World,~L,~R,~Error,~Out,~leftDispatch,~rightDispatch,contains(leftIds,id),left,right,leftIds,world,id) 37 def paired_dispatch(~World:Type,~L:Type,~R:Type,~Error:Data,~Out:Data,~leftDispatch:L -> World -> U32 -> L & (World & Exec.Invocation),~rightDispatch:R -> World -> U32 -> R & (World & Exec.Invocation),owners:Product,world:World,id:U32) -> Product & (World & Exec.Invocation): 38 paired_dispatch_actual(~World,~L,~R,~Error,~Out,~leftDispatch,~rightDispatch,owners,world,id) 39 def paired(~World:Type,~L:Type,~R:Type,~Error:Data,~Out:Data,~leftDispatch:L -> World -> U32 -> L & (World & Exec.Invocation),~rightDispatch:R -> World -> U32 -> R & (World & Exec.Invocation),left:Registry,right:Registry) -> Registry,Error,Out,paired_dispatch(~World,~L,~R,~Error,~Out,~leftDispatch,~rightDispatch)>: 40 match left right: 41 case Registry{left,+ln} Registry{right,rn}:Registry{Product{left,right,ids(ln)},List.append(&2,Plan.Node,ln,rn)} 42 43 def empty_dispatch(~World:Type,~Error:Data,~Out:Data,owners:Unit,world:World,_:U32) -> Unit & (World & Exec.Invocation): 44 (owners,(world,Exec.AdmissionRefused{})) 45 def empty(~World:Type,~Error:Data,~Out:Data) -> Registry: 46 Registry{Unit{},[]} 47 48 type ConditionRegistry<-World:Type,-Owners:Type,-Error:Data,-dispatch:Owners -> World -> U32 -> Owners & (World & Exec.Invocation)> is Type: 49 ConditionRegistry{registry:Registry,invalid:Maybe<&2,Plan.Invalid>} 50 def condition_permission(allowed:Bool,id:U32) -> Maybe<&2,Plan.Invalid>: 51 match allowed: 52 case True{}:None{} 53 case False{}:Some{Plan.InvalidCondition{id}} 54 def empty_conditions(~World:Type,~Error:Data) -> ConditionRegistry: 55 ConditionRegistry{empty(~World,~Error,~Bool),None{}} 56 def paired_conditions(~World:Type,~L:Type,~R:Type,~Error:Data,~leftDispatch:L -> World -> U32 -> L & (World & Exec.Invocation),~rightDispatch:R -> World -> U32 -> R & (World & Exec.Invocation),left:ConditionRegistry,right:ConditionRegistry) -> ConditionRegistry,Error,paired_dispatch(~World,~L,~R,~Error,~Bool,~leftDispatch,~rightDispatch)>: 57 match left right: 58 case ConditionRegistry{left,li} ConditionRegistry{right,ri}:ConditionRegistry{paired(~World,~L,~R,~Error,~Bool,~leftDispatch,~rightDispatch,left,right),Plan.first_error(~String,li,ri)}