1 import Base 2 import ./trace_facts.bend as Facts 3 import ./relation_types.bend as G 4 import ./world.bend as W 5 import ./entity_key.bend as Key 6 import ./entity_key_render.bend as Render 7 8 def kind(value:G.RelationKind) -> Facts.RelationKind: 9 match value: 10 case G.Ordinary{}:Facts.OrdinaryRelation{} 11 case G.Hierarchy{}:Facts.HierarchyRelation{} 12 def identity(~S:Data,value:G.Descriptor) -> Facts.RelationIdentity: 13 match value: 14 case G.Descriptor{id,name,inverseName,value}:Facts.RelationIdentity{id,name,inverseName,kind(value)} 15 def handle(~S:Data,target:W.Handle) -> Facts.HandleValue: 16 match target: 17 case W.Handle{namespace,+key}:Facts.HandleValue{namespace,Key.index(key),Key.generation(key)} 18 def error(value:G.Error) -> String: 19 match value: 20 case G.MissingEntity{source}:"MissingEntity:" ++ Render.show(source) 21 case G.MissingTargetEntity{source,target,name}:"MissingTargetEntity:" ++ Render.show(source) ++ ":" ++ Render.show(target) ++ ":" ++ name 22 case G.SelfRelationNotAllowed{source,name}:"SelfRelationNotAllowed:" ++ Render.show(source) ++ ":" ++ name 23 case G.HierarchyCycle{source,target,name}:"HierarchyCycle:" ++ Render.show(source) ++ ":" ++ Render.show(target) ++ ":" ++ name 24 case G.MissingChildEntity{source,child,name}:"MissingChildEntity:" ++ Render.show(source) ++ ":" ++ Render.show(child) ++ ":" ++ name 25 case G.DuplicateChild{source,child,name}:"DuplicateChild:" ++ Render.show(source) ++ ":" ++ Render.show(child) ++ ":" ++ name 26 case G.ChildNotRelatedToParent{source,child,name}:"ChildNotRelatedToParent:" ++ Render.show(source) ++ ":" ++ Render.show(child) ++ ":" ++ name 27 case G.ChildSetMismatch{source,name}:"ChildSetMismatch:" ++ Render.show(source) ++ ":" ++ name 28 def outcome(value:Maybe<&2,G.Error>) -> Facts.FactResult: 29 match value: 30 case None{}:Facts.Applied{} 31 case Some{why}:Facts.Refused{error(why)} 32 def relate(~S:Data,state:Facts.State,descriptor:G.Descriptor,operation:Facts.Operation,source:W.Handle,target:W.Handle,result:Facts.FactResult) -> Facts.State: 33 match state: 34 case Facts.Off{}:Facts.Off{} 35 case Facts.On{facts}:Facts.On{Facts.RelationFact{identity(~S,descriptor),operation,handle(~S,source),Facts.RelateAction{handle(~S,target)},result} <> facts} 36 def relate_applied(~S:Data,state:Facts.State,descriptor:G.Descriptor,source:W.Handle,target:W.Handle,error:Maybe<&2,G.Error>) -> Facts.State: 37 match state: 38 case Facts.Off{}:Facts.Off{} 39 case state:relate(~S,state,descriptor,Facts.ApplyOperation{},source,target,outcome(error)) 40 def unrelate(~S:Data,state:Facts.State,descriptor:G.Descriptor,operation:Facts.Operation,source:W.Handle,result:Facts.FactResult) -> Facts.State: 41 match state: 42 case Facts.Off{}:Facts.Off{} 43 case Facts.On{facts}:Facts.On{Facts.RelationFact{identity(~S,descriptor),operation,handle(~S,source),Facts.UnrelateAction{},result} <> facts} 44 def handles(~S:Data,targets:List<&2,W.Handle>) -> List<&2,Facts.HandleValue>: 45 match targets: 46 case []:[] 47 case target <> rest:handle(~S,target) <> handles(~S,rest) 48 def reorder(~S:Data,state:Facts.State,descriptor:G.Descriptor,operation:Facts.Operation,parent:W.Handle,children:List<&2,W.Handle>,result:Facts.FactResult) -> Facts.State: 49 match state: 50 case Facts.Off{}:Facts.Off{} 51 case Facts.On{facts}:Facts.On{Facts.RelationFact{identity(~S,descriptor),operation,handle(~S,parent),Facts.ReorderAction{handles(~S,children)},result} <> facts} 52 def reorder_applied(~S:Data,state:Facts.State,descriptor:G.Descriptor,parent:W.Handle,children:List<&2,W.Handle>,error:Maybe<&2,G.Error>) -> Facts.State: 53 match state: 54 case Facts.Off{}:Facts.Off{} 55 case state:reorder(~S,state,descriptor,Facts.ApplyOperation{},parent,children,outcome(error))