# A flat live certificate: depth plus one equality word. Its equation identifies # the owner with a balanced normalization of its proof-only tree observation. # Proof trees occur only under equality rewrites and are erased from native code. import Base import ../traversal_array.bend as Traversal import ./storage_tree_model.bend as Tree import ./storage_witness.bend as Witness def first(-Element: Data,tree: Tree.Tree) -> Element: match tree: case Tree.Leaf{value}: value case Tree.Node{left,right}: first(Element,left) def left(-Element: Data,tree: Tree.Tree) -> Tree.Tree: match tree: case Tree.Leaf{value}: Tree.Leaf{value} case Tree.Node{left,right}: left def right(-Element: Data,tree: Tree.Tree) -> Tree.Tree: match tree: case Tree.Leaf{value}: Tree.Leaf{value} case Tree.Node{left,right}: right def normalized(-Element: Data,depth: Nat,+tree: Tree.Tree) -> Tree.Tree: match depth: case 0n: Tree.Leaf{first(Element,tree)} case 1n+ +rest: Tree.Node{normalized(Element,rest,left(Element,tree)),normalized(Element,rest,right(Element,tree))} def normalized_witness(-Element: Data,+depth: Nat,-tree: Tree.Tree) -> Witness.Witness(Element,depth,Tree.pack(Element,normalized(Element,depth,tree))): match depth: case 0n: Witness.Leaf{first(Element,tree),{==}} case 1n+ +rest: Witness.Node{Tree.pack(Element,normalized(Element,rest,left(Element,tree))), Tree.pack(Element,normalized(Element,rest,right(Element,tree))),{==}, normalized_witness(Element,rest,left(Element,tree)),normalized_witness(Element,rest,right(Element,tree))} def restored(-Element: Data,+depth: Nat,-storage: Array,witness: Witness.Witness(Element,depth,storage)) -> {Tree.pack(Element,normalized(Element,depth,Tree.reflect(Element,storage))) == storage : Array}: match depth witness: case 0n Witness.Leaf{value,owner}: %Equal.sym(Array,storage,ALeaf{value},owner) : {Tree.pack(Element,normalized(Element,0n,Tree.reflect(Element,_))) == _ : Array} {==} case 1n+ +rest Witness.Node{left,right,owner,left_balanced,right_balanced}: %Equal.sym(Array,storage,ANode{left,right},owner) : {Tree.pack(Element,normalized(Element,1n+rest,Tree.reflect(Element,_))) == _ : Array} %restored(Element,rest,left,left_balanced) : {ANode{Tree.pack(Element,normalized(Element,rest,Tree.reflect(Element,left))), Tree.pack(Element,normalized(Element,rest,Tree.reflect(Element,right)))} == ANode{_,right} : Array} %restored(Element,rest,right,right_balanced) : {ANode{Tree.pack(Element,normalized(Element,rest,Tree.reflect(Element,left))), Tree.pack(Element,normalized(Element,rest,Tree.reflect(Element,right)))} == ANode{Tree.pack(Element,normalized(Element,rest,Tree.reflect(Element,left))),_} : Array} {==} type Certificate<-Element: Data,-storage: Array> is Data: Certificate{depth: Nat,equation: {storage == Tree.pack(Element,normalized(Element,depth,Tree.reflect(Element,storage))) : Array}} def witness_at(-Element: Data,+depth: Nat,-storage: Array, equation: {storage == Tree.pack(Element,normalized(Element,depth,Tree.reflect(Element,storage))) : Array}) -> Witness.Witness(Element,depth,storage): %Equal.sym(Array,storage,Tree.pack(Element,normalized(Element,depth,Tree.reflect(Element,storage))),equation) : Witness.Witness(Element,depth,_) normalized_witness(Element,depth,Tree.reflect(Element,storage)) def witness(-Element: Data,-storage: Array,certificate: Certificate) -> Witness.ArrayWitness: Certificate{+depth,equation} = certificate %Equal.sym(Array,storage,Tree.pack(Element,normalized(Element,depth,Tree.reflect(Element,storage))),equation) : Witness.ArrayWitness Witness.ArrayWitness{depth,normalized_witness(Element,depth,Tree.reflect(Element,storage))} def fresh_equation(-Element: Data,+depth: Nat,value: Element) -> {Array.new(Element,depth,value) == Tree.pack(Element,normalized(Element,depth,Tree.reflect(Element,Array.new(Element,depth,value)))) : Array}: %restored(Element,depth,Array.new(Element,depth,value),Witness.fresh(Element,depth,value)) : {_ == Tree.pack(Element,normalized(Element,depth,Tree.reflect(Element,Array.new(Element,depth,value)))) : Array} {==} def allocated(-Element: Data,+depth: Nat,value: Element) -> Certificate: Certificate{depth,fresh_equation(Element,depth,value)} def stored_equation(-Element: Data,+depth: Nat,-storage: Array,+index: U32,-value: Element, equation: {storage == Tree.pack(Element,normalized(Element,depth,Tree.reflect(Element,storage))) : Array}) -> {Array.set(Element,storage,index,value) == Tree.pack(Element,normalized(Element,depth,Tree.reflect(Element,Array.set(Element,storage,index,value)))) : Array}: %restored(Element,depth,Array.set(Element,storage,index,value), Witness.write(Element,depth,storage,index,value, witness_at(Element,depth,storage,equation))) : {_ == Tree.pack(Element,normalized(Element,depth,Tree.reflect(Element,Array.set(Element,storage,index,value)))) : Array} {==} def stored(-Element: Data,-storage: Array,index: U32,-value: Element,certificate: Certificate) -> Certificate: Certificate{+depth,equation} = certificate Certificate{depth,stored_equation(Element,depth,storage,index,value,equation)} def family(~Element: Data,-storage: Array) -> Data: Certificate def written(~Element: Data,+depth: Nat,values: List<&2,Element>,+offset: U32,-storage: Array, evidence: Witness.Witness(Element,depth,storage)) -> Witness.Witness(Element,depth,Traversal.write_list(~Element,values,offset,storage)): match values: case []: evidence case head <> tail: written(~Element,depth,tail,(offset + 1 : U32),Array.set(Element,storage,offset,head),Witness.write(Element,depth,storage,offset,head,evidence)) def written_equation(~Element: Data,+depth: Nat,values: List<&2,Element>,offset: U32,-storage: Array, equation: {storage == Tree.pack(Element,normalized(Element,depth,Tree.reflect(Element,storage))) : Array}) -> {Traversal.write_list(~Element,values,offset,storage) == Tree.pack(Element,normalized(Element,depth,Tree.reflect(Element,Traversal.write_list(~Element,values,offset,storage)))) : Array}: %restored(Element,depth,Traversal.write_list(~Element,values,offset,storage), written(~Element,depth,values,offset,storage,witness_at(Element,depth,storage,equation))) : {_ == Tree.pack(Element,normalized(Element,depth,Tree.reflect(Element,Traversal.write_list(~Element,values,offset,storage)))) : Array} {==} def write_list(~Element: Data,values: List<&2,Element>,offset: U32,-storage: Array,certificate: Certificate) -> Certificate: Certificate{+depth,equation} = certificate Certificate{depth,written_equation(~Element,depth,values,offset,storage,equation)}