~/bend-docscommunity

int.bend source

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)}