Binary representation of integers using inductive types #
THIS FILE IS SYNCHRONIZED WITH MATHLIB4. Any changes to this file require a corresponding PR to mathlib4.
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.
The type of positive binary numbers.
Instances for pos_num
Equations
Equations
- pos_num.inhabited = {default := 1}
The type of nonnegative binary numbers, using pos_num.
Instances for num
Equations
- num.has_zero = {zero := num.zero}
Equations
- num.has_one = {one := num.pos 1}
Equations
- num.inhabited = {default := 0}
Representation of integers using trichotomy around zero.
Instances for znum
Equations
- znum.has_zero = {zero := znum.zero}
Equations
- znum.has_one = {one := znum.pos 1}
Equations
- znum.inhabited = {default := 0}
bit b n appends the bit b to the end of n, where bit tt x = x1 and bit ff x = x0.
Equations
Addition of two pos_nums.
Equations
Equations
of_nat_succ n is the pos_num corresponding to n + 1.
Equations
of_nat n is the pos_num corresponding to n, except for of_nat 0 = 1.
Equations
Ordering of pos_nums.
Equations
- a.bit0.cmp b.bit0 = a.cmp b
- a.bit0.cmp b.bit1 = (a.cmp b).cases_on ordering.lt ordering.lt ordering.gt
- ᾰ.bit0.cmp 1 = ordering.gt
- a.bit1.cmp b.bit0 = (a.cmp b).cases_on ordering.lt ordering.gt ordering.gt
- a.bit1.cmp b.bit1 = a.cmp b
- ᾰ.bit1.cmp 1 = ordering.gt
- 1.cmp ᾰ.bit0 = ordering.lt
- 1.cmp ᾰ.bit1 = ordering.lt
- 1.cmp 1 = ordering.eq
Equations
- pos_num.has_lt = {lt := λ (a b : pos_num), a.cmp b = ordering.lt}
Equations
- pos_num.decidable_lt a b = id (ordering.decidable_eq (a.cmp b) ordering.lt)
Equations
- pos_num.decidable_le a b = id (ne.decidable (b.cmp a) ordering.lt)
cast_pos_num casts a pos_num into any type which has 1 and +.
Equations
- cast_pos_num a.bit0 = bit0 (cast_pos_num a)
- cast_pos_num a.bit1 = bit1 (cast_pos_num a)
- cast_pos_num 1 = 1
Equations
- pos_num_coe = {coe := cast_pos_num _inst_2}
Equations
- num.has_add = {add := num.add}
Equations
- num.has_mul = {mul := num.mul}
Equations
- num.has_lt = {lt := λ (a b : num), a.cmp b = ordering.lt}
Equations
- num.decidable_lt a b = id (ordering.decidable_eq (a.cmp b) ordering.lt)
Equations
- num.decidable_le a b = id (ne.decidable (b.cmp a) ordering.lt)
Converts x : num to -x : znum.
Equations
- (num.pos a).to_znum_neg = znum.neg a
- 0.to_znum_neg = 0
Equations
- num.of_nat' = nat.binary_rec 0 (λ (b : bool) (n : ℕ), cond b num.bit1 num.bit0)
Equations
- znum.has_neg = {neg := znum.zneg}
Equations
- znum.of_int' -[1+ n] = (num.of_nat' (n + 1)).to_znum_neg
- znum.of_int' ↑n = (num.of_nat' n).to_znum
Subtraction of two pos_nums, producing a znum.
Equations
- a.bit0.sub' b.bit0 = (a.sub' b).bit0
- a.bit0.sub' b.bit1 = (a.sub' b).bitm1
- ᾰ.bit0.sub' 1 = ᾰ.bit0.pred'.to_znum
- a.bit1.sub' b.bit0 = (a.sub' b).bit1
- a.bit1.sub' b.bit1 = (a.sub' b).bit0
- ᾰ.bit1.sub' 1 = ᾰ.bit1.pred'.to_znum
- 1.sub' ᾰ.bit0 = ᾰ.bit0.pred'.to_znum_neg
- 1.sub' ᾰ.bit1 = ᾰ.bit1.pred'.to_znum_neg
- pos_num.one.sub' 1 = pos_num.one.pred'.to_znum
Converts a znum to a pos_num, mapping all out of range values to 1.
Equations
- pos_num.of_znum (znum.neg ᾰ) = 1
- pos_num.of_znum (znum.pos p) = p
- pos_num.of_znum znum.zero = 1
Equations
Converts a znum to an option num, where of_znum' p = none if p < 0.
Equations
- num.of_znum' (znum.neg p) = option.none
- num.of_znum' (znum.pos p) = option.some (num.pos p)
- num.of_znum' 0 = option.some 0
Converts a znum to an option num, where of_znum p = 0 if p < 0.
Equations
- num.of_znum (znum.neg ᾰ) = 0
- num.of_znum (znum.pos p) = num.pos p
- num.of_znum znum.zero = 0
Equations
- num.has_sub = {sub := num.sub}
Addition of znums.
Equations
- (znum.neg a).add (znum.neg b) = znum.neg (a + b)
- (znum.neg a).add (znum.pos b) = b.sub' a
- (znum.neg ᾰ).add 0 = znum.neg ᾰ
- (znum.pos a).add (znum.neg b) = a.sub' b
- (znum.pos a).add (znum.pos b) = znum.pos (a + b)
- (znum.pos ᾰ).add 0 = znum.pos ᾰ
- 0.add (znum.neg ᾰ) = znum.neg ᾰ
- 0.add (znum.pos ᾰ) = znum.pos ᾰ
- 0.add znum.zero = znum.zero
Equations
- znum.has_add = {add := znum.add}
Multiplication of znums.
Equations
- (znum.neg a).mul (znum.neg b) = znum.pos (a * b)
- (znum.neg a).mul (znum.pos b) = znum.neg (a * b)
- (znum.neg ᾰ).mul 0 = 0
- (znum.pos a).mul (znum.neg b) = znum.neg (a * b)
- (znum.pos a).mul (znum.pos b) = znum.pos (a * b)
- (znum.pos ᾰ).mul 0 = 0
- 0.mul (znum.neg ᾰ) = 0
- 0.mul (znum.pos ᾰ) = 0
- 0.mul znum.zero = 0
Equations
- znum.has_mul = {mul := znum.mul}
Ordering on znums.
Equations
- (znum.neg a).cmp (znum.neg b) = b.cmp a
- (znum.neg _x).cmp (znum.pos ᾰ) = ordering.lt
- (znum.neg _x).cmp znum.zero = ordering.lt
- (znum.pos _x).cmp (znum.neg ᾰ) = ordering.gt
- (znum.pos a).cmp (znum.pos b) = a.cmp b
- (znum.pos _x).cmp znum.zero = ordering.gt
- znum.zero.cmp (znum.neg _x) = ordering.gt
- znum.zero.cmp (znum.pos _x) = ordering.lt
- 0.cmp 0 = ordering.eq
Equations
- znum.has_lt = {lt := λ (a b : znum), a.cmp b = ordering.lt}
Equations
- znum.decidable_lt a b = id (ordering.decidable_eq (a.cmp b) ordering.lt)
Equations
- znum.decidable_le a b = id (ne.decidable (b.cmp a) ordering.lt)
Auxiliary definition for pos_num.divmod.
Equations
- d.divmod_aux q r = pos_num.divmod_aux._match_1 q r (num.of_znum' (r.sub' (num.pos d)))
- pos_num.divmod_aux._match_1 q r (option.some r') = (q.bit1, r')
- pos_num.divmod_aux._match_1 q r option.none = (q.bit0, r)
divmod x y = (y / x, y % x).
Equations
- num.has_div = {div := num.div}
Equations
- num.has_mod = {mod := num.mod}
Auxiliary definition for num.gcd.
Equations
- num.gcd_aux n.succ (num.pos ᾰ) b = num.gcd_aux n (b % num.pos ᾰ) (num.pos ᾰ)
- num.gcd_aux n.succ 0 b = b
- num.gcd_aux 0 a b = b
Division of znum, where x / 0 = 0.
Equations
- (znum.neg n).div (znum.neg d) = znum.pos (n.pred' / num.pos d).succ'
- (znum.neg n).div (znum.pos d) = znum.neg (n.pred' / num.pos d).succ'
- (znum.neg ᾰ).div 0 = 0
- (znum.pos n).div (znum.neg d) = (n.div' d).to_znum_neg
- (znum.pos n).div (znum.pos d) = (n.div' d).to_znum
- (znum.pos ᾰ).div 0 = 0
- 0.div (znum.neg ᾰ) = 0
- 0.div (znum.pos ᾰ) = 0
- 0.div znum.zero = 0
Equations
- znum.has_div = {div := znum.div}
Equations
- znum.has_mod = {mod := znum.mod}