Built with Alectryon, running Coq+SerAPI v8.19.0+0.19.3. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use ⌘ instead of Ctrl.
[Loading ML file number_string_notation_plugin.cmxs (using legacy method) ... done]
Require Basics.Numerals.Decimal.Require Import Spaces.Nat.Core.Unset Elimination Schemes.Set Universe Minimization ToSet.Declare Scope int_scope.Delimit Scope int_scope with int.LocalOpen Scope int_scope.(** * The Integers *)(** ** Definition *)(** We define the integers as two copies of [nat] stuck together around a [zero]. *)InductiveInt : Type0 :=
| negS : nat -> Int
| zero : Int
| posS : nat -> Int.(** We can convert a [nat] to an [Int] by mapping [0] to [zero] and [S n] to [posS n]. Various operations on [nat] are preserved by this function. See the section on conversion functions starting with [int_nat_succ]. *)Definitionint_of_nat (n : nat) :=
match n with
| O => zero
| S n => posS n
end.(** We declare this conversion as a coercion so we can freely use [nat]s in statements about integers. *)Coercionint_of_nat : nat >-> Int.(** ** Number Notations *)(** Here we define some printing and parsing functions that convert the integers between numeral representations so that we can use notations such as [123] for [posS 122] and [-123] for [negS 122]. *)(** Printing *)Definitionint_to_number_int (n : Int) : Numeral.int :=
match n with
| posS n => Numeral.IntDec (Decimal.Pos (Nat.to_uint (S n)))
| zero => Numeral.IntDec (Decimal.Pos (Nat.to_uint 0))
| negS n => Numeral.IntDec (Decimal.Neg (Nat.to_uint (S n)))
end.(** Parsing *)Definitionint_of_number_int (d : Numeral.int) :=
match d with
| Numeral.IntDec (Decimal.Pos d) => int_of_nat (Nat.of_uint d)
| Numeral.IntDec (Decimal.Neg d) => negS (nat_pred (Nat.of_uint d))
| Numeral.IntHex (Hexadecimal.Pos u) => int_of_nat (Nat.of_hex_uint u)
| Numeral.IntHex (Hexadecimal.Neg u) => negS (nat_pred (Nat.of_hex_uint u))
end.Number NotationInt int_of_number_int int_to_number_int : int_scope.(** ** Successor, Predecessor and Negation *)(** These operations will be used in the induction principle we derive for [Int] so we need to define them early on. *)(** *** Successor and Predecessor *)Definitionint_succ (n : Int) : Int :=
match n with
| posS n => posS (S n)
| 0 => 1
| -1 => 0
| negS (S n) => negS n
end.Notation"n .+1" := (int_succ n) : int_scope.Definitionint_pred (n : Int) : Int :=
match n with
| posS (S n) => posS n
| 1 => 0
| 0 => -1
| negS n => negS (S n)
end.Notation"n .-1" := (int_pred n) : int_scope.(** *** Negation *)Definitionint_neg@{} (x : Int) : Int :=
match x with
| posS x => negS x
| zero => zero
| negS x => posS x
end.Notation"- x" := (int_neg x) : int_scope.(** ** Basic Properties *)(** *** Integer induction *)(** The induction principle for integers is similar to the induction principle for natural numbers. However we have two induction hypotheses going in either direction starting from 0. *)
P: Int -> Type H0: P 0 HP: foralln : nat, P n -> P n.+1 HN: foralln : nat, P (- n) -> P (- n).-1
forallx : Int, P x
P: Int -> Type H0: P 0 HP: foralln : nat, P n -> P n.+1 HN: foralln : nat, P (- n) -> P (- n).-1
forallx : Int, P x
P: Int -> Type H0: P 0 HP: foralln : nat, P n -> P n.+1 HN: foralln : nat, P (- n) -> P (- n).-1 x: nat
P (negS x)
P: Int -> Type H0: P 0 HP: foralln : nat, P n -> P n.+1 HN: foralln : nat, P (- n) -> P (- n).-1
P 0
P: Int -> Type H0: P 0 HP: foralln : nat, P n -> P n.+1 HN: foralln : nat, P (- n) -> P (- n).-1 x: nat
P (posS x)
P: Int -> Type H0: P 0 HP: foralln : nat, P n -> P n.+1 HN: foralln : nat, P (- n) -> P (- n).-1 x: nat
P (negS x)
P: Int -> Type H0: P 0 HP: foralln : nat, P n -> P n.+1 HN: foralln : nat, P (- n) -> P (- n).-1
P (-1)
P: Int -> Type H0: P 0 HP: foralln : nat, P n -> P n.+1 HN: foralln : nat, P (- n) -> P (- n).-1 x: nat IHx: P (negS x)
P (negS x.+1)
P: Int -> Type H0: P 0 HP: foralln : nat, P n -> P n.+1 HN: foralln : nat, P (- n) -> P (- n).-1
P (-1)
apply (HN 0%nat), H0.
P: Int -> Type H0: P 0 HP: foralln : nat, P n -> P n.+1 HN: foralln : nat, P (- n) -> P (- n).-1 x: nat IHx: P (negS x)
P (negS x.+1)
apply (HN x.+1%nat), IHx.
P: Int -> Type H0: P 0 HP: foralln : nat, P n -> P n.+1 HN: foralln : nat, P (- n) -> P (- n).-1
P 0
exact H0.
P: Int -> Type H0: P 0 HP: foralln : nat, P n -> P n.+1 HN: foralln : nat, P (- n) -> P (- n).-1 x: nat
P (posS x)
P: Int -> Type H0: P 0 HP: foralln : nat, P n -> P n.+1 HN: foralln : nat, P (- n) -> P (- n).-1
P 1
P: Int -> Type H0: P 0 HP: foralln : nat, P n -> P n.+1 HN: foralln : nat, P (- n) -> P (- n).-1 x: nat IHx: P (posS x)
P (posS x.+1)
P: Int -> Type H0: P 0 HP: foralln : nat, P n -> P n.+1 HN: foralln : nat, P (- n) -> P (- n).-1
P 1
apply (HP 0%nat), H0.
P: Int -> Type H0: P 0 HP: foralln : nat, P n -> P n.+1 HN: foralln : nat, P (- n) -> P (- n).-1 x: nat IHx: P (posS x)
P (posS x.+1)
apply (HP x.+1%nat), IHx.Defined.(** We record these so that they can be used with the [induction] tactic. *)DefinitionInt_rect := Int_ind.DefinitionInt_rec := Int_ind.(** *** Decidable Equality *)(** The integers have decidable equality. *)
DecidablePaths Int
DecidablePaths Int
x, y: Int
Decidable (x = y)
x, y: nat
Decidable (negS x = negS y)
x: nat
Decidable (negS x = 0)
x, y: nat
Decidable (negS x = posS y)
y: nat
Decidable (0 = negS y)
Decidable (0 = 0)
y: nat
Decidable (0 = posS y)
x, y: nat
Decidable (posS x = negS y)
x: nat
Decidable (posS x = 0)
x, y: nat
Decidable (posS x = posS y)
x, y: nat
Decidable (negS x = negS y)
Decidable (0 = 0)
x, y: nat
Decidable (posS x = posS y)
x, y: nat
Decidable (negS x = negS y)
x, y: nat
Decidable (posS x = posS y)
x, y: nat
Iff.iff ?Goal (negS x = negS y)
x, y: nat
Decidable ?Goal
x, y: nat
Iff.iff ?Goal2 (posS x = posS y)
x, y: nat
Decidable ?Goal2
x, y: nat
?Goal -> negS x = negS y
x, y: nat
negS x = negS y -> ?Goal
x, y: nat
?Goal1 -> posS x = posS y
x, y: nat
posS x = posS y -> ?Goal1
x, y: nat
Decidable ?Goal
x, y: nat
Decidable ?Goal1
x, y: nat
negS x = negS y -> x = y
x, y: nat
posS x = posS y -> x = y
x, y: nat
Decidable (x = y)
x, y: nat
Decidable (x = y)
x, y: nat
Decidable (x = y)
x, y: nat
Decidable (x = y)
1,2: exact _.Defined.(** By Hedberg's theorem, we have that the integers are a set. *)Instanceishset_int@{} : IsHSet Int := _.(** *** Pointedness *)(** We sometimes want to treat the integers as a pointed type with basepoint given by 0. *)Instanceispointed_int : IsPointed Int := 0.(** ** Operations *)(** *** Addition *)(** Addition for integers is defined by integer induction on the first argument. *)
exact (int_pred (IHx y)).Defined.Infix"+" := int_add : int_scope.Infix"-" := (funxy => x + -y) : int_scope.(** *** Multiplication *)(** Multiplication for integers is defined by integer induction on the first argument. *)
bydestruct x.Defined.(** Negation is an equivalence. *)
IsEquiv int_neg
IsEquiv int_neg
int_neg o int_neg == idmap
int_neg o int_neg == idmap
1,2: exact int_neg_neg.Defined.(** Negation is injective. *)Definitionisinj_int_neg@{} (x y : Int) : - x = - y -> x = y
:= equiv_inj int_neg.(** The negation of a successor is the predecessor of the negation. *)
x: Int
- x.+1 = (- x).-1
x: Int
- x.+1 = (- x).-1
bydestruct x as [[] | | ].Defined.(** The negation of a predecessor is the successor of the negation. *)
x: Int
- x.-1 = (- x).+1
x: Int
- x.-1 = (- x).+1
bydestruct x as [ | | []].Defined.(** The successor of a predecessor is the identity. *)
x: Int
x.-1.+1 = x
x: Int
x.-1.+1 = x
bydestruct x as [ | | []].Defined.(** The predecessor of a successor is the identity. *)
x: Int
x.+1.-1 = x
x: Int
x.+1.-1 = x
bydestruct x as [[] | | ].Defined.(** The successor is an equivalence on [Int] *)Instanceisequiv_int_succ@{} : IsEquiv int_succ
:= isequiv_adjointify int_succ int_pred int_pred_succ int_succ_pred.(** The predecessor is an equivalence on [Int] *)Instanceisequiv_int_pred@{} : IsEquiv int_pred
:= isequiv_inverse int_succ.(** *** Addition *)(** Integer addition with zero on the left is the identity by definition. *)Definitionint_add_0_l@{} (x : Int) : 0 + x = x := 1.(** Integer addition with zero on the right is the identity. *)
x: Int
x + 0 = x
x: Int
x + 0 = x
0 + 0 = 0
IHx: 0%nat + 0 = 0%nat
0%nat.+1 + 0 = 0%nat.+1
x: nat IHx: x.+1%nat + 0 = x.+1%nat
x.+1%nat.+1 + 0 = x.+1%nat.+1
IHx: - 0%nat + 0 = - 0%nat
(- 0%nat).-1 + 0 = (- 0%nat).-1
x: nat IHx: - x.+1%nat + 0 = - x.+1%nat
(- x.+1%nat).-1 + 0 = (- x.+1%nat).-1
0 + 0 = 0
reflexivity.
IHx: 0%nat + 0 = 0%nat
0%nat.+1 + 0 = 0%nat.+1
reflexivity.
x: nat IHx: x.+1%nat + 0 = x.+1%nat
x.+1%nat.+1 + 0 = x.+1%nat.+1
x: nat IHx: x.+1%nat + 0 = x.+1%nat
(x.+1%nat + 0).+1 = x.+1%nat.+1
exact (ap _ IHx).
IHx: - 0%nat + 0 = - 0%nat
(- 0%nat).-1 + 0 = (- 0%nat).-1
reflexivity.
x: nat IHx: - x.+1%nat + 0 = - x.+1%nat
(- x.+1%nat).-1 + 0 = (- x.+1%nat).-1
x: nat IHx: - x.+1%nat + 0 = - x.+1%nat
(- x.+1%nat + 0).-1 = (- x.+1%nat).-1
exact (ap _ IHx).Defined.(** Adding a successor on the left is the successor of the sum. *)
x, y: Int
x.+1 + y = (x + y).+1
x, y: Int
x.+1 + y = (x + y).+1
y: Int
0.+1 + y = (0 + y).+1
y: Int IHx: forally : Int, 0%nat.+1 + y = (0%nat + y).+1
0%nat.+1.+1 + y = (0%nat.+1 + y).+1
x: nat y: Int IHx: forally : Int, x.+1%nat.+1 + y = (x.+1%nat + y).+1
x.+1%nat.+1.+1 + y = (x.+1%nat.+1 + y).+1
y: Int IHx: forally : Int, (- 0%nat).+1 + y = (- 0%nat + y).+1
(- 0%nat).-1.+1 + y = ((- 0%nat).-1 + y).+1
x: nat y: Int IHx: forally : Int, (- x.+1%nat).+1 + y = (- x.+1%nat + y).+1
(- x.+1%nat).-1.+1 + y = ((- x.+1%nat).-1 + y).+1
y: Int IHx: forally : Int, (- 0%nat).+1 + y = (- 0%nat + y).+1
(- 0%nat).-1.+1 + y = ((- 0%nat).-1 + y).+1
x: nat y: Int IHx: forally : Int, (- x.+1%nat).+1 + y = (- x.+1%nat + y).+1
(- x.+1%nat).-1.+1 + y = ((- x.+1%nat).-1 + y).+1
all: symmetry; apply int_pred_succ.Defined.(** Adding a predecessor on the left is the predecessor of the sum. *)
x, y: Int
x.-1 + y = (x + y).-1
x, y: Int
x.-1 + y = (x + y).-1
y: Int
0.-1 + y = (0 + y).-1
y: Int IHx: forally : Int, 0%nat.-1 + y = (0%nat + y).-1
0%nat.+1.-1 + y = (0%nat.+1 + y).-1
x: nat y: Int IHx: forally : Int, x.+1%nat.-1 + y = (x.+1%nat + y).-1
x.+1%nat.+1.-1 + y = (x.+1%nat.+1 + y).-1
y: Int IHx: forally : Int, (- 0%nat).-1 + y = (- 0%nat + y).-1
(- 0%nat).-1.-1 + y = ((- 0%nat).-1 + y).-1
x: nat y: Int IHx: forally : Int, (- x.+1%nat).-1 + y = (- x.+1%nat + y).-1
(- x.+1%nat).-1.-1 + y = ((- x.+1%nat).-1 + y).-1
y: Int IHx: forally : Int, 0%nat.-1 + y = (0%nat + y).-1
0%nat.+1.-1 + y = (0%nat.+1 + y).-1
x: nat y: Int IHx: forally : Int, x.+1%nat.-1 + y = (x.+1%nat + y).-1
x.+1%nat.+1.-1 + y = (x.+1%nat.+1 + y).-1
all: symmetry; apply int_succ_pred.Defined.(** Adding a successor on the right is the successor of the sum. *)
x, y: Int
x + y.+1 = (x + y).+1
x, y: Int
x + y.+1 = (x + y).+1
y: Int
0 + y.+1 = (0 + y).+1
x: nat y: Int IHx: forally : Int, x + y.+1 = (x + y).+1
byrewrite int_neg_pred, int_add_succ_l, int_add_pred_r, IHx.Defined.(** Negation is a right inverse with respect to integer addition. *)
x: Int
x - x = 0
x: Int
x - x = 0
unfold"-"; byrewrite int_add_comm, int_add_neg_l.Defined.(** Negation distributes over addition. *)
x, y: Int
- (x + y) = - x - y
x, y: Int
- (x + y) = - x - y
y: Int
- (0 + y) = - 0 + - y
x: nat y: Int IHx: forally : Int, - (x + y) = - x + - y
- (x.+1 + y) = - x.+1 + - y
x: nat y: Int IHx: forally : Int, - (- x + y) = - - x + - y
- ((- x).-1 + y) = - (- x).-1 + - y
y: Int
- (0 + y) = - 0 + - y
reflexivity.
x: nat y: Int IHx: forally : Int, - (x + y) = - x + - y
- (x.+1 + y) = - x.+1 + - y
x: nat y: Int IHx: forally : Int, - (x + y) = - x + - y
- (x + y).+1 = - x.+1 + - y
x: nat y: Int IHx: forally : Int, - (x + y) = - x + - y
(- (x + y)).-1 = (- x).-1 + - y
x: nat y: Int IHx: forally : Int, - (x + y) = - x + - y
(- (x + y)).-1 = (- x + - y).-1
f_ap.
x: nat y: Int IHx: forally : Int, - (- x + y) = - - x + - y
- ((- x).-1 + y) = - (- x).-1 + - y
x: nat y: Int IHx: forally : Int, - (- x + y) = - - x + - y
- ((- x).-1 + y) = (- - x).+1 + - y
x: nat y: Int IHx: forally : Int, - (- x + y) = - - x + - y
- ((- x).-1 + y) = (- - x + - y).+1
x: nat y: Int IHx: forally : Int, - (- x + y) = - - x + - y
- (- x + y).-1 = (- - x + - y).+1
x: nat y: Int IHx: forally : Int, - (- x + y) = - - x + - y
(- (- x + y)).+1 = (- - x + - y).+1
f_ap.Defined.(** *** Multiplication *)(** Multiplication with a successor on the left is the sum of the multiplication without the successor and the multiplicand which was not a successor. *)
x, y: Int
x.+1 * y = y + x * y
x, y: Int
x.+1 * y = y + x * y
y: Int
0.+1 * y = y + 0 * y
y: Int IHx: forally : Int, 0%nat.+1 * y = y + 0%nat * y
0%nat.+1.+1 * y = y + 0%nat.+1 * y
x: nat y: Int IHx: forally : Int, x.+1%nat.+1 * y = y + x.+1%nat * y
x.+1%nat.+1.+1 * y = y + x.+1%nat.+1 * y
y: Int IHx: forally : Int, (- 0%nat).+1 * y = y + - 0%nat * y
(- 0%nat).-1.+1 * y = y + (- 0%nat).-1 * y
n: nat y: Int IHx: forally : Int, (- n.+1%nat).+1 * y = y + - n.+1%nat * y
(- n.+1%nat).-1.+1 * y = y + (- n.+1%nat).-1 * y
y: Int
0.+1 * y = y + 0 * y
reflexivity.
y: Int IHx: forally : Int, 0%nat.+1 * y = y + 0%nat * y
0%nat.+1.+1 * y = y + 0%nat.+1 * y
reflexivity.
x: nat y: Int IHx: forally : Int, x.+1%nat.+1 * y = y + x.+1%nat * y
x.+1%nat.+1.+1 * y = y + x.+1%nat.+1 * y
reflexivity.
y: Int IHx: forally : Int, (- 0%nat).+1 * y = y + - 0%nat * y
(- 0%nat).-1.+1 * y = y + (- 0%nat).-1 * y
y: Int IHx: forally : Int, (- 0%nat).+1 * y = y + - 0%nat * y
0 = y + (- y + 0)
y: Int IHx: forally : Int, (- 0%nat).+1 * y = y + - 0%nat * y
0 = y + - y
byrewrite int_add_neg_r.
n: nat y: Int IHx: forally : Int, (- n.+1%nat).+1 * y = y + - n.+1%nat * y
(- n.+1%nat).-1.+1 * y = y + (- n.+1%nat).-1 * y
n: nat y: Int IHx: forally : Int, (- n.+1%nat).+1 * y = y + - n.+1%nat * y
- n.+1%nat * y = y + (- n.+1%nat).-1 * y
n: nat y: Int IHx: forally : Int, (- n.+1%nat).+1 * y = y + - n.+1%nat * y
nat_rect (fun_ : nat => Int -> Int)
(funy : Int => - y + 0)
(fun (_ : nat) (IHx : Int -> Int) (y : Int) =>
- y + IHx y) n y =
y +
(- y +
nat_rect (fun_ : nat => Int -> Int)
(funy : Int => - y + 0)
(fun (_ : nat) (IHx : Int -> Int) (y : Int) =>
- y + IHx y) n y)
n: nat y: Int IHx: forally : Int, (- n.+1%nat).+1 * y = y + - n.+1%nat * y
nat_rect (fun_ : nat => Int -> Int)
(funy : Int => - y + 0)
(fun (_ : nat) (IHx : Int -> Int) (y : Int) =>
- y + IHx y) n y =
y + - y +
nat_rect (fun_ : nat => Int -> Int)
(funy : Int => - y + 0)
(fun (_ : nat) (IHx : Int -> Int) (y : Int) =>
- y + IHx y) n y
n: nat y: Int IHx: forally : Int, (- n.+1%nat).+1 * y = y + - n.+1%nat * y
nat_rect (fun_ : nat => Int -> Int)
(funy : Int => - y + 0)
(fun (_ : nat) (IHx : Int -> Int) (y : Int) =>
- y + IHx y) n y =
0 +
nat_rect (fun_ : nat => Int -> Int)
(funy : Int => - y + 0)
(fun (_ : nat) (IHx : Int -> Int) (y : Int) =>
- y + IHx y) n y
byrewrite int_add_0_l.Defined.(** Similarly, multiplication with a predecessor on the left is the sum of the multiplication without the predecessor and the negation of the multiplicand which was not a predecessor. *)
x, y: Int
x.-1 * y = - y + x * y
x, y: Int
x.-1 * y = - y + x * y
y: Int
0.-1 * y = - y + 0 * y
x: nat y: Int IHx: forally : Int, x.-1 * y = - y + x * y
x.+1.-1 * y = - y + x.+1 * y
y: Int IHx: forally : Int, (- 0%nat).-1 * y = - y + - 0%nat * y
(- 0%nat).-1.-1 * y = - y + (- 0%nat).-1 * y
n: nat y: Int IHx: forally : Int, (- n.+1%nat).-1 * y = - y + - n.+1%nat * y
(- n.+1%nat).-1.-1 * y = - y + (- n.+1%nat).-1 * y
y: Int
0.-1 * y = - y + 0 * y
reflexivity.
x: nat y: Int IHx: forally : Int, x.-1 * y = - y + x * y
x.+1.-1 * y = - y + x.+1 * y
x: nat y: Int IHx: forally : Int, x.-1 * y = - y + x * y
x.+1.-1 * y = - y + (y + x * y)
x: nat y: Int IHx: forally : Int, x.-1 * y = - y + x * y
x * y = - y + (y + x * y)
x: nat y: Int IHx: forally : Int, x.-1 * y = - y + x * y
x * y = - y + y + x * y
byrewrite int_add_neg_l.
y: Int IHx: forally : Int, (- 0%nat).-1 * y = - y + - 0%nat * y
(- 0%nat).-1.-1 * y = - y + (- 0%nat).-1 * y
reflexivity.
n: nat y: Int IHx: forally : Int, (- n.+1%nat).-1 * y = - y + - n.+1%nat * y
(- n.+1%nat).-1.-1 * y = - y + (- n.+1%nat).-1 * y
reflexivity.Defined.(** Integer multiplication with zero on the left is zero by definition. *)Definitionint_mul_0_l@{} (x : Int) : 0 * x = 0 := 1.(** Integer multiplication with zero on the right is zero. *)
x: Int
x * 0 = 0
x: Int
x * 0 = 0
0 * 0 = 0
x: nat IHx: x * 0 = 0
x.+1 * 0 = 0
x: nat IHx: - x * 0 = 0
(- x).-1 * 0 = 0
0 * 0 = 0
reflexivity.
x: nat IHx: x * 0 = 0
x.+1 * 0 = 0
byrewrite int_mul_succ_l, int_add_0_l.
x: nat IHx: - x * 0 = 0
(- x).-1 * 0 = 0
byrewrite int_mul_pred_l, int_add_0_l.Defined.(** Integer multiplication with one on the left is the identity. *)
x: Int
1 * x = x
x: Int
1 * x = x
apply int_add_0_r.Defined.(** Integer multiplication with one on the right is the identity. *)
x: Int
x * 1 = x
x: Int
x * 1 = x
0 * 1 = 0
x: nat IHx: x * 1 = x
x.+1 * 1 = x.+1
x: nat IHx: - x * 1 = - x
(- x).-1 * 1 = (- x).-1
0 * 1 = 0
reflexivity.
x: nat IHx: x * 1 = x
x.+1 * 1 = x.+1
byrewrite int_mul_succ_l, IHx.
x: nat IHx: - x * 1 = - x
(- x).-1 * 1 = (- x).-1
byrewrite int_mul_pred_l, IHx.Defined.(** Multiplying with a negation on the left is the same as negating the product. *)
x, y: Int
- x * y = - (x * y)
x, y: Int
- x * y = - (x * y)
y: Int
- 0 * y = - (0 * y)
x: nat y: Int IHx: forally : Int, - x * y = - (x * y)
- x.+1 * y = - (x.+1 * y)
x: nat y: Int IHx: forally : Int, - - x * y = - (- x * y)
- (- x).-1 * y = - ((- x).-1 * y)
y: Int
- 0 * y = - (0 * y)
reflexivity.
x: nat y: Int IHx: forally : Int, - x * y = - (x * y)
- x.+1 * y = - (x.+1 * y)
x: nat y: Int IHx: forally : Int, - x * y = - (x * y)
(- x).-1 * y = - (x.+1 * y)
x: nat y: Int IHx: forally : Int, - x * y = - (x * y)
- y + - x * y = - (x.+1 * y)
x: nat y: Int IHx: forally : Int, - x * y = - (x * y)
- y + - x * y = - (y + x * y)
x: nat y: Int IHx: forally : Int, - x * y = - (x * y)
- y + - x * y = - y + - (x * y)
byrewrite IHx.
x: nat y: Int IHx: forally : Int, - - x * y = - (- x * y)
- (- x).-1 * y = - ((- x).-1 * y)
x: nat y: Int IHx: forally : Int, - - x * y = - (- x * y)
(- - x).+1 * y = - ((- x).-1 * y)
x: nat y: Int IHx: forally : Int, - - x * y = - (- x * y)
y + - - x * y = - ((- x).-1 * y)
x: nat y: Int IHx: forally : Int, - - x * y = - (- x * y)
y + - - x * y = - (- y + - x * y)
x: nat y: Int IHx: forally : Int, - - x * y = - (- x * y)
y + - - x * y = - - y + - (- x * y)
x: nat y: Int IHx: forally : Int, - - x * y = - (- x * y)
y + - (- x * y) = - - y + - (- x * y)
byrewrite int_neg_neg.Defined.(** Multiplying with a successor on the right is the sum of the multiplication without the successor and the product of the multiplicand which was not a successor and the multiplicand. *)
x, y: Int
x * y.+1 = x + x * y
x, y: Int
x * y.+1 = x + x * y
y: Int
0 * y.+1 = 0 + 0 * y
x: nat y: Int IHx: forally : Int, x * y.+1 = x + x * y
x.+1 * y.+1 = x.+1 + x.+1 * y
x: nat y: Int IHx: forally : Int, - x * y.+1 = - x + - x * y
(- x).-1 * y.+1 = (- x).-1 + (- x).-1 * y
y: Int
0 * y.+1 = 0 + 0 * y
reflexivity.
x: nat y: Int IHx: forally : Int, x * y.+1 = x + x * y
x.+1 * y.+1 = x.+1 + x.+1 * y
x: nat y: Int IHx: forally : Int, x * y.+1 = x + x * y
y.+1 + x * y.+1 = x.+1 + (y + x * y)
x: nat y: Int IHx: forally : Int, x * y.+1 = x + x * y
(y + x * y.+1).+1 = (x + (y + x * y)).+1
x: nat y: Int IHx: forally : Int, x * y.+1 = x + x * y
y + x * y.+1 = x + (y + x * y)
x: nat y: Int IHx: forally : Int, x * y.+1 = x + x * y
y + (x + x * y) = x + (y + x * y)
x: nat y: Int IHx: forally : Int, x * y.+1 = x + x * y
y + x = x + y
byrewrite int_add_comm.
x: nat y: Int IHx: forally : Int, - x * y.+1 = - x + - x * y
(- x).-1 * y.+1 = (- x).-1 + (- x).-1 * y
x: nat y: Int IHx: forally : Int, - x * y.+1 = - x + - x * y
- y.+1 + - x * y.+1 = (- x).-1 + (- y + - x * y)
x: nat y: Int IHx: forally : Int, - x * y.+1 = - x + - x * y
(- y).-1 + - x * y.+1 = (- x).-1 + (- y + - x * y)
x: nat y: Int IHx: forally : Int, - x * y.+1 = - x + - x * y
(- y).-1 + - (x * y.+1) = (- x).-1 + (- y + - x * y)
x: nat y: Int IHx: forally : Int, - x * y.+1 = - x + - x * y
(- y + - (x * y.+1)).-1 = (- x + (- y + - x * y)).-1
x: nat y: Int IHx: forally : Int, - x * y.+1 = - x + - x * y
- y + - (x * y.+1) = - x + (- y + - x * y)
x: nat y: Int IHx: forally : Int, - x * y.+1 = - x + - x * y
- y + - x * y.+1 = - x + (- y + - x * y)
x: nat y: Int IHx: forally : Int, - x * y.+1 = - x + - x * y
- y + (- x + - x * y) = - x + (- y + - x * y)
x: nat y: Int IHx: forally : Int, - x * y.+1 = - x + - x * y
- y + - x = - x + - y
byrewrite int_add_comm.Defined.(** Multiplying with a predecessor on the right is the sum of the multiplication without the predecessor and the product of the multiplicand which was not a predecessor and the negation of the multiplicand which was not a predecessor. *)
x, y: Int
x * y.-1 = - x + x * y
x, y: Int
x * y.-1 = - x + x * y
y: Int
0 * y.-1 = - 0 + 0 * y
x: nat y: Int IHx: forally : Int, x * y.-1 = - x + x * y
x.+1 * y.-1 = - x.+1 + x.+1 * y
x: nat y: Int IHx: forally : Int, - x * y.-1 = - - x + - x * y
(- x).-1 * y.-1 = - (- x).-1 + (- x).-1 * y
y: Int
0 * y.-1 = - 0 + 0 * y
reflexivity.
x: nat y: Int IHx: forally : Int, x * y.-1 = - x + x * y
x.+1 * y.-1 = - x.+1 + x.+1 * y
x: nat y: Int IHx: forally : Int, x * y.-1 = - x + x * y
y.-1 + x * y.-1 = - x.+1 + (y + x * y)
x: nat y: Int IHx: forally : Int, x * y.-1 = - x + x * y
y.-1 + (- x + x * y) = - x.+1 + (y + x * y)
x: nat y: Int IHx: forally : Int, x * y.-1 = - x + x * y
y.-1 + - x = - x.+1 + y
x: nat y: Int IHx: forally : Int, x * y.-1 = - x + x * y
- - y.-1 + - x = - x.+1 + y
x: nat y: Int IHx: forally : Int, x * y.-1 = - x + x * y
- (- y.-1 + x) = - x.+1 + y
x: nat y: Int IHx: forally : Int, x * y.-1 = - x + x * y
- ((- y).+1 + x) = - x.+1 + y
x: nat y: Int IHx: forally : Int, x * y.-1 = - x + x * y
- (- y + x).+1 = - x.+1 + y
x: nat y: Int IHx: forally : Int, x * y.-1 = - x + x * y
- (x + - y).+1 = - x.+1 + y
x: nat y: Int IHx: forally : Int, x * y.-1 = - x + x * y
- (x.+1 + - y) = - x.+1 + y
x: nat y: Int IHx: forally : Int, x * y.-1 = - x + x * y
- x.+1 + - - y = - x.+1 + y
byrewrite int_neg_neg.
x: nat y: Int IHx: forally : Int, - x * y.-1 = - - x + - x * y
(- x).-1 * y.-1 = - (- x).-1 + (- x).-1 * y
x: nat y: Int IHx: forally : Int, - x * y.-1 = - - x + - x * y
(- x).-1 * y.-1 = (- - x).+1 + (- x).-1 * y
x: nat y: Int IHx: forally : Int, - x * y.-1 = - - x + - x * y
(- x).-1 * y.-1 = x.+1 + (- x).-1 * y
x: nat y: Int IHx: forally : Int, - x * y.-1 = - - x + - x * y
- y.-1 + - x * y.-1 = x.+1 + (- y + - x * y)
x: nat y: Int IHx: forally : Int, - x * y.-1 = - - x + - x * y
- y.-1 + (- - x + - x * y) = x.+1 + (- y + - x * y)
x: nat y: Int IHx: forally : Int, - x * y.-1 = - - x + - x * y
- y.-1 + - - x = x.+1 + - y
x: nat y: Int IHx: forally : Int, - x * y.-1 = - - x + - x * y
(- y).+1 + - - x = x.+1 + - y
x: nat y: Int IHx: forally : Int, - x * y.-1 = - - x + - x * y
(- y).+1 + x = x.+1 + - y
x: nat y: Int IHx: forally : Int, - x * y.-1 = - - x + - x * y
- y + x = x + - y
byrewrite int_add_comm.Defined.(** Integer multiplication is commutative. *)
x, y: Int
x * y = y * x
x, y: Int
x * y = y * x
x: Int
x * 0 = 0 * x
x: Int y: nat IHy: forallx : Int, x * y = y * x
x * y.+1 = y.+1 * x
x: Int y: nat IHy: forallx : Int, x * - y = - y * x
x * (- y).-1 = (- y).-1 * x
x: Int
x * 0 = 0 * x
apply int_mul_0_r.
x: Int y: nat IHy: forallx : Int, x * y = y * x
x * y.+1 = y.+1 * x
x: Int y: nat IHy: forallx : Int, x * y = y * x
x * y.+1 = x + y * x
x: Int y: nat IHy: forallx : Int, x * y = y * x
x + x * y = x + y * x
byrewrite IHy.
x: Int y: nat IHy: forallx : Int, x * - y = - y * x
x * (- y).-1 = (- y).-1 * x
x: Int y: nat IHy: forallx : Int, x * - y = - y * x
x * (- y).-1 = - x + - y * x
x: Int y: nat IHy: forallx : Int, x * - y = - y * x
- x + x * - y = - x + - y * x
byrewrite IHy.Defined.(** Multiplying with a negation on the right is the same as negating the product. *)
x, y: Int
x * - y = - (x * y)
x, y: Int
x * - y = - (x * y)
x, y: Int
- y * x = - (y * x)
apply int_mul_neg_l.Defined.(** Multiplication distributes over addition on the left. *)
x, y, z: Int
x * (y + z) = x * y + x * z
x, y, z: Int
x * (y + z) = x * y + x * z
y, z: Int
0 * (y + z) = 0 * y + 0 * z
x: nat y, z: Int IHx: forallyz : Int, x * (y + z) = x * y + x * z
x.+1 * (y + z) = x.+1 * y + x.+1 * z
x: nat y, z: Int IHx: forallyz : Int, - x * (y + z) = - x * y + - x * z
(- x).-1 * (y + z) = (- x).-1 * y + (- x).-1 * z
y, z: Int
0 * (y + z) = 0 * y + 0 * z
reflexivity.
x: nat y, z: Int IHx: forallyz : Int, x * (y + z) = x * y + x * z
x.+1 * (y + z) = x.+1 * y + x.+1 * z
x: nat y, z: Int IHx: forallyz : Int, x * (y + z) = x * y + x * z
y + z + x * (y + z) = y + x * y + (z + x * z)
x: nat y, z: Int IHx: forallyz : Int, x * (y + z) = x * y + x * z
y + z + (x * y + x * z) = y + x * y + (z + x * z)
x: nat y, z: Int IHx: forallyz : Int, x * (y + z) = x * y + x * z
y + z + x * y = y + x * y + z
x: nat y, z: Int IHx: forallyz : Int, x * (y + z) = x * y + x * z
z + x * y = x * y + z
byrewrite int_add_comm.
x: nat y, z: Int IHx: forallyz : Int, - x * (y + z) = - x * y + - x * z
(- x).-1 * (y + z) = (- x).-1 * y + (- x).-1 * z
x: nat y, z: Int IHx: forallyz : Int, - x * (y + z) = - x * y + - x * z
- (y + z) + - x * (y + z) =
- y + - x * y + (- z + - x * z)
x: nat y, z: Int IHx: forallyz : Int, - x * (y + z) = - x * y + - x * z
- (y + z) + (- x * y + - x * z) =
- y + - x * y + (- z + - x * z)
x: nat y, z: Int IHx: forallyz : Int, - x * (y + z) = - x * y + - x * z
- (y + z) + - x * y = - y + - x * y + - z
x: nat y, z: Int IHx: forallyz : Int, - x * (y + z) = - x * y + - x * z
- y + - z + - x * y = - y + - x * y + - z
x: nat y, z: Int IHx: forallyz : Int, - x * (y + z) = - x * y + - x * z
- z + - x * y = - x * y + - z
byrewrite int_add_comm.Defined.(** Multiplication distributes over addition on the right. *)
x, y, z: Int
(x + y) * z = x * z + y * z
x, y, z: Int
(x + y) * z = x * z + y * z
byrewrite int_mul_comm, int_dist_l, !(int_mul_comm z).Defined.(** Multiplication is associative. *)
x, y, z: Int
x * (y * z) = x * y * z
x, y, z: Int
x * (y * z) = x * y * z
y, z: Int
0 * (y * z) = 0 * y * z
x: nat y, z: Int IHx: forallyz : Int, x * (y * z) = x * y * z
x.+1 * (y * z) = x.+1 * y * z
x: nat y, z: Int IHx: forallyz : Int, - x * (y * z) = - x * y * z
(- x).-1 * (y * z) = (- x).-1 * y * z
y, z: Int
0 * (y * z) = 0 * y * z
reflexivity.
x: nat y, z: Int IHx: forallyz : Int, x * (y * z) = x * y * z
x.+1 * (y * z) = x.+1 * y * z
x: nat y, z: Int IHx: forallyz : Int, x * (y * z) = x * y * z
y * z + x * (y * z) = (y + x * y) * z
x: nat y, z: Int IHx: forallyz : Int, x * (y * z) = x * y * z
y * z + x * (y * z) = y * z + x * y * z
byrewrite IHx.
x: nat y, z: Int IHx: forallyz : Int, - x * (y * z) = - x * y * z
(- x).-1 * (y * z) = (- x).-1 * y * z
x: nat y, z: Int IHx: forallyz : Int, - x * (y * z) = - x * y * z
- (y * z) + - x * (y * z) = (- y + - x * y) * z
x: nat y, z: Int IHx: forallyz : Int, - x * (y * z) = - x * y * z
- (y * z) + - x * (y * z) = - y * z + - x * y * z
x: nat y, z: Int IHx: forallyz : Int, - x * (y * z) = - x * y * z
- y * z + - x * (y * z) = - y * z + - x * y * z
byrewrite IHx.Defined.(** ** Iteration of equivalences *)(** *** Iteration by arbitrary integers *)(** Iteration by arbitrary integers requires the endofunction to be an equivalence, so that we can define a negative iteration by using its inverse. *)Definitionint_iter {A} (f : A -> A) `{!IsEquiv f} (n : Int) : A -> A
:= match n with
| negS n => funx => nat_iter n.+1%nat f^-1 x
| zero => idmap
| posS n => funx => nat_iter n.+1%nat f x
end.
A: Type f: A -> A H: IsEquiv f n: Int a: A
int_iter f (- n) a = int_iter f^-1 n a
A: Type f: A -> A H: IsEquiv f n: Int a: A
int_iter f (- n) a = int_iter f^-1 n a
bydestruct n.Defined.
A: Type f: A -> A H: IsEquiv f n: Int a: A
int_iter f n.+1 a = f (int_iter f n a)
A: Type f: A -> A H: IsEquiv f n: Int a: A
int_iter f n.+1 a = f (int_iter f n a)
A: Type f: A -> A H: IsEquiv f a: A
int_iter f 0.+1 a = f (int_iter f 0 a)
A: Type f: A -> A H: IsEquiv f n: nat a: A IHn: int_iter f n.+1 a = f (int_iter f n a)
int_iter f n.+1.+1 a = f (int_iter f n.+1 a)
A: Type f: A -> A H: IsEquiv f n: nat a: A IHn: int_iter f (- n).+1 a = f (int_iter f (- n) a)
int_iter f (- n).-1.+1 a = f (int_iter f (- n).-1 a)
A: Type f: A -> A H: IsEquiv f a: A
int_iter f 0.+1 a = f (int_iter f 0 a)
reflexivity.
A: Type f: A -> A H: IsEquiv f n: nat a: A IHn: int_iter f n.+1 a = f (int_iter f n a)
int_iter f n.+1.+1 a = f (int_iter f n.+1 a)
bydestruct n.
A: Type f: A -> A H: IsEquiv f n: nat a: A IHn: int_iter f (- n).+1 a = f (int_iter f (- n) a)
int_iter f (- n).-1.+1 a = f (int_iter f (- n).-1 a)
A: Type f: A -> A H: IsEquiv f n: nat a: A IHn: int_iter f (- n).+1 a = f (int_iter f (- n) a)
int_iter f (- n) a = f (int_iter f (- n).-1 a)
A: Type f: A -> A H: IsEquiv f a: A IHn: int_iter f (- 0%nat).+1 a = f (int_iter f (- 0%nat) a)
int_iter f (- 0%nat) a = f (int_iter f (- 0%nat).-1 a)
A: Type f: A -> A H: IsEquiv f n: nat a: A IHn: int_iter f (- n.+1%nat).+1 a = f (int_iter f (- n.+1%nat) a)
int_iter f (- n.+1%nat) a =
f (int_iter f (- n.+1%nat).-1 a)
all: symmetry; apply eisretr.Defined.
A: Type f: A -> A H: IsEquiv f n: Int a: A
int_iter f n.+1 a = int_iter f n (f a)
A: Type f: A -> A H: IsEquiv f n: Int a: A
int_iter f n.+1 a = int_iter f n (f a)
A: Type f: A -> A H: IsEquiv f a: A
int_iter f 0.+1 a = int_iter f 0 (f a)
A: Type f: A -> A H: IsEquiv f n: nat a: A IHn: int_iter f n.+1 a = int_iter f n (f a)
int_iter f n.+1.+1 a = int_iter f n.+1 (f a)
A: Type f: A -> A H: IsEquiv f n: nat a: A IHn: int_iter f (- n).+1 a = int_iter f (- n) (f a)
int_iter f (- n).-1.+1 a = int_iter f (- n).-1 (f a)
A: Type f: A -> A H: IsEquiv f a: A
int_iter f 0.+1 a = int_iter f 0 (f a)
reflexivity.
A: Type f: A -> A H: IsEquiv f n: nat a: A IHn: int_iter f n.+1 a = int_iter f n (f a)
int_iter f n.+1.+1 a = int_iter f n.+1 (f a)
A: Type f: A -> A H: IsEquiv f a: A IHn: int_iter f 0%nat.+1 a = int_iter f 0%nat (f a)
int_iter f 0%nat.+1.+1 a = int_iter f 0%nat.+1 (f a)
A: Type f: A -> A H: IsEquiv f n: nat a: A IHn: int_iter f n.+1%nat.+1 a = int_iter f n.+1%nat (f a)
int_iter f n.+1%nat.+1.+1 a =
int_iter f n.+1%nat.+1 (f a)
A: Type f: A -> A H: IsEquiv f n: nat a: A IHn: int_iter f n.+1%nat.+1 a = int_iter f n.+1%nat (f a)
int_iter f n.+1%nat.+1.+1 a =
int_iter f n.+1%nat.+1 (f a)
cbn; f_ap.
A: Type f: A -> A H: IsEquiv f n: nat a: A IHn: int_iter f (- n).+1 a = int_iter f (- n) (f a)
int_iter f (- n).-1.+1 a = int_iter f (- n).-1 (f a)
A: Type f: A -> A H: IsEquiv f a: A IHn: int_iter f (- 0%nat).+1 a = int_iter f (- 0%nat) (f a)
int_iter f (- 0%nat).-1.+1 a =
int_iter f (- 0%nat).-1 (f a)
A: Type f: A -> A H: IsEquiv f n: nat a: A IHn: int_iter f (- n.+1%nat).+1 a = int_iter f (- n.+1%nat) (f a)
int_iter f (- n.+1%nat).-1.+1 a =
int_iter f (- n.+1%nat).-1 (f a)
A: Type f: A -> A H: IsEquiv f n: nat a: A IHn: int_iter f (- n.+1%nat).+1 a = int_iter f (- n.+1%nat) (f a)
int_iter f (- n.+1%nat).-1.+1 a =
int_iter f (- n.+1%nat).-1 (f a)
A: Type f: A -> A H: IsEquiv f n: nat a: A IHn: int_iter f (- n.+1%nat).+1 a = int_iter f (- n.+1%nat) (f a)
int_iter f (- n.+1%nat) a =
int_iter f (- n.+1%nat).-1 (f a)
A: Type f: A -> A H: IsEquiv f n: nat a: A IHn: int_iter f (- n.+1%nat).+1 a = int_iter f (- n.+1%nat) (f a)
nat_iter n f^-1 a = f^-1 (nat_iter n f^-1 (f a))
A: Type f: A -> A H: IsEquiv f n: nat a: A IHn: int_iter f (- n.+1%nat).+1 a = int_iter f (- n.+1%nat) (f a)
nat_iter n f^-1 a = int_iter f (- n.+1%nat).+1 a
bydestruct n.Defined.
A: Type f: A -> A H: IsEquiv f n: Int a: A
int_iter f n.-1 a = f^-1 (int_iter f n a)
A: Type f: A -> A H: IsEquiv f n: Int a: A
int_iter f n.-1 a = f^-1 (int_iter f n a)
(* Convert the problem to be a problem about [f^-1] and [-n]. *)
A: Type f: A -> A H: IsEquiv f n: Int a: A
int_iter f^-1 (- n.-1) a = f^-1 (int_iter f n a)
A: Type f: A -> A H: IsEquiv f n: Int a: A
int_iter f^-1 (- n.-1) a =
f^-1 (int_iter f^-1 (- n) a)
(* Then [int_iter_succ_l] applies, after changing [- n.-1] to [(-n).+1]. *)
A: Type f: A -> A H: IsEquiv f n: Int a: A
int_iter f^-1 (- n).+1 a =
f^-1 (int_iter f^-1 (- n) a)
apply int_iter_succ_l.Defined.
A: Type f: A -> A H: IsEquiv f n: Int a: A
int_iter f n.-1 a = int_iter f n (f^-1 a)
A: Type f: A -> A H: IsEquiv f n: Int a: A
int_iter f n.-1 a = int_iter f n (f^-1 a)
(* Convert the problem to be a problem about [f^-1] and [-n]. *)
A: Type f: A -> A H: IsEquiv f n: Int a: A
int_iter f^-1 (- n.-1) a = int_iter f n (f^-1 a)
A: Type f: A -> A H: IsEquiv f n: Int a: A
int_iter f^-1 (- n.-1) a =
int_iter f^-1 (- n) (f^-1 a)
(* Then [int_iter_succ_r] applies, after changing [- n.-1] to [(-n).+1]. *)
A: Type f: A -> A H: IsEquiv f n: Int a: A
int_iter f^-1 (- n).+1 a =
int_iter f^-1 (- n) (f^-1 a)
apply int_iter_succ_r.Defined.
A: Type f: A -> A H: IsEquiv f m, n: Int
int_iter f (m + n) == int_iter f m o int_iter f n
A: Type f: A -> A H: IsEquiv f m, n: Int
int_iter f (m + n) == int_iter f m o int_iter f n
A: Type f: A -> A H: IsEquiv f m, n: Int a: A
int_iter f (m + n) a = int_iter f m (int_iter f n a)
A: Type f: A -> A H: IsEquiv f n: Int a: A
int_iter f (0 + n) a = int_iter f 0 (int_iter f n a)
A: Type f: A -> A H: IsEquiv f m: nat n: Int a: A IHm: int_iter f (m + n) a = int_iter f m (int_iter f n a)
int_iter f (m.+1 + n) a =
int_iter f m.+1 (int_iter f n a)
A: Type f: A -> A H: IsEquiv f m: nat n: Int a: A IHm: int_iter f (- m + n) a = int_iter f (- m) (int_iter f n a)
int_iter f ((- m).-1 + n) a =
int_iter f (- m).-1 (int_iter f n a)
A: Type f: A -> A H: IsEquiv f n: Int a: A
int_iter f (0 + n) a = int_iter f 0 (int_iter f n a)
reflexivity.
A: Type f: A -> A H: IsEquiv f m: nat n: Int a: A IHm: int_iter f (m + n) a = int_iter f m (int_iter f n a)
int_iter f (m.+1 + n) a =
int_iter f m.+1 (int_iter f n a)
A: Type f: A -> A H: IsEquiv f m: nat n: Int a: A IHm: int_iter f (m + n) a = int_iter f m (int_iter f n a)
int_iter f (m + n).+1 a =
int_iter f m.+1 (int_iter f n a)
A: Type f: A -> A H: IsEquiv f m: nat n: Int a: A IHm: int_iter f (m + n) a = int_iter f m (int_iter f n a)
f (int_iter f (m + n) a) =
f (int_iter f m (int_iter f n a))
f_ap.
A: Type f: A -> A H: IsEquiv f m: nat n: Int a: A IHm: int_iter f (- m + n) a = int_iter f (- m) (int_iter f n a)
int_iter f ((- m).-1 + n) a =
int_iter f (- m).-1 (int_iter f n a)
A: Type f: A -> A H: IsEquiv f m: nat n: Int a: A IHm: int_iter f (- m + n) a = int_iter f (- m) (int_iter f n a)
int_iter f (- m + n).-1 a =
int_iter f (- m).-1 (int_iter f n a)
A: Type f: A -> A H: IsEquiv f m: nat n: Int a: A IHm: int_iter f (- m + n) a = int_iter f (- m) (int_iter f n a)
f^-1 (int_iter f (- m + n) a) =
f^-1 (int_iter f (- m) (int_iter f n a))
f_ap.Defined.(** If [g : A -> A'] commutes with automorphisms of [A] and [A'], then it commutes with iteration. *)
A, A': Type f: A -> A IsEquiv0: IsEquiv f f': A' -> A' IsEquiv1: IsEquiv f' g: A -> A' p: g o f == f' o g n: Int a: A
g (int_iter f n a) = int_iter f' n (g a)
A, A': Type f: A -> A IsEquiv0: IsEquiv f f': A' -> A' IsEquiv1: IsEquiv f' g: A -> A' p: g o f == f' o g n: Int a: A
g (int_iter f n a) = int_iter f' n (g a)
A, A': Type f: A -> A IsEquiv0: IsEquiv f f': A' -> A' IsEquiv1: IsEquiv f' g: A -> A' p: g o f == f' o g a: A
g (int_iter f 0 a) = int_iter f' 0 (g a)
A, A': Type f: A -> A IsEquiv0: IsEquiv f f': A' -> A' IsEquiv1: IsEquiv f' g: A -> A' p: g o f == f' o g n: nat a: A IHn: foralla : A,
g (int_iter f n a) = int_iter f' n (g a)
g (int_iter f n.+1 a) = int_iter f' n.+1 (g a)
A, A': Type f: A -> A IsEquiv0: IsEquiv f f': A' -> A' IsEquiv1: IsEquiv f' g: A -> A' p: g o f == f' o g n: nat a: A IHn: foralla : A,
g (int_iter f (- n) a) = int_iter f' (- n) (g a)
g (int_iter f (- n).-1 a) = int_iter f' (- n).-1 (g a)
A, A': Type f: A -> A IsEquiv0: IsEquiv f f': A' -> A' IsEquiv1: IsEquiv f' g: A -> A' p: g o f == f' o g a: A
g (int_iter f 0 a) = int_iter f' 0 (g a)
reflexivity.
A, A': Type f: A -> A IsEquiv0: IsEquiv f f': A' -> A' IsEquiv1: IsEquiv f' g: A -> A' p: g o f == f' o g n: nat a: A IHn: foralla : A,
g (int_iter f n a) = int_iter f' n (g a)
g (int_iter f n.+1 a) = int_iter f' n.+1 (g a)
A, A': Type f: A -> A IsEquiv0: IsEquiv f f': A' -> A' IsEquiv1: IsEquiv f' g: A -> A' p: g o f == f' o g n: nat a: A IHn: foralla : A,
g (int_iter f n a) = int_iter f' n (g a)
g (int_iter f n (f a)) = int_iter f' n (f' (g a))
A, A': Type f: A -> A IsEquiv0: IsEquiv f f': A' -> A' IsEquiv1: IsEquiv f' g: A -> A' p: g o f == f' o g n: nat a: A IHn: foralla : A,
g (int_iter f n a) = int_iter f' n (g a)
int_iter f' n (g (f a)) = int_iter f' n (f' (g a))
f_ap.
A, A': Type f: A -> A IsEquiv0: IsEquiv f f': A' -> A' IsEquiv1: IsEquiv f' g: A -> A' p: g o f == f' o g n: nat a: A IHn: foralla : A,
g (int_iter f (- n) a) = int_iter f' (- n) (g a)
g (int_iter f (- n).-1 a) = int_iter f' (- n).-1 (g a)
A, A': Type f: A -> A IsEquiv0: IsEquiv f f': A' -> A' IsEquiv1: IsEquiv f' g: A -> A' p: g o f == f' o g n: nat a: A IHn: foralla : A,
g (int_iter f (- n) a) = int_iter f' (- n) (g a)
g (int_iter f (- n) (f^-1 a)) =
int_iter f' (- n) (f'^-1 (g a))
A, A': Type f: A -> A IsEquiv0: IsEquiv f f': A' -> A' IsEquiv1: IsEquiv f' g: A -> A' p: g o f == f' o g n: nat a: A IHn: foralla : A,
g (int_iter f (- n) a) = int_iter f' (- n) (g a)
int_iter f' (- n) (g (f^-1 a)) =
int_iter f' (- n) (f'^-1 (g a))
A, A': Type f: A -> A IsEquiv0: IsEquiv f f': A' -> A' IsEquiv1: IsEquiv f' g: A -> A' p: g o f == f' o g n: nat a: A IHn: foralla : A,
g (int_iter f (- n) a) = int_iter f' (- n) (g a)
g (f^-1 a) = f'^-1 (g a)
A, A': Type f: A -> A IsEquiv0: IsEquiv f f': A' -> A' IsEquiv1: IsEquiv f' g: A -> A' p: g o f == f' o g n: nat a: A IHn: foralla : A,
g (int_iter f (- n) a) = int_iter f' (- n) (g a)
f' (g (f^-1 a)) = g a
A, A': Type f: A -> A IsEquiv0: IsEquiv f f': A' -> A' IsEquiv1: IsEquiv f' g: A -> A' p: g o f == f' o g n: nat a: A IHn: foralla : A,
g (int_iter f (- n) a) = int_iter f' (- n) (g a)
g (f (f^-1 a)) = g a
A, A': Type f: A -> A IsEquiv0: IsEquiv f f': A' -> A' IsEquiv1: IsEquiv f' g: A -> A' p: g o f == f' o g n: nat a: A IHn: foralla : A,
g (int_iter f (- n) a) = int_iter f' (- n) (g a)
f (f^-1 a) = a
apply eisretr.Defined.(** In particular, homotopic maps have homotopic iterations. *)Definitionint_iter_homotopic (n : Int) {A} (ff' : A -> A) `{!IsEquiv f} `{!IsEquiv f'}
(h : f == f')
: int_iter f n == int_iter f' n
:= int_iter_commute_map f f' idmap h n.(** [int_iter f n x] doesn't depend on the proof that [f] is an equivalence. *)Definitionint_iter_agree (n : Int) {A} (f : A -> A) {iefief' : IsEquiv f}
: forallx, @int_iter A f ief n x = @int_iter A f ief' n x
:= int_iter_homotopic n f f (fun_ => idpath).
n: Int A: Type f: A -> A IsEquiv0: IsEquiv f P: A -> Type Psucc: forallx : A, P x -> P (f x) Ppred: forallx : A, P x -> P (f^-1 x)
forallx : A, P x -> P (int_iter f n x)
n: Int A: Type f: A -> A IsEquiv0: IsEquiv f P: A -> Type Psucc: forallx : A, P x -> P (f x) Ppred: forallx : A, P x -> P (f^-1 x)
forallx : A, P x -> P (int_iter f n x)
A: Type f: A -> A IsEquiv0: IsEquiv f P: A -> Type Psucc: forallx : A, P x -> P (f x) Ppred: forallx : A, P x -> P (f^-1 x) x: A
P x -> P (int_iter f 0 x)
n: nat A: Type f: A -> A IsEquiv0: IsEquiv f P: A -> Type Psucc: forallx : A, P x -> P (f x) Ppred: forallx : A, P x -> P (f^-1 x) IHn: forallx : A, P x -> P (int_iter f n x) x: A
P x -> P (int_iter f n.+1 x)
n: nat A: Type f: A -> A IsEquiv0: IsEquiv f P: A -> Type Psucc: forallx : A, P x -> P (f x) Ppred: forallx : A, P x -> P (f^-1 x) IHn: forallx : A, P x -> P (int_iter f (- n) x) x: A
P x -> P (int_iter f (- n).-1 x)
A: Type f: A -> A IsEquiv0: IsEquiv f P: A -> Type Psucc: forallx : A, P x -> P (f x) Ppred: forallx : A, P x -> P (f^-1 x) x: A
P x -> P (int_iter f 0 x)
exact idmap.
n: nat A: Type f: A -> A IsEquiv0: IsEquiv f P: A -> Type Psucc: forallx : A, P x -> P (f x) Ppred: forallx : A, P x -> P (f^-1 x) IHn: forallx : A, P x -> P (int_iter f n x) x: A
P x -> P (int_iter f n.+1 x)
n: nat A: Type f: A -> A IsEquiv0: IsEquiv f P: A -> Type Psucc: forallx : A, P x -> P (f x) Ppred: forallx : A, P x -> P (f^-1 x) IHn: forallx : A, P x -> P (int_iter f n x) x: A H: P x
P (int_iter f n.+1 x)
n: nat A: Type f: A -> A IsEquiv0: IsEquiv f P: A -> Type Psucc: forallx : A, P x -> P (f x) Ppred: forallx : A, P x -> P (f^-1 x) IHn: forallx : A, P x -> P (int_iter f n x) x: A H: P x
P (f (int_iter f n x))
apply Psucc, IHn, H.
n: nat A: Type f: A -> A IsEquiv0: IsEquiv f P: A -> Type Psucc: forallx : A, P x -> P (f x) Ppred: forallx : A, P x -> P (f^-1 x) IHn: forallx : A, P x -> P (int_iter f (- n) x) x: A
P x -> P (int_iter f (- n).-1 x)
n: nat A: Type f: A -> A IsEquiv0: IsEquiv f P: A -> Type Psucc: forallx : A, P x -> P (f x) Ppred: forallx : A, P x -> P (f^-1 x) IHn: forallx : A, P x -> P (int_iter f (- n) x) x: A H: P x
P (int_iter f (- n).-1 x)
n: nat A: Type f: A -> A IsEquiv0: IsEquiv f P: A -> Type Psucc: forallx : A, P x -> P (f x) Ppred: forallx : A, P x -> P (f^-1 x) IHn: forallx : A, P x -> P (int_iter f (- n) x) x: A H: P x
P (f^-1 (int_iter f (- n) x))
apply Ppred, IHn, H.Defined.(** ** Exponentiation of loops *)Definitionloopexp {A : Type} {x : A} (p : x = x) (z : Int) : (x = x)
:= int_iter (equiv_concat_r p x) z idpath.Definitionloopexp_succ_r {A : Type} {x : A} (p : x = x) (z : Int)
: loopexp p z.+1 = loopexp p z @ p
:= int_iter_succ_l _ _ _.Definitionloopexp_pred_r {A : Type} {x : A} (p : x = x) (z : Int)
: loopexp p z.-1 = loopexp p z @ p^
:= int_iter_pred_l _ _ _.
A: Type x: A p: x = x z: Int
loopexp p z.+1 = p @ loopexp p z
A: Type x: A p: x = x z: Int
loopexp p z.+1 = p @ loopexp p z
A: Type x: A p: x = x z: Int
loopexp p z @ p = p @ loopexp p z
A: Type x: A p: x = x
loopexp p 0 @ p = p @ loopexp p 0
A: Type x: A p: x = x z: nat IHz: loopexp p z @ p = p @ loopexp p z
loopexp p z.+1 @ p = p @ loopexp p z.+1
A: Type x: A p: x = x z: nat IHz: loopexp p (- z) @ p = p @ loopexp p (- z)
loopexp p (- z).-1 @ p = p @ loopexp p (- z).-1
A: Type x: A p: x = x
loopexp p 0 @ p = p @ loopexp p 0
napply concat_1p_p1.
A: Type x: A p: x = x z: nat IHz: loopexp p z @ p = p @ loopexp p z
loopexp p z.+1 @ p = p @ loopexp p z.+1
A: Type x: A p: x = x z: nat IHz: loopexp p z @ p = p @ loopexp p z
(loopexp p z @ p) @ p = p @ (loopexp p z @ p)
A: Type x: A p: x = x z: nat IHz: loopexp p z @ p = p @ loopexp p z
(loopexp p z @ p) @ p = (p @ loopexp p z) @ p
f_ap.
A: Type x: A p: x = x z: nat IHz: loopexp p (- z) @ p = p @ loopexp p (- z)
loopexp p (- z).-1 @ p = p @ loopexp p (- z).-1
A: Type x: A p: x = x z: nat IHz: loopexp p (- z) @ p = p @ loopexp p (- z)
(loopexp p (- z) @ p^) @ p =
p @ (loopexp p (- z) @ p^)
A: Type x: A p: x = x z: nat IHz: loopexp p (- z) @ p = p @ loopexp p (- z)
loopexp p (- z) = p @ (loopexp p (- z) @ p^)
A: Type x: A p: x = x z: nat IHz: loopexp p (- z) @ p = p @ loopexp p (- z)
loopexp p (- z) = (p @ loopexp p (- z)) @ p^
byapply moveL_pV.Defined.
A: Type x: A p: x = x z: Int
loopexp p z.-1 = p^ @ loopexp p z
A: Type x: A p: x = x z: Int
loopexp p z.-1 = p^ @ loopexp p z
A: Type x: A p: x = x z: Int
loopexp p z @ p^ = p^ @ loopexp p z
A: Type x: A p: x = x
loopexp p 0 @ p^ = p^ @ loopexp p 0
A: Type x: A p: x = x z: nat IHz: loopexp p z @ p^ = p^ @ loopexp p z
loopexp p z.+1 @ p^ = p^ @ loopexp p z.+1
A: Type x: A p: x = x z: nat IHz: loopexp p (- z) @ p^ = p^ @ loopexp p (- z)
loopexp p (- z).-1 @ p^ = p^ @ loopexp p (- z).-1
A: Type x: A p: x = x
loopexp p 0 @ p^ = p^ @ loopexp p 0
exact (concat_1p _ @ (concat_p1 _)^).
A: Type x: A p: x = x z: nat IHz: loopexp p z @ p^ = p^ @ loopexp p z
loopexp p z.+1 @ p^ = p^ @ loopexp p z.+1
A: Type x: A p: x = x z: nat IHz: loopexp p z @ p^ = p^ @ loopexp p z
(loopexp p z @ p) @ p^ = p^ @ (loopexp p z @ p)
A: Type x: A p: x = x z: nat IHz: loopexp p z @ p^ = p^ @ loopexp p z
loopexp p z = p^ @ (loopexp p z @ p)
A: Type x: A p: x = x z: nat IHz: loopexp p z @ p^ = p^ @ loopexp p z
loopexp p z = (p^ @ loopexp p z) @ p
byapply moveL_pM.
A: Type x: A p: x = x z: nat IHz: loopexp p (- z) @ p^ = p^ @ loopexp p (- z)
loopexp p (- z).-1 @ p^ = p^ @ loopexp p (- z).-1
A: Type x: A p: x = x z: nat IHz: loopexp p (- z) @ p^ = p^ @ loopexp p (- z)
(loopexp p (- z) @ p^) @ p^ =
p^ @ (loopexp p (- z) @ p^)
A: Type x: A p: x = x z: nat IHz: loopexp p (- z) @ p^ = p^ @ loopexp p (- z)
(loopexp p (- z) @ p^) @ p^ =
(p^ @ loopexp p (- z)) @ p^
f_ap.Defined.
A, B: Type f: A -> B x: A p: x = x z: Int
ap f (loopexp p z) = loopexp (ap f p) z
A, B: Type f: A -> B x: A p: x = x z: Int
ap f (loopexp p z) = loopexp (ap f p) z
A, B: Type f: A -> B x: A p: x = x z: Int
(funx0 : x = x => ap f (equiv_concat_r p x x0)) ==
(funx0 : x = x =>
equiv_concat_r (ap f p) (f x) (ap f x0))
intro q; apply ap_pp.Defined.
A: Type x: A p: x = x m, n: Int
loopexp p (m + n) = loopexp p m @ loopexp p n
A: Type x: A p: x = x m, n: Int
loopexp p (m + n) = loopexp p m @ loopexp p n
A: Type x: A p: x = x n: Int
loopexp p (0 + n) = loopexp p 0 @ loopexp p n
A: Type x: A p: x = x m: nat n: Int IHm: loopexp p (m + n) = loopexp p m @ loopexp p n
loopexp p (m.+1 + n) = loopexp p m.+1 @ loopexp p n
A: Type x: A p: x = x m: nat n: Int IHm: loopexp p (- m + n) = loopexp p (- m) @ loopexp p n
loopexp p ((- m).-1 + n) =
loopexp p (- m).-1 @ loopexp p n
A: Type x: A p: x = x n: Int
loopexp p (0 + n) = loopexp p 0 @ loopexp p n
symmetry; apply concat_1p.
A: Type x: A p: x = x m: nat n: Int IHm: loopexp p (m + n) = loopexp p m @ loopexp p n
loopexp p (m.+1 + n) = loopexp p m.+1 @ loopexp p n
A: Type x: A p: x = x m: nat n: Int IHm: loopexp p (m + n) = loopexp p m @ loopexp p n
loopexp p (m + n).+1 = loopexp p m.+1 @ loopexp p n
A: Type x: A p: x = x m: nat n: Int IHm: loopexp p (m + n) = loopexp p m @ loopexp p n
p @ loopexp p (m + n) =
(p @ loopexp p m) @ loopexp p n
byrewrite IHm, concat_p_pp.
A: Type x: A p: x = x m: nat n: Int IHm: loopexp p (- m + n) = loopexp p (- m) @ loopexp p n
loopexp p ((- m).-1 + n) =
loopexp p (- m).-1 @ loopexp p n
A: Type x: A p: x = x m: nat n: Int IHm: loopexp p (- m + n) = loopexp p (- m) @ loopexp p n
loopexp p (- m + n).-1 =
loopexp p (- m).-1 @ loopexp p n
A: Type x: A p: x = x m: nat n: Int IHm: loopexp p (- m + n) = loopexp p (- m) @ loopexp p n
p^ @ loopexp p (- m + n) =
(p^ @ loopexp p (- m)) @ loopexp p n
byrewrite IHm, concat_p_pp.Defined.(** Under univalence, exponentiation of loops corresponds to iteration of auto-equivalences. *)
A: Type p: A = A z: Int a: A
equiv_path A A (loopexp p z) a =
int_iter (equiv_path A A p) z a
A: Type p: A = A z: Int a: A
equiv_path A A (loopexp p z) a =
int_iter (equiv_path A A p) z a
A: Type p: A = A z: Int a: A
(funx : A = A =>
equiv_path A A (equiv_concat_r p A x) a) ==
(funx : A = A =>
equiv_path A A p (equiv_path A A x a))
A: Type p: A = A z: Int a: A q: A = A
transport idmap (q @ p) a =
transport idmap p (transport idmap q a)
napply transport_pp.Defined.
H: Univalence A: Type f: A <~> A z: Int a: A
transport idmap (loopexp (path_universe f) z) a =
int_iter f z a
H: Univalence A: Type f: A <~> A z: Int a: A
transport idmap (loopexp (path_universe f) z) a =
int_iter f z a
H: Univalence A: Type z: Int a: A
forallf : A <~> A,
transport idmap (loopexp (path_universe f) z) a =
int_iter f z a
H: Univalence A: Type z: Int a: A p: A = A
transport idmap
(loopexp (path_universe (equiv_path A A p)) z) a =
int_iter (equiv_path A A p) z a
H: Univalence A: Type z: Int a: A p: A = A
transport idmap
(loopexp (path_universe (equiv_path A A p)) z) a =
equiv_path A A (loopexp p z) a
H: Univalence A: Type z: Int a: A p: A = A
path_universe (equiv_path A A p) = p
apply eissect.Defined.(** ** Converting between integers and naturals *)(** [int_of_nat] preserves successors. *)
n: nat
n.+1 = n.+1%nat
n: nat
n.+1 = n.+1%nat
byinduction n.Defined.(** [int_of_nat] preserves addition. Hence is a monoid homomorphism. *)
n, m: nat
n + m = (n + m)%nat
n, m: nat
n + m = (n + m)%nat
m: nat
0%nat + m = (0 + m)%nat
n, m: nat IHn: n + m = (n + m)%nat
n.+1%nat + m = (n.+1 + m)%nat
m: nat
0%nat + m = (0 + m)%nat
reflexivity.
n, m: nat IHn: n + m = (n + m)%nat
n.+1%nat + m = (n.+1 + m)%nat
n, m: nat IHn: n + m = (n + m)%nat
n.+1 + m = (nat_iter n S m).+1
n, m: nat IHn: n + m = (n + m)%nat
(n + m).+1 = (nat_iter n S m).+1
exact (ap _ IHn).Defined.(** [int_of_nat] preserves subtraction when not truncated. *)
n, m: nat
(m <= n)%nat -> n - m = (n - m)%nat
n, m: nat
(m <= n)%nat -> n - m = (n - m)%nat
n, m: nat H: (m <= n)%nat
n - m = (n - m)%nat
m: nat
m + - m = (m - m)%nat
m, n: nat H: (m <= n)%nat IHn: n + - m = (n - m)%nat
n.+1%nat + - m = (n.+1 - m)%nat
m: nat
m + - m = (m - m)%nat
m: nat
0 = (m - m)%nat
byrewrite nat_sub_cancel.
m, n: nat H: (m <= n)%nat IHn: n + - m = (n - m)%nat
n.+1%nat + - m = (n.+1 - m)%nat
m, n: nat H: (m <= n)%nat IHn: n + - m = (n - m)%nat
n.+1%nat + - m = (n - m).+1%nat
m, n: nat H: (m <= n)%nat IHn: n + - m = (n - m)%nat
n.+1 + - m = (n - m)%nat.+1
m, n: nat H: (m <= n)%nat IHn: n + - m = (n - m)%nat
(n + - m).+1 = (n - m)%nat.+1
exact (ap _ IHn).Defined.(** [int_of_nat] preserves multiplication. This makes [int_of_nat] a semiring homomorphism. *)