Integer
The integer
type is primitive but aliased in the Integer
module:
integer : U 0
Integer literals are written using a z`
parsing directive. For
example, zero is z`0
.
(* +z *)
plusz : integer -> integer -> integer
(* ~z *)
negz : integer -> integer
(* -z *)
minusz : integer -> integer -> integer
= fn x y . x +z ~z y
neq_0_1 : z`0 = z`1 : integer -> void
neq_0_neg1 : z`0 = z`-1 : integer -> void
plusz_commute : forall (a b : integer) . a +z b = b +z a : integer
plusz_assoc : forall (a b c : integer) . a +z b +z c = a +z (b +z c) : integer
plusz_id_l : forall (a : integer) . z`0 +z a = a : integer
plusz_id_r : forall (a : integer) . a +z z`0 = a : integer
plusz_inverse_l : forall (a : integer) . ~z a +z a = z`0 : integer
plusz_inverse_r : forall (a : integer) . a +z ~z a = z`0 : integer
negz_invol : forall (a : integer) . ~z (~z a) = a : integer
negz_plusz : forall (a b : integer) . ~z (a +z b) = ~z a +z ~z b : integer
plusz_cancel_l : forall (a b c : integer) . c +z a = c +z b : integer -> a = b : integer
plusz_cancel_r : forall (a b c : integer) . a +z c = b +z c : integer -> a = b : integer
plusz_shift_l : forall (a b c : integer) . a = b +z c : integer <-> ~z b +z a = c : integer
plusz_shift_r : forall (a b c : integer) . a +z b = c : integer <-> a = c +z ~z b : integer
plusz_shift_lr : forall (a b c : integer) . a +z b = c : integer <-> b = ~z a +z c : integer
plusz_shift_rl : forall (a b c : integer) . a = b +z c : integer <-> a +z ~z c = b : integer
plusz_compat : forall (a a' b b' : integer) .
a = a' : integer -> b = b' : integer -> a +z b = a' +z b' : integer
negz_compat : forall (a a' : integer) . a = a' : integer -> ~z a = ~z a' : integer
(* <z= *)
leqz : integer -> integer -> U 0
(* <z *)
ltz : integer -> integer -> U 0
= fn x y . z`1 +z x <z= y
leqz_inhabitant : forall (a b : integer) . a <z= b -> () : a <z= b
ltz_inhabitant : forall (a b : integer) . a <z b -> () : a <z b
leqz_0_1 : z`0 <z= z`1
ltz_0_1 : z`0 <z z`1
leqz_neg1_0 : z`-1 <z z`0
ltz_neg1_0 : z`-1 <z z`0
leqz_refl : forall (a : integer) . a <z= a
leqz_refl_eq : forall (a b : integer) . a = b : integer -> a <z= b
leqz_trans : forall (a b c : integer) . a <z= b -> b <z= c -> a <z= c
leqz_antisymm : forall (a b : integer) . a <z= b -> b <z= a -> a = b : integer
This one gives transitivity in the form needed for rewriting:
leqz_implication : forall (a a' b b' : integer) . a' <z= a -> b <z= b' -> a <z= b -> a' <z= b'
ltz_impl_leqz : forall (a b : integer) . a <z b -> a <z= b
ltz_irrefl : forall (a : integer) . a <z a -> void
ltz_trans : forall (a b c : integer) . a <z b -> b <z c -> a <z c
leqz_ltz_trans : forall (a b c : integer) . a <z= b -> b <z c -> a <z c
ltz_leqz_trans : forall (a b c : integer) . a <z b -> b <z= c -> a <z c
ltz_succ : forall (a : integer) . a <z z`1 +z a
leqz_succ : forall (a : integer) . a <z= z`1 +z a
plusz_leqz : forall (a a' b b' : integer) . a <z= a' -> b <z= b' -> a +z b <z= a' +z b'
plusz_cancel_leqz_l : forall (a b c : integer) . c +z a <z= c +z b -> a <z= b
plusz_cancel_leqz_r : forall (a b c : integer) . a +z c <z= b +z c -> a <z= b
plusz_cancel_leqz_leqz_l : forall (a a' b b' : integer) .
a +z b <z= a' +z b' -> a' <z= a -> b <z= b'
plusz_cancel_leqz_leqz_r : forall (a a' b b' : integer) .
a +z b <z= a' +z b' -> b' <z= b -> a <z= a'
plusz_shift_leqz_l : forall (a b c : integer) . a <z= b +z c <-> ~z b +z a <z= c
plusz_shift_leqz_r : forall (a b c : integer) . a +z b <z= c <-> a <z= c +z ~z b
plusz_shift_leqz_lr : forall (a b c : integer) . a +z b <z= c <-> b <z= ~z a +z c
plusz_shift_leqz_rl : forall (a b c : integer) . a <z= b +z c <-> a +z ~z c <z= b
plusz_ltz_l : forall (a a' b b' : integer) . a <z a' -> b <z= b' -> a +z b <z a' +z b'
plusz_ltz_r : forall (a a' b b' : integer) . a <z= a' -> b <z b' -> a +z b <z a' +z b'
plusz_ltz : forall (a a' b b' : integer) . a <z a' -> b <z b' -> a +z b <z a' +z b'
plusz_cancel_ltz_l : forall (a b c : integer) . c +z a <z c +z b -> a <z b
plusz_cancel_ltz_r : forall (a b c : integer) . a +z c <z b +z c -> a <z b
plusz_shift_ltz_l : forall (a b c : integer) . a <z b +z c <-> ~z b +z a <z c
plusz_shift_ltz_r : forall (a b c : integer) . a +z b <z c <-> a <z c +z ~z b
plusz_shift_ltz_lr : forall (a b c : integer) . a +z b <z c <-> b <z ~z a +z c
plusz_shift_ltz_rl : forall (a b c : integer) . a <z b +z c <-> a +z ~z c <z b
negz_leqz : forall (a b : integer) . a <z= b -> ~z b <z= ~z a
negz_leqz' : forall (a b : integer) . ~z b <z= ~z a -> a <z= b
negz_ltz : forall (a b : integer) . a <z b -> ~z b <z ~z a
negz_ltz' : forall (a b : integer) . ~z b <z ~z a -> a <z b
not_leqz : forall (a b : integer) . not (a <z= b) <-> b <z a
not_ltz : forall (a b : integer) . not (a <z b) <-> b <z= a
ltz_from_leqz_neq : forall (a b : integer) . a <z= b -> not (a = b : integer) -> a <z b
ltz_as_leqz_l : forall (a b : integer) . a <z b <-> z`1 +z a <z= b
ltz_as_leqz_r : forall (a b : integer) . a <z b <-> a +z z`1 <z= b
leqz_as_ltz_l : forall (a b : integer) . a <z= b <-> a <z z`1 +z b
leqz_as_ltz_r : forall (a b : integer) . a <z= b <-> a <z b +z z`1
(* =z? *)
eqzb : integer -> integer -> bool
(* <z=? *)
leqzb : integer -> integer -> bool
(* <z? *)
ltzb : integer -> integer -> bool
= fn a b . z`1 +z a <z=? b
(* !z=? *)
neqzb : integer -> integer -> bool
= fn a b . Bool.notb (a =z? b)
istrue_eqzb : forall (a b : integer) . Bool.istrue (a =z? b) <-> a = b : integer
istrue_neqzb : forall (a b : integer) . Bool.istrue (a !z=? b) <-> a != b : integer
istrue_leqzb : forall (a b : integer) . Bool.istrue (a <z=? b) <-> a <z= b
istrue_ltzb : forall (a b : integer) . Bool.istrue (a <z? b) <-> a <z b
notb_eqzb : forall (a b : integer) . Bool.notb (a =z? b) = a !z=? b : bool
notb_neqzb : forall (a b : integer) . Bool.notb (a !z=? b) = a =z? b : bool
notb_leqzb : forall (a b : integer) . Bool.notb (a <z=? b) = b <z? a : bool
notb_ltzb : forall (a b : integer) . Bool.notb (a <z? b) = b <z=? a : bool
We say that a
is smaller than b
when b
< a
≤ 0 or 0 ≤ a
< b
:
smaller : integer -> integer -> U 0
= fn a b . b <z a & a <z= z`0 % a <z b & z`0 <z= a
Smaller is well-founded, giving us strong induction for integers:
smaller_well_founded : forall (a : integer) . Acc integer smaller a
As a corollary, we can build an iterator for integers. It has three cases: a base case for zero, a negative case that works downwards, and a positive case that works upwards.
integer_iter : intersect (i : level) .
forall (P : integer -> U i) .
P z`0
-> (forall (a : integer) . a <z= z`0 -> P a -> P (z`-1 +z a))
-> (forall (a : integer) . z`0 <z= a -> P a -> P (z`1 +z a))
-> forall (a : integer) . P a
=rec= fn P hz hm hp a .
if z`0 =z? a
then hz
else (if z`0 <z=? a
then hp (z`-1 +z a) () (integer_iter P hz hm hp (z`-1 +z a))
else hm (z`1 +z a) () (integer_iter P hz hm hp (z`1 +z a)))
nat_to_integer : nat -> integer
=rec= fn n . nat_case n z`0 (fn n' . z`1 +z nat_to_integer n')
nat_to_integer (zero) --> z`0
nat_to_integer (succ n) --> plusz z`1 (nat_to_integer n)
integer_to_nat : integer -> nat
=rec= fn a . if a <z=? z`0 then 0 else succ (integer_to_nat (z`-1 +z a))
nat_to_integer_inv : forall (n : nat) . integer_to_nat (nat_to_integer n) = n : nat
integer_to_nat_inv : forall (a : integer) .
z`0 <z= a -> nat_to_integer (integer_to_nat a) = a : integer
nat_to_integer_nonneg : forall (n : nat) . z`0 <z= nat_to_integer n
nat_to_integer_mono : forall (m n : nat) . m <= n -> nat_to_integer m <z= nat_to_integer n
nat_to_integer_mono_lt : forall (m n : nat) . m < n -> nat_to_integer m <z nat_to_integer n
integer_to_nat_zero : integer_to_nat z`0 = 0 : nat
integer_to_nat_succ : forall (a : integer) .
z`0 <z= a -> integer_to_nat (z`1 +z a) = succ (integer_to_nat a) : nat
integer_to_nat_mono : forall (a b : integer) . a <z= b -> integer_to_nat a <= integer_to_nat b
integer_to_nat_mono_lt : forall (a b : integer) .
z`0 <z= a -> a <z b -> integer_to_nat a < integer_to_nat b
succ_to_integer : forall (n : nat) .
nat_to_integer (succ n) = z`1 +z nat_to_integer n : integer
plus_to_integer : forall (m n : nat) .
nat_to_integer (m + n) = nat_to_integer m +z nat_to_integer n : integer
plusz_to_nat : forall (a b : integer) .
z`0 <z= a
-> z`0 <z= b
-> integer_to_nat (a +z b) = integer_to_nat a + integer_to_nat b : nat
pred_to_integer : forall (n : nat) .
0 < n -> nat_to_integer (Nat.pred n) = z`-1 +z nat_to_integer n : integer
minus_to_integer : forall (m n : nat) .
n <= m
-> nat_to_integer (m - n)
= nat_to_integer m -z nat_to_integer n
: integer
minusz_to_nat : forall (a b : integer) .
z`0 <z= b
-> b <z= a
-> integer_to_nat (a -z b) = integer_to_nat a - integer_to_nat b : nat
eqb_to_integer : forall (m n : nat) . m =? n = nat_to_integer m =z? nat_to_integer n : bool
eqzb_to_nat : forall (a b : integer) .
z`0 <z= a
-> z`0 <z= b
-> a =z? b = integer_to_nat a =? integer_to_nat b : bool
leqb_to_integer : forall (m n : nat) . m <=? n = nat_to_integer m <z=? nat_to_integer n : bool
leqzb_to_nat : forall (a b : integer) .
z`0 <z= a
-> z`0 <z= b
-> a <z=? b = integer_to_nat a <=? integer_to_nat b : bool
ltb_to_integer : forall (m n : nat) . m <? n = nat_to_integer m <z? nat_to_integer n : bool
ltzb_to_nat : forall (a b : integer) .
z`0 <z= a
-> z`0 <z= b
-> a <z? b = integer_to_nat a <? integer_to_nat b : bool
neqb_to_integer : forall (m n : nat) . m !=? n = nat_to_integer m !z=? nat_to_integer n : bool
neqzb_to_nat : forall (a b : integer) .
z`0 <z= a
-> z`0 <z= b
-> a !z=? b = integer_to_nat a !=? integer_to_nat b : bool
eq_integer_decide : forall (a b : integer) . Decidable.decidable (a = b : integer)
neq_integer_decide : forall (a b : integer) . Decidable.decidable (a != b : integer)
leqz_decide : forall (a b : integer) . Decidable.decidable (a <z= b)
ltz_decide : forall (a b : integer) . Decidable.decidable (a <z b)
eq_integer_stable : forall (a b : integer) . Stable.stable (a = b : integer)
neq_integer_stable : forall (a b : integer) . Stable.stable (a != b : integer)
leqz_stable : forall (a b : integer) . Stable.stable (a <z= b)
ltz_stable : forall (a b : integer) . Stable.stable (a <z b)
leqz_iff_ltz_or_eq : forall (a b : integer) . a <z= b <-> a <z b % a = b : integer
integer_trichotomy : forall (a b : integer) . a <z b % a = b : integer % b <z a
integer_dichotomy : forall (a b : integer) . a <z= b % b <z a
integer_dichotomy_weak : forall (a b : integer) . a <z= b % b <z= a
integer_dichotomy_neq : forall (a b : integer) . a != b : integer -> a <z b % b <z a
(* *z *)
timesz : integer -> integer -> integer
timesz_id_l : forall (a : integer) . z`1 *z a = a : integer
timesz_id_r : forall (a : integer) . a *z z`1 = a : integer
timesz_ann_l : forall (a : integer) . z`0 *z a = z`0 : integer
timesz_ann_r : forall (a : integer) . a *z z`0 = z`0 : integer
timesz_commute : forall (a b : integer) . a *z b = b *z a : integer
timesz_assoc : forall (a b c : integer) . a *z b *z c = a *z (b *z c) : integer
timesz_dist_plusz_l : forall (a b c : integer) . (a +z b) *z c = a *z c +z b *z c : integer
timesz_dist_plusz_r : forall (a b c : integer) . a *z (b +z c) = a *z b +z a *z c : integer
negz_dist_timesz_l : forall (a b : integer) . ~z (a *z b) = ~z a *z b : integer
negz_dist_timesz_r : forall (a b : integer) . ~z (a *z b) = a *z ~z b : integer
negz_as_timesz : forall (a : integer) . ~z a = z`-1 *z a : integer
timesz_compat : forall (a a' b b' : integer) .
a = a' : integer -> b = b' : integer -> a *z b = a' *z b' : integer
timesz_leqz : forall (a a' b b' : integer) .
z`0 <z= a -> z`0 <z= b -> a <z= a' -> b <z= b' -> a *z b <z= a' *z b'
(* an alias for timesz_leqz *)
timesz_leqz_pos_pos : forall (a a' b b' : integer) .
z`0 <z= a -> z`0 <z= b -> a <z= a' -> b <z= b' -> a *z b <z= a' *z b'
timesz_leqz_neg_neg : forall (a a' b b' : integer) .
a' <z= z`0
-> b' <z= z`0
-> a <z= a'
-> b <z= b'
-> a' *z b' <z= a *z b
timesz_leqz_pos_neg : forall (a a' b b' : integer) .
z`0 <z= a -> b' <z= z`0 -> a <z= a' -> b <z= b' -> a' *z b <z= a *z b'
timesz_leqz_neg_pos : forall (a a' b b' : integer) .
a' <z= z`0 -> z`0 <z= b -> a <z= a' -> b <z= b' -> a *z b' <z= a' *z b
timesz_leqz_l : forall (a b b' : integer) . z`0 <z= a -> b <z= b' -> a *z b <z= a *z b'
timesz_leqz_r : forall (a a' b : integer) . z`0 <z= b -> a <z= a' -> a *z b <z= a' *z b
timesz_leqz_l_neg : forall (a b b' : integer) . a <z= z`0 -> b <z= b' -> a *z b' <z= a *z b
timesz_leqz_r_neg : forall (a a' b : integer) . b <z= z`0 -> a <z= a' -> a' *z b <z= a *z b
timesz_ltz_zero : forall (a b : integer) . z`0 <z a -> z`0 <z b -> z`0 <z a *z b
(* an alias for timesz_ltz_zero *)
timesz_ltz_zero_pos_pos : forall (a b : integer) . z`0 <z a -> z`0 <z b -> z`0 <z a *z b
timesz_ltz_zero_pos_neg : forall (a b : integer) . z`0 <z a -> b <z z`0 -> a *z b <z z`0
timesz_ltz_zero_neg_pos : forall (a b : integer) . a <z z`0 -> z`0 <z b -> a *z b <z z`0
timesz_ltz_zero_neg_neg : forall (a b : integer) . a <z z`0 -> b <z z`0 -> z`0 <z a *z b
integer_integral_domain : forall (a b : integer) .
a *z b = z`0 : integer -> a = z`0 : integer % b = z`0 : integer
timesz_ltz_zero_invert : forall (a b : integer) .
z`0 <z a *z b -> a <z z`0 & b <z z`0 % z`0 <z a & z`0 <z b
times_to_integer : forall (m n : nat) .
nat_to_integer (m * n) = nat_to_integer m *z nat_to_integer n : integer
timesz_to_nat : forall (a b : integer) .
z`0 <z= a
-> z`0 <z= b
-> integer_to_nat (a *z b) = integer_to_nat a * integer_to_nat b : nat
timesz_ltz_l : forall (a b b' : integer) . z`0 <z a -> b <z b' -> a *z b <z a *z b'
timesz_ltz_r : forall (a a' b : integer) . z`0 <z b -> a <z a' -> a *z b <z a' *z b
timesz_cancel_leqz_l : forall (a b c : integer) . z`0 <z c -> c *z a <z= c *z b -> a <z= b
timesz_cancel_leqz_r : forall (a b c : integer) . z`0 <z c -> a *z c <z= b *z c -> a <z= b
timesz_cancel_leqz_l_remainder : forall (a b c r : integer) .
z`0 <z c -> r <z c -> c *z a <z= c *z b +z r -> a <z= b
timesz_cancel_leqz_r_remainder : forall (a b c r : integer) .
z`0 <z c -> r <z c -> a *z c <z= b *z c +z r -> a <z= b
minz : integer -> integer -> integer
= fn a b . if a <z=? b then a else b
maxz : integer -> integer -> integer
= fn a b . if a <z=? b then b else a
negz_minz : forall (a b : integer) . ~z (minz a b) = maxz (~z a) (~z b) : integer
negz_maxz : forall (a b : integer) . ~z (maxz a b) = minz (~z a) (~z b) : integer
maxz_as_minz : forall (a b : integer) . maxz a b = ~z (minz (~z a) (~z b)) : integer
minz_as_maxz : forall (a b : integer) . minz a b = ~z (maxz (~z a) (~z b)) : integer
minz_commute : forall (a b : integer) . minz a b = minz b a : integer
maxz_commute : forall (a b : integer) . maxz a b = maxz b a : integer
minz_assoc : forall (a b c : integer) . minz (minz a b) c = minz a (minz b c) : integer
maxz_assoc : forall (a b c : integer) . maxz (maxz a b) c = maxz a (maxz b c) : integer
minz_leq_l : forall (a b : integer) . minz a b <z= a
minz_leq_r : forall (a b : integer) . minz a b <z= b
maxz_leq_l : forall (a b : integer) . a <z= maxz a b
maxz_leq_r : forall (a b : integer) . b <z= maxz a b
minz_glb : forall (a b c : integer) . c <z= a -> c <z= b -> c <z= minz a b
maxz_lub : forall (a b c : integer) . a <z= c -> b <z= c -> maxz a b <z= c
minz_eq_l : forall (a b : integer) . a <z= b -> minz a b = a : integer
minz_eq_r : forall (a b : integer) . b <z= a -> minz a b = b : integer
maxz_eq_l : forall (a b : integer) . b <z= a -> maxz a b = a : integer
maxz_eq_r : forall (a b : integer) . a <z= b -> maxz a b = b : integer
minz_idem : forall (a : integer) . minz a a = a : integer
maxz_idem : forall (a : integer) . maxz a a = a : integer
minz_dist_maxz_l : forall (a b c : integer) .
minz (maxz a b) c = maxz (minz a c) (minz b c) : integer
minz_dist_maxz_r : forall (a b c : integer) .
minz a (maxz b c) = maxz (minz a b) (minz a c) : integer
maxz_dist_minz_l : forall (a b c : integer) .
maxz (minz a b) c = minz (maxz a c) (maxz b c) : integer
maxz_dist_minz_r : forall (a b c : integer) .
maxz a (minz b c) = minz (maxz a b) (maxz a c) : integer
plusz_dist_minz_l : forall (a b c : integer) .
minz a b +z c = minz (a +z c) (b +z c) : integer
plusz_dist_minz_r : forall (a b c : integer) .
a +z minz b c = minz (a +z b) (a +z c) : integer
plusz_dist_maxz_l : forall (a b c : integer) .
maxz a b +z c = maxz (a +z c) (b +z c) : integer
plusz_dist_maxz_r : forall (a b c : integer) .
a +z maxz b c = maxz (a +z b) (a +z c) : integer
min_to_integer : forall (m n : nat) .
nat_to_integer (Nat.min m n)
= minz (nat_to_integer m) (nat_to_integer n)
: integer
max_to_integer : forall (m n : nat) .
nat_to_integer (Nat.max m n)
= maxz (nat_to_integer m) (nat_to_integer n)
: integer
minz_to_nat : forall (a b : integer) .
integer_to_nat (minz a b)
= Nat.min (integer_to_nat a) (integer_to_nat b)
: nat
maxz_to_nat : forall (a b : integer) .
integer_to_nat (maxz a b)
= Nat.max (integer_to_nat a) (integer_to_nat b)
: nat