Built with Alectryon. 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.
Require Import Basics.Overture Basics.Nat Basics.Tactics Basics.Decidable Basics.Equivalences Basics.PathGroupoids Types.Paths Types.Universe.Require Import Basics.Overture Basics.Nat Basics.Tactics Basics.Decidable Basics.Equivalences Basics.PathGroupoids Types.Paths Types.Universe.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. *)
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: forally0 : Int, - (x + y0) = - x + - y0
- (x.+1 + y) = - x.+1 + - y
x: nat y: Int IHx: forally0 : Int, - (- x + y0) = - - x + - y0
- ((- x).-1 + y) = - (- x).-1 + - y
y: Int
- (0 + y) = - 0 + - y
reflexivity.
x: nat y: Int IHx: forally0 : Int, - (x + y0) = - x + - y0
- (x.+1 + y) = - x.+1 + - y
x: nat y: Int IHx: forally0 : Int, - (x + y0) = - x + - y0
- (x + y).+1 = - x.+1 + - y
x: nat y: Int IHx: forally0 : Int, - (x + y0) = - x + - y0
(- (x + y)).-1 = (- x).-1 + - y
x: nat y: Int IHx: forally0 : Int, - (x + y0) = - x + - y0
(- (x + y)).-1 = (- x + - y).-1
f_ap.
x: nat y: Int IHx: forally0 : Int, - (- x + y0) = - - x + - y0
- ((- x).-1 + y) = - (- x).-1 + - y
x: nat y: Int IHx: forally0 : Int, - (- x + y0) = - - x + - y0
- ((- x).-1 + y) = (- - x).+1 + - y
x: nat y: Int IHx: forally0 : Int, - (- x + y0) = - - x + - y0
- ((- x).-1 + y) = (- - x + - y).+1
x: nat y: Int IHx: forally0 : Int, - (- x + y0) = - - x + - y0
- (- x + y).-1 = (- - x + - y).+1
x: nat y: Int IHx: forally0 : Int, - (- x + y0) = - - x + - y0
(- (- 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. *)
nat_rect (fun_ : nat => Int -> Int) (funy0 : Int => - y0 + 0)
(fun (_ : nat) (IHx0 : Int -> Int) (y0 : Int) => - y0 + IHx0 y0) n y =
0 +
nat_rect (fun_ : nat => Int -> Int) (funy0 : Int => - y0 + 0)
(fun (_ : nat) (IHx0 : Int -> Int) (y0 : Int) => - y0 + IHx0 y0) 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: forally0 : Int, x.-1 * y0 = - y0 + x * y0
(- 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: forally0 : Int, - x * y0 = - (x * y0)
- x.+1 * y = - (x.+1 * y)
x: nat y: Int IHx: forally0 : Int, - - x * y0 = - (- x * y0)
- (- x).-1 * y = - ((- x).-1 * y)
y: Int
- 0 * y = - (0 * y)
reflexivity.
x: nat y: Int IHx: forally0 : Int, - x * y0 = - (x * y0)
- x.+1 * y = - (x.+1 * y)
x: nat y: Int IHx: forally0 : Int, - x * y0 = - (x * y0)
(- x).-1 * y = - (x.+1 * y)
x: nat y: Int IHx: forally0 : Int, - x * y0 = - (x * y0)
- y + - x * y = - (x.+1 * y)
x: nat y: Int IHx: forally0 : Int, - x * y0 = - (x * y0)
- y + - x * y = - (y + x * y)
x: nat y: Int IHx: forally0 : Int, - x * y0 = - (x * y0)
- y + - x * y = - y + - (x * y)
byrewrite IHx.
x: nat y: Int IHx: forally0 : Int, - - x * y0 = - (- x * y0)
- (- x).-1 * y = - ((- x).-1 * y)
x: nat y: Int IHx: forally0 : Int, - - x * y0 = - (- x * y0)
(- - x).+1 * y = - ((- x).-1 * y)
x: nat y: Int IHx: forally0 : Int, - - x * y0 = - (- x * y0)
y + - - x * y = - ((- x).-1 * y)
x: nat y: Int IHx: forally0 : Int, - - x * y0 = - (- x * y0)
y + - - x * y = - (- y + - x * y)
x: nat y: Int IHx: forally0 : Int, - - x * y0 = - (- x * y0)
y + - - x * y = - - y + - (- x * y)
x: nat y: Int IHx: forally0 : Int, - - x * y0 = - (- x * y0)
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: forally0 : Int, x * y0.+1 = x + x * y0
x.+1 * y.+1 = x.+1 + x.+1 * y
x: nat y: Int IHx: forally0 : Int, - x * y0.+1 = - x + - x * y0
(- x).-1 * y.+1 = (- x).-1 + (- x).-1 * y
y: Int
0 * y.+1 = 0 + 0 * y
reflexivity.
x: nat y: Int IHx: forally0 : Int, x * y0.+1 = x + x * y0
x.+1 * y.+1 = x.+1 + x.+1 * y
x: nat y: Int IHx: forally0 : Int, x * y0.+1 = x + x * y0
y.+1 + x * y.+1 = x.+1 + (y + x * y)
x: nat y: Int IHx: forally0 : Int, x * y0.+1 = x + x * y0
(y + x * y.+1).+1 = (x + (y + x * y)).+1
x: nat y: Int IHx: forally0 : Int, x * y0.+1 = x + x * y0
y + x * y.+1 = x + (y + x * y)
x: nat y: Int IHx: forally0 : Int, x * y0.+1 = x + x * y0
y + (x + x * y) = x + (y + x * y)
x: nat y: Int IHx: forally0 : Int, x * y0.+1 = x + x * y0
y + x = x + y
byrewrite int_add_comm.
x: nat y: Int IHx: forally0 : Int, - x * y0.+1 = - x + - x * y0
(- x).-1 * y.+1 = (- x).-1 + (- x).-1 * y
x: nat y: Int IHx: forally0 : Int, - x * y0.+1 = - x + - x * y0
- y.+1 + - x * y.+1 = (- x).-1 + (- y + - x * y)
x: nat y: Int IHx: forally0 : Int, - x * y0.+1 = - x + - x * y0
(- y).-1 + - x * y.+1 = (- x).-1 + (- y + - x * y)
x: nat y: Int IHx: forally0 : Int, - x * y0.+1 = - x + - x * y0
(- y).-1 + - (x * y.+1) = (- x).-1 + (- y + - x * y)
x: nat y: Int IHx: forally0 : Int, - x * y0.+1 = - x + - x * y0
(- y + - (x * y.+1)).-1 = (- x + (- y + - x * y)).-1
x: nat y: Int IHx: forally0 : Int, - x * y0.+1 = - x + - x * y0
- y + - (x * y.+1) = - x + (- y + - x * y)
x: nat y: Int IHx: forally0 : Int, - x * y0.+1 = - x + - x * y0
- y + - x * y.+1 = - x + (- y + - x * y)
x: nat y: Int IHx: forally0 : Int, - x * y0.+1 = - x + - x * y0
- y + (- x + - x * y) = - x + (- y + - x * y)
x: nat y: Int IHx: forally0 : Int, - x * y0.+1 = - x + - x * y0
- 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: forally0 : Int, x * y0.-1 = - x + x * y0
x.+1 * y.-1 = - x.+1 + x.+1 * y
x: nat y: Int IHx: forally0 : Int, - x * y0.-1 = - - x + - x * y0
(- x).-1 * y.-1 = - (- x).-1 + (- x).-1 * y
y: Int
0 * y.-1 = - 0 + 0 * y
reflexivity.
x: nat y: Int IHx: forally0 : Int, x * y0.-1 = - x + x * y0
x.+1 * y.-1 = - x.+1 + x.+1 * y
x: nat y: Int IHx: forally0 : Int, x * y0.-1 = - x + x * y0
y.-1 + x * y.-1 = - x.+1 + (y + x * y)
x: nat y: Int IHx: forally0 : Int, x * y0.-1 = - x + x * y0
y.-1 + (- x + x * y) = - x.+1 + (y + x * y)
x: nat y: Int IHx: forally0 : Int, x * y0.-1 = - x + x * y0
y.-1 + - x = - x.+1 + y
x: nat y: Int IHx: forally0 : Int, x * y0.-1 = - x + x * y0
- - y.-1 + - x = - x.+1 + y
x: nat y: Int IHx: forally0 : Int, x * y0.-1 = - x + x * y0
- (- y.-1 + x) = - x.+1 + y
x: nat y: Int IHx: forally0 : Int, x * y0.-1 = - x + x * y0
- ((- y).+1 + x) = - x.+1 + y
x: nat y: Int IHx: forally0 : Int, x * y0.-1 = - x + x * y0
- (- y + x).+1 = - x.+1 + y
x: nat y: Int IHx: forally0 : Int, x * y0.-1 = - x + x * y0
- (x + - y).+1 = - x.+1 + y
x: nat y: Int IHx: forally0 : Int, x * y0.-1 = - x + x * y0
- (x.+1 + - y) = - x.+1 + y
x: nat y: Int IHx: forally0 : Int, x * y0.-1 = - x + x * y0
- x.+1 + - - y = - x.+1 + y
byrewrite int_neg_neg.
x: nat y: Int IHx: forally0 : Int, - x * y0.-1 = - - x + - x * y0
(- x).-1 * y.-1 = - (- x).-1 + (- x).-1 * y
x: nat y: Int IHx: forally0 : Int, - x * y0.-1 = - - x + - x * y0
(- x).-1 * y.-1 = (- - x).+1 + (- x).-1 * y
x: nat y: Int IHx: forally0 : Int, - x * y0.-1 = - - x + - x * y0
(- x).-1 * y.-1 = x.+1 + (- x).-1 * y
x: nat y: Int IHx: forally0 : Int, - x * y0.-1 = - - x + - x * y0
- y.-1 + - x * y.-1 = x.+1 + (- y + - x * y)
x: nat y: Int IHx: forally0 : Int, - x * y0.-1 = - - x + - x * y0
- y.-1 + (- - x + - x * y) = x.+1 + (- y + - x * y)
x: nat y: Int IHx: forally0 : Int, - x * y0.-1 = - - x + - x * y0
- y.-1 + - - x = x.+1 + - y
x: nat y: Int IHx: forally0 : Int, - x * y0.-1 = - - x + - x * y0
(- y).+1 + - - x = x.+1 + - y
x: nat y: Int IHx: forally0 : Int, - x * y0.-1 = - - x + - x * y0
(- y).+1 + x = x.+1 + - y
x: nat y: Int IHx: forally0 : Int, - x * y0.-1 = - - x + - x * y0
- 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: forallx0 : Int, x0 * y = y * x0
x * y.+1 = y.+1 * x
x: Int y: nat IHy: forallx0 : Int, x0 * - y = - y * x0
x * (- y).-1 = (- y).-1 * x
x: Int
x * 0 = 0 * x
apply int_mul_0_r.
x: Int y: nat IHy: forallx0 : Int, x0 * y = y * x0
x * y.+1 = y.+1 * x
x: Int y: nat IHy: forallx0 : Int, x0 * y = y * x0
x * y.+1 = x + y * x
x: Int y: nat IHy: forallx0 : Int, x0 * y = y * x0
x + x * y = x + y * x
byrewrite IHy.
x: Int y: nat IHy: forallx0 : Int, x0 * - y = - y * x0
x * (- y).-1 = (- y).-1 * x
x: Int y: nat IHy: forallx0 : Int, x0 * - y = - y * x0
x * (- y).-1 = - x + - y * x
x: Int y: nat IHy: forallx0 : Int, x0 * - y = - y * x0
- 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: forally0z0 : Int, x * (y0 + z0) = x * y0 + x * z0
x.+1 * (y + z) = x.+1 * y + x.+1 * z
x: nat y, z: Int IHx: forally0z0 : Int, - x * (y0 + z0) = - x * y0 + - x * z0
(- 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: forally0z0 : Int, x * (y0 + z0) = x * y0 + x * z0
x.+1 * (y + z) = x.+1 * y + x.+1 * z
x: nat y, z: Int IHx: forally0z0 : Int, x * (y0 + z0) = x * y0 + x * z0
y + z + x * (y + z) = y + x * y + (z + x * z)
x: nat y, z: Int IHx: forally0z0 : Int, x * (y0 + z0) = x * y0 + x * z0
y + z + (x * y + x * z) = y + x * y + (z + x * z)
x: nat y, z: Int IHx: forally0z0 : Int, x * (y0 + z0) = x * y0 + x * z0
y + z + x * y = y + x * y + z
x: nat y, z: Int IHx: forally0z0 : Int, x * (y0 + z0) = x * y0 + x * z0
z + x * y = x * y + z
byrewrite int_add_comm.
x: nat y, z: Int IHx: forally0z0 : Int, - x * (y0 + z0) = - x * y0 + - x * z0
(- x).-1 * (y + z) = (- x).-1 * y + (- x).-1 * z
x: nat y, z: Int IHx: forally0z0 : Int, - x * (y0 + z0) = - x * y0 + - x * z0
- (y + z) + - x * (y + z) = - y + - x * y + (- z + - x * z)
x: nat y, z: Int IHx: forally0z0 : Int, - x * (y0 + z0) = - x * y0 + - x * z0
- (y + z) + (- x * y + - x * z) = - y + - x * y + (- z + - x * z)
x: nat y, z: Int IHx: forally0z0 : Int, - x * (y0 + z0) = - x * y0 + - x * z0
- (y + z) + - x * y = - y + - x * y + - z
x: nat y, z: Int IHx: forally0z0 : Int, - x * (y0 + z0) = - x * y0 + - x * z0
- y + - z + - x * y = - y + - x * y + - z
x: nat y, z: Int IHx: forally0z0 : Int, - x * (y0 + z0) = - x * y0 + - x * z0
- 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: forally0z0 : Int, x * (y0 * z0) = x * y0 * z0
x.+1 * (y * z) = x.+1 * y * z
x: nat y, z: Int IHx: forally0z0 : Int, - x * (y0 * z0) = - x * y0 * z0
(- x).-1 * (y * z) = (- x).-1 * y * z
y, z: Int
0 * (y * z) = 0 * y * z
reflexivity.
x: nat y, z: Int IHx: forally0z0 : Int, x * (y0 * z0) = x * y0 * z0
x.+1 * (y * z) = x.+1 * y * z
x: nat y, z: Int IHx: forally0z0 : Int, x * (y0 * z0) = x * y0 * z0
y * z + x * (y * z) = (y + x * y) * z
x: nat y, z: Int IHx: forally0z0 : Int, x * (y0 * z0) = x * y0 * z0
y * z + x * (y * z) = y * z + x * y * z
byrewrite IHx.
x: nat y, z: Int IHx: forally0z0 : Int, - x * (y0 * z0) = - x * y0 * z0
(- x).-1 * (y * z) = (- x).-1 * y * z
x: nat y, z: Int IHx: forally0z0 : Int, - x * (y0 * z0) = - x * y0 * z0
- (y * z) + - x * (y * z) = (- y + - x * y) * z
x: nat y, z: Int IHx: forally0z0 : Int, - x * (y0 * z0) = - x * y0 * z0
- (y * z) + - x * (y * z) = - y * z + - x * y * z
x: nat y, z: Int IHx: forally0z0 : Int, - x * (y0 * z0) = - x * y0 * z0
- 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: foralla0 : A, g (int_iter f n a0) = int_iter f' n (g a0)
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: foralla0 : A, g (int_iter f (- n) a0) = int_iter f' (- n) (g a0)
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: foralla0 : A, g (int_iter f n a0) = int_iter f' n (g a0)
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: foralla0 : A, g (int_iter f n a0) = int_iter f' n (g a0)
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: foralla0 : A, g (int_iter f n a0) = int_iter f' n (g a0)
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: foralla0 : A, g (int_iter f (- n) a0) = int_iter f' (- n) (g a0)
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: foralla0 : A, g (int_iter f (- n) a0) = int_iter f' (- n) (g a0)
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: foralla0 : A, g (int_iter f (- n) a0) = int_iter f' (- n) (g a0)
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: foralla0 : A, g (int_iter f (- n) a0) = int_iter f' (- n) (g a0)
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: foralla0 : A, g (int_iter f (- n) a0) = int_iter f' (- n) (g a0)
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: foralla0 : A, g (int_iter f (- n) a0) = int_iter f' (- n) (g a0)
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: foralla0 : A, g (int_iter f (- n) a0) = int_iter f' (- n) (g a0)
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: forallx0 : A, P x0 -> P (f x0) Ppred: forallx0 : A, P x0 -> P (f^-1 x0) x: A
P x -> P (int_iter f 0 x)
n: nat A: Type f: A -> A IsEquiv0: IsEquiv f P: A -> Type Psucc: forallx0 : A, P x0 -> P (f x0) Ppred: forallx0 : A, P x0 -> P (f^-1 x0) IHn: forallx0 : A, P x0 -> P (int_iter f n x0) 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: forallx0 : A, P x0 -> P (f x0) Ppred: forallx0 : A, P x0 -> P (f^-1 x0) IHn: forallx0 : A, P x0 -> P (int_iter f (- n) x0) x: A
P x -> P (int_iter f (- n).-1 x)
A: Type f: A -> A IsEquiv0: IsEquiv f P: A -> Type Psucc: forallx0 : A, P x0 -> P (f x0) Ppred: forallx0 : A, P x0 -> P (f^-1 x0) 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: forallx0 : A, P x0 -> P (f x0) Ppred: forallx0 : A, P x0 -> P (f^-1 x0) IHn: forallx0 : A, P x0 -> P (int_iter f n x0) 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: forallx0 : A, P x0 -> P (f x0) Ppred: forallx0 : A, P x0 -> P (f^-1 x0) IHn: forallx0 : A, P x0 -> P (int_iter f n x0) 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: forallx0 : A, P x0 -> P (f x0) Ppred: forallx0 : A, P x0 -> P (f^-1 x0) IHn: forallx0 : A, P x0 -> P (int_iter f n x0) 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: forallx0 : A, P x0 -> P (f x0) Ppred: forallx0 : A, P x0 -> P (f^-1 x0) IHn: forallx0 : A, P x0 -> P (int_iter f (- n) x0) 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: forallx0 : A, P x0 -> P (f x0) Ppred: forallx0 : A, P x0 -> P (f^-1 x0) IHn: forallx0 : A, P x0 -> P (int_iter f (- n) x0) 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: forallx0 : A, P x0 -> P (f x0) Ppred: forallx0 : A, P x0 -> P (f^-1 x0) IHn: forallx0 : A, P x0 -> P (int_iter f (- n) x0) 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. *)