~/bend-docscommunity

proofs/lib/links.bend source

proofs/lib/links.bend on the hub · documented module

import Baseimport ../../src/containers/hash_table.bend as Himport ./u32.bend as UWimport ../../spec/lib/common.bend as SCimport ./nat_list.bend as NLimport ./logic.bend as Limport ./nat.bend as Nimport ./u32div.bend as UDimport ./words32.bend as W32import ./word.bend as WD# Ids linked through U32 words: lnk(s) is the link word of slot s, fst_or and# last_or the link of a list's first and last id (or a default), and how they# behave over appends and reversed appends.def lnk(+s: Nat) -> U32:  H.link(U32.from_nat(s))def fst_or(t: List<&2, Nat>, +q: U32) -> U32:  match t:    case Nil{}:      q    case Con{+s, t2}:      lnk(s)def last_or(t: List<&2, Nat>, +p: U32) -> U32:  match t:    case Nil{}:      p    case Con{+s, +t2}:      last_or(t2, lnk(s))def u_refl(+x: U32) -> {U32.is_eq(x, x) == True{} : Bool}:  UW.u32_eq_refl(x)def fst_app(+a: List<&2, Nat>, +b: List<&2, Nat>, +q: U32) -> {fst_or(SC.append(Nat, a, b), q) == fst_or(a, fst_or(b, q)) : U32}:  match a:    case Nil{}:      {==}    case Con{+h, +t}:      {==}def last_app(+a: List<&2, Nat>, +b: List<&2, Nat>, +p: U32) -> {last_or(SC.append(Nat, a, b), p) == last_or(b, last_or(a, p)) : U32}:  match a:    case Nil{}:      {==}    case Con{+h, +t}:      last_app(t, b, lnk(h))def last_lnk(+t: List<&2, Nat>, +a: Nat) -> {last_or(t, lnk(a)) == lnk(NL.lastn(t, a)) : U32}:  match t:    case Nil{}:      {==}    case Con{+b, +t2}:      last_lnk(t2, b)def fo_rapp(+l: List<&2, Nat>, +b: List<&2, Nat>, +d: U32) -> {fst_or(NL.rapp(l, b), d) == last_or(l, fst_or(b, d)) : U32}:  match l:    case Nil{}:      {==}    case Con{+x, +r}:      fo_rapp(r, Con{x, b}, d)def slot_link(+one: Nat, +h1: {one == 1n : Nat}, +s: U32, +hs: {Nat.is_lt(1n+UD.v(s), WD.sc(32n, one)) == True{} : Bool}) -> {UD.v(H.slot(H.link(s))) == UD.v(s) : Nat}:  +lv = W32.link_val(one, h1, s, hs)  +hle = L.subst(Nat, z => {Nat.is_le(1n, z) == True{} : Bool}, 1n+UD.v(s), UD.v(H.link(s)), Equal.sym(Nat, UD.v(H.link(s)), 1n+UD.v(s), lv), N.zero_le(UD.v(s)))  Equal.trans(Nat, UD.v(H.slot(H.link(s))), Nat.sub(UD.v(H.link(s)), 1n), UD.v(s), UW.sub_nat(H.link(s), 1, hle), Equal.trans(Nat, Nat.sub(UD.v(H.link(s)), 1n), Nat.sub(1n+UD.v(s), 1n), UD.v(s), Equal.cong(Nat, Nat, z => Nat.sub(z, 1n), UD.v(H.link(s)), 1n+UD.v(s), lv), N.sub_zero(UD.v(s))))def slot_lnk(+one: Nat, +h1: {one == 1n : Nat}, +s: Nat, +sd: Nat, +hsd: {Nat.is_lt(1n+sd, 32n) == True{} : Bool}, +hs: {Nat.is_lt(s, SC.pow2(sd)) == True{} : Bool}) -> {UD.v(H.slot(lnk(s))) == s : Nat}:  +hk = N.lt_le(sd, 32n, N.lt_trans(sd, 1n+sd, 32n, N.lt_succ(sd), hsd))  +e1 = UW.to_nat_from_nat(s, sd, hk, hs)  +hs2 = L.subst(Nat, z => {Nat.is_lt(z, SC.pow2(sd)) == True{} : Bool}, s, UD.v(U32.from_nat(s)), Equal.sym(Nat, UD.v(U32.from_nat(s)), s, e1), hs)  Equal.trans(Nat, UD.v(H.slot(lnk(s))), UD.v(U32.from_nat(s)), s, slot_link(one, h1, U32.from_nat(s), W32.bound32(one, h1, UD.v(U32.from_nat(s)), sd, hsd, hs2)), e1)