1 import Base 2 import ./persistence_declaration.bend as Persistence 3 import ./restore_data.bend as R 4 import ./decode_data.bend as D 5 import ./decode_construction.bend as Constructor 6 import ./bundle_construction.bend as Build 7 import ./ordinary_declaration.bend as Identity 8 9 type Record is Type: 10 Record{position:R.Position,owner:P,undo:P -> I} 11 type Applied is Type: 12 Applied{position:R.Position,undo:P -> I} 13 type State is Type: 14 State{context:Context,records:List>,returned:List,removed:List

,applied:List>} 15 type FamilyKind is Data:Component{} Resource{} 16 def same_kind(kind:FamilyKind,position:R.Position) -> Bool: 17 match kind position: 18 case Component{} R.Component{_}:True{} 19 case Resource{} R.Resource{}:True{} 20 case _ _:False{} 21 def constructed(~Context:Type,~I:Type,~P:Type,~Custom:Data,position:R.Position,records:List>,returned:List,removed:List

,applied:List>,context:Context,result:Build.Construction>) -> State & R.Dispatch: 22 match result: 23 case Build.Invalid{owner,error}:(State{context,records,List.append(&1,I,returned,[owner]),removed,applied},R.Rejected{error}) 24 case Build.Constructed{owner,undo}:(State{context,Record{position,owner,undo} <> records,returned,removed,applied},R.Staged{}) 25 def stored(~I:Type,~P:Type,~Custom:Data,undo:P -> I,receipt:D.Receipt

) -> Build.Construction>: 26 match receipt: 27 case D.Receipt{owner,D.Accepted{_}}:Build.Constructed{owner,undo} 28 case D.Receipt{owner,D.Rejected{error}}:Build.Invalid{undo(owner),Constructor.Validation{error}} 29 def admitted(~S:Data,~I:Type,~P:Type,~Custom:Data,~identity:Identity.Declaration,~project:P -> P & D.Raw,declaration:Persistence.Constructed,result:Build.Construction>) -> Build.Construction>: 30 match result: 31 case Build.Invalid{owner,error}:Build.Invalid{owner,error} 32 case Build.Constructed{owner,undo}:stored(~I,~P,~Custom,undo,Persistence.validate(~S,~P,~identity,~project,declaration,owner)) 33 def declaration(~S:Data,~I:Type,~P:Type,~Custom:Data,~identity:Identity.Declaration,~project:P -> P & D.Raw,~incoming:I -> I & D.Raw,~build:I -> D.Raw -> Build.Construction,factory:Constructor.FallibleFactory) -> Persistence.Constructed: 34 match factory: 35 case Constructor.FallibleFactory{declaration,_}:declaration 36 def supplied(~S:Data,~Context:Type,~I:Type,~P:Type,~Custom:Data,~identity:Identity.Declaration,~project:P -> P & D.Raw,~incoming:I -> I & D.Raw,~build:I -> D.Raw -> Build.Construction,~factory:Constructor.FallibleFactory,position:R.Position,records:List>,returned:List,removed:List

,applied:List>,observed:Context & I) -> State & R.Dispatch: 37 match observed: 38 case (context,input):constructed(~Context,~I,~P,~Custom,position,records,returned,removed,applied,context,admitted(~S,~I,~P,~Custom,~identity,~project,declaration(~S,~I,~P,~Custom,~identity,~project,~incoming,~build,factory),Constructor.fallible_construct(~S,~I,~P,~Custom,~identity,~project,~incoming,~build,factory,input))) 39 def selected(~S:Data,~Context:Type,~I:Type,~P:Type,~Custom:Data,~identity:Identity.Declaration,~project:P -> P & D.Raw,~incoming:I -> I & D.Raw,~build:I -> D.Raw -> Build.Construction,~factory:Constructor.FallibleFactory,~supply:Context -> D.Raw -> Context & I,matches:Bool,state:State,position:R.Position,field:D.Field) -> State & R.Dispatch: 40 match matches state field: 41 case False{} state _:(state,R.Unhandled{}) 42 case True{} State{context,records,returned,removed,applied} D.Field{_,raw}:supplied(~S,~Context,~I,~P,~Custom,~identity,~project,~incoming,~build,~factory,position,records,returned,removed,applied,supply(context,raw)) 43 def stage(~S:Data,~Context:Type,~I:Type,~P:Type,~Custom:Data,~identity:Identity.Declaration,~project:P -> P & D.Raw,~incoming:I -> I & D.Raw,~build:I -> D.Raw -> Build.Construction,~factory:Constructor.FallibleFactory,~supply:Context -> D.Raw -> Context & I,~kind:FamilyKind,state:State,+position:R.Position,+field:D.Field) -> State & R.Dispatch: 44 match field: 45 case D.Field{+name,+raw}:selected(~S,~Context,~I,~P,~Custom,~identity,~project,~incoming,~build,~factory,~supply,Bool.and(same_kind(kind,position),String.eq(name,Identity.key(~S,~P,identity))),state,position,D.Field{name,raw}) 46 def released(~I:Type,~P:Type,head:I,rest:List) -> List: 47 List.append(&1,I,rest,[head]) 48 def release_records(~I:Type,~P:Type,records:List>,returned:List) -> List: 49 match records: 50 case []:returned 51 case Record{_,owner,undo} <> rest:release_records(~I,~P,rest,undo(owner) <> returned) 52 def release(~Context:Type,~I:Type,~P:Type,state:State) -> State: 53 match state: 54 case State{context,records,returned,removed,applied}:State{context,[],release_records(~I,~P,records,returned),removed,applied} 55 def empty(~Context:Type,~I:Type,~P:Type,context:Context) -> State: 56 State{context,[],[],[],[]} 57 def commit(~Context:Type,~I:Type,~P:Type,state:State) -> State: 58 match state: 59 case State{context,_,_,_,_}:State{context,[],[],[],[]} 60 def take_recovery(~Context:Type,~I:Type,~P:Type,state:State) -> State & List: 61 match state: 62 case State{context,records,returned,removed,applied}:(State{context,records,[],removed,applied},returned)