1 import Base 2 import entity_key_render.bend as KeyText 3 import ./ordinary_app_composer.bend as Build 4 import ./ordinary_app_recipe.bend as Tree 5 import ./ordinary_app_observation_data.bend as DTO 6 import ./ordinary_app_registration_fields.bend as Fields 7 import ./world.bend as W 8 import ./inspector.bend as I 9 import ./relation_failure_reader.bend as Ord 10 import ./relation_types.bend as G 11 import ./relation_commands.bend as A 12 import ./relation_query.bend as RQ 13 import ./relation_providers.bend as P 14 import ./inspector_relation_projection.bend as IR 15 import ./inspector_query.bend as IQ 16 import ./inspector_query_projection.bend as Select 17 import ./transaction.bend as T 18 import ./commands.bend as Cmd 19 20 # One trusted ordinary relation declaration drives operational grants and view. 21 # Trusted setup projection of the retained relation declaration. The descriptor 22 # selects operational authority; presentation strings do not create another grant. 23 def descriptor(~S:Data,declaration:Ord.Declaration) -> G.Descriptor: 24 match declaration: 25 case Ord.Declaration{value}:value 26 def kind(value:G.RelationKind) -> String: 27 match value: 28 case G.Ordinary{}:"Ordinary" 29 case G.Hierarchy{}:"Hierarchy" 30 def descriptor_text(~S:Data,value:G.Descriptor) -> String: 31 match value: 32 case G.Descriptor{key,name,inverseName,tag}:"Relation{key=" ++ U32.show(key) ++ "|name=" ++ name ++ "|inverse=" ++ inverseName ++ "|kind=" ++ kind(tag) ++ "}" 33 def declared_spec(~S:Data,+value:G.Descriptor) -> RQ.Spec: 34 match value: 35 case G.Descriptor{+key,+name,+inverseName,+tag}:RQ.Spec{[RQ.optional_relation(~S,name,G.Descriptor{key,name,inverseName,tag}),RQ.optional_related(~S,inverseName,G.Descriptor{key,name,inverseName,tag})]} 36 # Inspector setup for optional outgoing and inverse cells of this declaration. 37 # Optional cells retain unlinked entities rather than requiring an existing edge. 38 def spec(~S:Data,declaration:Ord.Declaration) -> RQ.Spec: 39 match declaration: 40 case Ord.Declaration{+value}:declared_spec(~S,value) 41 # Advanced storage projection: relation edges wrap C and relation notices wrap E. 42 # The World remains an affine owner threaded through every App operation. 43 def World(~S:Data,~C:Type,~R:Type,~E:Data) -> Type: 44 W.World,R,A.Notice> 45 # Detached inspector row containing an entity handle and optional relation cells. 46 def Row(~S:Data) -> Data: 47 IQ.ProjectedRow>>> 48 # Detached relation observation: the declared descriptor and ordered inspector rows. 49 # This Data value does not grant access to the underlying World or inverse storage. 50 type View is Data: 51 View{descriptor:G.Descriptor,rows:List<&2,Row(~S)>} 52 # Advanced observation shape pairing prior rows with the added relation view. 53 def ObservedRows(~S:Data,~Rows:Data) -> Data: 54 DTO.Product> 55 def handle(~S:Data,value:W.Handle) -> String: 56 match value: 57 case W.Handle{ns,id}:U32.show(ns) ++ ":" ++ KeyText.show(id) 58 def relation_value(~S:Data,value:RQ.Value) -> String: 59 match value: 60 case RQ.Missing{}:"Missing" 61 case RQ.Target{target}:"Target:" ++ handle(~S,target) 62 case RQ.Sources{targets}:"Sources:" ++ List.show(&2,W.Handle,handle(~S),targets) 63 def end(value:RQ.End) -> String: 64 match value: 65 case RQ.Outgoing{}:"Outgoing" 66 case RQ.Incoming{}:"Incoming" 67 def cell(~S:Data,value:RQ.Cell) -> String: 68 match value: 69 case RQ.Cell{key,direction,value}:key ++ ":" ++ end(direction) ++ ":" ++ relation_value(~S,value) 70 # Default textual presentation of a detached row; it does not perform a query. 71 def builtin_row(~S:Data,value:Row(~S)) -> String: 72 match value: 73 case IQ.ProjectedRow{entity,Select.Product{_,cells}}:handle(~S,entity) ++ ":" ++ List.show(&2,RQ.Cell,cell(~S),cells) 74 def rendered(~S:Data,~render:Row(~S) -> String,rows:List<&2,Row(~S)>) -> List<&2,String>: 75 match rows: 76 case []:[] 77 case first <> rest:render(first) <> rendered(~S,~render,rest) 78 def presented(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration,~render:Row(~S) -> String,result:I.Frame,R,A.Notice> & List<&2,Row(~S)>) -> World(~S,~C,~R,~E) & DTO.Observation>: 79 match result: 80 case (I.Frame{world,_},+rows):(world,DTO.Observation{View{descriptor(~S,declaration),rows},descriptor_text(~S,descriptor(~S,declaration)) <> rendered(~S,~render,rows)}) 81 # Read a fresh relation inspector view while returning the World owner. 82 # Uses a fresh inspector cursor; it does not advance a registered gameplay reader 83 # or apply queued commands. The renderer consumes detached rows only. 84 def observe(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration,~render:Row(~S) -> String,world:World(~S,~C,~R,~E)) -> World(~S,~C,~R,~E) & DTO.Observation>: 85 presented(~S,~C,~R,~E,~declaration,~render,IQ.each_composed(~I.Frame,R,A.Notice>,~S,~Select.Product>>,~IR.grant(~S,~C,~R,~E,~Unit,~Select.empty(~I.Frame,R,A.Notice>,~S),~spec(~S,declaration)),I.Frame{world,None{}})) 86 # Advanced recipe adapter: retain the prior observation, then append this view. 87 # The shared World owner is passed through both observers in that order. 88 def observation(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration,~render:Row(~S) -> String,~Owners:Type,~Rows:Data,~prior:World(~S,~C,~R,~E) -> World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>) -> World(~S,~C,~R,~E) -> World(~S,~C,~R,~E) & DTO.Observation: 89 Tree.observe_pair(~World(~S,~C,~R,~E),~Rows,~View,~prior,~observe(~S,~C,~R,~E,~declaration,~render)) 90 # Advanced App type with a caller-supplied detached-row renderer. World, 91 # registration owners and the combined observation recipe remain inside the App. 92 def presented_Application(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration,~render:Row(~S) -> String,~Owners:Type,~Rows:Data,~prior:World(~S,~C,~R,~E) -> World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>) -> Type: 93 Build.Registered,~prior,~observe(~S,~C,~R,~E,~declaration,~render)),fold> 94 # Advanced recipe type for prior rows followed by the custom relation view. 95 def presented_Recipe(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration,~render:Row(~S) -> String,~Owners:Type,~Rows:Data,~prior:World(~S,~C,~R,~E) -> World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>) -> Type: 96 Tree.Recipe,~prior,~observe(~S,~C,~R,~E,~declaration,~render))> 97 # Install the custom relation observation recipe, preserving World, registration 98 # owners and debug state. This does not create edges or register a gameplay system. 99 def presented_install(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration,~render:Row(~S) -> String,~Owners:Type,~Rows:Data,~prior:World(~S,~C,~R,~E) -> World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,app:Build.Registered) -> presented_Application(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold): 100 match app: 101 case Build.Registered{world,owners,_,debug}:Build.Registered{world,owners,Tree.Recipe{},debug} 102 # Set observation enablement from flag, then snapshot through the installed recipe. 103 # Returns the App in both cases; disabled observation returns None. 104 def presented_snapshot_app(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration,~render:Row(~S) -> String,~Owners:Type,~Rows:Data,~prior:World(~S,~C,~R,~E) -> World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,app:presented_Application(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold),flag:Bool) -> presented_Application(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold) & Maybe<&2,DTO.Product>,DTO.Observation>>: 105 Build.snapshot(~S,~World(~S,~C,~R,~E),~Owners,~ObservedRows(~S,~Rows),~Tree.observe_pair(~World(~S,~C,~R,~E),~Rows,~View,~prior,~observe(~S,~C,~R,~E,~declaration,~render)),~fold,Build.enabled(~S,~World(~S,~C,~R,~E),~Owners,~ObservedRows(~S,~Rows),~Tree.observe_pair(~World(~S,~C,~R,~E),~Rows,~View,~prior,~observe(~S,~C,~R,~E,~declaration,~render)),~fold,app,flag)) 106 def returned(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration,~render:Row(~S) -> String,~Owners:Type,~Rows:Data,~prior:World(~S,~C,~R,~E) -> World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,~Error:Data,owners:Owners,recipe:presented_Recipe(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold),debug:Bool,result:T.Returned) -> presented_Application(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold) & T.Outcome: 107 match result: 108 case T.Returned{world,status}:(Build.Registered{world,owners,recipe,debug},status) 109 def queue_finished(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration,~render:Row(~S) -> String,~Owners:Type,~Rows:Data,~prior:World(~S,~C,~R,~E) -> World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,~Error:Data,status:A.QueueStatus,result:presented_Application(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold) & T.Outcome) -> presented_Application(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold) & DTO.Product>: 110 match result: 111 case (app,outcome):(app,DTO.Product{status,outcome}) 112 def queued(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration,~render:Row(~S) -> String,~Owners:Type,~Rows:Data,~prior:World(~S,~C,~R,~E) -> World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,~Error:Data,owners:Owners,recipe:presented_Recipe(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold),debug:Bool,outcome:T.Outcome,result:T.Tx> & A.QueueStatus) -> presented_Application(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold) & DTO.Product>: 113 match result: 114 case (frame,+status):queue_finished(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold,~Error,status,returned(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold,~Error,owners,recipe,debug,Cmd.tx_finish(~S,~A.Store,~R,~A.Notice,~Error,frame,outcome))) 115 # Stage source-to-target replacement under this declaration, then finish the 116 # transaction with the supplied outcome. Return the App, queue status and outcome 117 # separately: Queued is not barrier application success. Failure discards staged 118 # commands; barrier-time structural rejection is reported through relation notices. 119 def presented_relate_app(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration,~render:Row(~S) -> String,~Owners:Type,~Rows:Data,~prior:World(~S,~C,~R,~E) -> World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,~Error:Data,app:presented_Application(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold),targets:P.Targets,outcome:T.Outcome) -> presented_Application(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold) & DTO.Product>: 120 match app: 121 case Build.Registered{world,owners,recipe,debug}:queued(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold,~Error,owners,recipe,debug,outcome,P.relate(~T.Tx>,~S,~P.provide_write(~S,~C,~R,~E,~descriptor(~S,declaration)),T.begin(~World(~S,~C,~R,~E),~A.Notice,world),targets)) 122 # Stage removal of this source relation and finish with the supplied outcome. 123 # Returns App plus queue status and transaction outcome; successful staging remains 124 # invisible to graph reads until a barrier, and transaction failure discards it. 125 def presented_unrelate_app(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration,~render:Row(~S) -> String,~Owners:Type,~Rows:Data,~prior:World(~S,~C,~R,~E) -> World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,~Error:Data,app:presented_Application(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold),source:W.Handle,outcome:T.Outcome) -> presented_Application(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold) & DTO.Product>: 126 match app: 127 case Build.Registered{world,owners,recipe,debug}:queued(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold,~Error,owners,recipe,debug,outcome,P.unrelate(~T.Tx>,~S,~P.provide_write(~S,~C,~R,~E,~descriptor(~S,declaration)),T.begin(~World(~S,~C,~R,~E),~A.Notice,world),source)) 128 def inverse_finished(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration,~render:Row(~S) -> String,~Owners:Type,~Rows:Data,~prior:World(~S,~C,~R,~E) -> World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,value:Maybe<&2,List<&2,W.Handle>>,result:presented_Application(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold) & T.Outcome) -> presented_Application(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold) & Maybe<&2,List<&2,W.Handle>>: 129 match result: 130 case (app,_):(app,value) 131 def inverse_taken(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration,~render:Row(~S) -> String,~Owners:Type,~Rows:Data,~prior:World(~S,~C,~R,~E) -> World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,owners:Owners,recipe:presented_Recipe(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold),debug:Bool,result:T.Tx> & Maybe<&2,List<&2,W.Handle>>) -> presented_Application(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold) & Maybe<&2,List<&2,W.Handle>>: 132 match result: 133 case (frame,value):inverse_finished(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold,value,returned(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold,~Unit,owners,recipe,debug,Cmd.tx_finish(~S,~A.Store,~R,~A.Notice,~Unit,frame,T.Success{}))) 134 # Read the current inverse list in stored order and return the App owner. None 135 # denotes an invalid target; Some may contain an empty list. Pending commands are 136 # not applied, and this read does not offer direct inverse-list mutation. 137 def presented_inverse_app(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration,~render:Row(~S) -> String,~Owners:Type,~Rows:Data,~prior:World(~S,~C,~R,~E) -> World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,app:presented_Application(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold),target:W.Handle) -> presented_Application(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold) & Maybe<&2,List<&2,W.Handle>>: 138 match app: 139 case Build.Registered{world,owners,recipe,debug}:inverse_taken(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold,owners,recipe,debug,P.read(~T.Tx>,~S,~P.provide_read(~S,~C,~R,~E,~descriptor(~S,declaration)),T.begin(~World(~S,~C,~R,~E),~A.Notice,world),target)) 140 # Apply the World structural barrier, returning the App with its owners and recipe. 141 # This drains pending World commands, not only commands for this declaration; 142 # structural relation failures are published as notices by their command handlers. 143 def presented_barrier_app(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration,~render:Row(~S) -> String,~Owners:Type,~Rows:Data,~prior:World(~S,~C,~R,~E) -> World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,app:presented_Application(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold)) -> presented_Application(~S,~C,~R,~E,~declaration,~render,~Owners,~Rows,~prior,~fold): 144 match app: 145 case Build.Registered{world,owners,recipe,debug}:Build.Registered{W.barrier(~S,~A.Store,~R,~A.Notice,world),owners,recipe,debug} 146 # Ordinary relation App using builtin_row presentation and the retained declaration. 147 def Application(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration,~Owners:Type,~Rows:Data,~prior:World(~S,~C,~R,~E) -> World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>) -> Type: 148 presented_Application(~S,~C,~R,~E,~declaration,~builtin_row(~S),~Owners,~Rows,~prior,~fold) 149 150 # Advanced default-renderer recipe projection for composing typed App adapters. 151 def Recipe(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration,~Owners:Type,~Rows:Data,~prior:World(~S,~C,~R,~E) -> World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>) -> Type: 152 presented_Recipe(~S,~C,~R,~E,~declaration,~builtin_row(~S),~Owners,~Rows,~prior,~fold) 153 154 # Install the default relation observer without changing graph edges or owners. 155 # Typical order: install, relate_app with a successful outcome, barrier_app, then 156 # inverse_app or snapshot_app. See docs/parity/relations.md for accepted scenarios. 157 def install(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration,~Owners:Type,~Rows:Data,~prior:World(~S,~C,~R,~E) -> World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,app:Build.Registered) -> Application(~S,~C,~R,~E,~declaration,~Owners,~Rows,~prior,~fold): 158 presented_install(~S,~C,~R,~E,~declaration,~builtin_row(~S),~Owners,~Rows,~prior,~fold,app) 159 160 # Default-renderer snapshot; flag controls observation and the App is returned 161 # even when the observation is disabled (None). Does not apply pending commands. 162 def snapshot_app(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration,~Owners:Type,~Rows:Data,~prior:World(~S,~C,~R,~E) -> World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,app:Application(~S,~C,~R,~E,~declaration,~Owners,~Rows,~prior,~fold),flag:Bool) -> Application(~S,~C,~R,~E,~declaration,~Owners,~Rows,~prior,~fold) & Maybe<&2,DTO.Product>,DTO.Observation>>: 163 presented_snapshot_app(~S,~C,~R,~E,~declaration,~builtin_row(~S),~Owners,~Rows,~prior,~fold,app,flag) 164 165 # Default-renderer source-to-target request. Returns queue status separately from 166 # the supplied transaction outcome; call barrier_app before expecting graph changes. 167 def relate_app(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration,~Owners:Type,~Rows:Data,~prior:World(~S,~C,~R,~E) -> World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,~Error:Data,app:Application(~S,~C,~R,~E,~declaration,~Owners,~Rows,~prior,~fold),targets:P.Targets,outcome:T.Outcome) -> Application(~S,~C,~R,~E,~declaration,~Owners,~Rows,~prior,~fold) & DTO.Product>: 168 presented_relate_app(~S,~C,~R,~E,~declaration,~builtin_row(~S),~Owners,~Rows,~prior,~fold,~Error,app,targets,outcome) 169 170 # Default-renderer source removal request. The App is returned on refusal or 171 # transaction failure; staging and barrier-time relation validity remain distinct. 172 def unrelate_app(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration,~Owners:Type,~Rows:Data,~prior:World(~S,~C,~R,~E) -> World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,~Error:Data,app:Application(~S,~C,~R,~E,~declaration,~Owners,~Rows,~prior,~fold),source:W.Handle,outcome:T.Outcome) -> Application(~S,~C,~R,~E,~declaration,~Owners,~Rows,~prior,~fold) & DTO.Product>: 173 presented_unrelate_app(~S,~C,~R,~E,~declaration,~builtin_row(~S),~Owners,~Rows,~prior,~fold,~Error,app,source,outcome) 174 175 # Default-renderer inverse read, returning the App and Maybe ordered source handles. 176 # Reads the current graph; pending additions and removals require a barrier first. 177 def inverse_app(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration,~Owners:Type,~Rows:Data,~prior:World(~S,~C,~R,~E) -> World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,app:Application(~S,~C,~R,~E,~declaration,~Owners,~Rows,~prior,~fold),target:W.Handle) -> Application(~S,~C,~R,~E,~declaration,~Owners,~Rows,~prior,~fold) & Maybe<&2,List<&2,W.Handle>>: 178 presented_inverse_app(~S,~C,~R,~E,~declaration,~builtin_row(~S),~Owners,~Rows,~prior,~fold,app,target) 179 180 # Default-renderer structural barrier for all pending commands in this World. 181 def barrier_app(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration,~Owners:Type,~Rows:Data,~prior:World(~S,~C,~R,~E) -> World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,app:Application(~S,~C,~R,~E,~declaration,~Owners,~Rows,~prior,~fold)) -> Application(~S,~C,~R,~E,~declaration,~Owners,~Rows,~prior,~fold): 182 presented_barrier_app(~S,~C,~R,~E,~declaration,~builtin_row(~S),~Owners,~Rows,~prior,~fold,app)