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) *) (************************************************************************) Require Export NumPrelude NZAxioms. Require Import NZBase NZOrder NZAddOrder Plus Minus.
In this file, we investigate the shape of domains satisfying
the NZDomainSig interface. In particular, we define a
translation from Peano numbers nat into NZ.
Local Notation "f ^ n" := (fun x => nat_rect _ x (fun _ => f) n).n:natA:TypeR:relation AProper (R ==> (R ==> R) ==> R) (fun (x : A) (f : A -> A) => nat_rect (fun _ : nat => A) x (fun _ : nat => f) n)intros x y eq_xy f g eq_fg; induction n; [assumption | now apply eq_fg]. Qed. Module NZDomainProp (Import NZ:NZDomainSig'). Include NZBaseProp NZ.n:natA:TypeR:relation AProper (R ==> (R ==> R) ==> R) (fun (x : A) (f : A -> A) => nat_rect (fun _ : nat => A) x (fun _ : nat => f) n)
For any two points, one is an iterated successor of the other.
n, m:texists k : nat, n == (S ^ k) m \/ m == (S ^ k) nn, m:texists k : nat, n == (S ^ k) m \/ m == (S ^ k) nm:tforall n : t, exists k : nat, n == (S ^ k) m \/ m == (S ^ k) nm:tProper (eq ==> iff) (fun n : t => exists k : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k)m:texists k : nat, m == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k \/ m == nat_rect (fun _ : nat => t) m (fun _ : nat => S) km:tforall n : t, (exists k : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k) <-> (exists k : nat, S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k \/ m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) k)m:tProper (eq ==> iff) (fun n : t => exists k : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k)m, x, y:teq_xy:x == ypointwise_relation nat iff (fun k : nat => x == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k \/ m == nat_rect (fun _ : nat => t) x (fun _ : nat => S) k) (fun k : nat => y == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k \/ m == nat_rect (fun _ : nat => t) y (fun _ : nat => S) k)m, x, y:teq_xy:x == yn:natx == nat_rect (fun _ : nat => t) m (fun _ : nat => S) n <-> y == nat_rect (fun _ : nat => t) m (fun _ : nat => S) nm, x, y:teq_xy:x == yn:natm == nat_rect (fun _ : nat => t) x (fun _ : nat => S) n <-> m == nat_rect (fun _ : nat => t) y (fun _ : nat => S) nsplit; intros; etransitivity; try eassumption; now symmetry.m, x, y:teq_xy:x == yn:natx == nat_rect (fun _ : nat => t) m (fun _ : nat => S) n <-> y == nat_rect (fun _ : nat => t) m (fun _ : nat => S) nsplit; intros; (etransitivity; [eassumption|]); [|symmetry]; (eapply nat_rect_wd; [eassumption|apply succ_wd]).m, x, y:teq_xy:x == yn:natm == nat_rect (fun _ : nat => t) x (fun _ : nat => S) n <-> m == nat_rect (fun _ : nat => t) y (fun _ : nat => S) nm:texists k : nat, m == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k \/ m == nat_rect (fun _ : nat => t) m (fun _ : nat => S) km:tforall n : t, (exists k : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k) <-> (exists k : nat, S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k \/ m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) k)m:tm == nat_rect (fun _ : nat => t) m (fun _ : nat => S) 0 \/ m == nat_rect (fun _ : nat => t) m (fun _ : nat => S) 0m:tforall n : t, (exists k : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k) <-> (exists k : nat, S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k \/ m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) k)m:tforall n : t, (exists k : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k) <-> (exists k : nat, S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k \/ m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) k)m, n:t(exists k : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k) <-> (exists k : nat, S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k \/ m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) k)m, n:tk:natL:n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) kexists k0 : nat, S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) k0m, n:tk:natR:m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) kexists k0 : nat, S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) k0m, n:tk:natL:S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natR:m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natL:n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) kS n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) (Datatypes.S k) \/ m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) (Datatypes.S k)m, n:tk:natR:m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) kexists k0 : nat, S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) k0m, n:tk:natL:S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natR:m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natL:n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) kS n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) (Datatypes.S k)m, n:tk:natR:m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) kexists k0 : nat, S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) k0m, n:tk:natL:S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natR:m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natR:m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) kexists k0 : nat, S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) k0m, n:tk:natL:S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natR:m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tR:m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) 0exists k : nat, S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k \/ m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) km, n:tk:natR:m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) (Datatypes.S k)exists k0 : nat, S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) k0m, n:tk:natL:S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natR:m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tR:m == nexists k : nat, S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k \/ m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) km, n:tk:natR:m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) (Datatypes.S k)exists k0 : nat, S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) k0m, n:tk:natL:S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natR:m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tR:m == nS n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) 1 \/ m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) 1m, n:tk:natR:m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) (Datatypes.S k)exists k0 : nat, S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) k0m, n:tk:natL:S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natR:m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tR:m == nS n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) 1m, n:tk:natR:m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) (Datatypes.S k)exists k0 : nat, S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) k0m, n:tk:natL:S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natR:m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natR:m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) (Datatypes.S k)exists k0 : nat, S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) k0m, n:tk:natL:S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natR:m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natR:m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) kexists k0 : nat, S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) k0m, n:tk:natL:S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natR:m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natR:m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) kS n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k \/ m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) km, n:tk:natL:S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natR:m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natL:S n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natR:m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tL:S n == mexists k : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) km, n:tk:natL:S n == S (nat_rect (fun _ : nat => t) m (fun _ : nat => S) k)exists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natR:m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tL:S n == mn == nat_rect (fun _ : nat => t) m (fun _ : nat => S) 1 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) 1m, n:tk:natL:S n == S (nat_rect (fun _ : nat => t) m (fun _ : nat => S) k)exists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natR:m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natL:S n == S (nat_rect (fun _ : nat => t) m (fun _ : nat => S) k)exists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natR:m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natL:n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natR:m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natL:n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) kn == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) km, n:tk:natR:m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natR:m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) k0m, n:tk:natR:m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) kn == nat_rect (fun _ : nat => t) m (fun _ : nat => S) (Datatypes.S k) \/ m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) (Datatypes.S k)now rewrite nat_rect_succ_r. Qed.m, n:tk:natR:m == nat_rect (fun _ : nat => t) (S n) (fun _ : nat => S) km == nat_rect (fun _ : nat => t) n (fun _ : nat => S) (Datatypes.S k)
Generalized version of pred_succ when iterating
forall (k : nat) (n m : t), n == (S ^ k) m -> m == (P ^ k) nforall (k : nat) (n m : t), n == (S ^ k) m -> m == (P ^ k) nforall n m : t, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) 0 -> m == nat_rect (fun _ : nat => t) n (fun _ : nat => P) 0k:natIHk:forall n m : t, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k -> m == nat_rect (fun _ : nat => t) n (fun _ : nat => P) kforall n m : t, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) (Datatypes.S k) -> m == nat_rect (fun _ : nat => t) n (fun _ : nat => P) (Datatypes.S k)k:natIHk:forall n m : t, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k -> m == nat_rect (fun _ : nat => t) n (fun _ : nat => P) kforall n m : t, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) (Datatypes.S k) -> m == nat_rect (fun _ : nat => t) n (fun _ : nat => P) (Datatypes.S k)k:natIHk:forall n0 m0 : t, n0 == nat_rect (fun _ : nat => t) m0 (fun _ : nat => S) k -> m0 == nat_rect (fun _ : nat => t) n0 (fun _ : nat => P) kn, m:tH:n == S (nat_rect (fun _ : nat => t) m (fun _ : nat => S) k)m == P (nat_rect (fun _ : nat => t) n (fun _ : nat => P) k)k:natIHk:forall n0 m0 : t, n0 == nat_rect (fun _ : nat => t) m0 (fun _ : nat => S) k -> m0 == nat_rect (fun _ : nat => t) n0 (fun _ : nat => P) kn, m:tH:P n == P (S (nat_rect (fun _ : nat => t) m (fun _ : nat => S) k))m == P (nat_rect (fun _ : nat => t) n (fun _ : nat => P) k)k:natIHk:forall n0 m0 : t, n0 == nat_rect (fun _ : nat => t) m0 (fun _ : nat => S) k -> m0 == nat_rect (fun _ : nat => t) n0 (fun _ : nat => P) kn, m:tH:P n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) km == P (nat_rect (fun _ : nat => t) n (fun _ : nat => P) k)rewrite <- nat_rect_succ_r in H; auto. Qed.k:natIHk:forall n0 m0 : t, n0 == nat_rect (fun _ : nat => t) m0 (fun _ : nat => S) k -> m0 == nat_rect (fun _ : nat => t) n0 (fun _ : nat => P) kn, m:tH:m == nat_rect (fun _ : nat => t) (P n) (fun _ : nat => P) km == P (nat_rect (fun _ : nat => t) n (fun _ : nat => P) k)
From a given point, all others are iterated successors
or iterated predecessors.
forall n m : t, exists k : nat, n == (S ^ k) m \/ n == (P ^ k) mforall n m : t, exists k : nat, n == (S ^ k) m \/ n == (P ^ k) mn, m:texists k : nat, n == (S ^ k) m \/ n == (P ^ k) mn, m:tk:natH:n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ n == nat_rect (fun _ : nat => t) m (fun _ : nat => P) k0n, m:tk:natH:m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ n == nat_rect (fun _ : nat => t) m (fun _ : nat => P) k0n, m:tk:natH:m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) kexists k0 : nat, n == nat_rect (fun _ : nat => t) m (fun _ : nat => S) k0 \/ n == nat_rect (fun _ : nat => t) m (fun _ : nat => P) k0apply succ_swap_pred; auto. Qed.n, m:tk:natH:m == nat_rect (fun _ : nat => t) n (fun _ : nat => S) kn == nat_rect (fun _ : nat => t) m (fun _ : nat => P) k
In particular, all points are either iterated successors of 0
or iterated predecessors of 0 (or both).
forall n : t, exists p : nat, n == (S ^ p) 0 \/ n == (P ^ p) 0forall n : t, exists p : nat, n == (S ^ p) 0 \/ n == (P ^ p) 0exact (itersucc_or_iterpred n 0). Qed.n:texists p : nat, n == (S ^ p) 0 \/ n == (P ^ p) 0
Definition initial n := forall m, n ~= S m.forall n : t, initial n <-> S (P n) ~= nforall n : t, initial n <-> S (P n) ~= nn:tinitial n -> S (P n) ~= nn:tS (P n) ~= n -> initial nn:tBn:initial nEQ:S (P n) == nFalsen:tS (P n) ~= n -> initial nn:tBn:initial nEQ:n == S (P n)Falsen:tS (P n) ~= n -> initial nn:tS (P n) ~= n -> initial nn:tNEQ:S (P n) ~= nm:tEQ:n == S mFalserewrite EQ, pred_succ; auto with *. Qed.n:tNEQ:S (P n) ~= nm:tEQ:n == S mS (P n) == nforall n : t, initial n <-> ~ (exists m : t, n == S m)firstorder. Qed.forall n : t, initial n <-> ~ (exists m : t, n == S m)
First case: let's assume such an initial point exists
(i.e. S isn't surjective)...
Section InitialExists. Hypothesis init : t. Hypothesis Initial : initial init.
... then we have unicity of this initial point.
init:tInitial:initial initforall m : t, initial m -> m == initinit:tInitial:initial initforall m : t, initial m -> m == initinit:tInitial:initial initm:tIm:initial mm == initinit:tInitial:initial initm:tIm:initial mp:natH:init == nat_rect (fun _ : nat => t) m (fun _ : nat => S) pm == initinit:tInitial:initial initm:tIm:initial mp:natH:m == nat_rect (fun _ : nat => t) init (fun _ : nat => S) pm == initinit:tInitial:initial initm:tIm:initial mH:init == nat_rect (fun _ : nat => t) m (fun _ : nat => S) 0m == initinit:tInitial:initial initm:tIm:initial mp:natH:init == nat_rect (fun _ : nat => t) m (fun _ : nat => S) (Datatypes.S p)m == initinit:tInitial:initial initm:tIm:initial mp:natH:m == nat_rect (fun _ : nat => t) init (fun _ : nat => S) pm == initinit:tInitial:initial initm:tIm:initial mp:natH:init == nat_rect (fun _ : nat => t) m (fun _ : nat => S) (Datatypes.S p)m == initinit:tInitial:initial initm:tIm:initial mp:natH:m == nat_rect (fun _ : nat => t) init (fun _ : nat => S) pm == initinit:tInitial:initial initm:tIm:initial mp:natH:m == nat_rect (fun _ : nat => t) init (fun _ : nat => S) pm == initinit:tInitial:initial initm:tIm:initial mH:m == nat_rect (fun _ : nat => t) init (fun _ : nat => S) 0m == initinit:tInitial:initial initm:tIm:initial mp:natH:m == nat_rect (fun _ : nat => t) init (fun _ : nat => S) (Datatypes.S p)m == initdestruct (Im _ H). Qed.init:tInitial:initial initm:tIm:initial mp:natH:m == nat_rect (fun _ : nat => t) init (fun _ : nat => S) (Datatypes.S p)m == init
... then all other points are descendant of it.
init:tInitial:initial initforall m : t, exists p : nat, m == (S ^ p) initinit:tInitial:initial initforall m : t, exists p : nat, m == (S ^ p) initinit:tInitial:initial initm:texists p : nat, m == (S ^ p) initinit:tInitial:initial initm:tp:natH:init == nat_rect (fun _ : nat => t) m (fun _ : nat => S) pexists p0 : nat, m == nat_rect (fun _ : nat => t) init (fun _ : nat => S) p0init:tInitial:initial initm:tp:natH:m == nat_rect (fun _ : nat => t) init (fun _ : nat => S) pexists p0 : nat, m == nat_rect (fun _ : nat => t) init (fun _ : nat => S) p0init:tInitial:initial initm:tH:init == mexists p : nat, m == nat_rect (fun _ : nat => t) init (fun _ : nat => S) pinit:tInitial:initial initm:tp:natH:init == S (nat_rect (fun _ : nat => t) m (fun _ : nat => S) p)exists p0 : nat, m == nat_rect (fun _ : nat => t) init (fun _ : nat => S) p0init:tInitial:initial initm:tp:natH:m == nat_rect (fun _ : nat => t) init (fun _ : nat => S) pexists p0 : nat, m == nat_rect (fun _ : nat => t) init (fun _ : nat => S) p0init:tInitial:initial initm:tp:natH:init == S (nat_rect (fun _ : nat => t) m (fun _ : nat => S) p)exists p0 : nat, m == nat_rect (fun _ : nat => t) init (fun _ : nat => S) p0init:tInitial:initial initm:tp:natH:m == nat_rect (fun _ : nat => t) init (fun _ : nat => S) pexists p0 : nat, m == nat_rect (fun _ : nat => t) init (fun _ : nat => S) p0exists p; auto. Qed.init:tInitial:initial initm:tp:natH:m == nat_rect (fun _ : nat => t) init (fun _ : nat => S) pexists p0 : nat, m == nat_rect (fun _ : nat => t) init (fun _ : nat => S) p0
NB : We would like to have pred n == n for the initial element,
but nothing forces that. For instance we can have -3 as initial point,
and P(-3) = 2. A bit odd indeed, but legal according to NZDomainSig.
We can hence have n == (P^k) m without ∃ k', m == (S^k') n.
We need decidability of eq (or classical reasoning) for this:
Section SuccPred. Hypothesis eq_decidable : forall n m, n==m \/ n~=m.init:tInitial:initial initeq_decidable:forall n m : t, n == m \/ n ~= mforall n : t, ~ initial n -> S (P n) == ninit:tInitial:initial initeq_decidable:forall n m : t, n == m \/ n ~= mforall n : t, ~ initial n -> S (P n) == ninit:tInitial:initial initeq_decidable:forall n0 m : t, n0 == m \/ n0 ~= mn:tNB:~ initial nS (P n) == ninit:tInitial:initial initeq_decidable:forall n0 m : t, n0 == m \/ n0 ~= mn:tNB:~ S (P n) ~= nS (P n) == nelim NB; auto. Qed. End SuccPred. End InitialExists.init:tInitial:initial initeq_decidable:forall n0 m : t, n0 == m \/ n0 ~= mn:tNB:~ S (P n) ~= nH:S (P n) ~= nS (P n) == n
Second case : let's suppose now S surjective, i.e. no initial point.
Section InitialDontExists. Hypothesis succ_onto : forall n, exists m, n == S m.succ_onto:forall n : t, exists m : t, n == S mforall n : t, S (P n) == nsucc_onto:forall n : t, exists m : t, n == S mforall n : t, S (P n) == nsucc_onto:forall n0 : t, exists m : t, n0 == S mn:tS (P n) == nrewrite H, pred_succ; auto with *. Qed.succ_onto:forall n0 : t, exists m0 : t, n0 == S m0n, m:tH:n == S mS (P n) == nsucc_onto:forall n : t, exists m : t, n == S mforall n m : t, P n == P m -> n == msucc_onto:forall n : t, exists m : t, n == S mforall n m : t, P n == P m -> n == msucc_onto:forall n0 : t, exists m0 : t, n0 == S m0n, m:tP n == P m -> n == mrewrite !succ_onto_gives_succ_pred in H; auto. Qed. End InitialDontExists.succ_onto:forall n0 : t, exists m0 : t, n0 == S m0n, m:tH:S (P n) == S (P m)n == m
To summarize:
S is always injective, P is always surjective (thanks to pred_succ).
I) If S is not surjective, we have an initial point, which is unique.
This bottom is below zero: we have N shifted (or not) to the left.
P cannot be injective: P init = P (S (P init)).
(P init) can be arbitrary.
II) If S is surjective, we have ∀ n, S (P n) = n, S and P are
bijective and reciprocal.
IIa) if ∃ k≠O, 0 == S^k 0, then we have a cyclic structure Z/nZ
IIb) otherwise, we have Z
It is weaker than bi_induction. For instance it cannot prove that
we can go from one point by many S or many P, but only by many
S mixed with many P. Think of a model with two copies of N:
0, 1=S 0, 2=S 1, ...
0', 1'=S 0', 2'=S 1', ...
and P 0 = 0' and P 0' = 0.
forall A : t -> Prop, Proper (eq ==> iff) A -> A 0 -> (forall n : t, A n -> A (S n)) -> (forall n : t, A n -> A (P n)) -> forall n : t, A nforall A : t -> Prop, Proper (eq ==> iff) A -> A 0 -> (forall n : t, A n -> A (S n)) -> (forall n : t, A n -> A (P n)) -> forall n : t, A nA:t -> PropH:Proper (eq ==> iff) AH0:A 0H1:forall n0 : t, A n0 -> A (S n0)H2:forall n0 : t, A n0 -> A (P n0)n:tA nA:t -> PropH:Proper (eq ==> iff) AH0:A 0H1:forall n0 : t, A n0 -> A (S n0)H2:forall n0 : t, A n0 -> A (P n0)n:tforall n0 : t, A n0 <-> A (S n0)A:t -> PropH:Proper (eq ==> iff) AH0:A 0H1:forall n : t, A n -> A (S n)H2:forall n : t, A n -> A (P n)forall n : t, A n <-> A (S n)A:t -> PropH:Proper (eq ==> iff) AH0:A 0H1:forall n0 : t, A n0 -> A (S n0)H2:forall n0 : t, A n0 -> A (P n0)n:tA (S n) -> A nrewrite pred_succ in G; auto. Qed.A:t -> PropH:Proper (eq ==> iff) AH0:A 0H1:forall n0 : t, A n0 -> A (S n0)H2:forall n0 : t, A n0 -> A (P n0)n:tG:A (P (S n))A nforall A : t -> Prop, Proper (eq ==> iff) A -> forall n0 : t, A n0 -> (forall n : t, A n -> A (S n)) -> (forall n : t, A n -> A (P n)) -> forall n : t, A nforall A : t -> Prop, Proper (eq ==> iff) A -> forall n0 : t, A n0 -> (forall n : t, A n -> A (S n)) -> (forall n : t, A n -> A (P n)) -> forall n : t, A nA:t -> PropH:Proper (eq ==> iff) An0:tH0:A n0H1:forall n1 : t, A n1 -> A (S n1)H2:forall n1 : t, A n1 -> A (P n1)n:tA nA:t -> PropH:Proper (eq ==> iff) An0:tH0:A n0H1:forall n1 : t, A n1 -> A (S n1)H2:forall n1 : t, A n1 -> A (P n1)n:tA 0A:t -> PropH:Proper (eq ==> iff) An0:tH0:A n0H1:forall n1 : t, A n1 -> A (S n1)H2:forall n1 : t, A n1 -> A (P n1)n:tH3:A 0A nA:t -> PropH:Proper (eq ==> iff) An0:tH0:A n0H1:forall n1 : t, A n1 -> A (S n1)H2:forall n1 : t, A n1 -> A (P n1)n:tk:natA (nat_rect (fun _ : nat => t) n0 (fun _ : nat => S) k)A:t -> PropH:Proper (eq ==> iff) An0:tH0:A n0H1:forall n1 : t, A n1 -> A (S n1)H2:forall n1 : t, A n1 -> A (P n1)n:tk:natA (nat_rect (fun _ : nat => t) n0 (fun _ : nat => P) k)A:t -> PropH:Proper (eq ==> iff) An0:tH0:A n0H1:forall n1 : t, A n1 -> A (S n1)H2:forall n1 : t, A n1 -> A (P n1)n:tH3:A 0A nA:t -> PropH:Proper (eq ==> iff) An0:tH0:A n0H1:forall n1 : t, A n1 -> A (S n1)n:tk:natA (nat_rect (fun _ : nat => t) n0 (fun _ : nat => S) k)A:t -> PropH:Proper (eq ==> iff) An0:tH0:A n0H1:forall n1 : t, A n1 -> A (S n1)H2:forall n1 : t, A n1 -> A (P n1)n:tk:natA (nat_rect (fun _ : nat => t) n0 (fun _ : nat => P) k)A:t -> PropH:Proper (eq ==> iff) An0:tH0:A n0H1:forall n1 : t, A n1 -> A (S n1)H2:forall n1 : t, A n1 -> A (P n1)n:tH3:A 0A nA:t -> PropH:Proper (eq ==> iff) An0:tH0:A n0H1:forall n1 : t, A n1 -> A (S n1)H2:forall n1 : t, A n1 -> A (P n1)n:tk:natA (nat_rect (fun _ : nat => t) n0 (fun _ : nat => P) k)A:t -> PropH:Proper (eq ==> iff) An0:tH0:A n0H1:forall n1 : t, A n1 -> A (S n1)H2:forall n1 : t, A n1 -> A (P n1)n:tH3:A 0A nA:t -> PropH:Proper (eq ==> iff) An0:tH0:A n0H2:forall n1 : t, A n1 -> A (P n1)n:tk:natA (nat_rect (fun _ : nat => t) n0 (fun _ : nat => P) k)A:t -> PropH:Proper (eq ==> iff) An0:tH0:A n0H1:forall n1 : t, A n1 -> A (S n1)H2:forall n1 : t, A n1 -> A (P n1)n:tH3:A 0A napply bi_induction_pred; auto. Qed. End NZDomainProp.A:t -> PropH:Proper (eq ==> iff) An0:tH0:A n0H1:forall n1 : t, A n1 -> A (S n1)H2:forall n1 : t, A n1 -> A (P n1)n:tH3:A 0A n
We now focus on the translation from nat into NZ.
First, relationship with 0, succ, pred.
Module NZOfNat (Import NZ:NZDomainSig'). Definition ofnat (n : nat) : t := (S^n) 0. Declare Scope ofnat. Local Open Scope ofnat. Notation "[ n ]" := (ofnat n) (at level 7) : ofnat.[0] == 0reflexivity. Qed.[0] == 0forall n : nat, [Datatypes.S n] == S [n]now unfold ofnat. Qed.forall n : nat, [Datatypes.S n] == S [n]forall n : nat, n <> 0 -> [Nat.pred n] == P [n]forall n : nat, n <> 0 -> [Nat.pred n] == P [n]forall n : nat, n <> 0 -> nat_rect (fun _ : nat => t) 0 (fun _ : nat => S) (Nat.pred n) == P (nat_rect (fun _ : nat => t) 0 (fun _ : nat => S) n)0 <> 0 -> nat_rect (fun _ : nat => t) 0 (fun _ : nat => S) (Nat.pred 0) == P (nat_rect (fun _ : nat => t) 0 (fun _ : nat => S) 0)n:natDatatypes.S n <> 0 -> nat_rect (fun _ : nat => t) 0 (fun _ : nat => S) (Nat.pred (Datatypes.S n)) == P (nat_rect (fun _ : nat => t) 0 (fun _ : nat => S) (Datatypes.S n))n:natDatatypes.S n <> 0 -> nat_rect (fun _ : nat => t) 0 (fun _ : nat => S) (Nat.pred (Datatypes.S n)) == P (nat_rect (fun _ : nat => t) 0 (fun _ : nat => S) (Datatypes.S n))n:natnat_rect (fun _ : nat => t) 0 (fun _ : nat => S) (Nat.pred (Datatypes.S n)) == P (nat_rect (fun _ : nat => t) 0 (fun _ : nat => S) (Datatypes.S n))n:natnat_rect (fun _ : nat => t) 0 (fun _ : nat => S) n == P (S (nat_rect (fun _ : nat => t) 0 (fun _ : nat => S) n))apply pred_succ. Qed.n:natP (S (nat_rect (fun _ : nat => t) 0 (fun _ : nat => S) n)) == nat_rect (fun _ : nat => t) 0 (fun _ : nat => S) n
Since P 0 can be anything in NZ (either -1, 0, or even other
numbers, we cannot state previous lemma for n=O.
End NZOfNat.
If we require in addition a strict order on NZ, we can prove that
ofnat is injective, and hence that NZ is infinite
(i.e. we ban Z/nZ models)
Module NZOfNatOrd (Import NZ:NZOrdSig'). Include NZOfNat NZ. Include NZBaseProp NZ <+ NZOrderProp NZ. Local Open Scope ofnat.forall n : nat, 0 < [Datatypes.S n]forall n : nat, 0 < [Datatypes.S n]forall n : nat, 0 < nat_rect (fun _ : nat => t) 0 (fun _ : nat => S) (Datatypes.S n)0 < S 0n:natIH:0 < S (nat_rect (fun _ : nat => t) 0 (fun _ : nat => S) n)0 < S (S (nat_rect (fun _ : nat => t) 0 (fun _ : nat => S) n))n:natIH:0 < S (nat_rect (fun _ : nat => t) 0 (fun _ : nat => S) n)0 < S (S (nat_rect (fun _ : nat => t) 0 (fun _ : nat => S) n))n:natIH:0 < S (nat_rect (fun _ : nat => t) 0 (fun _ : nat => S) n)0 < S 0n:natIH:0 < S (nat_rect (fun _ : nat => t) 0 (fun _ : nat => S) n)S 0 < S (S (nat_rect (fun _ : nat => t) 0 (fun _ : nat => S) n))now rewrite <- succ_lt_mono. Qed.n:natIH:0 < S (nat_rect (fun _ : nat => t) 0 (fun _ : nat => S) n)S 0 < S (S (nat_rect (fun _ : nat => t) 0 (fun _ : nat => S) n))forall n : nat, 0 ~= [Datatypes.S n]forall n : nat, 0 ~= [Datatypes.S n]apply lt_neq, ofnat_S_gt_0. Qed.n:nat0 ~= [Datatypes.S n]forall n m : nat, [n] == [m] -> n = mforall n m : nat, [n] == [m] -> n = mm:nat[0] == [Datatypes.S m] -> 0 = Datatypes.S mn:natIH:forall m : nat, [n] == [m] -> n = m[Datatypes.S n] == [0] -> Datatypes.S n = 0n:natIH:forall m0 : nat, [n] == [m0] -> n = m0m:nat[Datatypes.S n] == [Datatypes.S m] -> Datatypes.S n = Datatypes.S mn:natIH:forall m : nat, [n] == [m] -> n = m[Datatypes.S n] == [0] -> Datatypes.S n = 0n:natIH:forall m0 : nat, [n] == [m0] -> n = m0m:nat[Datatypes.S n] == [Datatypes.S m] -> Datatypes.S n = Datatypes.S mn:natIH:forall m0 : nat, [n] == [m0] -> n = m0m:nat[Datatypes.S n] == [Datatypes.S m] -> Datatypes.S n = Datatypes.S mn:natIH:forall m0 : nat, [n] == [m0] -> n = m0m:natH:[Datatypes.S n] == [Datatypes.S m]Datatypes.S n = Datatypes.S mn:natIH:forall m0 : nat, [n] == [m0] -> n = m0m:natH:[Datatypes.S n] == [Datatypes.S m]n = mnow rewrite <- succ_inj_wd. Qed.n:natIH:forall m0 : nat, [n] == [m0] -> n = m0m:natH:[Datatypes.S n] == [Datatypes.S m][n] == [m]forall n m : nat, [n] == [m] <-> n = mforall n m : nat, [n] == [m] <-> n = mn, m:nat[n] == [m] -> n = mn, m:natn = m -> [n] == [m]intros; now subst. Qed. (* In addition, we can prove that [ofnat] preserves order. *)n, m:natn = m -> [n] == [m]forall n m : nat, [n] < [m] <-> n < mforall n m : nat, [n] < [m] <-> n < m0 < 0 -> 0 < 00 < 0 -> 0 < 0m:nat0 < [Datatypes.S m] -> 0 < Datatypes.S mm:nat0 < Datatypes.S m -> 0 < [Datatypes.S m]n:natIH:forall m : nat, [n] < [m] <-> n < m[Datatypes.S n] < 0 -> Datatypes.S n < 0n:natIH:forall m : nat, [n] < [m] <-> n < mDatatypes.S n < 0 -> [Datatypes.S n] < 0n:natIH:forall m0 : nat, [n] < [m0] <-> n < m0m:nat[Datatypes.S n] < [Datatypes.S m] -> Datatypes.S n < Datatypes.S mn:natIH:forall m0 : nat, [n] < [m0] <-> n < m0m:natDatatypes.S n < Datatypes.S m -> [Datatypes.S n] < [Datatypes.S m]0 < 0 -> 0 < 0m:nat0 < [Datatypes.S m] -> 0 < Datatypes.S mm:nat0 < Datatypes.S m -> 0 < [Datatypes.S m]n:natIH:forall m : nat, [n] < [m] <-> n < m[Datatypes.S n] < 0 -> Datatypes.S n < 0n:natIH:forall m : nat, [n] < [m] <-> n < mDatatypes.S n < 0 -> [Datatypes.S n] < 0n:natIH:forall m0 : nat, [n] < [m0] <-> n < m0m:nat[Datatypes.S n] < [Datatypes.S m] -> Datatypes.S n < Datatypes.S mn:natIH:forall m0 : nat, [n] < [m0] <-> n < m0m:natDatatypes.S n < Datatypes.S m -> [Datatypes.S n] < [Datatypes.S m]m:nat0 < [Datatypes.S m] -> 0 < Datatypes.S mm:nat0 < Datatypes.S m -> 0 < [Datatypes.S m]n:natIH:forall m : nat, [n] < [m] <-> n < m[Datatypes.S n] < 0 -> Datatypes.S n < 0n:natIH:forall m : nat, [n] < [m] <-> n < mDatatypes.S n < 0 -> [Datatypes.S n] < 0n:natIH:forall m0 : nat, [n] < [m0] <-> n < m0m:nat[Datatypes.S n] < [Datatypes.S m] -> Datatypes.S n < Datatypes.S mn:natIH:forall m0 : nat, [n] < [m0] <-> n < m0m:natDatatypes.S n < Datatypes.S m -> [Datatypes.S n] < [Datatypes.S m]m:nat0 < Datatypes.S m -> 0 < [Datatypes.S m]n:natIH:forall m : nat, [n] < [m] <-> n < m[Datatypes.S n] < 0 -> Datatypes.S n < 0n:natIH:forall m : nat, [n] < [m] <-> n < mDatatypes.S n < 0 -> [Datatypes.S n] < 0n:natIH:forall m0 : nat, [n] < [m0] <-> n < m0m:nat[Datatypes.S n] < [Datatypes.S m] -> Datatypes.S n < Datatypes.S mn:natIH:forall m0 : nat, [n] < [m0] <-> n < m0m:natDatatypes.S n < Datatypes.S m -> [Datatypes.S n] < [Datatypes.S m]n:natIH:forall m : nat, [n] < [m] <-> n < m[Datatypes.S n] < 0 -> Datatypes.S n < 0n:natIH:forall m : nat, [n] < [m] <-> n < mDatatypes.S n < 0 -> [Datatypes.S n] < 0n:natIH:forall m0 : nat, [n] < [m0] <-> n < m0m:nat[Datatypes.S n] < [Datatypes.S m] -> Datatypes.S n < Datatypes.S mn:natIH:forall m0 : nat, [n] < [m0] <-> n < m0m:natDatatypes.S n < Datatypes.S m -> [Datatypes.S n] < [Datatypes.S m]n:natIH:forall m : nat, [n] < [m] <-> n < mDatatypes.S n < 0 -> [Datatypes.S n] < 0n:natIH:forall m0 : nat, [n] < [m0] <-> n < m0m:nat[Datatypes.S n] < [Datatypes.S m] -> Datatypes.S n < Datatypes.S mn:natIH:forall m0 : nat, [n] < [m0] <-> n < m0m:natDatatypes.S n < Datatypes.S m -> [Datatypes.S n] < [Datatypes.S m]n:natIH:forall m0 : nat, [n] < [m0] <-> n < m0m:nat[Datatypes.S n] < [Datatypes.S m] -> Datatypes.S n < Datatypes.S mn:natIH:forall m0 : nat, [n] < [m0] <-> n < m0m:natDatatypes.S n < Datatypes.S m -> [Datatypes.S n] < [Datatypes.S m]rewrite !ofnat_succ, <- succ_lt_mono, IH; auto with arith. Qed.n:natIH:forall m0 : nat, [n] < [m0] <-> n < m0m:natDatatypes.S n < Datatypes.S m -> [Datatypes.S n] < [Datatypes.S m]forall n m : nat, [n] <= [m] <-> n <= mforall n m : nat, [n] <= [m] <-> n <= mn, m:nat[n] <= [m] <-> n <= mn, m:natn < m \/ n = m <-> n <= mn, m:natn < m \/ n = m -> n <= mn, m:natn <= m -> n < m \/ n = mapply Lt.le_lt_or_eq. Qed. End NZOfNatOrd.n, m:natn <= m -> n < m \/ n = m
For basic operations, we can prove correspondence with
their counterpart in nat.
Module NZOfNatOps (Import NZ:NZAxiomsSig'). Include NZOfNat NZ. Local Open Scope ofnat.forall (n : nat) (m : t), [n] + m == (S ^ n) mforall (n : nat) (m : t), [n] + m == (S ^ n) mm:t[0] + m == nat_rect (fun _ : nat => t) m (fun _ : nat => S) 0n:natIHn:forall m0 : t, [n] + m0 == nat_rect (fun _ : nat => t) m0 (fun _ : nat => S) nm:t[Datatypes.S n] + m == nat_rect (fun _ : nat => t) m (fun _ : nat => S) (Datatypes.S n)n:natIHn:forall m0 : t, [n] + m0 == nat_rect (fun _ : nat => t) m0 (fun _ : nat => S) nm:t[Datatypes.S n] + m == nat_rect (fun _ : nat => t) m (fun _ : nat => S) (Datatypes.S n)n:natIHn:forall m0 : t, [n] + m0 == nat_rect (fun _ : nat => t) m0 (fun _ : nat => S) nm:tS ([n] + m) == nat_rect (fun _ : nat => t) m (fun _ : nat => S) (Datatypes.S n)now f_equiv. Qed.n:natIHn:forall m0 : t, [n] + m0 == nat_rect (fun _ : nat => t) m0 (fun _ : nat => S) nm:tS ([n] + m) == S (nat_rect (fun _ : nat => t) m (fun _ : nat => S) n)forall n m : nat, [n + m] == [n] + [m]forall n m : nat, [n + m] == [n] + [m]n, m:nat[n + m] == [n] + [m]n, m:nat[n + m] == nat_rect (fun _ : nat => t) [m] (fun _ : nat => S) nm:nat[m] == [m]n, m:natIHn:[n + m] == nat_rect (fun _ : nat => t) [m] (fun _ : nat => S) nS [n + m] == S (nat_rect (fun _ : nat => t) [m] (fun _ : nat => S) n)now f_equiv. Qed.n, m:natIHn:[n + m] == nat_rect (fun _ : nat => t) [m] (fun _ : nat => S) nS [n + m] == S (nat_rect (fun _ : nat => t) [m] (fun _ : nat => S) n)forall n m : nat, [n * m] == [n] * [m]forall n m : nat, [n * m] == [n] * [m]m:nat0 == 0 * [m]n:natIHn:forall m0 : nat, [n * m0] == [n] * [m0]m:nat[m + n * m] == S [n] * [m]m:nat0 * [m] == 0n:natIHn:forall m0 : nat, [n * m0] == [n] * [m0]m:nat[m + n * m] == S [n] * [m]n:natIHn:forall m0 : nat, [n * m0] == [n] * [m0]m:nat[m + n * m] == S [n] * [m]n:natIHn:forall m0 : nat, [n * m0] == [n] * [m0]m:nat[n * m + m] == S [n] * [m]now f_equiv. Qed.n:natIHn:forall m0 : nat, [n * m0] == [n] * [m0]m:nat[n * m] + [m] == [n] * [m] + [m]forall (n : t) (m : nat), n - [m] == (P ^ m) nforall (n : t) (m : nat), n - [m] == (P ^ m) nn:tn - 0 == nn:tm:natIHm:n - [m] == nat_rect (fun _ : nat => t) n (fun _ : nat => P) mn - S [m] == P (nat_rect (fun _ : nat => t) n (fun _ : nat => P) m)n:tm:natIHm:n - [m] == nat_rect (fun _ : nat => t) n (fun _ : nat => P) mn - S [m] == P (nat_rect (fun _ : nat => t) n (fun _ : nat => P) m)now f_equiv. Qed.n:tm:natIHm:n - [m] == nat_rect (fun _ : nat => t) n (fun _ : nat => P) mP (n - [m]) == P (nat_rect (fun _ : nat => t) n (fun _ : nat => P) m)forall n m : nat, m <= n -> [n - m] == [n] - [m]forall n m : nat, m <= n -> [n - m] == [n] - [m]n, m:natH:m <= n[n - m] == [n] - [m]n, m:natH:m <= n[n - m] == nat_rect (fun _ : nat => t) [n] (fun _ : nat => P) mm:natforall n : nat, m <= n -> [n - m] == nat_rect (fun _ : nat => t) [n] (fun _ : nat => P) mforall n : nat, 0 <= n -> [n - 0] == nat_rect (fun _ : nat => t) [n] (fun _ : nat => P) 0m:natIHm:forall n : nat, m <= n -> [n - m] == nat_rect (fun _ : nat => t) [n] (fun _ : nat => P) mforall n : nat, Datatypes.S m <= n -> [n - Datatypes.S m] == nat_rect (fun _ : nat => t) [n] (fun _ : nat => P) (Datatypes.S m)n:natH:0 <= n[n - 0] == nat_rect (fun _ : nat => t) [n] (fun _ : nat => P) 0m:natIHm:forall n : nat, m <= n -> [n - m] == nat_rect (fun _ : nat => t) [n] (fun _ : nat => P) mforall n : nat, Datatypes.S m <= n -> [n - Datatypes.S m] == nat_rect (fun _ : nat => t) [n] (fun _ : nat => P) (Datatypes.S m)n:natH:0 <= n[n] == nat_rect (fun _ : nat => t) [n] (fun _ : nat => P) 0m:natIHm:forall n : nat, m <= n -> [n - m] == nat_rect (fun _ : nat => t) [n] (fun _ : nat => P) mforall n : nat, Datatypes.S m <= n -> [n - Datatypes.S m] == nat_rect (fun _ : nat => t) [n] (fun _ : nat => P) (Datatypes.S m)m:natIHm:forall n : nat, m <= n -> [n - m] == nat_rect (fun _ : nat => t) [n] (fun _ : nat => P) mforall n : nat, Datatypes.S m <= n -> [n - Datatypes.S m] == nat_rect (fun _ : nat => t) [n] (fun _ : nat => P) (Datatypes.S m)m:natIHm:forall n0 : nat, m <= n0 -> [n0 - m] == nat_rect (fun _ : nat => t) [n0] (fun _ : nat => P) mn:natH:Datatypes.S m <= n[n - Datatypes.S m] == nat_rect (fun _ : nat => t) [n] (fun _ : nat => P) (Datatypes.S m)m:natIHm:forall n : nat, m <= n -> [n - m] == nat_rect (fun _ : nat => t) [n] (fun _ : nat => P) mH:Datatypes.S m <= 0[0 - Datatypes.S m] == nat_rect (fun _ : nat => t) [0] (fun _ : nat => P) (Datatypes.S m)m:natIHm:forall n0 : nat, m <= n0 -> [n0 - m] == nat_rect (fun _ : nat => t) [n0] (fun _ : nat => P) mn:natH:Datatypes.S m <= Datatypes.S n[Datatypes.S n - Datatypes.S m] == nat_rect (fun _ : nat => t) [Datatypes.S n] (fun _ : nat => P) (Datatypes.S m)m:natIHm:forall n0 : nat, m <= n0 -> [n0 - m] == nat_rect (fun _ : nat => t) [n0] (fun _ : nat => P) mn:natH:Datatypes.S m <= Datatypes.S n[Datatypes.S n - Datatypes.S m] == nat_rect (fun _ : nat => t) [Datatypes.S n] (fun _ : nat => P) (Datatypes.S m)m:natIHm:forall n0 : nat, m <= n0 -> [n0 - m] == nat_rect (fun _ : nat => t) [n0] (fun _ : nat => P) mn:natH:Datatypes.S m <= Datatypes.S n[Datatypes.S n - Datatypes.S m] == nat_rect (fun _ : nat => t) (P [Datatypes.S n]) (fun _ : nat => P) mm:natIHm:forall n0 : nat, m <= n0 -> [n0 - m] == nat_rect (fun _ : nat => t) [n0] (fun _ : nat => P) mn:natH:Datatypes.S m <= Datatypes.S n[n - m] == nat_rect (fun _ : nat => t) (P (S [n])) (fun _ : nat => P) mm:natIHm:forall n0 : nat, m <= n0 -> [n0 - m] == nat_rect (fun _ : nat => t) [n0] (fun _ : nat => P) mn:natH:Datatypes.S m <= Datatypes.S n[n - m] == ?ym:natIHm:forall n0 : nat, m <= n0 -> [n0 - m] == nat_rect (fun _ : nat => t) [n0] (fun _ : nat => P) mn:natH:Datatypes.S m <= Datatypes.S n?y == nat_rect (fun _ : nat => t) (P (S [n])) (fun _ : nat => P) mm:natIHm:forall n0 : nat, m <= n0 -> [n0 - m] == nat_rect (fun _ : nat => t) [n0] (fun _ : nat => P) mn:natH:Datatypes.S m <= Datatypes.S nm <= nm:natIHm:forall n0 : nat, m <= n0 -> [n0 - m] == nat_rect (fun _ : nat => t) [n0] (fun _ : nat => P) mn:natH:Datatypes.S m <= Datatypes.S nnat_rect (fun _ : nat => t) [n] (fun _ : nat => P) m == nat_rect (fun _ : nat => t) (P (S [n])) (fun _ : nat => P) meapply nat_rect_wd; [symmetry;apply pred_succ|apply pred_wd]. Qed. End NZOfNatOps.m:natIHm:forall n0 : nat, m <= n0 -> [n0 - m] == nat_rect (fun _ : nat => t) [n0] (fun _ : nat => P) mn:natH:Datatypes.S m <= Datatypes.S nnat_rect (fun _ : nat => t) [n] (fun _ : nat => P) m == nat_rect (fun _ : nat => t) (P (S [n])) (fun _ : nat => P) m