# eukhe: lemmas of the doc_commit entry proofs: the wire primitives # # Each decoder answers Got{x, rest} only for the spelling of x before # rest (dcw.nat, dcw.str: wire_nat_exact, wire_str_exact, and a too long # count refused by wire_nat_too_long); the round trips turned around to # rewrite a decode of a spelling into its value; a count or a length # never opens with 'E'. import Base import ../../../bend/wire.bend as Wr import ../../../laws/base.bend as LawsBase import ../../../laws/wire.bend as Wire import ../../wire/wire_nat_exact.bend as PWireNatExact import ../../wire/wire_nat_decoded_fits.bend as PWireNatDecodedFits import ../../wire/wire_nat_too_long.bend as PWireNatTooLong import ../../wire/wire_nat_not_err.bend as PWireNatNotErr import ../../wire/wire_str_exact.bend as PWireStrExact import ../../wire/wire_bool_exact.bend as PWireBoolExact import ../../wire/wire_bool_round_trip.bend as PWireBoolRoundTrip import ../../base/wire.bend as LWire import ../../base/logic/string.bend as LLogicString def dcw.DT(-A: Data, d: Wr.Dec, G: Type) -> Type: match d: case Wr.Got{x, r}: Unit case Wr.Bad{}: G # a decoder answered Got and Bad def dcw.got_bad(-A: Data, -G: Type, -x: A, -r: String, e: {Wr.Got{x, r} == Wr.Bad{} : Wr.Dec}) -> G: %e : dcw.DT(A, _, G) Unit{} # s is the tag t then s1, and s1 is x: s is the tag t then x def dcw.after(-s: String, +t: Nat, -s1: String, -x: String, pre: {s == Wr.put_nat(t, s1) : String}, e: {s1 == x : String}) -> {s == Wr.put_nat(t, x) : String}: Equal.trans(String, s, Wr.put_nat(t, s1), Wr.put_nat(t, x), pre, Equal.cong(String, String, z => Wr.put_nat(t, z), s1, x, e)) def dcw.NP(s: String, d: Wr.Dec) -> Type: match d: case Wr.Got{n, r}: {s == Wr.put_nat(n, r) : String} case Wr.Bad{}: Unit def dcw.nat.at(+s: String, d: Wr.Dec, ed: {Wr.get_nat(s) == d : Wr.Dec}) -> dcw.NP(s, d): match d: case Wr.Got{+n, +r}: Wire.wire_nat_exact(s, n, r, ed) case Wr.Bad{}: Unit{} # a Nat decoded is spelled def dcw.nat(+s: String) -> dcw.NP(s, Wr.get_nat(s)): dcw.nat.at(s, Wr.get_nat(s), {==}) # a decoded string's length fits: a longer one's count is refused def dcw.str_fits.at(b: Bool, +s: String, +a: String, +r: String, eb: {LawsBase.wire_fits(String.length(a)) == b : Bool}, e1: {s == Wr.put_str(a, r) : String}, ed: {Wr.get_str(s) == Wr.Got{a, r} : Wr.Dec}) -> {LawsBase.wire_fits(String.length(a)) == True{} : Bool}: match b: case True{}: eb case False{}: +x = LLogicString.wr_app(a, r) +c1 = Equal.trans(Wr.Dec, Wr.Got{a, r}, Wr.get_str(s), Wr.get_str(Wr.put_str(a, r)), Equal.sym(Wr.Dec, Wr.get_str(s), Wr.Got{a, r}, ed), Equal.cong(String, Wr.Dec, z => Wr.get_str(z), s, Wr.put_str(a, r), e1)) +c2 = Equal.trans(Wr.Dec, Wr.Got{a, r}, Wr.get_str(Wr.put_str(a, r)), Wr.get_str(Wr.put_nat(String.length(a), x)), c1, Equal.cong(String, Wr.Dec, z => Wr.get_str(z), Wr.put_str(a, r), Wr.put_nat(String.length(a), x), LWire.wr_put_str(a, r))) +c3 = Equal.trans(Wr.Dec, Wr.Got{a, r}, Wr.get_str(Wr.put_nat(String.length(a), x)), Wr.Bad{}, c2, Equal.cong(Wr.Dec, Wr.Dec, z => Wr.get_str.go(z), Wr.get_nat(Wr.put_nat(String.length(a), x)), Wr.Bad{}, Wire.wire_nat_too_long(String.length(a), x, eb))) dcw.got_bad(String, {LawsBase.wire_fits(String.length(a)) == True{} : Bool}, a, r, c3) def dcw.SP(s: String, d: Wr.Dec) -> Type: match d: case Wr.Got{a, r}: {s == Wr.put_str(a, r) : String} & {LawsBase.wire_fits(String.length(a)) == True{} : Bool} case Wr.Bad{}: Unit def dcw.str.at(+s: String, d: Wr.Dec, ed: {Wr.get_str(s) == d : Wr.Dec}) -> dcw.SP(s, d): match d: case Wr.Got{+a, +r}: +e2 = ed +e1 = Wire.wire_str_exact(s, a, r, e2) (e1, dcw.str_fits.at(LawsBase.wire_fits(String.length(a)), s, a, r, {==}, e1, e2)) case Wr.Bad{}: Unit{} # a string decoded is spelled, and its length fits def dcw.str(+s: String) -> dcw.SP(s, Wr.get_str(s)): dcw.str.at(s, Wr.get_str(s), {==}) # a string that fits reads back (wire_str_round_trip, turned around) def dcw.str_back(+a: String, +rest: String, h: {LawsBase.wire_fits(String.length(a)) == True{} : Bool}) -> {Wr.Got{a, rest} == Wr.get_str(Wr.put_str(a, rest)) : Wr.Dec}: Equal.sym(Wr.Dec, Wr.get_str(Wr.put_str(a, rest)), Wr.Got{a, rest}, Wire.wire_str_round_trip(a, rest, h)) # a Bool reads back (wire_bool_round_trip, turned around) def dcw.bool_back(+b: Bool, +rest: String) -> {Wr.Got{b, rest} == Wr.get_bool(Wr.put_bool(b, rest)) : Wr.Dec}: Equal.sym(Wr.Dec, Wr.get_bool(Wr.put_bool(b, rest)), Wr.Got{b, rest}, Wire.wire_bool_round_trip(b, rest)) # a list's spelling opens with its count: never 'E' def dcw.fin_ok(p: Nat & String) -> {LawsBase.wire_opens_err(Wr.put_list.fin(p)) == False{} : Bool}: match p: case (n, s): Wire.wire_nat_not_err(n, s) # a string's spelling opens with its length: never 'E' def dcw.sfin_ok(p: Nat & String, rest: String) -> {LawsBase.wire_opens_err(Wr.put_str.fin(p, rest)) == False{} : Bool}: match p: case (n, b): Wire.wire_nat_not_err(n, String.reverse.go(b, rest))