~/bend-docscommunity

libs/wire/deps/int.bend source

libs/wire/deps/int.bend on the hub · documented module

# Fixed-width integers U8, U16, U64, I32 and I64: wrapping, checked and saturating arithmetic, and text in radix 2 to 36.import Base# The Int.* core serves only U64 and I64. When Base ships a native U64 (bendlang/bend#1027), delete it.def Int.bits.go(n: Nat, qr: Nat & Nat) -> Word(n):    match n:        case 0n:            WNil{}        case 1n+p:            (q, r) = qr            WCon{Nat.is_eq(r, 1n), Int.bits.go(p, Nat.divmod(q, 2n))}# The low n bits of k: k mod 2^n.def Int.bits(n: Nat, k: Nat) -> Word(n):    Int.bits.go(n, Nat.divmod(k, 2n))def Int.msb.go(n: Nat, b: Bool, w: Word(n)) -> Bool:    match n:        case 0n:            b        case 1n+p:            match w:                case WCon{h, t}:                    Int.msb.go(p, h, t)def Int.msb(n: Nat, w: Word(n)) -> Bool:    Int.msb.go(n, False{}, w)def Int.put_msb.bit(p: Nat, v: Bool, b: Bool) -> Bool:    match p:        case 0n:            v        case 1n+q:            bdef Int.put_msb(+n: Nat, +v: Bool, w: Word(n)) -> Word(n):    match n:        case 0n:            WNil{}        case 1n+p:            match w:                case WCon{b, t}:                    WCon{Int.put_msb.bit(p, v, b), Int.put_msb(p, v, t)}def Int.ext(m: Nat, n: Nat, +fill: Bool, w: Word(n)) -> Word(m):    match m:        case 0n:            WNil{}        case 1n+p:            match n:                case 0n:                    WCon{fill, Int.ext(p, 0n, fill, WNil{})}                case 1n+q:                    match w:                        case WCon{b, t}:                            WCon{b, Int.ext(p, q, fill, t)}def Int.ones(+n: Nat) -> Word(n):    Word.not(n, Word.zero(n))def Int.min(+n: Nat, s: Bool) -> Word(n):    match s:        case True{}:            Int.put_msb(n, True{}, Word.zero(n))        case False{}:            Word.zero(n)def Int.max(+n: Nat, s: Bool) -> Word(n):    match s:        case True{}:            Int.put_msb(n, False{}, Int.ones(n))        case False{}:            Int.ones(n)def Int.is_eq(+n: Nat, a: Word(n), b: Word(n)) -> Bool:    Cmp.is_eq(Word.cmp(n, a, b))def Int.is_zero(+n: Nat, w: Word(n)) -> Bool:    Int.is_eq(n, w, Word.zero(n))def Int.cmp(+n: Nat, s: Bool, a: Word(n), b: Word(n)) -> Cmp:    match s:        case True{}:            Word.cmp(n, Word.xor(n, a, Int.min(n, True{})),                Word.xor(n, b, Int.min(n, True{})))        case False{}:            Word.cmp(n, a, b)def Int.neg(+n: Nat, w: Word(n)) -> Word(n):    Word.sub(n, Word.zero(n), w)def Int.neg_if(+n: Nat, c: Bool, w: Word(n)) -> Word(n):    match c:        case True{}:            Int.neg(n, w)        case False{}:            wdef Int.abs(+n: Nat, +w: Word(n)) -> Word(n):    Int.neg_if(n, Int.msb(n, w), w)def Int.udivmod.fin(-p: Nat,                    q: Word(p),                    +n: Nat,                    s: Word(n),                    b: Word(n),                    g: Bool) -> Word(1n+p) & Word(n):    match g:        case True{}:            (WCon{True{}, q}, Word.sub(n, s, b))        case False{}:            (WCon{False{}, q}, s)def Int.udivmod.shl(-p: Nat,                    q: Word(p),                    +n: Nat,                    +b: Word(n),                    ts: Bool & Word(n)) -> Word(1n+p) & Word(n):    (t, s) = ts    +s2 = {s : Word(n)}    Int.udivmod.fin(p, q, n, s2, b, Bool.or(t, Cmp.is_ge(Word.cmp(n, s2, b))))def Int.udivmod.rec(-p: Nat,                    a0: Bool,                    +n: Nat,                    +b: Word(n),                    qr: Word(p) & Word(n)) -> Word(1n+p) & Word(n):    (q, r) = qr    Int.udivmod.shl(p, q, n, b, Word.shl.out(n, a0, r))def Int.udivmod.go(m: Nat, a: Word(m), +n: Nat, +b: Word(n)) -> Word(m) & Word(n):    match m a:        case 0n WNil{}:            (WNil{}, Word.zero(n))        case 1n+p WCon{a0, hi}:            Int.udivmod.rec(p, a0, n, b, Int.udivmod.go(p, hi, n, b))def Int.sdivmod.fix(+n: Nat, +na: Bool, nb: Bool, qr: Word(n) & Word(n)) -> Word(n) & Word(n):    (q, r) = qr    (Int.neg_if(n, Bool.xor(na, nb), q), Int.neg_if(n, na, r))# x / 0 is 0 and x % 0 is x, as in Base's U32. MIN / -1 wraps to MIN.def Int.divmod.if(z: Bool, s: Bool, +n: Nat, +a: Word(n), +b: Word(n)) -> Word(n) & Word(n):    match z:        case True{}:            (Word.zero(n), a)        case False{}:            match s:                case True{}:                    Int.sdivmod.fix(n, Int.msb(n, a), Int.msb(n, b),                        Int.udivmod.go(n, Int.abs(n, a), n, Int.abs(n, b)))                case False{}:                    Int.udivmod.go(n, a, n, b)def Int.divmod(+n: Nat, s: Bool, a: Word(n), +b: Word(n)) -> Word(n) & Word(n):    Int.divmod.if(Int.is_zero(n, b), s, n, a, b)def Int.fst(-n: Nat, p: Word(n) & Word(n)) -> Word(n):    (q, r) = p    qdef Int.snd(-n: Nat, p: Word(n) & Word(n)) -> Word(n):    (q, r) = p    rdef Int.div(+n: Nat, s: Bool, a: Word(n), b: Word(n)) -> Word(n):    Int.fst(n, Int.divmod(n, s, a, b))def Int.mod(+n: Nat, s: Bool, a: Word(n), b: Word(n)) -> Word(n):    Int.snd(n, Int.divmod(n, s, a, b))# True for signed MIN and -1, the one quotient that overflows.def Int.min_neg1(+n: Nat, s: Bool, a: Word(n), b: Word(n)) -> Bool:    match s:        case True{}:            Bool.and(Int.is_eq(n, a, Int.min(n, True{})),                Int.is_eq(n, b, Int.ones(n)))        case False{}:            False{}def Int.div_ov(+n: Nat, s: Bool, a: Word(n), +b: Word(n)) -> Bool:    Bool.or(Int.is_zero(n, b), Int.min_neg1(n, s, a, b))def Int.add_ov.go(+n: Nat, s: Bool, a: Word(n), b: Word(n), +r: Word(n)) -> Bool & Word(n):    match s:        case True{}:            (Int.msb(n, Word.and(n, Word.xor(n, a, r), Word.xor(n, b, r))), r)        case False{}:            (Cmp.is_lt(Word.cmp(n, r, a)), r)def Int.add_ov(+n: Nat, s: Bool, +a: Word(n), +b: Word(n)) -> Bool & Word(n):    Int.add_ov.go(n, s, a, b, Word.add(n, a, b))def Int.sub_ov.go(+n: Nat, s: Bool, +a: Word(n), b: Word(n), +r: Word(n)) -> Bool & Word(n):    match s:        case True{}:            (Int.msb(n, Word.and(n, Word.xor(n, a, b), Word.xor(n, a, r))), r)        case False{}:            (Cmp.is_lt(Word.cmp(n, a, b)), r)def Int.sub_ov(+n: Nat, s: Bool, +a: Word(n), +b: Word(n)) -> Bool & Word(n):    Int.sub_ov.go(n, s, a, b, Word.sub(n, a, b))def Int.mul_ov.go(+n: Nat, +s: Bool, +a: Word(n), +b: Word(n), +r: Word(n)) -> Bool & Word(n):    (Bool.or(Bool.and(Bool.not(Int.is_zero(n, b)),        Bool.not(Int.is_eq(n, Int.div(n, s, r, b), a))),        Int.min_neg1(n, s, a, b)), r)def Int.mul_ov(+n: Nat, s: Bool, +a: Word(n), +b: Word(n)) -> Bool & Word(n):    Int.mul_ov.go(n, s, a, b, Word.mul(n, a, b))def Int.checked(-n: Nat, o: Bool & Word(n)) -> Maybe<&2, Word(n)>:    (ov, r) = o    match ov:        case True{}:            None{}        case False{}:            Some{r}def Int.checked_div(+n: Nat, +s: Bool, +a: Word(n), +b: Word(n)) -> Maybe<&2, Word(n)>:    Int.checked(n, (Int.div_ov(n, s, a, b), Int.div(n, s, a, b)))def Int.checked_mod(+n: Nat, +s: Bool, +a: Word(n), +b: Word(n)) -> Maybe<&2, Word(n)>:    Int.checked(n, (Int.div_ov(n, s, a, b), Int.mod(n, s, a, b)))def Int.sat(low: Bool, +n: Nat, s: Bool) -> Word(n):    match low:        case True{}:            Int.min(n, s)        case False{}:            Int.max(n, s)def Int.saturate(+n: Nat, s: Bool, low: Bool, o: Bool & Word(n)) -> Word(n):    (ov, r) = o    match ov:        case True{}:            Int.sat(low, n, s)        case False{}:            rdef Int.saturating_add(+n: Nat, +s: Bool, +a: Word(n), b: Word(n)) -> Word(n):    Int.saturate(n, s, Bool.and(s, Int.msb(n, a)), Int.add_ov(n, s, a, b))def Int.saturating_sub(+n: Nat, +s: Bool, +a: Word(n), b: Word(n)) -> Word(n):    Int.saturate(n, s, Bool.or(Bool.not(s), Int.msb(n, a)),        Int.sub_ov(n, s, a, b))def Int.saturating_mul(+n: Nat, +s: Bool, +a: Word(n), +b: Word(n)) -> Word(n):    Int.saturate(n, s, Bool.and(s, Bool.xor(Int.msb(n, a), Int.msb(n, b))),        Int.mul_ov(n, s, a, b))def Int.shl(+n: Nat, k: Nat, w: Word(n)) -> Word(n):    match k:        case 0n:            w        case 1n+j:            Int.shl(n, j, Word.shl(n, w))# Signed shifts right are arithmetic: the sign bit fills in from the top.def Int.shr1(+n: Nat, s: Bool, +w: Word(n)) -> Word(n):    match s:        case True{}:            Int.put_msb(n, Int.msb(n, w), Word.shr(n, w))        case False{}:            Word.shr(n, w)def Int.shr(+n: Nat, +s: Bool, k: Nat, w: Word(n)) -> Word(n):    match k:        case 0n:            w        case 1n+j:            Int.shr(n, s, j, Int.shr1(n, s, w))# Digit d below 36 as '0'..'9', then 'a'..'z'.def Radix.digit.if(lo: Bool, d: U32) -> Char:    match lo:        case True{}:            Chr{U32.add(48, d)}        case False{}:            Chr{U32.add(87, d)}def Radix.digit(+d: U32) -> Char:    Radix.digit.if(U32.is_lt(d, 10), d)def Radix.in(+c: U32, lo: U32, hi: U32) -> Bool:    Bool.and(U32.is_ge(c, lo), U32.is_le(c, hi))def Radix.value.lower(ok: Bool, c: U32) -> U32:    match ok:        case True{}:            U32.sub(c, 87)        case False{}:            36def Radix.value.upper(ok: Bool, +c: U32) -> U32:    match ok:        case True{}:            U32.sub(c, 55)        case False{}:            Radix.value.lower(Radix.in(c, 97, 122), c)def Radix.value.if(ok: Bool, +c: U32) -> U32:    match ok:        case True{}:            U32.sub(c, 48)        case False{}:            Radix.value.upper(Radix.in(c, 65, 90), c)# The value of a digit in either case, or 36 when c is not a digit.def Radix.value(+c: U32) -> U32:    Radix.value.if(Radix.in(c, 48, 57), c)def Radix.clamp(r: U32) -> U32:    U32.clamp(r, 2, 36)def Radix.ok(+r: U32) -> Bool:    Radix.in(r, 2, 36)def Radix.sign.if(neg: Bool, pos: Bool, c: Char, t: String) -> Bool & String:    match neg:        case True{}:            (True{}, t)        case False{}:            match pos:                case True{}:                    (False{}, t)                case False{}:                    (False{}, SCon{c, t})# Splits one leading '-' or '+' off s: (negative, rest).def Radix.sign(s: String) -> Bool & String:    match s:        case SNil{}:            (False{}, SNil{})        case SCon{Chr{x}, t}:            +c = {x : U32}            Radix.sign.if(U32.is_eq(c, 45), U32.is_eq(c, 43), Chr{c}, t)# z is set once the value left to print is zero; fuel n bounds the digits.def Int.show.go(f: Nat,                +n: Nat,                +b: Word(n),                acc: String,                z: Bool,                qr: Word(n) & Word(n)) -> String:    match f:        case 0n:            acc        case 1n+g:            match z:                case True{}:                    acc                case False{}:                    (q, r) = qr                    +q2 = {q : Word(n)}                    Int.show.go(g, n, b,                        SCon{Radix.digit(U32.from_nat(Word.to_nat(n, r))), acc},                        Int.is_zero(n, q2), Int.udivmod.go(n, q2, n, b))def Int.show.u(+n: Nat, +b: Word(n), w: Word(n)) -> String:    Int.show.go(n, n, b, SNil{}, False{}, Int.udivmod.go(n, w, n, b))def Int.show.if(neg: Bool, +n: Nat, +b: Word(n), w: Word(n)) -> String:    match neg:        case True{}:            SCon{Chr{45}, Int.show.u(n, b, Int.neg(n, w))}        case False{}:            Int.show.u(n, b, w)def Int.show(+n: Nat, s: Bool, r: U32, +w: Word(n)) -> String:    match s:        case True{}:            Int.show.if(Int.msb(n, w), n, Int.bits(n, U32.to_nat(Radix.clamp(r))), w)        case False{}:            Int.show.u(n, Int.bits(n, U32.to_nat(Radix.clamp(r))), w)def Int.read.add(+n: Nat, d: Word(n), o: Bool & Word(n)) -> Maybe<&2, Word(n)>:    (ov, m) = o    match ov:        case True{}:            None{}        case False{}:            Int.checked(n, Int.add_ov(n, False{}, m, d))def Int.read.dig(ok: Bool, +n: Nat, +b: Word(n), acc: Word(n), d: U32) -> Maybe<&2, Word(n)>:    match ok:        case True{}:            Int.read.add(n, Int.bits(n, U32.to_nat(d)), Int.mul_ov(n, False{}, acc, b))        case False{}:            None{}def Int.read.step(+n: Nat,                  +b: Word(n),                  +r: U32,                  st: Maybe<&2, Word(n)>,                  x: U32) -> Maybe<&2, Word(n)>:    match st:        case None{}:            None{}        case Some{acc}:            +d = {Radix.value(x) : U32}            Int.read.dig(U32.is_lt(d, r), n, b, acc, d)def Int.read.go(s: String,                +n: Nat,                +b: Word(n),                +r: U32,                st: Maybe<&2, Word(n)>) -> Maybe<&2, Word(n)>:    match s:        case SNil{}:            st        case SCon{Chr{x}, t}:            Int.read.go(t, n, b, r, Int.read.step(n, b, r, st, x))def Int.read.u(+n: Nat, +b: Word(n), +r: U32, s: String) -> Maybe<&2, Word(n)>:    match s:        case SNil{}:            None{}        case SCon{h, t}:            Int.read.go(SCon{h, t}, n, b, r, Some{Word.zero(n)})def Int.read.fit(bad: Bool, -n: Nat, w: Word(n)) -> Maybe<&2, Word(n)>:    match bad:        case True{}:            None{}        case False{}:            Some{w}def Int.read.pos(+n: Nat, m: Maybe<&2, Word(n)>) -> Maybe<&2, Word(n)>:    match m:        case None{}:            None{}        case Some{w}:            +v = {w : Word(n)}            Int.read.fit(Int.msb(n, v), n, v)def Int.read.neg(+n: Nat, m: Maybe<&2, Word(n)>) -> Maybe<&2, Word(n)>:    match m:        case None{}:            None{}        case Some{w}:            +v = {w : Word(n)}            Int.read.fit(Cmp.is_gt(Word.cmp(n, v, Int.min(n, True{}))), n,                Int.neg(n, v))def Int.read.sign(s: Bool,                  neg: Bool,                  +n: Nat,                  +b: Word(n),                  +r: U32,                  t: String) -> Maybe<&2, Word(n)>:    match s:        case True{}:            match neg:                case True{}:                    Int.read.neg(n, Int.read.u(n, b, r, t))                case False{}:                    Int.read.pos(n, Int.read.u(n, b, r, t))        case False{}:            match neg:                case True{}:                    None{}                case False{}:                    Int.read.u(n, b, r, t)def Int.read.split(s: Bool, +n: Nat, +r: U32, p: Bool & String) -> Maybe<&2, Word(n)>:    (neg, t) = p    Int.read.sign(s, neg, n, Int.bits(n, U32.to_nat(r)), r, t)def Int.read.if(ok: Bool, +n: Nat, s: Bool, +r: U32, str: String) -> Maybe<&2, Word(n)>:    match ok:        case True{}:            Int.read.split(s, n, r, Radix.sign(str))        case False{}:            None{}def Int.read(+n: Nat, s: Bool, +r: U32, str: String) -> Maybe<&2, Word(n)>:    Int.read.if(Radix.ok(r), n, s, r, str)def Int.to_nat.s(neg: Bool, n: Nat, w: Word(n)) -> Maybe<&2, Nat>:    match neg:        case True{}:            None{}        case False{}:            Some{Word.to_nat(n, w)}# Signed values below zero have no Nat.def Int.to_nat(+n: Nat, +w: Word(n)) -> Maybe<&2, Nat>:    Int.to_nat.s(Int.msb(n, w), n, w)def Int.sext(m: Nat, +n: Nat, +w: Word(n)) -> Word(m):    Int.ext(m, n, Int.msb(n, w), w)# U8 and U16 hold their value in a U32 below 2^w, and m is 2^w - 1.def Nar.opt(ov: Bool, r: U32) -> Maybe<&2, U32>:    match ov:        case True{}:            None{}        case False{}:            Some{r}def Nar.over(+m: U32, +r: U32) -> Maybe<&2, U32>:    Nar.opt(U32.is_gt(r, m), r)def Nar.checked_sub(+a: U32, +b: U32) -> Maybe<&2, U32>:    Nar.opt(U32.is_lt(a, b), U32.sub(a, b))def Nar.checked_div(a: U32, +b: U32) -> Maybe<&2, U32>:    Nar.opt(U32.is_zero(b), U32.div(a, b))def Nar.checked_mod(a: U32, +b: U32) -> Maybe<&2, U32>:    Nar.opt(U32.is_zero(b), U32.mod(a, b))def Nar.sat_sub(lt: Bool, a: U32, b: U32) -> U32:    match lt:        case True{}:            0        case False{}:            U32.sub(a, b)def Nar.saturating_sub(+a: U32, +b: U32) -> U32:    Nar.sat_sub(U32.is_lt(a, b), a, b)# Digits of x in radix r, most significant first; fuel f bounds them.def Nar.show.go(f: Nat, +r: U32, acc: String, z: Bool, +x: U32) -> String:    match f:        case 0n:            acc        case 1n+g:            match z:                case True{}:                    acc                case False{}:                    +q = {U32.div(x, r) : U32}                    Nar.show.go(g, r, SCon{Radix.digit(U32.mod(x, r)), acc},                        U32.is_zero(q), q)def Nar.show(r: U32, x: U32) -> String:    Nar.show.go(32n, Radix.clamp(r), SNil{}, False{}, x)def Nar.read.dig(ok: Bool, +r: U32, acc: U32, d: U32) -> Maybe<&2, U32>:    match ok:        case True{}:            Some{U32.add(U32.mul(acc, r), d)}        case False{}:            None{}# acc * r + d stays at most m exactly when acc <= (m - d) / r.def Nar.read.step(+r: U32, +m: U32, st: Maybe<&2, U32>, x: U32) -> Maybe<&2, U32>:    match st:        case None{}:            None{}        case Some{acc}:            +a = {acc : U32}            +d = {Radix.value(x) : U32}            Nar.read.dig(Bool.and(U32.is_lt(d, r),                U32.is_le(a, U32.div(U32.sub(m, d), r))), r, a, d)def Nar.read.go(s: String, +r: U32, +m: U32, st: Maybe<&2, U32>) -> Maybe<&2, U32>:    match s:        case SNil{}:            st        case SCon{Chr{x}, t}:            Nar.read.go(t, r, m, Nar.read.step(r, m, st, x))# Digits in radix r, at most m; no sign.def Nar.read.u(+r: U32, +m: U32, s: String) -> Maybe<&2, U32>:    match s:        case SNil{}:            None{}        case SCon{h, t}:            Nar.read.go(SCon{h, t}, r, m, Some{0})def Nar.read.split(+r: U32, +m: U32, p: Bool & String) -> Maybe<&2, U32>:    (neg, t) = p    match neg:        case True{}:            None{}        case False{}:            Nar.read.u(r, m, t)def Nar.read.if(ok: Bool, +r: U32, +m: U32, s: String) -> Maybe<&2, U32>:    match ok:        case True{}:            Nar.read.split(r, m, Radix.sign(s))        case False{}:            None{}def Nar.read(+r: U32, +m: U32, s: String) -> Maybe<&2, U32>:    Nar.read.if(Radix.ok(r), r, m, s)# I32 holds its two's-complement bits in a U32.def S32.MIN() -> U32:    2147483648def S32.is_neg(x: U32) -> Bool:    U32.is_ge(x, S32.MIN())def S32.neg(x: U32) -> U32:    U32.sub(0, x)def S32.neg_if(c: Bool, x: U32) -> U32:    match c:        case True{}:            S32.neg(x)        case False{}:            xdef S32.abs(+x: U32) -> U32:    S32.neg_if(S32.is_neg(x), x)def S32.cmp(a: U32, b: U32) -> Cmp:    U32.cmp(U32.xor(a, S32.MIN()), U32.xor(b, S32.MIN()))# x / 0 is 0 and x % 0 is x, as in Base's U32. MIN / -1 wraps to MIN.def S32.divmod.if(z: Bool, +a: U32, +b: U32) -> U32 & U32:    match z:        case True{}:            (0, a)        case False{}:            (S32.neg_if(Bool.xor(S32.is_neg(a), S32.is_neg(b)),                U32.div(S32.abs(a), S32.abs(b))),                S32.neg_if(S32.is_neg(a), U32.mod(S32.abs(a), S32.abs(b))))def S32.fst(p: U32 & U32) -> U32:    (q, r) = p    qdef S32.snd(p: U32 & U32) -> U32:    (q, r) = p    rdef S32.div(a: U32, +b: U32) -> U32:    S32.fst(S32.divmod.if(U32.is_zero(b), a, b))def S32.mod(a: U32, +b: U32) -> U32:    S32.snd(S32.divmod.if(U32.is_zero(b), a, b))# True for MIN and -1, the one quotient that overflows.def S32.min_neg1(a: U32, b: U32) -> Bool:    Bool.and(U32.is_eq(a, S32.MIN()), U32.is_eq(b, 4294967295))def S32.div_ov(+a: U32, +b: U32) -> Bool:    Bool.or(U32.is_zero(b), S32.min_neg1(a, b))def S32.add_ov.go(a: U32, b: U32, +r: U32) -> Bool & U32:    (S32.is_neg(U32.and(U32.xor(a, r), U32.xor(b, r))), r)def S32.add_ov(+a: U32, +b: U32) -> Bool & U32:    S32.add_ov.go(a, b, U32.add(a, b))def S32.sub_ov.go(+a: U32, b: U32, +r: U32) -> Bool & U32:    (S32.is_neg(U32.and(U32.xor(a, b), U32.xor(a, r))), r)def S32.sub_ov(+a: U32, +b: U32) -> Bool & U32:    S32.sub_ov.go(a, b, U32.sub(a, b))def S32.mul_ov.go(+a: U32, +b: U32, +r: U32) -> Bool & U32:    (Bool.or(Bool.and(Bool.not(U32.is_zero(b)),        Bool.not(U32.is_eq(S32.div(r, b), a))), S32.min_neg1(a, b)), r)def S32.mul_ov(+a: U32, +b: U32) -> Bool & U32:    S32.mul_ov.go(a, b, U32.mul(a, b))def S32.checked(o: Bool & U32) -> Maybe<&2, U32>:    (ov, r) = o    Nar.opt(ov, r)def S32.checked_div(+a: U32, +b: U32) -> Maybe<&2, U32>:    Nar.opt(S32.div_ov(a, b), S32.div(a, b))def S32.checked_mod(+a: U32, +b: U32) -> Maybe<&2, U32>:    Nar.opt(S32.div_ov(a, b), S32.mod(a, b))def S32.sat(low: Bool) -> U32:    match low:        case True{}:            S32.MIN()        case False{}:            2147483647def S32.saturate(low: Bool, o: Bool & U32) -> U32:    (ov, r) = o    match ov:        case True{}:            S32.sat(low)        case False{}:            r# Shifts right are arithmetic: the sign bit fills in from the top.def S32.shr.if(neg: Bool, x: U32, k: Nat) -> U32:    match neg:        case True{}:            U32.not(U32.shrn(U32.not(x), k))        case False{}:            U32.shrn(x, k)def S32.show.if(neg: Bool, r: U32, x: U32) -> String:    match neg:        case True{}:            SCon{Chr{45}, Nar.show(r, S32.neg(x))}        case False{}:            Nar.show(r, x)def S32.read.neg(m: Maybe<&2, U32>) -> Maybe<&2, U32>:    match m:        case None{}:            None{}        case Some{x}:            Some{S32.neg(x)}def S32.read.split(+r: U32, p: Bool & String) -> Maybe<&2, U32>:    (neg, t) = p    match neg:        case True{}:            S32.read.neg(Nar.read.u(r, S32.MIN(), t))        case False{}:            Nar.read.u(r, 2147483647, t)def S32.read.if(ok: Bool, +r: U32, s: String) -> Maybe<&2, U32>:    match ok:        case True{}:            S32.read.split(r, Radix.sign(s))        case False{}:            None{}def S32.read(+r: U32, s: String) -> Maybe<&2, U32>:    S32.read.if(Radix.ok(r), r, s)def S32.to_nat.if(neg: Bool, x: U32) -> Maybe<&2, Nat>:    match neg:        case True{}:            None{}        case False{}:            Some{U32.to_nat(x)}# r is the radix. Show clamps it into 2..36; read rejects one outside it.def U32.show_radix(r: U32, x: U32) -> String:    Nar.show(r, x)def U32.read_radix(+r: U32, s: String) -> Maybe<&2, U32>:    Nar.read(r, 4294967295, s)type U8 is Data:    U8{data: U32}def U8.some(m: Maybe<&2, U32>) -> Maybe<&2, U8>:    match m:        case None{}:            None{}        case Some{x}:            Some{U8{x}}def U8.MIN() -> U8:    U8{0}def U8.MAX() -> U8:    U8{255}def U8.add(a: U8, b: U8) -> U8:    match a b:        case U8{x} U8{y}:            U8{U32.and(U32.add(x, y), 255)}def U8.sub(a: U8, b: U8) -> U8:    match a b:        case U8{x} U8{y}:            U8{U32.and(U32.sub(x, y), 255)}def U8.mul(a: U8, b: U8) -> U8:    match a b:        case U8{x} U8{y}:            U8{U32.and(U32.mul(x, y), 255)}def U8.and(a: U8, b: U8) -> U8:    match a b:        case U8{x} U8{y}:            U8{U32.and(x, y)}def U8.or(a: U8, b: U8) -> U8:    match a b:        case U8{x} U8{y}:            U8{U32.or(x, y)}def U8.xor(a: U8, b: U8) -> U8:    match a b:        case U8{x} U8{y}:            U8{U32.xor(x, y)}def U8.div(a: U8, b: U8) -> U8:    match a b:        case U8{x} U8{y}:            U8{U32.div(x, y)}def U8.mod(a: U8, b: U8) -> U8:    match a b:        case U8{x} U8{y}:            U8{U32.mod(x, y)}def U8.checked_add(a: U8, b: U8) -> Maybe<&2, U8>:    match a b:        case U8{x} U8{y}:            U8.some(Nar.over(255, U32.add(x, y)))def U8.checked_sub(a: U8, b: U8) -> Maybe<&2, U8>:    match a b:        case U8{x} U8{y}:            U8.some(Nar.checked_sub(x, y))def U8.checked_mul(a: U8, b: U8) -> Maybe<&2, U8>:    match a b:        case U8{x} U8{y}:            U8.some(Nar.over(255, U32.mul(x, y)))def U8.checked_div(a: U8, b: U8) -> Maybe<&2, U8>:    match a b:        case U8{x} U8{y}:            U8.some(Nar.checked_div(x, y))def U8.checked_mod(a: U8, b: U8) -> Maybe<&2, U8>:    match a b:        case U8{x} U8{y}:            U8.some(Nar.checked_mod(x, y))def U8.saturating_add(a: U8, b: U8) -> U8:    match a b:        case U8{x} U8{y}:            U8{U32.min(U32.add(x, y), 255)}def U8.saturating_sub(a: U8, b: U8) -> U8:    match a b:        case U8{x} U8{y}:            U8{Nar.saturating_sub(x, y)}def U8.saturating_mul(a: U8, b: U8) -> U8:    match a b:        case U8{x} U8{y}:            U8{U32.min(U32.mul(x, y), 255)}def U8.cmp(a: U8, b: U8) -> Cmp:    match a b:        case U8{x} U8{y}:            U32.cmp(x, y)def U8.is_eq(a: U8, b: U8) -> Bool:    Cmp.is_eq(U8.cmp(a, b))def U8.is_lt(a: U8, b: U8) -> Bool:    Cmp.is_lt(U8.cmp(a, b))def U8.is_le(a: U8, b: U8) -> Bool:    Cmp.is_le(U8.cmp(a, b))def U8.is_gt(a: U8, b: U8) -> Bool:    Cmp.is_gt(U8.cmp(a, b))def U8.is_ge(a: U8, b: U8) -> Bool:    Cmp.is_ge(U8.cmp(a, b))def U8.is_ne(a: U8, b: U8) -> Bool:    Bool.not(Cmp.is_eq(U8.cmp(a, b)))def U8.is_zero(a: U8) -> Bool:    match a:        case U8{x}:            U32.is_zero(x)def U8.not(a: U8) -> U8:    match a:        case U8{x}:            U8{U32.xor(x, 255)}def U8.shl(a: U8, k: Nat) -> U8:    match a:        case U8{x}:            U8{U32.and(U32.shln(x, k), 255)}def U8.shr(a: U8, k: Nat) -> U8:    match a:        case U8{x}:            U8{U32.shrn(x, k)}def U8.show_radix(r: U32, a: U8) -> String:    match a:        case U8{x}:            Nar.show(r, x)def U8.show(a: U8) -> String:    U8.show_radix(10, a)def U8.read_radix(r: U32, s: String) -> Maybe<&2, U8>:    U8.some(Nar.read(r, 255, s))def U8.read(s: String) -> Maybe<&2, U8>:    U8.read_radix(10, s)def U8.to_u32(a: U8) -> U32:    match a:        case U8{x}:            xdef U8.from_u32(a: U32) -> U8:    U8{U32.and(a, 255)}def U8.to_nat(a: U8) -> Nat:    match a:        case U8{x}:            U32.to_nat(x)def U8.from_nat(k: Nat) -> U8:    U8{U32.and(U32.from_nat(k), 255)}type U16 is Data:    U16{data: U32}def U16.some(m: Maybe<&2, U32>) -> Maybe<&2, U16>:    match m:        case None{}:            None{}        case Some{x}:            Some{U16{x}}def U16.MIN() -> U16:    U16{0}def U16.MAX() -> U16:    U16{65535}def U16.add(a: U16, b: U16) -> U16:    match a b:        case U16{x} U16{y}:            U16{U32.and(U32.add(x, y), 65535)}def U16.sub(a: U16, b: U16) -> U16:    match a b:        case U16{x} U16{y}:            U16{U32.and(U32.sub(x, y), 65535)}def U16.mul(a: U16, b: U16) -> U16:    match a b:        case U16{x} U16{y}:            U16{U32.and(U32.mul(x, y), 65535)}def U16.and(a: U16, b: U16) -> U16:    match a b:        case U16{x} U16{y}:            U16{U32.and(x, y)}def U16.or(a: U16, b: U16) -> U16:    match a b:        case U16{x} U16{y}:            U16{U32.or(x, y)}def U16.xor(a: U16, b: U16) -> U16:    match a b:        case U16{x} U16{y}:            U16{U32.xor(x, y)}def U16.div(a: U16, b: U16) -> U16:    match a b:        case U16{x} U16{y}:            U16{U32.div(x, y)}def U16.mod(a: U16, b: U16) -> U16:    match a b:        case U16{x} U16{y}:            U16{U32.mod(x, y)}def U16.checked_add(a: U16, b: U16) -> Maybe<&2, U16>:    match a b:        case U16{x} U16{y}:            U16.some(Nar.over(65535, U32.add(x, y)))def U16.checked_sub(a: U16, b: U16) -> Maybe<&2, U16>:    match a b:        case U16{x} U16{y}:            U16.some(Nar.checked_sub(x, y))def U16.checked_mul(a: U16, b: U16) -> Maybe<&2, U16>:    match a b:        case U16{x} U16{y}:            U16.some(Nar.over(65535, U32.mul(x, y)))def U16.checked_div(a: U16, b: U16) -> Maybe<&2, U16>:    match a b:        case U16{x} U16{y}:            U16.some(Nar.checked_div(x, y))def U16.checked_mod(a: U16, b: U16) -> Maybe<&2, U16>:    match a b:        case U16{x} U16{y}:            U16.some(Nar.checked_mod(x, y))def U16.saturating_add(a: U16, b: U16) -> U16:    match a b:        case U16{x} U16{y}:            U16{U32.min(U32.add(x, y), 65535)}def U16.saturating_sub(a: U16, b: U16) -> U16:    match a b:        case U16{x} U16{y}:            U16{Nar.saturating_sub(x, y)}def U16.saturating_mul(a: U16, b: U16) -> U16:    match a b:        case U16{x} U16{y}:            U16{U32.min(U32.mul(x, y), 65535)}def U16.cmp(a: U16, b: U16) -> Cmp:    match a b:        case U16{x} U16{y}:            U32.cmp(x, y)def U16.is_eq(a: U16, b: U16) -> Bool:    Cmp.is_eq(U16.cmp(a, b))def U16.is_lt(a: U16, b: U16) -> Bool:    Cmp.is_lt(U16.cmp(a, b))def U16.is_le(a: U16, b: U16) -> Bool:    Cmp.is_le(U16.cmp(a, b))def U16.is_gt(a: U16, b: U16) -> Bool:    Cmp.is_gt(U16.cmp(a, b))def U16.is_ge(a: U16, b: U16) -> Bool:    Cmp.is_ge(U16.cmp(a, b))def U16.is_ne(a: U16, b: U16) -> Bool:    Bool.not(Cmp.is_eq(U16.cmp(a, b)))def U16.is_zero(a: U16) -> Bool:    match a:        case U16{x}:            U32.is_zero(x)def U16.not(a: U16) -> U16:    match a:        case U16{x}:            U16{U32.xor(x, 65535)}def U16.shl(a: U16, k: Nat) -> U16:    match a:        case U16{x}:            U16{U32.and(U32.shln(x, k), 65535)}def U16.shr(a: U16, k: Nat) -> U16:    match a:        case U16{x}:            U16{U32.shrn(x, k)}def U16.show_radix(r: U32, a: U16) -> String:    match a:        case U16{x}:            Nar.show(r, x)def U16.show(a: U16) -> String:    U16.show_radix(10, a)def U16.read_radix(r: U32, s: String) -> Maybe<&2, U16>:    U16.some(Nar.read(r, 65535, s))def U16.read(s: String) -> Maybe<&2, U16>:    U16.read_radix(10, s)def U16.to_u32(a: U16) -> U32:    match a:        case U16{x}:            xdef U16.from_u32(a: U32) -> U16:    U16{U32.and(a, 65535)}def U16.to_nat(a: U16) -> Nat:    match a:        case U16{x}:            U32.to_nat(x)def U16.from_nat(k: Nat) -> U16:    U16{U32.and(U32.from_nat(k), 65535)}# ponytail: Word(64n) costs about 68 us per op. When Base ships a native U64# (bendlang/bend#1027), store Base's U64 here, as U8 and U16 store Base's U32.type U64 is Data:    U64{data: Word(64n)}def U64.some(m: Maybe<&2, Word(64n)>) -> Maybe<&2, U64>:    match m:        case None{}:            None{}        case Some{x}:            Some{U64{x}}def U64.MIN() -> U64:    U64{Int.min(64n, False{})}def U64.MAX() -> U64:    U64{Int.max(64n, False{})}def U64.add(a: U64, b: U64) -> U64:    match a b:        case U64{x} U64{y}:            U64{Word.add(64n, x, y)}def U64.sub(a: U64, b: U64) -> U64:    match a b:        case U64{x} U64{y}:            U64{Word.sub(64n, x, y)}def U64.mul(a: U64, b: U64) -> U64:    match a b:        case U64{x} U64{y}:            U64{Word.mul(64n, x, y)}def U64.and(a: U64, b: U64) -> U64:    match a b:        case U64{x} U64{y}:            U64{Word.and(64n, x, y)}def U64.or(a: U64, b: U64) -> U64:    match a b:        case U64{x} U64{y}:            U64{Word.or(64n, x, y)}def U64.xor(a: U64, b: U64) -> U64:    match a b:        case U64{x} U64{y}:            U64{Word.xor(64n, x, y)}def U64.div(a: U64, b: U64) -> U64:    match a b:        case U64{x} U64{y}:            U64{Int.div(64n, False{}, x, y)}def U64.mod(a: U64, b: U64) -> U64:    match a b:        case U64{x} U64{y}:            U64{Int.mod(64n, False{}, x, y)}def U64.checked_add(a: U64, b: U64) -> Maybe<&2, U64>:    match a b:        case U64{x} U64{y}:            U64.some(Int.checked(64n, Int.add_ov(64n, False{}, x, y)))def U64.checked_sub(a: U64, b: U64) -> Maybe<&2, U64>:    match a b:        case U64{x} U64{y}:            U64.some(Int.checked(64n, Int.sub_ov(64n, False{}, x, y)))def U64.checked_mul(a: U64, b: U64) -> Maybe<&2, U64>:    match a b:        case U64{x} U64{y}:            U64.some(Int.checked(64n, Int.mul_ov(64n, False{}, x, y)))def U64.checked_div(a: U64, b: U64) -> Maybe<&2, U64>:    match a b:        case U64{x} U64{y}:            U64.some(Int.checked_div(64n, False{}, x, y))def U64.checked_mod(a: U64, b: U64) -> Maybe<&2, U64>:    match a b:        case U64{x} U64{y}:            U64.some(Int.checked_mod(64n, False{}, x, y))def U64.saturating_add(a: U64, b: U64) -> U64:    match a b:        case U64{x} U64{y}:            U64{Int.saturating_add(64n, False{}, x, y)}def U64.saturating_sub(a: U64, b: U64) -> U64:    match a b:        case U64{x} U64{y}:            U64{Int.saturating_sub(64n, False{}, x, y)}def U64.saturating_mul(a: U64, b: U64) -> U64:    match a b:        case U64{x} U64{y}:            U64{Int.saturating_mul(64n, False{}, x, y)}def U64.cmp(a: U64, b: U64) -> Cmp:    match a b:        case U64{x} U64{y}:            Int.cmp(64n, False{}, x, y)def U64.is_eq(a: U64, b: U64) -> Bool:    Cmp.is_eq(U64.cmp(a, b))def U64.is_lt(a: U64, b: U64) -> Bool:    Cmp.is_lt(U64.cmp(a, b))def U64.is_le(a: U64, b: U64) -> Bool:    Cmp.is_le(U64.cmp(a, b))def U64.is_gt(a: U64, b: U64) -> Bool:    Cmp.is_gt(U64.cmp(a, b))def U64.is_ge(a: U64, b: U64) -> Bool:    Cmp.is_ge(U64.cmp(a, b))def U64.is_ne(a: U64, b: U64) -> Bool:    Bool.not(Cmp.is_eq(U64.cmp(a, b)))def U64.is_zero(a: U64) -> Bool:    match a:        case U64{x}:            Int.is_zero(64n, x)def U64.not(a: U64) -> U64:    match a:        case U64{x}:            U64{Word.not(64n, x)}def U64.shl(a: U64, k: Nat) -> U64:    match a:        case U64{x}:            U64{Int.shl(64n, k, x)}def U64.shr(a: U64, k: Nat) -> U64:    match a:        case U64{x}:            U64{Int.shr(64n, False{}, k, x)}def U64.show_radix(r: U32, a: U64) -> String:    match a:        case U64{x}:            Int.show(64n, False{}, r, x)def U64.show(a: U64) -> String:    U64.show_radix(10, a)def U64.read_radix(r: U32, s: String) -> Maybe<&2, U64>:    U64.some(Int.read(64n, False{}, r, s))def U64.read(s: String) -> Maybe<&2, U64>:    U64.read_radix(10, s)def U64.to_u32(a: U64) -> U32:    match a:        case U64{x}:            U32{Int.ext(32n, 64n, False{}, x)}def U64.from_u32(a: U32) -> U64:    match a:        case U32{x}:            U64{Int.ext(64n, 32n, False{}, x)}# A native build stops on a Nat past 2^48 - 1, so large U64 values have no native Nat.def U64.to_nat(a: U64) -> Nat:    match a:        case U64{x}:            Word.to_nat(64n, x)def U64.from_nat(k: Nat) -> U64:    U64{Int.bits(64n, k)}type I32 is Data:    I32{data: U32}def I32.some(m: Maybe<&2, U32>) -> Maybe<&2, I32>:    match m:        case None{}:            None{}        case Some{x}:            Some{I32{x}}def I32.MIN() -> I32:    I32{S32.MIN()}def I32.MAX() -> I32:    I32{2147483647}def I32.add(a: I32, b: I32) -> I32:    match a b:        case I32{x} I32{y}:            I32{U32.add(x, y)}def I32.sub(a: I32, b: I32) -> I32:    match a b:        case I32{x} I32{y}:            I32{U32.sub(x, y)}def I32.mul(a: I32, b: I32) -> I32:    match a b:        case I32{x} I32{y}:            I32{U32.mul(x, y)}def I32.and(a: I32, b: I32) -> I32:    match a b:        case I32{x} I32{y}:            I32{U32.and(x, y)}def I32.or(a: I32, b: I32) -> I32:    match a b:        case I32{x} I32{y}:            I32{U32.or(x, y)}def I32.xor(a: I32, b: I32) -> I32:    match a b:        case I32{x} I32{y}:            I32{U32.xor(x, y)}def I32.div(a: I32, b: I32) -> I32:    match a b:        case I32{x} I32{y}:            I32{S32.div(x, y)}def I32.mod(a: I32, b: I32) -> I32:    match a b:        case I32{x} I32{y}:            I32{S32.mod(x, y)}def I32.checked_add(a: I32, b: I32) -> Maybe<&2, I32>:    match a b:        case I32{x} I32{y}:            I32.some(S32.checked(S32.add_ov(x, y)))def I32.checked_sub(a: I32, b: I32) -> Maybe<&2, I32>:    match a b:        case I32{x} I32{y}:            I32.some(S32.checked(S32.sub_ov(x, y)))def I32.checked_mul(a: I32, b: I32) -> Maybe<&2, I32>:    match a b:        case I32{x} I32{y}:            I32.some(S32.checked(S32.mul_ov(x, y)))def I32.checked_div(a: I32, b: I32) -> Maybe<&2, I32>:    match a b:        case I32{x} I32{y}:            I32.some(S32.checked_div(x, y))def I32.checked_mod(a: I32, b: I32) -> Maybe<&2, I32>:    match a b:        case I32{x} I32{y}:            I32.some(S32.checked_mod(x, y))def I32.cmp(a: I32, b: I32) -> Cmp:    match a b:        case I32{x} I32{y}:            S32.cmp(x, y)def I32.saturating_add(a: I32, b: I32) -> I32:    match a b:        case I32{x} I32{y}:            +v = {x : U32}            I32{S32.saturate(S32.is_neg(v), S32.add_ov(v, y))}def I32.saturating_sub(a: I32, b: I32) -> I32:    match a b:        case I32{x} I32{y}:            +v = {x : U32}            I32{S32.saturate(S32.is_neg(v), S32.sub_ov(v, y))}def I32.saturating_mul(a: I32, b: I32) -> I32:    match a b:        case I32{x} I32{y}:            +v = {x : U32}            +w = {y : U32}            I32{S32.saturate(Bool.xor(S32.is_neg(v), S32.is_neg(w)), S32.mul_ov(v, w))}def I32.is_eq(a: I32, b: I32) -> Bool:    Cmp.is_eq(I32.cmp(a, b))def I32.is_lt(a: I32, b: I32) -> Bool:    Cmp.is_lt(I32.cmp(a, b))def I32.is_le(a: I32, b: I32) -> Bool:    Cmp.is_le(I32.cmp(a, b))def I32.is_gt(a: I32, b: I32) -> Bool:    Cmp.is_gt(I32.cmp(a, b))def I32.is_ge(a: I32, b: I32) -> Bool:    Cmp.is_ge(I32.cmp(a, b))def I32.is_ne(a: I32, b: I32) -> Bool:    Bool.not(Cmp.is_eq(I32.cmp(a, b)))def I32.is_zero(a: I32) -> Bool:    match a:        case I32{x}:            U32.is_zero(x)def I32.not(a: I32) -> I32:    match a:        case I32{x}:            I32{U32.not(x)}def I32.shl(a: I32, k: Nat) -> I32:    match a:        case I32{x}:            I32{U32.shln(x, k)}def I32.shr(a: I32, k: Nat) -> I32:    match a:        case I32{x}:            +v = {x : U32}            I32{S32.shr.if(S32.is_neg(v), v, k)}def I32.neg(a: I32) -> I32:    match a:        case I32{x}:            I32{S32.neg(x)}def I32.abs(a: I32) -> I32:    match a:        case I32{x}:            I32{S32.abs(x)}def I32.is_neg(a: I32) -> Bool:    match a:        case I32{x}:            S32.is_neg(x)def I32.show_radix(r: U32, a: I32) -> String:    match a:        case I32{x}:            +v = {x : U32}            S32.show.if(S32.is_neg(v), r, v)def I32.show(a: I32) -> String:    I32.show_radix(10, a)def I32.read_radix(r: U32, s: String) -> Maybe<&2, I32>:    I32.some(S32.read(r, s))def I32.read(s: String) -> Maybe<&2, I32>:    I32.read_radix(10, s)def I32.to_u32(a: I32) -> U32:    match a:        case I32{x}:            xdef I32.from_u32(a: U32) -> I32:    I32{a}def I32.to_nat(a: I32) -> Maybe<&2, Nat>:    match a:        case I32{x}:            +v = {x : U32}            S32.to_nat.if(S32.is_neg(v), v)def I32.from_nat(k: Nat) -> I32:    I32{U32.from_nat(k)}# ponytail: Word(64n) costs about 68 us per op. When Base ships a native U64# (bendlang/bend#1027), store its bits in Base's U64, as I32 does with Base's U32.type I64 is Data:    I64{data: Word(64n)}def I64.some(m: Maybe<&2, Word(64n)>) -> Maybe<&2, I64>:    match m:        case None{}:            None{}        case Some{x}:            Some{I64{x}}def I64.MIN() -> I64:    I64{Int.min(64n, True{})}def I64.MAX() -> I64:    I64{Int.max(64n, True{})}def I64.add(a: I64, b: I64) -> I64:    match a b:        case I64{x} I64{y}:            I64{Word.add(64n, x, y)}def I64.sub(a: I64, b: I64) -> I64:    match a b:        case I64{x} I64{y}:            I64{Word.sub(64n, x, y)}def I64.mul(a: I64, b: I64) -> I64:    match a b:        case I64{x} I64{y}:            I64{Word.mul(64n, x, y)}def I64.and(a: I64, b: I64) -> I64:    match a b:        case I64{x} I64{y}:            I64{Word.and(64n, x, y)}def I64.or(a: I64, b: I64) -> I64:    match a b:        case I64{x} I64{y}:            I64{Word.or(64n, x, y)}def I64.xor(a: I64, b: I64) -> I64:    match a b:        case I64{x} I64{y}:            I64{Word.xor(64n, x, y)}def I64.div(a: I64, b: I64) -> I64:    match a b:        case I64{x} I64{y}:            I64{Int.div(64n, True{}, x, y)}def I64.mod(a: I64, b: I64) -> I64:    match a b:        case I64{x} I64{y}:            I64{Int.mod(64n, True{}, x, y)}def I64.checked_add(a: I64, b: I64) -> Maybe<&2, I64>:    match a b:        case I64{x} I64{y}:            I64.some(Int.checked(64n, Int.add_ov(64n, True{}, x, y)))def I64.checked_sub(a: I64, b: I64) -> Maybe<&2, I64>:    match a b:        case I64{x} I64{y}:            I64.some(Int.checked(64n, Int.sub_ov(64n, True{}, x, y)))def I64.checked_mul(a: I64, b: I64) -> Maybe<&2, I64>:    match a b:        case I64{x} I64{y}:            I64.some(Int.checked(64n, Int.mul_ov(64n, True{}, x, y)))def I64.checked_div(a: I64, b: I64) -> Maybe<&2, I64>:    match a b:        case I64{x} I64{y}:            I64.some(Int.checked_div(64n, True{}, x, y))def I64.checked_mod(a: I64, b: I64) -> Maybe<&2, I64>:    match a b:        case I64{x} I64{y}:            I64.some(Int.checked_mod(64n, True{}, x, y))def I64.saturating_add(a: I64, b: I64) -> I64:    match a b:        case I64{x} I64{y}:            I64{Int.saturating_add(64n, True{}, x, y)}def I64.saturating_sub(a: I64, b: I64) -> I64:    match a b:        case I64{x} I64{y}:            I64{Int.saturating_sub(64n, True{}, x, y)}def I64.saturating_mul(a: I64, b: I64) -> I64:    match a b:        case I64{x} I64{y}:            I64{Int.saturating_mul(64n, True{}, x, y)}def I64.cmp(a: I64, b: I64) -> Cmp:    match a b:        case I64{x} I64{y}:            Int.cmp(64n, True{}, x, y)def I64.is_eq(a: I64, b: I64) -> Bool:    Cmp.is_eq(I64.cmp(a, b))def I64.is_lt(a: I64, b: I64) -> Bool:    Cmp.is_lt(I64.cmp(a, b))def I64.is_le(a: I64, b: I64) -> Bool:    Cmp.is_le(I64.cmp(a, b))def I64.is_gt(a: I64, b: I64) -> Bool:    Cmp.is_gt(I64.cmp(a, b))def I64.is_ge(a: I64, b: I64) -> Bool:    Cmp.is_ge(I64.cmp(a, b))def I64.is_ne(a: I64, b: I64) -> Bool:    Bool.not(Cmp.is_eq(I64.cmp(a, b)))def I64.is_zero(a: I64) -> Bool:    match a:        case I64{x}:            Int.is_zero(64n, x)def I64.not(a: I64) -> I64:    match a:        case I64{x}:            I64{Word.not(64n, x)}def I64.shl(a: I64, k: Nat) -> I64:    match a:        case I64{x}:            I64{Int.shl(64n, k, x)}def I64.shr(a: I64, k: Nat) -> I64:    match a:        case I64{x}:            I64{Int.shr(64n, True{}, k, x)}def I64.neg(a: I64) -> I64:    match a:        case I64{x}:            I64{Int.neg(64n, x)}def I64.abs(a: I64) -> I64:    match a:        case I64{x}:            I64{Int.abs(64n, x)}def I64.is_neg(a: I64) -> Bool:    match a:        case I64{x}:            Int.msb(64n, x)def I64.show_radix(r: U32, a: I64) -> String:    match a:        case I64{x}:            Int.show(64n, True{}, r, x)def I64.show(a: I64) -> String:    I64.show_radix(10, a)def I64.read_radix(r: U32, s: String) -> Maybe<&2, I64>:    I64.some(Int.read(64n, True{}, r, s))def I64.read(s: String) -> Maybe<&2, I64>:    I64.read_radix(10, s)def I64.to_u32(a: I64) -> U32:    match a:        case I64{x}:            U32{Int.sext(32n, 64n, x)}def I64.from_u32(a: U32) -> I64:    match a:        case U32{x}:            I64{Int.ext(64n, 32n, False{}, x)}def I64.to_nat(a: I64) -> Maybe<&2, Nat>:    match a:        case I64{x}:            Int.to_nat(64n, x)def I64.from_nat(k: Nat) -> I64:    I64{Int.bits(64n, k)}