Timings for Spec.v
Require Import Spaces.Pos.
Require Import Spaces.BinInt.Core.
Local Set Universe Minimization ToSet.
Local Open Scope binint_scope.
(** ** Addition is commutative *)
Lemma binint_add_comm n m : n + m = m + n.
all: apply ap, pos_add_comm.
(** ** Zero is the additive identity. *)
Definition binint_add_0_l n : 0 + n = n
:= 1.
Lemma binint_add_0_r n : n + 0 = n.
(** ** Multiplication by zero is zero *)
Definition binint_mul_0_l n : 0 * n = 0
:= 1.
Lemma binint_mul_0_r n : n * 0 = 0.
(** ** One is the multiplicative identity *)
Lemma binint_mul_1_l n : 1 * n = n.
Lemma binint_mul_1_r n : n * 1 = n.
destruct n; trivial; cbn; apply ap, pos_mul_1_r.
Lemma binint_pos_sub_diag n : binint_pos_sub n n = 0.
induction n; trivial; cbn.
all: exact (ap binint_double IHn).
Lemma binint_add_negation_l n : (-n) + n = 0.
destruct n; trivial; cbn; apply binint_pos_sub_diag.
Lemma binint_add_negation_r n : n + (-n) = 0.
destruct n; trivial; cbn; apply binint_pos_sub_diag.
(** ** Permutation of [neg] and [pos_succ] *)
Lemma binint_neg_pos_succ p : neg (pos_succ p) = binint_pred (neg p).
(** ** Permutation of [pos] and [pos_succ] *)
Lemma binint_pos_pos_succ p : pos (pos_succ p) = binint_succ (pos p).
(** ** Negation of a doubled positive integer *)
Lemma binint_negation_double a : - (binint_double a) = binint_double (- a).
(** Negation of the predecessor of a doubled positive integer. *)
Lemma binint_negation_pred_double a
: - (binint_pred_double a) = binint_succ_double (- a).
(** Negation of the doubling of the successor of an positive. *)
Lemma binint_negation_succ_double a
: - (binint_succ_double a) = binint_pred_double (- a).
(** Negation of subtraction of positive integers *)
Lemma binint_pos_sub_negation a b
: - (binint_pos_sub a b) = binint_pos_sub b a.
induction a as [|a ah|a ah];
destruct b;
cbn; trivial.
all: rewrite ?binint_negation_double,
?binint_negation_succ_double,
?binint_negation_pred_double.
(** ** [binint_succ] is a retract of [binint_pred] *)
Definition binint_succ_pred : binint_succ o binint_pred == idmap.
intros [n | | n]; [|trivial|].
all: destruct n; trivial.
1: apply pos_pred_double_succ.
apply pos_succ_pred_double.
(** ** [binint_pred] is a retract of [binint_succ] *)
Definition binint_pred_succ : binint_pred o binint_succ == idmap.
intros [n | | n]; [|trivial|].
all: destruct n; trivial.
1: apply pos_succ_pred_double.
apply pos_pred_double_succ.
(* ** The successor auto-equivalence. *)
Instance isequiv_binint_succ : IsEquiv binint_succ | 0
:= isequiv_adjointify binint_succ _ binint_succ_pred binint_pred_succ.
Definition equiv_binint_succ : BinInt <~> BinInt
:= Build_Equiv _ _ _ isequiv_binint_succ.
(** ** Negation distributes over addition *)
Lemma binint_negation_add_distr n m : - (n + m) = - n + - m.
destruct n, m; simpl; trivial using binint_pos_sub_negation.
(** ** Negation is injective *)
Lemma binint_negation_inj n m : -n = -m -> n = m.
destruct n, m; simpl; intro H.
2: apply pos_neq_zero in H.
3: apply pos_neq_neg in H.
4: apply zero_neq_pos in H.
6: apply zero_neq_neg in H.
7: apply neg_neq_pos in H.
8: apply neg_neq_zero in H.
(** ** Subtracting 1 from a successor gives the positive integer. *)
Lemma binint_pos_sub_succ_l a
: binint_pos_sub (pos_succ a) 1%pos = pos a.
cbn; apply ap, pos_pred_double_succ.
(** ** Subtracting a successor from 1 gives minus the integer. *)
Lemma binint_pos_sub_succ_r a
: binint_pos_sub 1%pos (pos_succ a) = neg a.
cbn; apply ap, pos_pred_double_succ.
(** ** Interaction of doubling functions and subtraction *)
Lemma binint_succ_double_binint_pos_sub a b
: binint_succ_double (binint_pos_sub a (pos_succ b))
= binint_pred_double (binint_pos_sub a b).
induction a; induction b; trivial.
by rewrite pos_pred_double_succ.
cbn; destruct (binint_pos_sub a b); trivial.
destruct (binint_pos_sub a (pos_succ b)); trivial.
cbn; destruct (binint_pos_sub a b); trivial.
cbn; destruct (binint_pos_sub a b); trivial.
Lemma binint_pred_double_binint_pos_sub a b
: binint_pred_double (binint_pos_sub (pos_succ a) b)
= binint_succ_double (binint_pos_sub a b).
induction a; induction b; trivial.
cbn; by destruct (binint_pos_sub a b).
cbn; by destruct (binint_pos_sub a b).
by rewrite pos_pred_double_succ.
by destruct (binint_pos_sub (pos_succ a) b).
by destruct (binint_pos_sub a b).
(** ** Subtractions cancel successors. *)
Lemma binint_pos_sub_succ_succ a b
: binint_pos_sub (pos_succ a) (pos_succ b) = binint_pos_sub a b.
rewrite <- 2 pos_add_1_r.
induction a; induction b; trivial.
by rewrite pos_pred_double_succ.
1: apply binint_succ_double_binint_pos_sub.
cbn; apply ap, ap, pos_pred_double_succ.
1: apply binint_pred_double_binint_pos_sub.
rewrite <- 2 pos_add_1_r.
(** ** Predecessor of a subtraction is the subtraction of a successor. *)
Lemma binint_pred_pos_sub_r a b
: binint_pred (binint_pos_sub a b) = binint_pos_sub a (pos_succ b).
induction b as [|b bH] using pos_peano_ind.
1: destruct a; trivial; destruct a; trivial.
induction a as [|a aH] using pos_peano_ind.
rewrite pos_succ_pred_double.
rewrite pos_pred_double_succ.
rewrite 2 binint_pos_sub_succ_succ.
(** ** Negation of the predecessor is an involution. *)
Lemma binint_negation_pred_negation_red x
: - binint_pred (- binint_pred x) = x.
destruct x as [x| |x]; trivial;
destruct x; trivial; cbn; apply ap.
1: apply pos_pred_double_succ.
apply pos_succ_pred_double.
(** ** Predecessor of a sum is the sum with a predecessor *)
Lemma binint_pred_add_r a b
: binint_pred (a + b) = a + binint_pred b.
intros [a| |a] [b| |b]; trivial.
by rewrite pos_add_assoc.
induction b as [|b bH] using pos_peano_ind.
intro a; exact (binint_pred_succ (neg a)).
rewrite (binint_pred_succ (pos b)).
rewrite <- binint_pos_sub_negation.
rewrite <- binint_pred_pos_sub_r.
apply binint_negation_inj.
rewrite binint_pos_sub_negation.
apply binint_negation_pred_negation_red.
apply binint_pred_pos_sub_r.
induction b as [|b bH] using pos_peano_ind.
intro a; exact (binint_pred_succ (pos a)).
rewrite (binint_pred_succ (pos b)).
cbn; rewrite pos_add_assoc.
change (binint_pred (binint_succ (pos (a + b)%pos)) = pos a + pos b).
(** ** Subtraction from a sum is the sum of a subtraction *)
Lemma binint_pos_sub_add (a b c : Pos)
: binint_pos_sub (a + b)%pos c = pos a + binint_pos_sub b c.
induction c as [|c ch] using pos_peano_ind.
change (binint_pred (pos a + pos b) = pos a + (binint_pred (pos b))).
rewrite <- binint_pred_pos_sub_r.
rewrite <- binint_pred_pos_sub_r.
(** An auxiliary lemma used to prove associativity. *)
Lemma binint_add_assoc_pos p n m : pos p + (n + m) = pos p + n + m.
destruct n as [n| |n], m as [m| |m]; trivial.
cbn; apply binint_negation_inj.
rewrite !binint_negation_add_distr, !binint_pos_sub_negation.
rewrite binint_add_comm, pos_add_comm.
apply binint_pos_sub_add.
by rewrite <- binint_pos_sub_add, binint_add_comm,
<- binint_pos_sub_add, pos_add_comm.
apply binint_pos_sub_add.
cbn; apply ap, pos_add_assoc.
(** ** Associativity of addition *)
Lemma binint_add_assoc n m p : n + (m + p) = n + m + p.
apply binint_negation_inj.
rewrite !binint_negation_add_distr.
apply binint_add_assoc_pos.
apply binint_add_assoc_pos.
(** ** Relationship between [int_succ], [int_pred] and addition. *)
Lemma binint_add_succ_l a b : binint_succ a + b = binint_succ (a + b).
rewrite <- binint_add_assoc, (binint_add_comm 1 b).
Lemma binint_add_succ_r a b : a + binint_succ b = binint_succ (a + b).
Lemma binint_add_pred_l a b : binint_pred a + b = binint_pred (a + b).
rewrite <- binint_add_assoc, (binint_add_comm (-1) b).
Lemma binint_add_pred_r a b : a + binint_pred b = binint_pred (a + b).
(** ** Commutativity of multiplication *)
Lemma binint_mul_comm n m : n * m = m * n.
destruct n, m; cbn; try reflexivity;
apply ap; apply pos_mul_comm.
(** Distributivity of multiplication over addition *)
Lemma binint_pos_sub_mul_pos n m p
: binint_pos_sub n m * pos p = binint_pos_sub (n * p)%pos (m * p)%pos.
rewrite 2 (pos_mul_comm _ p).
set (binint_pos_sub n m) as k.
rewrite binint_pos_sub_add.
rewrite <- (binint_pos_sub_negation _ (x0 _)).
rewrite binint_pos_sub_add.
rewrite binint_negation_add_distr.
rewrite binint_pos_sub_negation.
rewrite binint_add_assoc.
set (binint_pos_sub n m) as k.
Lemma binint_pos_sub_mul_neg n m p
: binint_pos_sub m n * neg p = binint_pos_sub (n * p)%pos (m * p)%pos.
rewrite 2 (pos_mul_comm _ p).
rewrite <- binint_pos_sub_negation.
by destruct (binint_pos_sub n m).
rewrite <- binint_pos_sub_negation.
set (binint_pos_sub n m) as k.
rewrite binint_pos_sub_add.
rewrite <- (binint_pos_sub_negation _ (x0 _)).
rewrite binint_pos_sub_add.
rewrite binint_negation_add_distr.
rewrite binint_pos_sub_negation.
rewrite binint_add_assoc.
rewrite <- (binint_pos_sub_negation m).
set (binint_pos_sub m n) as k.
Lemma binint_mul_add_distr_r n m p : (n + m) * p = n * p + m * p.
induction p; destruct n, m; cbn; trivial; try f_ap;
try apply pos_mul_add_distr_r;
try apply binint_pos_sub_mul_neg;
try apply binint_pos_sub_mul_pos;
apply binint_mul_0_r.
Lemma binint_mul_add_distr_l n m p : n * (m + p) = n * m + n * p.
rewrite 3 (binint_mul_comm n); apply binint_mul_add_distr_r.
Lemma binint_mul_assoc n m p : n * (m * p) = n * m * p.
destruct n, m, p; cbn; trivial; f_ap; apply pos_mul_assoc.