1 import Base 2 import ./world.bend as W 3 import ./ordinary_app_relation.bend as Relation 4 import ./relation_failure_reader.bend as Ord 5 import ./relation_types.bend as G 6 import ./relation_commands.bend as A 7 import ./ordinary_app_linked_cleanup.bend as LC 8 import ./transaction.bend as T 9 import ./commands.bend as Cmd 10 import ./system.bend as Sys 11 import ./capabilities.bend as Cap 12 import ./ordinary_app_composer.bend as Build 13 import ./ordinary_app_recipe.bend as Tree 14 import ./ordinary_app_observation_data.bend as DTO 15 import ./ordinary_app_registration_fields.bend as Fields 16 import ./ordinary_component_clear_declaration.bend as Clear 17 18 # Gameplay receives an abstract affine owner and this single live operation. 19 type Ops<-H:Type,-S:Data> is Type: 20 Ops{cleanup:Cap.Request,A.QueueStatus>} 21 def cleanup(-H:Type,-S:Data,caps:Ops,owner:H,handle:W.Handle) -> H & A.QueueStatus: 22 match caps: 23 case Ops{Cap.Request{request}}:request(owner,handle) 24 def writes(keys:List<&2,String>) -> List<&2,String>: 25 match keys: 26 case []:[] 27 case key <> rest:String.concat([key,":write"]) <> writes(rest) 28 def relation_accesses(~S:Data,declarations:List<&2,Ord.Declaration>) -> List<&2,String>: 29 match declarations: 30 case []:[] 31 case Ord.Declaration{G.Descriptor{_,name,_,_}} <> rest:String.concat([name,":write"]) <> relation_accesses(~S,rest) 32 def request(~S:Data,~C:Type,~R:Type,~E:Data,~declarations:List<&2,Ord.Declaration>,~clear:C -> W.Handle -> C & List<&2,A.Notice>,~record:W.Handle -> A.Notice,tx:T.Tx>,handle:W.Handle) -> T.Tx> & A.QueueStatus: 33 LC.queue(~S,~C,~R,~E,~declarations,~clear,~record,tx,handle) 34 def provide(~S:Data,~C:Type,~R:Type,~E:Data,~declarations:List<&2,Ord.Declaration>,~clear:C -> W.Handle -> C & List<&2,A.Notice>,~record:W.Handle -> A.Notice) -> Ops>,S>: 35 Ops{Cap.Request{request(~S,~C,~R,~E,~declarations,~clear,~record)}} 36 def returned(~S:Data,~C:Type,~R:Type,~E:Data,~U:Data,~Out:Data,output:Out,result:T.Returned) -> Sys.Outcome: 37 match result: 38 case T.Returned{world,T.Success{}}:Sys.Succeeded{world,output} 39 case T.Returned{world,T.Failure{error}}:Sys.Failed{world,error} 40 def invoked(~S:Data,~C:Type,~R:Type,~E:Data,~U:Data,~Out:Data,result:T.Tx> & (T.Outcome & Out)) -> Sys.Outcome: 41 match result: 42 case (tx,(outcome,output)):returned(~S,~C,~R,~E,~U,~Out,output,Cmd.tx_finish(~S,~A.Store,~R,~A.Notice,~U,tx,outcome)) 43 def runner(~S:Data,~C:Type,~R:Type,~E:Data,~declarations:List<&2,Ord.Declaration>,~clear:C -> W.Handle -> C & List<&2,A.Notice>,~record:W.Handle -> A.Notice,~Args:Data,~U:Data,~Out:Data,~body:@-H:Type -> Ops -> Args -> H -> H & (T.Outcome & Out),world:Relation.World(~S,~C,~R,~E),args:Args) -> Sys.Outcome: 44 invoked(~S,~C,~R,~E,~U,~Out,body(T.Tx>,provide(~S,~C,~R,~E,~declarations,~clear,~record),args,T.begin(~Relation.World(~S,~C,~R,~E),~A.Notice,world))) 45 def Owner(~S:Data,~C:Type,~R:Type,~E:Data,~declarations:List<&2,Ord.Declaration>,~clear:C -> W.Handle -> C & List<&2,A.Notice>,~record:W.Handle -> A.Notice,~Args:Data,~U:Data,~Out:Data,~body:@-H:Type -> Ops -> Args -> H -> H & (T.Outcome & Out)) -> Type: 46 Sys.Registry,R,A.Notice,Args,U,Out,runner(~S,~C,~R,~E,~declarations,~clear,~record,~Args,~U,~Out,~body)> 47 def register(~S:Data,~C:Type,~R:Type,~E:Data,~declarations:List<&2,Ord.Declaration>,~clear:C -> W.Handle -> C & List<&2,A.Notice>,~record:W.Handle -> A.Notice,~Args:Data,~U:Data,~Out:Data,~body:@-H:Type -> Ops -> Args -> H -> H & (T.Outcome & Out),~clearDeclaration:Clear.Declaration,clear>,world:Relation.World(~S,~C,~R,~E),name:String) -> Sys.RegistrationResult,R,A.Notice,Args,U,Out,runner(~S,~C,~R,~E,~declarations,~clear,~record,~Args,~U,~Out,~body)>: 48 Sys.register(~S,~A.Store,~R,~A.Notice,~Args,~U,~Out,~runner(~S,~C,~R,~E,~declarations,~clear,~record,~Args,~U,~Out,~body),world,name,List.append(&2,String,writes(Clear.keys(~S,~C,~A.Notice,~clear,clearDeclaration)),relation_accesses(~S,declarations))) 49 def run(~S:Data,~C:Type,~R:Type,~E:Data,~declarations:List<&2,Ord.Declaration>,~clear:C -> W.Handle -> C & List<&2,A.Notice>,~record:W.Handle -> A.Notice,~Args:Data,~U:Data,~Out:Data,~body:@-H:Type -> Ops -> Args -> H -> H & (T.Outcome & Out),owner:Sys.Registry,R,A.Notice,Args,U,Out,runner(~S,~C,~R,~E,~declarations,~clear,~record,~Args,~U,~Out,~body)>,world:Relation.World(~S,~C,~R,~E),args:Args) -> Sys.RunResult,R,A.Notice,Args,U,Out,runner(~S,~C,~R,~E,~declarations,~clear,~record,~Args,~U,~Out,~body)>: 50 Sys.run(~S,~A.Store,~R,~A.Notice,~Args,~U,~Out,~runner(~S,~C,~R,~E,~declarations,~clear,~record,~Args,~U,~Out,~body),owner,world,args) 51 type Defined<-App:Type,-Registry:Type> is Type: 52 Defined{app:App,owner:Registry} 53 DefinitionRejected{app:App} 54 type Executed<-App:Type,-Registry:Type,-Args:Data,-U:Data,-Out:Data> is Type: 55 Executed{app:App,owner:Registry,outcome:T.Outcome,output:Maybe<&2,Out>} 56 RegistrationRejected{app:App,owner:Registry,args:Args} 57 def registered_app(~S:Data,~C:Type,~R:Type,~E:Data,~declarations:List<&2,Ord.Declaration>,~clear:C -> W.Handle -> C & List<&2,A.Notice>,~record:W.Handle -> A.Notice,~Args:Data,~U:Data,~Out:Data,~body:@-H:Type -> Ops -> Args -> H -> H & (T.Outcome & Out),~Owners:Type,~Rows:Data,~observe:Relation.World(~S,~C,~R,~E) -> Relation.World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,owners:Owners,recipe:Tree.Recipe,debug:Bool,result:Sys.RegistrationResult,R,A.Notice,Args,U,Out,runner(~S,~C,~R,~E,~declarations,~clear,~record,~Args,~U,~Out,~body)>) -> Defined,Sys.Registry,R,A.Notice,Args,U,Out,runner(~S,~C,~R,~E,~declarations,~clear,~record,~Args,~U,~Out,~body)>>: 58 match result: 59 case Sys.Registered{world,registry}:Defined{LC.Installed{Build.Registered{world,owners,recipe,debug}},registry} 60 case Sys.RegistrationFailed{world}:DefinitionRejected{LC.Installed{Build.Registered{world,owners,recipe,debug}}} 61 def register_app(~S:Data,~C:Type,~R:Type,~E:Data,~declarations:List<&2,Ord.Declaration>,~clear:C -> W.Handle -> C & List<&2,A.Notice>,~record:W.Handle -> A.Notice,~Args:Data,~U:Data,~Out:Data,~body:@-H:Type -> Ops -> Args -> H -> H & (T.Outcome & Out),~Owners:Type,~Rows:Data,~observe:Relation.World(~S,~C,~R,~E) -> Relation.World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,~clearDeclaration:Clear.Declaration,clear>,installed:LC.Installed,name:String) -> Defined,Sys.Registry,R,A.Notice,Args,U,Out,runner(~S,~C,~R,~E,~declarations,~clear,~record,~Args,~U,~Out,~body)>>: 62 match installed: 63 case LC.Installed{Build.Registered{world,owners,recipe,debug}}:registered_app(~S,~C,~R,~E,~declarations,~clear,~record,~Args,~U,~Out,~body,~Owners,~Rows,~observe,~fold,owners,recipe,debug,register(~S,~C,~R,~E,~declarations,~clear,~record,~Args,~U,~Out,~body,~clearDeclaration,world,name)) 64 def executed_app(~S:Data,~C:Type,~R:Type,~E:Data,~declarations:List<&2,Ord.Declaration>,~clear:C -> W.Handle -> C & List<&2,A.Notice>,~record:W.Handle -> A.Notice,~Args:Data,~U:Data,~Out:Data,~body:@-H:Type -> Ops -> Args -> H -> H & (T.Outcome & Out),~Owners:Type,~Rows:Data,~observe:Relation.World(~S,~C,~R,~E) -> Relation.World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,owners:Owners,recipe:Tree.Recipe,debug:Bool,result:Sys.RunResult,R,A.Notice,Args,U,Out,runner(~S,~C,~R,~E,~declarations,~clear,~record,~Args,~U,~Out,~body)>) -> Executed,Sys.Registry,R,A.Notice,Args,U,Out,runner(~S,~C,~R,~E,~declarations,~clear,~record,~Args,~U,~Out,~body)>,Args,U,Out>: 65 match result: 66 case Sys.Completed{registry,Sys.Succeeded{world,output}}:Executed{LC.Installed{Build.Registered{world,owners,recipe,debug}},registry,T.Success{},Some{output}} 67 case Sys.Completed{registry,Sys.Failed{world,error}}:Executed{LC.Installed{Build.Registered{world,owners,recipe,debug}},registry,T.Failure{error},None{}} 68 case Sys.RegistrationRejected{registry,world,args}:RegistrationRejected{LC.Installed{Build.Registered{world,owners,recipe,debug}},registry,args} 69 def run_app(~S:Data,~C:Type,~R:Type,~E:Data,~declarations:List<&2,Ord.Declaration>,~clear:C -> W.Handle -> C & List<&2,A.Notice>,~record:W.Handle -> A.Notice,~Args:Data,~U:Data,~Out:Data,~body:@-H:Type -> Ops -> Args -> H -> H & (T.Outcome & Out),~Owners:Type,~Rows:Data,~observe:Relation.World(~S,~C,~R,~E) -> Relation.World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,owner:Sys.Registry,R,A.Notice,Args,U,Out,runner(~S,~C,~R,~E,~declarations,~clear,~record,~Args,~U,~Out,~body)>,installed:LC.Installed,input:Args) -> Executed,Sys.Registry,R,A.Notice,Args,U,Out,runner(~S,~C,~R,~E,~declarations,~clear,~record,~Args,~U,~Out,~body)>,Args,U,Out>: 70 match installed: 71 case LC.Installed{Build.Registered{world,owners,recipe,debug}}:executed_app(~S,~C,~R,~E,~declarations,~clear,~record,~Args,~U,~Out,~body,~Owners,~Rows,~observe,~fold,owners,recipe,debug,run(~S,~C,~R,~E,~declarations,~clear,~record,~Args,~U,~Out,~body,owner,world,input))