1 import Base 2 import ./world.bend as W 3 import ./system.bend as Sys 4 import ./ordinary_schema.bend as Schema 5 import ./owner_product.bend as Product 6 import ./world_resource_owner.bend as WR 7 import ./recovery_journal.bend as Journal 8 import ./recoverable_array.bend as A 9 import ./recoverable_array_owner.bend as ArrayOwner 10 import ./transaction.bend as T 11 # The ordinary constructor derives both lenses. Gameplay only sees opaque H. 12 type Frame is Type: 13 Frame{state:State,journal:List} 14 type Attempt is Type: 15 Applied{owner:H} 16 Refused{owner:H,replacement:P} 17 type Write<-S:Data,-P:Type,-identity:Schema.Resource>,-H:Type> is Type: 18 Write{replace:H -> Array

-> H,swap:H -> U32 -> P -> Attempt} 19 def replace_field(~S:Data,~P:Type,~identity:Schema.Resource>,~H:Type,cap:Write) -> H -> Array

-> H: 20 match cap: 21 case Write{f,_}:f 22 def swap_field(~S:Data,~P:Type,~identity:Schema.Resource>,~H:Type,cap:Write) -> H -> U32 -> P -> Attempt: 23 match cap: 24 case Write{_,f}:f 25 def replace(~S:Data,~P:Type,~identity:Schema.Resource>,~H:Type,~cap:Write,owner:H,value:Array

) -> H: 26 replace_field(~S,~P,~identity,~H,cap)(owner,value) 27 def swap(~S:Data,~P:Type,~identity:Schema.Resource>,~H:Type,~cap:Write,owner:H,index:U32,value:P) -> Attempt: 28 swap_field(~S,~P,~identity,~H,cap)(owner,index,value) 29 def release_take(~P:Type,values:List>) -> Unit & List>:(Unit{},values) 30 def release_put(~P:Type,unit:Unit,values:List>) -> List>:values 31 def release(~P:Type) -> Product.Lens>,List>,Unit>: 32 Product.Lens{release_take(~P),release_put(~P)} 33 def replaced(~S:Data,~C:Type,~P:Type,~E:Data,result:W.World,E> & List,E>,~List>)>) -> Frame,E>,List>>: 34 match result: 35 case (world,journal):Frame{world,journal} 36 def frame_replace(~S:Data,~C:Type,~P:Type,~E:Data,owner:Frame,E>,List>>,replacement:Array

) -> Frame,E>,List>>: 37 match owner: 38 case Frame{world,journal}:replaced(~S,~C,~P,~E,ArrayOwner.replace(~W.World,E>,~P,~WR.Rest,E>,~WR.lens(~S,~C,~Array

,~E),~List>,~Unit,~release(~P),world,journal,replacement)) 39 def swapped(~S:Data,~C:Type,~P:Type,~E:Data,result:ArrayOwner.Attempt,E>,List>,P>) -> Attempt,E>,List>>,P>: 40 match result: 41 case ArrayOwner.Applied{world,journal}:Applied{Frame{world,journal}} 42 case ArrayOwner.Refused{world,journal,replacement}:Refused{Frame{world,journal},replacement} 43 def frame_swap(~S:Data,~C:Type,~P:Type,~E:Data,owner:Frame,E>,List>>,index:U32,replacement:P) -> Attempt,E>,List>>,P>: 44 match owner: 45 case Frame{world,journal}:swapped(~S,~C,~P,~E,ArrayOwner.swap(~W.World,E>,~P,~WR.Rest,E>,~WR.lens(~S,~C,~Array

,~E),~List>,~Unit,~release(~P),world,journal,index,replacement)) 46 def grant(~S:Data,~C:Type,~P:Type,~E:Data,~identity:Schema.Resource>) -> Write,E>,List>>>: 47 Write{frame_replace(~S,~C,~P,~E),frame_swap(~S,~C,~P,~E)} 48 def succeeded(~Error:Data,outcome:T.Outcome) -> Bool: 49 match outcome: 50 case T.Success{}:True{} 51 case T.Failure{_}:False{} 52 type Reply is Type: 53 Reply{outcome:T.Outcome,output:Out,recovered:List>} 54 def finished(~S:Data,~C:Type,~P:Type,~E:Data,~Error:Data,~Out:Type,outcome:T.Outcome,output:Out,result:W.World,E> & List>) -> Sys.Outcome,E>,Unit,Reply>: 55 match result: 56 case (world,recovered):Sys.Succeeded{world,Reply{outcome,output,recovered}} 57 def completing(~S:Data,~C:Type,~P:Type,~E:Data,~Error:Data,~Out:Type,world:W.World,E>,journal:List,E>,~List>)>,result:T.Outcome & Out) -> Sys.Outcome,E>,Unit,Reply>: 58 match result: 59 case (+outcome,output):finished(~S,~C,~P,~E,~Error,~Out,outcome,output,Journal.finish(~W.World,E>,~List>,journal,succeeded(~Error,outcome),world,[])) 60 def returned(~S:Data,~C:Type,~P:Type,~E:Data,~Error:Data,~Out:Type,result:Frame,E>,List>> & (T.Outcome & Out)) -> Sys.Outcome,E>,Unit,Reply>: 61 match result: 62 case (Frame{world,journal},output):completing(~S,~C,~P,~E,~Error,~Out,world,journal,output) 63 def runner(~S:Data,~C:Type,~P:Type,~E:Data,~identity:Schema.Resource>,~Args:Type,~Error:Data,~Out:Type,~body:@-H:Type -> @-caps:Write -> Args -> H -> H & (T.Outcome & Out),world:W.World,E>,args:Args) -> Sys.Outcome,E>,Unit,Reply>: 64 returned(~S,~C,~P,~E,~Error,~Out,body(Frame,E>,List>>,grant(~S,~C,~P,~E,~identity),args,Frame{world,[]})) 65 def Registry(~S:Data,~C:Type,~P:Type,~E:Data,~identity:Schema.Resource>,~Args:Type,~Error:Data,~Out:Type,~body:@-H:Type -> @-caps:Write -> Args -> H -> H & (T.Outcome & Out)) -> Type: 66 Sys.Registry,E,Args,Unit,Reply,runner(~S,~C,~P,~E,~identity,~Args,~Error,~Out,~body)> 67 def define(~S:Data,~C:Type,~P:Type,~E:Data,~identity:Schema.Resource>,~Args:Type,~Error:Data,~Out:Type,~body:@-H:Type -> @-caps:Write -> Args -> H -> H & (T.Outcome & Out),world:W.World,E>,name:String) -> Sys.RegistrationResult,E,Args,Unit,Reply,runner(~S,~C,~P,~E,~identity,~Args,~Error,~Out,~body)>: 68 Sys.register(~S,~C,~Array

,~E,~Args,~Unit,~Reply,~runner(~S,~C,~P,~E,~identity,~Args,~Error,~Out,~body),world,name,[Schema.resource_key(~S,~Array

,identity)]) 69 type Run is Type: 70 Completed{world:World,registry:Registry,outcome:T.Outcome,output:Out,recovered:List>} 71 RegistrationRejected{world:World,registry:Registry,args:Args} 72 TransportFailed{world:World,registry:Registry} 73 def done(~S:Data,~C:Type,~P:Type,~E:Data,~identity:Schema.Resource>,~Args:Type,~Error:Data,~Out:Type,~body:@-H:Type -> @-caps:Write -> Args -> H -> H & (T.Outcome & Out),outcome:T.Outcome,output:Out,recovered:List>,updated:W.World,E> & Sys.Registry,E,Args,Unit,Reply,runner(~S,~C,~P,~E,~identity,~Args,~Error,~Out,~body)>) -> Run,E>,Sys.Registry,E,Args,Unit,Reply,runner(~S,~C,~P,~E,~identity,~Args,~Error,~Out,~body)>,Args,Error,Out,P>: 74 match updated: 75 case (world,registry):Completed{world,registry,outcome,output,recovered} 76 def completed(~S:Data,~C:Type,~P:Type,~E:Data,~identity:Schema.Resource>,~Args:Type,~Error:Data,~Out:Type,~body:@-H:Type -> @-caps:Write -> Args -> H -> H & (T.Outcome & Out),result:Sys.RunResult,E,Args,Unit,Reply,runner(~S,~C,~P,~E,~identity,~Args,~Error,~Out,~body)>) -> Run,E>,Sys.Registry,E,Args,Unit,Reply,runner(~S,~C,~P,~E,~identity,~Args,~Error,~Out,~body)>,Args,Error,Out,P>: 77 match result: 78 case Sys.RegistrationRejected{registry,world,args}:RegistrationRejected{world,registry,args} 79 case Sys.Completed{registry,Sys.Succeeded{world,Reply{+outcome,output,recovered}}}:done(~S,~C,~P,~E,~identity,~Args,~Error,~Out,~body,outcome,output,recovered,(world,registry)) 80 case Sys.Completed{registry,Sys.Failed{world,_}}:TransportFailed{world,registry} 81 def run(~S:Data,~C:Type,~P:Type,~E:Data,~identity:Schema.Resource>,~Args:Type,~Error:Data,~Out:Type,~body:@-H:Type -> @-caps:Write -> Args -> H -> H & (T.Outcome & Out),registry:Sys.Registry,E,Args,Unit,Reply,runner(~S,~C,~P,~E,~identity,~Args,~Error,~Out,~body)>,world:W.World,E>,args:Args) -> Run,E>,Sys.Registry,E,Args,Unit,Reply,runner(~S,~C,~P,~E,~identity,~Args,~Error,~Out,~body)>,Args,Error,Out,P>: 82 completed(~S,~C,~P,~E,~identity,~Args,~Error,~Out,~body,Sys.run(~S,~C,~Array

,~E,~Args,~Unit,~Reply,~runner(~S,~C,~P,~E,~identity,~Args,~Error,~Out,~body),registry,world,args))