1 import Base 2 import ./restore_graph_data.bend as R 3 import ./world.bend as W 4 import ./relation_commands.bend as Relation 5 import ./owner_product.bend as Product 6 import ./decode_data.bend as D 7 import ./snapshot_data.bend as Basic 8 import ./entity_key.bend as Key 9 import ./relation_types.bend as G 10 import ./relation_graph.bend as Graph 11 import ./relation_failure_reader.bend as Ordinary 12 13 def included(found:Bool,target:Key.Key,sources:List<&2,Key.Key>,rest:List<&2,R.Group>) -> List<&2,R.Group>: 14 match found: 15 case True{}:R.Group{target,sources} <> rest 16 case False{}:rest 17 def groups(~S:Data,entries:List<&2,G.Inverse>,+descriptor:G.Descriptor) -> List<&2,R.Group>: 18 match entries: 19 case []:[] 20 case G.Inverse{other,target,sources} <> rest:included(U32.is_eq(Graph.key(~S,descriptor),Graph.key(~S,other)),target,sources,groups(~S,rest,descriptor)) 21 def relations(~S:Data,declarations:List<&2,Ordinary.Declaration>,+graph:G.Graph) -> List<&2,R.Relation>: 22 match declarations graph: 23 case [] _:[] 24 case Ordinary.Declaration{+descriptor} <> rest G.Graph{+edges,+inverses}:R.Relation{Graph.name(~S,descriptor),groups(~S,inverses,descriptor)} <> relations(~S,rest,G.Graph{edges,inverses}) 25 def machine_read_joined(~Resources:Type,~Machines:Type,resource:Resources,result:Machines & List<&2,D.Field>) -> Product.Owner & List<&2,D.Field>: 26 match result: 27 case (machines,fields):(Product.Owner{resource,machines},fields) 28 def machine_read(~Resources:Type,~Machines:Type,~readMachines:Machines -> Machines & List<&2,D.Field>,resource:Product.Owner) -> Product.Owner & List<&2,D.Field>: 29 match resource: 30 case Product.Owner{resource,machines}:machine_read_joined(~Resources,~Machines,resource,readMachines(machines)) 31 def machine_joined(~S:Data,~C:Type,~Resources:Type,~Machines:Type,~E:Data,~readMachines:Machines -> Machines & List<&2,D.Field>,basic:Basic.Snapshot,relations:List<&2,R.Relation>,result:W.World,Product.Owner,E> & List<&2,D.Field>) -> W.World,Product.Owner,E> & Basic.Outcome: 32 match result: 33 case (world,machines):(world,Basic.Saved{R.Snapshot{basic,relations,machines}}) 34 def graph_joined(~S:Data,~C:Type,~Resources:Type,~Machines:Type,~E:Data,~readMachines:Machines -> Machines & List<&2,D.Field>,basic:Basic.Snapshot,declarations:List<&2,Ordinary.Declaration>,result:W.World,Product.Owner,E> & G.Graph) -> W.World,Product.Owner,E> & Basic.Outcome: 35 match result: 36 case (world,graph):machine_joined(~S,~C,~Resources,~Machines,~E,~readMachines,basic,relations(~S,declarations,graph),W.observe_resource(~S,~Relation.Store,~Product.Owner,~E,~List<&2,D.Field>,~machine_read(~Resources,~Machines,~readMachines),world)) 37 def basic_joined(~S:Data,~C:Type,~Resources:Type,~Machines:Type,~E:Data,~readMachines:Machines -> Machines & List<&2,D.Field>,declarations:List<&2,Ordinary.Declaration>,result:W.World,Product.Owner,E> & Basic.Outcome) -> W.World,Product.Owner,E> & Basic.Outcome: 38 match result: 39 case (world,Basic.RefusedPending{}):(world,Basic.RefusedPending{}) 40 case (world,Basic.Saved{basic}):graph_joined(~S,~C,~Resources,~Machines,~E,~readMachines,basic,declarations,W.with_store(~S,~Relation.Store,~Product.Owner,~E,~G.Graph,Relation.graph_read(~S,~C),world)) 41 def save_ready(~S:Data,~C:Type,~Resources:Type,~Machines:Type,~E:Data,~readMachines:Machines -> Machines & List<&2,D.Field>,~saveBasic:W.World,Product.Owner,E> -> W.World,Product.Owner,E> & Basic.Outcome,declarations:List<&2,Ordinary.Declaration>,result:W.World,Product.Owner,E> & Bool) -> W.World,Product.Owner,E> & Basic.Outcome: 42 match result: 43 case (world,False{}):(world,Basic.RefusedPending{}) 44 case (world,True{}):basic_joined(~S,~C,~Resources,~Machines,~E,~readMachines,declarations,saveBasic(world)) 45 # Save graph and committed machine values only after structural admission. 46 # RefusedPending preserves World and skips even saveBasic/readMachines callbacks. 47 # Separate queued machine transitions remain outside this committed-value snapshot; 48 # this operation neither rejects them nor applies a machine marker/barrier. 49 def save(~S:Data,~C:Type,~Resources:Type,~Machines:Type,~E:Data,~readMachines:Machines -> Machines & List<&2,D.Field>,~saveBasic:W.World,Product.Owner,E> -> W.World,Product.Owner,E> & Basic.Outcome,declarations:List<&2,Ordinary.Declaration>,world:W.World,Product.Owner,E>) -> W.World,Product.Owner,E> & Basic.Outcome: 50 save_ready(~S,~C,~Resources,~Machines,~E,~readMachines,~saveBasic,declarations,Basic.ready(~S,~Relation.Store,~Product.Owner,~E,world))