aboutsummaryrefslogtreecommitdiffhomepage
path: root/theories/Numbers/Natural/Axioms/NBase.v
diff options
context:
space:
mode:
Diffstat (limited to 'theories/Numbers/Natural/Axioms/NBase.v')
-rw-r--r--theories/Numbers/Natural/Axioms/NBase.v196
1 files changed, 196 insertions, 0 deletions
diff --git a/theories/Numbers/Natural/Axioms/NBase.v b/theories/Numbers/Natural/Axioms/NBase.v
new file mode 100644
index 000000000..fd483265d
--- /dev/null
+++ b/theories/Numbers/Natural/Axioms/NBase.v
@@ -0,0 +1,196 @@
+Require Export NumPrelude.
+Require Import NZBase.
+
+Module Type NBaseSig.
+
+Parameter Inline N : Set.
+Parameter Inline E : N -> N -> Prop.
+Parameter Inline O : N.
+Parameter Inline S : N -> N.
+
+Delimit Scope NatScope with Nat.
+Open Local Scope NatScope.
+
+Notation "x == y" := (E x y) (at level 70) : NatScope.
+Notation "x ~= y" := (~ E x y) (at level 70) : NatScope.
+Notation "0" := O : NatScope.
+Notation "1" := (S O) : NatScope.
+
+Axiom E_equiv : equiv N E.
+Add Relation N E
+ reflexivity proved by (proj1 E_equiv)
+ symmetry proved by (proj2 (proj2 E_equiv))
+ transitivity proved by (proj1 (proj2 E_equiv))
+as E_rel.
+
+Add Morphism S with signature E ==> E as S_wd.
+
+Axiom succ_inj : forall n1 n2 : N, S n1 == S n2 -> n1 == n2.
+Axiom succ_neq_0 : forall n : N, S n ~= 0.
+
+Axiom induction :
+ forall A : N -> Prop, predicate_wd E A ->
+ A 0 -> (forall n : N, A n -> A (S n)) -> forall n : N, A n.
+
+End NBaseSig.
+
+Module NBasePropFunct (Import NBaseMod : NBaseSig).
+Open Local Scope NatScope.
+
+(*Theorem E_equiv : equiv N E.
+Proof E_equiv.
+
+Theorem succ_inj_wd : forall n1 n2 : N, S n1 == S n2 <-> n1 == n2.
+Proof succ_inj_wd.
+
+Theorem succ_neq_0 : forall n : N, S n ~= 0.
+Proof succ_neq_0.
+
+Theorem induction :
+ forall A : N -> Prop, predicate_wd E A ->
+ A 0 -> (forall n : N, A n -> A (S n)) -> forall n : N, A n.
+Proof induction.*)
+
+Module NZBaseMod <: NZBaseSig.
+Definition NZ := N.
+Definition NZE := E.
+Definition NZ0 := 0.
+Definition NZsucc := S.
+
+(* Axioms *)
+Definition NZE_equiv := E_equiv.
+Definition NZsucc_inj := succ_inj.
+
+Add Relation NZ NZE
+ reflexivity proved by (proj1 NZE_equiv)
+ symmetry proved by (proj2 (proj2 NZE_equiv))
+ transitivity proved by (proj1 (proj2 NZE_equiv))
+as NZE_rel.
+
+Add Morphism NZsucc with signature NZE ==> NZE as NZsucc_wd.
+Proof S_wd.
+
+Theorem NZinduction :
+ forall A : N -> Prop, predicate_wd E A ->
+ A 0 -> (forall n : N, A n <-> A (S n)) -> forall n : N, A n.
+Proof.
+intros A A_wd Base Step.
+apply induction; try assumption.
+intros; now apply -> Step.
+Qed.
+
+End NZBaseMod.
+
+Module Export NZBasePropMod := NZBasePropFunct NZBaseMod.
+
+Theorem neq_symm : forall n m : N, n ~= m -> m ~= n.
+Proof NZneq_symm.
+
+Theorem succ_inj_wd_neg : forall n m : N, S n ~= S m <-> n ~= m.
+Proof NZsucc_inj_wd_neg.
+
+Ltac induct n := induction_maker n ltac:(apply induction).
+
+Theorem nondep_induction :
+ forall A : N -> Prop, predicate_wd E A ->
+ A 0 -> (forall n : N, A (S n)) -> forall n : N, A n.
+Proof.
+intros; apply induction; auto.
+Qed.
+
+Ltac nondep_induct n := induction_maker n ltac:(apply nondep_induction).
+
+Theorem neq_0 : ~ forall n, n == 0.
+Proof.
+intro H; apply (succ_neq_0 0). apply H.
+Qed.
+
+Theorem neq_0_succ : forall n, n ~= 0 <-> exists m, n == S m.
+Proof.
+nondep_induct n. split; intro H;
+[now elim H | destruct H as [m H]; symmetry in H; false_hyp H succ_neq_0].
+intro n; split; intro H; [now exists n | apply succ_neq_0].
+Qed.
+
+Theorem zero_or_succ : forall n, n == 0 \/ exists m, n == S m.
+Proof.
+nondep_induct n; [now left | intros n; right; now exists n].
+Qed.
+
+(* The following is useful for reasoning about, e.g., Fibonacci numbers *)
+Section DoubleInduction.
+
+Variable A : N -> Prop.
+Hypothesis A_wd : predicate_wd E A.
+
+Add Morphism A with signature E ==> iff as A_morph.
+Proof.
+exact A_wd.
+Qed.
+
+Theorem double_induction :
+ A 0 -> A 1 ->
+ (forall n, A n -> A (S n) -> A (S (S n))) -> forall n, A n.
+Proof.
+intros until 3.
+assert (D : forall n, A n /\ A (S n)); [ |intro n; exact (proj1 (D n))].
+induct n; [ | intros n [IH1 IH2]]; auto.
+Qed.
+
+End DoubleInduction.
+
+Ltac double_induct n := induction_maker n ltac:(apply double_induction).
+
+(* The following is useful for reasoning about, e.g., Ackermann function *)
+Section TwoDimensionalInduction.
+
+Variable R : N -> N -> Prop.
+Hypothesis R_wd : rel_wd E E R.
+
+Add Morphism R with signature E ==> E ==> iff as R_morph.
+Proof.
+exact R_wd.
+Qed.
+
+Theorem two_dim_induction :
+ R 0 0 ->
+ (forall n m, R n m -> R n (S m)) ->
+ (forall n, (forall m, R n m) -> R (S n) 0) -> forall n m, R n m.
+Proof.
+intros H1 H2 H3. induct n.
+induct m.
+exact H1. exact (H2 0).
+intros n IH. induct m.
+now apply H3. exact (H2 (S n)).
+Qed.
+
+End TwoDimensionalInduction.
+
+Ltac two_dim_induct n m :=
+ try intros until n;
+ try intros until m;
+ pattern n, m; apply two_dim_induction; clear n m;
+ [unfold rel_wd; unfold fun2_wd;
+ let x1 := fresh "x" in
+ let y1 := fresh "y" in
+ let H1 := fresh "H" in
+ let x2 := fresh "x" in
+ let y2 := fresh "y" in
+ let H2 := fresh "H" in
+ intros x1 y1 H1 x2 y2 H2;
+ qsetoid_rewrite H1;
+ qiff x2 y2 H2 | | | ].
+(* This is not a very efficient approach because qsetoid_rewrite uses
+qiff to take the formula apart in order to make it quantifier-free,
+and then qiff is called again and takes the formula apart for the
+second time. It is better to analyze the formula once and generalize
+qiff to take a list of equalities that it has to rewrite. *)
+
+End NBasePropFunct.
+
+
+(*
+ Local Variables:
+ tags-file-name: "~/coq/trunk/theories/Numbers/TAGS"
+ End:
+*)