Binary representation of integers using inductive types #
Note: Unlike in Coq, where this representation is preferred because of
the reliance on kernel reduction, in Lean this representation is discouraged
in favor of the "Peano" natural numbers Nat
, and the purpose of this
collection of theorems is to show the equivalence of the different approaches.
Equations
bit b n
appends the bit b
to the end of n
, where bit tt x = x1
and bit ff x = x0
.
Equations
- PosNum.bit b = bif b then PosNum.bit1 else PosNum.bit0
Instances For
The successor of a PosNum
.
Equations
- PosNum.one.succ = PosNum.one.bit0
- n.bit1.succ = n.succ.bit0
- n.bit0.succ = n.bit1
Instances For
Addition of two PosNum
s.
Equations
- PosNum.one.add x = x.succ
- x.add PosNum.one = x.succ
- a.bit0.add b.bit0 = (a.add b).bit0
- a.bit1.add b.bit1 = (a.add b).succ.bit0
- a.bit0.add b.bit1 = (a.add b).bit1
- a.bit1.add b.bit0 = (a.add b).bit1
Instances For
The predecessor of a PosNum
as a Num
.
Equations
- PosNum.one.pred' = 0
- n.bit0.pred' = Num.pos (Num.casesOn n.pred' 1 PosNum.bit1)
- n.bit1.pred' = Num.pos n.bit0
Instances For
The predecessor of a PosNum
as a PosNum
. This means that pred 1 = 1
.
Equations
- a.pred = Num.casesOn a.pred' 1 id
Instances For
ofNatSucc n
is the PosNum
corresponding to n + 1
.
Equations
- PosNum.ofNatSucc 0 = 1
- PosNum.ofNatSucc n.succ = (PosNum.ofNatSucc n).succ
Instances For
ofNat n
is the PosNum
corresponding to n
, except for ofNat 0 = 1
.
Equations
- PosNum.ofNat n = PosNum.ofNatSucc n.pred
Instances For
Equations
- PosNum.instOfNatHAddNatOfNat = { ofNat := PosNum.ofNat (n + 1) }
Ordering of PosNum
s.
Equations
- PosNum.one.cmp PosNum.one = Ordering.eq
- x.cmp PosNum.one = Ordering.gt
- PosNum.one.cmp x = Ordering.lt
- a.bit0.cmp b.bit0 = a.cmp b
- a.bit0.cmp b.bit1 = Ordering.casesOn (a.cmp b) Ordering.lt Ordering.lt Ordering.gt
- a.bit1.cmp b.bit0 = Ordering.casesOn (a.cmp b) Ordering.lt Ordering.gt Ordering.gt
- a.bit1.cmp b.bit1 = a.cmp b
Instances For
Equations
- PosNum.instLT = { lt := fun (a b : PosNum) => a.cmp b = Ordering.lt }
Equations
- PosNum.instLE = { le := fun (a b : PosNum) => ¬b < a }
Equations
- instReprPosNum = { reprPrec := fun (n : PosNum) (x : ℕ) => repr ↑n }
Equations
- instReprNum = { reprPrec := fun (n : Num) (x : ℕ) => repr ↑n }
Equations
- Num.instLT = { lt := fun (a b : Num) => a.cmp b = Ordering.lt }
Equations
- Num.ofNat' = Nat.binaryRec 0 fun (b : Bool) (x : ℕ) => bif b then Num.bit1 else Num.bit0
Instances For
bitm1 x
appends a 1
to the end of x
, mapping x
to 2 * x - 1
.
Equations
- x.bitm1 = match x with | ZNum.zero => ZNum.neg 1 | ZNum.pos n => ZNum.pos (Num.casesOn n.pred' 1 PosNum.bit1) | ZNum.neg n => ZNum.neg n.bit1
Instances For
Equations
- ZNum.ofInt' x = match x with | Int.ofNat n => (Num.ofNat' n).toZNum | Int.negSucc n => (Num.ofNat' (n + 1)).toZNumNeg
Instances For
Subtraction of two PosNum
s, producing a ZNum
.
Equations
- x.sub' PosNum.one = x.pred'.toZNum
- PosNum.one.sub' x = x.pred'.toZNumNeg
- a.bit0.sub' b.bit0 = (a.sub' b).bit0
- a.bit0.sub' b.bit1 = (a.sub' b).bitm1
- a.bit1.sub' b.bit0 = (a.sub' b).bit1
- a.bit1.sub' b.bit1 = (a.sub' b).bit0
Instances For
Converts a ZNum
to a PosNum
, mapping all out of range values to 1
.
Equations
- PosNum.ofZNum x = match x with | ZNum.pos p => p | x => 1
Instances For
Equations
- ZNum.instLT = { lt := fun (a b : ZNum) => a.cmp b = Ordering.lt }
Auxiliary definition for PosNum.divMod
.
Equations
- d.divModAux q r = match Num.ofZNum' (r.sub' (Num.pos d)) with | some r' => (q.bit1, r') | none => (q.bit0, r)
Instances For
Auxiliary definition for Num.gcd
.
Equations
- Num.gcdAux 0 x✝ x = x
- Num.gcdAux n.succ Num.zero x = x
- Num.gcdAux n.succ x✝ x = Num.gcdAux n (x % x✝) x✝
Instances For
Equations
- instReprZNum = { reprPrec := fun (n : ZNum) (x : ℕ) => repr ↑n }