Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(************************************************************************) (* * The Coq Proof Assistant / The Coq Development Team *) (* v * INRIA, CNRS and contributors - Copyright 1999-2018 *) (* <O___,, * (see CREDITS file for the list of authors) *) (* \VV/ **************************************************************) (* // * This file is distributed under the terms of the *) (* * GNU Lesser General Public License Version 2.1 *) (* * (see LICENSE file for the text of the license) *) (************************************************************************) (* Evgeny Makarov, INRIA, 2007 *) (************************************************************************) Require Import NSub ZAxioms. Require Export Ring. Declare Scope pair_scope. Local Open Scope pair_scope. Notation "s #1" := (fst s) (at level 9, format "s '#1'") : pair_scope. Notation "s #2" := (snd s) (at level 9, format "s '#2'") : pair_scope. Module ZPairsAxiomsMod (Import N : NAxiomsMiniSig) <: ZAxiomsMiniSig. Module Import NProp. Include NSubProp N. End NProp. Declare Scope NScope. Delimit Scope NScope with N. Bind Scope NScope with N.t. Infix "==" := N.eq (at level 70) : NScope. Notation "x ~= y" := (~ N.eq x y) (at level 70) : NScope. Notation "0" := N.zero : NScope. Notation "1" := N.one : NScope. Notation "2" := N.two : NScope. Infix "+" := N.add : NScope. Infix "-" := N.sub : NScope. Infix "*" := N.mul : NScope. Infix "<" := N.lt : NScope. Infix "<=" := N.le : NScope. Local Open Scope NScope.
The definitions of functions (add, mul, etc.) will be unfolded
by the properties functor. Since we don't want add_comm to refer
to unfolded definitions of equality: fun p1 p2 ⇒ (fst p1 +
snd p2) = (fst p2 + snd p1), we will provide an extra layer of
definitions.
Module Z. Definition t := (N.t * N.t)%type. Definition zero : t := (0, 0). Definition one : t := (1,0). Definition two : t := (2,0). Definition eq (p q : t) := (p#1 + q#2 == q#1 + p#2). Definition succ (n : t) : t := (N.succ n#1, n#2). Definition pred (n : t) : t := (n#1, N.succ n#2). Definition opp (n : t) : t := (n#2, n#1). Definition add (n m : t) : t := (n#1 + m#1, n#2 + m#2). Definition sub (n m : t) : t := (n#1 + m#2, n#2 + m#1). Definition mul (n m : t) : t := (n#1 * m#1 + n#2 * m#2, n#1 * m#2 + n#2 * m#1). Definition lt (n m : t) := n#1 + m#2 < m#1 + n#2. Definition le (n m : t) := n#1 + m#2 <= m#1 + n#2. Definition min (n m : t) : t := (min (n#1 + m#2) (m#1 + n#2), n#2 + m#2). Definition max (n m : t) : t := (max (n#1 + m#2) (m#1 + n#2), n#2 + m#2).
NB : We do not have Z.pred (Z.succ n) = n but only Z.pred (Z.succ n) == n.
It could be possible to consider as canonical only pairs where
one of the elements is 0, and make all operations convert
canonical values into other canonical values. In that case, we
could get rid of setoids and arrive at integers as signed natural
numbers.
NB : Unfortunately, the elements of the pair keep increasing during
many operations, even during subtraction.
End Z. Declare Scope ZScope. Delimit Scope ZScope with Z. Bind Scope ZScope with Z.t. Infix "==" := Z.eq (at level 70) : ZScope. Notation "x ~= y" := (~ Z.eq x y) (at level 70) : ZScope. Notation "0" := Z.zero : ZScope. Notation "1" := Z.one : ZScope. Notation "2" := Z.two : ZScope. Infix "+" := Z.add : ZScope. Infix "-" := Z.sub : ZScope. Infix "*" := Z.mul : ZScope. Notation "- x" := (Z.opp x) : ZScope. Infix "<" := Z.lt : ZScope. Infix "<=" := Z.le : ZScope. Local Open Scope ZScope.forall n m : Z.t, n - m = n + - mreflexivity. Qed.forall n m : Z.t, n - m = n + - mEquivalence Z.eqEquivalence Z.eqReflexive Z.eqSymmetric Z.eqTransitive Z.eqforall x : Z.t, (x#1 + x#2 == x#1 + x#2)%NSymmetric Z.eqTransitive Z.eqSymmetric Z.eqTransitive Z.eqTransitive Z.eqforall x y z : Z.t, (x#1 + y#2 == y#1 + x#2)%N -> (y#1 + z#2 == z#1 + y#2)%N -> (x#1 + z#2 == z#1 + x#2)%Nn1, n2, m1, m2, p1, p2:tH1:(n1 + m2 == m1 + n2)%NH2:(m1 + p2 == p1 + m2)%N(n1 + p2 == p1 + n2)%Nn1, n2, m1, m2, p1, p2:tH1:(n1 + m2 == m1 + n2)%NH2:(m1 + p2 == p1 + m2)%N(n1 + p2 + (m1 + m2) == p1 + n2 + (m1 + m2))%Nnow rewrite add_shuffle1, (add_comm m1). Qed.n1, n2, m1, m2, p1, p2:tH1:(n1 + m2 == m1 + n2)%NH2:(m1 + p2 == p1 + m2)%N(p1 + m2 + (n2 + m1) == p1 + n2 + (m1 + m2))%NProper (eq ==> eq ==> Z.eq) pairintros n1 n2 H1 m1 m2 H2; unfold Z.eq; simpl; now rewrite H1, H2. Qed.Proper (eq ==> eq ==> Z.eq) pairProper (Z.eq ==> Z.eq) Z.succProper (Z.eq ==> Z.eq) Z.succdo 2 rewrite add_succ_l; now rewrite H. Qed.n, m:Z.tH:(n#1 + m#2 == m#1 + n#2)%N(succ n#1 + m#2 == succ m#1 + n#2)%NProper (Z.eq ==> Z.eq) Z.predProper (Z.eq ==> Z.eq) Z.preddo 2 rewrite add_succ_r; now rewrite H. Qed.n, m:Z.tH:(n#1 + m#2 == m#1 + n#2)%N(n#1 + succ m#2 == m#1 + succ n#2)%NProper (Z.eq ==> Z.eq ==> Z.eq) Z.addProper (Z.eq ==> Z.eq ==> Z.eq) Z.addnow rewrite add_shuffle1, H1, H2, add_shuffle1. Qed.n1, m1:Z.tH1:(n1#1 + m1#2 == m1#1 + n1#2)%Nn2, m2:Z.tH2:(n2#1 + m2#2 == m2#1 + n2#2)%N(n1#1 + n2#1 + (m1#2 + m2#2) == m1#1 + m2#1 + (n1#2 + n2#2))%NProper (Z.eq ==> Z.eq) Z.oppProper (Z.eq ==> Z.eq) Z.oppnow rewrite (add_comm n2), (add_comm m2). Qed.n1, n2, m1, m2:tH:(n1 + m2 == m1 + n2)%N(n2 + m1 == m2 + n1)%NProper (Z.eq ==> Z.eq ==> Z.eq) Z.subProper (Z.eq ==> Z.eq ==> Z.eq) Z.subn1, m1:Z.tH1:n1 == m1n2, m2:Z.tH2:n2 == m2n1 - n2 == m1 - m2now do 2 f_equiv. Qed.n1, m1:Z.tH1:n1 == m1n2, m2:Z.tH2:n2 == m2n1 + - n2 == m1 + - m2forall n m : Z.t, n * m == m * nforall n m : Z.t, n * m == m * nn1, n2, m1, m2:t(n1 * m1 + n2 * m2 + (m1 * n2 + m2 * n1) == m1 * n1 + m2 * n2 + (n1 * m2 + n2 * m1))%Ndo 2 f_equiv; apply mul_comm. Qed.n1, n2, m1, m2:t(n1 * m1 + n2 * m2 + (m2 * n1 + m1 * n2) == m1 * n1 + m2 * n2 + (n1 * m2 + n2 * m1))%NProper (Z.eq ==> Z.eq ==> Z.eq) Z.mulProper (Z.eq ==> Z.eq ==> Z.eq) Z.mulforall n : Z.t, Proper (Z.eq ==> Z.eq) (Z.mul n)H:forall n : Z.t, Proper (Z.eq ==> Z.eq) (Z.mul n)Proper (Z.eq ==> Z.eq ==> Z.eq) Z.mulforall n : Z.t, Proper ((fun p q : Z.t => (p#1 + q#2 == q#1 + p#2)%N) ==> (fun p q : Z.t => (p#1 + q#2 == q#1 + p#2)%N)) (fun m : Z.t => ((n#1 * m#1 + n#2 * m#2)%N, (n#1 * m#2 + n#2 * m#1)%N))H:forall n : Z.t, Proper (Z.eq ==> Z.eq) (Z.mul n)Proper (Z.eq ==> Z.eq ==> Z.eq) Z.muln1, n2, p1, p2, q1, q2:tH:(p1 + q2 == q1 + p2)%N(n1 * p1 + n2 * p2 + (n1 * q2 + n2 * q1) == n1 * q1 + n2 * q2 + (n1 * p2 + n2 * p1))%NH:forall n : Z.t, Proper (Z.eq ==> Z.eq) (Z.mul n)Proper (Z.eq ==> Z.eq ==> Z.eq) Z.muln1, n2, p1, p2, q1, q2:tH:(p1 + q2 == q1 + p2)%N(n1 * q2 + n1 * p1 + (n2 * p2 + n2 * q1) == n1 * q1 + n2 * q2 + (n1 * p2 + n2 * p1))%NH:forall n : Z.t, Proper (Z.eq ==> Z.eq) (Z.mul n)Proper (Z.eq ==> Z.eq ==> Z.eq) Z.muln1, n2, p1, p2, q1, q2:tH:(p1 + q2 == q1 + p2)%N(n1 * q1 + n2 * q2 + (n1 * p2 + n2 * p1) == n1 * q2 + n1 * p1 + (n2 * p2 + n2 * q1))%NH:forall n : Z.t, Proper (Z.eq ==> Z.eq) (Z.mul n)Proper (Z.eq ==> Z.eq ==> Z.eq) Z.muln1, n2, p1, p2, q1, q2:tH:(p1 + q2 == q1 + p2)%N(n1 * q1 + n1 * p2 + (n2 * q2 + n2 * p1) == n1 * q2 + n1 * p1 + (n2 * p2 + n2 * q1))%NH:forall n : Z.t, Proper (Z.eq ==> Z.eq) (Z.mul n)Proper (Z.eq ==> Z.eq ==> Z.eq) Z.muln1, n2, p1, p2, q1, q2:tH:(p1 + q2 == q1 + p2)%N(n1 * (q1 + p2) + n2 * (q2 + p1) == n1 * (q2 + p1) + n2 * (p2 + q1))%NH:forall n : Z.t, Proper (Z.eq ==> Z.eq) (Z.mul n)Proper (Z.eq ==> Z.eq ==> Z.eq) Z.muln1, n2, p1, p2, q1, q2:tH:(p1 + q2 == q1 + p2)%N(n1 * (q1 + p2) + n2 * (q1 + p2) == n1 * (q1 + p2) + n2 * (q1 + p2))%NH:forall n : Z.t, Proper (Z.eq ==> Z.eq) (Z.mul n)Proper (Z.eq ==> Z.eq ==> Z.eq) Z.mulH:forall n : Z.t, Proper (Z.eq ==> Z.eq) (Z.mul n)Proper (Z.eq ==> Z.eq ==> Z.eq) Z.mulH:forall n0 : Z.t, Proper (Z.eq ==> Z.eq) (Z.mul n0)n, n':Z.tHn:n == n'm, m':Z.tHm:m == m'n * m == n' * m'reflexivity. Qed. Section Induction. Variable A : Z.t -> Prop. Hypothesis A_wd : Proper (Z.eq==>iff) A.H:forall n0 : Z.t, Proper (Z.eq ==> Z.eq) (Z.mul n0)n, n':Z.tHn:n == n'm, m':Z.tHm:m == m'm' * n' == m' * n'A:Z.t -> PropA_wd:Proper (Z.eq ==> iff) AA 0 -> (forall n : Z.t, A n <-> A (Z.succ n)) -> forall n : Z.t, A nA:Z.t -> PropA_wd:Proper (Z.eq ==> iff) AA 0 -> (forall n : Z.t, A n <-> A (Z.succ n)) -> forall n : Z.t, A nA:Z.t -> PropA_wd:Proper (Z.eq ==> iff) AA 0 -> (forall n : Z.t, A n <-> A (Z.succ n)) -> forall n : Z.t, A nA:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n:Z.tA nA:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tA (n, m)A:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tH1:forall p : t, A (p, 0)A (n, m)A:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tforall p : t, A (p, 0)A:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tH1:forall p : t, A (p, 0)H2:forall p : t, A (0, p)A (n, m)A:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tH1:forall p : t, A (p, 0)forall p : t, A (0, p)A:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tforall p : t, A (p, 0)A:Z.t -> PropA_wd:Proper ((fun p0 q : Z.t => p0#1 + q#2 == q#1 + p0#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tH1:forall p0 : t, A (p0, 0)H2:forall p0 : t, A (0, p0)p:tH:p + n == mA (n, m)A:Z.t -> PropA_wd:Proper ((fun p0 q : Z.t => p0#1 + q#2 == q#1 + p0#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tH1:forall p0 : t, A (p0, 0)H2:forall p0 : t, A (0, p0)p:tH:p + m == nA (n, m)A:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tH1:forall p : t, A (p, 0)forall p : t, A (0, p)A:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tforall p : t, A (p, 0)A:Z.t -> PropA_wd:Proper ((fun p0 q : Z.t => p0#1 + q#2 == q#1 + p0#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tH1:forall p0 : t, A (p0, 0)H2:forall p0 : t, A (0, p0)p:tH:p + n == mA (0, p)A:Z.t -> PropA_wd:Proper ((fun p0 q : Z.t => p0#1 + q#2 == q#1 + p0#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tH1:forall p0 : t, A (p0, 0)H2:forall p0 : t, A (0, p0)p:tH:p + m == nA (n, m)A:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tH1:forall p : t, A (p, 0)forall p : t, A (0, p)A:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tforall p : t, A (p, 0)A:Z.t -> PropA_wd:Proper ((fun p0 q : Z.t => p0#1 + q#2 == q#1 + p0#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tH1:forall p0 : t, A (p0, 0)H2:forall p0 : t, A (0, p0)p:tH:p + m == nA (n, m)A:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tH1:forall p : t, A (p, 0)forall p : t, A (0, p)A:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tforall p : t, A (p, 0)A:Z.t -> PropA_wd:Proper ((fun p0 q : Z.t => p0#1 + q#2 == q#1 + p0#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tH1:forall p0 : t, A (p0, 0)H2:forall p0 : t, A (0, p0)p:tH:p + m == nA (p, 0)A:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tH1:forall p : t, A (p, 0)forall p : t, A (0, p)A:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tforall p : t, A (p, 0)A:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tH1:forall p : t, A (p, 0)forall p : t, A (0, p)A:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tforall p : t, A (p, 0)A:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tH1:forall p : t, A (p, 0)A (0, 0)A:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tH1:forall p : t, A (p, 0)forall n0 : t, A (0, n0) -> A (0, succ n0)A:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tforall p : t, A (p, 0)A:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tH1:forall p : t, A (p, 0)forall n0 : t, A (0, n0) -> A (0, succ n0)A:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tforall p : t, A (p, 0)A:Z.t -> PropA_wd:Proper ((fun p0 q : Z.t => p0#1 + q#2 == q#1 + p0#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tH1:forall p0 : t, A (p0, 0)p:tIH:A (0, p)A (0, succ p)A:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tforall p : t, A (p, 0)A:Z.t -> PropA_wd:Proper ((fun p0 q : Z.t => p0#1 + q#2 == q#1 + p0#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tH1:forall p0 : t, A (p0, 0)p:tIH:A (1, succ p)A (0, succ p)A:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tforall p : t, A (p, 0)A:Z.t -> PropA_wd:Proper ((fun p0 q : Z.t => p0#1 + q#2 == q#1 + p0#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tH1:forall p0 : t, A (p0, 0)p:tIH:A (succ 0, succ p)A (0, succ p)A:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tforall p : t, A (p, 0)A:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tforall p : t, A (p, 0)A:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tA (0, 0)A:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tforall n0 : t, A (n0, 0) -> A (succ n0, 0)A:Z.t -> PropA_wd:Proper ((fun p q : Z.t => p#1 + q#2 == q#1 + p#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m:tforall n0 : t, A (n0, 0) -> A (succ n0, 0)A:Z.t -> PropA_wd:Proper ((fun p0 q : Z.t => p0#1 + q#2 == q#1 + p0#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m, p:tIH:A (p, 0)A (succ p, 0)A:Z.t -> PropA_wd:Proper ((fun p0 q : Z.t => p0#1 + q#2 == q#1 + p0#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m, p:tIH:A (p, 0)A (succ p, (p, 0)#2)now apply -> AS. Close Scope NScope. Qed. End Induction. (* Time to prove theorems in the language of Z *)A:Z.t -> PropA_wd:Proper ((fun p0 q : Z.t => p0#1 + q#2 == q#1 + p0#2) ==> iff) AA0:A (0, 0)AS:forall n0 : Z.t, A n0 <-> A (succ n0#1, n0#2)n, m, p:tIH:A (p, 0)A (succ (p, 0)#1, (p, 0)#2)forall n : Z.t, Z.pred (Z.succ n) == nunfold Z.pred, Z.succ, Z.eq; intro n; simpl; now nzsimpl. Qed.forall n : Z.t, Z.pred (Z.succ n) == nforall n : Z.t, Z.succ (Z.pred n) == nintro n; unfold Z.succ, Z.pred, Z.eq; simpl; now nzsimpl. Qed.forall n : Z.t, Z.succ (Z.pred n) == n1 == Z.succ 01 == Z.succ 0now nzsimpl'. Qed.(1 + 0 == succ 0 + 0)%N2 == Z.succ 12 == Z.succ 1now nzsimpl'. Qed.(2 + 0 == succ 1 + 0)%N- 0 == 0- 0 == 0now nzsimpl. Qed.(0 + 0 == 0 + 0)%Nforall n : Z.t, - Z.succ n == Z.pred (- n)reflexivity. Qed.forall n : Z.t, - Z.succ n == Z.pred (- n)forall n : Z.t, 0 + n == nforall n : Z.t, 0 + n == nnow nzsimpl. Qed.n:Z.t(0 + n#1 + n#2 == n#1 + (0 + n#2))%Nforall n m : Z.t, Z.succ n + m == Z.succ (n + m)forall n m : Z.t, Z.succ n + m == Z.succ (n + m)now nzsimpl. Qed.n, m:Z.t(succ n#1 + m#1 + (n#2 + m#2) == succ (n#1 + m#1) + (n#2 + m#2))%Nforall n : Z.t, n - 0 == nforall n : Z.t, n - 0 == nnow nzsimpl. Qed.n:Z.t(n#1 + 0 + n#2 == n#1 + (n#2 + 0))%Nforall n m : Z.t, n - Z.succ m == Z.pred (n - m)forall n m : Z.t, n - Z.succ m == Z.pred (n - m)symmetry; now rewrite add_succ_r. Qed.n, m:Z.t(n#1 + m#2 + succ (n#2 + m#1) == n#1 + m#2 + (n#2 + succ m#1))%Nforall n : Z.t, 0 * n == 0intros (n1,n2); unfold Z.mul, Z.eq; simpl; now nzsimpl. Qed.forall n : Z.t, 0 * n == 0forall n m : Z.t, Z.succ n * m == n * m + mforall n m : Z.t, Z.succ n * m == n * m + mn1, n2, m1, m2:t(n1 * m1 + m1 + n2 * m2 + (n1 * m2 + n2 * m1 + m2) == n1 * m1 + n2 * m2 + m1 + (n1 * m2 + m2 + n2 * m1))%Nnow rewrite <- (add_assoc _ m2), (add_comm m2), (add_assoc _ (n2*m1)%N m2). Qed.n1, n2, m1, m2:t(n1 * m1 + n2 * m2 + m1 + (n1 * m2 + n2 * m1 + m2) == n1 * m1 + n2 * m2 + m1 + (n1 * m2 + m2 + n2 * m1))%N
Order
forall n m : Z.t, n <= m <-> n < m \/ n == mintros; apply N.lt_eq_cases. Qed.forall n m : Z.t, n <= m <-> n < m \/ n == mforall n : Z.t, ~ n < nintros; apply N.lt_irrefl. Qed.forall n : Z.t, ~ n < nforall n m : Z.t, n < Z.succ m <-> n <= mforall n m : Z.t, n < Z.succ m <-> n <= mapply lt_succ_r. Qed.n, m:Z.t(n#1 + m#2 < succ (m#1 + n#2))%N <-> (n#1 + m#2 <= m#1 + n#2)%Nforall n m : Z.t, n <= m -> Z.min n m == nforall n m : Z.t, n <= m -> Z.min n m == nn1, n2, m1, m2:tH:(n1 + m2 <= m1 + n2)%N(min (n1 + m2) (m1 + n2) + n2 == n1 + (n2 + m2))%Nnow rewrite <- add_assoc, (add_comm m2). Qed.n1, n2, m1, m2:tH:(n1 + m2 <= m1 + n2)%N(n1 + m2 + n2 == n1 + (n2 + m2))%Nforall n m : Z.t, m <= n -> Z.min n m == mforall n m : Z.t, m <= n -> Z.min n m == mn1, n2, m1, m2:tH:(m1 + n2 <= n1 + m2)%N(min (n1 + m2) (m1 + n2) + m2 == m1 + (n2 + m2))%Nnow rewrite add_assoc. Qed.n1, n2, m1, m2:tH:(m1 + n2 <= n1 + m2)%N(m1 + n2 + m2 == m1 + (n2 + m2))%Nforall n m : Z.t, m <= n -> Z.max n m == nforall n m : Z.t, m <= n -> Z.max n m == nn1, n2, m1, m2:tH:(m1 + n2 <= n1 + m2)%N(max (n1 + m2) (m1 + n2) + n2 == n1 + (n2 + m2))%Nnow rewrite <- add_assoc, (add_comm m2). Qed.n1, n2, m1, m2:tH:(m1 + n2 <= n1 + m2)%N(n1 + m2 + n2 == n1 + (n2 + m2))%Nforall n m : Z.t, n <= m -> Z.max n m == mforall n m : Z.t, n <= m -> Z.max n m == mn, m:Z.tH:(n#1 + m#2 <= m#1 + n#2)%N(max (n#1 + m#2) (m#1 + n#2) + m#2 == m#1 + (n#2 + m#2))%Nnow rewrite add_assoc. Qed.n, m:Z.tH:(n#1 + m#2 <= m#1 + n#2)%N(m#1 + n#2 + m#2 == m#1 + (n#2 + m#2))%Nforall n m : Z.t, n < m <-> ~ m <= nforall n m : Z.t, n < m <-> ~ m <= napply lt_nge. Qed.n, m:Z.tn < m <-> ~ m <= nProper (Z.eq ==> Z.eq ==> iff) Z.ltProper (Z.eq ==> Z.eq ==> iff) Z.ltforall n : Z.t, Proper (Z.eq ==> iff) (Z.lt n)H:forall n : Z.t, Proper (Z.eq ==> iff) (Z.lt n)Proper (Z.eq ==> Z.eq ==> iff) Z.ltn1, n2:tProper (Z.eq ==> iff) (Z.lt (n1, n2))H:forall n : Z.t, Proper (Z.eq ==> iff) (Z.lt n)Proper (Z.eq ==> Z.eq ==> iff) Z.ltn1, n2:tProper (Z.eq ==> Basics.impl) (Z.lt (n1, n2))H:forall n : Z.t, Proper (Z.eq ==> iff) (Z.lt n)Proper (Z.eq ==> Z.eq ==> iff) Z.ltn1, n2, r1, r2, s1, s2:tEq:(r1 + s2 == s1 + r2)%NH:(n1 + r2 < r1 + n2)%N(n1 + s2 < s1 + n2)%NH:forall n : Z.t, Proper (Z.eq ==> iff) (Z.lt n)Proper (Z.eq ==> Z.eq ==> iff) Z.ltn1, n2, r1, r2, s1, s2:tEq:(r1 + s2 == s1 + r2)%NH:(n1 + r2 < r1 + n2)%N(n1 + s2 + (r1 + r2) < s1 + n2 + (r1 + r2))%NH:forall n : Z.t, Proper (Z.eq ==> iff) (Z.lt n)Proper (Z.eq ==> Z.eq ==> iff) Z.ltn1, n2, r1, r2, s1, s2:tEq:(r1 + s2 == s1 + r2)%NH:(n1 + r2 < r1 + n2)%N(n1 + r2 + (s1 + r2) < s1 + n2 + (r1 + r2))%NH:forall n : Z.t, Proper (Z.eq ==> iff) (Z.lt n)Proper (Z.eq ==> Z.eq ==> iff) Z.ltn1, n2, r1, r2, s1, s2:tEq:(r1 + s2 == s1 + r2)%NH:(n1 + r2 < r1 + n2)%N(n1 + r2 + (s1 + r2) < r1 + n2 + (s1 + r2))%NH:forall n : Z.t, Proper (Z.eq ==> iff) (Z.lt n)Proper (Z.eq ==> Z.eq ==> iff) Z.ltH:forall n : Z.t, Proper (Z.eq ==> iff) (Z.lt n)Proper (Z.eq ==> Z.eq ==> iff) Z.ltH:forall n0 : Z.t, Proper (Z.eq ==> iff) (Z.lt n0)n, n':Z.tHn:n == n'm, m':Z.tHm:m == m'n < m <-> n' < m'rewrite 2 lt_nge, 2 lt_eq_cases, Hn; auto with *. Qed. Definition t := Z.t. Definition eq := Z.eq. Definition zero := Z.zero. Definition one := Z.one. Definition two := Z.two. Definition succ := Z.succ. Definition pred := Z.pred. Definition add := Z.add. Definition sub := Z.sub. Definition mul := Z.mul. Definition opp := Z.opp. Definition lt := Z.lt. Definition le := Z.le. Definition min := Z.min. Definition max := Z.max. End ZPairsAxiomsMod. (* For example, let's build integers out of pairs of Peano natural numbers and get their properties *) (* The following lines increase the compilation time at least twice *) (* Require PeanoNat. Module Export ZPairsPeanoAxiomsMod := ZPairsAxiomsMod PeanoNat.Nat. Module Export ZPairsPropMod := ZPropFunct ZPairsPeanoAxiomsMod. Eval compute in (3, 5) * (4, 6). *)H:forall n0 : Z.t, Proper (Z.eq ==> iff) (Z.lt n0)n, n':Z.tHn:n == n'm, m':Z.tHm:m == m'n < m' <-> n' < m'