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
Returns a boolean for whether the PosNum is one.
Equations
- PosNum.isOne x = match x with | PosNum.one => true | x => false
Instances For
Addition of two PosNums.
Equations
- PosNum.add PosNum.one x = PosNum.succ x
- PosNum.add x PosNum.one = PosNum.succ x
- PosNum.add (PosNum.bit0 a) (PosNum.bit0 b) = PosNum.bit0 (PosNum.add a b)
- PosNum.add (PosNum.bit1 a) (PosNum.bit1 b) = PosNum.bit0 (PosNum.succ (PosNum.add a b))
- PosNum.add (PosNum.bit0 a) (PosNum.bit1 b) = PosNum.bit1 (PosNum.add a b)
- PosNum.add (PosNum.bit1 a) (PosNum.bit0 b) = PosNum.bit1 (PosNum.add a b)
Instances For
Equations
- PosNum.instAddPosNum = { add := PosNum.add }
The predecessor of a PosNum as a Num.
Equations
- PosNum.pred' PosNum.one = 0
- PosNum.pred' (PosNum.bit0 n) = Num.pos (Num.casesOn (PosNum.pred' n) 1 PosNum.bit1)
- PosNum.pred' (PosNum.bit1 n) = Num.pos (PosNum.bit0 n)
Instances For
The predecessor of a PosNum as a PosNum. This means that pred 1 = 1.
Equations
- PosNum.pred a = Num.casesOn (PosNum.pred' a) 1 id
Instances For
The number of bits of a PosNum, as a PosNum.
Equations
- PosNum.size PosNum.one = 1
- PosNum.size (PosNum.bit0 n) = PosNum.succ (PosNum.size n)
- PosNum.size (PosNum.bit1 n) = PosNum.succ (PosNum.size n)
Instances For
Multiplication of two PosNums.
Equations
- PosNum.mul a PosNum.one = a
- PosNum.mul a (PosNum.bit0 n) = PosNum.bit0 (PosNum.mul a n)
- PosNum.mul a (PosNum.bit1 n) = PosNum.bit0 (PosNum.mul a n) + a
Instances For
Equations
- PosNum.instMulPosNum = { mul := PosNum.mul }
Equations
- PosNum.instOfNatPosNumHAddNatInstHAddInstAddNatOfNat = { ofNat := PosNum.ofNat (n + 1) }
Ordering of PosNums.
Equations
- PosNum.cmp PosNum.one PosNum.one = Ordering.eq
- PosNum.cmp x PosNum.one = Ordering.gt
- PosNum.cmp PosNum.one x = Ordering.lt
- PosNum.cmp (PosNum.bit0 a) (PosNum.bit0 b) = PosNum.cmp a b
- PosNum.cmp (PosNum.bit0 a) (PosNum.bit1 b) = Ordering.casesOn (PosNum.cmp a b) Ordering.lt Ordering.lt Ordering.gt
- PosNum.cmp (PosNum.bit1 a) (PosNum.bit0 b) = Ordering.casesOn (PosNum.cmp a b) Ordering.lt Ordering.gt Ordering.gt
- PosNum.cmp (PosNum.bit1 a) (PosNum.bit1 b) = PosNum.cmp a b
Instances For
Equations
- PosNum.instLTPosNum = { lt := fun (a b : PosNum) => PosNum.cmp a b = Ordering.lt }
Equations
- PosNum.instLEPosNum = { le := fun (a b : PosNum) => ¬b < a }
Equations
- PosNum.decidableLT x✝ x = match x✝, x with | a, b => id inferInstance
Equations
- PosNum.decidableLE x✝ x = match x✝, x with | a, b => id inferInstance
castPosNum casts a PosNum into any type which has 1 and +.
Equations
- ↑PosNum.one = 1
- ↑(PosNum.bit0 n) = bit0 ↑n
- ↑(PosNum.bit1 n) = bit1 ↑n
Instances For
Equations
- instReprPosNum = { reprPrec := fun (n : PosNum) (x : ℕ) => repr ↑n }
Equations
- instReprNum = { reprPrec := fun (n : Num) (x : ℕ) => repr ↑n }
The number of bits required to represent a Num, as a Nat. size 0 is defined to be 0.
Equations
- Num.natSize x = match x with | Num.zero => 0 | Num.pos n => PosNum.natSize n
Instances For
Ordering of Nums.
Equations
- Num.cmp x✝ x = match x✝, x with | Num.zero, Num.zero => Ordering.eq | x, Num.zero => Ordering.gt | Num.zero, x => Ordering.lt | Num.pos a, Num.pos b => PosNum.cmp a b
Instances For
Equations
- Num.instLTNum = { lt := fun (a b : Num) => Num.cmp a b = Ordering.lt }
Equations
- Num.decidableLT x✝ x = match x✝, x with | a, b => id inferInstance
Equations
- Num.decidableLE x✝ x = match x✝, x with | a, b => id inferInstance
Equations
- Num.toZNum x = match x with | Num.zero => 0 | Num.pos a => ZNum.pos a
Instances For
Equations
- Num.ofNat' = Nat.binaryRec 0 fun (b : Bool) (x : ℕ) => bif b then Num.bit1 else Num.bit0
Instances For
The successor of a ZNum.
Equations
- ZNum.succ x = match x with | ZNum.zero => 1 | ZNum.pos a => ZNum.pos (PosNum.succ a) | ZNum.neg a => Num.toZNumNeg (PosNum.pred' a)
Instances For
The predecessor of a ZNum.
Equations
- ZNum.pred x = match x with | ZNum.zero => ZNum.neg 1 | ZNum.pos a => Num.toZNum (PosNum.pred' a) | ZNum.neg a => ZNum.neg (PosNum.succ a)
Instances For
bit1 x appends a 1 to the end of x, mapping x to 2 * x + 1.
Equations
- ZNum.bit1 x = match x with | ZNum.zero => 1 | ZNum.pos n => ZNum.pos (PosNum.bit1 n) | ZNum.neg n => ZNum.neg (Num.casesOn (PosNum.pred' n) 1 PosNum.bit1)
Instances For
bitm1 x appends a 1 to the end of x, mapping x to 2 * x - 1.
Equations
- ZNum.bitm1 x = match x with | ZNum.zero => ZNum.neg 1 | ZNum.pos n => ZNum.pos (Num.casesOn (PosNum.pred' n) 1 PosNum.bit1) | ZNum.neg n => ZNum.neg (PosNum.bit1 n)
Instances For
Equations
- ZNum.ofInt' x = match x with | Int.ofNat n => Num.toZNum (Num.ofNat' n) | Int.negSucc n => Num.toZNumNeg (Num.ofNat' (n + 1))
Instances For
Subtraction of two PosNums, producing a ZNum.
Equations
- PosNum.sub' x PosNum.one = Num.toZNum (PosNum.pred' x)
- PosNum.sub' PosNum.one x = Num.toZNumNeg (PosNum.pred' x)
- PosNum.sub' (PosNum.bit0 a) (PosNum.bit0 b) = ZNum.bit0 (PosNum.sub' a b)
- PosNum.sub' (PosNum.bit0 a) (PosNum.bit1 b) = ZNum.bitm1 (PosNum.sub' a b)
- PosNum.sub' (PosNum.bit1 a) (PosNum.bit0 b) = ZNum.bit1 (PosNum.sub' a b)
- PosNum.sub' (PosNum.bit1 a) (PosNum.bit1 b) = ZNum.bit0 (PosNum.sub' a b)
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
Subtraction of PosNums, where if a < b, then a - b = 1.
Equations
- PosNum.sub a b = match PosNum.sub' a b with | ZNum.pos p => p | x => 1
Instances For
Equations
- PosNum.instSubPosNum = { sub := PosNum.sub }
Equations
- ZNum.instLTZNum = { lt := fun (a b : ZNum) => ZNum.cmp a b = Ordering.lt }
Equations
- ZNum.instLEZNum = { le := fun (a b : ZNum) => ¬b < a }
Equations
- ZNum.decidableLT x✝ x = match x✝, x with | a, b => id inferInstance
Equations
- ZNum.decidableLE x✝ x = match x✝, x with | a, b => id inferInstance
Auxiliary definition for PosNum.divMod.
Equations
- PosNum.divModAux d q r = match Num.ofZNum' (Num.sub' r (Num.pos d)) with | some r' => (Num.bit1 q, r') | none => (Num.bit0 q, r)
Instances For
divMod x y = (y / x, y % x).
Equations
- PosNum.divMod d (PosNum.bit0 n) = match PosNum.divMod d n with | (q, r₁) => PosNum.divModAux d q (Num.bit0 r₁)
- PosNum.divMod d (PosNum.bit1 n) = match PosNum.divMod d n with | (q, r₁) => PosNum.divModAux d q (Num.bit1 r₁)
- PosNum.divMod d PosNum.one = PosNum.divModAux d 0 1
Instances For
Auxiliary definition for Num.gcd.
Equations
- Num.gcdAux 0 x✝ x = x
- Num.gcdAux (Nat.succ n) Num.zero x = x
- Num.gcdAux (Nat.succ n) x✝ x = Num.gcdAux n (x % x✝) x✝
Instances For
Greatest Common Divisor (GCD) of two Nums.
Equations
- Num.gcd a b = if a ≤ b then Num.gcdAux (Num.natSize a + Num.natSize b) a b else Num.gcdAux (Num.natSize b + Num.natSize a) b a
Instances For
Equations
- instReprZNum = { reprPrec := fun (n : ZNum) (x : ℕ) => repr ↑n }