Compare commits

...

4 commits

Author SHA1 Message Date
Floris van Doorn
5333dcfa02 remove print command in hott/init 2018-01-25 17:33:42 -05:00
jonas-frey
d68cdae2f3 Imp hott (#10)
removing sorrys
2018-01-25 18:08:17 -05:00
Floris van Doorn
7411011340 remove HoTT library (except init)
Use previous commit if you want to use the HoTT library
2017-02-10 12:07:22 -05:00
Floris van Doorn
18313bfab0 feat(hott): make Type.{0} impredicative
Warnings: - no_confusion is not generated, which means that injection and cases tactics might not work
- there are some sorry's in the init folder
- most files out of the init folder don't compile
2017-02-10 12:04:08 -05:00
166 changed files with 86 additions and 37469 deletions

View file

@ -1,29 +0,0 @@
algebra
=======
The following files are [ported](../port.md) from the standard library. If anything needs to be changed, it is probably a good idea to change it in the standard library and then port the file again (see also [script/port.pl](../../script/port.pl)).
* [priority](priority.hlean) : priority for algebraic operations
* [relation](relation.hlean)
* [binary](binary.hlean) : binary operations
* [order](order.hlean)
* [lattice](lattice.hlean)
* [group](group.hlean)
* [ring](ring.hlean)
* [ordered_group](ordered_group.hlean)
* [ordered_ring](ordered_ring.hlean)
* [field](field.hlean)
* [ordered_field](ordered_field.hlean)
* [bundled](bundled.hlean) : bundled versions of the algebraic structures
Files which are not ported from the standard library:
* [group_theory](group_theory.hlean) : Basic theorems about group homomorphisms and isomorphisms
* [trunc_group](trunc_group.hlean) : truncate an infinity-group to a group
* [homotopy_group](homotopy_group.hlean) : homotopy groups of a pointed type
* [e_closure](e_closure.hlean) : the type of words formed by a relation
* [graph](graph.hlean) : definition and operations on paths in a graph.
Subfolders (not ported):
* [category](category/category.md) : Category Theory

View file

@ -1,117 +0,0 @@
/-
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura, Jeremy Avigad
General properties of binary operations.
-/
open eq.ops function
namespace binary
section
variable {A : Type}
variables (op₁ : A → A → A) (inv : A → A) (one : A)
local notation a * b := op₁ a b
local notation a ⁻¹ := inv a
definition commutative := Πa b, a * b = b * a
definition associative := Πa b c, (a * b) * c = a * (b * c)
definition left_identity := Πa, one * a = a
definition right_identity := Πa, a * one = a
definition left_inverse := Πa, a⁻¹ * a = one
definition right_inverse := Πa, a * a⁻¹ = one
definition left_cancelative := Πa b c, a * b = a * c → b = c
definition right_cancelative := Πa b c, a * b = c * b → a = c
definition inv_op_cancel_left := Πa b, a⁻¹ * (a * b) = b
definition op_inv_cancel_left := Πa b, a * (a⁻¹ * b) = b
definition inv_op_cancel_right := Πa b, a * b⁻¹ * b = a
definition op_inv_cancel_right := Πa b, a * b * b⁻¹ = a
variable (op₂ : A → A → A)
local notation a + b := op₂ a b
definition left_distributive := Πa b c, a * (b + c) = a * b + a * c
definition right_distributive := Πa b c, (a + b) * c = a * c + b * c
definition right_commutative {B : Type} (f : B → A → B) := Π b a₁ a₂, f (f b a₁) a₂ = f (f b a₂) a₁
definition left_commutative {B : Type} (f : A → B → B) := Π a₁ a₂ b, f a₁ (f a₂ b) = f a₂ (f a₁ b)
end
section
variable {A : Type}
variable {f : A → A → A}
variable H_comm : commutative f
variable H_assoc : associative f
local infixl `*` := f
theorem left_comm : left_commutative f :=
take a b c, calc
a*(b*c) = (a*b)*c : H_assoc
... = (b*a)*c : H_comm
... = b*(a*c) : H_assoc
theorem right_comm : right_commutative f :=
take a b c, calc
(a*b)*c = a*(b*c) : H_assoc
... = a*(c*b) : H_comm
... = (a*c)*b : H_assoc
theorem comm4 (a b c d : A) : a*b*(c*d) = a*c*(b*d) :=
calc
a*b*(c*d) = a*b*c*d : H_assoc
... = a*c*b*d : right_comm H_comm H_assoc
... = a*c*(b*d) : H_assoc
end
section
variable {A : Type}
variable {f : A → A → A}
variable H_assoc : associative f
local infixl `*` := f
theorem assoc4helper (a b c d) : (a*b)*(c*d) = a*((b*c)*d) :=
calc
(a*b)*(c*d) = a*(b*(c*d)) : H_assoc
... = a*((b*c)*d) : H_assoc
end
definition right_commutative_compose_right
{A B : Type} (f : A → A → A) (g : B → A) (rcomm : right_commutative f) : right_commutative (compose_right f g) :=
λ a b₁ b₂, !rcomm
definition left_commutative_compose_left
{A B : Type} (f : A → A → A) (g : B → A) (lcomm : left_commutative f) : left_commutative (compose_left f g) :=
λ a b₁ b₂, !lcomm
end binary
open eq
namespace is_equiv
definition inv_preserve_binary {A B : Type} (f : A → B) [H : is_equiv f]
(mA : A → A → A) (mB : B → B → B) (H : Π(a a' : A), f (mA a a') = mB (f a) (f a'))
(b b' : B) : f⁻¹ (mB b b') = mA (f⁻¹ b) (f⁻¹ b') :=
begin
have H2 : f⁻¹ (mB (f (f⁻¹ b)) (f (f⁻¹ b'))) = f⁻¹ (f (mA (f⁻¹ b) (f⁻¹ b'))), from ap f⁻¹ !H⁻¹,
rewrite [+right_inv f at H2,left_inv f at H2,▸* at H2,H2]
end
definition preserve_binary_of_inv_preserve {A B : Type} (f : A → B) [H : is_equiv f]
(mA : A → A → A) (mB : B → B → B) (H : Π(b b' : B), f⁻¹ (mB b b') = mA (f⁻¹ b) (f⁻¹ b'))
(a a' : A) : f (mA a a') = mB (f a) (f a') :=
begin
have H2 : f (mA (f⁻¹ (f a)) (f⁻¹ (f a'))) = f (f⁻¹ (mB (f a) (f a'))), from ap f !H⁻¹,
rewrite [right_inv f at H2,+left_inv f at H2,▸* at H2,H2]
end
end is_equiv
namespace equiv
open is_equiv
definition inv_preserve_binary {A B : Type} (f : A ≃ B)
(mA : A → A → A) (mB : B → B → B) (H : Π(a a' : A), f (mA a a') = mB (f a) (f a'))
(b b' : B) : f⁻¹ (mB b b') = mA (f⁻¹ b) (f⁻¹ b') :=
inv_preserve_binary f mA mB H b b'
definition preserve_binary_of_inv_preserve {A B : Type} (f : A ≃ B)
(mA : A → A → A) (mB : B → B → B) (H : Π(b b' : B), f⁻¹ (mB b b') = mA (f⁻¹ b) (f⁻¹ b'))
(a a' : A) : f (mA a a') = mB (f a) (f a') :=
preserve_binary_of_inv_preserve f mA mB H a a'
end equiv

View file

@ -1,193 +0,0 @@
/-
Copyright (c) 2015 Jeremy Avigad. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Jeremy Avigad
Bundled structures
-/
import algebra.group homotopy.interval
open algebra pointed is_trunc
namespace algebra
structure Semigroup :=
(carrier : Type) (struct : semigroup carrier)
attribute Semigroup.carrier [coercion]
attribute Semigroup.struct [instance]
structure CommSemigroup :=
(carrier : Type) (struct : comm_semigroup carrier)
attribute CommSemigroup.carrier [coercion]
attribute CommSemigroup.struct [instance]
structure Monoid :=
(carrier : Type) (struct : monoid carrier)
attribute Monoid.carrier [coercion]
attribute Monoid.struct [instance]
structure CommMonoid :=
(carrier : Type) (struct : comm_monoid carrier)
attribute CommMonoid.carrier [coercion]
attribute CommMonoid.struct [instance]
structure Group :=
(carrier : Type) (struct : group carrier)
attribute Group.carrier [coercion]
attribute Group.struct [instance]
section
local attribute Group.struct [instance]
definition pSet_of_Group [constructor] [reducible] [coercion] (G : Group) : Set* :=
ptrunctype.mk G !semigroup.is_set_carrier 1
end
attribute algebra._trans_of_pSet_of_Group [unfold 1]
attribute algebra._trans_of_pSet_of_Group_1 algebra._trans_of_pSet_of_Group_2 [constructor]
definition pType_of_Group [reducible] [constructor] : Group → Type* :=
algebra._trans_of_pSet_of_Group_1
definition Set_of_Group [reducible] [constructor] : Group → Set :=
algebra._trans_of_pSet_of_Group_2
definition AddGroup : Type := Group
definition AddGroup.mk [constructor] [reducible] (G : Type) (H : add_group G) : AddGroup :=
Group.mk G H
definition AddGroup.struct [reducible] (G : AddGroup) : add_group G :=
Group.struct G
attribute AddGroup.struct Group.struct [instance] [priority 2000]
structure AbGroup :=
(carrier : Type) (struct : ab_group carrier)
attribute AbGroup.carrier [coercion]
definition AddAbGroup : Type := AbGroup
definition AddAbGroup.mk [constructor] [reducible] (G : Type) (H : add_ab_group G) :
AddAbGroup :=
AbGroup.mk G H
definition AddAbGroup.struct [reducible] (G : AddAbGroup) : add_ab_group G :=
AbGroup.struct G
attribute AddAbGroup.struct AbGroup.struct [instance] [priority 2000]
definition Group_of_AbGroup [coercion] [constructor] (G : AbGroup) : Group :=
Group.mk G _
attribute algebra._trans_of_Group_of_AbGroup_1
algebra._trans_of_Group_of_AbGroup
algebra._trans_of_Group_of_AbGroup_3 [constructor]
attribute algebra._trans_of_Group_of_AbGroup_2 [unfold 1]
definition ab_group_AbGroup [instance] (G : AbGroup) : ab_group G :=
AbGroup.struct G
definition add_ab_group_AddAbGroup [instance] (G : AddAbGroup) : add_ab_group G :=
AbGroup.struct G
-- structure AddSemigroup :=
-- (carrier : Type) (struct : add_semigroup carrier)
-- attribute AddSemigroup.carrier [coercion]
-- attribute AddSemigroup.struct [instance]
-- structure AddCommSemigroup :=
-- (carrier : Type) (struct : add_comm_semigroup carrier)
-- attribute AddCommSemigroup.carrier [coercion]
-- attribute AddCommSemigroup.struct [instance]
-- structure AddMonoid :=
-- (carrier : Type) (struct : add_monoid carrier)
-- attribute AddMonoid.carrier [coercion]
-- attribute AddMonoid.struct [instance]
-- structure AddCommMonoid :=
-- (carrier : Type) (struct : add_comm_monoid carrier)
-- attribute AddCommMonoid.carrier [coercion]
-- attribute AddCommMonoid.struct [instance]
-- structure AddGroup :=
-- (carrier : Type) (struct : add_group carrier)
-- attribute AddGroup.carrier [coercion]
-- attribute AddGroup.struct [instance]
-- structure AddAbGroup :=
-- (carrier : Type) (struct : add_ab_group carrier)
-- attribute AddAbGroup.carrier [coercion]
-- attribute AddAbGroup.struct [instance]
-- some bundled infinity-structures
structure InfGroup :=
(carrier : Type) (struct : inf_group carrier)
attribute InfGroup.carrier [coercion]
attribute InfGroup.struct [instance]
section
local attribute InfGroup.struct [instance]
definition pType_of_InfGroup [constructor] [reducible] [coercion] (G : InfGroup) : Type* :=
pType.mk G 1
end
attribute algebra._trans_of_pType_of_InfGroup [unfold 1]
definition AddInfGroup : Type := InfGroup
definition AddInfGroup.mk [constructor] [reducible] (G : Type) (H : add_inf_group G) :
AddInfGroup :=
InfGroup.mk G H
definition AddInfGroup.struct [reducible] (G : AddInfGroup) : add_inf_group G :=
InfGroup.struct G
attribute AddInfGroup.struct InfGroup.struct [instance] [priority 2000]
structure AbInfGroup :=
(carrier : Type) (struct : ab_inf_group carrier)
attribute AbInfGroup.carrier [coercion]
definition AddAbInfGroup : Type := AbInfGroup
definition AddAbInfGroup.mk [constructor] [reducible] (G : Type) (H : add_ab_inf_group G) :
AddAbInfGroup :=
AbInfGroup.mk G H
definition AddAbInfGroup.struct [reducible] (G : AddAbInfGroup) : add_ab_inf_group G :=
AbInfGroup.struct G
attribute AddAbInfGroup.struct AbInfGroup.struct [instance] [priority 2000]
definition InfGroup_of_AbInfGroup [coercion] [constructor] (G : AbInfGroup) : InfGroup :=
InfGroup.mk G _
attribute algebra._trans_of_InfGroup_of_AbInfGroup_1 [constructor]
attribute algebra._trans_of_InfGroup_of_AbInfGroup [unfold 1]
definition InfGroup_of_Group [constructor] (G : Group) : InfGroup :=
InfGroup.mk G _
definition AddInfGroup_of_AddGroup [constructor] (G : AddGroup) : AddInfGroup :=
AddInfGroup.mk G _
definition AbInfGroup_of_AbGroup [constructor] (G : AbGroup) : AbInfGroup :=
AbInfGroup.mk G _
definition AddAbInfGroup_of_AddAbGroup [constructor] (G : AddAbGroup) : AddAbInfGroup :=
AddAbInfGroup.mk G _
end algebra

View file

@ -1,143 +0,0 @@
/-
Copyright (c) 2014 Jakob von Raumer. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Jakob von Raumer
-/
import .iso
open iso is_equiv equiv eq is_trunc sigma
/-
A category is a precategory extended by a witness
that the function from paths to isomorphisms is an equivalence.
-/
namespace category
/-
TODO: restructure this. Should is_univalent be a class with as argument
(C : Precategory). Or is that problematic if we want to apply this to cases where e.g.
a b are functors, and we need to synthesize ? : precategory (functor C D).
-/
definition is_univalent [class] {ob : Type} (C : precategory ob) :=
Π(a b : ob), is_equiv (iso_of_eq : a = b → a ≅ b)
definition is_equiv_of_is_univalent [instance] {ob : Type} [C : precategory ob]
[H : is_univalent C] (a b : ob) : is_equiv (iso_of_eq : a = b → a ≅ b) :=
H a b
structure category [class] (ob : Type) extends parent : precategory ob :=
mk' :: (iso_of_path_equiv : is_univalent parent)
-- Remark: category and precategory are classes. So, the structure command
-- does not create a coercion between them automatically.
-- This coercion is needed for definitions such as category_eq_of_equiv
-- without it, we would have to explicitly use category.to_precategory
attribute category.to_precategory [coercion]
abbreviation iso_of_path_equiv := @category.iso_of_path_equiv
attribute category.iso_of_path_equiv [instance]
definition category.mk [reducible] [unfold 2] {ob : Type} (C : precategory ob)
(H : is_univalent C) : category ob :=
precategory.rec_on C category.mk' H
section basic
variables {ob : Type} [C : category ob]
include C
-- Make iso_of_path_equiv a class instance
attribute iso_of_path_equiv [instance]
definition eq_equiv_iso [constructor] (a b : ob) : (a = b) ≃ (a ≅ b) :=
equiv.mk iso_of_eq _
definition eq_of_iso [reducible] {a b : ob} : a ≅ b → a = b :=
iso_of_eq⁻¹ᶠ
definition iso_of_eq_eq_of_iso {a b : ob} (p : a ≅ b) : iso_of_eq (eq_of_iso p) = p :=
right_inv iso_of_eq p
definition hom_of_eq_eq_of_iso {a b : ob} (p : a ≅ b) : hom_of_eq (eq_of_iso p) = to_hom p :=
ap to_hom !iso_of_eq_eq_of_iso
definition inv_of_eq_eq_of_iso {a b : ob} (p : a ≅ b) : inv_of_eq (eq_of_iso p) = to_inv p :=
ap to_inv !iso_of_eq_eq_of_iso
theorem eq_of_iso_refl {a : ob} : eq_of_iso (iso.refl a) = idp :=
inv_eq_of_eq idp
theorem eq_of_iso_trans {a b c : ob} (p : a ≅ b) (q : b ≅ c) :
eq_of_iso (p ⬝i q) = eq_of_iso p ⬝ eq_of_iso q :=
begin
apply inv_eq_of_eq,
apply eq.inverse, apply concat, apply iso_of_eq_con,
apply concat, apply ap (λ x, x ⬝i _), apply iso_of_eq_eq_of_iso,
apply ap (λ x, _ ⬝i x), apply iso_of_eq_eq_of_iso
end
definition is_trunc_1_ob : is_trunc 1 ob :=
begin
apply is_trunc_succ_intro, intro a b,
fapply is_trunc_is_equiv_closed,
exact (@eq_of_iso _ _ a b),
apply is_equiv_inv,
end
end basic
-- Bundled version of categories
-- we don't use Category.carrier explicitly, but rather use Precategory.carrier (to_Precategory C)
structure Category : Type :=
(carrier : Type)
(struct : category carrier)
attribute Category.struct [instance] [coercion]
definition Category.to_Precategory [constructor] [coercion] [reducible] (C : Category)
: Precategory :=
Precategory.mk (Category.carrier C) _
definition category.Mk [constructor] [reducible] := Category.mk
definition category.MK [constructor] [reducible] (C : Precategory)
(H : is_univalent C) : Category := Category.mk C (category.mk C H)
definition Category.eta (C : Category) : Category.mk C C = C :=
Category.rec (λob c, idp) C
protected definition category.sigma_char.{u v} [constructor] (ob : Type)
: category.{u v} ob ≃ Σ(C : precategory.{u v} ob), is_univalent C :=
begin
fapply equiv.MK,
{ intro x, induction x, constructor, assumption},
{ intro y, induction y with y1 y2, induction y1, constructor, assumption},
{ intro y, induction y with y1 y2, induction y1, reflexivity},
{ intro x, induction x, reflexivity}
end
definition category_eq {ob : Type}
{C D : category ob}
(p : Π{a b}, @hom ob C a b = @hom ob D a b)
(q : Πa b c g f, cast p (@comp ob C a b c g f) = @comp ob D a b c (cast p g) (cast p f))
: C = D :=
begin
apply eq_of_fn_eq_fn !category.sigma_char,
fapply sigma_eq,
{ induction C, induction D, esimp, exact precategory_eq @p q},
{ unfold is_univalent, apply is_prop.elimo},
end
definition category_eq_of_equiv {ob : Type}
{C D : category ob}
(p : Π⦃a b⦄, @hom ob C a b ≃ @hom ob D a b)
(q : Π{a b c} g f, p (@comp ob C a b c g f) = @comp ob D a b c (p g) (p f))
: C = D :=
begin
fapply category_eq,
{ intro a b, exact ua !@p},
{ intros, refine !cast_ua ⬝ !q ⬝ _, unfold [category.to_precategory],
apply ap011 !@category.comp !cast_ua⁻¹ᵖ !cast_ua⁻¹ᵖ},
end
-- TODO: Category_eq[']
end category

View file

@ -1,14 +0,0 @@
algebra.category
================
Development of Category Theory. The following files are in this folder (sorted such that files only import previous files).
* [precategory](precategory.hlean)
* [iso](iso.hlean) : iso, mono, epi, split mono, split epi
* [category](category.hlean) : Categories (i.e. univalent or Rezk-complete precategories)
* [groupoid](groupoid.hlean)
* [functor](functor/functor.md) (subfolder) : definition and properties of functors
* [strict](strict.hlean) : Strict categories
* [nat_trans](nat_trans.hlean) : Natural transformations
* [constructions](constructions/constructions.md) (subfolder) : basic constructions on categories and examples of categories
* [limits](limits/limits.md) (subfolder) : Limits and colimits in precategories

View file

@ -1,174 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
Comma category
-/
import ..functor.basic ..strict ..category
open eq functor equiv sigma sigma.ops is_trunc iso is_equiv
namespace category
structure comma_object {A B C : Precategory} (S : A ⇒ C) (T : B ⇒ C) :=
(a : A)
(b : B)
(f : S a ⟶ T b)
abbreviation ob1 [unfold 6] := @comma_object.a
abbreviation ob2 [unfold 6] := @comma_object.b
abbreviation mor [unfold 6] := @comma_object.f
variables {A B C : Precategory} (S : A ⇒ C) (T : B ⇒ C)
definition comma_object_sigma_char : (Σ(a : A) (b : B), S a ⟶ T b) ≃ comma_object S T :=
begin
fapply equiv.MK,
{ intro u, exact comma_object.mk u.1 u.2.1 u.2.2},
{ intro x, cases x with a b f, exact ⟨a, b, f⟩},
{ intro x, cases x, reflexivity},
{ intro u, cases u with u1 u2, cases u2, reflexivity},
end
theorem is_trunc_comma_object (n : trunc_index) [HA : is_trunc n A]
[HB : is_trunc n B] [H : Π(s d : C), is_trunc n (hom s d)] : is_trunc n (comma_object S T) :=
by apply is_trunc_equiv_closed;apply comma_object_sigma_char
variables {S T}
definition comma_object_eq' {x y : comma_object S T} (p : ob1 x = ob1 y) (q : ob2 x = ob2 y)
(r : mor x =[ap011 (@hom C C) (ap (to_fun_ob S) p) (ap (to_fun_ob T) q)] mor y) : x = y :=
begin
cases x with a b f, cases y with a' b' f', cases p, cases q,
esimp [ap011,congr,ap,subst] at r,
eapply (idp_rec_on r), reflexivity
end
--TODO: remove. This is a different version where Hq is not in square brackets
-- definition eq_comp_inverse_of_comp_eq' {ob : Type} {C : precategory ob} {d c b : ob} {r : hom c d}
-- {q : hom b c} {x : hom b d} {Hq : is_iso q} (p : r ∘ q = x) : r = x ∘ q⁻¹ʰ :=
-- sorry
-- := sorry --eq_inverse_comp_of_comp_eq p
definition comma_object_eq {x y : comma_object S T} (p : ob1 x = ob1 y) (q : ob2 x = ob2 y)
(r : T (hom_of_eq q) ∘ mor x ∘ S (inv_of_eq p) = mor y) : x = y :=
begin
cases x with a b f, cases y with a' b' f', cases p, cases q,
apply ap (comma_object.mk a' b'),
rewrite [▸* at r, -r, +respect_id, id_leftright]
end
definition ap_ob1_comma_object_eq' (x y : comma_object S T) (p : ob1 x = ob1 y) (q : ob2 x = ob2 y)
(r : mor x =[ap011 (@hom C C) (ap (to_fun_ob S) p) (ap (to_fun_ob T) q)] mor y)
: ap ob1 (comma_object_eq' p q r) = p :=
begin
cases x with a b f, cases y with a' b' f', cases p, cases q,
eapply (idp_rec_on r), reflexivity
end
definition ap_ob2_comma_object_eq' (x y : comma_object S T) (p : ob1 x = ob1 y) (q : ob2 x = ob2 y)
(r : mor x =[ap011 (@hom C C) (ap (to_fun_ob S) p) (ap (to_fun_ob T) q)] mor y)
: ap ob2 (comma_object_eq' p q r) = q :=
begin
cases x with a b f, cases y with a' b' f', cases p, cases q,
eapply (idp_rec_on r), reflexivity
end
structure comma_morphism (x y : comma_object S T) :=
mk' ::
(g : ob1 x ⟶ ob1 y)
(h : ob2 x ⟶ ob2 y)
(p : T h ∘ mor x = mor y ∘ S g)
(p' : mor y ∘ S g = T h ∘ mor x)
abbreviation mor1 := @comma_morphism.g
abbreviation mor2 := @comma_morphism.h
abbreviation coh := @comma_morphism.p
abbreviation coh' := @comma_morphism.p'
protected definition comma_morphism.mk [constructor] [reducible]
{x y : comma_object S T} (g h p) : comma_morphism x y :=
comma_morphism.mk' g h p p⁻¹
variables (x y z w : comma_object S T)
definition comma_morphism_sigma_char :
(Σ(g : ob1 x ⟶ ob1 y) (h : ob2 x ⟶ ob2 y), T h ∘ mor x = mor y ∘ S g) ≃ comma_morphism x y :=
begin
fapply equiv.MK,
{ intro u, exact (comma_morphism.mk u.1 u.2.1 u.2.2)},
{ intro f, cases f with g h p p', exact ⟨g, h, p⟩},
{ intro f, cases f with g h p p', esimp,
apply ap (comma_morphism.mk' g h p), apply is_prop.elim},
{ intro u, cases u with u1 u2, cases u2 with u2 u3, reflexivity},
end
theorem is_trunc_comma_morphism (n : trunc_index) [H1 : is_trunc n (ob1 x ⟶ ob1 y)]
[H2 : is_trunc n (ob2 x ⟶ ob2 y)] [Hp : Πm1 m2, is_trunc n (T m2 ∘ mor x = mor y ∘ S m1)]
: is_trunc n (comma_morphism x y) :=
by apply is_trunc_equiv_closed; apply comma_morphism_sigma_char
variables {x y z w}
definition comma_morphism_eq {f f' : comma_morphism x y}
(p : mor1 f = mor1 f') (q : mor2 f = mor2 f') : f = f' :=
begin
cases f with g h p₁ p₁', cases f' with g' h' p₂ p₂', cases p, cases q,
apply ap011 (comma_morphism.mk' g' h'),
apply is_prop.elim,
apply is_prop.elim
end
definition comma_compose (g : comma_morphism y z) (f : comma_morphism x y) : comma_morphism x z :=
comma_morphism.mk
(mor1 g ∘ mor1 f)
(mor2 g ∘ mor2 f)
(by rewrite [+respect_comp,-assoc,coh,assoc,coh,-assoc])
local infix ` ∘∘ `:60 := comma_compose
definition comma_id : comma_morphism x x :=
comma_morphism.mk id id (by rewrite [+respect_id,id_left,id_right])
theorem comma_assoc (h : comma_morphism z w) (g : comma_morphism y z) (f : comma_morphism x y) :
h ∘∘ (g ∘∘ f) = (h ∘∘ g) ∘∘ f :=
comma_morphism_eq !assoc !assoc
theorem comma_id_left (f : comma_morphism x y) : comma_id ∘∘ f = f :=
comma_morphism_eq !id_left !id_left
theorem comma_id_right (f : comma_morphism x y) : f ∘∘ comma_id = f :=
comma_morphism_eq !id_right !id_right
variables (S T)
definition comma_category [constructor] : Precategory :=
precategory.MK (comma_object S T)
comma_morphism
(λa b, !is_trunc_comma_morphism)
(@comma_compose _ _ _ _ _)
(@comma_id _ _ _ _ _)
(@comma_assoc _ _ _ _ _)
(@comma_id_left _ _ _ _ _)
(@comma_id_right _ _ _ _ _)
--TODO: this definition doesn't use category structure of A and B
definition strict_precategory_comma [HA : strict_precategory A] [HB : strict_precategory B] :
strict_precategory (comma_object S T) :=
strict_precategory.mk (comma_category S T) !is_trunc_comma_object
/-
--set_option pp.notation false
definition is_univalent_comma (HA : is_univalent A) (HB : is_univalent B)
: is_univalent (comma_category S T) :=
begin
intros c d,
fapply adjointify,
{ intro i, cases i with f s, cases s with g l r, cases f with fA fB fp, cases g with gA gB gp,
esimp at *, fapply comma_object_eq,
{apply iso_of_eq⁻¹ᶠ, exact (iso.MK fA gA (ap mor1 l) (ap mor1 r))},
{apply iso_of_eq⁻¹ᶠ, exact (iso.MK fB gB (ap mor2 l) (ap mor2 r))},
{ apply sorry /-rewrite hom_of_eq_eq_of_iso,-/ }},
{ apply sorry},
{ apply sorry},
end
-/
end category

View file

@ -1,181 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
Cones of a diagram in a category
-/
import ..nat_trans ..category
open functor nat_trans eq equiv is_trunc is_equiv iso sigma sigma.ops pi
namespace category
structure cone_obj {I C : Precategory} (F : I ⇒ C) :=
(c : C)
(η : constant_functor I c ⟹ F)
variables {I C D : Precategory} {F : I ⇒ C} {x y z : cone_obj F} {i : I}
definition cone_to_obj [unfold 4] := @cone_obj.c
definition cone_to_nat [unfold 4] (c : cone_obj F) : constant_functor I (cone_to_obj c) ⟹ F :=
cone_obj.η c
local attribute cone_to_obj [coercion]
structure cone_hom (x y : cone_obj F) :=
(f : x ⟶ y)
(p : Πi, cone_to_nat y i ∘ f = cone_to_nat x i)
definition cone_to_hom [unfold 6] := @cone_hom.f
definition cone_to_eq [unfold 6] (f : cone_hom x y) (i : I)
: cone_to_nat y i ∘ (cone_to_hom f) = cone_to_nat x i :=
cone_hom.p f i
local attribute cone_to_hom [coercion]
definition cone_id [constructor] (x : cone_obj F) : cone_hom x x :=
cone_hom.mk id
(λi, !id_right)
definition cone_comp [constructor] (g : cone_hom y z) (f : cone_hom x y) : cone_hom x z :=
cone_hom.mk (cone_to_hom g ∘ cone_to_hom f)
abstract λi, by rewrite [assoc, +cone_to_eq] end
definition cone_obj_eq (p : cone_to_obj x = cone_to_obj y)
(q : Πi, cone_to_nat x i = cone_to_nat y i ∘ hom_of_eq p) : x = y :=
begin
induction x, induction y, esimp at *, induction p, apply ap (cone_obj.mk c),
apply nat_trans_eq, intro i, exact q i ⬝ !id_right
end
theorem c_cone_obj_eq (p : cone_to_obj x = cone_to_obj y)
(q : Πi, cone_to_nat x i = cone_to_nat y i ∘ hom_of_eq p) : ap cone_to_obj (cone_obj_eq p q) = p :=
begin
induction x, induction y, esimp at *, induction p,
esimp [cone_obj_eq], rewrite [-ap_compose,↑function.compose,ap_constant]
end
theorem cone_hom_eq {f f' : cone_hom x y} (q : cone_to_hom f = cone_to_hom f') : f = f' :=
begin
induction f, induction f', esimp at *, induction q, apply ap (cone_hom.mk f),
apply @is_prop.elim, apply pi.is_trunc_pi, intro x, apply is_trunc_eq, -- type class fails
end
variable (F)
definition precategory_cone [instance] [constructor] : precategory (cone_obj F) :=
@precategory.mk _ cone_hom
abstract begin
intro x y,
have H : cone_hom x y ≃ Σ(f : x ⟶ y), Πi, cone_to_nat y i ∘ f = cone_to_nat x i,
begin
fapply equiv.MK,
{ intro f, induction f, constructor, assumption},
{ intro v, induction v, constructor, assumption},
{ intro v, induction v, reflexivity},
{ intro f, induction f, reflexivity}
end,
apply is_trunc.is_trunc_equiv_closed_rev, exact H,
fapply sigma.is_trunc_sigma, intros,
apply is_trunc_succ, apply pi.is_trunc_pi, intros, esimp,
/-exact _,-/ -- type class inference fails here
apply is_trunc_eq,
end end
(λx y z, cone_comp)
cone_id
abstract begin intros, apply cone_hom_eq, esimp, apply assoc end end
abstract begin intros, apply cone_hom_eq, esimp, apply id_left end end
abstract begin intros, apply cone_hom_eq, esimp, apply id_right end end
definition cone [constructor] : Precategory :=
precategory.Mk (precategory_cone F)
variable {F}
definition cone_iso_pr1 [constructor] (h : x ≅ y) : cone_to_obj x ≅ cone_to_obj y :=
iso.MK
(cone_to_hom (to_hom h))
(cone_to_hom (to_inv h))
(ap cone_to_hom (to_left_inverse h))
(ap cone_to_hom (to_right_inverse h))
definition cone_iso.mk [constructor] (f : cone_to_obj x ≅ cone_to_obj y)
(p : Πi, cone_to_nat y i ∘ to_hom f = cone_to_nat x i) : x ≅ y :=
begin
fapply iso.MK,
{ exact !cone_hom.mk p},
{ fapply cone_hom.mk,
{ exact to_inv f},
{ intro i, apply comp_inverse_eq_of_eq_comp, exact (p i)⁻¹}},
{ apply cone_hom_eq, esimp, apply left_inverse},
{ apply cone_hom_eq, esimp, apply right_inverse},
end
variables (x y)
definition cone_iso_equiv [constructor] : (x ≅ y) ≃ Σ(f : cone_to_obj x ≅ cone_to_obj y),
Πi, cone_to_nat y i ∘ to_hom f = cone_to_nat x i :=
begin
fapply equiv.MK,
{ intro h, exact ⟨cone_iso_pr1 h, cone_to_eq (to_hom h)⟩},
{ intro v, exact cone_iso.mk v.1 v.2},
{ intro v, induction v with f p, fapply sigma_eq: esimp,
{ apply iso_eq, reflexivity},
{ apply is_prop.elimo, apply is_trunc_pi, intro i, apply is_prop_hom_eq}},
{ intro h, esimp, apply iso_eq, apply cone_hom_eq, reflexivity},
end
definition cone_eq_equiv : (x = y) ≃ Σ(f : cone_to_obj x = cone_to_obj y),
Πi, cone_to_nat y i ∘ hom_of_eq f = cone_to_nat x i :=
begin
fapply equiv.MK,
{ intro r, fapply sigma.mk, exact ap cone_to_obj r, induction r, intro i, apply id_right},
{ intro v, induction v with p q, induction x with c η, induction y with c' η', esimp at *,
apply cone_obj_eq p, esimp, intro i, exact (q i)⁻¹},
{ intro v, induction v with p q, induction x with c η, induction y with c' η', esimp at *,
induction p, esimp, fapply sigma_eq: esimp,
{ apply c_cone_obj_eq},
{ apply is_prop.elimo, apply is_trunc_pi, intro i, apply is_prop_hom_eq}},
{ intro r, induction r, esimp, induction x, esimp, apply ap02, apply is_prop.elim},
end
section is_univalent
definition is_univalent_cone {I : Precategory} {C : Category} (F : I ⇒ C)
: is_univalent (cone F) :=
begin
intro x y,
fapply is_equiv_of_equiv_of_homotopy,
{ exact calc
(x = y) ≃ (Σ(f : cone_to_obj x = cone_to_obj y), Πi, cone_to_nat y i ∘ hom_of_eq f = cone_to_nat x i)
: cone_eq_equiv
... ≃ (Σ(f : cone_to_obj x ≅ cone_to_obj y), Πi, cone_to_nat y i ∘ to_hom f = cone_to_nat x i)
: sigma_equiv_sigma !eq_equiv_iso (λa, !equiv.refl)
... ≃ (x ≅ y) : cone_iso_equiv },
{ intro p, induction p, esimp [equiv.trans,equiv.symm], esimp [sigma_functor],
apply iso_eq, reflexivity}
end
definition category_cone [instance] [constructor] {I : Precategory} {C : Category} (F : I ⇒ C)
: category (cone_obj F) :=
category.mk _ (is_univalent_cone F)
definition Category_cone [constructor] {I : Precategory} {C : Category} (F : I ⇒ C)
: Category :=
Category.mk _ (category_cone F)
end is_univalent
definition cone_obj_compose [constructor] (G : C ⇒ D) (x : cone_obj F) : cone_obj (G ∘f F) :=
begin
fapply cone_obj.mk,
{ exact G x},
{ fapply change_natural_map,
{ refine ((G ∘fn cone_to_nat x) ∘n _), apply nat_trans_of_eq, fapply functor_eq: esimp,
intro i j k, esimp, rewrite [id_leftright,respect_id]},
{ intro i, esimp, exact G (cone_to_nat x i)},
{ intro i, esimp, rewrite [ap010_functor_eq, ▸*, id_right]}}
end
end category

View file

@ -1,24 +0,0 @@
algebra.category.constructions
==============================
Common categories and constructions on categories. The following files are in this folder.
* [functor](functor.hlean) : Functor category
* [opposite](opposite.hlean) : Opposite category
* [set](set.hlean) : Category of sets
* [sum](sum.hlean) : Sum category
* [product](product.hlean) : Product category
* [comma](comma.hlean) : Comma category
* [cone](cone.hlean) : Cone category
* [pushout](pushout.hlean) : Categorical structure of paths in a graph and quotients of them.
Pushout of categories, pushout of groupoids.
* [fundamental_groupoid](fundamental_groupoid.hlean) : The fundamental groupoid of a type
* [rezk](rezk.hlean) : Rezk completion
Discrete, indiscrete or finite categories:
* [finite_cats](finite_cats.hlean) : Some finite categories, which are diagrams of common limits (the diagram for the pullback or the equalizer). Also contains a general construction of categories where you give some generators for the morphisms, with the condition that you cannot compose two of thosex
* [discrete](discrete.hlean) : Discrete category. Also the groupoid formed by a 1-type
* [indiscrete](indiscrete.hlean)
* [terminal](terminal.hlean)
* [initial](initial.hlean)

View file

@ -1,8 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
-/
import .functor .set .opposite .product .comma .sum .discrete .indiscrete .terminal .initial .order
.pushout .fundamental_groupoid

View file

@ -1,72 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
Discrete category
-/
import ..groupoid types.bool ..nat_trans
open eq is_trunc iso bool functor nat_trans
namespace category
definition precategory_of_1_type [constructor] (A : Type) [H : is_trunc 1 A] : precategory A :=
@precategory.mk _ _ (@is_trunc_eq _ _ H)
(λ (a b c : A) (p : b = c) (q : a = b), q ⬝ p)
(λ (a : A), refl a)
(λ (a b c d : A) (p : c = d) (q : b = c) (r : a = b), con.assoc r q p)
(λ (a b : A) (p : a = b), con_idp p)
(λ (a b : A) (p : a = b), idp_con p)
definition groupoid_of_1_type [constructor] (A : Type) [H : is_trunc 1 A] : groupoid A :=
groupoid.mk !precategory_of_1_type
(λ (a b : A) (p : a = b), is_iso.mk _ !con.right_inv !con.left_inv)
definition Precategory_of_1_type [constructor] (A : Type) [H : is_trunc 1 A] : Precategory :=
precategory.Mk (precategory_of_1_type A)
definition Groupoid_of_1_type [constructor] (A : Type) [H : is_trunc 1 A] : Groupoid :=
groupoid.Mk _ (groupoid_of_1_type A)
definition discrete_precategory [constructor] (A : Type) [H : is_set A] : precategory A :=
precategory_of_1_type A
definition discrete_groupoid [constructor] (A : Type) [H : is_set A] : groupoid A :=
groupoid_of_1_type A
definition Discrete_precategory [constructor] (A : Type) [H : is_set A] : Precategory :=
precategory.Mk (discrete_precategory A)
definition Discrete_groupoid [constructor] (A : Type) [H : is_set A] : Groupoid :=
groupoid.Mk _ (discrete_groupoid A)
definition c2 [constructor] : Precategory := Discrete_precategory bool
definition c2_functor [constructor] (C : Precategory) (x y : C) : c2 ⇒ C :=
functor.mk (bool.rec x y)
(bool.rec (bool.rec (λf, id) (by contradiction))
(bool.rec (by contradiction) (λf, id)))
abstract (bool.rec idp idp) end
abstract begin intro b₁ b₂ b₃ g f, induction b₁: induction b₂: induction b₃:
esimp at *: try contradiction: exact !id_id⁻¹ end end
definition c2_functor_eta {C : Precategory} (F : c2 ⇒ C) :
c2_functor C (to_fun_ob F ff) (to_fun_ob F tt) = F :=
begin
fapply functor_eq: esimp,
{ intro b, induction b: reflexivity},
{ intro b₁ b₂ p, induction p, induction b₁: esimp; rewrite [id_leftright]; exact !respect_id⁻¹}
end
definition c2_nat_trans [constructor] {C : Precategory} {x y u v : C} (f : x ⟶ u) (g : y ⟶ v) :
c2_functor C x y ⟹ c2_functor C u v :=
begin
fapply nat_trans.mk: esimp,
{ intro b, induction b, exact f, exact g},
{ intro b₁ b₂ p, induction p, induction b₁: esimp: apply id_comp_eq_comp_id},
end
end category

View file

@ -1,142 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
Some finite categories which are neither discrete nor indiscrete
-/
import ..functor.basic types.sum
open bool unit is_trunc sum eq functor equiv
namespace category
variables {A : Type} (R : A → A → Type) (H : Π⦃a b c⦄, R a b → R b c → empty)
[HR : Πa b, is_set (R a b)] [HA : is_trunc 1 A]
include H HR HA
-- we call a category sparse if you cannot compose two morphism, except the ones which come from equality
definition sparse_category' [constructor] : precategory A :=
precategory.mk
(λa b, R a b ⊎ a = b)
begin
intros a b c g f, induction g with rg pg: induction f with rf pf,
{ exfalso, exact H rf rg},
{ exact inl (pf⁻¹ ▸ rg)},
{ exact inl (pg ▸ rf)},
{ exact inr (pf ⬝ pg)},
end
(λa, inr idp)
abstract begin
intros a b c d h g f, induction h with rh ph: induction g with rg pg: induction f with rf pf:
esimp: try induction pf; try induction pg; try induction ph: esimp;
try (exfalso; apply H;assumption;assumption)
end end
abstract by intros a b f; induction f with rf pf: reflexivity end
abstract by intros a b f; (induction f with rf pf: esimp); rewrite idp_con end
definition sparse_category [constructor] : Precategory :=
precategory.Mk (sparse_category' R @H)
definition sparse_category_functor [constructor] (C : Precategory) (f : A → C)
(g : Π{a b} (r : R a b), f a ⟶ f b) : sparse_category R H ⇒ C :=
functor.mk f
(λa b, sum.rec g (eq.rec id))
(λa, idp)
abstract begin
intro a b c g f, induction g with rg pg: induction f with rf pf: esimp:
try induction pg: try induction pf: esimp,
exfalso, exact H rf rg,
exact !id_right⁻¹,
exact !id_left⁻¹,
exact !id_id⁻¹
end end
omit H HR HA
section equalizer
inductive equalizer_category_hom : bool → bool → Type :=
| f1 : equalizer_category_hom ff tt
| f2 : equalizer_category_hom ff tt
open equalizer_category_hom
theorem is_set_equalizer_category_hom (b₁ b₂ : bool) : is_set (equalizer_category_hom b₁ b₂) :=
begin
have H : Πb b', equalizer_category_hom b b' ≃ bool.rec (bool.rec empty bool) (λb, empty) b b',
begin
intro b b', fapply equiv.MK,
{ intro x, induction x, exact ff, exact tt},
{ intro v, induction b: induction b': induction v, exact f1, exact f2},
{ intro v, induction b: induction b': induction v: reflexivity},
{ intro x, induction x: reflexivity}
end,
apply is_trunc_equiv_closed_rev, apply H,
induction b₁: induction b₂: exact _
end
local attribute is_set_equalizer_category_hom [instance]
definition equalizer_category [constructor] : Precategory :=
sparse_category
equalizer_category_hom
begin intro a b c g f; cases g: cases f end
definition equalizer_category_functor [constructor] (C : Precategory) {x y : C} (f g : x ⟶ y)
: equalizer_category ⇒ C :=
sparse_category_functor _ _ C
(bool.rec x y)
begin intro a b h; induction h, exact f, exact g end
end equalizer
section pullback
inductive pullback_category_ob : Type :=
| TR : pullback_category_ob
| BL : pullback_category_ob
| BR : pullback_category_ob
theorem pullback_category_ob_decidable_equality : decidable_eq pullback_category_ob :=
begin
intro x y; induction x: induction y:
try exact decidable.inl idp:
apply decidable.inr; contradiction
end
open pullback_category_ob
inductive pullback_category_hom : pullback_category_ob → pullback_category_ob → Type :=
| f1 : pullback_category_hom TR BR
| f2 : pullback_category_hom BL BR
open pullback_category_hom
theorem is_set_pullback_category_hom (b₁ b₂ : pullback_category_ob)
: is_set (pullback_category_hom b₁ b₂) :=
begin
have H : Πb b', pullback_category_hom b b' ≃
pullback_category_ob.rec (λb, empty) (λb, empty)
(pullback_category_ob.rec unit unit empty) b' b,
begin
intro b b', fapply equiv.MK,
{ intro x, induction x: exact star},
{ intro v, induction b: induction b': induction v, exact f1, exact f2},
{ intro v, induction b: induction b': induction v: reflexivity},
{ intro x, induction x: reflexivity}
end,
apply is_trunc_equiv_closed_rev, apply H,
induction b₁: induction b₂: exact _
end
local attribute is_set_pullback_category_hom pullback_category_ob_decidable_equality [instance]
definition pullback_category [constructor] : Precategory :=
sparse_category
pullback_category_hom
begin intro a b c g f; cases g: cases f end
definition pullback_category_functor [constructor] (C : Precategory) {x y z : C}
(f : x ⟶ z) (g : y ⟶ z) : pullback_category ⇒ C :=
sparse_category_functor _ _ C
(pullback_category_ob.rec x y z)
begin intro a b h; induction h, exact f, exact g end
end pullback
end category

View file

@ -1,812 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn, Jakob von Raumer
Functor precategory and category
-/
import .opposite ..functor.attributes
open eq category is_trunc nat_trans iso is_equiv category.hom trunc
namespace functor
definition precategory_functor [instance] [constructor] (D C : Precategory)
: precategory (functor C D) :=
precategory.mk (λa b, nat_trans a b)
(λ a b c g f, nat_trans.compose g f)
(λ a, nat_trans.id)
(λ a b c d h g f, !nat_trans.assoc)
(λ a b f, !nat_trans.id_left)
(λ a b f, !nat_trans.id_right)
definition Precategory_functor [reducible] [constructor] (D C : Precategory) : Precategory :=
precategory.Mk (precategory_functor D C)
infixr ` ^c `:80 := Precategory_functor
section
/- we prove that if a natural transformation is pointwise an iso, then it is an iso -/
variables {C D : Precategory} {F G : C ⇒ D} (η : F ⟹ G) [iso : Π(a : C), is_iso (η a)]
include iso
definition nat_trans_inverse [constructor] : G ⟹ F :=
nat_trans.mk
(λc, (η c)⁻¹)
(λc d f,
abstract begin
apply comp_inverse_eq_of_eq_comp,
transitivity (natural_map η d)⁻¹ ∘ to_fun_hom G f ∘ natural_map η c,
{apply eq_inverse_comp_of_comp_eq, symmetry, apply naturality},
{apply assoc}
end end)
definition nat_trans_left_inverse : nat_trans_inverse η ∘n η = 1 :=
begin
fapply (apdt011 nat_trans.mk),
apply eq_of_homotopy, intro c, apply left_inverse,
apply eq_of_homotopy3, intros, apply is_set.elim
end
definition nat_trans_right_inverse : η ∘n nat_trans_inverse η = 1 :=
begin
fapply (apdt011 nat_trans.mk),
apply eq_of_homotopy, intro c, apply right_inverse,
apply eq_of_homotopy3, intros, apply is_set.elim
end
definition is_natural_iso [constructor] : is_iso η :=
is_iso.mk _ (nat_trans_left_inverse η) (nat_trans_right_inverse η)
variable (iso)
definition natural_iso.mk [constructor] : F ≅ G :=
iso.mk _ (is_natural_iso η)
omit iso
variables (F G)
definition is_natural_inverse (η : Πc, F c ≅ G c)
(nat : Π⦃a b : C⦄ (f : hom a b), G f ∘ to_hom (η a) = to_hom (η b) ∘ F f)
{a b : C} (f : hom a b) : F f ∘ to_inv (η a) = to_inv (η b) ∘ G f :=
let η' : F ⟹ G := nat_trans.mk (λc, to_hom (η c)) @nat in
naturality (nat_trans_inverse η') f
definition is_natural_inverse' (η₁ : Πc, F c ≅ G c) (η₂ : F ⟹ G) (p : η₁ ~ η₂)
{a b : C} (f : hom a b) : F f ∘ to_inv (η₁ a) = to_inv (η₁ b) ∘ G f :=
is_natural_inverse F G η₁ abstract λa b g, (p a)⁻¹ ▸ (p b)⁻¹ ▸ naturality η₂ g end f
variables {F G}
definition natural_iso.MK [constructor]
(η : Πc, F c ⟶ G c) (p : Π(c c' : C) (f : c ⟶ c'), G f ∘ η c = η c' ∘ F f)
(θ : Πc, G c ⟶ F c) (r : Πc, θ c ∘ η c = id) (q : Πc, η c ∘ θ c = id) : F ≅ G :=
iso.mk (nat_trans.mk η p) (@(is_natural_iso _) (λc, is_iso.mk (θ c) (r c) (q c)))
definition natural_iso.mk' [constructor]
(η : Πc, F c ≅ G c) (p : Π(c c' : C) (f : c ⟶ c'), G f ∘ to_hom (η c) = to_hom (η c') ∘ F f) :
F ≅ G :=
natural_iso.MK (λc, to_hom (η c)) p (λc, to_inv (η c))
(λc, to_left_inverse (η c)) (λc, to_right_inverse (η c))
end
section
/- and conversely, if a natural transformation is an iso, it is componentwise an iso -/
variables {A B C D : Precategory} {F G : C ⇒ D} (η : hom F G) [isoη : is_iso η] (c : C)
include isoη
definition componentwise_is_iso [constructor] : is_iso (η c) :=
@is_iso.mk _ _ _ _ _ (natural_map η⁻¹ c) (ap010 natural_map ( left_inverse η) c)
(ap010 natural_map (right_inverse η) c)
local attribute componentwise_is_iso [instance]
variable {isoη}
definition natural_map_inverse : natural_map η⁻¹ c = (η c)⁻¹ := idp
variable [isoη]
definition naturality_iso {c c' : C} (f : c ⟶ c') : G f = η c' ∘ F f ∘ (η c)⁻¹ :=
calc
G f = (G f ∘ η c) ∘ (η c)⁻¹ : by rewrite comp_inverse_cancel_right
... = (η c' ∘ F f) ∘ (η c)⁻¹ : by rewrite naturality
... = η c' ∘ F f ∘ (η c)⁻¹ : by rewrite assoc
definition naturality_iso' {c c' : C} (f : c ⟶ c') : (η c')⁻¹ ∘ G f ∘ η c = F f :=
calc
(η c')⁻¹ ∘ G f ∘ η c = (η c')⁻¹ ∘ η c' ∘ F f : by rewrite naturality
... = F f : by rewrite inverse_comp_cancel_left
omit isoη
definition componentwise_iso [constructor] (η : F ≅ G) (c : C) : F c ≅ G c :=
iso.mk (natural_map (to_hom η) c)
(@componentwise_is_iso _ _ _ _ (to_hom η) (struct η) c)
definition componentwise_iso_id (c : C) : componentwise_iso (iso.refl F) c = iso.refl (F c) :=
iso_eq (idpath (ID (F c)))
definition componentwise_iso_iso_of_eq (p : F = G) (c : C)
: componentwise_iso (iso_of_eq p) c = iso_of_eq (ap010 to_fun_ob p c) :=
eq.rec_on p !componentwise_iso_id
theorem naturality_iso_id {F : C ⇒ C} (η : F ≅ 1) (c : C)
: componentwise_iso η (F c) = F (componentwise_iso η c) :=
comp.cancel_left (to_hom (componentwise_iso η c))
((naturality (to_hom η)) (to_hom (componentwise_iso η c)))
definition natural_map_hom_of_eq (p : F = G) (c : C)
: natural_map (hom_of_eq p) c = hom_of_eq (ap010 to_fun_ob p c) :=
eq.rec_on p idp
definition natural_map_inv_of_eq (p : F = G) (c : C)
: natural_map (inv_of_eq p) c = hom_of_eq (ap010 to_fun_ob p c)⁻¹ :=
eq.rec_on p idp
definition hom_of_eq_compose_right {H : B ⇒ C} (p : F = G)
: hom_of_eq (ap (λx, x ∘f H) p) = hom_of_eq p ∘nf H :=
eq.rec_on p idp
definition inv_of_eq_compose_right {H : B ⇒ C} (p : F = G)
: inv_of_eq (ap (λx, x ∘f H) p) = inv_of_eq p ∘nf H :=
eq.rec_on p idp
definition hom_of_eq_compose_left {H : D ⇒ C} (p : F = G)
: hom_of_eq (ap (λx, H ∘f x) p) = H ∘fn hom_of_eq p :=
by induction p; exact !fn_id⁻¹
definition inv_of_eq_compose_left {H : D ⇒ C} (p : F = G)
: inv_of_eq (ap (λx, H ∘f x) p) = H ∘fn inv_of_eq p :=
by induction p; exact !fn_id⁻¹
definition assoc_natural [constructor] (H : C ⇒ D) (G : B ⇒ C) (F : A ⇒ B)
: H ∘f (G ∘f F) ⟹ (H ∘f G) ∘f F :=
change_natural_map (hom_of_eq !functor.assoc)
(λa, id)
(λa, !natural_map_hom_of_eq ⬝ ap hom_of_eq !ap010_assoc)
definition assoc_natural_rev [constructor] (H : C ⇒ D) (G : B ⇒ C) (F : A ⇒ B)
: (H ∘f G) ∘f F ⟹ H ∘f (G ∘f F) :=
change_natural_map (inv_of_eq !functor.assoc)
(λa, id)
(λa, !natural_map_inv_of_eq ⬝ ap (λx, hom_of_eq x⁻¹) !ap010_assoc)
definition assoc_iso [constructor] (H : C ⇒ D) (G : B ⇒ C) (F : A ⇒ B)
: H ∘f (G ∘f F) ≅ (H ∘f G) ∘f F :=
iso.MK (assoc_natural H G F) (assoc_natural_rev H G F)
(nat_trans_eq (λa, proof !id_id qed)) (nat_trans_eq (λa, proof !id_id qed))
definition id_left_natural [constructor] (F : C ⇒ D) : functor.id ∘f F ⟹ F :=
change_natural_map
(hom_of_eq !functor.id_left)
(λc, id)
(λc, by induction F; exact !natural_map_hom_of_eq ⬝ ap hom_of_eq !ap010_functor_mk_eq_constant)
definition id_left_natural_rev [constructor] (F : C ⇒ D) : F ⟹ functor.id ∘f F :=
change_natural_map
(inv_of_eq !functor.id_left)
(λc, id)
(λc, by induction F; exact !natural_map_inv_of_eq ⬝
ap (λx, hom_of_eq x⁻¹) !ap010_functor_mk_eq_constant)
definition id_right_natural [constructor] (F : C ⇒ D) : F ∘f functor.id ⟹ F :=
change_natural_map
(hom_of_eq !functor.id_right)
(λc, id)
(λc, by induction F; exact !natural_map_hom_of_eq ⬝ ap hom_of_eq !ap010_functor_mk_eq_constant)
definition id_right_natural_rev [constructor] (F : C ⇒ D) : F ⟹ F ∘f functor.id :=
change_natural_map
(inv_of_eq !functor.id_right)
(λc, id)
(λc, by induction F; exact !natural_map_inv_of_eq ⬝
ap (λx, hom_of_eq x⁻¹) !ap010_functor_mk_eq_constant)
end
section
variables {C D E : Precategory} {G G' : D ⇒ E} {F F' : C ⇒ D} {J : D ⇒ D}
definition is_iso_nf_compose [constructor] (G : D ⇒ E) (η : F ⟹ F') [H : is_iso η]
: is_iso (G ∘fn η) :=
is_iso.mk
(G ∘fn @inverse (C ⇒ D) _ _ _ η _)
abstract !fn_n_distrib⁻¹ ⬝ ap (λx, G ∘fn x) (@left_inverse (C ⇒ D) _ _ _ η _) ⬝ !fn_id end
abstract !fn_n_distrib⁻¹ ⬝ ap (λx, G ∘fn x) (@right_inverse (C ⇒ D) _ _ _ η _) ⬝ !fn_id end
definition is_iso_fn_compose [constructor] (η : G ⟹ G') (F : C ⇒ D) [H : is_iso η]
: is_iso (η ∘nf F) :=
is_iso.mk
(@inverse (D ⇒ E) _ _ _ η _ ∘nf F)
abstract !n_nf_distrib⁻¹ ⬝ ap (λx, x ∘nf F) (@left_inverse (D ⇒ E) _ _ _ η _) ⬝ !id_nf end
abstract !n_nf_distrib⁻¹ ⬝ ap (λx, x ∘nf F) (@right_inverse (D ⇒ E) _ _ _ η _) ⬝ !id_nf end
definition functor_iso_compose [constructor] (G : D ⇒ E) (η : F ≅ F') : G ∘f F ≅ G ∘f F' :=
iso.mk _ (is_iso_nf_compose G (to_hom η))
definition iso_functor_compose [constructor] (η : G ≅ G') (F : C ⇒ D) : G ∘f F ≅ G' ∘f F :=
iso.mk _ (is_iso_fn_compose (to_hom η) F)
infixr ` ∘fi ` :62 := functor_iso_compose
infixr ` ∘if ` :62 := iso_functor_compose
/- TODO: also needs n_nf_distrib and id_nf for these compositions
definition nidf_compose [constructor] (η : J ⟹ 1) (F : C ⇒ D) [H : is_iso η]
: is_iso (η ∘n1f F) :=
is_iso.mk
(@inverse (D ⇒ D) _ _ _ η _ ∘1nf F)
abstract _ end
_
definition idnf_compose [constructor] (η : 1 ⟹ J) (F : C ⇒ D) [H : is_iso η]
: is_iso (η ∘1nf F) :=
is_iso.mk _
_
_
definition fnid_compose [constructor] (F : D ⇒ E) (η : J ⟹ 1) [H : is_iso η]
: is_iso (F ∘fn1 η) :=
is_iso.mk _
_
_
definition fidn_compose [constructor] (F : D ⇒ E) (η : 1 ⟹ J) [H : is_iso η]
: is_iso (F ∘f1n η) :=
is_iso.mk _
_
_
-/
end
namespace functor
variables {C : Precategory} {D : Category} {F G : D ^c C}
definition eq_of_iso_ob (η : F ≅ G) (c : C) : F c = G c :=
by apply eq_of_iso; apply componentwise_iso; exact η
local attribute functor.to_fun_hom [reducible]
definition eq_of_iso (η : F ≅ G) : F = G :=
begin
fapply functor_eq,
{exact (eq_of_iso_ob η)},
{intro c c' f,
esimp [eq_of_iso_ob, inv_of_eq, hom_of_eq, eq_of_iso],
rewrite [*right_inv iso_of_eq],
symmetry, apply @naturality_iso _ _ _ _ _ (iso.struct _)
}
end
definition iso_of_eq_eq_of_iso (η : F ≅ G) : iso_of_eq (eq_of_iso η) = η :=
begin
apply iso_eq,
apply nat_trans_eq,
intro c,
rewrite natural_map_hom_of_eq, esimp [eq_of_iso],
rewrite ap010_functor_eq, esimp [hom_of_eq,eq_of_iso_ob],
rewrite (right_inv iso_of_eq),
end
definition eq_of_iso_iso_of_eq (p : F = G) : eq_of_iso (iso_of_eq p) = p :=
begin
apply functor_eq2,
intro c,
esimp [eq_of_iso],
rewrite ap010_functor_eq,
esimp [eq_of_iso_ob],
rewrite componentwise_iso_iso_of_eq,
rewrite (left_inv iso_of_eq)
end
definition is_univalent (D : Category) (C : Precategory) : is_univalent (D ^c C) :=
λF G, adjointify _ eq_of_iso
iso_of_eq_eq_of_iso
eq_of_iso_iso_of_eq
end functor
definition category_functor [instance] [constructor] (D : Category) (C : Precategory)
: category (D ^c C) :=
category.mk (D ^c C) (functor.is_univalent D C)
definition Category_functor [constructor] (D : Category) (C : Precategory) : Category :=
category.Mk (D ^c C) !category_functor
--this definition is only useful if the exponent is a category,
-- and the elaborator has trouble with inserting the coercion
definition Category_functor' [constructor] (D C : Category) : Category :=
Category_functor D C
namespace ops
infixr ` ^c2 `:35 := Category_functor
end ops
namespace functor
variables {C : Precategory} {D : Category} {F G : D ^c C}
definition eq_of_pointwise_iso (η : F ⟹ G) (iso : Π(a : C), is_iso (η a)) : F = G :=
eq_of_iso (natural_iso.mk η iso)
definition iso_of_eq_eq_of_pointwise_iso (η : F ⟹ G) (iso : Π(c : C), is_iso (η c))
: iso_of_eq (eq_of_pointwise_iso η iso) = natural_iso.mk η iso :=
!iso_of_eq_eq_of_iso
definition hom_of_eq_eq_of_pointwise_iso (η : F ⟹ G) (iso : Π(c : C), is_iso (η c))
: hom_of_eq (eq_of_pointwise_iso η iso) = η :=
!hom_of_eq_eq_of_iso
definition inv_of_eq_eq_of_pointwise_iso (η : F ⟹ G) (iso : Π(c : C), is_iso (η c))
: inv_of_eq (eq_of_pointwise_iso η iso) = nat_trans_inverse η :=
!inv_of_eq_eq_of_iso
end functor
/-
functors involving only the functor category
(see ..functor.curry for some other functors involving also products)
-/
variables {C D I : Precategory}
definition constant2_functor [constructor] (F : I ⇒ D ^c C) (c : C) : I ⇒ D :=
functor.mk (λi, to_fun_ob (F i) c)
(λi j f, natural_map (F f) c)
abstract (λi, ap010 natural_map !respect_id c ⬝ proof idp qed) end
abstract (λi j k g f, ap010 natural_map !respect_comp c) end
definition constant2_functor_natural [constructor] (F : I ⇒ D ^c C) {c d : C} (f : c ⟶ d)
: constant2_functor F c ⟹ constant2_functor F d :=
nat_trans.mk (λi, to_fun_hom (F i) f)
(λi j k, (naturality (F k) f)⁻¹)
definition functor_flip [constructor] (F : I ⇒ D ^c C) : C ⇒ D ^c I :=
functor.mk (constant2_functor F)
@(constant2_functor_natural F)
abstract begin intros, apply nat_trans_eq, intro i, esimp, apply respect_id end end
abstract begin intros, apply nat_trans_eq, intro i, esimp, apply respect_comp end end
definition eval_functor [constructor] (C D : Precategory) (d : D) : C ^c D ⇒ C :=
begin
fapply functor.mk: esimp,
{ intro F, exact F d},
{ intro G F η, exact η d},
{ intro F, reflexivity},
{ intro H G F η θ, reflexivity},
end
definition precomposition_functor [constructor] {C D} (E) (F : C ⇒ D)
: E ^c D ⇒ E ^c C :=
begin
fapply functor.mk: esimp,
{ intro G, exact G ∘f F},
{ intro G H η, exact η ∘nf F},
{ intro G, reflexivity},
{ intro G H I η θ, reflexivity},
end
definition faithful_precomposition_functor [instance]
{C D E} {H : C ⇒ D} [Hs : essentially_surjective H] : faithful (precomposition_functor E H) :=
begin
intro F G γ δ Hγδ, apply nat_trans_eq, intro b,
induction Hs b with Hb, induction Hb with a f,
refine naturality_iso_right γ f ⬝ _ ⬝ (naturality_iso_right δ f)⁻¹,
apply ap (λ x, _ ∘ natural_map x a ∘ _) Hγδ,
end
open sigma sigma.ops
section fully_faithful_precomposition
variables {E : Precategory} {H : C ⇒ D} [Hs : essentially_surjective H] [Hf : full H]
{F G : D ⇒ E} (γ : F ∘f H ⟹ G ∘f H)
include Hs Hf
private definition fully_faithful_precomposition_functor_prop [instance] (b) :
is_prop (Σ g, Π a (f : H a ≅ b), γ a = G f⁻¹ⁱ ∘ g ∘ F f) :=
begin
fapply is_prop.mk, intros g h, cases g with g Hg, cases h with h Hh,
fapply sigma.dpair_eq_dpair,
{ induction Hs b with Hb, induction Hb with a0 f,
apply comp.cancel_right (F f), apply comp.cancel_left (G f⁻¹ⁱ),
apply (Hg a0 f)⁻¹ ⬝ (Hh a0 f) },
apply is_prop.elimo
end
private definition fully_faithful_precomposition_functor_pair [reducible] (b) :
Σ g, Π a (f : H a ≅ b), γ a = G f⁻¹ⁱ ∘ g ∘ F f :=
begin
induction Hs b with Hb, induction Hb with a0 h, fconstructor,
exact G h ∘ γ a0 ∘ F h⁻¹ⁱ, intro a f,
induction Hf (to_hom (f ⬝i h⁻¹ⁱ)) with k Ek,
have is_iso (H k), by rewrite Ek; apply _,
refine _ ⬝ !assoc⁻¹, refine _ ⬝ ap (λ x, x ∘ F f) !assoc⁻¹, refine _ ⬝ !assoc,
refine _ ⬝ ap (λ x, (G f⁻¹ⁱ ∘ G h) ∘ x) !assoc,
do 2 krewrite [-respect_comp], esimp,
apply eq_comp_of_inverse_comp_eq,
exact ap (λ x, G x ∘ γ a) Ek⁻¹ ⬝ naturality γ k ⬝ ap (λ x, γ a0 ∘ F x) Ek
end
--TODO speed this up
private definition fully_faithful_precomposition_naturality {b b' : carrier D}
(f : hom b b') : to_fun_hom G f ∘ (fully_faithful_precomposition_functor_pair γ b).1
= (fully_faithful_precomposition_functor_pair γ b').1 ∘ to_fun_hom F f :=
begin
esimp[fully_faithful_precomposition_functor_pair],
induction Hs b with Hb, induction Hb with a h,
induction Hs b' with Hb', induction Hb' with a' h',
induction Hf (to_hom h'⁻¹ⁱ ∘ f ∘ to_hom h) with k Ek,
apply concat, apply assoc,
apply concat, apply ap (λ x, x ∘ _),
apply concat, apply !respect_comp⁻¹,
apply concat, apply ap (λ x, to_fun_hom G x), apply inverse,
apply comp_eq_of_eq_inverse_comp, apply Ek, apply respect_comp,
apply concat, apply !assoc⁻¹,
apply concat, apply ap (λ x, _ ∘ x), apply concat, apply assoc,
apply concat, apply ap (λ x, x ∘ _), apply naturality γ, apply !assoc⁻¹,
apply concat, apply ap (λ x, _ ∘ _ ∘ x), apply concat, esimp, apply !respect_comp⁻¹,
apply concat, apply ap (λ x, to_fun_hom F x),
apply comp_inverse_eq_of_eq_comp, apply Ek ⬝ !assoc, apply respect_comp,
apply concat, apply assoc, apply concat, apply assoc,
apply ap (λ x, x ∘ _) !assoc⁻¹
end
definition fully_faithful_precomposition_functor [instance] :
fully_faithful (precomposition_functor E H) :=
begin
apply fully_faithful_of_full_of_faithful,
{ apply faithful_precomposition_functor },
{ intro F G γ, esimp at *, fapply image.mk,
fconstructor,
{ intro b, apply (fully_faithful_precomposition_functor_pair γ b).1 },
{ intro b b' f, apply fully_faithful_precomposition_naturality },
{ fapply nat_trans_eq, intro a, esimp,
apply inverse,
induction (fully_faithful_precomposition_functor_pair γ (to_fun_ob H a)) with g Hg,
esimp, apply concat, apply Hg a (iso.refl (H a)), esimp,
apply concat, apply ap (λ x, x ∘ _), apply respect_id, apply concat, apply id_left,
apply concat, apply ap (λ x, _ ∘ x), apply respect_id, apply id_right } }
end
end fully_faithful_precomposition
end functor
namespace functor
section essentially_surjective_precomposition
parameters {A B : Precategory} {C : Category}
{H : A ⇒ B} [He : is_weak_equivalence H] (F : A ⇒ C)
variables {b b' : carrier B} (f : hom b b')
include A B C H He F
structure essentially_surj_precomp_X (b : carrier B) : Type :=
(c : carrier C)
(k : Π (a : carrier A) (h : H a ≅ b), F a ≅ c)
(k_coh : Π {a a'} h h' (f : hom a a'), to_hom h' ∘ (to_fun_hom H f) = to_hom h
→ to_hom (k a' h') ∘ to_fun_hom F f = to_hom (k a h))
local abbreviation X := essentially_surj_precomp_X
local abbreviation X.mk [constructor] := @essentially_surj_precomp_X.mk
local abbreviation X.c [unfold 7] := @essentially_surj_precomp_X.c
local abbreviation X.k [unfold 7] := @essentially_surj_precomp_X.k
local abbreviation X.k_coh [unfold 7] := @essentially_surj_precomp_X.k_coh
section
variables {c c' : carrier C} (p : c = c')
{k : Π (a : carrier A) (h : H a ≅ b), F a ≅ c}
{k' : Π (a : carrier A) (h : H a ≅ b), F a ≅ c'}
(q : Π (a : carrier A) (h : H a ≅ b), to_hom (k a h ⬝i iso_of_eq p) = to_hom (k' a h))
{k_coh : Π {a a'} h h' (f : hom a a'), to_hom h' ∘ (to_fun_hom H f) = to_hom h
→ to_hom (k a' h') ∘ to_fun_hom F f = to_hom (k a h)}
{k'_coh : Π {a a'} h h' (f : hom a a'), to_hom h' ∘ (to_fun_hom H f) = to_hom h
→ to_hom (k' a' h') ∘ to_fun_hom F f = to_hom (k' a h)}
include c c' p k k' q
private theorem X_eq : X.mk c k @k_coh = X.mk c' k' @k'_coh :=
begin
cases p,
assert q' : k = k',
{ apply eq_of_homotopy, intro a, apply eq_of_homotopy, intro h,
apply iso_eq, apply !id_left⁻¹ ⬝ q a h },
cases q',
apply ap (essentially_surj_precomp_X.mk c' k'),
apply is_prop.elim
end
end
open prod.ops sigma.ops
private theorem X_prop [instance] : is_prop (X b) :=
begin
induction He.2 b with Hb, cases Hb with a0 Ha0,
fapply is_prop.mk, intros f g, cases f with cf kf kf_coh, cases g with cg kg kg_coh,
fapply X_eq,
{ apply eq_of_iso, apply iso.trans, apply iso.symm, apply kf a0 Ha0,
apply kg a0 Ha0 },
{ intro a h,
assert fHf : Σ f : hom a a0, to_hom Ha0 ∘ (to_fun_hom H f) = to_hom h,
{ fconstructor, apply hom_inv, apply He.1, exact to_hom Ha0⁻¹ⁱ ∘ to_hom h,
apply concat, apply ap (λ x, _ ∘ x), apply right_inv (to_fun_hom H),
apply comp_inverse_cancel_left },
apply concat, apply ap (λ x, to_hom x ∘ _), apply iso_of_eq_eq_of_iso,
apply concat, apply ap (λ x, _ ∘ x), apply (kf_coh h Ha0 fHf.1 fHf.2)⁻¹,
apply concat, rotate 1, apply kg_coh h Ha0 fHf.1 fHf.2,
apply concat, apply assoc, apply ap (λ x, x ∘ _),
apply concat, apply !assoc⁻¹,
apply concat, apply ap (λ x, _ ∘ x), apply comp.left_inverse,
apply id_right },
end
private definition X_inh (b) : X b :=
begin
induction He.2 b with Hb, cases Hb with a0 Ha0,
fconstructor, exact F a0,
{ intro a h, apply to_fun_iso F, apply reflect_iso H,
exact h ⬝i Ha0⁻¹ⁱ },
{ intros a a' h h' f HH,
apply concat, apply !respect_comp⁻¹, apply ap (to_fun_hom F),
esimp, rewrite [-HH],
apply concat, apply ap (λ x, _ ∘ x), apply inverse, apply left_inv (to_fun_hom H),
apply concat, apply !hom_inv_respect_comp⁻¹, apply ap (hom_inv H),
apply !assoc⁻¹ }
end
local abbreviation G0 [reducible] := λ (b), X.c (X_inh b)
private definition k := λ b, X.k (X_inh b)
private definition k_coh := λ b, @X.k_coh b (X_inh b)
private definition X_c_eq_of_eq {b} (t t' : X b) (p : t = t') : X.c t = X.c t' :=
by cases p; reflexivity
private definition X_k_eq_of_eq {b} (t t' : X b) (p : t = t') (a : carrier A) (h : H a ≅ b) :
X_c_eq_of_eq t t' p ▸ X.k t a h = X.k t' a h:=
by cases p; reflexivity
private definition X_phi {b} (t : X b) : X.c t = X.c (X_inh b) :=
X_c_eq_of_eq _ _ !is_prop.elim
private definition X_phi_transp {b} (t : X b) (a : carrier A) (h : H a ≅ b) :
(X_phi t) ▸ (X.k t a h) = k b a h :=
by apply X_k_eq_of_eq t _ !is_prop.elim
private definition X_phi_hom_of_eq' {b} (t t' : X b) (p : t = t') (a : carrier A) (h : H a ≅ b) :
X.k t' a h ⬝i (iso_of_eq (X_c_eq_of_eq t t' p)⁻¹) = X.k t a h :=
begin
cases p, apply iso_eq, apply id_left
end
private definition X_phi_hom_of_eq {b} (t : X b) (a : carrier A) (h : H a ≅ b) :
to_hom (k b a h ⬝i (iso_of_eq (X_phi t)⁻¹)) = to_hom (X.k t a h) :=
begin
apply ap to_hom, apply X_phi_hom_of_eq'
end
structure essentially_surj_precomp_Y {b b' : carrier B} (f : hom b b') : Type :=
(g : hom (G0 b) (G0 b'))
(Hg : Π {a a' : carrier A} h h' (l : hom a a'), to_hom h' ∘ to_fun_hom H l = f ∘ to_hom h →
to_hom (k b' a' h') ∘ to_fun_hom F l = g ∘ to_hom (k b a h))
local abbreviation Y := @essentially_surj_precomp_Y
local abbreviation Y.mk := @essentially_surj_precomp_Y.mk
local abbreviation Y.g := @essentially_surj_precomp_Y.g
section
variables {g : hom (G0 b) (G0 b')} {g' : hom (G0 b) (G0 b')} (p : g = g')
(Hg : Π {a a' : carrier A} h h' (l : hom a a'), to_hom h' ∘ to_fun_hom H l = f ∘ to_hom h →
to_hom (k b' a' h') ∘ to_fun_hom F l = g ∘ to_hom (k b a h))
(Hg' : Π {a a' : carrier A} h h' (l : hom a a'), to_hom h' ∘ to_fun_hom H l = f ∘ to_hom h →
to_hom (k b' a' h') ∘ to_fun_hom F l = g' ∘ to_hom (k b a h))
include p
private theorem Y_eq : Y.mk g @Hg = Y.mk g' @Hg' :=
begin
cases p, apply ap (Y.mk g'),
apply is_prop.elim,
end
end
private theorem Y_prop [instance] : is_prop (Y f) :=
begin
induction He.2 b with Hb, cases Hb with a0 h0,
induction He.2 b' with Hb', cases Hb' with a0' h0',
fapply is_prop.mk, intros,
cases x with g0 Hg0, cases y with g1 Hg1,
apply Y_eq,
assert l0Hl0 : Σ l0 : hom a0 a0', to_hom h0' ∘ to_fun_hom H l0 = f ∘ to_hom h0,
{ fconstructor, apply hom_inv, apply He.1, exact to_hom h0'⁻¹ⁱ ∘ f ∘ to_hom h0,
apply concat, apply ap (λ x, _ ∘ x), apply right_inv (to_fun_hom H),
apply comp_inverse_cancel_left },
apply comp.cancel_right (to_hom (k b a0 h0)),
apply concat, apply inverse, apply Hg0 h0 h0' l0Hl0.1 l0Hl0.2,
apply Hg1 h0 h0' l0Hl0.1 l0Hl0.2
end
private definition Y_inh : Y f :=
begin
induction He.2 b with Hb, cases Hb with a0 h0,
induction He.2 b' with Hb', cases Hb' with a0' h0',
assert l0Hl0 : Σ l0 : hom a0 a0', to_hom h0' ∘ to_fun_hom H l0 = f ∘ to_hom h0,
{ fconstructor, apply hom_inv, apply He.1, exact to_hom h0'⁻¹ⁱ ∘ f ∘ to_hom h0,
apply concat, apply ap (λ x, _ ∘ x), apply right_inv (to_fun_hom H),
apply comp_inverse_cancel_left },
fapply Y.mk,
{ refine to_hom (k b' a0' h0') ∘ _ ∘ to_hom (k b a0 h0)⁻¹ⁱ,
apply to_fun_hom F, apply l0Hl0.1 },
{ intros a a' h h' l Hl, esimp, apply inverse,
assert mHm : Σ m, to_hom h0 ∘ to_fun_hom H m = to_hom h,
{ fconstructor, apply hom_inv, apply He.1, exact to_hom h0⁻¹ⁱ ∘ to_hom h,
apply concat, apply ap (λ x, _ ∘ x), apply right_inv (to_fun_hom H),
apply comp_inverse_cancel_left },
assert m'Hm' : Σ m', to_hom h0' ∘ to_fun_hom H m' = to_hom h',
{ fconstructor, apply hom_inv, apply He.1, exact to_hom h0'⁻¹ⁱ ∘ to_hom h',
apply concat, apply ap (λ x, _ ∘ x), apply right_inv (to_fun_hom H),
apply comp_inverse_cancel_left },
assert m'l0lm : l0Hl0.1 ∘ mHm.1 = m'Hm'.1 ∘ l,
{ apply faithful_of_fully_faithful, apply He.1,
apply concat, apply respect_comp, apply comp.cancel_left (to_hom h0'), apply inverse,
apply concat, apply ap (λ x, _ ∘ x), apply respect_comp,
apply concat, apply assoc,
apply concat, apply ap (λ x, x ∘ _), apply m'Hm'.2,
apply concat, apply Hl,
apply concat, apply ap (λ x, _ ∘ x), apply mHm.2⁻¹,
apply concat, apply assoc,
apply concat, apply ap (λ x, x ∘ _), apply l0Hl0.2⁻¹, apply !assoc⁻¹ },
apply concat, apply !assoc⁻¹,
apply concat, apply ap (λ x, _ ∘ x), apply !assoc⁻¹,
apply concat, apply ap (λ x, _ ∘ _ ∘ x), apply inverse_comp_eq_of_eq_comp,
apply inverse, apply k_coh b h h0, apply mHm.2,
apply concat, apply ap (λ x, _ ∘ x), apply concat, apply !respect_comp⁻¹,
apply concat, apply ap (to_fun_hom F), apply m'l0lm, apply respect_comp,
apply concat, apply assoc, apply ap (λ x, x ∘ _),
apply k_coh, apply m'Hm'.2 }
end
private definition G_hom [constructor] := λ {b b'} (f : hom b b'), Y.g (Y_inh f)
private definition G_hom_coh := λ {b b'} (f : hom b b'),
@essentially_surj_precomp_Y.Hg b b' f (Y_inh f)
private theorem G_hom_id (b : carrier B) : G_hom (ID b) = ID (G0 b) :=
begin
cases He with He1 He2, esimp[G_hom, Y_inh],
induction He2 b with Hb, cases Hb with a h, --why do i need to destruct He?
apply concat, apply ap (λ x, _ ∘ x ∘ _),
apply concat, apply ap (to_fun_hom F),
apply concat, apply ap (hom_inv H), apply inverse_comp_id_comp,
apply hom_inv_respect_id,
apply respect_id,
apply comp_id_comp_inverse
end
private theorem G_hom_comp {b0 b1 b2 : carrier B} (g : hom b1 b2) (f : hom b0 b1) :
G_hom (g ∘ f) = G_hom g ∘ G_hom f :=
begin
cases He with He1 He2, esimp[G_hom, Y_inh],
induction He2 b0 with Hb0, cases Hb0 with a0 h0,
induction He2 b1 with Hb1, cases Hb1 with a1 h1,
induction He2 b2 with Hb2, cases Hb2 with b2 h2,
apply concat, apply assoc,
apply concat, rotate 1, apply !assoc⁻¹,
apply concat, rotate 1, apply !assoc⁻¹,
apply ap (λ x, x ∘ _),
apply inverse, apply concat, apply ap (λ x, x ∘ _),
apply concat, apply !assoc⁻¹, apply ap (λ x, _ ∘ x),
apply concat, apply !assoc⁻¹, apply ap (λ x, _ ∘ x), apply comp.left_inverse,
apply concat, apply !assoc⁻¹, apply ap (λ x, _ ∘ x),
apply concat, apply ap (λ x, x ∘ _), apply id_right,
apply concat, apply !respect_comp⁻¹, apply ap (to_fun_hom F),
apply concat, apply !hom_inv_respect_comp⁻¹, apply ap (hom_inv H),
apply concat, apply ap (λ x, x ∘ _), apply assoc,
apply concat, apply assoc,
apply concat, apply ap (λ x, x ∘ _), apply comp_inverse_cancel_right,
apply concat, apply !assoc⁻¹, apply ap (λ x, _ ∘ x),
apply assoc,
end
private definition G_functor : B ⇒ C :=
begin
fconstructor,
{ exact G0 },
{ intro b b' f, exact G_hom f },
{ intro b, apply G_hom_id },
{ intro a b c g f, apply G_hom_comp }
end
private definition XF (a0 : carrier A) : X (H a0) :=
begin
fconstructor,
{ exact F a0 },
{ intro a h, apply to_fun_iso F, apply reflect_iso, apply He.1, exact h },
{ intro a a' h h' f l, esimp,
apply concat, apply !respect_comp⁻¹, apply ap (to_fun_hom F), apply inverse,
apply concat, apply ap (hom_inv H) l⁻¹,
apply concat, apply hom_inv_respect_comp, apply ap (λ x, _ ∘ x), apply left_inv }
end
private definition G0_H_eq_F (a0 : carrier A) : G0 (H a0) = F a0 :=
begin
apply inverse, apply X_phi (XF a0)
end
private theorem G_hom_H_eq_F {a0 a0' : carrier A} (f0 : hom a0 a0') :
hom_of_eq (G0_H_eq_F a0') ∘ G_hom (to_fun_hom H f0) ∘ inv_of_eq (G0_H_eq_F a0)
= to_fun_hom F f0 :=
begin
apply comp_eq_of_eq_inverse_comp, apply comp_inverse_eq_of_eq_comp,
apply concat, apply ap essentially_surj_precomp_Y.g, apply is_prop.elim,
fconstructor,
{ exact (inv_of_eq (G0_H_eq_F a0') ∘ to_fun_hom F f0) ∘ hom_of_eq (G0_H_eq_F a0) },
{ intros a a' h h' l α, esimp[G0_H_eq_F], apply inverse,
apply concat, apply !assoc⁻¹,
apply concat, apply ap (λ x, _ ∘ x), apply X_phi_hom_of_eq,
apply concat, apply !assoc⁻¹,
apply inverse_comp_eq_of_eq_comp, apply inverse,
apply concat, apply assoc,
apply concat, apply ap (λ x, x ∘ _), apply X_phi_hom_of_eq, esimp[XF],
refine !respect_comp⁻¹ ⬝ ap (to_fun_hom F) _ ⬝ !respect_comp,
apply eq_of_fn_eq_fn' (to_fun_hom H),
refine !respect_comp ⬝ _ ⬝ !respect_comp⁻¹,
apply concat, apply ap (λ x, x ∘ _) !(right_inv (to_fun_hom H)),
apply concat, rotate 1, apply ap (λ x, _ ∘ x) !(right_inv (to_fun_hom H))⁻¹,
exact α },
reflexivity
end
end essentially_surjective_precomposition
definition essentially_surjective_precomposition_functor [instance] {A B : Precategory}
(C : Category) (H : A ⇒ B) [He : is_weak_equivalence H] :
essentially_surjective (precomposition_functor C H) :=
begin
intro F, apply tr, fconstructor, apply G_functor F,
apply iso_of_eq, fapply functor_eq,
{ intro a, esimp[G_functor], exact G0_H_eq_F F a },
{ intro a b f, exact G_hom_H_eq_F F f }
end
variables {C D E : Precategory}
definition postcomposition_functor [constructor] {C D} (E) (F : C ⇒ D)
: C ^c E ⇒ D ^c E :=
begin
fapply functor.mk: esimp,
{ intro G, exact F ∘f G},
{ intro G H η, exact F ∘fn η},
{ intro G, apply fn_id},
{ intro G H I η θ, apply fn_n_distrib},
end
definition constant_diagram [constructor] (C D) : C ⇒ C ^c D :=
begin
fapply functor.mk: esimp,
{ intro c, exact constant_functor D c},
{ intro c d f, exact constant_nat_trans D f},
{ intro c, fapply nat_trans_eq, reflexivity},
{ intro c d e g f, fapply nat_trans_eq, reflexivity},
end
definition opposite_functor_opposite_left [constructor] (C D : Precategory)
: (C ^c D)ᵒᵖ ⇒ Cᵒᵖ ^c Dᵒᵖ :=
begin
fapply functor.mk: esimp,
{ exact opposite_functor},
{ intro F G, exact opposite_nat_trans},
{ intro F, apply nat_trans_eq, reflexivity},
{ intro u v w g f, apply nat_trans_eq, reflexivity}
end
definition opposite_functor_opposite_right [constructor] (C D : Precategory)
: Cᵒᵖ ^c Dᵒᵖ ⇒ (C ^c D)ᵒᵖ :=
begin
fapply functor.mk: esimp,
{ exact opposite_functor_rev},
{ apply @opposite_rev_nat_trans},
{ intro F, apply nat_trans_eq, intro d, reflexivity},
{ intro F G H η θ, apply nat_trans_eq, intro d, reflexivity}
end
definition constant_diagram_opposite [constructor] (C D)
: (constant_diagram C D)ᵒᵖᶠ = opposite_functor_opposite_right C D ∘f constant_diagram Cᵒᵖ Dᵒᵖ :=
begin
fapply functor_eq,
{ reflexivity },
{ intro c c' f, esimp at *, refine !nat_trans.id_right ⬝ !nat_trans.id_left ⬝ _,
apply nat_trans_eq, intro d, reflexivity }
end
end functor

View file

@ -1,36 +0,0 @@
/-
Copyright (c) 2016 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
-/
import ..groupoid ..functor.basic
open eq is_trunc iso trunc functor
namespace category
definition fundamental_precategory [constructor] (A : Type) : Precategory :=
precategory.MK A
(λa a', trunc 0 (a = a'))
_
(λa₁ a₂ a₃ q p, tconcat p q)
(λa, tidp)
(λa₁ a₂ a₃ a₄ r q p, tassoc p q r)
(λa₁ a₂, tcon_tidp)
(λa₁ a₂, tidp_tcon)
definition fundamental_groupoid [constructor] (A : Type) : Groupoid :=
groupoid.MK (fundamental_precategory A)
(λa b p, is_iso.mk (tinverse p) (right_tinv p) (left_tinv p))
definition fundamental_groupoid_functor [constructor] {A B : Type} (f : A → B) :
fundamental_groupoid A ⇒ fundamental_groupoid B :=
functor.mk f (λa a', tap f) (λa, tap_tidp f) (λa₁ a₂ a₃ q p, tap_tcon f p q)
notation `Π₁` := fundamental_groupoid
notation `Π₁⇒` := fundamental_groupoid_functor
end category

View file

@ -1,31 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
Indiscrete category
-/
import .opposite
open functor is_trunc unit eq
namespace category
variable (X : Type)
definition indiscrete_precategory [constructor] : precategory X :=
precategory.mk (λx y, unit)
(λx y z f g, star)
(λx, star)
(λx y z w f g h, idp)
(λx y f, by induction f; reflexivity)
(λx y f, by induction f; reflexivity)
definition Indiscrete_precategory [constructor] : Precategory :=
precategory.Mk (indiscrete_precategory X)
definition indiscrete_op : (Indiscrete_precategory X)ᵒᵖ = Indiscrete_precategory X := idp
end category

View file

@ -1,47 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
Initial category
-/
import .indiscrete
open functor is_trunc eq
namespace category
definition initial_precategory [constructor] : precategory empty :=
indiscrete_precategory empty
definition Initial_precategory [constructor] : Precategory :=
precategory.Mk initial_precategory
notation 0 := Initial_precategory
definition zero_op : 0ᵒᵖ = 0 := idp
definition initial_functor [constructor] (C : Precategory) : 0 ⇒ C :=
functor.mk (λx, empty.elim x)
(λx y f, empty.elim x)
(λx, empty.elim x)
(λx y z g f, empty.elim x)
definition is_contr_initial_functor [instance] (C : Precategory) : is_contr (0 ⇒ C) :=
is_contr.mk (initial_functor C)
begin
intro F, fapply functor_eq,
{ intro x, exact empty.elim x},
{ intro x y f, exact empty.elim x}
end
definition initial_functor_op (C : Precategory)
: (initial_functor C)ᵒᵖᶠ = initial_functor Cᵒᵖ :=
by apply @is_prop.elim (0 ⇒ Cᵒᵖ)
definition initial_functor_comp {C D : Precategory} (F : C ⇒ D)
: F ∘f initial_functor C = initial_functor D :=
by apply @is_prop.elim (0 ⇒ D)
end category

View file

@ -1,158 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn, Jakob von Raumer
Opposite precategory and (TODO) category
-/
import ..nat_trans ..category
open eq functor iso equiv is_equiv nat_trans
namespace category
definition opposite [reducible] [constructor] {ob : Type} (C : precategory ob) : precategory ob :=
precategory.mk' (λ a b, hom b a)
(λ a b c f g, g ∘ f)
(λ a, id)
(λ a b c d f g h, !assoc')
(λ a b c d f g h, !assoc)
(λ a b f, !id_right)
(λ a b f, !id_left)
(λ a, !id_id)
(λ a b, !is_set_hom)
definition Opposite [reducible] [constructor] (C : Precategory) : Precategory :=
precategory.Mk (opposite C)
infixr `∘op`:60 := @comp _ (opposite _) _ _ _
postfix `ᵒᵖ`:(max+2) := Opposite
variables {C D E : Precategory} {a b c : C}
definition compose_op {f : hom a b} {g : hom b c} : f ∘op g = g ∘ f :=
by reflexivity
definition opposite_opposite' {ob : Type} (C : precategory ob) : opposite (opposite C) = C :=
by cases C; apply idp
definition opposite_opposite : (Cᵒᵖ)ᵒᵖ = C :=
(ap (Precategory.mk C) (opposite_opposite' C)) ⬝ !Precategory.eta
theorem opposite_hom_of_eq {ob : Type} [C : precategory ob] {c c' : ob} (p : c = c')
: @hom_of_eq ob (opposite C) c c' p = inv_of_eq p :=
by induction p; reflexivity
theorem opposite_inv_of_eq {ob : Type} [C : precategory ob] {c c' : ob} (p : c = c')
: @inv_of_eq ob (opposite C) c c' p = hom_of_eq p :=
by induction p; reflexivity
definition opposite_functor [constructor] (F : C ⇒ D) : Cᵒᵖ ⇒ Dᵒᵖ :=
begin
apply functor.mk,
intros, apply respect_id F,
intros, apply @respect_comp C D
end
definition opposite_functor_rev [constructor] (F : Cᵒᵖ ⇒ Dᵒᵖ) : C ⇒ D :=
begin
apply functor.mk,
intros, apply respect_id F,
intros, apply @respect_comp Cᵒᵖ Dᵒᵖ
end
postfix `ᵒᵖᶠ`:(max+2) := opposite_functor
postfix `ᵒᵖ'`:(max+2) := opposite_functor_rev
definition functor_id_op (C : Precategory) : (1 : C ⇒ C)ᵒᵖᶠ = 1 :=
idp
definition opposite_rev_opposite_functor (F : Cᵒᵖ ⇒ Dᵒᵖ) : Fᵒᵖ' ᵒᵖᶠ = F :=
begin
fapply functor_eq: esimp,
{ intro c c' f, esimp, exact !id_right ⬝ !id_left}
end
definition opposite_opposite_rev_functor (F : C ⇒ D) : Fᵒᵖᶠᵒᵖ' = F :=
begin
fapply functor_eq: esimp,
{ intro c c' f, esimp, exact !id_leftright}
end
definition opposite_compose (G : D ⇒ E) (F : C ⇒ D) : (G ∘f F)ᵒᵖᶠ = Gᵒᵖᶠ ∘f Fᵒᵖᶠ :=
idp
definition opposite_nat_trans [constructor] {F G : C ⇒ D} (η : F ⟹ G) : Gᵒᵖᶠ ⟹ Fᵒᵖᶠ :=
begin
fapply nat_trans.mk: esimp,
{ intro c, exact η c},
{ intro c c' f, exact !naturality⁻¹},
end
definition opposite_rev_nat_trans [constructor] {F G : Cᵒᵖ ⇒ Dᵒᵖ} (η : F ⟹ G) : Gᵒᵖ' ⟹ Fᵒᵖ' :=
begin
fapply nat_trans.mk: esimp,
{ intro c, exact η c},
{ intro c c' f, exact !(@naturality Cᵒᵖ Dᵒᵖ)⁻¹},
end
definition opposite_nat_trans_rev [constructor] {F G : C ⇒ D} (η : Fᵒᵖᶠ ⟹ Gᵒᵖᶠ) : G ⟹ F :=
begin
fapply nat_trans.mk: esimp,
{ intro c, exact η c},
{ intro c c' f, exact !(@naturality Cᵒᵖ Dᵒᵖ _ _ η)⁻¹},
end
definition opposite_rev_nat_trans_rev [constructor] {F G : Cᵒᵖ ⇒ Dᵒᵖ} (η : Fᵒᵖ' ⟹ Gᵒᵖ') : G ⟹ F :=
begin
fapply nat_trans.mk: esimp,
{ intro c, exact η c},
{ intro c c' f, exact (naturality η f)⁻¹},
end
definition opposite_iso [constructor] {ob : Type} [C : precategory ob] {a b : ob}
(H : @iso _ C a b) : @iso _ (opposite C) a b :=
begin
fapply @iso.MK _ (opposite C),
{ exact to_inv H},
{ exact to_hom H},
{ exact to_left_inverse H},
{ exact to_right_inverse H},
end
definition iso_of_opposite_iso [constructor] {ob : Type} [C : precategory ob] {a b : ob}
(H : @iso _ (opposite C) a b) : @iso _ C a b :=
begin
fapply iso.MK,
{ exact to_inv H},
{ exact to_hom H},
{ exact to_left_inverse H},
{ exact to_right_inverse H},
end
definition opposite_iso_equiv [constructor] {ob : Type} [C : precategory ob] (a b : ob)
: @iso _ (opposite C) a b ≃ @iso _ C a b :=
begin
fapply equiv.MK,
{ exact iso_of_opposite_iso},
{ exact opposite_iso},
{ intro H, apply iso_eq, reflexivity},
{ intro H, apply iso_eq, reflexivity},
end
definition is_univalent_opposite (C : Category) : is_univalent (Opposite C) :=
begin
intro x y,
fapply is_equiv_of_equiv_of_homotopy,
{ refine @eq_equiv_iso C C x y ⬝e _, symmetry, esimp at *, apply opposite_iso_equiv},
{ intro p, induction p, reflexivity}
end
definition category_opposite [constructor] (C : Category) : category (Opposite C) :=
category.mk _ (is_univalent_opposite C)
definition Category_opposite [constructor] (C : Category) : Category :=
Category.mk _ (category_opposite C)
end category

View file

@ -1,43 +0,0 @@
/-
Copyright (c) 2014 Jakob von Raumer. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Jakob von Raumer
Categories of (hprop value) ordered sets.
-/
import ..category algebra.order types.fin
open algebra category is_trunc is_equiv equiv iso
namespace category
section
universe variable l
parameters (A : Type.{l}) [HA : is_set A] [OA : weak_order.{l} A]
[Hle : Π a b : A, is_prop (a ≤ b)]
include A HA OA Hle
definition precategory_order [constructor] : precategory.{l l} A :=
begin
fconstructor,
{ intro a b, exact a ≤ b },
{ intro a b c, exact ge.trans },
{ intro a, apply le.refl },
do 5 (intros; apply is_prop.elim),
{ intros, apply is_trunc_succ }
end
local attribute [instance] precategory_order
definition category_order : category.{l l} A :=
begin
fapply category.mk precategory_order,
intros a b, fapply adjointify,
{ intro f, apply le.antisymm, apply iso.to_hom f, apply iso.to_inv f },
{ intro f, fapply iso_eq, esimp[precategory_order], apply is_prop.elim },
{ intro p, apply is_prop.elim }
end
end
end category

View file

@ -1,143 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn, Jakob von Raumer
Product precategory and (TODO) category
-/
import ..category ..nat_trans hit.trunc
open eq prod is_trunc functor sigma trunc iso prod.ops nat_trans
namespace category
definition precategory_prod [constructor] [instance] (obC obD : Type)
[C : precategory obC] [D : precategory obD] : precategory (obC × obD) :=
precategory.mk' (λ a b, hom a.1 b.1 × hom a.2 b.2)
(λ a b c g f, (g.1 ∘ f.1, g.2 ∘ f.2))
(λ a, (id, id))
(λ a b c d h g f, pair_eq !assoc !assoc )
(λ a b c d h g f, pair_eq !assoc' !assoc' )
(λ a b f, prod_eq !id_left !id_left )
(λ a b f, prod_eq !id_right !id_right)
(λ a, prod_eq !id_id !id_id)
_
definition Precategory_prod [reducible] [constructor] (C D : Precategory) : Precategory :=
precategory.Mk (precategory_prod C D)
infixr ` ×c `:70 := Precategory_prod
variables {C C' D D' X : Precategory} {u v : carrier (C ×c D)}
theorem prod_hom_of_eq (p : u.1 = v.1) (q : u.2 = v.2)
: hom_of_eq (prod_eq p q) = (hom_of_eq p, hom_of_eq q) :=
by induction u; induction v; esimp at *; induction p; induction q; reflexivity
theorem prod_inv_of_eq (p : u.1 = v.1) (q : u.2 = v.2)
: inv_of_eq (prod_eq p q) = (inv_of_eq p, inv_of_eq q) :=
by induction u; induction v; esimp at *; induction p; induction q; reflexivity
theorem pr1_hom_of_eq (p : u.1 = v.1) (q : u.2 = v.2)
: (hom_of_eq (prod_eq p q)).1 = hom_of_eq p :=
by exact ap pr1 !prod_hom_of_eq
theorem pr1_inv_of_eq (p : u.1 = v.1) (q : u.2 = v.2)
: (inv_of_eq (prod_eq p q)).1 = inv_of_eq p :=
by exact ap pr1 !prod_inv_of_eq
theorem pr2_hom_of_eq (p : u.1 = v.1) (q : u.2 = v.2)
: (hom_of_eq (prod_eq p q)).2 = hom_of_eq q :=
by exact ap pr2 !prod_hom_of_eq
theorem pr2_inv_of_eq (p : u.1 = v.1) (q : u.2 = v.2)
: (inv_of_eq (prod_eq p q)).2 = inv_of_eq q :=
by exact ap pr2 !prod_inv_of_eq
definition pr1_functor [constructor] : C ×c D ⇒ C :=
functor.mk pr1
(λa b, pr1)
(λa, idp)
(λa b c g f, idp)
definition pr2_functor [constructor] : C ×c D ⇒ D :=
functor.mk pr2
(λa b, pr2)
(λa, idp)
(λa b c g f, idp)
definition functor_prod [constructor] [reducible] (F : X ⇒ C) (G : X ⇒ D) : X ⇒ C ×c D :=
functor.mk (λ a, pair (F a) (G a))
(λ a b f, pair (F f) (G f))
(λ a, abstract pair_eq !respect_id !respect_id end)
(λ a b c g f, abstract pair_eq !respect_comp !respect_comp end)
infixr ` ×f `:70 := functor_prod
definition prod_functor_eta (F : X ⇒ C ×c D) : pr1_functor ∘f F ×f pr2_functor ∘f F = F :=
begin
fapply functor_eq: esimp,
{ intro e, apply prod_eq: reflexivity},
{ intro e e' f, apply prod_eq: esimp,
{ refine ap (λx, x ∘ _ ∘ _) !pr1_hom_of_eq ⬝ _,
refine ap (λx, _ ∘ _ ∘ x) !pr1_inv_of_eq ⬝ _, esimp,
apply id_leftright},
{ refine ap (λx, x ∘ _ ∘ _) !pr2_hom_of_eq ⬝ _,
refine ap (λx, _ ∘ _ ∘ x) !pr2_inv_of_eq ⬝ _, esimp,
apply id_leftright}}
end
definition pr1_functor_prod (F : X ⇒ C) (G : X ⇒ D) : pr1_functor ∘f (F ×f G) = F :=
functor_eq (λx, idp)
(λx y f, !id_leftright)
definition pr2_functor_prod (F : X ⇒ C) (G : X ⇒ D) : pr2_functor ∘f (F ×f G) = G :=
functor_eq (λx, idp)
(λx y f, !id_leftright)
-- definition universal_property_prod {C D X : Precategory} (F : X ⇒ C) (G : X ⇒ D)
-- : is_contr (Σ(H : X ⇒ C ×c D), pr1_functor ∘f H = F × pr2_functor ∘f H = G) :=
-- is_contr.mk
-- ⟨functor_prod F G, (pr1_functor_prod F G, pr2_functor_prod F G)⟩
-- begin
-- intro v, induction v with H w, induction w with p q,
-- symmetry, fapply sigma_eq: esimp,
-- { fapply functor_eq,
-- { intro x, apply prod_eq: esimp,
-- { exact ap010 to_fun_ob p x},
-- { exact ap010 to_fun_ob q x}},
-- { intro x y f, apply prod_eq: esimp,
-- { exact sorry},
-- { exact sorry}}},
-- { exact sorry}
-- end
definition prod_functor_prod [constructor] (F : C ⇒ D) (G : C' ⇒ D') : C ×c C' ⇒ D ×c D' :=
(F ∘f pr1_functor) ×f (G ∘f pr2_functor)
definition prod_nat_trans [constructor] {C D D' : Precategory}
{F F' : C ⇒ D} {G G' : C ⇒ D'} (η : F ⟹ F') (θ : G ⟹ G') : F ×f G ⟹ F' ×f G' :=
begin
fapply nat_trans.mk: esimp,
{ intro c, exact (η c, θ c)},
{ intro c c' f, apply prod_eq: esimp:apply naturality}
end
infixr ` ×n `:70 := prod_nat_trans
definition prod_flip_functor [constructor] (C D : Precategory) : C ×c D ⇒ D ×c C :=
functor.mk (λp, (p.2, p.1))
(λp p' h, (h.2, h.1))
(λp, idp)
(λp p' p'' h' h, idp)
definition functor_prod_flip_functor_prod_flip (C D : Precategory)
: prod_flip_functor D C ∘f (prod_flip_functor C D) = functor.id :=
begin
fapply functor_eq,
{ intro p, apply prod.eta},
{ intro p p' h, cases p with c d, cases p' with c' d',
apply id_leftright}
end
end category

View file

@ -1,499 +0,0 @@
/-
Copyright (c) 2016 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
The pushout of categories
The morphisms in the pushout of two categories is defined as a quotient on lists of composable
morphisms. For this we use the notion of paths in a graph.
-/
import ..category ..nat_trans hit.set_quotient algebra.relation ..groupoid algebra.graph
.functor
open eq is_trunc functor trunc sum set_quotient relation iso category sigma nat nat_trans
/- we first define the categorical structure on paths in a graph -/
namespace paths
section
parameters {A : Type} {R : A → A → Type}
(Q : Π⦃a a' : A⦄, paths R a a' → paths R a a' → Type)
variables ⦃a a' a₁ a₂ a₃ a₄ : A⦄
definition paths_trel [constructor] (l l' : paths R a a') : Prop :=
∥paths_rel Q l l'∥
local notation `S` := @paths_trel
definition paths_quotient (a a' : A) : Type := set_quotient (@S a a')
local notation `mor` := paths_quotient
local attribute paths_quotient [reducible]
definition is_reflexive_R : is_reflexive (@S a a') :=
begin constructor, intro s, apply tr, constructor end
local attribute is_reflexive_R [instance]
definition paths_compose [unfold 7 8] (g : mor a₂ a₃) (f : mor a₁ a₂) : mor a₁ a₃ :=
begin
refine quotient_binary_map _ _ g f, exact append,
intros, refine trunc_functor2 _ r s, exact rel_respect_append
end
definition paths_id [constructor] (a : A) : mor a a :=
class_of nil
local infix ` ∘∘ `:60 := paths_compose
local notation `p1` := paths_id _
theorem paths_assoc (h : mor a₃ a₄) (g : mor a₂ a₃) (f : mor a₁ a₂) :
h ∘∘ (g ∘∘ f) = (h ∘∘ g) ∘∘ f :=
begin
induction h using set_quotient.rec_prop with h,
induction g using set_quotient.rec_prop with g,
induction f using set_quotient.rec_prop with f,
rewrite [▸*, append_assoc]
end
theorem paths_id_left (f : mor a a') : p1 ∘∘ f = f :=
begin
induction f using set_quotient.rec_prop with f,
reflexivity
end
theorem paths_id_right (f : mor a a') : f ∘∘ p1 = f :=
begin
induction f using set_quotient.rec_prop with f,
rewrite [▸*, append_nil]
end
definition Precategory_paths [constructor] : Precategory :=
precategory.MK A
mor
_
paths_compose
paths_id
paths_assoc
paths_id_left
paths_id_right
/- given a way to reverse edges and some additional properties we can extend this to a
groupoid structure -/
parameters (inv : Π⦃a a' : A⦄, R a a' → R a' a)
(rel_inv : Π⦃a a' : A⦄ {l l' : paths R a a'},
Q l l' → paths_rel Q (reverse inv l) (reverse inv l'))
(li : Π⦃a a' : A⦄ (r : R a a'), paths_rel Q [inv r, r] nil)
(ri : Π⦃a a' : A⦄ (r : R a a'), paths_rel Q [r, inv r] nil)
include rel_inv li ri
definition paths_inv [unfold 8] (f : mor a a') : mor a' a :=
begin
refine quotient_unary_map (reverse inv) _ f,
intros, refine trunc_functor _ _ r, esimp,
intro s, apply rel_respect_reverse inv s rel_inv
end
local postfix `^`:max := paths_inv
theorem paths_left_inv (f : mor a₁ a₂) : f^ ∘∘ f = p1 :=
begin
induction f using set_quotient.rec_prop with f,
esimp, apply eq_of_rel, apply tr,
apply rel_left_inv, apply li
end
theorem paths_right_inv (f : mor a₁ a₂) : f ∘∘ f^ = p1 :=
begin
induction f using set_quotient.rec_prop with f,
esimp, apply eq_of_rel, apply tr,
apply rel_right_inv, apply ri
end
definition Groupoid_paths [constructor] : Groupoid :=
groupoid.MK Precategory_paths
(λa b f, is_iso.mk (paths_inv f) (paths_left_inv f) (paths_right_inv f))
end
end paths
open paths
namespace category
/- We also define the pushout of two groupoids with a type of basepoints, which are surjectively
mapped into C (although we don't need to assume that this mapping is surjective for the
definition) -/
section
inductive bpushout_prehom_index {S : Type} {C D E : Precategory} (k : S → C) (F : C ⇒ D)
(G : C ⇒ E) : D + E → D + E → Type :=
| iD : Π{d d' : D} (f : d ⟶ d'), bpushout_prehom_index k F G (inl d) (inl d')
| iE : Π{e e' : E} (g : e ⟶ e'), bpushout_prehom_index k F G (inr e) (inr e')
| DE : Π(s : S), bpushout_prehom_index k F G (inl (F (k s))) (inr (G (k s)))
| ED : Π(s : S), bpushout_prehom_index k F G (inr (G (k s))) (inl (F (k s)))
open bpushout_prehom_index
definition bpushout_prehom {S : Type} {C D E : Precategory} (k : S → C) (F : C ⇒ D) (G : C ⇒ E) :
D + E → D + E → Type :=
paths (bpushout_prehom_index k F G)
inductive bpushout_hom_rel_index {S : Type} {C D E : Precategory} (k : S → C) (F : C ⇒ D)
(G : C ⇒ E) : Π⦃x x' : D + E⦄,
bpushout_prehom k F G x x' → bpushout_prehom k F G x x' → Type :=
| DD : Π{d₁ d₂ d₃ : D} (g : d₂ ⟶ d₃) (f : d₁ ⟶ d₂),
bpushout_hom_rel_index k F G [iD k F G g, iD k F G f] [iD k F G (g ∘ f)]
| EE : Π{e₁ e₂ e₃ : E} (g : e₂ ⟶ e₃) (f : e₁ ⟶ e₂),
bpushout_hom_rel_index k F G [iE k F G g, iE k F G f] [iE k F G (g ∘ f)]
| DED : Π(s : S), bpushout_hom_rel_index k F G [ED k F G s, DE k F G s] nil
| EDE : Π(s : S), bpushout_hom_rel_index k F G [DE k F G s, ED k F G s] nil
| idD : Π(d : D), bpushout_hom_rel_index k F G [iD k F G (ID d)] nil
| idE : Π(e : E), bpushout_hom_rel_index k F G [iE k F G (ID e)] nil
| cohDE : Π{s₁ s₂ : S} (h : k s₁ ⟶ k s₂),
bpushout_hom_rel_index k F G [iE k F G (G h), DE k F G s₁] [DE k F G s₂, iD k F G (F h)]
| cohED : Π{s₁ s₂ : S} (h : k s₁ ⟶ k s₂),
bpushout_hom_rel_index k F G [ED k F G s₂, iE k F G (G h)] [iD k F G (F h), ED k F G s₁]
open bpushout_hom_rel_index paths.paths_rel
definition Precategory_bpushout [constructor] {S : Type} {C D E : Precategory}
(k : S → C) (F : C ⇒ D) (G : C ⇒ E) : Precategory :=
Precategory_paths (bpushout_hom_rel_index k F G)
parameters {C D E X : Precategory} (F : C ⇒ D) (G : C ⇒ E) (H : D ⇒ X) (K : E ⇒ X)
(η : H ∘f F ≅ K ∘f G)
definition Cpushout [constructor] : Precategory :=
Precategory_bpushout (λc, c) F G
definition Cpushout_inl [constructor] : D ⇒ Cpushout :=
begin
fapply functor.mk,
{ exact inl},
{ intro d d' f, exact class_of [iD (λc, c) F G f]},
{ intro d, refine eq_of_rel (tr (paths_rel_of_Q _)), apply idD},
{ intro d₁ d₂ d₃ g f, refine (eq_of_rel (tr (paths_rel_of_Q _)))⁻¹, apply DD}
end
definition Cpushout_inr [constructor] : E ⇒ Cpushout :=
begin
fapply functor.mk,
{ exact inr},
{ intro e e' f, exact class_of [iE (λc, c) F G f]},
{ intro e, refine eq_of_rel (tr (paths_rel_of_Q _)), apply idE},
{ intro e₁ e₂ e₃ g f, refine (eq_of_rel (tr (paths_rel_of_Q _)))⁻¹, apply EE}
end
definition Cpushout_coh [constructor] : Cpushout_inl ∘f F ≅ Cpushout_inr ∘f G :=
begin
fapply natural_iso.MK,
{ intro c, exact class_of [DE (λ c, c) F G c]},
{ intro c c' f, refine eq_of_rel (tr (paths_rel_of_Q !cohDE))},
{ intro c, exact class_of [ED (λ c, c) F G c]},
{ intro c, refine eq_of_rel (tr (paths_rel_of_Q !DED))},
{ intro c, refine eq_of_rel (tr (paths_rel_of_Q !EDE))},
end
--(class_of [DE (λ c, c) F G s])
variables ⦃x x' x₁ x₂ x₃ : Cpushout⦄
include H K
local notation `R` := bpushout_prehom_index (λ c, c) F G
local notation `Q` := bpushout_hom_rel_index (λ c, c) F G
definition Cpushout_functor_ob [unfold 9] (x : Cpushout) : X :=
begin
induction x with d e,
{ exact H d},
{ exact K e}
end
include η
parameters {F G H K}
definition Cpushout_functor_reduction_rule [unfold 12] (i : R x x') :
Cpushout_functor_ob x ⟶ Cpushout_functor_ob x' :=
begin
induction i,
{ exact H f},
{ exact K g},
{ exact natural_map (to_hom η) s},
{ exact natural_map (to_inv η) s}
end
definition Cpushout_functor_list (l : paths R x x') :
Cpushout_functor_ob x ⟶ Cpushout_functor_ob x' :=
realize _
Cpushout_functor_reduction_rule
(λa, id)
(λa b c g f, f ∘ g) l
definition Cpushout_functor_list_nil (x : Cpushout) :
Cpushout_functor_list (@nil _ _ x) = id :=
idp
definition Cpushout_functor_list_cons (r : R x₂ x₃) (l : paths R x₁ x₂) :
Cpushout_functor_list (r :: l) = Cpushout_functor_reduction_rule r ∘ Cpushout_functor_list l :=
idp
definition Cpushout_functor_list_singleton (r : R x₁ x₂) :
Cpushout_functor_list [r] = Cpushout_functor_reduction_rule r :=
realize_singleton (λa b f, id_right f) r
definition Cpushout_functor_list_pair (r₂ : R x₂ x₃) (r₁ : R x₁ x₂) :
Cpushout_functor_list [r₂, r₁] =
Cpushout_functor_reduction_rule r₂ ∘ Cpushout_functor_reduction_rule r₁ :=
realize_pair (λa b f, id_right f) r₂ r₁
definition Cpushout_functor_list_append (l₂ : paths R x₂ x₃) (l₁ : paths R x₁ x₂) :
Cpushout_functor_list (l₂ ++ l₁) = Cpushout_functor_list l₂ ∘ Cpushout_functor_list l₁ :=
realize_append (λa b c d h g f, assoc f g h) (λa b f, id_left f) l₂ l₁
theorem Cpushout_functor_list_rel {l l' : paths R x x'} (q : Q l l') :
Cpushout_functor_list l = Cpushout_functor_list l' :=
begin
induction q,
{ rewrite [Cpushout_functor_list_pair, Cpushout_functor_list_singleton],
exact (respect_comp H g f)⁻¹},
{ rewrite [Cpushout_functor_list_pair, Cpushout_functor_list_singleton],
exact (respect_comp K g f)⁻¹},
{ rewrite [Cpushout_functor_list_pair, Cpushout_functor_list_nil],
exact ap010 natural_map (to_left_inverse η) s},
{ rewrite [Cpushout_functor_list_pair, Cpushout_functor_list_nil],
exact ap010 natural_map (to_right_inverse η) s},
{ rewrite [Cpushout_functor_list_singleton, Cpushout_functor_list_nil], exact respect_id H d},
{ rewrite [Cpushout_functor_list_singleton, Cpushout_functor_list_nil], exact respect_id K e},
{ rewrite [+Cpushout_functor_list_pair], exact naturality (to_hom η) h},
{ rewrite [+Cpushout_functor_list_pair], exact (naturality (to_inv η) h)⁻¹}
end
definition Cpushout_functor_hom [unfold 12] (f : x ⟶ x') :
Cpushout_functor_ob x ⟶ Cpushout_functor_ob x' :=
begin
induction f with l l l' q,
{ exact Cpushout_functor_list l},
{ esimp at *, induction q with q, refine realize_eq _ _ _ q,
{ intros, apply assoc},
{ intros, apply id_left},
intro a₁ a₂ l₁ l₁ q, exact Cpushout_functor_list_rel q}
end
definition Cpushout_functor [constructor] : Cpushout ⇒ X :=
begin
fapply functor.mk,
{ exact Cpushout_functor_ob},
{ exact Cpushout_functor_hom},
{ intro x, reflexivity},
{ intro x₁ x₂ x₃ g f,
induction g using set_quotient.rec_prop with l₂,
induction f using set_quotient.rec_prop with l₁,
exact Cpushout_functor_list_append l₂ l₁}
end
definition Cpushout_functor_inl [constructor] : Cpushout_functor ∘f Cpushout_inl ≅ H :=
begin
fapply natural_iso.mk,
{ fapply nat_trans.mk,
{ intro d, exact id},
{ intro d d' f, rewrite [▸*, Cpushout_functor_list_singleton], apply comp_id_eq_id_comp}},
esimp, exact _
end
definition Cpushout_functor_inr [constructor] : Cpushout_functor ∘f Cpushout_inr ≅ K :=
begin
fapply natural_iso.mk,
{ fapply nat_trans.mk,
{ intro d, exact id},
{ intro d d' f, rewrite [▸*, Cpushout_functor_list_singleton], apply comp_id_eq_id_comp}},
esimp, exact _
end
definition Cpushout_functor_coh (c : C) : natural_map (to_hom Cpushout_functor_inr) (G c) ∘
Cpushout_functor (natural_map (to_hom Cpushout_coh) c) ∘
natural_map (to_inv Cpushout_functor_inl) (F c) = natural_map (to_hom η) c :=
!id_leftright ⬝ !Cpushout_functor_list_singleton
definition Cpushout_functor_unique_ob [unfold 13] (L : Cpushout ⇒ X) (η₁ : L ∘f Cpushout_inl ≅ H)
(η₂ : L ∘f Cpushout_inr ≅ K) (x : Cpushout) : L x ⟶ Cpushout_functor x :=
begin
induction x with d e,
{ exact natural_map (to_hom η₁) d},
{ exact natural_map (to_hom η₂) e}
end
definition Cpushout_functor_unique_inv_ob [unfold 13] (L : Cpushout ⇒ X)
(η₁ : L ∘f Cpushout_inl ≅ H) (η₂ : L ∘f Cpushout_inr ≅ K) (x : Cpushout) :
Cpushout_functor x ⟶ L x :=
begin
induction x with d e,
{ exact natural_map (to_inv η₁) d},
{ exact natural_map (to_inv η₂) e}
end
definition Cpushout_functor_unique_nat_singleton (L : Cpushout ⇒ X) (η₁ : L ∘f Cpushout_inl ≅ H)
(η₂ : L ∘f Cpushout_inr ≅ K)
(p : Πs, natural_map (to_hom η₂) (to_fun_ob G s) ∘
to_fun_hom L (natural_map (to_hom Cpushout_coh) s) ∘
natural_map (to_inv η₁) (to_fun_ob F s) = natural_map (to_hom η) s) (r : R x x') :
Cpushout_functor_reduction_rule r ∘ Cpushout_functor_unique_ob L η₁ η₂ x =
Cpushout_functor_unique_ob L η₁ η₂ x' ∘ L (class_of [r]) :=
begin
induction r,
{ exact naturality (to_hom η₁) f},
{ exact naturality (to_hom η₂) g},
{ refine ap (λx, x ∘ _) (p s)⁻¹ ⬝ _, refine !assoc' ⬝ _, apply ap (λx, _ ∘ x),
refine !assoc' ⬝ _ ⬝ !id_right, apply ap (λx, _ ∘ x),
exact ap010 natural_map (to_left_inverse η₁) (F s)},
{ apply comp.cancel_left (to_hom (componentwise_iso η s)),
refine !assoc ⬝ _ ⬝ ap (λx, x ∘ _) (p s),
refine ap (λx, x ∘ _) (ap010 natural_map (to_right_inverse η) s) ⬝ _ ⬝ !assoc,
refine !id_left ⬝ !id_right⁻¹ ⬝ _, apply ap (λx, _ ∘ x),
refine _ ⬝ ap (λx, _ ∘ x) (ap (λx, x ∘ _) _⁻¹ ⬝ !assoc') ⬝ !assoc,
rotate 2, exact ap010 natural_map (to_left_inverse η₁) (F s),
refine _⁻¹ ⬝ ap (λx, _ ∘ x) !id_left⁻¹, refine (respect_comp L _ _)⁻¹ ⬝ _ ⬝ respect_id L _,
apply ap (to_fun_hom L), refine eq_of_rel (tr (paths_rel_of_Q _)), apply EDE},
end
definition Cpushout_functor_unique [constructor] (L : Cpushout ⇒ X) (η₁ : L ∘f Cpushout_inl ≅ H)
(η₂ : L ∘f Cpushout_inr ≅ K)
(p : Πs, natural_map (to_hom η₂) (to_fun_ob G s) ∘
to_fun_hom L (natural_map (to_hom Cpushout_coh) s) ∘
natural_map (to_inv η₁) (to_fun_ob F s) = natural_map (to_hom η) s) :
L ≅ Cpushout_functor :=
begin
fapply natural_iso.MK,
{ exact Cpushout_functor_unique_ob L η₁ η₂},
{ intro x x' f, induction f using set_quotient.rec_prop with l,
esimp, induction l with x x₁ x₂ x₃ r l IH,
{ refine !id_left ⬝ !id_right⁻¹ ⬝ _⁻¹, apply ap (λx, _ ∘ x), apply respect_id},
{ rewrite [Cpushout_functor_list_cons, assoc', ▸*, IH, assoc, ▸*,
Cpushout_functor_unique_nat_singleton L η₁ η₂ p r, ▸*, assoc', -respect_comp L]}},
{ exact Cpushout_functor_unique_inv_ob L η₁ η₂},
{ intro x, induction x with d e,
{ exact ap010 natural_map (to_left_inverse η₁) d},
{ exact ap010 natural_map (to_left_inverse η₂) e}},
{ intro x, induction x with d e,
{ exact ap010 natural_map (to_right_inverse η₁) d},
{ exact ap010 natural_map (to_right_inverse η₂) e}},
end
end
open bpushout_prehom_index prod prod.ops is_equiv equiv
definition Cpushout_universal {C D E : Precategory} {X : Category} (F : C ⇒ D) (G : C ⇒ E)
(H : D ⇒ X) (K : E ⇒ X) (η : H ∘f F ≅ K ∘f G) :
is_contr (Σ(L : Cpushout F G ⇒ X) (θ : L ∘f Cpushout_inl F G ≅ H × L ∘f Cpushout_inr F G ≅ K),
Πs, natural_map (to_hom θ.2) (to_fun_ob G s) ∘ to_fun_hom L (class_of [DE (λ c, c) F G s]) ∘
natural_map (to_inv θ.1) (to_fun_ob F s) = natural_map (to_hom η) s) :=
begin
fapply is_contr.mk,
{ exact ⟨Cpushout_functor η, (Cpushout_functor_inl η, Cpushout_functor_inr η),
Cpushout_functor_coh η⟩},
intro v₁, induction v₁ with L v₂, induction v₂ with θ p, induction θ with θ₁ θ₂,
fapply sigma_eq,
{ esimp, apply eq_of_iso, symmetry, exact Cpushout_functor_unique η L θ₁ θ₂ p},
fapply sigma_pathover,
{ apply prod_pathover: esimp,
{ apply iso_pathover,
apply hom_pathover_functor_left_constant_right (precomposition_functor _ _),
apply nat_trans_eq, intro d,
xrewrite [↑[hom_of_eq], to_right_inv !eq_equiv_iso, ▸*],
exact (ap010 natural_map (to_right_inverse θ₁) d)⁻¹},
{ apply iso_pathover,
apply hom_pathover_functor_left_constant_right (precomposition_functor _ _),
apply nat_trans_eq, intro e,
xrewrite [↑[hom_of_eq], to_right_inv !eq_equiv_iso, ▸*],
exact (ap010 natural_map (to_right_inverse θ₂) e)⁻¹}},
apply is_prop.elimo
end
local attribute prod.eq_pr1 prod.eq_pr2 [reducible]
definition Cpushout_equiv {C D E : Precategory} {X : Category} (F : C ⇒ D) (G : C ⇒ E) :
(Cpushout F G ⇒ X) ≃ Σ(H : (D ⇒ X) × (E ⇒ X)), H.1 ∘f F ≅ H.2 ∘f G :=
begin
fapply equiv.MK,
{ intro K, refine ⟨(K ∘f Cpushout_inl F G, K ∘f Cpushout_inr F G), _⟩,
exact !assoc_iso⁻¹ⁱ ⬝i (K ∘fi Cpushout_coh F G) ⬝i !assoc_iso},
{ intro v, cases v with w η, cases w with K L, exact Cpushout_functor η},
{ exact abstract begin intro v, cases v with w η, cases w with K L, esimp at *,
fapply sigma_eq,
{ fapply prod_eq: esimp; apply eq_of_iso,
{ exact Cpushout_functor_inl η},
{ exact Cpushout_functor_inr η}},
esimp, apply iso_pathover, apply hom_pathover,
rewrite [ap_compose' _ pr₁, ap_compose' _ pr₂, prod_eq_pr1, prod_eq_pr2],
rewrite [-+respect_hom_of_eq (precomposition_functor _ _), +hom_of_eq_eq_of_iso],
apply nat_trans_eq, intro c, esimp [category.to_precategory],
rewrite [+id_left, +id_right, Cpushout_functor_list_singleton] end end},
{ exact abstract begin intro K, esimp,
refine eq_base_of_is_prop_sigma _ !is_trunc_succ _ _, rotate 1,
{ refine Cpushout_universal F G (K ∘f Cpushout_inl F G) (K ∘f Cpushout_inr F G) _,
exact !assoc_iso⁻¹ⁱ ⬝i (K ∘fi Cpushout_coh F G) ⬝i !assoc_iso},
{ esimp, fconstructor, esimp, split,
{ fapply natural_iso.mk',
{ intro c, reflexivity},
{ intro c c' f, rewrite [▸*, id_right, Cpushout_functor_list_singleton, id_left]}},
{ fapply natural_iso.mk',
{ intro c, reflexivity},
{ intro c c' f, rewrite [▸*, id_right, Cpushout_functor_list_singleton, id_left]}},
intro c, rewrite [▸*, id_left, id_right, Cpushout_functor_list_singleton]},
{ esimp, fconstructor,
{ split: reflexivity},
intro c, reflexivity} end end}
end
/- Pushout of groupoids with a type of basepoints -/
section
variables {S : Type} {C D E : Groupoid} (k : S → C) (F : C ⇒ D) (G : C ⇒ E)
variables ⦃x x' x₁ x₂ x₃ x₄ : Precategory_bpushout k F G⦄
open bpushout_prehom_index paths.paths_rel bpushout_hom_rel_index
definition bpushout_index_inv [unfold 8] (i : bpushout_prehom_index k F G x x') :
bpushout_prehom_index k F G x' x :=
begin
induction i,
{ exact iD k F G f⁻¹},
{ exact iE k F G g⁻¹},
{ exact ED k F G s},
{ exact DE k F G s},
end
theorem bpushout_index_reverse {l l' : bpushout_prehom k F G x x'}
(q : bpushout_hom_rel_index k F G l l') : paths_rel (bpushout_hom_rel_index k F G)
(reverse (bpushout_index_inv k F G) l) (reverse (bpushout_index_inv k F G) l') :=
begin
induction q: apply paths_rel_of_Q;
try rewrite reverse_singleton; rewrite *reverse_pair; try rewrite reverse_nil; esimp;
try rewrite [comp_inverse]; try rewrite [id_inverse]; rewrite [-*respect_inv]; constructor
end
theorem bpushout_index_li (i : bpushout_prehom_index k F G x x') :
paths_rel (bpushout_hom_rel_index k F G) [bpushout_index_inv k F G i, i] nil :=
begin
induction i: esimp,
{ refine rtrans (paths_rel_of_Q !DD) _,
rewrite [comp.left_inverse], exact paths_rel_of_Q !idD},
{ refine rtrans (paths_rel_of_Q !EE) _,
rewrite [comp.left_inverse], exact paths_rel_of_Q !idE},
{ exact paths_rel_of_Q !DED},
{ exact paths_rel_of_Q !EDE}
end
theorem bpushout_index_ri (i : bpushout_prehom_index k F G x x') :
paths_rel (bpushout_hom_rel_index k F G) [i, bpushout_index_inv k F G i] nil :=
begin
induction i: esimp,
{ refine rtrans (paths_rel_of_Q !DD) _,
rewrite [comp.right_inverse], exact paths_rel_of_Q !idD},
{ refine rtrans (paths_rel_of_Q !EE) _,
rewrite [comp.right_inverse], exact paths_rel_of_Q !idE},
{ exact paths_rel_of_Q !EDE},
{ exact paths_rel_of_Q !DED}
end
definition Groupoid_bpushout [constructor] : Groupoid :=
Groupoid_paths (bpushout_hom_rel_index k F G) (bpushout_index_inv k F G)
(bpushout_index_reverse k F G) (bpushout_index_li k F G) (bpushout_index_ri k F G)
definition Gpushout [constructor] : Groupoid :=
Groupoid_bpushout (λc, c) F G
end
end category

View file

@ -1,441 +0,0 @@
/-
Copyright (c) 2016 Jakob von Raumer. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Jakob von Raumer
The Rezk completion
-/
import algebra.category hit.two_quotient types.trunc types.arrow algebra.category.functor.attributes
open eq category equiv trunc_two_quotient is_trunc iso e_closure function pi trunctype
namespace rezk
section
universes l k
parameters {A : Type.{l}} [C : precategory.{l k} A]
include C
inductive rezk_Q : Π ⦃a b : A⦄, e_closure iso a b → e_closure iso a b → Type :=
| comp_con : Π ⦃a b c : A⦄ (g : b ≅ c) (f : a ≅ b) , rezk_Q [f ⬝i g] ([f] ⬝r [g])
definition rezk_carrier := trunc_two_quotient 1 iso rezk_Q
local attribute rezk_carrier [reducible]
definition is_trunc_rezk_carrier [instance] : is_trunc 1 rezk_carrier := _
variables {a b c : A}
definition elt (a : A) : rezk_carrier := incl0 a
definition pth (f : a ≅ b) : elt a = elt b := incl1 f
definition resp_comp (g : b ≅ c) (f : a ≅ b) : pth (f ⬝i g) = pth f ⬝ pth g :=
incl2 (rezk_Q.comp_con g f)
definition resp_id (a : A) : pth (iso.refl a) = idp :=
begin
apply cancel_right (pth (iso.refl a)), refine _ ⬝ !idp_con⁻¹,
refine !resp_comp⁻¹ ⬝ _,
apply ap pth, apply iso_eq, apply id_left,
end
protected definition rec {P : rezk_carrier → Type} [Π x, is_trunc 1 (P x)]
(Pe : Π a, P (elt a)) (Pp : Π ⦃a b⦄ (f : a ≅ b), Pe a =[pth f] Pe b)
(Pcomp : Π ⦃a b c⦄ (g : b ≅ c) (f : a ≅ b),
change_path (resp_comp g f) (Pp (f ⬝i g)) = Pp f ⬝o Pp g)
(x : rezk_carrier) : P x :=
begin
induction x,
{ apply Pe },
{ apply Pp },
{ induction q with a b c g f, apply Pcomp }
end
protected definition rec_on {P : rezk_carrier → Type} [Π x, is_trunc 1 (P x)]
(x : rezk_carrier)
(Pe : Π a, P (elt a)) (Pp : Π ⦃a b⦄ (f : a ≅ b), Pe a =[pth f] Pe b)
(Pcomp : Π ⦃a b c⦄ (g : b ≅ c) (f : a ≅ b),
change_path (resp_comp g f) (Pp (f ⬝i g)) = Pp f ⬝o Pp g) : P x :=
rec Pe Pp Pcomp x
protected definition set_rec {P : rezk_carrier → Type} [Π x, is_set (P x)]
(Pe : Π a, P (elt a)) (Pp : Π⦃a b⦄ (f : a ≅ b), Pe a =[pth f] Pe b)
(x : rezk_carrier) : P x :=
rec Pe Pp !center x
protected definition prop_rec {P : rezk_carrier → Type} [Π x, is_prop (P x)]
(Pe : Π a, P (elt a)) (x : rezk_carrier) : P x :=
rec Pe !center !center x
protected definition elim {P : Type} [is_trunc 1 P] (Pe : A → P)
(Pp : Π ⦃a b⦄ (f : a ≅ b), Pe a = Pe b)
(Pcomp : Π ⦃a b c⦄ (g : b ≅ c) (f : a ≅ b), Pp (f ⬝i g) = Pp f ⬝ Pp g)
(x : rezk_carrier) : P :=
begin
induction x,
{ exact Pe a },
{ exact Pp s },
{ induction q with a b c g f, exact Pcomp g f }
end
protected definition elim_on [reducible] {P : Type} [is_trunc 1 P] (x : rezk_carrier)
(Pe : A → P) (Pp : Π ⦃a b⦄ (f : a ≅ b), Pe a = Pe b)
(Pcomp : Π ⦃a b c⦄ (g : b ≅ c) (f : a ≅ b), Pp (f ⬝i g) = Pp f ⬝ Pp g) : P :=
elim Pe Pp Pcomp x
protected definition set_elim [reducible] {P : Type} [is_set P] (Pe : A → P)
(Pp : Π ⦃a b⦄ (f : a ≅ b), Pe a = Pe b) (x : rezk_carrier) : P :=
elim Pe Pp !center x
protected definition prop_elim [reducible] {P : Type} [is_prop P] (Pe : A → P)
(x : rezk_carrier) : P :=
elim Pe !center !center x
definition elim_pth {P : Type} [is_trunc 1 P] {Pe : A → P} {Pp : Π⦃a b⦄ (f : a ≅ b), Pe a = Pe b}
(Pcomp : Π⦃a b c⦄ (g : b ≅ c) (f : a ≅ b), Pp (f ⬝i g) = Pp f ⬝ Pp g) {a b : A} (f : a ≅ b) :
ap (elim Pe Pp Pcomp) (pth f) = Pp f :=
!elim_incl1
--TODO generalize this to arbitrary truncated two-quotients or not?
protected definition elim_set.{m} [reducible] (Pe : A → Set.{m}) (Pp : Π ⦃a b⦄ (f : a ≅ b), Pe a ≃ Pe b)
(Pcomp : Π ⦃a b c⦄ (g : b ≅ c) (f : a ≅ b) (x : Pe a), Pp (f ⬝i g) x = Pp g (Pp f x))
(x : rezk_carrier) : Set.{m} :=
elim Pe (λa b f, tua (Pp f)) (λa b c g f, ap tua (equiv_eq (Pcomp g f)) ⬝ !tua_trans) x
protected definition elim_set_pt.{m} [reducible] (Pe : A → Set.{m}) (Pp : Π ⦃a b⦄ (f : a ≅ b), Pe a ≃ Pe b)
(Pcomp : Π ⦃a b c⦄ (g : b ≅ c) (f : a ≅ b) (x : Pe a), Pp (f ⬝i g) x = Pp g (Pp f x))
(a : A) : trunctype.carrier (rezk.elim_set Pe Pp Pcomp (elt a)) = Pe a :=
idp
protected theorem elim_set_pth {Pe : A → Set} {Pp : Π⦃a b⦄ (f : a ≅ b), Pe a ≃ Pe b}
(Pcomp : Π⦃a b c⦄ (g : b ≅ c) (f : a ≅ b) (x : Pe a), Pp (f ⬝i g) x = Pp g (Pp f x))
{a b : A} (f : a ≅ b) :
transport (elim_set Pe Pp Pcomp) (pth f) = Pp f :=
begin
rewrite [tr_eq_cast_ap_fn, ↑elim_set, ▸*],
rewrite [ap_compose' trunctype.carrier, elim_pth], apply tcast_tua_fn
end
end
end rezk open rezk
attribute rezk.elt [constructor]
attribute rezk.rec rezk.elim [unfold 8] [recursor 8]
attribute rezk.rec_on rezk.elim_on [unfold 5]
attribute rezk.set_rec rezk.set_elim [unfold 7]
attribute rezk.prop_rec rezk.prop_elim
rezk.elim_set [unfold 6]
namespace rezk
section
universes l k
parameters (A : Type.{l}) (C : precategory.{l k} A)
definition rezk_hom_left_pt [constructor] (a : A) (b : @rezk_carrier A C) : Set.{k} :=
begin
refine rezk.elim_set _ _ _ b,
{ clear b, intro b, exact trunctype.mk' 0 (hom a b) },
{ clear b, intro b b' f, apply equiv_postcompose (iso.to_hom f) },
{ clear b, intro b b' b'' f g x, apply !assoc⁻¹ }
end
private definition pathover_rezk_hom_left_pt {a b c : A} (f : hom a b) (g : b ≅ c) :
pathover (rezk_hom_left_pt a) f (pth g) ((to_hom g) ∘ f) :=
begin
apply pathover_of_tr_eq, apply @homotopy_of_eq _ _ _ (λ f, (to_hom g) ∘ f),
apply rezk.elim_set_pth,
end
definition rezk_hom_left_pth_1_trunc [instance] (a a' : A) (f : a ≅ a') :
Π b, is_trunc 1 (carrier (rezk_hom_left_pt a b) ≃ carrier (rezk_hom_left_pt a' b)) :=
λ b, is_trunc_equiv _ _ _
definition rezk_hom_left_pth (a a' : A) (f : a ≅ a') (b : rezk_carrier) :
carrier (rezk_hom_left_pt a b) ≃ carrier (rezk_hom_left_pt a' b) :=
begin
--induction b using rezk.rec with b' b' b g, --why does this not work if it works below?
refine @rezk.rec _ _ _ (rezk_hom_left_pth_1_trunc a a' f) _ _ _ b,
intro b, apply equiv_precompose (to_hom f⁻¹ⁱ), --how do i unfold properly at this point?
{ intro b b' g, apply equiv_pathover, intro g' g'' H,
refine !pathover_rezk_hom_left_pt ⬝op _,
refine !assoc ⬝ ap (λ x, x ∘ _) _, refine eq_of_parallel_po_right _ H,
apply pathover_rezk_hom_left_pt },
intro b b' b'' g g', apply @is_prop.elim, apply is_trunc_pathover, apply is_trunc_equiv
end
definition rezk_hom [unfold 3 4] (a b : @rezk_carrier A C) : Set.{k} :=
begin
refine rezk.elim_set _ _ _ a,
{ clear a, intro a, exact rezk_hom_left_pt a b },
{ clear a, intro a a' f, apply rezk_hom_left_pth a a' f },
{ clear a, intro a a' a'' Ef Eg Rfg, induction b using rezk.rec,
apply assoc, apply is_prop.elimo, apply is_set.elimo }
end
private definition pathover_rezk_hom_left {a b c : A} (f : hom a c) (g : a ≅ b) :
pathover (λ x, rezk_hom x (elt c)) f (pth g) (f ∘ (to_hom g)⁻¹) :=
begin
apply pathover_of_tr_eq, apply @homotopy_of_eq _ _ _ (λ f, f ∘ (to_hom g)⁻¹),
apply rezk.elim_set_pth,
end
private definition pathover_rezk_hom_right {a b c : A} (f : hom a b) (g : b ≅ c) : --todo delete?
pathover (rezk_hom (elt a)) f (pth g) ((to_hom g) ∘ f) :=
begin
apply pathover_rezk_hom_left_pt,
end
private definition transport_rezk_hom_eq_comp {a c : A} (f : hom a a) (g : a ≅ c) :
transport (λ x, rezk_hom x x) (pth g) f = (to_hom g) ∘ f ∘ (to_hom g)⁻¹ :=
begin
apply concat, apply tr_diag_eq_tr_tr rezk_hom,
apply concat, apply ap (λ x, _ ▸ x),
apply tr_eq_of_pathover, apply pathover_rezk_hom_left,
apply tr_eq_of_pathover, apply pathover_rezk_hom_left_pt
end
definition rezk_id (a : @rezk_carrier A C) : rezk_hom a a :=
begin
induction a using rezk.rec,
apply id,
{ apply pathover_of_tr_eq, refine !transport_rezk_hom_eq_comp ⬝ _,
refine (ap (λ x, to_hom f ∘ x) !id_left) ⬝ _, apply right_inverse },
apply is_set.elimo
end
definition rezk_comp_pt_pt [reducible] {c : rezk_carrier} {a b : A}
(g : carrier (rezk_hom (elt b) c))
(f : carrier (rezk_hom (elt a) (elt b))) : carrier (rezk_hom (elt a) c) :=
begin
induction c using rezk.set_rec with c c c' ic,
exact g ∘ f,
{ apply arrow_pathover_left, intro d,
apply concato !pathover_rezk_hom_left_pt, apply pathover_idp_of_eq,
apply concat, apply assoc, apply ap (λ x, x ∘ f),
apply inverse, apply tr_eq_of_pathover, apply pathover_rezk_hom_left_pt },
end
definition rezk_comp_pt_pth [reducible] {c : rezk_carrier} {a b b' : A} {ib : iso b b'} :
pathover (λ b, carrier (rezk_hom b c) → carrier (rezk_hom (elt a) b) → carrier (rezk_hom (elt a) c))
(λ g f, rezk_comp_pt_pt g f) (pth ib) (λ g f, rezk_comp_pt_pt g f) :=
begin
apply arrow_pathover_left, intro x,
apply arrow_pathover_left, intro y,
induction c using rezk.set_rec with c c c' ic,
{ apply pathover_of_eq, apply inverse,
apply concat, apply ap (λ x, rezk_comp_pt_pt x _), apply tr_eq_of_pathover,
apply pathover_rezk_hom_left,
apply concat, apply ap (rezk_comp_pt_pt _), apply tr_eq_of_pathover,
apply pathover_rezk_hom_left_pt,
refine !assoc ⬝ ap (λ x, x ∘ y) _,
refine !assoc⁻¹ ⬝ _,
refine ap (λ y, x ∘ y) !iso.left_inverse ⬝ _,
apply id_right },
apply @is_prop.elimo
end
definition rezk_comp {a b c : @rezk_carrier A C} (g : rezk_hom b c) (f : rezk_hom a b) :
rezk_hom a c :=
begin
induction a using rezk.set_rec with a a a' ia,
{ induction b using rezk.set_rec with b b b' ib,
apply rezk_comp_pt_pt g f, apply rezk_comp_pt_pth },
{ induction b using rezk.set_rec with b b b' ib,
apply arrow_pathover_left, intro f,
induction c using rezk.set_rec with c c c' ic,
{ apply concato, apply pathover_rezk_hom_left,
apply pathover_idp_of_eq, refine !assoc⁻¹ ⬝ ap (λ x, g ∘ x) _⁻¹,
apply tr_eq_of_pathover, apply pathover_rezk_hom_left },
apply is_prop.elimo,
apply is_prop.elimo }
end
definition is_set_rezk_hom [instance] (a b : @rezk_carrier A C) : is_set (rezk_hom a b) :=
_
protected definition id_left {a b : @rezk_carrier A C} (f : rezk_hom a b) :
rezk_comp (rezk_id b) f = f :=
begin
induction a using rezk.prop_rec with a a a' ia,
induction b using rezk.prop_rec with b b b' ib,
apply id_left,
end
protected definition id_right {a b : @rezk_carrier A C} (f : rezk_hom a b) :
rezk_comp f (rezk_id a) = f :=
begin
induction a using rezk.prop_rec with a a a' ia,
induction b using rezk.prop_rec with b b b' ib,
apply id_right,
end
protected definition assoc {a b c d : @rezk_carrier A C} (h : rezk_hom c d)
(g : rezk_hom b c) (f : rezk_hom a b) :
rezk_comp h (rezk_comp g f) = rezk_comp (rezk_comp h g) f :=
begin
induction a using rezk.prop_rec with a a a' ia,
induction b using rezk.prop_rec with b b b' ib,
induction c using rezk.prop_rec with c c c' ic,
induction d using rezk.prop_rec with d d d' id,
apply assoc,
end
definition rezk_precategory [instance] : precategory (@rezk_carrier A C) :=
precategory.mk rezk_hom @rezk_comp rezk_id @assoc @id_left @id_right
end
definition to_rezk_Precategory.{l k} : Precategory.{l k} → Precategory.{(max l k) k} :=
begin
intro C, apply Precategory.mk (@rezk_carrier (Precategory.carrier C) C),
apply rezk_precategory _ _,
end
definition rezk_functor [constructor] (C : Precategory) : functor C (to_rezk_Precategory C) :=
begin
fapply functor.mk, apply elt,
{ intro a b f, exact f },
do 2 (intros; reflexivity)
end
section
parameters {A : Type} [C : precategory A]
include C
protected definition elt_iso_of_iso [reducible] {a b : A} (f : a ≅ b) : elt a ≅ elt b :=
begin
fapply iso.mk, apply to_hom f, apply functor.preserve_is_iso (rezk_functor _)
end
protected definition iso_of_elt_iso [reducible] {a b : A} (f : elt a ≅ elt b) : a ≅ b :=
begin
cases f with f Hf, cases Hf with inv linv rinv,
fapply iso.mk, exact f, fapply is_iso.mk, exact inv, exact linv, exact rinv
end
protected definition iso_of_elt_iso_distrib {a b c : A} (f : elt a ≅ elt b) (g : elt b ≅ elt c) :
iso_of_elt_iso (f ⬝i g) = (iso_of_elt_iso f) ⬝i (iso_of_elt_iso g) :=
begin
cases g with g Hg, cases Hg with invg linvg rinvg,
cases f with f Hf, cases Hf with invf linvf rinvf,
reflexivity
end
protected definition iso_equiv_elt_iso (a b : A) : (a ≅ b) ≃ (elt a ≅ elt b) :=
begin
fapply equiv.MK, apply elt_iso_of_iso, apply iso_of_elt_iso,
{ intro f, cases f with f Hf, cases Hf with inv linv rinv, fapply iso_eq, reflexivity },
{ intro f, fapply iso_eq, reflexivity }
end
private definition hom_transport_eq_transport_hom {a b b' : @rezk_carrier A C} (f : a ≅ b)
(p : b = b') : to_hom (transport (iso a) p f) = transport (λ x, hom _ _) p (to_hom f) :=
by cases p; reflexivity
private definition hom_transport_eq_transport_hom' {a a' b : @rezk_carrier A C} (f : a ≅ b)
(p : a = a') : to_hom (transport (λ x, iso x b) p f) = transport (λ x, hom _ _) p (to_hom f) :=
by cases p; reflexivity
private definition pathover_iso_pth {a b b' : A} (f : elt a ≅ elt b)
(ib : b ≅ b') : pathover (λ x, iso (elt a) x) f (pth ib) (f ⬝i elt_iso_of_iso ib) :=
begin
apply pathover_of_tr_eq, apply iso_eq,
apply concat, apply hom_transport_eq_transport_hom,
apply tr_eq_of_pathover, apply pathover_rezk_hom_right A C
end
private definition pathover_iso_pth' {a a' b : A} (f : elt a ≅ elt b)
(ia : a ≅ a') : pathover (λ x, iso x (elt b)) f (pth ia) (elt_iso_of_iso (iso.symm ia) ⬝i f) :=
begin
apply pathover_of_tr_eq, apply iso_eq,
apply concat, apply hom_transport_eq_transport_hom',
apply tr_eq_of_pathover, apply pathover_rezk_hom_left A C
end
private definition eq_of_iso_pt {a : A} {b : @rezk_carrier A C} :
elt a ≅ b → elt a = b :=
begin
intro f,
induction b using rezk.set_rec with b b b' ib,
apply pth, apply iso_of_elt_iso f,
apply arrow_pathover, intro f g p, apply eq_pathover,
refine !ap_constant ⬝ph _ ⬝hp !ap_id⁻¹, apply square_of_eq,
refine !resp_comp⁻¹ ⬝ (ap pth _)⁻¹ ⬝ !idp_con⁻¹,
apply concat, apply inverse, apply ap rezk.iso_of_elt_iso,
apply eq_of_parallel_po_right (pathover_iso_pth _ _) p,
apply concat, apply iso_of_elt_iso_distrib,
apply ap (λ x, _ ⬝i x), apply equiv.to_left_inv !iso_equiv_elt_iso
end
protected definition eq_of_iso {a b : @rezk_carrier A C} :
a ≅ b → a = b :=
begin
intro f,
induction a using rezk.set_rec with a a a' ia,
apply eq_of_iso_pt f,
{ induction b using rezk.set_rec with b b b' ib,
{ apply arrow_pathover, intro f g p, apply eq_pathover,
refine !ap_id ⬝ph _ ⬝hp !ap_constant⁻¹, apply square_of_eq,
refine (ap pth _) ⬝ !resp_comp,
assert H : g = (elt_iso_of_iso (iso.symm ia) ⬝i f),
apply eq_of_parallel_po_right p (pathover_iso_pth' _ _),
rewrite H, apply inverse,
apply concat, apply ap (λ x, ia ⬝i x), apply iso_of_elt_iso_distrib,
apply concat, apply ap (λ x, _ ⬝i (x ⬝i _)), apply equiv.to_left_inv !iso_equiv_elt_iso,
apply iso_eq, apply inverse_comp_cancel_right },
apply @is_prop.elimo }
end
protected definition eq_of_iso_of_eq (a b : @rezk_carrier A C) (p : a = b) :
eq_of_iso (iso_of_eq p) = p :=
begin
cases p, clear b,
induction a using rezk.prop_rec,
refine ap pth _ ⬝ !resp_id,
apply iso_eq, reflexivity
end
protected definition iso_of_eq_of_iso (a b : @rezk_carrier A C) (f : a ≅ b) :
iso_of_eq (eq_of_iso f) = f :=
begin
induction a using rezk.prop_rec with a,
induction b using rezk.prop_rec with b,
cases f with f Hf, apply iso_eq,
apply concat, apply ap to_hom, apply !transport_iso_of_eq⁻¹,
apply concat, apply ap to_hom, apply tr_eq_of_pathover, apply pathover_iso_pth,
cases Hf with invf linv rinv, apply id_right,
end
end
definition rezk_category.{l k} {A : Type.{l}} [C : precategory.{l k} A] :
category.{(max l k) k} (@rezk_carrier.{l k} A C) :=
begin
fapply category.mk (rezk_precategory A C),
intros, fapply is_equiv.adjointify,
apply rezk.eq_of_iso,
apply rezk.iso_of_eq_of_iso,
apply rezk.eq_of_iso_of_eq
end
section
variable (C : Precategory)
definition fully_faithful_rezk_functor : fully_faithful (rezk_functor C) :=
by intros; apply is_equiv.is_equiv_id
open trunc
definition essentially_surj_rezk_functor : essentially_surjective (rezk_functor C) :=
begin
intro a, esimp[to_rezk_Precategory] at *,
induction a using rezk.prop_rec with a, apply tr,
constructor, apply iso.refl (elt a),
end
definition is_weak_equiv_rezk_functor : is_weak_equivalence (rezk_functor C) :=
prod.mk (fully_faithful_rezk_functor C) (essentially_surj_rezk_functor C)
end
end rezk

View file

@ -1,101 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn, Jakob von Raumer
Category of sets
-/
import ..functor.basic ..category types.equiv types.lift
open eq category equiv iso is_equiv is_trunc function sigma
namespace category
definition precategory_Set.{u} [reducible] [constructor] : precategory Set.{u} :=
precategory.mk (λx y : Set, x → y)
(λx y z g f a, g (f a))
(λx a, a)
(λx y z w h g f, eq_of_homotopy (λa, idp))
(λx y f, eq_of_homotopy (λa, idp))
(λx y f, eq_of_homotopy (λa, idp))
definition Precategory_Set [reducible] [constructor] : Precategory :=
Precategory.mk Set precategory_Set
abbreviation set [constructor] := Precategory_Set
namespace set
local attribute is_equiv_subtype_eq [instance]
definition iso_of_equiv [constructor] {A B : set} (f : A ≃ B) : A ≅ B :=
iso.MK (to_fun f)
(to_inv f)
(eq_of_homotopy (left_inv (to_fun f)))
(eq_of_homotopy (right_inv (to_fun f)))
definition equiv_of_iso [constructor] {A B : set} (f : A ≅ B) : A ≃ B :=
begin
apply equiv.MK (to_hom f) (iso.to_inv f),
exact ap10 (to_right_inverse f),
exact ap10 (to_left_inverse f)
end
definition is_equiv_iso_of_equiv [constructor] (A B : set)
: is_equiv (@iso_of_equiv A B) :=
adjointify _ (λf, equiv_of_iso f)
(λf, proof iso_eq idp qed)
(λf, equiv_eq' idp)
local attribute is_equiv_iso_of_equiv [instance]
definition iso_of_eq_eq_compose (A B : Set) : @iso_of_eq _ _ A B =
@iso_of_equiv A B ∘ @equiv_of_eq A B ∘ subtype_eq_inv _ _ ∘
@ap _ _ (to_fun (trunctype.sigma_char 0)) A B :=
eq_of_homotopy (λp, eq.rec_on p idp)
definition equiv_equiv_iso (A B : set) : (A ≃ B) ≃ (A ≅ B) :=
equiv.MK (λf, iso_of_equiv f)
(λf, proof equiv.MK (to_hom f)
(iso.to_inv f)
(ap10 (to_right_inverse f))
(ap10 (to_left_inverse f)) qed)
(λf, proof iso_eq idp qed)
(λf, proof equiv_eq' idp qed)
definition equiv_eq_iso (A B : set) : (A ≃ B) = (A ≅ B) :=
ua !equiv_equiv_iso
definition is_univalent_Set (A B : set) : is_equiv (iso_of_eq : A = B → A ≅ B) :=
have H₁ : is_equiv (@iso_of_equiv A B ∘ @equiv_of_eq A B ∘ subtype_eq_inv _ _ ∘
@ap _ _ (to_fun (trunctype.sigma_char 0)) A B), from
@is_equiv_compose _ _ _ _ _
(@is_equiv_compose _ _ _ _ _
(@is_equiv_compose _ _ _ _ _
_
(@is_equiv_subtype_eq_inv _ _ _ _ _))
!univalence)
!is_equiv_iso_of_equiv,
let H₂ := (iso_of_eq_eq_compose A B)⁻¹ in
begin
rewrite H₂ at H₁,
assumption
end
end set
definition category_Set [instance] [constructor] : category Set :=
category.mk precategory_Set set.is_univalent_Set
definition Category_Set [reducible] [constructor] : Category :=
Category.mk Set category_Set
abbreviation cset [constructor] := Category_Set
open functor lift
definition functor_lift.{u v} [constructor] : set.{u} ⇒ set.{max u v} :=
functor.mk tlift
(λa b, lift_functor)
(λa, eq_of_homotopy (λx, by induction x; reflexivity))
(λa b c g f, eq_of_homotopy (λx, by induction x; reflexivity))
end category

View file

@ -1,112 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn, Jakob von Raumer
Sum precategory and (TODO) category
-/
import ..category ..nat_trans types.sum
open eq sum is_trunc functor lift nat_trans
namespace category
--set_option pp.universes true
definition sum_hom.{u v w x} [unfold 5 6] {obC : Type.{u}} {obD : Type.{v}}
(C : precategory.{u w} obC) (D : precategory.{v x} obD)
: obC + obD → obC + obD → Type.{max w x} :=
sum.rec (λc, sum.rec (λc', lift (c ⟶ c')) (λd, lift empty))
(λd, sum.rec (λc, lift empty) (λd', lift (d ⟶ d')))
theorem is_set_sum_hom {obC : Type} {obD : Type}
(C : precategory obC) (D : precategory obD) (x y : obC + obD)
: is_set (sum_hom C D x y) :=
by induction x: induction y: esimp at *: exact _
local attribute is_set_sum_hom [instance]
definition precategory_sum [constructor] [instance] (obC obD : Type)
[C : precategory obC] [D : precategory obD] : precategory (obC + obD) :=
precategory.mk (sum_hom C D)
(λ a b c g f, begin induction a: induction b: induction c: esimp at *;
induction f with f; induction g with g; (contradiction | exact up (g ∘ f)) end)
(λ a, by induction a: exact up id)
(λ a b c d h g f,
abstract begin induction a: induction b: induction c: induction d:
esimp at *; induction f with f; induction g with g; induction h with h;
esimp at *; try contradiction: apply ap up !assoc end end)
(λ a b f, abstract begin induction a: induction b: esimp at *;
induction f with f; esimp; try contradiction: exact ap up !id_left end end)
(λ a b f, abstract begin induction a: induction b: esimp at *;
induction f with f; esimp; try contradiction: exact ap up !id_right end end)
definition Precategory_sum [constructor] (C D : Precategory) : Precategory :=
precategory.Mk (precategory_sum C D)
infixr ` +c `:65 := Precategory_sum
variables {C C' D D' : Precategory}
definition inl_functor [constructor] : C ⇒ C +c D :=
functor.mk inl
(λa b, up)
(λa, idp)
(λa b c g f, idp)
definition inr_functor [constructor] : D ⇒ C +c D :=
functor.mk inr
(λa b, up)
(λa, idp)
(λa b c g f, idp)
definition sum_functor [constructor] (F : C ⇒ D) (G : C' ⇒ D) : C +c C' ⇒ D :=
begin
fapply functor.mk: esimp,
{ intro a, induction a, exact F a, exact G a},
{ intro a b f, induction a: induction b: esimp at *;
induction f with f; esimp; try contradiction: (exact F f|exact G f)},
{ exact abstract begin intro a, induction a: esimp; apply respect_id end end},
{ intros a b c g f, induction a: induction b: induction c: esimp at *;
induction f with f; induction g with g; try contradiction:
esimp; apply respect_comp}, -- REPORT: abstracting this argument fails
end
infixr ` +f `:65 := sum_functor
definition sum_functor_eta (F : C +c C' ⇒ D) : F ∘f inl_functor +f F ∘f inr_functor = F :=
begin
fapply functor_eq: esimp,
{ intro a, induction a: reflexivity},
{ exact abstract begin esimp, intro a b f,
induction a: induction b: esimp at *; induction f with f; esimp;
try contradiction: apply id_leftright end end}
end
definition sum_functor_inl (F : C ⇒ D) (G : C' ⇒ D) : (F +f G) ∘f inl_functor = F :=
begin
fapply functor_eq,
reflexivity,
esimp, intros, apply id_leftright
end
definition sum_functor_inr (F : C ⇒ D) (G : C' ⇒ D) : (F +f G) ∘f inr_functor = G :=
begin
fapply functor_eq,
reflexivity,
esimp, intros, apply id_leftright
end
definition sum_functor_sum [constructor] (F : C ⇒ D) (G : C' ⇒ D') : C +c C' ⇒ D +c D' :=
(inl_functor ∘f F) +f (inr_functor ∘f G)
definition sum_nat_trans [constructor] {F F' : C ⇒ D} {G G' : C' ⇒ D} (η : F ⟹ F') (θ : G ⟹ G')
: F +f G ⟹ F' +f G' :=
begin
fapply nat_trans.mk,
{ intro a, induction a: esimp, exact η a, exact θ a},
{ intro a b f, induction a: induction b: esimp at *; induction f with f; esimp;
try contradiction: apply naturality}
end
infixr ` +n `:65 := sum_nat_trans
end category

View file

@ -1,57 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
Terminal category
-/
import .indiscrete
open functor is_trunc unit eq
namespace category
definition terminal_precategory [constructor] : precategory unit :=
indiscrete_precategory unit
definition Terminal_precategory [constructor] : Precategory :=
precategory.Mk terminal_precategory
notation 1 := Terminal_precategory
definition one_op : 1ᵒᵖ = 1 := idp
definition terminal_functor [constructor] (C : Precategory) : C ⇒ 1 :=
functor.mk (λx, star)
(λx y f, star)
(λx, idp)
(λx y z g f, idp)
definition is_contr_functor_one [instance] (C : Precategory) : is_contr (C ⇒ 1) :=
is_contr.mk (terminal_functor C)
begin
intro F, fapply functor_eq,
{ intro x, apply @is_prop.elim unit},
{ intro x y f, apply @is_prop.elim unit}
end
definition terminal_functor_op (C : Precategory)
: (terminal_functor C)ᵒᵖᶠ = terminal_functor Cᵒᵖ := idp
definition terminal_functor_comp {C D : Precategory} (F : C ⇒ D)
: (terminal_functor D) ∘f F = terminal_functor C := idp
definition point [constructor] (C : Precategory) (c : C) : 1 ⇒ C :=
functor.mk (λx, c)
(λx y f, id)
(λx, idp)
(λx y z g f, !id_id⁻¹)
-- we need id_id in the declaration of precategory to make this to hold definitionally
definition point_op (C : Precategory) (c : C) : (point C c)ᵒᵖᶠ = point Cᵒᵖ c := idp
definition point_comp {C D : Precategory} (F : C ⇒ D) (c : C)
: F ∘f point C c = point D (F c) := idp
end category

View file

@ -1,7 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
-/
import .category .strict .groupoid .constructions .limits .functor

View file

@ -1,274 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
Adjoint functors
-/
import .attributes .examples
open functor nat_trans is_trunc eq iso prod
namespace category
structure adjoint {C D : Precategory} (F : C ⇒ D) (G : D ⇒ C) :=
(η : 1 ⟹ G ∘f F)
(ε : F ∘f G ⟹ 1)
(H : Π(c : C), ε (F c) ∘ F (η c) = ID (F c))
(K : Π(d : D), G (ε d) ∘ η (G d) = ID (G d))
abbreviation to_unit [unfold 5] := @adjoint.η
abbreviation to_counit [unfold 5] := @adjoint.ε
abbreviation to_counit_unit_eq [unfold 5] := @adjoint.H
abbreviation to_unit_counit_eq [unfold 5] := @adjoint.K
-- TODO: define is_left_adjoint in terms of adjoint:
-- structure is_left_adjoint (F : C ⇒ D) :=
-- (G : D ⇒ C) -- G
-- (is_adjoint : adjoint F G)
infix ` ⊣ `:55 := adjoint
structure is_left_adjoint [class] {C D : Precategory} (F : C ⇒ D) :=
(G : D ⇒ C)
(η : 1 ⟹ G ∘f F)
(ε : F ∘f G ⟹ 1)
(H : Π(c : C), ε (F c) ∘ F (η c) = ID (F c))
(K : Π(d : D), G (ε d) ∘ η (G d) = ID (G d))
abbreviation right_adjoint [unfold 4] := @is_left_adjoint.G
abbreviation unit [unfold 4] := @is_left_adjoint.η
abbreviation counit [unfold 4] := @is_left_adjoint.ε
abbreviation counit_unit_eq [unfold 4] := @is_left_adjoint.H
abbreviation unit_counit_eq [unfold 4] := @is_left_adjoint.K
theorem is_prop_is_left_adjoint [instance] {C : Category} {D : Precategory} (F : C ⇒ D)
: is_prop (is_left_adjoint F) :=
begin
apply is_prop.mk,
intro G G', cases G with G η ε H K, cases G' with G' η' ε' H' K',
have lem₁ : Π(p : G = G'), p ▸ η = η' → p ▸ ε = ε'
→ is_left_adjoint.mk G η ε H K = is_left_adjoint.mk G' η' ε' H' K',
begin
intros p q r, induction p, induction q, induction r, esimp,
apply apd011 (is_left_adjoint.mk G η ε) !is_prop.elim !is_prop.elimo
end,
have lem₂ : Π (d : carrier D),
(to_fun_hom G (natural_map ε' d) ∘
natural_map η (to_fun_ob G' d)) ∘
to_fun_hom G' (natural_map ε d) ∘
natural_map η' (to_fun_ob G d) = id,
begin
intro d, esimp,
rewrite [assoc],
rewrite [-assoc (G (ε' d))],
esimp, rewrite [nf_fn_eq_fn_nf_pt' G' ε η d],
esimp, rewrite [assoc],
esimp, rewrite [-assoc],
rewrite [↑functor.compose, -respect_comp G],
rewrite [nf_fn_eq_fn_nf_pt ε ε' d,nf_fn_eq_fn_nf_pt η' η (G d),▸*],
rewrite [respect_comp G],
rewrite [assoc,▸*,-assoc (G (ε d))],
rewrite [↑functor.compose, -respect_comp G],
rewrite [H' (G d)],
rewrite [respect_id,▸*,id_right],
apply K
end,
have lem₃ : Π (d : carrier D),
(to_fun_hom G' (natural_map ε d) ∘
natural_map η' (to_fun_ob G d)) ∘
to_fun_hom G (natural_map ε' d) ∘
natural_map η (to_fun_ob G' d) = id,
begin
intro d, esimp,
rewrite [assoc, -assoc (G' (ε d))],
esimp, rewrite [nf_fn_eq_fn_nf_pt' G ε' η' d],
esimp, rewrite [assoc], esimp, rewrite [-assoc],
rewrite [↑functor.compose, -respect_comp G'],
rewrite [nf_fn_eq_fn_nf_pt ε' ε d,nf_fn_eq_fn_nf_pt η η' (G' d)],
esimp,
rewrite [respect_comp G'],
rewrite [assoc,▸*,-assoc (G' (ε' d))],
rewrite [↑functor.compose, -respect_comp G'],
rewrite [H (G' d)],
rewrite [respect_id,▸*,id_right],
apply K'
end,
fapply lem₁,
{ fapply functor.eq_of_pointwise_iso,
{ fapply change_natural_map,
{ exact (G' ∘fn1 ε) ∘n !assoc_natural_rev ∘n (η' ∘1nf G)},
{ intro d, exact (G' (ε d) ∘ η' (G d))},
{ intro d, exact ap (λx, _ ∘ x) !id_left}},
{ intro d, fconstructor,
{ exact (G (ε' d) ∘ η (G' d))},
{ exact lem₂ d },
{ exact lem₃ d }}},
{ clear lem₁, refine transport_hom_of_eq_right _ η ⬝ _,
krewrite hom_of_eq_compose_right,
rewrite functor.hom_of_eq_eq_of_pointwise_iso,
apply nat_trans_eq, intro c, esimp,
refine !assoc⁻¹ ⬝ ap (λx, _ ∘ x) (nf_fn_eq_fn_nf_pt η η' c) ⬝ !assoc ⬝ _,
esimp, rewrite [-respect_comp G',H c,respect_id G',▸*,id_left]},
{ clear lem₁, refine transport_hom_of_eq_left _ ε ⬝ _,
krewrite inv_of_eq_compose_left,
rewrite functor.inv_of_eq_eq_of_pointwise_iso,
apply nat_trans_eq, intro d, esimp,
krewrite [respect_comp],
rewrite [assoc,nf_fn_eq_fn_nf_pt ε' ε d,-assoc,▸*,H (G' d),id_right]}
end
section
universe variables u v w
parameters {C : Precategory.{u v}} {D : Precategory.{w v}} {F : C ⇒ D} {G : D ⇒ C}
(θ : hom_functor D ∘f prod_functor_prod Fᵒᵖᶠ 1 ≅ hom_functor C ∘f prod_functor_prod 1 G)
include θ
definition adj_unit [constructor] : 1 ⟹ G ∘f F :=
begin
fapply nat_trans.mk: esimp,
{ intro c, exact natural_map (to_hom θ) (c, F c) id},
{ intro c c' f,
note H := naturality (to_hom θ) (ID c, F f),
note K := ap10 H id,
rewrite [▸* at K, id_right at K, ▸*, K, respect_id, +id_right],
clear H K,
note H := naturality (to_hom θ) (f, ID (F c')),
note K := ap10 H id,
rewrite [▸* at K, respect_id at K,+id_left at K, K]}
end
definition adj_counit [constructor] : F ∘f G ⟹ 1 :=
begin
fapply nat_trans.mk: esimp,
{ intro d, exact natural_map (to_inv θ) (G d, d) id, },
{ intro d d' g,
note H := naturality (to_inv θ) (Gᵒᵖᶠ g, ID d'),
note K := ap10 H id,
rewrite [▸* at K, id_left at K, ▸*, K, respect_id, +id_left],
clear H K,
note H := naturality (to_inv θ) (ID (G d), g),
note K := ap10 H id,
rewrite [▸* at K, respect_id at K,+id_right at K, K]}
end
theorem adj_eq_unit (c : C) (d : D) (f : F c ⟶ d)
: natural_map (to_hom θ) (c, d) f = G f ∘ adj_unit c :=
begin
esimp,
note H := naturality (to_hom θ) (ID c, f),
note K := ap10 H id,
rewrite [▸* at K, id_right at K, K, respect_id, +id_right],
end
theorem adj_eq_counit (c : C) (d : D) (g : c ⟶ G d)
: natural_map (to_inv θ) (c, d) g = adj_counit d ∘ F g :=
begin
esimp,
note H := naturality (to_inv θ) (g, ID d),
note K := ap10 H id,
rewrite [▸* at K, id_left at K, K, respect_id, +id_left],
end
definition adjoint.mk' [constructor] : F ⊣ G :=
begin
fapply adjoint.mk,
{ exact adj_unit},
{ exact adj_counit},
{ intro c, esimp, refine (adj_eq_counit c (F c) (adj_unit c))⁻¹ ⬝ _,
apply ap10 (to_left_inverse (componentwise_iso θ (c, F c)))},
{ intro d, esimp, refine (adj_eq_unit (G d) d (adj_counit d))⁻¹ ⬝ _,
apply ap10 (to_right_inverse (componentwise_iso θ (G d, d)))},
end
end
/- TODO (below): generalize above definitions to arbitrary categories
section
universe variables u₁ u₂ v₁ v₂
parameters {C : Precategory.{u₁ v₁}} {D : Precategory.{u₂ v₂}} {F : C ⇒ D} {G : D ⇒ C}
(θ : functor_lift.{v₂ v₁} ∘f hom_functor D ∘f prod_functor_prod Fᵒᵖᶠ 1 ≅
functor_lift.{v₁ v₂} ∘f hom_functor C ∘f prod_functor_prod 1 G)
include θ
open lift
definition adj_unit [constructor] : 1 ⟹ G ∘f F :=
begin
fapply nat_trans.mk: esimp,
{ intro c, exact down (natural_map (to_hom θ) (c, F c) (up id))},
{ intro c c' f,
let H := naturality (to_hom θ) (ID c, F f),
let K := ap10 H (up id),
rewrite [▸* at K, id_right at K, ▸*, K, respect_id, +id_right],
clear H K,
let H := naturality (to_hom θ) (f, ID (F c')),
let K := ap10 H id,
rewrite [▸* at K, respect_id at K,+id_left at K, K]}
end
definition adj_counit [constructor] : F ∘f G ⟹ 1 :=
begin
fapply nat_trans.mk: esimp,
{ intro d, exact natural_map (to_inv θ) (G d, d) id, },
{ intro d d' g,
let H := naturality (to_inv θ) (Gᵒᵖᶠ g, ID d'),
let K := ap10 H id,
rewrite [▸* at K, id_left at K, ▸*, K, respect_id, +id_left],
clear H K,
let H := naturality (to_inv θ) (ID (G d), g),
let K := ap10 H id,
rewrite [▸* at K, respect_id at K,+id_right at K, K]}
end
theorem adj_eq_unit (c : C) (d : D) (f : F c ⟶ d)
: natural_map (to_hom θ) (c, d) (up f) = G f ∘ adj_unit c :=
begin
esimp,
let H := naturality (to_hom θ) (ID c, f),
let K := ap10 H id,
rewrite [▸* at K, id_right at K, K, respect_id, +id_right],
end
theorem adj_eq_counit (c : C) (d : D) (g : c ⟶ G d)
: natural_map (to_inv θ) (c, d) (up g) = adj_counit d ∘ F g :=
begin
esimp,
let H := naturality (to_inv θ) (g, ID d),
let K := ap10 H id,
rewrite [▸* at K, id_left at K, K, respect_id, +id_left],
end
definition adjoint.mk' [constructor] : F ⊣ G :=
begin
fapply adjoint.mk,
{ exact adj_unit},
{ exact adj_counit},
{ intro c, esimp, refine (adj_eq_counit c (F c) (adj_unit c))⁻¹ ⬝ _,
apply ap10 (to_left_inverse (componentwise_iso θ (c, F c)))},
{ intro d, esimp, refine (adj_eq_unit (G d) d (adj_counit d))⁻¹ ⬝ _,
apply ap10 (to_right_inverse (componentwise_iso θ (G d, d)))},
end
end
-/
variables {C D : Precategory} {F : C ⇒ D} {G : D ⇒ C}
definition adjoint_opposite [constructor] (H : F ⊣ G) : Gᵒᵖᶠ ⊣ Fᵒᵖᶠ :=
begin
fconstructor,
{ rexact opposite_nat_trans (to_counit H)},
{ rexact opposite_nat_trans (to_unit H)},
{ rexact to_unit_counit_eq H},
{ rexact to_counit_unit_eq H}
end
definition adjoint_of_opposite [constructor] (H : Fᵒᵖᶠ ⊣ Gᵒᵖᶠ) : G ⊣ F :=
begin
fconstructor,
{ rexact opposite_rev_nat_trans (to_counit H)},
{ rexact opposite_rev_nat_trans (to_unit H)},
{ rexact to_unit_counit_eq H},
{ rexact to_counit_unit_eq H}
end
end category

View file

@ -1,39 +0,0 @@
import .equivalence
open eq functor nat_trans
namespace category
variables {C D E : Precategory} (F : C ⇒ D) (G : D ⇒ C) (H : D ≅c E)
/-
definition adjoint_compose [constructor] (K : F ⊣ G)
: H ∘f F ⊣ G ∘f H⁻¹ᴱ :=
begin
fconstructor,
{ fapply change_natural_map,
{ exact calc
1 ⟹ G ∘f F : to_unit K
... ⟹ (G ∘f 1) ∘f F : !id_right_natural_rev ∘nf F
... ⟹ (G ∘f (H⁻¹ ∘f H)) ∘f F : (G ∘fn unit H) ∘nf F
... ⟹ ((G ∘f H⁻¹) ∘f H) ∘f F : !assoc_natural ∘nf F
... ⟹ (G ∘f H⁻¹) ∘f (H ∘f F) : assoc_natural_rev},
{ intro c, esimp, exact G (unit H (F c)) ∘ to_unit K c},
{ intro c, rewrite [▸*, +id_left]}},
{ fapply change_natural_map,
{ exact calc
(H ∘f F) ∘f (G ∘f H⁻¹)
⟹ ((H ∘f F) ∘f G) ∘f H⁻¹ : assoc_natural
... ⟹ (H ∘f (F ∘f G)) ∘f H⁻¹ : !assoc_natural_rev ∘nf H⁻¹
... ⟹ (H ∘f 1) ∘f H⁻¹ : (H ∘fn to_counit K) ∘nf H⁻¹
... ⟹ H ∘f H⁻¹ : !id_right_natural ∘nf H⁻¹
... ⟹ 1 : counit H},
{ intro e, esimp, exact counit H e ∘ to_fun_hom H (to_counit K (H⁻¹ e))},
{ intro c, rewrite [▸*, +id_right, +id_left]}},
{ intro c, rewrite [▸*, +respect_comp], refine !assoc ⬝ ap (λx, x ∘ _) !assoc⁻¹ ⬝ _,
rewrite [-respect_comp],
},
{ }
end
-/
end category

View file

@ -1,198 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
Attributes of functors (full, faithful, split essentially surjective, ...)
Adjoint functors, isomorphisms and equivalences have their own file
-/
import .basic function arity
open eq functor trunc prod is_equiv iso equiv function is_trunc sigma
namespace category
variables {C D E : Precategory} {F : C ⇒ D} {G : D ⇒ C}
definition faithful [class] (F : C ⇒ D) := Π⦃c c' : C⦄ ⦃f f' : c ⟶ c'⦄, F f = F f' → f = f'
definition full [class] (F : C ⇒ D) := Π⦃c c' : C⦄, is_surjective (@(to_fun_hom F) c c')
definition fully_faithful [class] (F : C ⇒ D) := Π(c c' : C), is_equiv (@(to_fun_hom F) c c')
definition split_essentially_surjective [class] (F : C ⇒ D) := Π(d : D), Σ(c : C), F c ≅ d
definition essentially_surjective [class] (F : C ⇒ D) := Π(d : D), ∃(c : C), F c ≅ d
definition is_weak_equivalence [class] (F : C ⇒ D) :=
fully_faithful F × essentially_surjective F
definition is_equiv_of_fully_faithful [instance] (F : C ⇒ D)
[H : fully_faithful F] (c c' : C) : is_equiv (@(to_fun_hom F) c c') :=
!H
definition fully_faithful_of_is_weak_equivalence [instance] (F : C ⇒ D)
[H : is_weak_equivalence F] : fully_faithful F :=
pr1 H
definition essentially_surjective_of_is_weak_equivalence [instance] (F : C ⇒ D)
[H : is_weak_equivalence F] : essentially_surjective F :=
pr2 H
definition hom_inv [reducible] (F : C ⇒ D) [H : fully_faithful F] {c c' : C} (f : F c ⟶ F c')
: c ⟶ c' :=
(to_fun_hom F)⁻¹ᶠ f
definition hom_inv_respect_id (F : C ⇒ D) [H : fully_faithful F] (c : C) :
hom_inv F (ID (F c)) = id :=
begin
apply eq_of_fn_eq_fn' (to_fun_hom F),
exact !(right_inv (to_fun_hom F)) ⬝ !respect_id⁻¹,
end
definition hom_inv_respect_comp (F : C ⇒ D) [H : fully_faithful F] {a b c : C}
(g : F b ⟶ F c) (f : F a ⟶ F b) : hom_inv F (g ∘ f) = hom_inv F g ∘ hom_inv F f :=
begin
apply eq_of_fn_eq_fn' (to_fun_hom F),
refine !(right_inv (to_fun_hom F)) ⬝ _ ⬝ !respect_comp⁻¹,
rewrite [right_inv (to_fun_hom F), right_inv (to_fun_hom F)],
end
definition reflect_is_iso [constructor] (F : C ⇒ D) [H : fully_faithful F] {c c' : C}
(f : c ⟶ c') [H : is_iso (F f)] : is_iso f :=
begin
fconstructor,
{ exact (to_fun_hom F)⁻¹ᶠ (F f)⁻¹},
{ apply eq_of_fn_eq_fn' (to_fun_hom F),
rewrite [respect_comp,right_inv (to_fun_hom F),respect_id,left_inverse]},
{ apply eq_of_fn_eq_fn' (to_fun_hom F),
rewrite [respect_comp,right_inv (to_fun_hom F),respect_id,right_inverse]},
end
definition reflect_iso [constructor] (F : C ⇒ D) [H : fully_faithful F] {c c' : C}
(f : F c ≅ F c') : c ≅ c' :=
begin
fconstructor,
{ exact (to_fun_hom F)⁻¹ᶠ f},
{ have H : is_iso (F ((to_fun_hom F)⁻¹ᶠ f)), from
have H' : is_iso (to_hom f), from _,
(right_inv (to_fun_hom F) (to_hom f))⁻¹ ▸ H',
exact reflect_is_iso F _},
end
theorem reflect_inverse (F : C ⇒ D) [H : fully_faithful F] {c c' : C} (f : c ⟶ c')
[H' : is_iso f] : (to_fun_hom F)⁻¹ᶠ (F f)⁻¹ = f⁻¹ :=
@inverse_eq_inverse _ _ _ _ _ _ (reflect_is_iso F f) H' idp
definition hom_equiv_F_hom_F [constructor] (F : C ⇒ D)
[H : fully_faithful F] (c c' : C) : (c ⟶ c') ≃ (F c ⟶ F c') :=
equiv.mk _ !H
definition iso_equiv_F_iso_F [constructor] (F : C ⇒ D)
[H : fully_faithful F] (c c' : C) : (c ≅ c') ≃ (F c ≅ F c') :=
begin
fapply equiv.MK,
{ exact to_fun_iso F},
{ apply reflect_iso F},
{ exact abstract begin
intro f, induction f with f F', induction F' with g p q, apply iso_eq,
esimp [reflect_iso], apply right_inv end end},
{ exact abstract begin
intro f, induction f with f F', induction F' with g p q, apply iso_eq,
esimp [reflect_iso], apply right_inv end end},
end
definition full_of_fully_faithful [instance] (F : C ⇒ D) [H : fully_faithful F] : full F :=
λc c' g, tr (fiber.mk ((@(to_fun_hom F) c c')⁻¹ᶠ g) !right_inv)
definition faithful_of_fully_faithful [instance] (F : C ⇒ D) [H : fully_faithful F]
: faithful F :=
λc c' f f' p, is_injective_of_is_embedding p
definition is_embedding_of_faithful [instance] (F : C ⇒ D) [H : faithful F] (c c' : C)
: is_embedding (to_fun_hom F : c ⟶ c' → F c ⟶ F c') :=
begin
apply is_embedding_of_is_injective,
apply H
end
definition is_surjective_of_full [instance] (F : C ⇒ D) [H : full F] (c c' : C)
: is_surjective (to_fun_hom F : c ⟶ c' → F c ⟶ F c') :=
@H c c'
definition fully_faithful_of_full_of_faithful (H : faithful F) (K : full F)
: fully_faithful F :=
begin
intro c c',
apply is_equiv_of_is_surjective_of_is_embedding,
end
theorem is_prop_fully_faithful [instance] (F : C ⇒ D) : is_prop (fully_faithful F) :=
by unfold fully_faithful; exact _
theorem is_prop_full [instance] (F : C ⇒ D) : is_prop (full F) :=
by unfold full; exact _
theorem is_prop_faithful [instance] (F : C ⇒ D) : is_prop (faithful F) :=
by unfold faithful; exact _
theorem is_prop_essentially_surjective [instance] (F : C ⇒ D)
: is_prop (essentially_surjective F) :=
by unfold essentially_surjective; exact _
definition essentially_surjective_of_split_essentially_surjective [instance] (F : C ⇒ D)
[H : split_essentially_surjective F] : essentially_surjective F :=
λd, tr (H d)
definition fully_faithful_equiv (F : C ⇒ D) : fully_faithful F ≃ (faithful F × full F) :=
equiv_of_is_prop (λH, (faithful_of_fully_faithful F, full_of_fully_faithful F))
(λH, fully_faithful_of_full_of_faithful (pr1 H) (pr2 H))
/- alternative proof using direct calculation with equivalences
definition fully_faithful_equiv (F : C ⇒ D) : fully_faithful F ≃ (faithful F × full F) :=
calc
fully_faithful F
≃ (Π(c c' : C), is_embedding (to_fun_hom F) × is_surjective (to_fun_hom F))
: pi_equiv_pi_right (λc, pi_equiv_pi_right
(λc', !is_equiv_equiv_is_embedding_times_is_surjective))
... ≃ (Π(c : C), (Π(c' : C), is_embedding (to_fun_hom F)) ×
(Π(c' : C), is_surjective (to_fun_hom F)))
: pi_equiv_pi_right (λc, !equiv_prod_corec)
... ≃ (Π(c c' : C), is_embedding (to_fun_hom F)) × full F
: equiv_prod_corec
... ≃ faithful F × full F
: prod_equiv_prod_right (pi_equiv_pi_right (λc, pi_equiv_pi_right
(λc', !is_embedding_equiv_is_injective)))
-/
definition fully_faithful_compose (G : D ⇒ E) (F : C ⇒ D) [fully_faithful G] [fully_faithful F] :
fully_faithful (G ∘f F) :=
λc c', is_equiv_compose (to_fun_hom G) (to_fun_hom F)
definition full_compose (G : D ⇒ E) (F : C ⇒ D) [full G] [full F] : full (G ∘f F) :=
λc c', is_surjective_compose (to_fun_hom G) (to_fun_hom F) _ _
definition faithful_compose (G : D ⇒ E) (F : C ⇒ D) [H₁ : faithful G] [H₂ : faithful F] :
faithful (G ∘f F) :=
λc c' f f' p, H₂ (H₁ p)
definition essentially_surjective_compose (G : D ⇒ E) (F : C ⇒ D) [H₁ : essentially_surjective G]
[H₂ : essentially_surjective F] : essentially_surjective (G ∘f F) :=
begin
intro e,
induction H₁ e with v, induction v with d p,
induction H₂ d with w, induction w with c q,
exact exists.intro c (to_fun_iso G q ⬝i p)
end
definition split_essentially_surjective_compose (G : D ⇒ E) (F : C ⇒ D)
[H₁ : split_essentially_surjective G] [H₂ : split_essentially_surjective F]
: split_essentially_surjective (G ∘f F) :=
begin
intro e, induction H₁ e with d p, induction H₂ d with c q,
exact ⟨c, to_fun_iso G q ⬝i p⟩
end
/- we get the fact that the identity functor satisfies all these properties via the fact that it
is an isomorphism -/
end category

View file

@ -1,301 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn, Jakob von Raumer
-/
import ..iso types.pi
open function category eq prod prod.ops equiv is_equiv sigma sigma.ops is_trunc funext iso pi
structure functor (C D : Precategory) : Type :=
(to_fun_ob : C → D)
(to_fun_hom : Π {a b : C}, hom a b → hom (to_fun_ob a) (to_fun_ob b))
(respect_id : Π (a : C), to_fun_hom (ID a) = ID (to_fun_ob a))
(respect_comp : Π {a b c : C} (g : hom b c) (f : hom a b),
to_fun_hom (g ∘ f) = to_fun_hom g ∘ to_fun_hom f)
namespace functor
infixl ` ⇒ `:55 := functor
variables {A B C D E : Precategory}
attribute to_fun_ob [coercion]
attribute to_fun_hom [coercion]
-- The following lemmas will later be used to prove that the type of
-- precategories forms a precategory itself
protected definition compose [reducible] [constructor] (G : functor D E) (F : functor C D)
: functor C E :=
functor.mk
(λ x, G (F x))
(λ a b f, G (F f))
(λ a, abstract calc
G (F (ID a)) = G (ID (F a)) : by rewrite respect_id
... = ID (G (F a)) : by rewrite respect_id end)
(λ a b c g f, abstract calc
G (F (g ∘ f)) = G (F g ∘ F f) : by rewrite respect_comp
... = G (F g) ∘ G (F f) : by rewrite respect_comp end)
infixr ` ∘f `:75 := functor.compose
protected definition id [reducible] [constructor] {C : Precategory} : functor C C :=
mk (λa, a) (λ a b f, f) (λ a, idp) (λ a b c f g, idp)
protected definition ID [reducible] [constructor] (C : Precategory) : functor C C := @functor.id C
notation 1 := functor.id
definition constant_functor [constructor] (C : Precategory) {D : Precategory} (d : D) : C ⇒ D :=
functor.mk (λc, d)
(λc c' f, id)
(λc, idp)
(λa b c g f, !id_id⁻¹)
/- introduction rule for equalities between functors -/
definition functor_mk_eq' {F₁ F₂ : C → D} {H₁ : Π(a b : C), hom a b → hom (F₁ a) (F₁ b)}
{H₂ : Π(a b : C), hom a b → hom (F₂ a) (F₂ b)} (id₁ id₂ comp₁ comp₂)
(pF : F₁ = F₂) (pH : pF ▸ H₁ = H₂)
: functor.mk F₁ H₁ id₁ comp₁ = functor.mk F₂ H₂ id₂ comp₂ :=
apdt01111 functor.mk pF pH !is_prop.elim !is_prop.elim
definition functor_eq' {F₁ F₂ : C ⇒ D} : Π(p : to_fun_ob F₁ = to_fun_ob F₂),
(transport (λx, Πa b f, hom (x a) (x b)) p @(to_fun_hom F₁) = @(to_fun_hom F₂)) → F₁ = F₂ :=
by induction F₁; induction F₂; apply functor_mk_eq'
definition functor_mk_eq {F₁ F₂ : C → D} {H₁ : Π(a b : C), hom a b → hom (F₁ a) (F₁ b)}
{H₂ : Π(a b : C), hom a b → hom (F₂ a) (F₂ b)} (id₁ id₂ comp₁ comp₂) (pF : F₁ ~ F₂)
(pH : Π(a b : C) (f : hom a b), hom_of_eq (pF b) ∘ H₁ a b f ∘ inv_of_eq (pF a) = H₂ a b f)
: functor.mk F₁ H₁ id₁ comp₁ = functor.mk F₂ H₂ id₂ comp₂ :=
begin
fapply functor_mk_eq',
{ exact eq_of_homotopy pF},
{ refine eq_of_homotopy (λc, eq_of_homotopy (λc', eq_of_homotopy (λf, _))), intros,
rewrite [+pi_transport_constant,-pH,-transport_hom]}
end
definition functor_eq {F₁ F₂ : C ⇒ D} : Π(p : to_fun_ob F₁ ~ to_fun_ob F₂),
(Π(a b : C) (f : hom a b), hom_of_eq (p b) ∘ F₁ f ∘ inv_of_eq (p a) = F₂ f) → F₁ = F₂ :=
by induction F₁; induction F₂; apply functor_mk_eq
definition functor_mk_eq_constant {F : C → D} {H₁ : Π(a b : C), hom a b → hom (F a) (F b)}
{H₂ : Π(a b : C), hom a b → hom (F a) (F b)} (id₁ id₂ comp₁ comp₂)
(pH : Π(a b : C) (f : hom a b), H₁ a b f = H₂ a b f)
: functor.mk F H₁ id₁ comp₁ = functor.mk F H₂ id₂ comp₂ :=
functor_eq (λc, idp) (λa b f, !id_leftright ⬝ !pH)
definition preserve_is_iso [constructor] (F : C ⇒ D) {a b : C} (f : hom a b) [H : is_iso f]
: is_iso (F f) :=
begin
fapply @is_iso.mk, apply (F (f⁻¹)),
repeat (apply concat ; symmetry ; apply (respect_comp F) ;
apply concat ; apply (ap (λ x, to_fun_hom F x)) ;
(apply iso.left_inverse | apply iso.right_inverse);
apply (respect_id F) ),
end
theorem respect_inv (F : C ⇒ D) {a b : C} (f : hom a b) [H : is_iso f] [H' : is_iso (F f)] :
F (f⁻¹) = (F f)⁻¹ :=
begin
fapply @left_inverse_eq_right_inverse, apply (F f),
transitivity to_fun_hom F (f⁻¹ ∘ f),
{symmetry, apply (respect_comp F)},
{transitivity to_fun_hom F category.id,
{congruence, apply iso.left_inverse},
{apply respect_id}},
apply iso.right_inverse
end
attribute preserve_is_iso [instance] [priority 100]
definition to_fun_iso [constructor] (F : C ⇒ D) {a b : C} (f : a ≅ b) : F a ≅ F b :=
iso.mk (F f) _
theorem respect_inv' (F : C ⇒ D) {a b : C} (f : hom a b) {H : is_iso f} : F (f⁻¹) = (F f)⁻¹ :=
respect_inv F f
theorem respect_refl (F : C ⇒ D) (a : C) : to_fun_iso F (iso.refl a) = iso.refl (F a) :=
iso_eq !respect_id
theorem respect_symm (F : C ⇒ D) {a b : C} (f : a ≅ b)
: to_fun_iso F f⁻¹ⁱ = (to_fun_iso F f)⁻¹ⁱ :=
iso_eq !respect_inv
theorem respect_trans (F : C ⇒ D) {a b c : C} (f : a ≅ b) (g : b ≅ c)
: to_fun_iso F (f ⬝i g) = to_fun_iso F f ⬝i to_fun_iso F g :=
iso_eq !respect_comp
definition respect_iso_of_eq (F : C ⇒ D) {a b : C} (p : a = b) :
to_fun_iso F (iso_of_eq p) = iso_of_eq (ap F p) :=
by induction p; apply respect_refl
theorem respect_hom_of_eq (F : C ⇒ D) {a b : C} (p : a = b) :
F (hom_of_eq p) = hom_of_eq (ap F p) :=
by induction p; apply respect_id
definition respect_inv_of_eq (F : C ⇒ D) {a b : C} (p : a = b) :
F (inv_of_eq p) = inv_of_eq (ap F p) :=
by induction p; apply respect_id
protected definition assoc (H : C ⇒ D) (G : B ⇒ C) (F : A ⇒ B) :
H ∘f (G ∘f F) = (H ∘f G) ∘f F :=
!functor_mk_eq_constant (λa b f, idp)
protected definition id_left (F : C ⇒ D) : 1 ∘f F = F :=
functor.rec_on F (λF1 F2 F3 F4, !functor_mk_eq_constant (λa b f, idp))
protected definition id_right (F : C ⇒ D) : F ∘f 1 = F :=
functor.rec_on F (λF1 F2 F3 F4, !functor_mk_eq_constant (λa b f, idp))
protected definition comp_id_eq_id_comp (F : C ⇒ D) : F ∘f 1 = 1 ∘f F :=
!functor.id_right ⬝ !functor.id_left⁻¹
definition functor_of_eq [constructor] {C D : Precategory} (p : C = D :> Precategory) : C ⇒ D :=
functor.mk (transport carrier p)
(λa b f, by induction p; exact f)
(by intro c; induction p; reflexivity)
(by intros; induction p; reflexivity)
protected definition sigma_char :
(Σ (to_fun_ob : C → D)
(to_fun_hom : Π ⦃a b : C⦄, hom a b → hom (to_fun_ob a) (to_fun_ob b)),
(Π (a : C), to_fun_hom (ID a) = ID (to_fun_ob a)) ×
(Π {a b c : C} (g : hom b c) (f : hom a b),
to_fun_hom (g ∘ f) = to_fun_hom g ∘ to_fun_hom f)) ≃ (functor C D) :=
begin
fapply equiv.MK,
{intro S, induction S with d1 S2, induction S2 with d2 P1, induction P1 with P11 P12,
exact functor.mk d1 d2 P11 @P12},
{intro F, induction F with d1 d2 d3 d4, exact ⟨d1, @d2, (d3, @d4)⟩},
{intro F, induction F, reflexivity},
{intro S, induction S with d1 S2, induction S2 with d2 P1, induction P1, reflexivity},
end
definition change_fun [constructor] (F : C ⇒ D) (Fob : C → D)
(Fhom : Π⦃c c' : C⦄ (f : c ⟶ c'), Fob c ⟶ Fob c') (p : F = Fob) (q : F =[p] Fhom) : C ⇒ D :=
functor.mk
Fob
Fhom
proof abstract λa, transporto (λFo (Fh : Π⦃c c'⦄, _), Fh (ID a) = ID (Fo a))
q (respect_id F a) end qed
proof abstract λa b c g f, transporto (λFo (Fh : Π⦃c c'⦄, _), Fh (g ∘ f) = Fh g ∘ Fh f)
q (respect_comp F g f) end qed
section
local attribute precategory.is_set_hom [instance] [priority 1001]
local attribute trunctype.struct [instance] [priority 1] -- remove after #842 is closed
protected theorem is_set_functor [instance]
[HD : is_set D] : is_set (functor C D) :=
by apply is_trunc_equiv_closed; apply functor.sigma_char
end
/- higher equalities in the functor type -/
definition functor_mk_eq'_idp (F : C → D) (H : Π(a b : C), hom a b → hom (F a) (F b))
(id comp) : functor_mk_eq' id id comp comp (idpath F) (idpath H) = idp :=
begin
fapply apd011 (apdt01111 functor.mk idp idp),
apply is_prop.elim,
apply is_prop.elimo
end
definition functor_eq'_idp (F : C ⇒ D) : functor_eq' idp idp = (idpath F) :=
by (cases F; apply functor_mk_eq'_idp)
definition functor_eq_eta' {F₁ F₂ : C ⇒ D} (p : F₁ = F₂)
: functor_eq' (ap to_fun_ob p) (!tr_compose⁻¹ ⬝ apdt to_fun_hom p) = p :=
begin
cases p, cases F₁,
refine _ ⬝ !functor_eq'_idp,
esimp
end
theorem functor_eq2' {F₁ F₂ : C ⇒ D} {p₁ p₂ : to_fun_ob F₁ = to_fun_ob F₂} (q₁ q₂)
(r : p₁ = p₂) : functor_eq' p₁ q₁ = functor_eq' p₂ q₂ :=
by cases r; apply (ap (functor_eq' p₂)); apply is_prop.elim
theorem functor_eq2 {F₁ F₂ : C ⇒ D} (p q : F₁ = F₂) (r : ap010 to_fun_ob p ~ ap010 to_fun_ob q)
: p = q :=
begin
cases F₁ with ob₁ hom₁ id₁ comp₁,
cases F₂ with ob₂ hom₂ id₂ comp₂,
rewrite [-functor_eq_eta' p, -functor_eq_eta' q],
apply functor_eq2',
apply ap_eq_ap_of_homotopy,
exact r,
end
theorem ap010_apd01111_functor {F₁ F₂ : C → D} {H₁ : Π(a b : C), hom a b → hom (F₁ a) (F₁ b)}
{H₂ : Π(a b : C), hom a b → hom (F₂ a) (F₂ b)} {id₁ id₂ comp₁ comp₂}
(pF : F₁ = F₂) (pH : pF ▸ H₁ = H₂) (pid : cast (apdt011 _ pF pH) id₁ = id₂)
(pcomp : cast (apdt0111 _ pF pH pid) comp₁ = comp₂) (c : C)
: ap010 to_fun_ob (apdt01111 functor.mk pF pH pid pcomp) c = ap10 pF c :=
by induction pF; induction pH; induction pid; induction pcomp; reflexivity
definition ap010_functor_eq {F₁ F₂ : C ⇒ D} (p : to_fun_ob F₁ ~ to_fun_ob F₂)
(q : (λ(a b : C) (f : hom a b), hom_of_eq (p b) ∘ F₁ f ∘ inv_of_eq (p a)) ~3 @(to_fun_hom F₂))
(c : C) : ap010 to_fun_ob (functor_eq p q) c = p c :=
begin
cases F₁ with F₁o F₁h F₁id F₁comp, cases F₂ with F₂o F₂h F₂id F₂comp,
esimp [functor_eq,functor_mk_eq,functor_mk_eq'],
rewrite [ap010_apd01111_functor,↑ap10,{apd10 (eq_of_homotopy p)}right_inv apd10]
end
definition ap010_functor_mk_eq_constant {F : C → D} {H₁ : Π(a b : C), hom a b → hom (F a) (F b)}
{H₂ : Π(a b : C), hom a b → hom (F a) (F b)} {id₁ id₂ comp₁ comp₂}
(pH : Π(a b : C) (f : hom a b), H₁ a b f = H₂ a b f) (c : C) :
ap010 to_fun_ob (functor_mk_eq_constant id₁ id₂ comp₁ comp₂ pH) c = idp :=
!ap010_functor_eq
definition ap010_assoc (H : C ⇒ D) (G : B ⇒ C) (F : A ⇒ B) (a : A) :
ap010 to_fun_ob (functor.assoc H G F) a = idp :=
by apply ap010_functor_mk_eq_constant
definition compose_pentagon (K : D ⇒ E) (H : C ⇒ D) (G : B ⇒ C) (F : A ⇒ B) :
(calc K ∘f H ∘f G ∘f F = (K ∘f H) ∘f G ∘f F : functor.assoc
... = ((K ∘f H) ∘f G) ∘f F : functor.assoc)
=
(calc K ∘f H ∘f G ∘f F = K ∘f (H ∘f G) ∘f F : ap (λx, K ∘f x) !functor.assoc
... = (K ∘f H ∘f G) ∘f F : functor.assoc
... = ((K ∘f H) ∘f G) ∘f F : ap (λx, x ∘f F) !functor.assoc) :=
begin
have lem1 : Π{F₁ F₂ : A ⇒ D} (p : F₁ = F₂) (a : A),
ap010 to_fun_ob (ap (λx, K ∘f x) p) a = ap (to_fun_ob K) (ap010 to_fun_ob p a),
by intros; cases p; esimp,
have lem2 : Π{F₁ F₂ : B ⇒ E} (p : F₁ = F₂) (a : A),
ap010 to_fun_ob (ap (λx, x ∘f F) p) a = ap010 to_fun_ob p (F a),
by intros; cases p; esimp,
apply functor_eq2,
intro a, esimp,
rewrite [+ap010_con,lem1,lem2,
ap010_assoc K H (G ∘f F) a,
ap010_assoc (K ∘f H) G F a,
ap010_assoc H G F a,
ap010_assoc K H G (F a),
ap010_assoc K (H ∘f G) F a],
end
definition hom_pathover_functor {c₁ c₂ : C} {p : c₁ = c₂} (F G : C ⇒ D)
{f₁ : F c₁ ⟶ G c₁} {f₂ : F c₂ ⟶ G c₂}
(q : to_fun_hom G (hom_of_eq p) ∘ f₁ = f₂ ∘ to_fun_hom F (hom_of_eq p)) : f₁ =[p] f₂ :=
hom_pathover (hom_whisker_right _ (respect_hom_of_eq G _)⁻¹ ⬝ q ⬝
hom_whisker_left _ (respect_hom_of_eq F _))
definition hom_pathover_constant_left_functor_right {c₁ c₂ : C} {p : c₁ = c₂} {d : D} (F : C ⇒ D)
{f₁ : d ⟶ F c₁} {f₂ : d ⟶ F c₂} (q : to_fun_hom F (hom_of_eq p) ∘ f₁ = f₂) : f₁ =[p] f₂ :=
hom_pathover_constant_left (hom_whisker_right _ (respect_hom_of_eq F _)⁻¹ ⬝ q)
definition hom_pathover_functor_left_constant_right {c₁ c₂ : C} {p : c₁ = c₂} {d : D} (F : C ⇒ D)
{f₁ : F c₁ ⟶ d} {f₂ : F c₂ ⟶ d} (q : f₁ = f₂ ∘ to_fun_hom F (hom_of_eq p)) : f₁ =[p] f₂ :=
hom_pathover_constant_right (q ⬝ hom_whisker_left _ (respect_hom_of_eq F _))
definition hom_pathover_id_left_functor_right {c₁ c₂ : C} {p : c₁ = c₂} (F : C ⇒ C)
{f₁ : c₁ ⟶ F c₁} {f₂ : c₂ ⟶ F c₂} (q : to_fun_hom F (hom_of_eq p) ∘ f₁ = f₂ ∘ hom_of_eq p) :
f₁ =[p] f₂ :=
hom_pathover_id_left (hom_whisker_right _ (respect_hom_of_eq F _)⁻¹ ⬝ q)
definition hom_pathover_functor_left_id_right {c₁ c₂ : C} {p : c₁ = c₂} (F : C ⇒ C)
{f₁ : F c₁ ⟶ c₁} {f₂ : F c₂ ⟶ c₂} (q : hom_of_eq p ∘ f₁ = f₂ ∘ to_fun_hom F (hom_of_eq p)) :
f₁ =[p] f₂ :=
hom_pathover_id_right (q ⬝ hom_whisker_left _ (respect_hom_of_eq F _))
end functor

View file

@ -1,7 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
-/
import .exponential_laws

View file

@ -1,490 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
Functors which are equivalences or isomorphisms
-/
import .adjoint
open eq functor iso prod nat_trans is_equiv equiv is_trunc sigma.ops
namespace category
variables {C D : Precategory} {F : C ⇒ D} {G : D ⇒ C}
structure is_equivalence [class] (F : C ⇒ D) extends is_left_adjoint F :=
mk' ::
(is_iso_unit : is_iso η)
(is_iso_counit : is_iso ε)
abbreviation inverse := @is_equivalence.G
postfix ⁻¹ := inverse
--a second notation for the inverse, which is not overloaded (there is no unicode superscript F)
postfix [parsing_only] `⁻¹ᴱ`:std.prec.max_plus := inverse
definition is_isomorphism [class] (F : C ⇒ D) := fully_faithful F × is_equiv (to_fun_ob F)
structure equivalence (C D : Precategory) :=
(to_functor : C ⇒ D)
(struct : is_equivalence to_functor)
structure isomorphism (C D : Precategory) :=
(to_functor : C ⇒ D)
(struct : is_isomorphism to_functor)
structure weak_equivalence (C D : Precategory) :=
mk' :: (intermediate : Precategory)
(left_functor : intermediate ⇒ C)
(right_functor : intermediate ⇒ D)
[structl : is_weak_equivalence left_functor]
[structr : is_weak_equivalence right_functor]
infix ` ≃c `:25 := equivalence
infix ` ≅c `:25 := isomorphism
infix ` ≃w `:25 := weak_equivalence
attribute equivalence.struct isomorphism.struct [instance] [priority 1500]
attribute equivalence.to_functor isomorphism.to_functor [coercion]
definition is_iso_unit [instance] (F : C ⇒ D) [H : is_equivalence F] : is_iso (unit F) :=
!is_equivalence.is_iso_unit
definition is_iso_counit [instance] (F : C ⇒ D) [H : is_equivalence F] : is_iso (counit F) :=
!is_equivalence.is_iso_counit
definition iso_unit (F : C ⇒ D) [H : is_equivalence F] : F⁻¹ᴱ ∘f F ≅ 1 :=
(@(iso.mk _) !is_iso_unit)⁻¹ⁱ
definition iso_counit (F : C ⇒ D) [H : is_equivalence F] : F ∘f F⁻¹ᴱ ≅ 1 :=
@(iso.mk _) !is_iso_counit
definition split_essentially_surjective_of_is_equivalence [instance] (F : C ⇒ D)
[is_equivalence F] : split_essentially_surjective F :=
begin
intro d, fconstructor,
{ exact F⁻¹ d},
{ exact componentwise_iso (@(iso.mk (counit F)) !is_iso_counit) d}
end
end category
namespace category
section
parameters {C D : Precategory} {F : C ⇒ D} {G : D ⇒ C} (η : G ∘f F ≅ 1) (ε : F ∘f G ≅ 1)
private definition ηn : 1 ⟹ G ∘f F := to_inv η
private definition εn : F ∘f G ⟹ 1 := to_hom ε
private definition ηi (c : C) : G (F c) ≅ c := componentwise_iso η c
private definition εi (d : D) : F (G d) ≅ d := componentwise_iso ε d
private definition ηi' (c : C) : G (F c) ≅ c :=
to_fun_iso G (to_fun_iso F (ηi c)⁻¹ⁱ) ⬝i to_fun_iso G (εi (F c)) ⬝i ηi c
local attribute ηn εn ηi εi ηi' [reducible]
private theorem adj_η_natural {c c' : C} (f : hom c c')
: G (F f) ∘ to_inv (ηi' c) = to_inv (ηi' c') ∘ f :=
let ηi'_nat : G ∘f F ⟹ 1 :=
calc
G ∘f F ⟹ (G ∘f F) ∘f 1 : id_right_natural_rev (G ∘f F)
... ⟹ (G ∘f F) ∘f (G ∘f F) : (G ∘f F) ∘fn ηn
... ⟹ ((G ∘f F) ∘f G) ∘f F : assoc_natural (G ∘f F) G F
... ⟹ (G ∘f (F ∘f G)) ∘f F : assoc_natural_rev G F G ∘nf F
... ⟹ (G ∘f 1) ∘f F : (G ∘fn εn) ∘nf F
... ⟹ G ∘f F : id_right_natural G ∘nf F
... ⟹ 1 : to_hom η
in
begin
refine is_natural_inverse' (G ∘f F) functor.id ηi' ηi'_nat _ f,
intro c, esimp, rewrite [+id_left,id_right]
end
private theorem adjointify_adjH (c : C) :
to_hom (εi (F c)) ∘ F (to_hom (ηi' c))⁻¹ = id :=
begin
rewrite [respect_inv], apply comp_inverse_eq_of_eq_comp,
rewrite [id_left,↑ηi',+respect_comp,+respect_inv',assoc], apply eq_comp_inverse_of_comp_eq,
rewrite [↑εi,-naturality_iso_id ε (F c)],
symmetry, exact naturality εn (F (to_hom (ηi c)))
end
private theorem adjointify_adjK (d : D) :
G (to_hom (εi d)) ∘ to_hom (ηi' (G d))⁻¹ⁱ = id :=
begin
apply comp_inverse_eq_of_eq_comp,
rewrite [id_left,↑ηi',+respect_inv',assoc], apply eq_comp_inverse_of_comp_eq,
rewrite [↑ηi,-naturality_iso_id η (G d),↑εi,naturality_iso_id ε d],
exact naturality (to_hom η) (G (to_hom (εi d))),
end
parameter (G)
include η ε
definition is_equivalence.mk : is_equivalence F :=
begin
fapply is_equivalence.mk',
{ exact G},
{ fapply nat_trans.mk,
{ intro c, exact to_inv (ηi' c)},
{ intro c c' f, exact adj_η_natural f}},
{ exact εn},
{ exact adjointify_adjH},
{ exact adjointify_adjK},
{ exact @(is_natural_iso _) (λc, !is_iso_inverse)},
{ unfold εn, apply iso.struct, },
end
definition equivalence.MK : C ≃c D :=
equivalence.mk F is_equivalence.mk
end
section
parameters {C D : Precategory} (F : C ⇒ D)
[H₁ : fully_faithful F] [H₂ : split_essentially_surjective F]
include H₁ H₂
definition inverse_of_fully_faithful_of_split_essentially_surjective [constructor] : D ⇒ C :=
begin
fapply functor.mk,
{ exact λd, (H₂ d).1},
{ intro d d' g, apply (to_fun_hom F)⁻¹ᶠ, refine to_inv (H₂ d').2 ∘ g ∘ to_hom (H₂ d).2},
{ intro d, apply inv_eq_of_eq, rewrite [id_left, respect_id, to_left_inverse]},
{ intros d₁ d₂ d₃ g f, apply inv_eq_of_eq,
rewrite [respect_comp, +right_inv (to_fun_hom F), +assoc', comp_inverse_cancel_left]}
end
definition is_equivalence_of_fully_faithful_of_split_essentially_surjective [constructor]
: is_equivalence F :=
begin
fapply is_equivalence.mk,
{ exact inverse_of_fully_faithful_of_split_essentially_surjective},
{ fapply natural_iso.mk',
{ intro c, esimp, apply reflect_iso F, exact (H₂ (F c)).2},
intro c c' f, esimp, apply eq_of_fn_eq_fn' (to_fun_hom F),
rewrite [+respect_comp, +right_inv (to_fun_hom F), comp_inverse_cancel_left]},
{ fapply natural_iso.mk',
{ intro c, esimp, exact (H₂ c).2},
intro c c' f, esimp, rewrite [right_inv (to_fun_hom F), comp_inverse_cancel_left]}
end
end
variables {C D E : Precategory} {F : C ⇒ D}
--TODO: add variants
definition unit_eq_counit_inv (F : C ⇒ D) [H : is_equivalence F] (c : C) :
to_fun_hom F (natural_map (unit F) c) =
@(is_iso.inverse (counit F (F c))) (@(componentwise_is_iso (counit F)) !is_iso_counit (F c)) :=
begin
apply eq_inverse_of_comp_eq_id, apply counit_unit_eq
end
definition fully_faithful_of_is_equivalence [instance] [constructor] (F : C ⇒ D)
[H : is_equivalence F] : fully_faithful F :=
begin
intro c c',
fapply adjointify,
{ intro g, exact natural_map (@(iso.inverse (unit F)) !is_iso_unit) c' ∘ F⁻¹ g ∘ unit F c},
{ intro g, rewrite [+respect_comp,▸*],
xrewrite [natural_map_inverse (unit F) c', respect_inv'],
apply inverse_comp_eq_of_eq_comp,
rewrite [+unit_eq_counit_inv],
esimp, exact naturality (counit F)⁻¹ _},
{ intro f, xrewrite [▸*,natural_map_inverse (unit F) c'], apply inverse_comp_eq_of_eq_comp,
apply naturality (unit F)},
end
definition is_isomorphism.mk [constructor] {F : C ⇒ D} (G : D ⇒ C)
(p : G ∘f F = 1) (q : F ∘f G = 1) : is_isomorphism F :=
begin
constructor,
{ apply fully_faithful_of_is_equivalence, fapply is_equivalence.mk,
{ exact G},
{ apply iso_of_eq p},
{ apply iso_of_eq q}},
{ fapply adjointify,
{ exact G},
{ exact ap010 to_fun_ob q},
{ exact ap010 to_fun_ob p}}
end
definition isomorphism.MK [constructor] (F : C ⇒ D) (G : D ⇒ C)
(p : G ∘f F = 1) (q : F ∘f G = 1) : C ≅c D :=
isomorphism.mk F (is_isomorphism.mk G p q)
definition is_equiv_ob_of_is_isomorphism [instance] [unfold 4] (F : C ⇒ D)
[H : is_isomorphism F] : is_equiv (to_fun_ob F) :=
pr2 H
definition fully_faithful_of_is_isomorphism [unfold 4] (F : C ⇒ D)
[H : is_isomorphism F] : fully_faithful F :=
pr1 H
section
local attribute fully_faithful_of_is_isomorphism [instance]
definition strict_inverse [constructor] (F : C ⇒ D) [H : is_isomorphism F] : D ⇒ C :=
begin
fapply functor.mk,
{ intro d, exact (to_fun_ob F)⁻¹ᶠ d},
{ intro d d' g, exact (to_fun_hom F)⁻¹ᶠ (inv_of_eq !right_inv ∘ g ∘ hom_of_eq !right_inv)},
{ intro d, apply inv_eq_of_eq, rewrite [respect_id,id_left], apply left_inverse},
{ intro d₁ d₂ d₃ g₂ g₁, apply inv_eq_of_eq, rewrite [respect_comp F,+right_inv (to_fun_hom F)],
rewrite [+assoc], esimp, /-apply ap (λx, (x ∘ _) ∘ _), FAILS-/ refine ap (λx, (x ∘ _) ∘ _) _,
refine !id_right⁻¹ ⬝ _, rewrite [▸*,-+assoc], refine ap (λx, _ ∘ _ ∘ x) _,
exact !right_inverse⁻¹},
end
postfix /-[parsing-only]-/ `⁻¹ˢ`:std.prec.max_plus := strict_inverse
definition strict_right_inverse (F : C ⇒ D) [H : is_isomorphism F] : F ∘f F⁻¹ˢ = 1 :=
begin
fapply functor_eq,
{ intro d, esimp, apply right_inv},
{ intro d d' g,
rewrite [▸*, right_inv (to_fun_hom F), +assoc],
rewrite [↑[hom_of_eq,inv_of_eq,iso.to_inv], right_inverse],
rewrite [id_left], apply comp_inverse_cancel_right},
end
definition strict_left_inverse (F : C ⇒ D) [H : is_isomorphism F] : F⁻¹ˢ ∘f F = 1 :=
begin
fapply functor_eq,
{ intro d, esimp, apply left_inv},
{ intro d d' g, esimp, apply comp_eq_of_eq_inverse_comp, apply comp_inverse_eq_of_eq_comp,
apply inv_eq_of_eq, rewrite [+respect_comp,-assoc], apply ap011 (λx y, x ∘ F g ∘ y),
{ rewrite [adj], rewrite [▸*,respect_inv_of_eq F]},
{ rewrite [adj,▸*,respect_hom_of_eq F]}},
end
end
definition is_equivalence_of_is_isomorphism [instance] [constructor] (F : C ⇒ D)
[is_isomorphism F] : is_equivalence F :=
begin
fapply is_equivalence.mk,
{ apply F⁻¹ˢ},
{ apply iso_of_eq !strict_left_inverse},
{ apply iso_of_eq !strict_right_inverse},
end
definition equivalence_of_isomorphism [constructor] (F : C ≅c D) : C ≃c D :=
equivalence.mk F _
theorem is_prop_is_equivalence [instance] {C : Category} {D : Precategory} (F : C ⇒ D)
: is_prop (is_equivalence F) :=
begin
have f : is_equivalence F ≃ Σ(H : is_left_adjoint F), is_iso (unit F) × is_iso (counit F),
begin
fapply equiv.MK,
{ intro H, induction H, fconstructor: constructor, repeat (esimp;assumption) },
{ intro H, induction H with H1 H2, induction H1, induction H2, constructor,
repeat (esimp at *;assumption)},
{ intro H, induction H with H1 H2, induction H1, induction H2, reflexivity},
{ intro H, induction H, reflexivity}
end,
apply is_trunc_equiv_closed_rev, exact f,
end
theorem is_prop_is_isomorphism [instance] (F : C ⇒ D) : is_prop (is_isomorphism F) :=
by unfold is_isomorphism; exact _
/- closure properties -/
definition is_isomorphism_id [instance] [constructor] (C : Precategory)
: is_isomorphism (1 : C ⇒ C) :=
is_isomorphism.mk 1 !functor.id_right !functor.id_right
definition is_isomorphism_strict_inverse [constructor] (F : C ⇒ D) [K : is_isomorphism F]
: is_isomorphism F⁻¹ˢ :=
is_isomorphism.mk F !strict_right_inverse !strict_left_inverse
definition is_isomorphism_compose [constructor] (G : D ⇒ E) (F : C ⇒ D)
[H : is_isomorphism G] [K : is_isomorphism F] : is_isomorphism (G ∘f F) :=
is_isomorphism.mk
(F⁻¹ˢ ∘f G⁻¹ˢ)
abstract begin
rewrite [functor.assoc,-functor.assoc F⁻¹ˢ,strict_left_inverse,functor.id_right,
strict_left_inverse]
end end
abstract begin
rewrite [functor.assoc,-functor.assoc G,strict_right_inverse,functor.id_right,
strict_right_inverse]
end end
definition is_equivalence_id [constructor] (C : Precategory) : is_equivalence (1 : C ⇒ C) := _
definition is_equivalence_inverse [constructor] (F : C ⇒ D) [K : is_equivalence F]
: is_equivalence F⁻¹ᴱ :=
is_equivalence.mk F (iso_counit F) (iso_unit F)
definition is_equivalence_compose [constructor] (G : D ⇒ E) (F : C ⇒ D)
[H : is_equivalence G] [K : is_equivalence F] : is_equivalence (G ∘f F) :=
is_equivalence.mk
(F⁻¹ᴱ ∘f G⁻¹ᴱ)
abstract begin
rewrite [functor.assoc,-functor.assoc F⁻¹ᴱ],
refine ((_ ∘fi !iso_unit) ∘if _) ⬝i _,
refine (iso_of_eq !functor.id_right ∘if _) ⬝i _,
apply iso_unit
end end
abstract begin
rewrite [functor.assoc,-functor.assoc G],
refine ((_ ∘fi !iso_counit) ∘if _) ⬝i _,
refine (iso_of_eq !functor.id_right ∘if _) ⬝i _,
apply iso_counit
end end
variable (C)
definition equivalence.refl [refl] [constructor] : C ≃c C :=
equivalence.mk _ !is_equivalence_id
definition isomorphism.refl [refl] [constructor] : C ≅c C :=
isomorphism.mk _ !is_isomorphism_id
variable {C}
definition equivalence.symm [symm] [constructor] (H : C ≃c D) : D ≃c C :=
equivalence.mk _ (is_equivalence_inverse H)
definition isomorphism.symm [symm] [constructor] (H : C ≅c D) : D ≅c C :=
isomorphism.mk _ (is_isomorphism_strict_inverse H)
definition equivalence.trans [trans] [constructor] (H : C ≃c D) (K : D ≃c E) : C ≃c E :=
equivalence.mk _ (is_equivalence_compose K H)
definition isomorphism.trans [trans] [constructor] (H : C ≅c D) (K : D ≅c E) : C ≅c E :=
isomorphism.mk _ (is_isomorphism_compose K H)
definition equivalence.to_strict_inverse [unfold 3] (H : C ≃c D) : D ⇒ C :=
H⁻¹ᴱ
definition isomorphism.to_strict_inverse [unfold 3] (H : C ≅c D) : D ⇒ C :=
H⁻¹ˢ
definition is_isomorphism_of_is_equivalence [constructor] {C D : Category} (F : C ⇒ D)
[H : is_equivalence F] : is_isomorphism F :=
begin
fapply is_isomorphism.mk,
{ exact F⁻¹ᴱ},
{ apply eq_of_iso, apply iso_unit},
{ apply eq_of_iso, apply iso_counit},
end
definition isomorphism_of_equivalence [constructor] {C D : Category} (F : C ≃c D) : C ≅c D :=
isomorphism.mk F !is_isomorphism_of_is_equivalence
definition equivalence_eq {C : Category} {D : Precategory} {F F' : C ≃c D}
(p : equivalence.to_functor F = equivalence.to_functor F') : F = F' :=
begin
induction F, induction F', exact apd011 equivalence.mk p !is_prop.elimo
end
definition isomorphism_eq {F F' : C ≅c D}
(p : isomorphism.to_functor F = isomorphism.to_functor F') : F = F' :=
begin
induction F, induction F', exact apd011 isomorphism.mk p !is_prop.elimo
end
definition is_equiv_isomorphism_of_equivalence [constructor] (C D : Category)
: is_equiv (@equivalence_of_isomorphism C D) :=
begin
fapply adjointify,
{ exact isomorphism_of_equivalence},
{ intro F, apply equivalence_eq, reflexivity},
{ intro F, apply isomorphism_eq, reflexivity},
end
definition isomorphism_equiv_equivalence [constructor] (C D : Category)
: (C ≅c D) ≃ (C ≃c D) :=
equiv.mk _ !is_equiv_isomorphism_of_equivalence
definition isomorphism_of_eq [constructor] {C D : Precategory} (p : C = D) : C ≅c D :=
isomorphism.MK (functor_of_eq p)
(functor_of_eq p⁻¹)
(by induction p; reflexivity)
(by induction p; reflexivity)
definition equiv_ob_of_isomorphism [constructor] {C D : Precategory} (H : C ≅c D) : C ≃ D :=
equiv.mk H _
definition equiv_hom_of_isomorphism [constructor] {C D : Precategory} (H : C ≅c D) (c c' : C)
: c ⟶ c' ≃ H c ⟶ H c' :=
equiv.mk (to_fun_hom (isomorphism.to_functor H)) _
/- weak equivalences -/
theorem is_prop_is_weak_equivalence [instance] (F : C ⇒ D) : is_prop (is_weak_equivalence F) :=
by unfold is_weak_equivalence; exact _
definition is_weak_equivalence_of_is_equivalence [instance] (F : C ⇒ D) [is_equivalence F]
: is_weak_equivalence F :=
(_, _)
definition fully_faithful_of_is_weak_equivalence.mk [instance] (F : C ⇒ D)
[H : is_weak_equivalence F] : fully_faithful F :=
pr1 H
definition essentially_surjective_of_is_weak_equivalence.mk [instance] (F : C ⇒ D)
[H : is_weak_equivalence F] : essentially_surjective F :=
pr2 H
definition is_weak_equivalence_compose (G : D ⇒ E) (F : C ⇒ D)
[H : is_weak_equivalence G] [K : is_weak_equivalence F] : is_weak_equivalence (G ∘f F) :=
(fully_faithful_compose G F, essentially_surjective_compose G F)
definition weak_equivalence.mk [constructor] (F : C ⇒ D) (H : is_weak_equivalence F) : C ≃w D :=
weak_equivalence.mk' C 1 F
definition weak_equivalence.symm [unfold 3] : C ≃w D → D ≃w C
| (@weak_equivalence.mk' _ _ X F₁ F₂ H₁ H₂) := weak_equivalence.mk' X F₂ F₁
/- TODO
definition is_equiv_isomorphism_of_eq [constructor] (C D : Precategory)
: is_equiv (@isomorphism_of_eq C D) :=
begin
fapply adjointify,
{ intro H, fapply Precategory_eq_of_equiv,
{ apply equiv_ob_of_isomorphism H},
{ exact equiv_hom_of_isomorphism H},
{ /-exact sorry FAILS-/ intros, esimp, apply respect_comp}},
{ intro H, apply isomorphism_eq, esimp, fapply functor_eq: esimp,
{ intro c, exact sorry},
{ exact sorry}},
{ intro p, induction p, esimp, exact sorry},
end
definition eq_equiv_isomorphism [constructor] (C D : Precategory)
: (C = D) ≃ (C ≅c D) :=
equiv.mk _ !is_equiv_isomorphism_of_eq
definition equivalence_of_eq [unfold 3] [reducible] {C D : Precategory} (p : C = D) : C ≃c D :=
equivalence_of_isomorphism (isomorphism_of_eq p)
definition eq_equiv_equivalence [constructor] (C D : Category) : (C = D) ≃ (C ≃c D) :=
!eq_equiv_isomorphism ⬝e !isomorphism_equiv_equivalence
definition is_equivalence_equiv [constructor] (F : C ⇒ D)
: is_equivalence F ≃ (fully_faithful F × split_essentially_surjective F) :=
sorry
definition is_equivalence_equiv_is_weak_equivalence [constructor] {C D : Category}
(F : C ⇒ D) : is_equivalence F ≃ is_weak_equivalence F :=
sorry
-- weak_equivalence.trans
-/
/- TODO?
definition is_isomorphism_equiv1 (F : C ⇒ D) : is_equivalence F
≃ Σ(G : D ⇒ C) (η : 1 = G ∘f F) (ε : F ∘f G = 1),
sorry ⬝ ap (λ(H : C ⇒ C), F ∘f H) η ⬝ sorry = ap (λ(H : D ⇒ D), H ∘f F) ε⁻¹ :=
sorry
definition is_isomorphism_equiv2 (F : C ⇒ D) : is_equivalence F
≃ ∃(G : D ⇒ C), 1 = G ∘f F × F ∘f G = 1 :=
sorry
-/
end category

View file

@ -1,237 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
Definition of functors involving at least two different constructions of categories
-/
import ..constructions.functor ..constructions.product ..constructions.opposite
..constructions.set
open category nat_trans eq prod prod.ops
namespace functor
section
open iso equiv
variables {C D E : Precategory} (F F' : C ×c D ⇒ E) (G G' : C ⇒ E ^c D)
/- currying a functor -/
definition functor_curry_ob [reducible] [constructor] (c : C) : D ⇒ E :=
F ∘f (constant_functor D c ×f 1)
definition functor_curry_hom [constructor] ⦃c c' : C⦄ (f : c ⟶ c')
: functor_curry_ob F c ⟹ functor_curry_ob F c' :=
F ∘fn (constant_nat_trans D f ×n 1)
local abbreviation Fhom [constructor] := @functor_curry_hom
theorem functor_curry_id (c : C) : Fhom F (ID c) = 1 :=
nat_trans_eq (λd, respect_id F (c, d))
theorem functor_curry_comp ⦃c c' c'' : C⦄ (f' : c' ⟶ c'') (f : c ⟶ c')
: Fhom F (f' ∘ f) = Fhom F f' ∘n Fhom F f :=
begin
apply nat_trans_eq,
intro d, calc
natural_map (Fhom F (f' ∘ f)) d = F (f' ∘ f, id) : by esimp
... = F (f' ∘ f, category.id ∘ category.id) : by rewrite id_id
... = F ((f',id) ∘ (f, id)) : by esimp
... = F (f',id) ∘ F (f, id) : by rewrite [respect_comp F]
... = natural_map ((Fhom F f') ∘ (Fhom F f)) d : by esimp
end
definition functor_curry [constructor] : C ⇒ E ^c D :=
functor.mk (functor_curry_ob F)
(functor_curry_hom F)
(functor_curry_id F)
(functor_curry_comp F)
/- currying a functor, flipping the arguments -/
definition functor_curry_rev_ob [reducible] [constructor] (d : D) : C ⇒ E :=
F ∘f (1 ×f constant_functor C d)
definition functor_curry_rev_hom [constructor] ⦃d d' : D⦄ (g : d ⟶ d')
: functor_curry_rev_ob F d ⟹ functor_curry_rev_ob F d' :=
F ∘fn (1 ×n constant_nat_trans C g)
local abbreviation Fhomr [constructor] := @functor_curry_rev_hom
theorem functor_curry_rev_id (d : D) : Fhomr F (ID d) = nat_trans.id :=
nat_trans_eq (λc, respect_id F (c, d))
theorem functor_curry_rev_comp ⦃d d' d'' : D⦄ (g' : d' ⟶ d'') (g : d ⟶ d')
: Fhomr F (g' ∘ g) = Fhomr F g' ∘n Fhomr F g :=
begin
apply nat_trans_eq, esimp, intro c, rewrite [-id_id at {1}], apply respect_comp F
end
definition functor_curry_rev [constructor] : D ⇒ E ^c C :=
functor.mk (functor_curry_rev_ob F)
(functor_curry_rev_hom F)
(functor_curry_rev_id F)
(functor_curry_rev_comp F)
/- uncurrying a functor -/
definition functor_uncurry_ob [reducible] (p : C ×c D) : E :=
to_fun_ob (G p.1) p.2
definition functor_uncurry_hom ⦃p p' : C ×c D⦄ (f : hom p p')
: functor_uncurry_ob G p ⟶ functor_uncurry_ob G p' :=
to_fun_hom (to_fun_ob G p'.1) f.2 ∘ natural_map (to_fun_hom G f.1) p.2
local abbreviation Ghom := @functor_uncurry_hom
theorem functor_uncurry_id (p : C ×c D) : Ghom G (ID p) = id :=
calc
Ghom G (ID p) = to_fun_hom (to_fun_ob G p.1) id ∘ natural_map (to_fun_hom G id) p.2 : by esimp
... = id ∘ natural_map (to_fun_hom G id) p.2 : by rewrite respect_id
... = id ∘ natural_map nat_trans.id p.2 : by rewrite respect_id
... = id : id_id
theorem functor_uncurry_comp ⦃p p' p'' : C ×c D⦄ (f' : p' ⟶ p'') (f : p ⟶ p')
: Ghom G (f' ∘ f) = Ghom G f' ∘ Ghom G f :=
calc
Ghom G (f' ∘ f)
= to_fun_hom (to_fun_ob G p''.1) (f'.2 ∘ f.2) ∘ natural_map (to_fun_hom G (f'.1 ∘ f.1)) p.2 : by esimp
... = (to_fun_hom (to_fun_ob G p''.1) f'.2 ∘ to_fun_hom (to_fun_ob G p''.1) f.2)
∘ natural_map (to_fun_hom G (f'.1 ∘ f.1)) p.2 : by rewrite respect_comp
... = (to_fun_hom (to_fun_ob G p''.1) f'.2 ∘ to_fun_hom (to_fun_ob G p''.1) f.2)
∘ natural_map (to_fun_hom G f'.1 ∘ to_fun_hom G f.1) p.2 : by rewrite respect_comp
... = (to_fun_hom (to_fun_ob G p''.1) f'.2 ∘ to_fun_hom (to_fun_ob G p''.1) f.2)
∘ (natural_map (to_fun_hom G f'.1) p.2 ∘ natural_map (to_fun_hom G f.1) p.2) : by esimp
... = (to_fun_hom (to_fun_ob G p''.1) f'.2 ∘ natural_map (to_fun_hom G f'.1) p'.2)
∘ (to_fun_hom (to_fun_ob G p'.1) f.2 ∘ natural_map (to_fun_hom G f.1) p.2) :
by rewrite [square_prepostcompose (!naturality⁻¹ᵖ) _ _]
... = Ghom G f' ∘ Ghom G f : by esimp
definition functor_uncurry [constructor] : C ×c D ⇒ E :=
functor.mk (functor_uncurry_ob G)
(functor_uncurry_hom G)
(functor_uncurry_id G)
(functor_uncurry_comp G)
definition functor_uncurry_functor_curry : functor_uncurry (functor_curry F) = F :=
functor_eq (λp, ap (to_fun_ob F) !prod.eta)
begin
intro cd cd' fg,
cases cd with c d, cases cd' with c' d', cases fg with f g,
transitivity to_fun_hom (functor_uncurry (functor_curry F)) (f, g),
apply id_leftright,
show (functor_uncurry (functor_curry F)) (f, g) = F (f,g),
from calc
(functor_uncurry (functor_curry F)) (f, g)
= to_fun_hom F (id, g) ∘ to_fun_hom F (f, id) : by esimp
... = F (category.id ∘ f, g ∘ category.id) : (respect_comp F (id,g) (f,id))⁻¹
... = F (f, g ∘ category.id) : by rewrite id_left
... = F (f,g) : by rewrite id_right,
end
definition functor_curry_functor_uncurry_ob (c : C)
: functor_curry (functor_uncurry G) c = G c :=
begin
fapply functor_eq,
{ intro d, reflexivity},
{ intro d d' g, refine !id_leftright ⬝ _, esimp,
rewrite [▸*, ↑functor_uncurry_hom, respect_id, ▸*, id_right]}
end
definition functor_curry_functor_uncurry : functor_curry (functor_uncurry G) = G :=
begin
fapply functor_eq, exact (functor_curry_functor_uncurry_ob G),
intro c c' f,
fapply nat_trans_eq,
intro d,
apply concat,
{apply (ap (λx, x ∘ _)),
apply concat, apply natural_map_hom_of_eq, apply (ap hom_of_eq), apply ap010_functor_eq},
apply concat,
{apply (ap (λx, _ ∘ x)), apply (ap (λx, _ ∘ x)),
apply concat, apply natural_map_inv_of_eq,
apply (ap (λx, hom_of_eq x⁻¹)), apply ap010_functor_eq},
apply concat, apply id_leftright,
apply concat, apply (ap (λx, x ∘ _)), apply respect_id,
apply id_left
end
/-
This only states that the carriers of (C ^ D) ^ E and C ^ (E × D) are equivalent.
In [exponential laws] we prove that these are in fact isomorphic categories
-/
definition prod_functor_equiv_functor_functor [constructor] (C D E : Precategory)
: (C ×c D ⇒ E) ≃ (C ⇒ E ^c D) :=
equiv.MK functor_curry
functor_uncurry
functor_curry_functor_uncurry
functor_uncurry_functor_curry
variables {F F' G G'}
definition nat_trans_curry_nat [constructor] (η : F ⟹ F') (c : C)
: functor_curry_ob F c ⟹ functor_curry_ob F' c :=
begin
fapply nat_trans.mk: esimp,
{ intro d, exact η (c, d)},
{ intro d d' f, apply naturality}
end
definition nat_trans_curry [constructor] (η : F ⟹ F')
: functor_curry F ⟹ functor_curry F' :=
begin
fapply nat_trans.mk: esimp,
{ exact nat_trans_curry_nat η},
{ intro c c' f, apply nat_trans_eq, intro d, esimp, apply naturality}
end
definition nat_trans_uncurry [constructor] (η : G ⟹ G')
: functor_uncurry G ⟹ functor_uncurry G' :=
begin
fapply nat_trans.mk: esimp,
{ intro v, unfold functor_uncurry_ob, exact (η v.1) v.2},
{ intro v w f, unfold functor_uncurry_hom,
rewrite [-assoc, ap010 natural_map (naturality η f.1) v.2, assoc, naturality, -assoc]}
end
end
section
open is_trunc
/- hom-functors -/
definition hom_functor_assoc {C : Precategory} {a1 a2 a3 a4 a5 a6 : C}
(f1 : hom a5 a6) (f2 : hom a4 a5) (f3 : hom a3 a4) (f4 : hom a2 a3) (f5 : hom a1 a2)
: (f1 ∘ f2) ∘ f3 ∘ (f4 ∘ f5) = f1 ∘ (f2 ∘ f3 ∘ f4) ∘ f5 :=
calc
_ = f1 ∘ f2 ∘ f3 ∘ f4 ∘ f5 : by rewrite -assoc
... = f1 ∘ (f2 ∘ f3) ∘ f4 ∘ f5 : by rewrite -assoc
... = f1 ∘ ((f2 ∘ f3) ∘ f4) ∘ f5 : by rewrite -(assoc (f2 ∘ f3) _ _)
... = _ : by rewrite (assoc f2 f3 f4)
-- the functor hom(-,-)
definition hom_functor.{u v} [constructor] (C : Precategory.{u v}) : Cᵒᵖ ×c C ⇒ set.{v} :=
functor.mk
(λ (x : Cᵒᵖ ×c C), @homset (Cᵒᵖ) C x.1 x.2)
(λ (x y : Cᵒᵖ ×c C) (f : @category.precategory.hom (Cᵒᵖ ×c C) (Cᵒᵖ ×c C) x y)
(h : @homset (Cᵒᵖ) C x.1 x.2), f.2 ∘[C] (h ∘[C] f.1))
(λ x, abstract @eq_of_homotopy _ _ _ (ID (@homset Cᵒᵖ C x.1 x.2))
(λ h, concat (by apply @id_left) (by apply @id_right)) end)
(λ x y z g f, abstract eq_of_homotopy (by intros; apply @hom_functor_assoc) end)
-- the functor hom(-, c)
definition hom_functor_left.{u v} [constructor] {C : Precategory.{u v}} (c : C)
: Cᵒᵖ ⇒ set.{v} :=
functor_curry_rev_ob !hom_functor c
-- the functor hom(c, -)
definition hom_functor_right.{u v} [constructor] {C : Precategory.{u v}} (c : C)
: C ⇒ set.{v} :=
functor_curry_ob !hom_functor c
definition nat_trans_hom_functor_left [constructor] {C : Precategory}
⦃c c' : C⦄ (f : c ⟶ c') : hom_functor_left c ⟹ hom_functor_left c' :=
functor_curry_rev_hom !hom_functor f
-- the yoneda embedding itself is defined in [yoneda].
end
end functor

View file

@ -1,284 +0,0 @@
/-
Copyright (c) 2015-2016 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn, Jakob von Raumer
Exponential laws
-/
import types.unit .equivalence .examples
..constructions.terminal ..constructions.initial ..constructions.product ..constructions.sum
..constructions.discrete
open eq category functor is_trunc nat_trans iso unit prod sum prod.ops bool
namespace category
/- C ^ 0 ≅ 1 -/
definition functor_zero_iso_one [constructor] (C : Precategory) : C ^c 0 ≅c 1 :=
begin
fapply isomorphism.MK,
{ apply terminal_functor},
{ apply point, apply initial_functor},
{ fapply functor_eq: intros; esimp at *,
{ apply eq_of_is_contr},
{ apply nat_trans_eq, intro u, induction u}},
{ fapply functor_eq: intros; esimp at *,
{ induction x, reflexivity},
{ induction f, reflexivity}},
end
/- 0 ^ C ≅ 0 if C is inhabited -/
definition zero_functor_functor_zero [constructor] (C : Precategory) (c : C) : 0 ^c C ⇒ 0 :=
begin
fapply functor.mk: esimp,
{ intro F, exact F c},
{ intro F, eapply empty.elim (F c)},
{ intro F, eapply empty.elim (F c)},
{ intro F, eapply empty.elim (F c)},
end
definition zero_functor_iso_zero [constructor] (C : Precategory) (c : C) : 0 ^c C ≅c 0 :=
begin
fapply isomorphism.MK,
{ exact zero_functor_functor_zero C c},
{ apply initial_functor},
{ fapply functor_eq: esimp,
{ intro F, apply empty.elim (F c)},
{ intro F, apply empty.elim (F c)}},
{ fapply functor_eq: esimp,
{ intro u, apply empty.elim u},
{ apply empty.elim}},
end
/- C ^ 1 ≅ C -/
definition functor_one_iso [constructor] (C : Precategory) : C ^c 1 ≅c C :=
begin
fapply isomorphism.MK,
{ exact !eval_functor star},
{ apply functor_curry, apply pr1_functor},
{ fapply functor_eq: esimp,
{ intro F, fapply functor_eq: esimp,
{ intro u, induction u, reflexivity},
{ intro u v f, induction u, induction v, induction f, esimp, rewrite [+id_id,-respect_id]}},
{ intro F G η, apply nat_trans_eq, intro u, esimp,
rewrite [natural_map_hom_of_eq _ u, natural_map_inv_of_eq _ u,▸*,+ap010_functor_eq _ _ u],
induction u, rewrite [▸*, id_leftright]}},
{ fapply functor_eq: esimp,
{ intro c d f, rewrite [▸*, id_leftright]}},
end
/- 1 ^ C ≅ 1 -/
definition one_functor_iso_one [constructor] (C : Precategory) : 1 ^c C ≅c 1 :=
begin
fapply isomorphism.MK,
{ apply terminal_functor},
{ apply functor_curry, apply pr1_functor},
{ fapply functor_eq: esimp,
{ intro F, fapply functor_eq: esimp,
{ intro c, apply unit.eta},
{ intro c d f, apply unit.eta}},
{ intro F G η, fapply nat_trans_eq, esimp, intro c, apply unit.eta}},
{ fapply functor_eq: esimp,
{ intro u, apply unit.eta},
{ intro u v f, apply unit.eta}},
end
/- C ^ 2 ≅ C × C -/
definition functor_two_right [constructor] (C : Precategory)
: C ^c c2 ⇒ C ×c C :=
begin
fapply functor.mk: esimp,
{ intro F, exact (F ff, F tt)},
{ intro F G η, esimp, exact (η ff, η tt)},
{ intro F, reflexivity},
{ intro F G H η θ, reflexivity}
end
definition functor_two_left [constructor] (C : Precategory)
: C ×c C ⇒ C ^c c2 :=
begin
fapply functor.mk: esimp,
{ intro v, exact c2_functor C v.1 v.2},
{ intro v w f, exact c2_nat_trans f.1 f.2},
{ intro v, apply nat_trans_eq, esimp, intro b, induction b: reflexivity},
{ intro u v w g f, apply nat_trans_eq, esimp, intro b, induction b: reflexivity}
end
definition functor_two_iso [constructor] (C : Precategory)
: C ^c c2 ≅c C ×c C :=
begin
fapply isomorphism.MK: esimp,
{ apply functor_two_right},
{ apply functor_two_left},
{ fapply functor_eq: esimp,
{ intro F, apply c2_functor_eta},
{ intro F G η, fapply nat_trans_eq, intro b, esimp,
rewrite [@natural_map_hom_of_eq _ _ _ G, @natural_map_inv_of_eq _ _ _ F,
↑c2_functor_eta, +@ap010_functor_eq c2 C, ▸*],
induction b: esimp; apply id_leftright}},
{ fapply functor_eq: esimp,
{ intro v, apply prod.eta},
{ intro v w f, induction v, induction w, esimp, apply prod_eq: apply id_leftright}},
end
/- Cᵒᵖ ^ Dᵒᵖ ≅ (C ^ D)ᵒᵖ -/
definition opposite_functor_opposite_iso [constructor] (C D : Precategory)
: Cᵒᵖ ^c Dᵒᵖ ≅c (C ^c D)ᵒᵖ :=
begin
fapply isomorphism.MK: esimp,
{ apply opposite_functor_opposite_right},
{ apply opposite_functor_opposite_left},
{ fapply functor_eq: esimp,
{ exact opposite_rev_opposite_functor},
{ intro F G η, fapply nat_trans_eq, esimp, intro d,
rewrite [@natural_map_hom_of_eq _ _ _ G, @natural_map_inv_of_eq _ _ _ F,
↑opposite_rev_opposite_functor, +@ap010_functor_eq Dᵒᵖ Cᵒᵖ, ▸*],
exact !id_right ⬝ !id_left}},
{ fapply functor_eq: esimp,
{ exact opposite_opposite_rev_functor},
{ intro F G η, fapply nat_trans_eq, esimp, intro d,
rewrite [opposite_hom_of_eq, opposite_inv_of_eq, @natural_map_hom_of_eq _ _ _ F,
@natural_map_inv_of_eq _ _ _ G, ↑opposite_opposite_rev_functor, +@ap010_functor_eq, ▸*],
exact !id_right ⬝ !id_left}},
end
/- C ^ (D + E) ≅ C ^ D × C ^ E -/
definition functor_sum_right [constructor] (C D E : Precategory)
: C ^c (D +c E) ⇒ C ^c D ×c C ^c E :=
begin
apply functor_prod,
{ apply precomposition_functor, apply inl_functor},
{ apply precomposition_functor, apply inr_functor}
end
definition functor_sum_left [constructor] (C D E : Precategory)
: C ^c D ×c C ^c E ⇒ C ^c (D +c E) :=
begin
fapply functor.mk: esimp,
{ intro V, exact V.1 +f V.2},
{ intro V W ν, apply sum_nat_trans, exact ν.1, exact ν.2},
{ intro V, apply nat_trans_eq, intro a, induction a: reflexivity},
{ intro U V W ν μ, apply nat_trans_eq, intro a, induction a: reflexivity}
-- REPORT: cannot abstract
end
definition functor_sum_iso [constructor] (C D E : Precategory)
: C ^c (D +c E) ≅c C ^c D ×c C ^c E :=
begin
fapply isomorphism.MK,
{ apply functor_sum_right},
{ apply functor_sum_left},
{ fapply functor_eq: esimp,
{ exact sum_functor_eta},
{ intro F G η, fapply nat_trans_eq, intro a, esimp,
rewrite [@natural_map_hom_of_eq _ _ _ G _ a, @natural_map_inv_of_eq _ _ _ F _ a,
↑sum_functor_eta,+ap010_functor_eq _ _ a],
induction a: esimp: apply id_leftright}},
{ fapply functor_eq: esimp,
{ intro V, induction V with F G, apply prod_eq: esimp,
apply sum_functor_inl, apply sum_functor_inr},
{ intro V W ν, induction V with F G, induction W with F' G', induction ν with η θ,
apply prod_eq: apply nat_trans_eq,
{ intro d, rewrite [▸*,@pr1_hom_of_eq (C ^c D) (C ^c E), @pr1_inv_of_eq (C ^c D) (C ^c E),
@natural_map_hom_of_eq _ _ _ F' _ d, @natural_map_inv_of_eq _ _ _ F _ d,
↑sum_functor_inl,+ap010_functor_eq _ _ d, ▸*], apply id_leftright},
{ intro e, rewrite [▸*,@pr2_hom_of_eq (C ^c D) (C ^c E), @pr2_inv_of_eq (C ^c D) (C ^c E),
@natural_map_hom_of_eq _ _ _ G' _ e, @natural_map_inv_of_eq _ _ _ G _ e,
↑sum_functor_inr,+ap010_functor_eq _ _ e, ▸*], apply id_leftright}}},
end
/- (C × D) ^ E ≅ C ^ E × D ^ E -/
definition prod_functor_right [constructor] (C D E : Precategory)
: (C ×c D) ^c E ⇒ C ^c E ×c D ^c E :=
begin
apply functor_prod,
{ apply postcomposition_functor, apply pr1_functor},
{ apply postcomposition_functor, apply pr2_functor}
end
definition prod_functor_left [constructor] (C D E : Precategory)
: C ^c E ×c D ^c E ⇒ (C ×c D) ^c E :=
begin
fapply functor.mk: esimp,
{ intro V, exact V.1 ×f V.2},
{ intro V W ν, exact prod_nat_trans ν.1 ν.2},
{ intro V, apply nat_trans_eq, intro e, reflexivity},
{ intro U V W ν μ, apply nat_trans_eq, intro e, reflexivity}
end
definition prod_functor_iso [constructor] (C D E : Precategory)
: (C ×c D) ^c E ≅c C ^c E ×c D ^c E :=
begin
fapply isomorphism.MK,
{ apply prod_functor_right},
{ apply prod_functor_left},
{ fapply functor_eq: esimp,
{ exact prod_functor_eta},
{ intro F G η, fapply nat_trans_eq, intro e, esimp,
rewrite [@natural_map_hom_of_eq _ _ _ G, @natural_map_inv_of_eq _ _ _ F,↑prod_functor_eta,
+ap010_functor_eq, +hom_of_eq_inv, ▸*, pr1_hom_of_eq, pr2_hom_of_eq,
pr1_inv_of_eq, pr2_inv_of_eq, ▸*, +id_leftright, prod.eta]}},
{ fapply functor_eq: esimp,
{ intro V, apply prod_eq: esimp, apply pr1_functor_prod, apply pr2_functor_prod},
{ intro V W ν, rewrite [@pr1_hom_of_eq (C ^c E) (D ^c E), @pr2_hom_of_eq (C ^c E) (D ^c E),
@pr1_inv_of_eq (C ^c E) (D ^c E), @pr2_inv_of_eq (C ^c E) (D ^c E)],
apply prod_eq: apply nat_trans_eq; intro v: esimp,
{ rewrite [@natural_map_hom_of_eq _ _ _ W.1, @natural_map_inv_of_eq _ _ _ V.1, ▸*,
↑pr1_functor_prod,+ap010_functor_eq, ▸*, id_leftright]},
{ rewrite [@natural_map_hom_of_eq _ _ _ W.2, @natural_map_inv_of_eq _ _ _ V.2, ▸*,
↑pr2_functor_prod,+ap010_functor_eq, ▸*, id_leftright]}}},
end
/- (C ^ D) ^ E ≅ C ^ (E × D) -/
definition functor_functor_right [constructor] (C D E : Precategory)
: (C ^c D) ^c E ⇒ C ^c (E ×c D) :=
begin
fapply functor.mk: esimp,
{ exact functor_uncurry},
{ apply @nat_trans_uncurry},
{ intro F, apply nat_trans_eq, intro e, reflexivity},
{ intro F G H η θ, apply nat_trans_eq, intro e, reflexivity}
end
definition functor_functor_left [constructor] (C D E : Precategory)
: C ^c (E ×c D) ⇒ (C ^c D) ^c E :=
begin
fapply functor.mk: esimp,
{ exact functor_curry},
{ apply @nat_trans_curry},
{ intro F, apply nat_trans_eq, intro e, reflexivity},
{ intro F G H η θ, apply nat_trans_eq, intro e, reflexivity}
end
definition functor_functor_iso [constructor] (C D E : Precategory)
: (C ^c D) ^c E ≅c C ^c (E ×c D) :=
begin
fapply isomorphism.MK: esimp,
{ apply functor_functor_right},
{ apply functor_functor_left},
{ fapply functor_eq: esimp,
{ exact functor_curry_functor_uncurry},
{ intro F G η, fapply nat_trans_eq, intro e, esimp,
rewrite [@natural_map_hom_of_eq _ _ _ G, @natural_map_inv_of_eq _ _ _ F,
↑functor_curry_functor_uncurry, +@ap010_functor_eq E (C ^c D)],
apply nat_trans_eq, intro d, rewrite [▸*, hom_of_eq_inv,
@natural_map_hom_of_eq _ _ _ (G e), @natural_map_inv_of_eq _ _ _ (F e),
↑functor_curry_functor_uncurry_ob, +@ap010_functor_eq D C, ▸*, id_leftright]}},
{ fapply functor_eq: esimp,
{ intro F, apply functor_uncurry_functor_curry},
{ intro F G η, fapply nat_trans_eq, esimp, intro v, induction v with c d,
rewrite [@natural_map_hom_of_eq _ _ _ G, @natural_map_inv_of_eq _ _ _ F,
↑functor_uncurry_functor_curry, +@ap010_functor_eq, ▸*], apply id_leftright}},
end
end category

View file

@ -1,14 +0,0 @@
algebra.category.functor
========================
Functors, functor attributes, equivalences, isomorphism, adjointness.
* [basic](basic.hlean) : Definition and basic properties of functors
* [examples](examples.hlean) : Constructions of functors between categories, involving more than one category in the [constructions](../constructions/constructions.md) folder (functors which only depend on one constructions are in the corresponding file). This includes the currying and uncurrying of functors
* [attributes](attributes.hlean): Attributes of functors (full, faithful, split essentially surjective, ...)
* [adjoint](adjoint.hlean) : Adjoint functors and equivalences
* [equivalence](equivalence.hlean) : Equivalences and Isomorphisms
* [exponential_laws](exponential_laws.hlean)
* [yoneda](yoneda.hlean) : the Yoneda Embedding
Note: the functor category is defined in [constructions.functor](../constructions/functor.hlean). Functors preserving limits is in [limits.functor_preserve](../limits/functor_preserve.hlean).

View file

@ -1,171 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
Yoneda embedding and Yoneda lemma
-/
import .examples .attributes
open category eq functor prod.ops is_trunc iso is_equiv category.set nat_trans lift
namespace yoneda
universe variables u v
variable {C : Precategory.{u v}}
/-
These attributes make sure that the fields of the category "set" reduce to the right things
However, we don't want to have them globally, because that will unfold the composition g ∘ f
in a Category to category.category.comp g f
-/
local attribute category.to_precategory [constructor]
-- should this be defined as "yoneda_embedding Cᵒᵖ"?
definition contravariant_yoneda_embedding [constructor] [reducible]
(C : Precategory) : Cᵒᵖ ⇒ cset ^c C :=
functor_curry !hom_functor
/-
we use (change_fun) to make sure that (to_fun_ob (yoneda_embedding C) c) will reduce to
(hom_functor_left c) instead of (functor_curry_rev_ob (hom_functor C) c)
-/
definition yoneda_embedding [constructor] (C : Precategory.{u v}) : C ⇒ cset ^c Cᵒᵖ :=
--(functor_curry_rev !hom_functor)
change_fun
(functor_curry_rev !hom_functor)
hom_functor_left
nat_trans_hom_functor_left
idp
idpo
notation `ɏ` := yoneda_embedding _
definition yoneda_lemma_hom_fun [unfold_full] (c : C) (F : Cᵒᵖ ⇒ cset)
(x : trunctype.carrier (F c)) (c' : Cᵒᵖ) : to_fun_ob (ɏ c) c' ⟶ F c' :=
begin
esimp [yoneda_embedding], intro f, exact F f x
end
definition yoneda_lemma_hom_nat (c : C) (F : Cᵒᵖ ⇒ cset)
(x : trunctype.carrier (F c)) {c₁ c₂ : Cᵒᵖ} (f : c₁ ⟶ c₂)
: F f ∘ yoneda_lemma_hom_fun c F x c₁ = yoneda_lemma_hom_fun c F x c₂ ∘ to_fun_hom (ɏ c) f :=
begin
esimp [yoneda_embedding], apply eq_of_homotopy, intro f',
refine _ ⬝ ap (λy, to_fun_hom F y x) !(@id_left _ C)⁻¹,
exact ap10 !(@respect_comp Cᵒᵖ cset)⁻¹ x
end
definition yoneda_lemma_hom [constructor] (c : C) (F : Cᵒᵖ ⇒ cset)
(x : trunctype.carrier (F c)) : ɏ c ⟹ F :=
begin
fapply nat_trans.mk,
{ exact yoneda_lemma_hom_fun c F x},
{ intro c₁ c₂ f, exact yoneda_lemma_hom_nat c F x f}
end
definition yoneda_lemma_equiv [constructor] (c : C)
(F : Cᵒᵖ ⇒ cset) : hom (ɏ c) F ≃ lift (trunctype.carrier (to_fun_ob F c)) :=
begin
fapply equiv.MK,
{ intro η, exact up (η c id)},
{ intro x, induction x with x, exact yoneda_lemma_hom c F x},
{ exact abstract begin intro x, induction x with x, esimp, apply ap up,
exact ap10 !respect_id x end end},
{ exact abstract begin intro η, esimp, apply nat_trans_eq,
intro c', esimp, apply eq_of_homotopy,
intro f,
transitivity (F f ∘ η c) id, reflexivity,
rewrite naturality, esimp [yoneda_embedding], rewrite [id_left], apply ap _ !id_left end end},
end
definition yoneda_lemma (c : C) (F : Cᵒᵖ ⇒ cset) :
homset (ɏ c) F ≅ functor_lift (F c) :=
begin
apply iso_of_equiv, esimp, apply yoneda_lemma_equiv,
end
theorem yoneda_lemma_natural_ob (F : Cᵒᵖ ⇒ cset) {c c' : C} (f : c' ⟶ c)
(η : ɏ c ⟹ F) :
to_fun_hom (functor_lift ∘f F) f (to_hom (yoneda_lemma c F) η) =
to_hom (yoneda_lemma c' F) (η ∘n to_fun_hom ɏ f) :=
begin
esimp [yoneda_lemma,yoneda_embedding], apply ap up,
transitivity (F f ∘ η c) id, reflexivity,
rewrite naturality,
esimp [yoneda_embedding],
apply ap (η c'),
esimp [yoneda_embedding, Opposite],
rewrite [+id_left,+id_right],
end
-- TODO: Investigate what is the bottleneck to type check the next theorem
-- attribute yoneda_lemma functor_lift Precategory_Set precategory_Set homset
-- yoneda_embedding nat_trans.compose functor_nat_trans_compose [reducible]
-- attribute tlift functor.compose [reducible]
theorem yoneda_lemma_natural_functor (c : C) (F F' : Cᵒᵖ ⇒ cset)
(θ : F ⟹ F') (η : to_fun_ob ɏ c ⟹ F) :
(functor_lift.{v u} ∘fn θ) c (to_hom (yoneda_lemma c F) η) =
proof to_hom (yoneda_lemma c F') (θ ∘n η) qed :=
by reflexivity
-- theorem xx.{u v} {C : Precategory.{u v}} (c : C) (F F' : Cᵒᵖ ⇒ set)
-- (θ : F ⟹ F') (η : to_fun_ob ɏ c ⟹ F) :
-- proof _ qed =
-- to_hom (yoneda_lemma c F') (θ ∘n η) :=
-- by reflexivity
-- theorem yy.{u v} {C : Precategory.{u v}} (c : C) (F F' : Cᵒᵖ ⇒ set)
-- (θ : F ⟹ F') (η : to_fun_ob ɏ c ⟹ F) :
-- (functor_lift.{v u} ∘fn θ) c (to_hom (yoneda_lemma c F) η) =
-- proof _ qed :=
-- by reflexivity
open equiv
definition fully_faithful_yoneda_embedding [instance] (C : Precategory.{u v}) :
fully_faithful (ɏ : C ⇒ cset ^c Cᵒᵖ) :=
begin
intro c c',
fapply is_equiv_of_equiv_of_homotopy,
{ symmetry, transitivity _, apply @equiv_of_iso (homset _ _),
exact @yoneda_lemma C c (ɏ c'), esimp [yoneda_embedding], exact !equiv_lift⁻¹ᵉ},
{ intro f, apply nat_trans_eq, intro c, apply eq_of_homotopy, intro f',
esimp [equiv.symm,equiv.trans],
esimp [yoneda_lemma,yoneda_embedding,Opposite],
rewrite [id_left,id_right]}
end
definition is_embedding_yoneda_embedding (C : Category.{u v}) :
is_embedding (ɏ : C → Cᵒᵖ ⇒ cset) :=
begin
intro c c', fapply is_equiv_of_equiv_of_homotopy,
{ exact !eq_equiv_iso ⬝e !iso_equiv_F_iso_F ⬝e !eq_equiv_iso⁻¹ᵉ},
{ intro p, induction p, esimp [equiv.trans, equiv.symm, to_fun_iso], -- to_fun_iso not unfolded
esimp [to_fun_iso],
rewrite -eq_of_iso_refl,
apply ap eq_of_iso, apply iso_eq, esimp,
apply nat_trans_eq, intro c',
apply eq_of_homotopy, intro f,
rewrite [▸*, category.category.id_left], apply id_right}
end
definition is_representable (F : Cᵒᵖ ⇒ cset) := Σ(c : C), ɏ c ≅ F
section
set_option apply.class_instance false
open functor.ops
definition is_prop_representable {C : Category.{u v}} (F : Cᵒᵖ ⇒ cset)
: is_prop (is_representable F) :=
begin
fapply is_trunc_equiv_closed,
{ unfold [is_representable],
rexact fiber.sigma_char ɏ F ⬝e sigma.sigma_equiv_sigma_right
(λc, @eq_equiv_iso (cset ^c2 Cᵒᵖ) _ (hom_functor_left c) F)},
{ apply function.is_prop_fiber_of_is_embedding, apply is_embedding_yoneda_embedding}
end
end
end yoneda

View file

@ -1,85 +0,0 @@
/-
Copyright (c) 2014 Jakob von Raumer. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Jakob von Raumer, Floris van Doorn
Ported from Coq HoTT
-/
import .iso algebra.bundled
open eq is_trunc iso category algebra nat unit
namespace category
structure groupoid [class] (ob : Type) extends parent : precategory ob :=
mk' :: (all_iso : Π ⦃a b : ob⦄ (f : hom a b), @is_iso ob parent a b f)
abbreviation all_iso := @groupoid.all_iso
attribute groupoid.all_iso [instance] [priority 3000]
attribute groupoid.to_precategory [unfold 2]
definition groupoid.mk [reducible] [constructor] {ob : Type} (C : precategory ob)
(H : Π (a b : ob) (f : a ⟶ b), is_iso f) : groupoid ob :=
precategory.rec_on C groupoid.mk' H
definition groupoid_of_group.{l} [constructor] (A : Type.{l}) [G : group A] :
groupoid.{0 l} unit :=
begin
fapply groupoid.mk; fapply precategory.mk: intros,
{ exact A},
{ exact _},
{ exact a_2 * a_1},
{ exact 1},
{ apply mul.assoc},
{ apply mul_one},
{ apply one_mul},
{ esimp [precategory.mk],
fapply is_iso.mk,
{ exact f⁻¹},
{ apply mul.right_inv},
{ apply mul.left_inv}},
end
definition hom_group [constructor] {A : Type} [G : groupoid A] (a : A) : group (hom a a) :=
begin
fapply group.mk,
apply is_set_hom,
intro f g, apply (comp f g),
intros f g h, apply (assoc f g h)⁻¹,
apply (ID a),
intro f, apply id_left,
intro f, apply id_right,
intro f, exact (iso.inverse f),
intro f, exact (iso.left_inverse f),
end
definition group_of_is_contr_groupoid {ob : Type} [H : is_contr ob]
[G : groupoid ob] : group (hom (center ob) (center ob)) := !hom_group
definition group_of_groupoid_unit [G : groupoid unit] : group (hom ⋆ ⋆) := !hom_group
-- Bundled version of categories
-- we don't use Groupoid.carrier explicitly, but rather use Groupoid.carrier (to_Precategory C)
structure Groupoid : Type :=
(carrier : Type)
(struct : groupoid carrier)
attribute Groupoid.struct [instance] [coercion]
definition Groupoid.to_Precategory [coercion] [reducible] [unfold 1] (C : Groupoid)
: Precategory :=
Precategory.mk (Groupoid.carrier C) _
attribute Groupoid._trans_of_to_Precategory_1 [unfold 1]
definition groupoid.Mk [reducible] [constructor] := Groupoid.mk
definition groupoid.MK [reducible] [constructor] (C : Precategory)
(H : Π (a b : C) (f : a ⟶ b), is_iso f) : Groupoid :=
Groupoid.mk C (groupoid.mk C H)
definition Groupoid.eta [unfold 1] (C : Groupoid) : Groupoid.mk C C = C :=
Groupoid.rec (λob c, idp) C
definition Groupoid_of_Group [constructor] (G : Group) : Groupoid :=
Groupoid.mk unit (groupoid_of_group G)
end category

View file

@ -1,469 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Floris van Doorn, Jakob von Raumer
-/
import .precategory types.sigma arity
open eq category prod equiv is_equiv sigma sigma.ops is_trunc
namespace iso
structure split_mono [class] {ob : Type} [C : precategory ob] {a b : ob} (f : a ⟶ b) :=
{retraction_of : b ⟶ a}
(retraction_comp : retraction_of ∘ f = id)
structure split_epi [class] {ob : Type} [C : precategory ob] {a b : ob} (f : a ⟶ b) :=
{section_of : b ⟶ a}
(comp_section : f ∘ section_of = id)
structure is_iso [class] {ob : Type} [C : precategory ob] {a b : ob} (f : a ⟶ b) :=
(inverse : b ⟶ a)
(left_inverse : inverse ∘ f = id)
(right_inverse : f ∘ inverse = id)
attribute is_iso.inverse [reducible]
open split_mono split_epi is_iso
abbreviation retraction_of [unfold 6] := @split_mono.retraction_of
abbreviation retraction_comp [unfold 6] := @split_mono.retraction_comp
abbreviation section_of [unfold 6] := @split_epi.section_of
abbreviation comp_section [unfold 6] := @split_epi.comp_section
abbreviation inverse [unfold 6] := @is_iso.inverse
abbreviation left_inverse [unfold 6] := @is_iso.left_inverse
abbreviation right_inverse [unfold 6] := @is_iso.right_inverse
postfix ⁻¹ := inverse
--a second notation for the inverse, which is not overloaded
postfix [parsing_only] `⁻¹ʰ`:std.prec.max_plus := inverse -- input using \-1h
variables {ob : Type} [C : precategory ob]
variables {a b c : ob} {g : b ⟶ c} {f : a ⟶ b} {h : b ⟶ a}
include C
definition split_mono_of_is_iso [constructor] [instance] [priority 300]
(f : a ⟶ b) [H : is_iso f] : split_mono f :=
split_mono.mk !left_inverse
definition split_epi_of_is_iso [constructor] [instance] [priority 300]
(f : a ⟶ b) [H : is_iso f] : split_epi f :=
split_epi.mk !right_inverse
definition is_iso_id [constructor] [instance] [priority 500] (a : ob) : is_iso (ID a) :=
is_iso.mk _ !id_id !id_id
definition is_iso_inverse [constructor] [instance] [priority 200] (f : a ⟶ b) {H : is_iso f}
: is_iso f⁻¹ :=
is_iso.mk _ !right_inverse !left_inverse
theorem left_inverse_eq_right_inverse {f : a ⟶ b} {g g' : hom b a}
(Hl : g ∘ f = id) (Hr : f ∘ g' = id) : g = g' :=
by rewrite [-(id_right g), -Hr, assoc, Hl, id_left]
theorem retraction_eq [H : split_mono f] (H2 : f ∘ h = id) : retraction_of f = h :=
left_inverse_eq_right_inverse !retraction_comp H2
theorem section_eq [H : split_epi f] (H2 : h ∘ f = id) : section_of f = h :=
(left_inverse_eq_right_inverse H2 !comp_section)⁻¹
theorem inverse_eq_right [H : is_iso f] (H2 : f ∘ h = id) : f⁻¹ = h :=
left_inverse_eq_right_inverse !left_inverse H2
theorem inverse_eq_left [H : is_iso f] (H2 : h ∘ f = id) : f⁻¹ = h :=
(left_inverse_eq_right_inverse H2 !right_inverse)⁻¹
theorem retraction_eq_section (f : a ⟶ b) [Hl : split_mono f] [Hr : split_epi f] :
retraction_of f = section_of f :=
retraction_eq !comp_section
definition is_iso_of_split_epi_of_split_mono [constructor] (f : a ⟶ b)
[Hl : split_mono f] [Hr : split_epi f] : is_iso f :=
is_iso.mk _ ((retraction_eq_section f) ▸ (retraction_comp f)) (comp_section f)
theorem inverse_unique (H H' : is_iso f) : @inverse _ _ _ _ f H = @inverse _ _ _ _ f H' :=
@inverse_eq_left _ _ _ _ _ _ H !left_inverse
theorem inverse_involutive (f : a ⟶ b) [H : is_iso f] [H : is_iso (f⁻¹)]
: (f⁻¹)⁻¹ = f :=
inverse_eq_right !left_inverse
theorem inverse_eq_inverse {f g : a ⟶ b} [H : is_iso f] [H : is_iso g] (p : f = g)
: f⁻¹ = g⁻¹ :=
by cases p;apply inverse_unique
theorem retraction_id (a : ob) : retraction_of (ID a) = id :=
retraction_eq !id_id
theorem section_id (a : ob) : section_of (ID a) = id :=
section_eq !id_id
theorem id_inverse (a : ob) [H : is_iso (ID a)] : (ID a)⁻¹ = id :=
inverse_eq_left !id_id
definition split_mono_comp [constructor] [instance] [priority 150] (g : b ⟶ c) (f : a ⟶ b)
[Hf : split_mono f] [Hg : split_mono g] : split_mono (g ∘ f) :=
split_mono.mk
(show (retraction_of f ∘ retraction_of g) ∘ g ∘ f = id,
by rewrite [-assoc, assoc _ g f, retraction_comp, id_left, retraction_comp])
definition split_epi_comp [constructor] [instance] [priority 150] (g : b ⟶ c) (f : a ⟶ b)
[Hf : split_epi f] [Hg : split_epi g] : split_epi (g ∘ f) :=
split_epi.mk
(show (g ∘ f) ∘ section_of f ∘ section_of g = id,
by rewrite [-assoc, {f ∘ _}assoc, comp_section, id_left, comp_section])
definition is_iso_comp [constructor] [instance] [priority 150] (g : b ⟶ c) (f : a ⟶ b)
[Hf : is_iso f] [Hg : is_iso g] : is_iso (g ∘ f) :=
!is_iso_of_split_epi_of_split_mono
theorem is_prop_is_iso [instance] (f : hom a b) : is_prop (is_iso f) :=
begin
apply is_prop.mk, intro H H',
cases H with g li ri, cases H' with g' li' ri',
fapply (apd0111 (@is_iso.mk ob C a b f)),
apply left_inverse_eq_right_inverse,
apply li,
apply ri',
apply is_prop.elimo,
apply is_prop.elimo,
end
end iso open iso
/- isomorphic objects -/
structure iso {ob : Type} [C : precategory ob] (a b : ob) :=
(to_hom : hom a b)
(struct : is_iso to_hom)
infix ` ≅ `:50 := iso
notation c ` ≅[`:50 C:0 `] `:0 c':50 := @iso C _ c c'
attribute iso.struct [instance] [priority 2000]
namespace iso
variables {ob : Type} [C : precategory ob]
variables {a b c : ob} {g : b ⟶ c} {f : a ⟶ b} {h : b ⟶ a}
include C
attribute to_hom [coercion]
protected definition MK [constructor] (f : a ⟶ b) (g : b ⟶ a)
(H1 : g ∘ f = id) (H2 : f ∘ g = id) :=
@(mk f) (is_iso.mk _ H1 H2)
variable {C}
definition to_inv [reducible] [unfold 5] (f : a ≅ b) : b ⟶ a := (to_hom f)⁻¹
definition to_left_inverse [unfold 5] (f : a ≅ b) : (to_hom f)⁻¹ ∘ (to_hom f) = id :=
left_inverse (to_hom f)
definition to_right_inverse [unfold 5] (f : a ≅ b) : (to_hom f) ∘ (to_hom f)⁻¹ = id :=
right_inverse (to_hom f)
variable [C]
protected definition refl [constructor] (a : ob) : a ≅ a :=
mk (ID a) _
protected definition symm [constructor] ⦃a b : ob⦄ (H : a ≅ b) : b ≅ a :=
mk (to_hom H)⁻¹ _
protected definition trans [constructor] ⦃a b c : ob⦄ (H1 : a ≅ b) (H2 : b ≅ c) : a ≅ c :=
mk (to_hom H2 ∘ to_hom H1) _
infixl ` ⬝i `:75 := iso.trans
postfix `⁻¹ⁱ`:(max + 1) := iso.symm
definition change_hom [constructor] (H : a ≅ b) (f : a ⟶ b) (p : to_hom H = f) : a ≅ b :=
iso.MK f (to_inv H) (p ▸ to_left_inverse H) (p ▸ to_right_inverse H)
definition change_inv [constructor] (H : a ≅ b) (g : b ⟶ a) (p : to_inv H = g) : a ≅ b :=
iso.MK (to_hom H) g (p ▸ to_left_inverse H) (p ▸ to_right_inverse H)
definition iso_mk_eq {f f' : a ⟶ b} [H : is_iso f] [H' : is_iso f'] (p : f = f')
: iso.mk f _ = iso.mk f' _ :=
apd011 iso.mk p !is_prop.elimo
variable {C}
definition iso_eq {f f' : a ≅ b} (p : to_hom f = to_hom f') : f = f' :=
by (cases f; cases f'; apply (iso_mk_eq p))
definition iso_pathover {X : Type} {x₁ x₂ : X} {p : x₁ = x₂} {a : X → ob} {b : X → ob}
{f₁ : a x₁ ≅ b x₁} {f₂ : a x₂ ≅ b x₂} (q : to_hom f₁ =[p] to_hom f₂) : f₁ =[p] f₂ :=
begin
cases f₁, cases f₂, esimp at q, induction q, apply pathover_idp_of_eq,
exact ap (iso.mk _) !is_prop.elim
end
variable [C]
-- The structure for isomorphism can be characterized up to equivalence by a sigma type.
protected definition sigma_char ⦃a b : ob⦄ : (Σ (f : hom a b), is_iso f) ≃ (a ≅ b) :=
begin
fapply (equiv.mk),
{intro S, apply iso.mk, apply (S.2)},
{fapply adjointify,
{intro p, cases p with f H, exact sigma.mk f H},
{intro p, cases p, apply idp},
{intro S, cases S, apply idp}},
end
-- The type of isomorphisms between two objects is a set
definition is_set_iso [instance] : is_set (a ≅ b) :=
begin
apply is_trunc_is_equiv_closed,
apply equiv.to_is_equiv (!iso.sigma_char),
end
definition iso_of_eq [unfold 5] (p : a = b) : a ≅ b :=
eq.rec_on p (iso.refl a)
definition hom_of_eq [reducible] [unfold 5] (p : a = b) : a ⟶ b :=
iso.to_hom (iso_of_eq p)
definition inv_of_eq [reducible] [unfold 5] (p : a = b) : b ⟶ a :=
iso.to_inv (iso_of_eq p)
definition iso_of_eq_inv (p : a = b) : iso_of_eq p⁻¹ = iso.symm (iso_of_eq p) :=
eq.rec_on p idp
theorem hom_of_eq_inv (p : a = b) : hom_of_eq p⁻¹ = inv_of_eq p :=
eq.rec_on p idp
theorem inv_of_eq_inv (p : a = b) : inv_of_eq p⁻¹ = hom_of_eq p :=
eq.rec_on p idp
definition iso_of_eq_con (p : a = b) (q : b = c)
: iso_of_eq (p ⬝ q) = iso.trans (iso_of_eq p) (iso_of_eq q) :=
eq.rec_on q (eq.rec_on p (iso_eq !id_id⁻¹))
definition transport_iso_of_eq (p : a = b) :
p ▸ !iso.refl = iso_of_eq p :=
by cases p; reflexivity
definition hom_pathover {X : Type} {x₁ x₂ : X} {p : x₁ = x₂} {a b : X → ob}
{f₁ : a x₁ ⟶ b x₁} {f₂ : a x₂ ⟶ b x₂} (q : hom_of_eq (ap b p) ∘ f₁ = f₂ ∘ hom_of_eq (ap a p)) :
f₁ =[p] f₂ :=
begin
induction p, apply pathover_idp_of_eq, exact !id_left⁻¹ ⬝ q ⬝ !id_right
end
definition hom_pathover_constant_left {X : Type} {x₁ x₂ : X} {p : x₁ = x₂} {a : ob} {b : X → ob}
{f₁ : a ⟶ b x₁} {f₂ : a ⟶ b x₂} (q : hom_of_eq (ap b p) ∘ f₁ = f₂) : f₁ =[p] f₂ :=
hom_pathover (q ⬝ !id_right⁻¹ ⬝ ap (λx, _ ∘ hom_of_eq x) !ap_constant⁻¹)
definition hom_pathover_constant_right {X : Type} {x₁ x₂ : X} {p : x₁ = x₂} {a : X → ob} {b : ob}
{f₁ : a x₁ ⟶ b} {f₂ : a x₂ ⟶ b} (q : f₁ = f₂ ∘ hom_of_eq (ap a p)) : f₁ =[p] f₂ :=
hom_pathover (ap (λx, hom_of_eq x ∘ _) !ap_constant ⬝ !id_left ⬝ q)
definition hom_pathover_id_left {p : a = b} {c : ob → ob} {f₁ : a ⟶ c a} {f₂ : b ⟶ c b}
(q : hom_of_eq (ap c p) ∘ f₁ = f₂ ∘ hom_of_eq p) : f₁ =[p] f₂ :=
hom_pathover (q ⬝ ap (λx, _ ∘ hom_of_eq x) !ap_id⁻¹)
definition hom_pathover_id_right {p : a = b} {c : ob → ob} {f₁ : c a ⟶ a} {f₂ : c b ⟶ b}
(q : hom_of_eq p ∘ f₁ = f₂ ∘ hom_of_eq (ap c p)) : f₁ =[p] f₂ :=
hom_pathover (ap (λx, hom_of_eq x ∘ _) !ap_id ⬝ q)
definition hom_pathover_id_left_id_right {p : a = b} {f₁ : a ⟶ a} {f₂ : b ⟶ b}
(q : hom_of_eq p ∘ f₁ = f₂ ∘ hom_of_eq p) : f₁ =[p] f₂ :=
hom_pathover_id_left (ap (λx, hom_of_eq x ∘ _) !ap_id ⬝ q)
definition hom_pathover_id_left_constant_right {p : a = b} {f₁ : a ⟶ c} {f₂ : b ⟶ c}
(q : f₁ = f₂ ∘ hom_of_eq p) : f₁ =[p] f₂ :=
hom_pathover_constant_right (q ⬝ ap (λx, _ ∘ hom_of_eq x) !ap_id⁻¹)
definition hom_pathover_constant_left_id_right {p : a = b} {f₁ : c ⟶ a} {f₂ : c ⟶ b}
(q : hom_of_eq p ∘ f₁ = f₂) : f₁ =[p] f₂ :=
hom_pathover_constant_left (ap (λx, hom_of_eq x ∘ _) !ap_id ⬝ q)
section
open funext
variables {X : Type} {x y : X} {F G : X → ob}
definition transport_hom_of_eq (p : F = G) (f : hom (F x) (F y))
: p ▸ f = hom_of_eq (apd10 p y) ∘ f ∘ inv_of_eq (apd10 p x) :=
by induction p; exact !id_leftright⁻¹
definition transport_hom_of_eq_right (p : x = y) (f : hom c (F x))
: p ▸ f = hom_of_eq (ap F p) ∘ f :=
by induction p; exact !id_left⁻¹
definition transport_hom_of_eq_left (p : x = y) (f : hom (F x) c)
: p ▸ f = f ∘ inv_of_eq (ap F p) :=
by induction p; exact !id_right⁻¹
definition transport_hom (p : F ~ G) (f : hom (F x) (F y))
: eq_of_homotopy p ▸ f = hom_of_eq (p y) ∘ f ∘ inv_of_eq (p x) :=
calc
eq_of_homotopy p ▸ f =
hom_of_eq (apd10 (eq_of_homotopy p) y) ∘ f ∘ inv_of_eq (apd10 (eq_of_homotopy p) x)
: transport_hom_of_eq
... = hom_of_eq (p y) ∘ f ∘ inv_of_eq (p x) : {right_inv apd10 p}
end
structure mono [class] (f : a ⟶ b) :=
(elim : ∀c (g h : hom c a), f ∘ g = f ∘ h → g = h)
structure epi [class] (f : a ⟶ b) :=
(elim : ∀c (g h : hom b c), g ∘ f = h ∘ f → g = h)
definition mono_of_split_mono [instance] (f : a ⟶ b) [H : split_mono f] : mono f :=
mono.mk
(λ c g h H,
calc
g = id ∘ g : by rewrite id_left
... = (retraction_of f ∘ f) ∘ g : by rewrite retraction_comp
... = (retraction_of f ∘ f) ∘ h : by rewrite [-assoc, H, -assoc]
... = id ∘ h : by rewrite retraction_comp
... = h : by rewrite id_left)
definition epi_of_split_epi [instance] (f : a ⟶ b) [H : split_epi f] : epi f :=
epi.mk
(λ c g h H,
calc
g = g ∘ id : by rewrite id_right
... = g ∘ f ∘ section_of f : by rewrite -(comp_section f)
... = h ∘ f ∘ section_of f : by rewrite [assoc, H, -assoc]
... = h ∘ id : by rewrite comp_section
... = h : by rewrite id_right)
definition mono_comp [instance] (g : b ⟶ c) (f : a ⟶ b) [Hf : mono f] [Hg : mono g]
: mono (g ∘ f) :=
mono.mk
(λ d h₁ h₂ H,
have H2 : g ∘ (f ∘ h₁) = g ∘ (f ∘ h₂),
begin
rewrite *assoc, exact H
end,
!mono.elim (!mono.elim H2))
definition epi_comp [instance] (g : b ⟶ c) (f : a ⟶ b) [Hf : epi f] [Hg : epi g]
: epi (g ∘ f) :=
epi.mk
(λ d h₁ h₂ H,
have H2 : (h₁ ∘ g) ∘ f = (h₂ ∘ g) ∘ f,
begin
rewrite -*assoc, exact H
end,
!epi.elim (!epi.elim H2))
end iso
attribute iso.refl [refl]
attribute iso.symm [symm]
attribute iso.trans [trans]
namespace iso
/-
rewrite lemmas for inverses, modified from
https://github.com/JasonGross/HoTT-categories/blob/master/theories/Categories/Category/Morphisms.v
-/
section
variables {ob : Type} [C : precategory ob] include C
variables {a b c d : ob} (f : b ⟶ a)
(r : c ⟶ d) (q : b ⟶ c) (p : a ⟶ b)
(g : d ⟶ c)
variable [Hq : is_iso q] include Hq
theorem comp.right_inverse : q ∘ q⁻¹ = id := !right_inverse
theorem comp.left_inverse : q⁻¹ ∘ q = id := !left_inverse
theorem inverse_comp_cancel_left : q⁻¹ ∘ (q ∘ p) = p :=
by rewrite [assoc, left_inverse, id_left]
theorem comp_inverse_cancel_left : q ∘ (q⁻¹ ∘ g) = g :=
by rewrite [assoc, right_inverse, id_left]
theorem comp_inverse_cancel_right : (r ∘ q) ∘ q⁻¹ = r :=
by rewrite [-assoc, right_inverse, id_right]
theorem inverse_comp_cancel_right : (f ∘ q⁻¹) ∘ q = f :=
by rewrite [-assoc, left_inverse, id_right]
theorem comp_inverse [Hp : is_iso p] [Hpq : is_iso (q ∘ p)] : (q ∘ p)⁻¹ʰ = p⁻¹ʰ ∘ q⁻¹ʰ :=
inverse_eq_left
(show (p⁻¹ʰ ∘ q⁻¹ʰ) ∘ q ∘ p = id, from
by rewrite [-assoc, inverse_comp_cancel_left, left_inverse])
theorem inverse_comp_inverse_left [H' : is_iso g] : (q⁻¹ ∘ g)⁻¹ = g⁻¹ ∘ q :=
inverse_involutive q ▸ comp_inverse q⁻¹ g
theorem inverse_comp_inverse_right [H' : is_iso f] : (q ∘ f⁻¹)⁻¹ = f ∘ q⁻¹ :=
inverse_involutive f ▸ comp_inverse q f⁻¹
theorem inverse_comp_inverse_inverse [H' : is_iso r] : (q⁻¹ ∘ r⁻¹)⁻¹ = r ∘ q :=
inverse_involutive r ▸ inverse_comp_inverse_left q r⁻¹
end
section
variables {ob : Type} {C : precategory ob} include C
variables {d c b a : ob}
{r' : c ⟶ d} {i : b ⟶ c} {f : b ⟶ a}
{r : c ⟶ d} {q : b ⟶ c} {p : a ⟶ b}
{g : d ⟶ c} {h : c ⟶ b} {p' : a ⟶ b}
{x : b ⟶ d} {z : a ⟶ c}
{y : d ⟶ b} {w : c ⟶ a}
variable [Hq : is_iso q] include Hq
theorem comp_eq_of_eq_inverse_comp (H : y = q⁻¹ ∘ g) : q ∘ y = g :=
H⁻¹ ▸ comp_inverse_cancel_left q g
theorem comp_eq_of_eq_comp_inverse (H : w = f ∘ q⁻¹) : w ∘ q = f :=
H⁻¹ ▸ inverse_comp_cancel_right f q
theorem eq_comp_of_inverse_comp_eq (H : q⁻¹ ∘ g = y) : g = q ∘ y :=
(comp_eq_of_eq_inverse_comp H⁻¹)⁻¹
theorem eq_comp_of_comp_inverse_eq (H : f ∘ q⁻¹ = w) : f = w ∘ q :=
(comp_eq_of_eq_comp_inverse H⁻¹)⁻¹
variable {Hq}
theorem inverse_comp_eq_of_eq_comp (H : z = q ∘ p) : q⁻¹ ∘ z = p :=
H⁻¹ ▸ inverse_comp_cancel_left q p
theorem comp_inverse_eq_of_eq_comp (H : x = r ∘ q) : x ∘ q⁻¹ = r :=
H⁻¹ ▸ comp_inverse_cancel_right r q
theorem eq_inverse_comp_of_comp_eq (H : q ∘ p = z) : p = q⁻¹ ∘ z :=
(inverse_comp_eq_of_eq_comp H⁻¹)⁻¹
theorem eq_comp_inverse_of_comp_eq (H : r ∘ q = x) : r = x ∘ q⁻¹ :=
(comp_inverse_eq_of_eq_comp H⁻¹)⁻¹
theorem eq_inverse_of_comp_eq_id' (H : h ∘ q = id) : h = q⁻¹ := (inverse_eq_left H)⁻¹
theorem eq_inverse_of_comp_eq_id (H : q ∘ h = id) : h = q⁻¹ := (inverse_eq_right H)⁻¹
theorem inverse_eq_of_id_eq_comp (H : id = h ∘ q) : q⁻¹ = h :=
(eq_inverse_of_comp_eq_id' H⁻¹)⁻¹
theorem inverse_eq_of_id_eq_comp' (H : id = q ∘ h) : q⁻¹ = h :=
(eq_inverse_of_comp_eq_id H⁻¹)⁻¹
variable [Hq]
theorem eq_of_comp_inverse_eq_id (H : i ∘ q⁻¹ = id) : i = q :=
eq_inverse_of_comp_eq_id' H ⬝ inverse_involutive q
theorem eq_of_inverse_comp_eq_id (H : q⁻¹ ∘ i = id) : i = q :=
eq_inverse_of_comp_eq_id H ⬝ inverse_involutive q
theorem eq_of_id_eq_comp_inverse (H : id = i ∘ q⁻¹) : q = i := (eq_of_comp_inverse_eq_id H⁻¹)⁻¹
theorem eq_of_id_eq_inverse_comp (H : id = q⁻¹ ∘ i) : q = i := (eq_of_inverse_comp_eq_id H⁻¹)⁻¹
theorem inverse_comp_id_comp : q⁻¹ ∘ id ∘ q = id :=
ap (λ x, _ ∘ x) !id_left ⬝ !comp.left_inverse
theorem comp_id_comp_inverse : q ∘ id ∘ q⁻¹ = id :=
ap (λ x, _ ∘ x) !id_left ⬝ !comp.right_inverse
variables (q)
theorem comp.cancel_left (H : q ∘ p = q ∘ p') : p = p' :=
by rewrite [-inverse_comp_cancel_left q p, H, inverse_comp_cancel_left q]
theorem comp.cancel_right (H : r ∘ q = r' ∘ q) : r = r' :=
by rewrite [-comp_inverse_cancel_right r q, H, comp_inverse_cancel_right _ q]
end
end iso
namespace iso
/- precomposition and postcomposition by an iso is an equivalence -/
definition is_equiv_postcompose [constructor] {ob : Type} [precategory ob] {a b c : ob}
(g : b ⟶ c) [is_iso g] : is_equiv (λ(f : a ⟶ b), g ∘ f) :=
begin
fapply adjointify,
{ exact λf', g⁻¹ ∘ f'},
{ intro f', apply comp_inverse_cancel_left},
{ intro f, apply inverse_comp_cancel_left}
end
definition equiv_postcompose [constructor] {ob : Type} [precategory ob] {a b c : ob}
(g : b ⟶ c) [is_iso g] : (a ⟶ b) ≃ (a ⟶ c) :=
equiv.mk (λ(f : a ⟶ b), g ∘ f) (is_equiv_postcompose g)
definition is_equiv_precompose [constructor] {ob : Type} [precategory ob] {a b c : ob}
(f : a ⟶ b) [is_iso f] : is_equiv (λ(g : b ⟶ c), g ∘ f) :=
begin
fapply adjointify,
{ exact λg', g' ∘ f⁻¹},
{ intro g', apply comp_inverse_cancel_right},
{ intro g, apply inverse_comp_cancel_right}
end
definition equiv_precompose [constructor] {ob : Type} [precategory ob] {a b c : ob}
(f : a ⟶ b) [is_iso f] : (b ⟶ c) ≃ (a ⟶ c) :=
equiv.mk (λ(g : b ⟶ c), g ∘ f) (is_equiv_precompose f)
end iso

View file

@ -1,44 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
colimit_functor ⊣ Δ ⊣ limit_functor
-/
import .colimits ..functor.adjoint
open eq functor category is_trunc prod nat_trans
namespace category
definition limit_functor_adjoint [constructor] (D I : Precategory) [H : has_limits_of_shape D I] :
constant_diagram D I ⊣ limit_functor D I :=
adjoint.mk'
begin
fapply natural_iso.MK,
{ intro dF η, induction dF with d F, esimp at *,
fapply hom_limit,
{ exact natural_map η},
{ intro i j f, exact !naturality ⬝ !id_right}},
{ esimp, intro dF dF' fθ, induction dF with d F, induction dF' with d' F',
induction fθ with f θ, esimp at *, apply eq_of_homotopy, intro η,
apply eq_hom_limit, intro i,
rewrite [assoc, limit_hom_limit_commute,
-assoc, assoc (limit_morphism F i), hom_limit_commute]},
{ esimp, intro dF f, induction dF with d F, esimp at *,
refine !limit_nat_trans ∘n constant_nat_trans I f},
{ esimp, intro dF, induction dF with d F, esimp, apply eq_of_homotopy, intro η,
apply nat_trans_eq, intro i, esimp, apply hom_limit_commute},
{ esimp, intro dF, induction dF with d F, esimp, apply eq_of_homotopy, intro f,
symmetry, apply eq_hom_limit, intro i, reflexivity}
end
/-
definition adjoint_colimit_functor [constructor] (D I : Precategory)
[H : has_colimits_of_shape D I] : colimit_functor D I ⊣ constant_diagram D I :=
have H : colimit_functor D I ⊣ (constant_diagram Dᵒᵖ Iᵒᵖ)ᵒᵖ', from _,
_
-/
end category

View file

@ -1,332 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
Colimits in a category
-/
import .limits ..constructions.opposite
open is_trunc functor nat_trans eq
-- we define colimits to be the dual of a limit
namespace category
variables {ob : Type} [C : precategory ob] {c c' : ob} (D I : Precategory)
include C
definition is_initial [reducible] (c : ob) := @is_terminal _ (opposite C) c
definition is_contr_of_is_initial (c d : ob) [H : is_initial d]
: is_contr (d ⟶ c) :=
H c
local attribute is_contr_of_is_initial [instance]
definition initial_morphism (c c' : ob) [H : is_initial c'] : c' ⟶ c :=
!center
definition hom_initial_eq [H : is_initial c'] (f f' : c' ⟶ c) : f = f' :=
!is_prop.elim
definition eq_initial_morphism [H : is_initial c'] (f : c' ⟶ c) : f = initial_morphism c c' :=
!is_prop.elim
definition initial_iso_initial {c c' : ob} (H : is_initial c) (K : is_initial c') : c ≅ c' :=
iso_of_opposite_iso (@terminal_iso_terminal _ (opposite C) _ _ H K)
theorem is_prop_is_initial [instance] : is_prop (is_initial c) := _
omit C
definition has_initial_object [reducible] : Type := has_terminal_object Dᵒᵖ
definition initial_object [unfold 2] [reducible] [H : has_initial_object D] : D :=
has_terminal_object.d Dᵒᵖ
definition has_initial_object.is_initial [H : has_initial_object D]
: is_initial (initial_object D) :=
@has_terminal_object.is_terminal (Opposite D) H
variable {D}
definition initial_object_iso_initial_object (H₁ H₂ : has_initial_object D)
: @initial_object D H₁ ≅ @initial_object D H₂ :=
initial_iso_initial (@has_initial_object.is_initial D H₁) (@has_initial_object.is_initial D H₂)
set_option pp.coercions true
theorem is_prop_has_initial_object [instance] (D : Category)
: is_prop (has_initial_object D) :=
is_prop_has_terminal_object (Category_opposite D)
variable (D)
abbreviation has_colimits_of_shape := has_limits_of_shape Dᵒᵖ Iᵒᵖ
/-
The next definitions states that a category is cocomplete with respect to diagrams
in a certain universe. "is_cocomplete.{o₁ h₁ o₂ h₂}" means that D is cocomplete
with respect to diagrams of type Precategory.{o₂ h₂}
-/
abbreviation is_cocomplete (D : Precategory) := is_complete Dᵒᵖ
definition has_colimits_of_shape_of_is_cocomplete [instance] [H : is_cocomplete D]
(I : Precategory) : has_colimits_of_shape D I := H Iᵒᵖ
section
open pi
theorem is_prop_has_colimits_of_shape [instance] (D : Category) (I : Precategory)
: is_prop (has_colimits_of_shape D I) :=
is_prop_has_limits_of_shape (Category_opposite D) _
theorem is_prop_is_cocomplete [instance] (D : Category) : is_prop (is_cocomplete D) :=
is_prop_is_complete (Category_opposite D)
end
variables {D I} (F : I ⇒ D) [H : has_colimits_of_shape D I] {i j : I}
include H
abbreviation cocone := (cone Fᵒᵖᶠ)ᵒᵖ
definition has_initial_object_cocone [H : has_colimits_of_shape D I]
(F : I ⇒ D) : has_initial_object (cocone F) :=
begin
unfold [has_colimits_of_shape,has_limits_of_shape] at H,
exact H Fᵒᵖᶠ
end
local attribute has_initial_object_cocone [instance]
definition colimit_cocone : cocone F := limit_cone Fᵒᵖᶠ
definition is_initial_colimit_cocone [instance] : is_initial (colimit_cocone F) :=
is_terminal_limit_cone Fᵒᵖᶠ
definition colimit_object : D :=
limit_object Fᵒᵖᶠ
definition colimit_nat_trans : constant_functor Iᵒᵖ (colimit_object F) ⟹ Fᵒᵖᶠ :=
limit_nat_trans Fᵒᵖᶠ
definition colimit_morphism (i : I) : F i ⟶ colimit_object F :=
limit_morphism Fᵒᵖᶠ i
variable {H}
theorem colimit_commute {i j : I} (f : i ⟶ j)
: colimit_morphism F j ∘ to_fun_hom F f = colimit_morphism F i :=
by rexact limit_commute Fᵒᵖᶠ f
variable [H]
definition colimit_cone_obj [constructor] {d : D} {η : Πi, F i ⟶ d}
(p : Π⦃j i : I⦄ (f : i ⟶ j), η j ∘ to_fun_hom F f = η i) : cone_obj Fᵒᵖᶠ :=
limit_cone_obj Fᵒᵖᶠ proof p qed
variable {H}
definition colimit_hom {d : D} (η : Πi, F i ⟶ d)
(p : Π⦃j i : I⦄ (f : i ⟶ j), η j ∘ to_fun_hom F f = η i) : colimit_object F ⟶ d :=
hom_limit Fᵒᵖᶠ η proof p qed
theorem colimit_hom_commute {d : D} (η : Πi, F i ⟶ d)
(p : Π⦃j i : I⦄ (f : i ⟶ j), η j ∘ to_fun_hom F f = η i) (i : I)
: colimit_hom F η p ∘ colimit_morphism F i = η i :=
by rexact hom_limit_commute Fᵒᵖᶠ η proof p qed i
definition colimit_cone_hom [constructor] {d : D} {η : Πi, F i ⟶ d}
(p : Π⦃j i : I⦄ (f : i ⟶ j), η j ∘ to_fun_hom F f = η i) {h : colimit_object F ⟶ d}
(q : Πi, h ∘ colimit_morphism F i = η i)
: cone_hom (colimit_cone_obj F p) (colimit_cocone F) :=
by rexact limit_cone_hom Fᵒᵖᶠ proof p qed proof q qed
variable {F}
theorem eq_colimit_hom {d : D} {η : Πi, F i ⟶ d}
(p : Π⦃j i : I⦄ (f : i ⟶ j), η j ∘ to_fun_hom F f = η i) {h : colimit_object F ⟶ d}
(q : Πi, h ∘ colimit_morphism F i = η i) : h = colimit_hom F η p :=
by rexact @eq_hom_limit _ _ Fᵒᵖᶠ _ _ _ proof p qed _ proof q qed
theorem colimit_cocone_unique {d : D} {η : Πi, F i ⟶ d}
(p : Π⦃j i : I⦄ (f : i ⟶ j), η j ∘ to_fun_hom F f = η i)
{h₁ : colimit_object F ⟶ d} (q₁ : Πi, h₁ ∘ colimit_morphism F i = η i)
{h₂ : colimit_object F ⟶ d} (q₂ : Πi, h₂ ∘ colimit_morphism F i = η i) : h₁ = h₂ :=
@limit_cone_unique _ _ Fᵒᵖᶠ _ _ _ proof p qed _ proof q₁ qed _ proof q₂ qed
definition colimit_hom_colimit [reducible] {F G : I ⇒ D} (η : F ⟹ G)
: colimit_object F ⟶ colimit_object G :=
colimit_hom _ (λi, colimit_morphism G i ∘ η i)
abstract by intro i j f; rewrite [-assoc,-naturality,assoc,colimit_commute] end
omit H
variable (F)
definition colimit_object_iso_colimit_object [constructor] (H₁ H₂ : has_colimits_of_shape D I) :
@(colimit_object F) H₁ ≅ @(colimit_object F) H₂ :=
iso_of_opposite_iso (limit_object_iso_limit_object Fᵒᵖᶠ H₁ H₂)
definition colimit_functor [constructor] (D I : Precategory) [H : has_colimits_of_shape D I]
: D ^c I ⇒ D :=
(limit_functor Dᵒᵖ Iᵒᵖ ∘f opposite_functor_opposite_left D I)ᵒᵖ'
section bin_coproducts
open bool prod.ops
definition has_binary_coproducts [reducible] (D : Precategory) := has_colimits_of_shape D c2
variables [K : has_binary_coproducts D] (d d' : D)
include K
definition coproduct_object : D :=
colimit_object (c2_functor D d d')
infixr `+l`:27 := coproduct_object
local infixr + := coproduct_object
definition inl : d ⟶ d + d' :=
colimit_morphism (c2_functor D d d') ff
definition inr : d' ⟶ d + d' :=
colimit_morphism (c2_functor D d d') tt
variables {d d'}
definition coproduct_hom {x : D} (f : d ⟶ x) (g : d' ⟶ x) : d + d' ⟶ x :=
colimit_hom (c2_functor D d d') (bool.rec f g)
(by intro b₁ b₂ f; induction b₁: induction b₂: esimp at *; try contradiction: apply id_right)
theorem coproduct_hom_inl {x : D} (f : d ⟶ x) (g : d' ⟶ x) : coproduct_hom f g ∘ !inl = f :=
colimit_hom_commute (c2_functor D d d') (bool.rec f g) _ ff
theorem coproduct_hom_inr {x : D} (f : d ⟶ x) (g : d' ⟶ x) : coproduct_hom f g ∘ !inr = g :=
colimit_hom_commute (c2_functor D d d') (bool.rec f g) _ tt
theorem eq_coproduct_hom {x : D} {f : d ⟶ x} {g : d' ⟶ x} {h : d + d' ⟶ x}
(p : h ∘ !inl = f) (q : h ∘ !inr = g) : h = coproduct_hom f g :=
eq_colimit_hom _ (bool.rec p q)
theorem coproduct_cocone_unique {x : D} {f : d ⟶ x} {g : d' ⟶ x}
{h₁ : d + d' ⟶ x} (p₁ : h₁ ∘ !inl = f) (q₁ : h₁ ∘ !inr = g)
{h₂ : d + d' ⟶ x} (p₂ : h₂ ∘ !inl = f) (q₂ : h₂ ∘ !inr = g) : h₁ = h₂ :=
eq_coproduct_hom p₁ q₁ ⬝ (eq_coproduct_hom p₂ q₂)⁻¹
variable (D)
-- TODO: define this in terms of colimit_functor and functor_two_left (in exponential_laws)
definition coproduct_functor [constructor] : D ×c D ⇒ D :=
functor.mk
(λx, coproduct_object x.1 x.2)
(λx y f, coproduct_hom (!inl ∘ f.1) (!inr ∘ f.2))
abstract begin intro x, symmetry, apply eq_coproduct_hom: apply id_comp_eq_comp_id end end
abstract begin intro x y z g f, symmetry, apply eq_coproduct_hom,
rewrite [-assoc,coproduct_hom_inl,assoc,coproduct_hom_inl,-assoc],
rewrite [-assoc,coproduct_hom_inr,assoc,coproduct_hom_inr,-assoc] end end
omit K
variables {D} (d d')
definition coproduct_object_iso_coproduct_object [constructor] (H₁ H₂ : has_binary_coproducts D) :
@coproduct_object D H₁ d d' ≅ @coproduct_object D H₂ d d' :=
colimit_object_iso_colimit_object _ H₁ H₂
end bin_coproducts
/-
intentionally we define coproducts in terms of colimits,
but coequalizers in terms of equalizers, to see which characterization is more useful
-/
section coequalizers
open bool prod.ops sum equalizer_category_hom
definition has_coequalizers [reducible] (D : Precategory) := has_equalizers Dᵒᵖ
variables [K : has_coequalizers D]
include K
variables {d d' x : D} (f g : d ⟶ d')
definition coequalizer_object : D :=
!(@equalizer_object Dᵒᵖ) f g
definition coequalizer : d' ⟶ coequalizer_object f g :=
!(@equalizer Dᵒᵖ)
theorem coequalizes : coequalizer f g ∘ f = coequalizer f g ∘ g :=
by rexact !(@equalizes Dᵒᵖ)
variables {f g}
definition coequalizer_hom (h : d' ⟶ x) (p : h ∘ f = h ∘ g) : coequalizer_object f g ⟶ x :=
!(@hom_equalizer Dᵒᵖ) proof p qed
theorem coequalizer_hom_coequalizer (h : d' ⟶ x) (p : h ∘ f = h ∘ g)
: coequalizer_hom h p ∘ coequalizer f g = h :=
by rexact !(@equalizer_hom_equalizer Dᵒᵖ)
theorem eq_coequalizer_hom {h : d' ⟶ x} (p : h ∘ f = h ∘ g) {i : coequalizer_object f g ⟶ x}
(q : i ∘ coequalizer f g = h) : i = coequalizer_hom h p :=
by rexact !(@eq_hom_equalizer Dᵒᵖ) proof q qed
theorem coequalizer_cocone_unique {h : d' ⟶ x} (p : h ∘ f = h ∘ g)
{i₁ : coequalizer_object f g ⟶ x} (q₁ : i₁ ∘ coequalizer f g = h)
{i₂ : coequalizer_object f g ⟶ x} (q₂ : i₂ ∘ coequalizer f g = h) : i₁ = i₂ :=
!(@equalizer_cone_unique Dᵒᵖ) proof p qed proof q₁ qed proof q₂ qed
omit K
variables (f g)
definition coequalizer_object_iso_coequalizer_object [constructor] (H₁ H₂ : has_coequalizers D) :
@coequalizer_object D H₁ _ _ f g ≅ @coequalizer_object D H₂ _ _ f g :=
iso_of_opposite_iso !(@equalizer_object_iso_equalizer_object Dᵒᵖ)
end coequalizers
section pushouts
open bool prod.ops sum pullback_category_hom
definition has_pushouts [reducible] (D : Precategory) := has_pullbacks Dᵒᵖ
variables [K : has_pushouts D]
include K
variables {d₁ d₂ d₃ x : D} (f : d₁ ⟶ d₂) (g : d₁ ⟶ d₃)
definition pushout_object : D :=
!(@pullback_object Dᵒᵖ) f g
definition pushout : d₃ ⟶ pushout_object f g :=
!(@pullback Dᵒᵖ)
definition pushout_rev : d₂ ⟶ pushout_object f g :=
!(@pullback_rev Dᵒᵖ)
theorem pushout_commutes : pushout_rev f g ∘ f = pushout f g ∘ g :=
by rexact !(@pullback_commutes Dᵒᵖ)
variables {f g}
definition pushout_hom (h₁ : d₂ ⟶ x) (h₂ : d₃ ⟶ x) (p : h₁ ∘ f = h₂ ∘ g)
: pushout_object f g ⟶ x :=
!(@hom_pullback Dᵒᵖ) proof p qed
theorem pushout_hom_pushout (h₁ : d₂ ⟶ x) (h₂ : d₃ ⟶ x) (p : h₁ ∘ f = h₂ ∘ g)
: pushout_hom h₁ h₂ p ∘ pushout f g = h₂ :=
by rexact !(@pullback_hom_pullback Dᵒᵖ)
theorem pushout_hom_pushout_rev (h₁ : d₂ ⟶ x) (h₂ : d₃ ⟶ x) (p : h₁ ∘ f = h₂ ∘ g)
: pushout_hom h₁ h₂ p ∘ pushout_rev f g = h₁ :=
by rexact !(@pullback_rev_hom_pullback Dᵒᵖ)
theorem eq_pushout_hom {h₁ : d₂ ⟶ x} {h₂ : d₃ ⟶ x} (p : h₁ ∘ f = h₂ ∘ g)
{i : pushout_object f g ⟶ x} (q : i ∘ pushout f g = h₂) (r : i ∘ pushout_rev f g = h₁)
: i = pushout_hom h₁ h₂ p :=
by rexact !(@eq_hom_pullback Dᵒᵖ) proof q qed proof r qed
theorem pushout_cocone_unique {h₁ : d₂ ⟶ x} {h₂ : d₃ ⟶ x} (p : h₁ ∘ f = h₂ ∘ g)
{i₁ : pushout_object f g ⟶ x} (q₁ : i₁ ∘ pushout f g = h₂) (r₁ : i₁ ∘ pushout_rev f g = h₁)
{i₂ : pushout_object f g ⟶ x} (q₂ : i₂ ∘ pushout f g = h₂) (r₂ : i₂ ∘ pushout_rev f g = h₁)
: i₁ = i₂ :=
!(@pullback_cone_unique Dᵒᵖ) proof p qed proof q₁ qed proof r₁ qed proof q₂ qed proof r₂ qed
omit K
variables (f g)
definition pushout_object_iso_pushout_object [constructor] (H₁ H₂ : has_pushouts D) :
@pushout_object D H₁ _ _ _ f g ≅ @pushout_object D H₂ _ _ _ f g :=
iso_of_opposite_iso !(@pullback_object_iso_pullback_object (Opposite D))
end pushouts
definition has_limits_of_shape_op_op [H : has_limits_of_shape D Iᵒᵖᵒᵖ]
: has_limits_of_shape D I :=
by induction I with I Is; induction Is; exact H
namespace ops
infixr + := coproduct_object
end ops
end category

View file

@ -1,7 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
-/
import .set .functor .adjoint .functor_preserve

View file

@ -1,148 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn, Jakob von Raumer
Functor category has (co)limits if the codomain has them
-/
import .colimits
open functor nat_trans eq is_trunc
namespace category
-- preservation of limits
variables {D C I : Precategory}
definition functor_limit_object [constructor]
[H : has_limits_of_shape D I] (F : I ⇒ D ^c C) : C ⇒ D :=
begin
have lem : Π(c d : carrier C) (f : hom c d) ⦃i j : carrier I⦄ (k : i ⟶ j),
(constant2_functor F d) k ∘ to_fun_hom (F i) f ∘ limit_morphism (constant2_functor F c) i =
to_fun_hom (F j) f ∘ limit_morphism (constant2_functor F c) j,
begin intro c d f i j k, rewrite [-limit_commute _ k,▸*,+assoc,▸*,-naturality (F k) f] end,
fapply functor.mk,
{ intro c, exact limit_object (constant2_functor F c)},
{ intro c d f, fapply hom_limit,
{ intro i, refine to_fun_hom (F i) f ∘ !limit_morphism},
{ apply lem}},
{ exact abstract begin intro c, symmetry, apply eq_hom_limit, intro i,
rewrite [id_right,respect_id,▸*,id_left] end end},
{ intro a b c g f, symmetry, apply eq_hom_limit, intro i, -- report: adding abstract fails here
rewrite [respect_comp,assoc,hom_limit_commute,-assoc,hom_limit_commute,assoc]}
end
definition functor_limit_cone [constructor]
[H : has_limits_of_shape D I] (F : I ⇒ D ^c C) : cone_obj F :=
begin
fapply cone_obj.mk,
{ exact functor_limit_object F},
{ fapply nat_trans.mk,
{ intro i, esimp, fapply nat_trans.mk,
{ intro c, esimp, apply limit_morphism},
{ intro c d f, rewrite [▸*,hom_limit_commute (constant2_functor F d)]}},
{ intro i j k, apply nat_trans_eq, intro c,
rewrite [▸*,id_right,limit_commute (constant2_functor F c)]}}
end
variables (D C I)
definition has_limits_of_shape_functor [instance] [H : has_limits_of_shape D I]
: has_limits_of_shape (D ^c C) I :=
begin
intro F, fapply has_terminal_object.mk,
{ exact functor_limit_cone F},
{ intro c, esimp at *, induction c with G η, induction η with η p, esimp at *,
fapply is_contr.mk,
{ fapply cone_hom.mk,
{ fapply nat_trans.mk,
{ intro c, esimp, fapply hom_limit,
{ intro i, esimp, exact η i c},
{ intro i j k, esimp, exact ap010 natural_map (p k) c ⬝ !id_right}},
{ intro c d f, esimp, fapply @limit_cone_unique,
{ intro i, esimp, exact to_fun_hom (F i) f ∘ η i c},
{ intro i j k, rewrite [▸*,assoc,-naturality,-assoc,-compose_def,p k,▸*,id_right]},
{ intro i, rewrite [assoc, hom_limit_commute (constant2_functor F d),▸*,-assoc,
hom_limit_commute]},
{ intro i, rewrite [assoc, hom_limit_commute (constant2_functor F d),naturality]}}},
{ intro i, apply nat_trans_eq, intro c,
rewrite [▸*,hom_limit_commute (constant2_functor F c)]}},
{ intro h, induction h with f q, apply cone_hom_eq,
apply nat_trans_eq, intro c, esimp at *, symmetry,
apply eq_hom_limit, intro i, exact ap010 natural_map (q i) c}}
end
definition is_complete_functor [instance] [H : is_complete D] : is_complete (D ^c C) :=
λI, _
variables {D C I}
-- preservation of colimits
-- definition constant2_functor_op [constructor] (F : I ⇒ (D ^c C)ᵒᵖ) (c : C) : I ⇒ D :=
-- proof
-- functor.mk (λi, to_fun_ob (F i) c)
-- (λi j f, natural_map (F f) c)
-- abstract (λi, ap010 natural_map !respect_id c ⬝ proof idp qed) end
-- abstract (λi j k g f, ap010 natural_map !respect_comp c) end
-- qed
definition functor_colimit_object [constructor]
[H : has_colimits_of_shape D I] (F : Iᵒᵖ ⇒ (D ^c C)ᵒᵖ) : C ⇒ D :=
begin
fapply functor.mk,
{ intro c, exact colimit_object (constant2_functor Fᵒᵖ' c)},
{ intro c d f, apply colimit_hom_colimit, apply constant2_functor_natural _ f},
{ exact abstract begin intro c, symmetry, apply eq_colimit_hom, intro i,
rewrite [id_left,▸*,respect_id,id_right] end end},
{ intro a b c g f, symmetry, apply eq_colimit_hom, intro i, -- report: adding abstract fails here
rewrite [▸*,respect_comp,-assoc,colimit_hom_commute,assoc,colimit_hom_commute,-assoc]}
end
definition functor_colimit_cone [constructor]
[H : has_colimits_of_shape D I] (F : Iᵒᵖ ⇒ (D ^c C)ᵒᵖ) : cone_obj F :=
begin
fapply cone_obj.mk,
{ exact functor_colimit_object F},
{ fapply nat_trans.mk,
{ intro i, esimp, fapply nat_trans.mk,
{ intro c, esimp, apply colimit_morphism},
{ intro c d f, apply colimit_hom_commute (constant2_functor Fᵒᵖ' c)}},
{ intro i j k, apply nat_trans_eq, intro c,
rewrite [▸*,id_left], apply colimit_commute (constant2_functor Fᵒᵖ' c)}}
end
variables (D C I)
definition has_colimits_of_shape_functor [instance] [H : has_colimits_of_shape D I]
: has_colimits_of_shape (D ^c C) I :=
begin
intro F, fapply has_terminal_object.mk,
{ exact functor_colimit_cone F},
{ intro c, esimp at *, induction c with G η, induction η with η p, esimp at *,
fapply is_contr.mk,
{ fapply cone_hom.mk,
{ fapply nat_trans.mk,
{ intro c, esimp, fapply colimit_hom,
{ intro i, esimp, exact η i c},
{ intro i j k, esimp, exact ap010 natural_map (p k) c ⬝ !id_left}},
{ intro c d f, esimp, fapply @colimit_cocone_unique,
{ intro i, esimp, exact η i d ∘ to_fun_hom (F i) f},
{ intro i j k, rewrite [▸*,-assoc,naturality,assoc,-compose_def,p k,▸*,id_left]},
{ intro i, rewrite [-assoc, colimit_hom_commute (constant2_functor Fᵒᵖ' c),
▸*, naturality]},
{ intro i, rewrite [-assoc, colimit_hom_commute (constant2_functor Fᵒᵖ' c),▸*,assoc,
colimit_hom_commute (constant2_functor Fᵒᵖ' d)]}}},
{ intro i, apply nat_trans_eq, intro c,
rewrite [▸*,colimit_hom_commute (constant2_functor Fᵒᵖ' c)]}},
{ intro h, induction h with f q, apply cone_hom_eq,
apply nat_trans_eq, intro c, esimp at *, symmetry,
apply eq_colimit_hom, intro i, exact ap010 natural_map (q i) c}}
end
local attribute has_limits_of_shape_op_op [instance] [priority 1]
universe variables u v
definition is_cocomplete_functor [instance] [H : is_cocomplete.{_ _ u v} D]
: is_cocomplete.{_ _ u v} (D ^c C) :=
λI, _
end category

View file

@ -1,125 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
Functors preserving limits
-/
import .colimits ..functor.yoneda ..functor.adjoint
open eq functor yoneda is_trunc nat_trans
namespace category
variables {I C D : Precategory} {F : I ⇒ C} {G : C ⇒ D}
/- notions of preservation of limits -/
definition preserves_limits_of_shape [class] (G : C ⇒ D) (I : Precategory)
[H : has_limits_of_shape C I] :=
Π(F : I ⇒ C), is_terminal (cone_obj_compose G (limit_cone F))
definition preserves_existing_limits_of_shape [class] (G : C ⇒ D) (I : Precategory) :=
Π(F : I ⇒ C) [H : has_terminal_object (cone F)],
is_terminal (cone_obj_compose G (terminal_object (cone F)))
definition preserves_existing_limits [class] (G : C ⇒ D) :=
Π(I : Precategory) (F : I ⇒ C) [H : has_terminal_object (cone F)],
is_terminal (cone_obj_compose G (terminal_object (cone F)))
definition preserves_limits [class] (G : C ⇒ D) [H : is_complete C] :=
Π(I : Precategory) [H : has_limits_of_shape C I] (F : I ⇒ C),
is_terminal (cone_obj_compose G (limit_cone F))
definition preserves_chosen_limits_of_shape [class] (G : C ⇒ D) (I : Precategory)
[H : has_limits_of_shape C I] [H : has_limits_of_shape D I] :=
Π(F : I ⇒ C), cone_obj_compose G (limit_cone F) = limit_cone (G ∘f F)
definition preserves_chosen_limits [class] (G : C ⇒ D)
[H : is_complete C] [H : is_complete D] :=
Π(I : Precategory) (F : I ⇒ C), cone_obj_compose G (limit_cone F) = limit_cone (G ∘f F)
/- basic instances -/
definition preserves_limits_of_shape_of_preserves_limits [instance] (G : C ⇒ D)
(I : Precategory) [H : is_complete C] [H : preserves_limits G]
: preserves_limits_of_shape G I := H I
definition preserves_chosen_limits_of_shape_of_preserves_chosen_limits [instance] (G : C ⇒ D)
(I : Precategory) [H : is_complete C] [H : is_complete D] [K : preserves_chosen_limits G]
: preserves_chosen_limits_of_shape G I := K I
/- yoneda preserves existing limits -/
local attribute category.to_precategory [constructor]
definition preserves_existing_limits_yoneda_embedding_lemma [constructor]
(y : cone_obj F)
[H : is_terminal y] {G : Cᵒᵖ ⇒ cset} (η : constant_functor I G ⟹ ɏ ∘f F) :
G ⟹ hom_functor_left (cone_to_obj y) :=
begin
fapply nat_trans.mk: esimp,
{ intro c x, fapply to_hom_limit,
{ intro i, exact η i c x},
{ exact abstract begin
intro i j k,
exact !id_right⁻¹ ⬝ !assoc⁻¹ ⬝ ap0100 natural_map (naturality η k) c x end end
}},
-- [BUG] abstracting here creates multiple lemmas proving this fact
{ intro c c' f, apply eq_of_homotopy, intro x,
rewrite [id_left], apply to_eq_hom_limit, intro i,
refine !assoc ⬝ _, rewrite to_hom_limit_commute,
refine _ ⬝ ap10 (naturality (η i) f) x, rewrite [▸*, id_left]}
-- abstracting here fails
end
theorem preserves_existing_limits_yoneda_embedding (C : Precategory)
: preserves_existing_limits (yoneda_embedding C) :=
begin
intro I F H Gη, induction H with y H, induction Gη with G η, esimp at *,
have lem : Π(i : carrier I),
nat_trans_hom_functor_left (natural_map (cone_to_nat y) i)
∘n @preserves_existing_limits_yoneda_embedding_lemma I C F y H G η = natural_map η i,
begin
intro i, apply nat_trans_eq, intro c, apply eq_of_homotopy, intro x,
esimp, refine !assoc ⬝ !id_right ⬝ !to_hom_limit_commute
end,
fapply is_contr.mk,
{ fapply cone_hom.mk,
{ exact preserves_existing_limits_yoneda_embedding_lemma y η},
{ exact lem}},
{ intro v, apply cone_hom_eq, esimp, apply nat_trans_eq, esimp, intro c,
apply eq_of_homotopy, intro x, refine (to_eq_hom_limit _ _)⁻¹,
intro i, refine !id_right⁻¹ ⬝ !assoc⁻¹ ⬝ _,
exact ap0100 natural_map (cone_to_eq v i) c x}
end
/- left adjoint functors preserve limits -/
/- definition preserves_existing_limits_left_adjoint_lemma {C D : Precategory} (F : C ⇒ D)
[H : is_left_adjoint F] {I : Precategory} {G : I ⇒ C} (y : cone_obj G) [K : is_terminal y]
{d : carrier D} (η : constant_functor I d ⟹ F ∘f G) : d ⟶ to_fun_ob F (cone_to_obj y) :=
begin
let η := unit F, let θ := counit F, exact sorry
end
theorem preserves_existing_limits_left_adjoint {C D : Precategory} (F : C ⇒ D)
[H : is_left_adjoint F] : preserves_existing_limits F :=
begin
intro I G K dη, induction K with y K, induction dη with d η, esimp at *,
-- have lem : Π (i : carrier I),
-- nat_trans_hom_functor_left (natural_map (cone_to_nat y) i)
-- ∘n preserves_existing_limits_yoneda_embedding_lemma y η = natural_map η i,
-- { intro i, apply nat_trans_eq, intro c, apply eq_of_homotopy, intro x,
-- esimp, refine !assoc ⬝ !id_right ⬝ !to_hom_limit_commute},
fapply is_contr.mk,
{ fapply cone_hom.mk,
{ esimp, exact sorry},
{ exact lem}},
{ intro v, apply cone_hom_eq, esimp, apply nat_trans_eq, esimp, intro c,
apply eq_of_homotopy, intro x, refine (to_eq_hom_limit _ _)⁻¹,
intro i, refine !id_right⁻¹ ⬝ !assoc⁻¹ ⬝ _,
exact ap0100 natural_map (cone_to_eq v i) c x}
end-/
end category

View file

@ -1,417 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
Limits in a category
-/
import ..constructions.cone ..constructions.discrete ..constructions.product
..constructions.finite_cats ..category ..constructions.functor
open is_trunc functor nat_trans eq
namespace category
variables {ob : Type} [C : precategory ob] {c c' : ob} (D I : Precategory)
include C
definition is_terminal [class] (c : ob) := Πd, is_contr (d ⟶ c)
definition is_contr_of_is_terminal (c d : ob) [H : is_terminal d] : is_contr (c ⟶ d) :=
H c
local attribute is_contr_of_is_terminal [instance]
definition terminal_morphism (c c' : ob) [H : is_terminal c'] : c ⟶ c' :=
!center
definition hom_terminal_eq [H : is_terminal c'] (f f' : c ⟶ c') : f = f' :=
!is_prop.elim
definition eq_terminal_morphism [H : is_terminal c'] (f : c ⟶ c') : f = terminal_morphism c c' :=
!is_prop.elim
definition terminal_iso_terminal (c c' : ob) [H : is_terminal c] [K : is_terminal c']
: c ≅ c' :=
iso.MK !terminal_morphism !terminal_morphism !hom_terminal_eq !hom_terminal_eq
local attribute is_terminal [reducible]
theorem is_prop_is_terminal [instance] : is_prop (is_terminal c) :=
_
omit C
structure has_terminal_object [class] (D : Precategory) :=
(d : D)
(is_terminal : is_terminal d)
definition terminal_object [reducible] [unfold 2] := @has_terminal_object.d
attribute has_terminal_object.is_terminal [instance]
variable {D}
definition terminal_object_iso_terminal_object (H₁ H₂ : has_terminal_object D)
: @terminal_object D H₁ ≅ @terminal_object D H₂ :=
!terminal_iso_terminal
theorem is_prop_has_terminal_object [instance] (D : Category)
: is_prop (has_terminal_object D) :=
begin
apply is_prop.mk, intro t₁ t₂, induction t₁ with d₁ H₁, induction t₂ with d₂ H₂,
have p : d₁ = d₂,
begin apply eq_of_iso, apply terminal_iso_terminal end,
induction p, exact ap _ !is_prop.elim
end
variable (D)
definition has_limits_of_shape [class] := Π(F : I ⇒ D), has_terminal_object (cone F)
/-
The next definitions states that a category is complete with respect to diagrams
in a certain universe. "is_complete.{o₁ h₁ o₂ h₂}" means that D is complete
with respect to diagrams with shape in Precategory.{o₂ h₂}
-/
definition is_complete.{o₁ h₁ o₂ h₂} [class] (D : Precategory.{o₁ h₁}) :=
Π(I : Precategory.{o₂ h₂}), has_limits_of_shape D I
definition has_limits_of_shape_of_is_complete [instance] [H : is_complete D] (I : Precategory)
: has_limits_of_shape D I := H I
section
open pi
theorem is_prop_has_limits_of_shape [instance] (D : Category) (I : Precategory)
: is_prop (has_limits_of_shape D I) :=
by apply is_trunc_pi; intro F; exact is_prop_has_terminal_object (Category_cone F)
local attribute is_complete [reducible]
theorem is_prop_is_complete [instance] (D : Category) : is_prop (is_complete D) := _
end
variables {D I}
definition has_terminal_object_cone [H : has_limits_of_shape D I]
(F : I ⇒ D) : has_terminal_object (cone F) := H F
local attribute has_terminal_object_cone [instance]
variables (F : I ⇒ D) [H : has_limits_of_shape D I] {i j : I}
include H
definition limit_cone : cone F := !terminal_object
definition is_terminal_limit_cone [instance] : is_terminal (limit_cone F) :=
has_terminal_object.is_terminal _
section specific_limit
omit H
variable {F}
variables (x : cone_obj F) [K : is_terminal x]
include K
definition to_limit_object : D :=
cone_to_obj x
definition to_limit_nat_trans : constant_functor I (to_limit_object x) ⟹ F :=
cone_to_nat x
definition to_limit_morphism (i : I) : to_limit_object x ⟶ F i :=
to_limit_nat_trans x i
theorem to_limit_commute {i j : I} (f : i ⟶ j)
: to_fun_hom F f ∘ to_limit_morphism x i = to_limit_morphism x j :=
naturality (to_limit_nat_trans x) f ⬝ !id_right
definition to_limit_cone_obj [constructor] {d : D} {η : Πi, d ⟶ F i}
(p : Π⦃i j : I⦄ (f : i ⟶ j), to_fun_hom F f ∘ η i = η j) : cone_obj F :=
cone_obj.mk d (nat_trans.mk η (λa b f, p f ⬝ !id_right⁻¹))
definition to_hom_limit {d : D} (η : Πi, d ⟶ F i)
(p : Π⦃i j : I⦄ (f : i ⟶ j), to_fun_hom F f ∘ η i = η j) : d ⟶ to_limit_object x :=
cone_to_hom (terminal_morphism (to_limit_cone_obj x p) x)
theorem to_hom_limit_commute {d : D} (η : Πi, d ⟶ F i)
(p : Π⦃i j : I⦄ (f : i ⟶ j), to_fun_hom F f ∘ η i = η j) (i : I)
: to_limit_morphism x i ∘ to_hom_limit x η p = η i :=
cone_to_eq (terminal_morphism (to_limit_cone_obj x p) x) i
definition to_limit_cone_hom [constructor] {d : D} {η : Πi, d ⟶ F i}
(p : Π⦃i j : I⦄ (f : i ⟶ j), to_fun_hom F f ∘ η i = η j) {h : d ⟶ to_limit_object x}
(q : Πi, to_limit_morphism x i ∘ h = η i)
: cone_hom (to_limit_cone_obj x p) x :=
cone_hom.mk h q
variable {x}
theorem to_eq_hom_limit {d : D} {η : Πi, d ⟶ F i}
(p : Π⦃i j : I⦄ (f : i ⟶ j), to_fun_hom F f ∘ η i = η j) {h : d ⟶ to_limit_object x}
(q : Πi, to_limit_morphism x i ∘ h = η i) : h = to_hom_limit x η p :=
ap cone_to_hom (eq_terminal_morphism (to_limit_cone_hom x p q))
theorem to_limit_cone_unique {d : D} {η : Πi, d ⟶ F i}
(p : Π⦃i j : I⦄ (f : i ⟶ j), to_fun_hom F f ∘ η i = η j)
{h₁ : d ⟶ to_limit_object x} (q₁ : Πi, to_limit_morphism x i ∘ h₁ = η i)
{h₂ : d ⟶ to_limit_object x} (q₂ : Πi, to_limit_morphism x i ∘ h₂ = η i): h₁ = h₂ :=
to_eq_hom_limit p q₁ ⬝ (to_eq_hom_limit p q₂)⁻¹
omit K
definition to_limit_object_iso_to_limit_object [constructor] (x y : cone_obj F)
[K : is_terminal x] [L : is_terminal y] : to_limit_object x ≅ to_limit_object y :=
cone_iso_pr1 !terminal_iso_terminal
end specific_limit
/-
TODO: relate below definitions to above definitions.
However, type class resolution seems to fail...
-/
definition limit_object : D :=
cone_to_obj (limit_cone F)
definition limit_nat_trans : constant_functor I (limit_object F) ⟹ F :=
cone_to_nat (limit_cone F)
definition limit_morphism (i : I) : limit_object F ⟶ F i :=
limit_nat_trans F i
variable {H}
theorem limit_commute {i j : I} (f : i ⟶ j)
: to_fun_hom F f ∘ limit_morphism F i = limit_morphism F j :=
naturality (limit_nat_trans F) f ⬝ !id_right
variable [H]
definition limit_cone_obj [constructor] {d : D} {η : Πi, d ⟶ F i}
(p : Π⦃i j : I⦄ (f : i ⟶ j), to_fun_hom F f ∘ η i = η j) : cone_obj F :=
cone_obj.mk d (nat_trans.mk η (λa b f, p f ⬝ !id_right⁻¹))
variable {H}
definition hom_limit {d : D} (η : Πi, d ⟶ F i)
(p : Π⦃i j : I⦄ (f : i ⟶ j), to_fun_hom F f ∘ η i = η j) : d ⟶ limit_object F :=
cone_to_hom (@(terminal_morphism (limit_cone_obj F p) _) (is_terminal_limit_cone _))
theorem hom_limit_commute {d : D} (η : Πi, d ⟶ F i)
(p : Π⦃i j : I⦄ (f : i ⟶ j), to_fun_hom F f ∘ η i = η j) (i : I)
: limit_morphism F i ∘ hom_limit F η p = η i :=
cone_to_eq (@(terminal_morphism (limit_cone_obj F p) _) (is_terminal_limit_cone _)) i
definition limit_cone_hom [constructor] {d : D} {η : Πi, d ⟶ F i}
(p : Π⦃i j : I⦄ (f : i ⟶ j), to_fun_hom F f ∘ η i = η j) {h : d ⟶ limit_object F}
(q : Πi, limit_morphism F i ∘ h = η i) : cone_hom (limit_cone_obj F p) (limit_cone F) :=
cone_hom.mk h q
variable {F}
theorem eq_hom_limit {d : D} {η : Πi, d ⟶ F i}
(p : Π⦃i j : I⦄ (f : i ⟶ j), to_fun_hom F f ∘ η i = η j) {h : d ⟶ limit_object F}
(q : Πi, limit_morphism F i ∘ h = η i) : h = hom_limit F η p :=
ap cone_to_hom (@eq_terminal_morphism _ _ _ _ (is_terminal_limit_cone _) (limit_cone_hom F p q))
theorem limit_cone_unique {d : D} {η : Πi, d ⟶ F i}
(p : Π⦃i j : I⦄ (f : i ⟶ j), to_fun_hom F f ∘ η i = η j)
{h₁ : d ⟶ limit_object F} (q₁ : Πi, limit_morphism F i ∘ h₁ = η i)
{h₂ : d ⟶ limit_object F} (q₂ : Πi, limit_morphism F i ∘ h₂ = η i): h₁ = h₂ :=
eq_hom_limit p q₁ ⬝ (eq_hom_limit p q₂)⁻¹
definition limit_hom_limit {F G : I ⇒ D} (η : F ⟹ G) : limit_object F ⟶ limit_object G :=
hom_limit _ (λi, η i ∘ limit_morphism F i)
abstract by intro i j f; rewrite [assoc,naturality,-assoc,limit_commute] end
theorem limit_hom_limit_commute {F G : I ⇒ D} (η : F ⟹ G)
: limit_morphism G i ∘ limit_hom_limit η = η i ∘ limit_morphism F i :=
!hom_limit_commute
-- theorem hom_limit_commute {d : D} (η : Πi, d ⟶ F i)
-- (p : Π⦃i j : I⦄ (f : i ⟶ j), to_fun_hom F f ∘ η i = η j) (i : I)
-- : limit_morphism F i ∘ hom_limit F η p = η i :=
-- cone_to_eq (@(terminal_morphism (limit_cone_obj F p) _) (is_terminal_limit_cone _)) i
omit H
variable (F)
definition limit_object_iso_limit_object [constructor] (H₁ H₂ : has_limits_of_shape D I) :
@(limit_object F) H₁ ≅ @(limit_object F) H₂ :=
cone_iso_pr1 !terminal_object_iso_terminal_object
definition limit_functor [constructor] (D I : Precategory) [H : has_limits_of_shape D I]
: D ^c I ⇒ D :=
begin
fapply functor.mk: esimp,
{ intro F, exact limit_object F},
{ apply @limit_hom_limit},
{ intro F, unfold limit_hom_limit, refine (eq_hom_limit _ _)⁻¹, intro i,
apply comp_id_eq_id_comp},
{ intro F G H η θ, unfold limit_hom_limit, refine (eq_hom_limit _ _)⁻¹, intro i,
rewrite [assoc, hom_limit_commute, -assoc, hom_limit_commute, assoc]}
end
section bin_products
open bool prod.ops
definition has_binary_products [reducible] (D : Precategory) := has_limits_of_shape D c2
variables [K : has_binary_products D] (d d' : D)
include K
definition product_object : D :=
limit_object (c2_functor D d d')
infixr ` ×l `:75 := product_object
definition pr1 : d ×l d' ⟶ d :=
limit_morphism (c2_functor D d d') ff
definition pr2 : d ×l d' ⟶ d' :=
limit_morphism (c2_functor D d d') tt
variables {d d'}
definition hom_product {x : D} (f : x ⟶ d) (g : x ⟶ d') : x ⟶ d ×l d' :=
hom_limit (c2_functor D d d') (bool.rec f g)
(by intro b₁ b₂ f; induction b₁: induction b₂: esimp at *; try contradiction: apply id_left)
theorem pr1_hom_product {x : D} (f : x ⟶ d) (g : x ⟶ d') : !pr1 ∘ hom_product f g = f :=
hom_limit_commute (c2_functor D d d') (bool.rec f g) _ ff
theorem pr2_hom_product {x : D} (f : x ⟶ d) (g : x ⟶ d') : !pr2 ∘ hom_product f g = g :=
hom_limit_commute (c2_functor D d d') (bool.rec f g) _ tt
theorem eq_hom_product {x : D} {f : x ⟶ d} {g : x ⟶ d'} {h : x ⟶ d ×l d'}
(p : !pr1 ∘ h = f) (q : !pr2 ∘ h = g) : h = hom_product f g :=
eq_hom_limit _ (bool.rec p q)
theorem product_cone_unique {x : D} {f : x ⟶ d} {g : x ⟶ d'}
{h₁ : x ⟶ d ×l d'} (p₁ : !pr1 ∘ h₁ = f) (q₁ : !pr2 ∘ h₁ = g)
{h₂ : x ⟶ d ×l d'} (p₂ : !pr1 ∘ h₂ = f) (q₂ : !pr2 ∘ h₂ = g) : h₁ = h₂ :=
eq_hom_product p₁ q₁ ⬝ (eq_hom_product p₂ q₂)⁻¹
variable (D)
-- TODO: define this in terms of limit_functor and functor_two_left (in exponential_laws)
definition product_functor [constructor] : D ×c D ⇒ D :=
functor.mk
(λx, product_object x.1 x.2)
(λx y f, hom_product (f.1 ∘ !pr1) (f.2 ∘ !pr2))
abstract begin intro x, symmetry, apply eq_hom_product: apply comp_id_eq_id_comp end end
abstract begin intro x y z g f, symmetry, apply eq_hom_product,
rewrite [assoc,pr1_hom_product,-assoc,pr1_hom_product,assoc],
rewrite [assoc,pr2_hom_product,-assoc,pr2_hom_product,assoc] end end
omit K
variables {D} (d d')
definition product_object_iso_product_object [constructor] (H₁ H₂ : has_binary_products D) :
@product_object D H₁ d d' ≅ @product_object D H₂ d d' :=
limit_object_iso_limit_object _ H₁ H₂
end bin_products
section equalizers
open bool prod.ops sum equalizer_category_hom
definition has_equalizers [reducible] (D : Precategory) := has_limits_of_shape D equalizer_category
variables [K : has_equalizers D]
include K
variables {d d' x : D} (f g : d ⟶ d')
definition equalizer_object : D :=
limit_object (equalizer_category_functor D f g)
definition equalizer : equalizer_object f g ⟶ d :=
limit_morphism (equalizer_category_functor D f g) ff
theorem equalizes : f ∘ equalizer f g = g ∘ equalizer f g :=
limit_commute (equalizer_category_functor D f g) (inl f1) ⬝
(limit_commute (equalizer_category_functor D f g) (inl f2))⁻¹
variables {f g}
definition hom_equalizer (h : x ⟶ d) (p : f ∘ h = g ∘ h) : x ⟶ equalizer_object f g :=
hom_limit (equalizer_category_functor D f g)
(bool.rec h (g ∘ h))
begin
intro b₁ b₂ i; induction i with j j: induction j,
-- report(?) "esimp" is super slow here
exact p, reflexivity, apply id_left
end
theorem equalizer_hom_equalizer (h : x ⟶ d) (p : f ∘ h = g ∘ h)
: equalizer f g ∘ hom_equalizer h p = h :=
hom_limit_commute (equalizer_category_functor D f g) (bool.rec h (g ∘ h)) _ ff
theorem eq_hom_equalizer {h : x ⟶ d} (p : f ∘ h = g ∘ h) {i : x ⟶ equalizer_object f g}
(q : equalizer f g ∘ i = h) : i = hom_equalizer h p :=
eq_hom_limit _ (bool.rec q
begin
refine ap (λx, x ∘ i) (limit_commute (equalizer_category_functor D f g) (inl f2))⁻¹ ⬝ _,
refine !assoc⁻¹ ⬝ _,
exact ap (λx, _ ∘ x) q
end)
theorem equalizer_cone_unique {h : x ⟶ d} (p : f ∘ h = g ∘ h)
{i₁ : x ⟶ equalizer_object f g} (q₁ : equalizer f g ∘ i₁ = h)
{i₂ : x ⟶ equalizer_object f g} (q₂ : equalizer f g ∘ i₂ = h) : i₁ = i₂ :=
eq_hom_equalizer p q₁ ⬝ (eq_hom_equalizer p q₂)⁻¹
omit K
variables (f g)
definition equalizer_object_iso_equalizer_object [constructor] (H₁ H₂ : has_equalizers D) :
@equalizer_object D H₁ _ _ f g ≅ @equalizer_object D H₂ _ _ f g :=
limit_object_iso_limit_object _ H₁ H₂
end equalizers
section pullbacks
open sum prod.ops pullback_category_ob pullback_category_hom
definition has_pullbacks [reducible] (D : Precategory) := has_limits_of_shape D pullback_category
variables [K : has_pullbacks D]
include K
variables {d₁ d₂ d₃ x : D} (f : d₁ ⟶ d₃) (g : d₂ ⟶ d₃)
definition pullback_object : D :=
limit_object (pullback_category_functor D f g)
definition pullback : pullback_object f g ⟶ d₂ :=
limit_morphism (pullback_category_functor D f g) BL
definition pullback_rev : pullback_object f g ⟶ d₁ :=
limit_morphism (pullback_category_functor D f g) TR
theorem pullback_commutes : f ∘ pullback_rev f g = g ∘ pullback f g :=
limit_commute (pullback_category_functor D f g) (inl f1) ⬝
(limit_commute (pullback_category_functor D f g) (inl f2))⁻¹
variables {f g}
definition hom_pullback (h₁ : x ⟶ d₁) (h₂ : x ⟶ d₂) (p : f ∘ h₁ = g ∘ h₂)
: x ⟶ pullback_object f g :=
hom_limit (pullback_category_functor D f g)
(pullback_category_ob.rec h₁ h₂ (g ∘ h₂))
begin
intro i₁ i₂ k; induction k with j j: induction j,
exact p, reflexivity, apply id_left
end
theorem pullback_hom_pullback (h₁ : x ⟶ d₁) (h₂ : x ⟶ d₂) (p : f ∘ h₁ = g ∘ h₂)
: pullback f g ∘ hom_pullback h₁ h₂ p = h₂ :=
hom_limit_commute (pullback_category_functor D f g) (pullback_category_ob.rec h₁ h₂ (g ∘ h₂)) _ BL
theorem pullback_rev_hom_pullback (h₁ : x ⟶ d₁) (h₂ : x ⟶ d₂) (p : f ∘ h₁ = g ∘ h₂)
: pullback_rev f g ∘ hom_pullback h₁ h₂ p = h₁ :=
hom_limit_commute (pullback_category_functor D f g) (pullback_category_ob.rec h₁ h₂ (g ∘ h₂)) _ TR
theorem eq_hom_pullback {h₁ : x ⟶ d₁} {h₂ : x ⟶ d₂} (p : f ∘ h₁ = g ∘ h₂)
{k : x ⟶ pullback_object f g} (q : pullback f g ∘ k = h₂) (r : pullback_rev f g ∘ k = h₁)
: k = hom_pullback h₁ h₂ p :=
eq_hom_limit _ (pullback_category_ob.rec r q
begin
refine ap (λx, x ∘ k) (limit_commute (pullback_category_functor D f g) (inl f2))⁻¹ ⬝ _,
refine !assoc⁻¹ ⬝ _,
exact ap (λx, _ ∘ x) q
end)
theorem pullback_cone_unique {h₁ : x ⟶ d₁} {h₂ : x ⟶ d₂} (p : f ∘ h₁ = g ∘ h₂)
{k₁ : x ⟶ pullback_object f g} (q₁ : pullback f g ∘ k₁ = h₂) (r₁ : pullback_rev f g ∘ k₁ = h₁)
{k₂ : x ⟶ pullback_object f g} (q₂ : pullback f g ∘ k₂ = h₂) (r₂ : pullback_rev f g ∘ k₂ = h₁)
: k₁ = k₂ :=
(eq_hom_pullback p q₁ r₁) ⬝ (eq_hom_pullback p q₂ r₂)⁻¹
variables (f g)
definition pullback_object_iso_pullback_object [constructor] (H₁ H₂ : has_pullbacks D) :
@pullback_object D H₁ _ _ _ f g ≅ @pullback_object D H₂ _ _ _ f g :=
limit_object_iso_limit_object _ H₁ H₂
end pullbacks
namespace ops
infixr ×l := product_object
end ops
end category

View file

@ -1,9 +0,0 @@
algebra.category.limits
=======================
* [limits](limits.hlean) : Limits in a category, defined as terminal object in the cone category
* [colimits](colimits.hlean) : Colimits in a category, defined as the limit of the opposite functor
* [functor_preserve](functor_preserve.hlean) : Functors which preserve limits and colimits
* [adjoint](adjoint.hlean) : the (co)limit functor is adjoint to the diagonal map
* [set](set.hlean) : set is a complete and cocomplete category
* [functor](functor.hlean) : if `D` has (co)limits of a certain shape, then so has `D ^ C`

View file

@ -1,105 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn, Jakob von Raumer
The category of sets is complete and cocomplete
-/
import .colimits ..constructions.set hit.set_quotient
open eq functor is_trunc sigma pi sigma.ops trunc set_quotient
namespace category
local attribute category.to_precategory [unfold 2]
definition is_complete_set_cone.{u v w} [constructor]
(I : Precategory.{v w}) (F : I ⇒ set.{max u v w}) : cone_obj F :=
begin
fapply cone_obj.mk,
{ fapply trunctype.mk,
{ exact Σ(s : Π(i : I), trunctype.carrier (F i)),
Π{i j : I} (f : i ⟶ j), F f (s i) = (s j)},
{ with_options [elaborator.ignore_instances true] -- TODO: fix
( refine is_trunc_sigma _ _;
( apply is_trunc_pi);
( intro s;
refine is_trunc_pi _ _; intro i;
refine is_trunc_pi _ _; intro j;
refine is_trunc_pi _ _; intro f;
apply is_trunc_eq))}},
{ fapply nat_trans.mk,
{ intro i x, esimp at x, exact x.1 i},
{ intro i j f, esimp, apply eq_of_homotopy, intro x, esimp at x, induction x with s p,
esimp, apply p}}
end
definition is_complete_set.{u v w} [instance] : is_complete.{(max u v w)+1 (max u v w) v w} set :=
begin
intro I F, fapply has_terminal_object.mk,
{ exact is_complete_set_cone.{u v w} I F},
{ intro c, esimp at *, induction c with X η, induction η with η p, esimp at *,
fapply is_contr.mk,
{ fapply cone_hom.mk,
{ intro x, esimp at *, fapply sigma.mk,
{ intro i, exact η i x},
{ intro i j f, exact ap10 (p f) x}},
{ intro i, reflexivity}},
{ esimp, intro h, induction h with f q, apply cone_hom_eq, esimp at *,
apply eq_of_homotopy, intro x, fapply sigma_eq: esimp,
{ apply eq_of_homotopy, intro i, exact (ap10 (q i) x)⁻¹},
{ with_options [elaborator.ignore_instances true] -- TODO: fix
( refine is_prop.elimo _ _ _;
refine is_trunc_pi _ _; intro i;
refine is_trunc_pi _ _; intro j;
refine is_trunc_pi _ _; intro f;
apply is_trunc_eq)}}}
end
definition is_cocomplete_set_cone_rel.{u v w} [unfold 3 4]
(I : Precategory.{v w}) (F : I ⇒ set.{max u v w}ᵒᵖ) : (Σ(i : I), trunctype.carrier (F i)) →
(Σ(i : I), trunctype.carrier (F i)) → Prop.{max u v w} :=
begin
intro v w, induction v with i x, induction w with j y,
fapply trunctype.mk,
{ exact ∃(f : i ⟶ j), to_fun_hom F f y = x},
{ exact _}
end
definition is_cocomplete_set_cone.{u v w} [constructor]
(I : Precategory.{v w}) (F : I ⇒ set.{max u v w}ᵒᵖ) : cone_obj F :=
begin
fapply cone_obj.mk,
{ fapply trunctype.mk,
{ apply set_quotient (is_cocomplete_set_cone_rel.{u v w} I F)},
{ apply is_set_set_quotient}},
{ fapply nat_trans.mk,
{ intro i x, esimp, apply class_of, exact ⟨i, x⟩},
{ intro i j f, esimp, apply eq_of_homotopy, intro y, apply eq_of_rel, esimp,
exact exists.intro f idp}}
end
-- TODO: change this after induction tactic for trunc/set_quotient is implemented
definition is_cocomplete_set.{u v w} [instance]
: is_cocomplete.{(max u v w)+1 (max u v w) v w} set :=
begin
intro I F, fapply has_terminal_object.mk,
{ exact is_cocomplete_set_cone.{u v w} I F},
{ intro c, esimp at *, induction c with X η, induction η with η p, esimp at *,
fapply is_contr.mk,
{ fapply cone_hom.mk,
{ refine set_quotient.elim _ _,
{ intro v, induction v with i x, exact η i x},
{ intro v w r, induction v with i x, induction w with j y, esimp at *,
refine trunc.elim_on r _, clear r,
intro u, induction u with f q,
exact ap (η i) q⁻¹ ⬝ ap10 (p f) y}},
{ intro i, reflexivity}},
{ esimp, intro h, induction h with f q, apply cone_hom_eq, esimp at *,
apply eq_of_homotopy, refine set_quotient.rec _ _,
{ intro v, induction v with i x, esimp, exact (ap10 (q i) x)⁻¹},
{ intro v w r, apply is_prop.elimo}}},
end
end category

View file

@ -1,197 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Floris van Doorn, Jakob von Raumer
-/
import .functor.basic
open eq category functor is_trunc equiv sigma.ops sigma is_equiv function pi funext iso
structure nat_trans {C : Precategory} {D : Precategory} (F G : C ⇒ D)
: Type :=
(natural_map : Π (a : C), hom (F a) (G a))
(naturality : Π {a b : C} (f : hom a b), G f ∘ natural_map a = natural_map b ∘ F f)
namespace nat_trans
infixl ` ⟹ `:25 := nat_trans -- \==>
variables {B C D E : Precategory} {F G H I : C ⇒ D} {F' G' : D ⇒ E} {F'' G'' : E ⇒ B} {J : C ⇒ C}
attribute natural_map [coercion]
protected definition compose [constructor] (η : G ⟹ H) (θ : F ⟹ G) : F ⟹ H :=
nat_trans.mk
(λ a, η a ∘ θ a)
(λ a b f,
abstract calc
H f ∘ (η a ∘ θ a) = (H f ∘ η a) ∘ θ a : by rewrite assoc
... = (η b ∘ G f) ∘ θ a : by rewrite naturality
... = η b ∘ (G f ∘ θ a) : by rewrite assoc
... = η b ∘ (θ b ∘ F f) : by rewrite naturality
... = (η b ∘ θ b) ∘ F f : by rewrite assoc
end)
infixr ` ∘n `:60 := nat_trans.compose
definition compose_def (η : G ⟹ H) (θ : F ⟹ G) (c : C) : (η ∘n θ) c = η c ∘ θ c := idp
protected definition id [reducible] [constructor] {F : C ⇒ D} : nat_trans F F :=
mk (λa, id) (λa b f, !id_right ⬝ !id_left⁻¹)
protected definition ID [reducible] [constructor] (F : C ⇒ D) : nat_trans F F :=
(@nat_trans.id C D F)
notation 1 := nat_trans.id
definition constant_nat_trans [constructor] (C : Precategory) {D : Precategory} {d d' : D}
(g : d ⟶ d') : constant_functor C d ⟹ constant_functor C d' :=
mk (λc, g) (λc c' f, !id_comp_eq_comp_id)
open iso
definition naturality_iso_left (η : F ⟹ G) {a b : C} (f : a ≅ b) : η a = (G f)⁻¹ ∘ η b ∘ F f :=
by apply eq_inverse_comp_of_comp_eq; apply naturality
definition naturality_iso_right (η : F ⟹ G) {a b : C} (f : a ≅ b) : η b = G f ∘ η a ∘ (F f)⁻¹ :=
by refine _⁻¹ ⬝ !assoc⁻¹; apply comp_inverse_eq_of_eq_comp; apply naturality
definition nat_trans_mk_eq {η₁ η₂ : Π (a : C), hom (F a) (G a)}
(nat₁ : Π (a b : C) (f : hom a b), G f ∘ η₁ a = η₁ b ∘ F f)
(nat₂ : Π (a b : C) (f : hom a b), G f ∘ η₂ a = η₂ b ∘ F f)
(p : η₁ ~ η₂)
: nat_trans.mk η₁ nat₁ = nat_trans.mk η₂ nat₂ :=
apd011 nat_trans.mk (eq_of_homotopy p) !is_prop.elimo
definition nat_trans_eq {η₁ η₂ : F ⟹ G} : natural_map η₁ ~ natural_map η₂ → η₁ = η₂ :=
by induction η₁; induction η₂; apply nat_trans_mk_eq
protected definition assoc (η₃ : H ⟹ I) (η₂ : G ⟹ H) (η₁ : F ⟹ G) :
η₃ ∘n (η₂ ∘n η₁) = (η₃ ∘n η₂) ∘n η₁ :=
nat_trans_eq (λa, !assoc)
protected definition id_left (η : F ⟹ G) : 1 ∘n η = η :=
nat_trans_eq (λa, !id_left)
protected definition id_right (η : F ⟹ G) : η ∘n 1 = η :=
nat_trans_eq (λa, !id_right)
protected definition sigma_char (F G : C ⇒ D) :
(Σ (η : Π (a : C), hom (F a) (G a)), Π (a b : C) (f : hom a b), G f ∘ η a = η b ∘ F f) ≃ (F ⟹ G) :=
begin
fapply equiv.mk,
-- TODO(Leo): investigate why we need to use rexact in the following line
{intro S, apply nat_trans.mk, rexact (S.2)},
fapply adjointify,
intro H,
fapply sigma.mk,
intro a, exact (H a),
intro a b f, exact (naturality H f),
intro η, apply nat_trans_eq, intro a, apply idp,
intro S,
fapply sigma_eq,
{ apply eq_of_homotopy, intro a, apply idp},
{ apply is_prop.elimo}
end
definition is_set_nat_trans [instance] : is_set (F ⟹ G) :=
by apply is_trunc_is_equiv_closed; apply (equiv.to_is_equiv !nat_trans.sigma_char)
definition change_natural_map [constructor] (η : F ⟹ G) (f : Π (a : C), F a ⟶ G a)
(p : Πa, η a = f a) : F ⟹ G :=
nat_trans.mk f (λa b g, p a ▸ p b ▸ naturality η g)
definition nat_trans_functor_compose [constructor] (η : G ⟹ H) (F : E ⇒ C)
: G ∘f F ⟹ H ∘f F :=
nat_trans.mk
(λ a, η (F a))
(λ a b f, naturality η (F f))
definition functor_nat_trans_compose [constructor] (F : D ⇒ E) (η : G ⟹ H)
: F ∘f G ⟹ F ∘f H :=
nat_trans.mk
(λ a, F (η a))
(λ a b f, calc
F (H f) ∘ F (η a) = F (H f ∘ η a) : by rewrite respect_comp
... = F (η b ∘ G f) : by rewrite (naturality η f)
... = F (η b) ∘ F (G f) : by rewrite respect_comp)
definition nat_trans_id_functor_compose [constructor] (η : J ⟹ 1) (F : E ⇒ C)
: J ∘f F ⟹ F :=
nat_trans.mk
(λ a, η (F a))
(λ a b f, naturality η (F f))
definition id_nat_trans_functor_compose [constructor] (η : 1 ⟹ J) (F : E ⇒ C)
: F ⟹ J ∘f F :=
nat_trans.mk
(λ a, η (F a))
(λ a b f, naturality η (F f))
definition functor_nat_trans_id_compose [constructor] (F : C ⇒ D) (η : J ⟹ 1)
: F ∘f J ⟹ F :=
nat_trans.mk
(λ a, F (η a))
(λ a b f, calc
F f ∘ F (η a) = F (f ∘ η a) : by rewrite respect_comp
... = F (η b ∘ J f) : by rewrite (naturality η f)
... = F (η b) ∘ F (J f) : by rewrite respect_comp)
definition functor_id_nat_trans_compose [constructor] (F : C ⇒ D) (η : 1 ⟹ J)
: F ⟹ F ∘f J :=
nat_trans.mk
(λ a, F (η a))
(λ a b f, calc
F (J f) ∘ F (η a) = F (J f ∘ η a) : by rewrite respect_comp
... = F (η b ∘ f) : by rewrite (naturality η f)
... = F (η b) ∘ F f : by rewrite respect_comp)
infixr ` ∘nf ` :62 := nat_trans_functor_compose
infixr ` ∘fn ` :62 := functor_nat_trans_compose
infixr ` ∘n1f `:62 := nat_trans_id_functor_compose
infixr ` ∘1nf `:62 := id_nat_trans_functor_compose
infixr ` ∘f1n `:62 := functor_id_nat_trans_compose
infixr ` ∘fn1 `:62 := functor_nat_trans_id_compose
definition nf_fn_eq_fn_nf_pt (η : F ⟹ G) (θ : F' ⟹ G') (c : C)
: (θ (G c)) ∘ (F' (η c)) = (G' (η c)) ∘ (θ (F c)) :=
(naturality θ (η c))⁻¹
variable (F')
definition nf_fn_eq_fn_nf_pt' (η : F ⟹ G) (θ : F'' ⟹ G'') (c : C)
: (θ (F' (G c))) ∘ (F'' (F' (η c))) = (G'' (F' (η c))) ∘ (θ (F' (F c))) :=
(naturality θ (F' (η c)))⁻¹
variable {F'}
definition nf_fn_eq_fn_nf (η : F ⟹ G) (θ : F' ⟹ G')
: (θ ∘nf G) ∘n (F' ∘fn η) = (G' ∘fn η) ∘n (θ ∘nf F) :=
nat_trans_eq (λ c, nf_fn_eq_fn_nf_pt η θ c)
definition fn_n_distrib (F' : D ⇒ E) (η : G ⟹ H) (θ : F ⟹ G)
: F' ∘fn (η ∘n θ) = (F' ∘fn η) ∘n (F' ∘fn θ) :=
nat_trans_eq (λc, by apply respect_comp)
definition n_nf_distrib (η : G ⟹ H) (θ : F ⟹ G) (F' : B ⇒ C)
: (η ∘n θ) ∘nf F' = (η ∘nf F') ∘n (θ ∘nf F') :=
nat_trans_eq (λc, idp)
definition fn_id (F' : D ⇒ E) : F' ∘fn nat_trans.ID F = 1 :=
nat_trans_eq (λc, by apply respect_id)
definition id_nf (F' : B ⇒ C) : nat_trans.ID F ∘nf F' = 1 :=
nat_trans_eq (λc, idp)
definition id_fn (η : G ⟹ H) (c : C) : (1 ∘fn η) c = η c :=
idp
definition nf_id (η : G ⟹ H) (c : C) : (η ∘nf 1) c = η c :=
idp
definition nat_trans_of_eq [reducible] [constructor] (p : F = G) : F ⟹ G :=
nat_trans.mk (λc, hom_of_eq (ap010 to_fun_ob p c))
(λa b f, eq.rec_on p (!id_right ⬝ !id_left⁻¹))
definition compose_rev [unfold_full] (θ : F ⟹ G) (η : G ⟹ H) : F ⟹ H := η ∘n θ
end nat_trans
attribute nat_trans.compose_rev [trans]
attribute nat_trans.id [refl]

View file

@ -1,294 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
-/
import types.trunc types.pi arity
open eq is_trunc pi equiv
namespace category
/-
Just as in Coq-HoTT we add two redundant fields to precategories: assoc' and id_id.
The first is to make (Cᵒᵖ)ᵒᵖ = C definitionally when C is a constructor.
The second is to ensure that the functor from the terminal category 1 ⇒ Cᵒᵖ is
opposite to the functor 1 ⇒ C.
-/
structure precategory [class] (ob : Type) : Type :=
mk' ::
(hom : ob → ob → Type)
(comp : Π⦃a b c : ob⦄, hom b c → hom a b → hom a c)
(ID : Π (a : ob), hom a a)
(assoc : Π ⦃a b c d : ob⦄ (h : hom c d) (g : hom b c) (f : hom a b),
comp h (comp g f) = comp (comp h g) f)
(assoc' : Π ⦃a b c d : ob⦄ (h : hom c d) (g : hom b c) (f : hom a b),
comp (comp h g) f = comp h (comp g f))
(id_left : Π ⦃a b : ob⦄ (f : hom a b), comp !ID f = f)
(id_right : Π ⦃a b : ob⦄ (f : hom a b), comp f !ID = f)
(id_id : Π (a : ob), comp !ID !ID = ID a)
(is_set_hom : Π(a b : ob), is_set (hom a b))
attribute precategory.is_set_hom [instance]
infixr ∘ := precategory.comp
-- input ⟶ using \--> (this is a different arrow than \-> (→))
infixl [parsing_only] ` ⟶ `:60 := precategory.hom
namespace hom
infixl ` ⟶ `:60 := precategory.hom -- if you open this namespace, hom a b is printed as a ⟶ b
end hom
abbreviation hom [unfold 2] := @precategory.hom
abbreviation comp [unfold 2] := @precategory.comp
abbreviation ID [unfold 2] := @precategory.ID
abbreviation assoc [unfold 2] := @precategory.assoc
abbreviation assoc' [unfold 2] := @precategory.assoc'
abbreviation id_left [unfold 2] := @precategory.id_left
abbreviation id_right [unfold 2] := @precategory.id_right
abbreviation id_id [unfold 2] := @precategory.id_id
abbreviation is_set_hom [unfold 2] := @precategory.is_set_hom
definition is_prop_hom_eq {ob : Type} [C : precategory ob] {x y : ob} (f g : x ⟶ y)
: is_prop (f = g) :=
_
-- the constructor you want to use in practice
protected definition precategory.mk [constructor] {ob : Type} (hom : ob → ob → Type)
[set : Π (a b : ob), is_set (hom a b)]
(comp : Π ⦃a b c : ob⦄, hom b c → hom a b → hom a c) (ID : Π (a : ob), hom a a)
(ass : Π ⦃a b c d : ob⦄ (h : hom c d) (g : hom b c) (f : hom a b),
comp h (comp g f) = comp (comp h g) f)
(idl : Π ⦃a b : ob⦄ (f : hom a b), comp (ID b) f = f)
(idr : Π ⦃a b : ob⦄ (f : hom a b), comp f (ID a) = f) : precategory ob :=
precategory.mk' hom comp ID ass (λa b c d h g f, !ass⁻¹) idl idr (λa, !idl) set
section basic_lemmas
variables {ob : Type} [C : precategory ob]
variables {a b c d : ob} {h : c ⟶ d} {g : hom b c} {f f' : hom a b} {i : a ⟶ a}
include C
definition id [reducible] [unfold 2] := ID a
definition id_leftright (f : hom a b) : id ∘ f ∘ id = f := !id_left ⬝ !id_right
definition comp_id_eq_id_comp (f : hom a b) : f ∘ id = id ∘ f := !id_right ⬝ !id_left⁻¹
definition id_comp_eq_comp_id (f : hom a b) : id ∘ f = f ∘ id := !id_left ⬝ !id_right⁻¹
definition hom_whisker_left (g : b ⟶ c) (p : f = f') : g ∘ f = g ∘ f' :=
ap (λx, g ∘ x) p
definition hom_whisker_right (g : c ⟶ a) (p : f = f') : f ∘ g = f' ∘ g :=
ap (λx, x ∘ g) p
/- many variants of hom_pathover are defined in .iso and .functor.basic -/
definition left_id_unique (H : Π{b} {f : hom b a}, i ∘ f = f) : i = id :=
calc i = i ∘ id : by rewrite id_right
... = id : by rewrite H
definition right_id_unique (H : Π{b} {f : hom a b}, f ∘ i = f) : i = id :=
calc i = id ∘ i : by rewrite id_left
... = id : by rewrite H
definition homset [reducible] [constructor] (x y : ob) : Set :=
Set.mk (hom x y) _
end basic_lemmas
section squares
parameters {ob : Type} [C : precategory ob]
local infixl ` ⟶ `:25 := @precategory.hom ob C
local infixr ∘ := @precategory.comp ob C _ _ _
definition compose_squares {xa xb xc ya yb yc : ob}
{xg : xb ⟶ xc} {xf : xa ⟶ xb} {yg : yb ⟶ yc} {yf : ya ⟶ yb}
{wa : xa ⟶ ya} {wb : xb ⟶ yb} {wc : xc ⟶ yc}
(xyab : wb ∘ xf = yf ∘ wa) (xybc : wc ∘ xg = yg ∘ wb)
: wc ∘ (xg ∘ xf) = (yg ∘ yf) ∘ wa :=
calc
wc ∘ (xg ∘ xf) = (wc ∘ xg) ∘ xf : by rewrite assoc
... = (yg ∘ wb) ∘ xf : by rewrite xybc
... = yg ∘ (wb ∘ xf) : by rewrite assoc
... = yg ∘ (yf ∘ wa) : by rewrite xyab
... = (yg ∘ yf) ∘ wa : by rewrite assoc
definition compose_squares_2x2 {xa xb xc ya yb yc za zb zc : ob}
{xg : xb ⟶ xc} {xf : xa ⟶ xb} {yg : yb ⟶ yc} {yf : ya ⟶ yb} {zg : zb ⟶ zc} {zf : za ⟶ zb}
{va : ya ⟶ za} {vb : yb ⟶ zb} {vc : yc ⟶ zc} {wa : xa ⟶ ya} {wb : xb ⟶ yb} {wc : xc ⟶ yc}
(xyab : wb ∘ xf = yf ∘ wa) (xybc : wc ∘ xg = yg ∘ wb)
(yzab : vb ∘ yf = zf ∘ va) (yzbc : vc ∘ yg = zg ∘ vb)
: (vc ∘ wc) ∘ (xg ∘ xf) = (zg ∘ zf) ∘ (va ∘ wa) :=
calc
(vc ∘ wc) ∘ (xg ∘ xf) = vc ∘ (wc ∘ (xg ∘ xf)) : by rewrite (assoc vc wc _)
... = vc ∘ ((yg ∘ yf) ∘ wa) : by rewrite (compose_squares xyab xybc)
... = (vc ∘ (yg ∘ yf)) ∘ wa : by rewrite assoc
... = ((zg ∘ zf) ∘ va) ∘ wa : by rewrite (compose_squares yzab yzbc)
... = (zg ∘ zf) ∘ (va ∘ wa) : by rewrite assoc
definition square_precompose {xa xb xc yb yc : ob}
{xg : xb ⟶ xc} {yg : yb ⟶ yc} {wb : xb ⟶ yb} {wc : xc ⟶ yc}
(H : wc ∘ xg = yg ∘ wb) (xf : xa ⟶ xb) : wc ∘ xg ∘ xf = yg ∘ wb ∘ xf :=
calc
wc ∘ xg ∘ xf = (wc ∘ xg) ∘ xf : by rewrite assoc
... = (yg ∘ wb) ∘ xf : by rewrite H
... = yg ∘ wb ∘ xf : by rewrite assoc
definition square_postcompose {xb xc yb yc yd : ob}
{xg : xb ⟶ xc} {yg : yb ⟶ yc} {wb : xb ⟶ yb} {wc : xc ⟶ yc}
(H : wc ∘ xg = yg ∘ wb) (yh : yc ⟶ yd) : (yh ∘ wc) ∘ xg = (yh ∘ yg) ∘ wb :=
calc
(yh ∘ wc) ∘ xg = yh ∘ wc ∘ xg : by rewrite assoc
... = yh ∘ yg ∘ wb : by rewrite H
... = (yh ∘ yg) ∘ wb : by rewrite assoc
definition square_prepostcompose {xa xb xc yb yc yd : ob}
{xg : xb ⟶ xc} {yg : yb ⟶ yc} {wb : xb ⟶ yb} {wc : xc ⟶ yc}
(H : wc ∘ xg = yg ∘ wb) (yh : yc ⟶ yd) (xf : xa ⟶ xb)
: (yh ∘ wc) ∘ (xg ∘ xf) = (yh ∘ yg) ∘ (wb ∘ xf) :=
square_precompose (square_postcompose H yh) xf
end squares
structure Precategory : Type :=
(carrier : Type)
(struct : precategory carrier)
definition precategory.Mk [reducible] [constructor] {ob} (C) : Precategory := Precategory.mk ob C
definition precategory.MK [reducible] [constructor] (a b c d e f g h) : Precategory :=
Precategory.mk a (@precategory.mk a b c d e f g h)
abbreviation carrier [unfold 1] := @Precategory.carrier
attribute Precategory.carrier [coercion]
attribute Precategory.struct [instance] [priority 10000] [coercion]
-- definition precategory.carrier [coercion] [reducible] := Precategory.carrier
-- definition precategory.struct [instance] [coercion] := Precategory.struct
notation g ` ∘[`:60 C:0 `] `:0 f:60 :=
@comp (Precategory.carrier C) (Precategory.struct C) _ _ _ g f
-- TODO: make this left associative
definition Precategory.eta (C : Precategory) : Precategory.mk C C = C :=
Precategory.rec (λob c, idp) C
/-Characterization of paths between precategories-/
-- introduction tule for paths between precategories
definition precategory_eq {ob : Type}
{C D : precategory ob}
(p : Π{a b}, @hom ob C a b = @hom ob D a b)
(q : Πa b c g f, cast p (@comp ob C a b c g f) = @comp ob D a b c (cast p g) (cast p f))
: C = D :=
begin
induction C with hom1 comp1 ID1 a b il ir, induction D with hom2 comp2 ID2 a' b' il' ir',
esimp at *,
revert q, eapply homotopy2.rec_on @p, esimp, clear p, intro p q, induction p,
esimp at *,
have H : comp1 = comp2,
begin apply eq_of_homotopy3, intros, apply eq_of_homotopy2, intros, apply q end,
induction H,
have K : ID1 = ID2,
begin apply eq_of_homotopy, intro a, exact !ir'⁻¹ ⬝ !il end,
induction K,
apply ap0111111 (precategory.mk' hom1 comp1 ID1): apply is_prop.elim
end
definition precategory_eq_of_equiv {ob : Type}
{C D : precategory ob}
(p : Π⦃a b⦄, @hom ob C a b ≃ @hom ob D a b)
(q : Π{a b c} g f, p (@comp ob C a b c g f) = @comp ob D a b c (p g) (p f))
: C = D :=
begin
fapply precategory_eq,
{ intro a b, exact ua !@p},
{ intros, refine !cast_ua ⬝ !q ⬝ _, apply ap011 !@comp !cast_ua⁻¹ !cast_ua⁻¹},
end
/- if we need to prove properties about precategory_eq, it might be easier with the following proof:
begin
induction C with hom1 comp1 ID1, induction D with hom2 comp2 ID2, esimp at *,
have H : Σ(s : hom1 = hom2), (λa b, equiv_of_eq (apd100 s a b)) = p,
begin
fconstructor,
{ apply eq_of_homotopy2, intros, apply ua, apply p},
{ apply eq_of_homotopy2, intros, rewrite [to_right_inv !eq_equiv_homotopy2, equiv_of_eq_ua]}
end,
induction H with H1 H2, induction H1, esimp at H2,
have K : (λa b, equiv.refl) = p,
begin refine _ ⬝ H2, apply eq_of_homotopy2, intros, exact !equiv_of_eq_refl⁻¹ end,
induction K, clear H2,
esimp at *,
have H : comp1 = comp2,
begin apply eq_of_homotopy3, intros, apply eq_of_homotopy2, intros, apply q end,
have K : ID1 = ID2,
begin apply eq_of_homotopy, intros, apply r end,
induction H, induction K,
apply ap0111111 (precategory.mk' hom1 comp1 ID1): apply is_prop.elim
end
-/
definition Precategory_eq {C D : Precategory}
(p : carrier C = carrier D)
(q : Π{a b : C}, a ⟶ b = cast p a ⟶ cast p b)
(r : Π{a b c : C} (g : b ⟶ c) (f : a ⟶ b), cast q (g ∘ f) = cast q g ∘ cast q f)
: C = D :=
begin
induction C with X C, induction D with Y D, esimp at *, induction p,
esimp at *,
apply ap (Precategory.mk X),
apply precategory_eq @q @r
end
definition Precategory_eq_of_equiv {C D : Precategory}
(p : carrier C ≃ carrier D)
(q : Π⦃a b : C⦄, a ⟶ b ≃ p a ⟶ p b)
(r : Π{a b c : C} (g : b ⟶ c) (f : a ⟶ b), q (g ∘ f) = q g ∘ q f)
: C = D :=
begin
induction C with X C, induction D with Y D, esimp at *,
revert q r, eapply equiv.rec_on_ua p, clear p, intro p, induction p, esimp,
intros,
apply ap (Precategory.mk X),
apply precategory_eq_of_equiv @q @r
end
-- elimination rules for paths between precategories.
-- The first elimination rule is "ap carrier"
definition Precategory_eq_hom [unfold 3] {C D : Precategory} (p : C = D) (a b : C)
: hom a b = hom (cast (ap carrier p) a) (cast (ap carrier p) b) :=
by induction p; reflexivity
--(ap10 (ap10 (apdt (λx, @hom (carrier x) (Precategory.struct x)) p⁻¹ᵖ) a) b)⁻¹ᵖ ⬝ _
-- beta/eta rules
definition ap_Precategory_eq' {C D : Precategory}
(p : carrier C = carrier D)
(q : Π{a b : C}, a ⟶ b = cast p a ⟶ cast p b)
(r : Π{a b c : C} (g : b ⟶ c) (f : a ⟶ b), cast q (g ∘ f) = cast q g ∘ cast q f)
(s : Πa, cast q (ID a) = ID (cast p a)) : ap carrier (Precategory_eq p @q @r) = p :=
begin
induction C with X C, induction D with Y D, esimp at *, induction p,
rewrite [↑Precategory_eq, -ap_compose,↑function.compose,ap_constant]
end
/-
theorem Precategory_eq'_eta {C D : Precategory} (p : C = D) :
Precategory_eq
(ap carrier p)
(Precategory_eq_hom p)
(by induction p; intros; reflexivity) = p :=
begin
induction p, induction C with X C, unfold Precategory_eq,
induction C, unfold precategory_eq, exact sorry
end
-/
/-
theorem Precategory_eq2 {C D : Precategory} (p q : C = D)
(r : ap carrier p = ap carrier q)
(s : Precategory_eq_hom p =[r] Precategory_eq_hom q)
: p = q :=
begin
end
-/
end category

View file

@ -1,48 +0,0 @@
/-
Copyright (c) 2015 Jakob von Raumer. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn, Jakob von Raumer
-/
import .functor.basic
open is_trunc eq
namespace category
structure strict_precategory [class] (ob : Type) extends precategory ob :=
mk' :: (is_set_ob : is_set ob)
attribute strict_precategory.is_set_ob [instance]
definition strict_precategory.mk [reducible] {ob : Type} (C : precategory ob)
(H : is_set ob) : strict_precategory ob :=
precategory.rec_on C strict_precategory.mk' H
structure Strict_precategory : Type :=
(carrier : Type)
(struct : strict_precategory carrier)
attribute Strict_precategory.struct [instance] [coercion]
definition Strict_precategory.to_Precategory [coercion] [reducible]
(C : Strict_precategory) : Precategory :=
Precategory.mk (Strict_precategory.carrier C) _
open functor
-- TODO: move to constructions.cat?
definition precategory_strict_precategory [constructor] : precategory Strict_precategory :=
precategory.mk (λ A B, A ⇒ B)
(λ A B C G F, G ∘f F)
(λ A, 1)
(λ A B C D, functor.assoc)
(λ A B, functor.id_left)
(λ A B, functor.id_right)
definition Precategory_strict_precategory [constructor] := precategory.Mk precategory_strict_precategory
namespace ops
abbreviation Cat := Precategory_strict_precategory
end ops
end category

View file

@ -1,7 +0,0 @@
/-
Copyright (c) 2016 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
-/
import .homotopy_group .ordered_field

View file

@ -1,243 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Floris van Doorn
The "equivalence closure" of a type-valued relation.
A more appropriate intuition is the type of words formed from the relation,
and inverses, concatenations and reflexivity
-/
import algebra.relation eq2 arity cubical.pathover2
open eq equiv function
inductive e_closure {A : Type} (R : A → A → Type) : A → A → Type :=
| of_rel : Π{a a'} (r : R a a'), e_closure R a a'
| of_path : Π{a a'} (pp : a = a'), e_closure R a a'
| symm : Π{a a'} (r : e_closure R a a'), e_closure R a' a
| trans : Π{a a' a''} (r : e_closure R a a') (r' : e_closure R a' a''), e_closure R a a''
namespace e_closure
infix ` ⬝r `:75 := e_closure.trans
postfix `⁻¹ʳ`:(max+10) := e_closure.symm
notation `[`:max a `]`:0 := e_closure.of_rel a
notation `<`:max p `>`:0 := e_closure.of_path _ p
abbreviation rfl [constructor] {A : Type} {R : A → A → Type} {a : A} := of_path R (idpath a)
end e_closure
open e_closure
namespace relation
section
parameters {A : Type}
{R : A → A → Type}
local abbreviation T := e_closure R
variables ⦃a a' a'' : A⦄ {s : R a a'} {r : T a a} {B C : Type}
protected definition e_closure.elim [unfold 8] {f : A → B}
(e : Π⦃a a' : A⦄, R a a' → f a = f a') (t : T a a') : f a = f a' :=
begin
induction t with a a' r a a' pp a a' r IH a a' a'' r r' IH₁ IH₂,
exact e r,
exact ap f pp,
exact IH⁻¹,
exact IH₁ ⬝ IH₂
end
definition ap_e_closure_elim_h [unfold 12] {B C : Type} {f : A → B} {g : B → C}
(e : Π⦃a a' : A⦄, R a a' → f a = f a')
{e' : Π⦃a a' : A⦄, R a a' → g (f a) = g (f a')}
(p : Π⦃a a' : A⦄ (s : R a a'), ap g (e s) = e' s) (t : T a a')
: ap g (e_closure.elim e t) = e_closure.elim e' t :=
begin
induction t with a a' r a a' pp a a' r IH a a' a'' r r' IH₁ IH₂,
apply p,
induction pp, reflexivity,
exact ap_inv g (e_closure.elim e r) ⬝ inverse2 IH,
exact ap_con g (e_closure.elim e r) (e_closure.elim e r') ⬝ (IH₁ ◾ IH₂)
end
definition ap_e_closure_elim_h_symm [unfold_full] {B C : Type} {f : A → B} {g : B → C}
{e : Π⦃a a' : A⦄, R a a' → f a = f a'}
{e' : Π⦃a a' : A⦄, R a a' → g (f a) = g (f a')}
(p : Π⦃a a' : A⦄ (s : R a a'), ap g (e s) = e' s) (t : T a a') :
ap_e_closure_elim_h e p t⁻¹ʳ = ap_inv g (e_closure.elim e t) ⬝ (ap_e_closure_elim_h e p t)⁻² :=
by reflexivity
definition ap_e_closure_elim_h_trans [unfold_full] {B C : Type} {f : A → B} {g : B → C}
{e : Π⦃a a' : A⦄, R a a' → f a = f a'}
{e' : Π⦃a a' : A⦄, R a a' → g (f a) = g (f a')}
(p : Π⦃a a' : A⦄ (s : R a a'), ap g (e s) = e' s) (t : T a a') (t' : T a' a'')
: ap_e_closure_elim_h e p (t ⬝r t') = ap_con g (e_closure.elim e t) (e_closure.elim e t') ⬝
(ap_e_closure_elim_h e p t ◾ ap_e_closure_elim_h e p t') :=
by reflexivity
definition ap_e_closure_elim [unfold 10] {B C : Type} {f : A → B} (g : B → C)
(e : Π⦃a a' : A⦄, R a a' → f a = f a') (t : T a a')
: ap g (e_closure.elim e t) = e_closure.elim (λa a' r, ap g (e r)) t :=
ap_e_closure_elim_h e (λa a' s, idp) t
definition ap_e_closure_elim_symm [unfold_full] {B C : Type} {f : A → B} (g : B → C)
(e : Π⦃a a' : A⦄, R a a' → f a = f a') (t : T a a')
: ap_e_closure_elim g e t⁻¹ʳ = ap_inv g (e_closure.elim e t) ⬝ (ap_e_closure_elim g e t)⁻² :=
by reflexivity
definition ap_e_closure_elim_trans [unfold_full] {B C : Type} {f : A → B} (g : B → C)
(e : Π⦃a a' : A⦄, R a a' → f a = f a') (t : T a a') (t' : T a' a'')
: ap_e_closure_elim g e (t ⬝r t') = ap_con g (e_closure.elim e t) (e_closure.elim e t') ⬝
(ap_e_closure_elim g e t ◾ ap_e_closure_elim g e t') :=
by reflexivity
definition e_closure_elim_eq [unfold 8] {f : A → B}
{e e' : Π⦃a a' : A⦄, R a a' → f a = f a'} (p : e ~3 e') (t : T a a')
: e_closure.elim e t = e_closure.elim e' t :=
begin
induction t with a a' r a a' pp a a' r IH a a' a'' r r' IH₁ IH₂,
apply p,
reflexivity,
exact IH⁻²,
exact IH₁ ◾ IH₂
end
-- TODO: formulate and prove this without using function extensionality,
-- and modify the proofs using this to also not use function extensionality
-- strategy: use `e_closure_elim_eq` instead of `ap ... (eq_of_homotopy3 p)`
definition ap_e_closure_elim_h_eq {B C : Type} {f : A → B} {g : B → C}
(e : Π⦃a a' : A⦄, R a a' → f a = f a')
{e' : Π⦃a a' : A⦄, R a a' → g (f a) = g (f a')}
(p : Π⦃a a' : A⦄ (s : R a a'), ap g (e s) = e' s) (t : T a a')
: ap_e_closure_elim_h e p t =
ap_e_closure_elim g e t ⬝ ap (λx, e_closure.elim x t) (eq_of_homotopy3 p) :=
begin
fapply homotopy3.rec_on p,
intro q, esimp at q, induction q,
esimp, rewrite eq_of_homotopy3_id
end
theorem ap_ap_e_closure_elim_h {B C D : Type} {f : A → B}
{g : B → C} (h : C → D)
(e : Π⦃a a' : A⦄, R a a' → f a = f a')
{e' : Π⦃a a' : A⦄, R a a' → g (f a) = g (f a')}
(p : Π⦃a a' : A⦄ (s : R a a'), ap g (e s) = e' s) (t : T a a')
: square (ap (ap h) (ap_e_closure_elim_h e p t))
(ap_e_closure_elim_h e (λa a' s, ap_compose h g (e s)) t)
(ap_compose h g (e_closure.elim e t))⁻¹
(ap_e_closure_elim_h e' (λa a' s, (ap (ap h) (p s))⁻¹) t) :=
begin
induction t with a a' r a a' pp a a' r IH a a' a'' r r' IH₁ IH₂,
{ esimp,
apply square_of_eq, exact !con.right_inv ⬝ !con.left_inv⁻¹},
{ induction pp, apply ids},
{ rewrite [▸*,ap_con (ap h)],
refine (transpose !ap_compose_inv)⁻¹ᵛ ⬝h _,
rewrite [con_inv,inv_inv,-inv2_inv],
exact !ap_inv2 ⬝v square_inv2 IH},
{ rewrite [▸*,ap_con (ap h)],
refine (transpose !ap_compose_con)⁻¹ᵛ ⬝h _,
rewrite [con_inv,inv_inv,con2_inv],
refine !ap_con2 ⬝v square_con2 IH₁ IH₂},
end
theorem ap_ap_e_closure_elim {B C D : Type} {f : A → B}
(g : B → C) (h : C → D)
(e : Π⦃a a' : A⦄, R a a' → f a = f a') (t : T a a')
: square (ap (ap h) (ap_e_closure_elim g e t))
(ap_e_closure_elim_h e (λa a' s, ap_compose h g (e s)) t)
(ap_compose h g (e_closure.elim e t))⁻¹
(ap_e_closure_elim h (λa a' r, ap g (e r)) t) :=
!ap_ap_e_closure_elim_h
definition ap_e_closure_elim_h_zigzag {B C D : Type} {f : A → B}
{g : B → C} (h : C → D)
(e : Π⦃a a' : A⦄, R a a' → f a = f a')
{e' : Π⦃a a' : A⦄, R a a' → h (g (f a)) = h (g (f a'))}
(p : Π⦃a a' : A⦄ (s : R a a'), ap (h ∘ g) (e s) = e' s) (t : T a a')
: ap_e_closure_elim h (λa a' s, ap g (e s)) t ⬝
(ap_e_closure_elim_h e (λa a' s, ap_compose h g (e s)) t)⁻¹ ⬝
ap_e_closure_elim_h e p t =
ap_e_closure_elim_h (λa a' s, ap g (e s)) (λa a' s, (ap_compose h g (e s))⁻¹ ⬝ p s) t :=
begin
refine whisker_right _ (eq_of_square (ap_ap_e_closure_elim g h e t)⁻¹ʰ)⁻¹ ⬝ _,
refine !con.assoc ⬝ _, apply inv_con_eq_of_eq_con, apply eq_of_square,
apply transpose,
-- the rest of the proof is almost the same as the proof of ap_ap_e_closure_elim[_h].
-- Is there a connection between these theorems?
induction t with a a' r a a' pp a a' r IH a a' a'' r r' IH₁ IH₂,
{ esimp, apply square_of_eq, apply idp_con},
{ induction pp, apply ids},
{ rewrite [▸*,ap_con (ap h)],
refine (transpose !ap_compose_inv)⁻¹ᵛ ⬝h _,
rewrite [con_inv,inv_inv,-inv2_inv],
exact !ap_inv2 ⬝v square_inv2 IH},
{ rewrite [▸*,ap_con (ap h)],
refine (transpose !ap_compose_con)⁻¹ᵛ ⬝h _,
rewrite [con_inv,inv_inv,con2_inv],
refine !ap_con2 ⬝v square_con2 IH₁ IH₂},
end
definition is_equivalence_e_closure : is_equivalence T :=
begin
constructor,
intro a, exact rfl,
intro a a' t, exact t⁻¹ʳ,
intro a a' a'' t t', exact t ⬝r t',
end
/- dependent elimination -/
variables {P : B → Type} {Q : C → Type} {f : A → B} {g : B → C} {f' : Π(a : A), P (f a)}
protected definition e_closure.elimo [unfold 11] (p : Π⦃a a' : A⦄, R a a' → f a = f a')
(po : Π⦃a a' : A⦄ (s : R a a'), f' a =[p s] f' a') (t : T a a')
: f' a =[e_closure.elim p t] f' a' :=
begin
induction t with a a' r a a' pp a a' r IH a a' a'' r r' IH₁ IH₂,
exact po r,
induction pp, constructor,
exact IH⁻¹ᵒ,
exact IH₁ ⬝o IH₂
end
definition elimo_symm [unfold_full] (p : Π⦃a a' : A⦄, R a a' → f a = f a')
(po : Π⦃a a' : A⦄ (s : R a a'), f' a =[p s] f' a') (t : T a a')
: e_closure.elimo p po t⁻¹ʳ = (e_closure.elimo p po t)⁻¹ᵒ :=
by reflexivity
definition elimo_trans [unfold_full] (p : Π⦃a a' : A⦄, R a a' → f a = f a')
(po : Π⦃a a' : A⦄ (s : R a a'), f' a =[p s] f' a') (t : T a a') (t' : T a' a'')
: e_closure.elimo p po (t ⬝r t') = e_closure.elimo p po t ⬝o e_closure.elimo p po t' :=
by reflexivity
definition ap_e_closure_elimo_h [unfold 12] {g' : Πb, Q (g b)}
(p : Π⦃a a' : A⦄, R a a' → f a = f a')
(po : Π⦃a a' : A⦄ (s : R a a'), g' (f a) =[p s] g' (f a'))
(q : Π⦃a a' : A⦄ (s : R a a'), apd g' (p s) = po s)
(t : T a a') : apd g' (e_closure.elim p t) = e_closure.elimo p po t :=
begin
induction t with a a' r a a' pp a a' r IH a a' a'' r r' IH₁ IH₂,
apply q,
induction pp, reflexivity,
esimp [e_closure.elim],
exact apd_inv g' (e_closure.elim p r) ⬝ IH⁻²ᵒ,
exact apd_con g' (e_closure.elim p r) (e_closure.elim p r') ⬝ (IH₁ ◾o IH₂)
end
theorem e_closure_elimo_ap {g' : Π(a : A), Q (g (f a))}
(p : Π⦃a a' : A⦄, R a a' → f a = f a')
(po : Π⦃a a' : A⦄ (s : R a a'), g' a =[ap g (p s)] g' a')
(t : T a a') : e_closure.elimo p (λa a' s, pathover_of_pathover_ap Q g (po s)) t =
pathover_of_pathover_ap Q g (change_path (ap_e_closure_elim g p t)⁻¹
(e_closure.elimo (λa a' r, ap g (p r)) po t)) :=
begin
induction t with a a' r a a' pp a a' r IH a a' a'' r r' IH₁ IH₂,
{ reflexivity},
{ induction pp; reflexivity},
{ rewrite [+elimo_symm, ap_e_closure_elim_symm, IH, con_inv, change_path_con, ▸*, -inv2_inv,
change_path_invo, pathover_of_pathover_ap_invo]},
{ rewrite [+elimo_trans, ap_e_closure_elim_trans, IH₁, IH₂, con_inv, change_path_con, ▸*,
con2_inv, change_path_cono, pathover_of_pathover_ap_cono]},
end
end
end relation

View file

@ -1,526 +0,0 @@
/-
Copyright (c) 2014 Robert Lewis. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Robert Lewis
Structures with multiplicative and additive components, including division rings and fields.
The development is modeled after Isabelle's library.
-/
import algebra.binary algebra.group algebra.ring
open eq eq.ops algebra
set_option class.force_new true
variable {A : Type}
namespace algebra
structure division_ring [class] (A : Type) extends ring A, has_inv A, zero_ne_one_class A :=
(mul_inv_cancel : Π{a}, a ≠ zero → mul a (inv a) = one)
(inv_mul_cancel : Π{a}, a ≠ zero → mul (inv a) a = one)
section division_ring
variables [s : division_ring A] {a b c : A}
include s
protected definition algebra.div (a b : A) : A := a * b⁻¹
definition division_ring_has_div [instance] : has_div A :=
has_div.mk algebra.div
lemma division.def (a b : A) : a / b = a * b⁻¹ :=
rfl
theorem mul_inv_cancel (H : a ≠ 0) : a * a⁻¹ = 1 :=
division_ring.mul_inv_cancel H
theorem inv_mul_cancel (H : a ≠ 0) : a⁻¹ * a = 1 :=
division_ring.inv_mul_cancel H
theorem inv_eq_one_div (a : A) : a⁻¹ = 1 / a := !one_mul⁻¹
theorem div_eq_mul_one_div (a b : A) : a / b = a * (1 / b) :=
by rewrite [*division.def, one_mul]
theorem mul_one_div_cancel (H : a ≠ 0) : a * (1 / a) = 1 :=
by rewrite [-inv_eq_one_div, (mul_inv_cancel H)]
theorem one_div_mul_cancel (H : a ≠ 0) : (1 / a) * a = 1 :=
by rewrite [-inv_eq_one_div, (inv_mul_cancel H)]
theorem div_self (H : a ≠ 0) : a / a = 1 := mul_inv_cancel H
theorem one_div_one : 1 / 1 = (1:A) := div_self (ne.symm zero_ne_one)
theorem mul_div_assoc (a b : A) : (a * b) / c = a * (b / c) := !mul.assoc
theorem one_div_ne_zero (H : a ≠ 0) : 1 / a ≠ 0 :=
assume H2 : 1 / a = 0,
have C1 : 0 = (1:A), from symm (by rewrite [-(mul_one_div_cancel H), H2, mul_zero]),
absurd C1 zero_ne_one
theorem one_inv_eq : 1⁻¹ = (1:A) :=
by rewrite [-mul_one ((1:A)⁻¹), inv_mul_cancel (ne.symm (@zero_ne_one A _))]
theorem div_one (a : A) : a / 1 = a :=
by rewrite [*division.def, one_inv_eq, mul_one]
theorem zero_div (a : A) : 0 / a = 0 := !zero_mul
-- note: integral domain has a "mul_ne_zero". A commutative division ring is an integral
-- domain, but let's not define that class for now.
theorem division_ring.mul_ne_zero (Ha : a ≠ 0) (Hb : b ≠ 0) : a * b ≠ 0 :=
assume H : a * b = 0,
have C1 : a = 0, by rewrite [-(mul_one a), -(mul_one_div_cancel Hb), -mul.assoc, H, zero_mul],
absurd C1 Ha
theorem mul_ne_zero_comm (H : a * b ≠ 0) : b * a ≠ 0 :=
have H2 : a ≠ 0 × b ≠ 0, from ne_zero_prod_ne_zero_of_mul_ne_zero H,
division_ring.mul_ne_zero (prod.pr2 H2) (prod.pr1 H2)
theorem eq_one_div_of_mul_eq_one (H : a * b = 1) : b = 1 / a :=
have a ≠ 0, from
(suppose a = 0,
have 0 = (1:A), by rewrite [-(zero_mul b), -this, H],
absurd this zero_ne_one),
show b = 1 / a, from symm (calc
1 / a = (1 / a) * 1 : mul_one
... = (1 / a) * (a * b) : H
... = (1 / a) * a * b : mul.assoc
... = 1 * b : one_div_mul_cancel this
... = b : one_mul)
theorem eq_one_div_of_mul_eq_one_left (H : b * a = 1) : b = 1 / a :=
have a ≠ 0, from
(suppose a = 0,
have 0 = 1, from symm (calc
1 = b * a : symm H
... = b * 0 : this
... = 0 : mul_zero),
absurd this zero_ne_one),
show b = 1 / a, from symm (calc
1 / a = 1 * (1 / a) : one_mul
... = b * a * (1 / a) : H
... = b * (a * (1 / a)) : mul.assoc
... = b * 1 : mul_one_div_cancel this
... = b : mul_one)
theorem division_ring.one_div_mul_one_div (Ha : a ≠ 0) (Hb : b ≠ 0) :
(1 / a) * (1 / b) = 1 / (b * a) :=
have (b * a) * ((1 / a) * (1 / b)) = 1, by
rewrite [mul.assoc, -(mul.assoc a), (mul_one_div_cancel Ha), one_mul,
(mul_one_div_cancel Hb)],
eq_one_div_of_mul_eq_one this
theorem one_div_neg_one_eq_neg_one : (1:A) / (-1) = -1 :=
have (-1) * (-1) = (1:A), by rewrite [-neg_eq_neg_one_mul, neg_neg],
symm (eq_one_div_of_mul_eq_one this)
theorem division_ring.one_div_neg_eq_neg_one_div (H : a ≠ 0) : 1 / (- a) = - (1 / a) :=
have -1 ≠ (0:A), from
(suppose -1 = 0, absurd (symm (calc
1 = -(-1) : neg_neg
... = -0 : this
... = (0:A) : neg_zero)) zero_ne_one),
calc
1 / (- a) = 1 / ((-1) * a) : neg_eq_neg_one_mul
... = (1 / a) * (1 / (- 1)) : division_ring.one_div_mul_one_div H this
... = (1 / a) * (-1) : one_div_neg_one_eq_neg_one
... = - (1 / a) : mul_neg_one_eq_neg
theorem div_neg_eq_neg_div (b : A) (Ha : a ≠ 0) : b / (- a) = - (b / a) :=
calc
b / (- a) = b * (1 / (- a)) : by rewrite -inv_eq_one_div
... = b * -(1 / a) : division_ring.one_div_neg_eq_neg_one_div Ha
... = -(b * (1 / a)) : neg_mul_eq_mul_neg
... = - (b * a⁻¹) : inv_eq_one_div
theorem neg_div (a b : A) : (-b) / a = - (b / a) :=
by rewrite [neg_eq_neg_one_mul, mul_div_assoc, -neg_eq_neg_one_mul]
theorem division_ring.neg_div_neg_eq (a : A) {b : A} (Hb : b ≠ 0) : (-a) / (-b) = a / b :=
by rewrite [(div_neg_eq_neg_div _ Hb), neg_div, neg_neg]
theorem division_ring.one_div_one_div (H : a ≠ 0) : 1 / (1 / a) = a :=
symm (eq_one_div_of_mul_eq_one_left (mul_one_div_cancel H))
theorem division_ring.eq_of_one_div_eq_one_div (Ha : a ≠ 0) (Hb : b ≠ 0) (H : 1 / a = 1 / b) :
a = b :=
by rewrite [-(division_ring.one_div_one_div Ha), H, (division_ring.one_div_one_div Hb)]
theorem mul_inv_eq (Ha : a ≠ 0) (Hb : b ≠ 0) : (b * a)⁻¹ = a⁻¹ * b⁻¹ :=
inverse (calc
a⁻¹ * b⁻¹ = (1 / a) * b⁻¹ : inv_eq_one_div
... = (1 / a) * (1 / b) : inv_eq_one_div
... = (1 / (b * a)) : division_ring.one_div_mul_one_div Ha Hb
... = (b * a)⁻¹ : inv_eq_one_div)
theorem mul_div_cancel (a : A) {b : A} (Hb : b ≠ 0) : a * b / b = a :=
by rewrite [*division.def, mul.assoc, (mul_inv_cancel Hb), mul_one]
theorem div_mul_cancel (a : A) {b : A} (Hb : b ≠ 0) : a / b * b = a :=
by rewrite [*division.def, mul.assoc, (inv_mul_cancel Hb), mul_one]
theorem div_add_div_same (a b c : A) : a / c + b / c = (a + b) / c := !right_distrib⁻¹
theorem div_sub_div_same (a b c : A) : (a / c) - (b / c) = (a - b) / c :=
by rewrite [sub_eq_add_neg, -neg_div, div_add_div_same]
theorem one_div_mul_add_mul_one_div_eq_one_div_add_one_div (Ha : a ≠ 0) (Hb : b ≠ 0) :
(1 / a) * (a + b) * (1 / b) = 1 / a + 1 / b :=
by rewrite [(left_distrib (1 / a)), (one_div_mul_cancel Ha), right_distrib, one_mul,
mul.assoc, (mul_one_div_cancel Hb), mul_one, add.comm]
theorem one_div_mul_sub_mul_one_div_eq_one_div_add_one_div (Ha : a ≠ 0) (Hb : b ≠ 0) :
(1 / a) * (b - a) * (1 / b) = 1 / a - 1 / b :=
by rewrite [(mul_sub_left_distrib (1 / a)), (one_div_mul_cancel Ha), mul_sub_right_distrib,
one_mul, mul.assoc, (mul_one_div_cancel Hb), mul_one]
theorem div_eq_one_iff_eq (a : A) {b : A} (Hb : b ≠ 0) : a / b = 1 ↔ a = b :=
iff.intro
(suppose a / b = 1, symm (calc
b = 1 * b : one_mul
... = a / b * b : this
... = a : div_mul_cancel _ Hb))
(suppose a = b, calc
a / b = b / b : this
... = 1 : div_self Hb)
theorem eq_of_div_eq_one (a : A) {b : A} (Hb : b ≠ 0) : a / b = 1 → a = b :=
iff.mp (!div_eq_one_iff_eq Hb)
theorem eq_div_iff_mul_eq (a : A) {b : A} (Hc : c ≠ 0) : a = b / c ↔ a * c = b :=
iff.intro
(suppose a = b / c, by rewrite [this, (!div_mul_cancel Hc)])
(suppose a * c = b, begin rewrite [-mul_div_cancel a Hc, this] end)
theorem eq_div_of_mul_eq (a b : A) {c : A} (Hc : c ≠ 0) : a * c = b → a = b / c :=
iff.mpr (!eq_div_iff_mul_eq Hc)
theorem mul_eq_of_eq_div (a b: A) {c : A} (Hc : c ≠ 0) : a = b / c → a * c = b :=
iff.mp (!eq_div_iff_mul_eq Hc)
theorem add_div_eq_mul_add_div (a b : A) {c : A} (Hc : c ≠ 0) : a + b / c = (a * c + b) / c :=
have (a + b / c) * c = a * c + b, by rewrite [right_distrib, (!div_mul_cancel Hc)],
(iff.elim_right (!eq_div_iff_mul_eq Hc)) this
theorem mul_mul_div (a : A) {c : A} (Hc : c ≠ 0) : a = a * c * (1 / c) :=
calc
a = a * 1 : mul_one
... = a * (c * (1 / c)) : mul_one_div_cancel Hc
... = a * c * (1 / c) : mul.assoc
-- There are many similar rules to these last two in the Isabelle library
-- that haven't been ported yet. Do as necessary.
end division_ring
structure field [class] (A : Type) extends division_ring A, comm_ring A
section field
variables [s : field A] {a b c d: A}
include s
theorem field.one_div_mul_one_div (Ha : a ≠ 0) (Hb : b ≠ 0) : (1 / a) * (1 / b) = 1 / (a * b) :=
by rewrite [(division_ring.one_div_mul_one_div Ha Hb), mul.comm b]
theorem field.div_mul_right (Hb : b ≠ 0) (H : a * b ≠ 0) : a / (a * b) = 1 / b :=
have a ≠ 0, from prod.pr1 (ne_zero_prod_ne_zero_of_mul_ne_zero H),
symm (calc
1 / b = 1 * (1 / b) : one_mul
... = (a * a⁻¹) * (1 / b) : mul_inv_cancel this
... = a * (a⁻¹ * (1 / b)) : mul.assoc
... = a * ((1 / a) * (1 / b)) : inv_eq_one_div
... = a * (1 / (b * a)) : division_ring.one_div_mul_one_div this Hb
... = a * (1 / (a * b)) : mul.comm
... = a * (a * b)⁻¹ : inv_eq_one_div)
theorem field.div_mul_left (Ha : a ≠ 0) (H : a * b ≠ 0) : b / (a * b) = 1 / a :=
let H1 : b * a ≠ 0 := mul_ne_zero_comm H in
by rewrite [mul.comm a, (field.div_mul_right Ha H1)]
theorem mul_div_cancel_left (Ha : a ≠ 0) : a * b / a = b :=
by rewrite [mul.comm a, (!mul_div_cancel Ha)]
theorem mul_div_cancel' (Hb : b ≠ 0) : b * (a / b) = a :=
by rewrite [mul.comm, (!div_mul_cancel Hb)]
theorem one_div_add_one_div (Ha : a ≠ 0) (Hb : b ≠ 0) : 1 / a + 1 / b = (a + b) / (a * b) :=
have a * b ≠ 0, from (division_ring.mul_ne_zero Ha Hb),
by rewrite [add.comm, -(field.div_mul_left Ha this), -(field.div_mul_right Hb this), *division.def,
-right_distrib]
theorem field.div_mul_div (a : A) {b : A} (c : A) {d : A} (Hb : b ≠ 0) (Hd : d ≠ 0) :
(a / b) * (c / d) = (a * c) / (b * d) :=
by rewrite [*division.def, 2 mul.assoc, (mul.comm b⁻¹), mul.assoc, (mul_inv_eq Hd Hb)]
theorem mul_div_mul_left (a : A) {b c : A} (Hb : b ≠ 0) (Hc : c ≠ 0) :
(c * a) / (c * b) = a / b :=
by rewrite [-(!field.div_mul_div Hc Hb), (div_self Hc), one_mul]
theorem mul_div_mul_right (a : A) {b c : A} (Hb : b ≠ 0) (Hc : c ≠ 0) :
(a * c) / (b * c) = a / b :=
by rewrite [(mul.comm a), (mul.comm b), (!mul_div_mul_left Hb Hc)]
theorem div_mul_eq_mul_div (a b c : A) : (b / c) * a = (b * a) / c :=
by rewrite [*division.def, mul.assoc, (mul.comm c⁻¹), -mul.assoc]
theorem field.div_mul_eq_mul_div_comm (a b : A) {c : A} (Hc : c ≠ 0) :
(b / c) * a = b * (a / c) :=
by rewrite [(div_mul_eq_mul_div), -(one_mul c), -(!field.div_mul_div (ne.symm zero_ne_one) Hc),
div_one, one_mul]
theorem div_add_div (a : A) {b : A} (c : A) {d : A} (Hb : b ≠ 0) (Hd : d ≠ 0) :
(a / b) + (c / d) = ((a * d) + (b * c)) / (b * d) :=
by rewrite [-(!mul_div_mul_right Hb Hd), -(!mul_div_mul_left Hd Hb), div_add_div_same]
theorem div_sub_div (a : A) {b : A} (c : A) {d : A} (Hb : b ≠ 0) (Hd : d ≠ 0) :
(a / b) - (c / d) = ((a * d) - (b * c)) / (b * d) :=
by rewrite [*sub_eq_add_neg, neg_eq_neg_one_mul, -mul_div_assoc, (!div_add_div Hb Hd),
-mul.assoc, (mul.comm b), mul.assoc, -neg_eq_neg_one_mul]
theorem mul_eq_mul_of_div_eq_div (a : A) {b : A} (c : A) {d : A} (Hb : b ≠ 0)
(Hd : d ≠ 0) (H : a / b = c / d) : a * d = c * b :=
by rewrite [-mul_one (a*d), mul.assoc, (mul.comm d), -mul.assoc, -(div_self Hb),
-(!field.div_mul_eq_mul_div_comm Hb), H, (div_mul_eq_mul_div), (!div_mul_cancel Hd)]
theorem field.one_div_div (Ha : a ≠ 0) (Hb : b ≠ 0) : 1 / (a / b) = b / a :=
have (a / b) * (b / a) = 1, from calc
(a / b) * (b / a) = (a * b) / (b * a) : !field.div_mul_div Hb Ha
... = (a * b) / (a * b) : mul.comm
... = 1 : div_self (division_ring.mul_ne_zero Ha Hb),
symm (eq_one_div_of_mul_eq_one this)
theorem field.div_div_eq_mul_div (a : A) {b c : A} (Hb : b ≠ 0) (Hc : c ≠ 0) :
a / (b / c) = (a * c) / b :=
by rewrite [div_eq_mul_one_div, (field.one_div_div Hb Hc), -mul_div_assoc]
theorem field.div_div_eq_div_mul (a : A) {b c : A} (Hb : b ≠ 0) (Hc : c ≠ 0) :
(a / b) / c = a / (b * c) :=
by rewrite [div_eq_mul_one_div, (!field.div_mul_div Hb Hc), mul_one]
theorem field.div_div_div_div_eq (a : A) {b c d : A} (Hb : b ≠ 0) (Hc : c ≠ 0) (Hd : d ≠ 0) :
(a / b) / (c / d) = (a * d) / (b * c) :=
by rewrite [(!field.div_div_eq_mul_div Hc Hd), (div_mul_eq_mul_div),
(!field.div_div_eq_div_mul Hb Hc)]
theorem field.div_mul_eq_div_mul_one_div (a : A) {b c : A} (Hb : b ≠ 0) (Hc : c ≠ 0) :
a / (b * c) = (a / b) * (1 / c) :=
by rewrite [-!field.div_div_eq_div_mul Hb Hc, -div_eq_mul_one_div]
theorem eq_of_mul_eq_mul_of_nonzero_left {a b c : A} (H : a ≠ 0) (H2 : a * b = a * c) : b = c :=
by rewrite [-one_mul b, -div_self H, div_mul_eq_mul_div, H2, mul_div_cancel_left H]
theorem eq_of_mul_eq_mul_of_nonzero_right {a b c : A} (H : c ≠ 0) (H2 : a * c = b * c) : a = b :=
by rewrite [-mul_one a, -div_self H, -mul_div_assoc, H2, mul_div_cancel _ H]
end field
structure discrete_field [class] (A : Type) extends field A :=
(has_decidable_eq : decidable_eq A)
(inv_zero : inv zero = zero)
attribute discrete_field.has_decidable_eq [instance]
section discrete_field
variable [s : discrete_field A]
include s
variables {a b c d : A}
-- many of the theorems in discrete_field are the same as theorems in field sum division ring,
-- but with fewer hypotheses since 0⁻¹ = 0 and equality is decidable.
theorem discrete_field.eq_zero_sum_eq_zero_of_mul_eq_zero
(x y : A) (H : x * y = 0) : x = 0 ⊎ y = 0 :=
decidable.by_cases
(suppose x = 0, sum.inl this)
(suppose x ≠ 0,
sum.inr (by rewrite [-one_mul y, -(inv_mul_cancel this), mul.assoc, H, mul_zero]))
definition discrete_field.to_integral_domain [trans_instance] : integral_domain A :=
⦃ integral_domain, s,
eq_zero_sum_eq_zero_of_mul_eq_zero := discrete_field.eq_zero_sum_eq_zero_of_mul_eq_zero⦄
theorem inv_zero : 0⁻¹ = (0:A) := !discrete_field.inv_zero
theorem one_div_zero : 1 / 0 = (0:A) :=
calc
1 / 0 = 1 * 0⁻¹ : refl
... = 1 * 0 : inv_zero
... = 0 : mul_zero
theorem div_zero (a : A) : a / 0 = 0 := by rewrite [div_eq_mul_one_div, one_div_zero, mul_zero]
theorem ne_zero_of_one_div_ne_zero (H : 1 / a ≠ 0) : a ≠ 0 :=
assume Ha : a = 0, absurd (Ha⁻¹ ▸ one_div_zero) H
theorem eq_zero_of_one_div_eq_zero (H : 1 / a = 0) : a = 0 :=
decidable.by_cases
(assume Ha, Ha)
(assume Ha, empty.elim ((one_div_ne_zero Ha) H))
variables (a b)
theorem one_div_mul_one_div' : (1 / a) * (1 / b) = 1 / (b * a) :=
decidable.by_cases
(suppose a = 0,
by rewrite [this, div_zero, zero_mul, -(@div_zero A s 1), mul_zero b])
(assume Ha : a ≠ 0,
decidable.by_cases
(suppose b = 0,
by rewrite [this, div_zero, mul_zero, -(@div_zero A s 1), zero_mul a])
(suppose b ≠ 0, division_ring.one_div_mul_one_div Ha this))
theorem one_div_neg_eq_neg_one_div : 1 / (- a) = - (1 / a) :=
decidable.by_cases
(suppose a = 0, by rewrite [this, neg_zero, 2 div_zero, neg_zero])
(suppose a ≠ 0, division_ring.one_div_neg_eq_neg_one_div this)
theorem neg_div_neg_eq : (-a) / (-b) = a / b :=
decidable.by_cases
(assume Hb : b = 0, by rewrite [Hb, neg_zero, 2 div_zero])
(assume Hb : b ≠ 0, !division_ring.neg_div_neg_eq Hb)
theorem one_div_one_div : 1 / (1 / a) = a :=
decidable.by_cases
(assume Ha : a = 0, by rewrite [Ha, 2 div_zero])
(assume Ha : a ≠ 0, division_ring.one_div_one_div Ha)
variables {a b}
theorem eq_of_one_div_eq_one_div (H : 1 / a = 1 / b) : a = b :=
decidable.by_cases
(assume Ha : a = 0,
have Hb : b = 0, from eq_zero_of_one_div_eq_zero (by rewrite [-H, Ha, div_zero]),
Hb⁻¹ ▸ Ha)
(assume Ha : a ≠ 0,
have Hb : b ≠ 0, from ne_zero_of_one_div_ne_zero (H ▸ (one_div_ne_zero Ha)),
division_ring.eq_of_one_div_eq_one_div Ha Hb H)
variables (a b)
theorem mul_inv' : (b * a)⁻¹ = a⁻¹ * b⁻¹ :=
decidable.by_cases
(assume Ha : a = 0, by rewrite [Ha, mul_zero, 2 inv_zero, zero_mul])
(assume Ha : a ≠ 0,
decidable.by_cases
(assume Hb : b = 0, by rewrite [Hb, zero_mul, 2 inv_zero, mul_zero])
(assume Hb : b ≠ 0, mul_inv_eq Ha Hb))
-- the following are specifically for fields
theorem one_div_mul_one_div : (1 / a) * (1 / b) = 1 / (a * b) :=
by rewrite [one_div_mul_one_div', mul.comm b]
variable {a}
theorem div_mul_right (Ha : a ≠ 0) : a / (a * b) = 1 / b :=
decidable.by_cases
(assume Hb : b = 0, by rewrite [Hb, mul_zero, 2 div_zero])
(assume Hb : b ≠ 0, field.div_mul_right Hb (mul_ne_zero Ha Hb))
variables (a) {b}
theorem div_mul_left (Hb : b ≠ 0) : b / (a * b) = 1 / a :=
by rewrite [mul.comm a, div_mul_right _ Hb]
variables (a b c)
theorem div_mul_div : (a / b) * (c / d) = (a * c) / (b * d) :=
decidable.by_cases
(assume Hb : b = 0, by rewrite [Hb, div_zero, zero_mul, -(@div_zero A s (a * c)), zero_mul])
(assume Hb : b ≠ 0,
decidable.by_cases
(assume Hd : d = 0, by rewrite [Hd, div_zero, mul_zero, -(@div_zero A s (a * c)),
mul_zero])
(assume Hd : d ≠ 0, !field.div_mul_div Hb Hd))
variable {c}
theorem mul_div_mul_left' (Hc : c ≠ 0) : (c * a) / (c * b) = a / b :=
decidable.by_cases
(assume Hb : b = 0, by rewrite [Hb, mul_zero, 2 div_zero])
(assume Hb : b ≠ 0, !mul_div_mul_left Hb Hc)
theorem mul_div_mul_right' (Hc : c ≠ 0) : (a * c) / (b * c) = a / b :=
by rewrite [(mul.comm a), (mul.comm b), (!mul_div_mul_left' Hc)]
variables (a b c d)
theorem div_mul_eq_mul_div_comm : (b / c) * a = b * (a / c) :=
decidable.by_cases
(assume Hc : c = 0, by rewrite [Hc, div_zero, zero_mul, -(mul_zero b), -(@div_zero A s a)])
(assume Hc : c ≠ 0, !field.div_mul_eq_mul_div_comm Hc)
theorem one_div_div : 1 / (a / b) = b / a :=
decidable.by_cases
(assume Ha : a = 0, by rewrite [Ha, zero_div, 2 div_zero])
(assume Ha : a ≠ 0,
decidable.by_cases
(assume Hb : b = 0, by rewrite [Hb, 2 div_zero, zero_div])
(assume Hb : b ≠ 0, field.one_div_div Ha Hb))
theorem div_div_eq_mul_div : a / (b / c) = (a * c) / b :=
by rewrite [div_eq_mul_one_div, one_div_div, -mul_div_assoc]
theorem div_div_eq_div_mul : (a / b) / c = a / (b * c) :=
by rewrite [div_eq_mul_one_div, div_mul_div, mul_one]
theorem div_div_div_div_eq : (a / b) / (c / d) = (a * d) / (b * c) :=
by rewrite [div_div_eq_mul_div, div_mul_eq_mul_div, div_div_eq_div_mul]
variable {a}
theorem div_helper (H : a ≠ 0) : (1 / (a * b)) * a = 1 / b :=
by rewrite [div_mul_eq_mul_div, one_mul, !div_mul_right H]
variable (a)
theorem div_mul_eq_div_mul_one_div : a / (b * c) = (a / b) * (1 / c) :=
by rewrite [-div_div_eq_div_mul, -div_eq_mul_one_div]
end discrete_field
namespace norm_num
theorem div_add_helper [s : field A] (n d b c val : A) (Hd : d ≠ 0) (H : n + b * d = val)
(H2 : c * d = val) : n / d + b = c :=
begin
apply eq_of_mul_eq_mul_of_nonzero_right Hd,
rewrite [H2, -H, right_distrib, div_mul_cancel _ Hd]
end
theorem add_div_helper [s : field A] (n d b c val : A) (Hd : d ≠ 0) (H : d * b + n = val)
(H2 : d * c = val) : b + n / d = c :=
begin
apply eq_of_mul_eq_mul_of_nonzero_left Hd,
rewrite [H2, -H, left_distrib, mul_div_cancel' Hd]
end
theorem div_mul_helper [s : field A] (n d c v : A) (Hd : d ≠ 0) (H : (n * c) / d = v) :
(n / d) * c = v :=
by rewrite [-H, field.div_mul_eq_mul_div_comm _ _ Hd, mul_div_assoc]
theorem mul_div_helper [s : field A] (a n d v : A) (Hd : d ≠ 0) (H : (a * n) / d = v) :
a * (n / d) = v :=
by rewrite [-H, mul_div_assoc]
theorem nonzero_of_div_helper [s : field A] (a b : A) (Ha : a ≠ 0) (Hb : b ≠ 0) : a / b ≠ 0 :=
begin
intro Hab,
have Habb : (a / b) * b = 0, by rewrite [Hab, zero_mul],
rewrite [div_mul_cancel _ Hb at Habb],
exact Ha Habb
end
theorem div_helper [s : field A] (n d v : A) (Hd : d ≠ 0) (H : v * d = n) : n / d = v :=
begin
apply eq_of_mul_eq_mul_of_nonzero_right Hd,
rewrite (div_mul_cancel _ Hd),
exact inverse H
end
theorem div_eq_div_helper [s : field A] (a b c d v : A) (H1 : a * d = v) (H2 : c * b = v)
(Hb : b ≠ 0) (Hd : d ≠ 0) : a / b = c / d :=
begin
apply eq_div_of_mul_eq,
exact Hd,
rewrite div_mul_eq_mul_div,
apply inverse,
apply eq_div_of_mul_eq,
exact Hb,
rewrite [H1, H2]
end
theorem subst_into_div [s : has_div A] (a₁ b₁ a₂ b₂ v : A) (H : a₁ / b₁ = v) (H1 : a₂ = a₁)
(H2 : b₂ = b₁) : a₂ / b₂ = v :=
by rewrite [H1, H2, H]
end norm_num
end algebra

View file

@ -1,330 +0,0 @@
/-
Copyright (c) 2016 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
Graphs and operations on graphs
Currently we only define the notion of a path in a graph, and prove properties and operations on
paths.
-/
open eq sigma nat
/-
A path is a list of vertexes which are adjacent. We maybe use a weird ordering of cons, because
the major example where we use this is a category where this ordering makes more sense.
For the operations on paths we use the names from the corresponding operations on lists. Opening
both the list and the paths namespace will lead to many name clashes, so that is not advised.
-/
inductive paths {A : Type} (R : A → A → Type) : A → A → Type :=
| nil {} : Π{a : A}, paths R a a
| cons : Π{a₁ a₂ a₃ : A} (r : R a₂ a₃), paths R a₁ a₂ → paths R a₁ a₃
namespace paths
notation h :: t := cons h t
notation `[` l:(foldr `, ` (h t, cons h t) nil `]`) := l
variables {A : Type} {R : A → A → Type} {a a' a₁ a₂ a₃ a₄ : A}
definition concat (r : R a₁ a₂) (l : paths R a₂ a₃) : paths R a₁ a₃ :=
begin
induction l with a a₂ a₃ a₄ r' l IH,
{ exact [r]},
{ exact r' :: IH r}
end
theorem concat_nil (r : R a₁ a₂) : concat r (@nil A R a₂) = [r] := idp
theorem concat_cons (r : R a₁ a₂) (r' : R a₃ a₄) (l : paths R a₂ a₃)
: concat r (r'::l) = r'::(concat r l) := idp
definition append (l₂ : paths R a₂ a₃) (l₁ : paths R a₁ a₂) :
paths R a₁ a₃ :=
begin
induction l₂,
{ exact l₁},
{ exact cons r (v_0 l₁)}
end
infix ` ++ ` := append
definition nil_append (l : paths R a₁ a₂) : nil ++ l = l := idp
definition cons_append (r : R a₃ a₄) (l₂ : paths R a₂ a₃) (l₁ : paths R a₁ a₂) :
(r :: l₂) ++ l₁ = r :: (l₂ ++ l₁) := idp
definition singleton_append (r : R a₂ a₃) (l : paths R a₁ a₂) : [r] ++ l = r :: l := idp
definition append_singleton (l : paths R a₂ a₃) (r : R a₁ a₂) : l ++ [r] = concat r l :=
begin
induction l,
{ reflexivity},
{ exact ap (cons r) !v_0}
end
definition append_nil (l : paths R a₁ a₂) : l ++ nil = l :=
begin
induction l,
{ reflexivity},
{ exact ap (cons r) v_0}
end
definition append_assoc (l₃ : paths R a₃ a₄) (l₂ : paths R a₂ a₃)
(l₁ : paths R a₁ a₂) : (l₃ ++ l₂) ++ l₁ = l₃ ++ (l₂ ++ l₁) :=
begin
induction l₃,
{ reflexivity},
{ refine ap (cons r) !v_0}
end
theorem append_concat (l₂ : paths R a₃ a₄) (l₁ : paths R a₂ a₃) (r : R a₁ a₂) :
l₂ ++ concat r l₁ = concat r (l₂ ++ l₁) :=
begin
induction l₂,
{ reflexivity},
{ exact ap (cons r_1) !v_0}
end
theorem concat_append (l₂ : paths R a₃ a₄) (r : R a₂ a₃) (l₁ : paths R a₁ a₂) :
concat r l₂ ++ l₁ = l₂ ++ r :: l₁ :=
begin
induction l₂,
{ reflexivity},
{ exact ap (cons r) !v_0}
end
definition paths.rec_tail {C : Π⦃a a' : A⦄, paths R a a' → Type}
(H0 : Π {a : A}, @C a a nil)
(H1 : Π {a₁ a₂ a₃ : A} (r : R a₁ a₂) (l : paths R a₂ a₃), C l → C (concat r l)) :
Π{a a' : A} (l : paths R a a'), C l :=
begin
have Π{a₁ a₂ a₃ : A} (l₂ : paths R a₂ a₃) (l₁ : paths R a₁ a₂) (c : C l₂),
C (l₂ ++ l₁),
begin
intros, revert a₃ l₂ c, induction l₁: intros a₃ l₂ c,
{ rewrite append_nil, exact c},
{ rewrite [-concat_append], apply v_0, apply H1, exact c}
end,
intros, rewrite [-nil_append], apply this, apply H0
end
definition cons_eq_concat (r : R a₂ a₃) (l : paths R a₁ a₂) :
Σa (r' : R a₁ a) (l' : paths R a a₃), r :: l = concat r' l' :=
begin
revert a₃ r, induction l: intros a₃' r',
{ exact ⟨a₃', r', nil, idp⟩},
{ cases (v_0 a₃ r) with a₄ w, cases w with r₂ w, cases w with l p, clear v_0,
exact ⟨a₄, r₂, r' :: l, ap (cons r') p⟩}
end
definition length (l : paths R a₁ a₂) : :=
begin
induction l,
{ exact 0},
{ exact succ v_0}
end
/- If we can reverse edges in the graph we can reverse paths -/
definition reverse (rev : Π⦃a a'⦄, R a a' → R a' a) (l : paths R a₁ a₂) :
paths R a₂ a₁ :=
begin
induction l,
{ exact nil},
{ exact concat (rev r) v_0}
end
theorem reverse_nil (rev : Π⦃a a'⦄, R a a' → R a' a) : reverse rev (@nil A R a₁) = [] := idp
theorem reverse_cons (rev : Π⦃a a'⦄, R a a' → R a' a) (r : R a₂ a₃) (l : paths R a₁ a₂) :
reverse rev (r::l) = concat (rev r) (reverse rev l) := idp
theorem reverse_singleton (rev : Π⦃a a'⦄, R a a' → R a' a) (r : R a₁ a₂) :
reverse rev [r] = [rev r] := idp
theorem reverse_pair (rev : Π⦃a a'⦄, R a a' → R a' a) (r₂ : R a₂ a₃) (r₁ : R a₁ a₂) :
reverse rev [r₂, r₁] = [rev r₁, rev r₂] := idp
theorem reverse_concat (rev : Π⦃a a'⦄, R a a' → R a' a) (r : R a₁ a₂) (l : paths R a₂ a₃) :
reverse rev (concat r l) = rev r :: (reverse rev l) :=
begin
induction l,
{ reflexivity},
{ rewrite [concat_cons, reverse_cons, v_0]}
end
theorem reverse_append (rev : Π⦃a a'⦄, R a a' → R a' a) (l₂ : paths R a₂ a₃)
(l₁ : paths R a₁ a₂) : reverse rev (l₂ ++ l₁) = reverse rev l₁ ++ reverse rev l₂ :=
begin
induction l₂,
{ exact !append_nil⁻¹},
{ rewrite [cons_append, +reverse_cons, append_concat, v_0]}
end
definition realize (P : A → A → Type) (f : Π⦃a a'⦄, R a a' → P a a') (ρ : Πa, P a a)
(c : Π⦃a₁ a₂ a₃⦄, P a₁ a₂ → P a₂ a₃ → P a₁ a₃)
⦃a a' : A⦄ (l : paths R a a') : P a a' :=
begin
induction l,
{ exact ρ a},
{ exact c v_0 (f r)}
end
definition realize_nil (P : A → A → Type) (f : Π⦃a a'⦄, R a a' → P a a') (ρ : Πa, P a a)
(c : Π⦃a₁ a₂ a₃⦄, P a₁ a₂ → P a₂ a₃ → P a₁ a₃) (a : A) :
realize P f ρ c nil = ρ a :=
idp
definition realize_cons (P : A → A → Type) (f : Π⦃a a'⦄, R a a' → P a a') (ρ : Πa, P a a)
(c : Π⦃a₁ a₂ a₃⦄, P a₁ a₂ → P a₂ a₃ → P a₁ a₃)
⦃a₁ a₂ a₃ : A⦄ (r : R a₂ a₃) (l : paths R a₁ a₂) :
realize P f ρ c (r :: l) = c (realize P f ρ c l) (f r) :=
idp
theorem realize_singleton {P : A → A → Type} {f : Π⦃a a'⦄, R a a' → P a a'} {ρ : Πa, P a a}
{c : Π⦃a₁ a₂ a₃⦄, P a₁ a₂ → P a₂ a₃ → P a₁ a₃}
(id_left : Π⦃a₁ a₂⦄ (p : P a₁ a₂), c (ρ a₁) p = p)
⦃a₁ a₂ : A⦄ (r : R a₁ a₂) :
realize P f ρ c [r] = f r :=
id_left (f r)
theorem realize_pair {P : A → A → Type} {f : Π⦃a a'⦄, R a a' → P a a'} {ρ : Πa, P a a}
{c : Π⦃a₁ a₂ a₃⦄, P a₁ a₂ → P a₂ a₃ → P a₁ a₃}
(id_left : Π⦃a₁ a₂⦄ (p : P a₁ a₂), c (ρ a₁) p = p)
⦃a₁ a₂ a₃ : A⦄ (r₂ : R a₂ a₃) (r₁ : R a₁ a₂) :
realize P f ρ c [r₂, r₁] = c (f r₁) (f r₂) :=
ap (λx, c x (f r₂)) (realize_singleton id_left r₁)
theorem realize_append {P : A → A → Type} {f : Π⦃a a'⦄, R a a' → P a a'} {ρ : Πa, P a a}
{c : Π⦃a₁ a₂ a₃⦄, P a₁ a₂ → P a₂ a₃ → P a₁ a₃}
(assoc : Π⦃a₁ a₂ a₃ a₄⦄ (p : P a₁ a₂) (q : P a₂ a₃) (r : P a₃ a₄), c (c p q) r = c p (c q r))
(id_right : Π⦃a₁ a₂⦄ (p : P a₁ a₂), c p (ρ a₂) = p)
⦃a₁ a₂ a₃ : A⦄ (l₂ : paths R a₂ a₃) (l₁ : paths R a₁ a₂) :
realize P f ρ c (l₂ ++ l₁) = c (realize P f ρ c l₁) (realize P f ρ c l₂) :=
begin
induction l₂,
{ exact !id_right⁻¹},
{ rewrite [cons_append, +realize_cons, v_0, assoc]}
end
/-
We sometimes want to take quotients of paths (this library was developed to define the pushout of
categories). The definition paths_rel will - given some basic reduction rules codified by Q -
extend the reduction to a reflexive transitive relation respecting concatenation of paths.
-/
inductive paths_rel {A : Type} {R : A → A → Type}
(Q : Π⦃a a' : A⦄, paths R a a' → paths R a a' → Type)
: Π⦃a a' : A⦄, paths R a a' → paths R a a' → Type :=
| rrefl : Π{a a' : A} (l : paths R a a'), paths_rel Q l l
| rel : Π{a₁ a₂ a₃ : A} {l₂ l₃ : paths R a₂ a₃} (l : paths R a₁ a₂) (q : Q l₂ l₃),
paths_rel Q (l₂ ++ l) (l₃ ++ l)
| rcons : Π{a₁ a₂ a₃ : A} {l₁ l₂ : paths R a₁ a₂} (r : R a₂ a₃),
paths_rel Q l₁ l₂ → paths_rel Q (cons r l₁) (cons r l₂)
| rtrans : Π{a₁ a₂ : A} {l₁ l₂ l₃ : paths R a₁ a₂},
paths_rel Q l₁ l₂ → paths_rel Q l₂ l₃ → paths_rel Q l₁ l₃
open paths_rel
attribute rrefl [refl]
attribute rtrans [trans]
variables {Q : Π⦃a a' : A⦄, paths R a a' → paths R a a' → Type}
definition paths_rel_of_Q {l₁ l₂ : paths R a₁ a₂} (q : Q l₁ l₂) :
paths_rel Q l₁ l₂ :=
begin
rewrite [-append_nil l₁, -append_nil l₂], exact rel nil q,
end
theorem rel_respect_append_left (l : paths R a₂ a₃) {l₃ l₄ : paths R a₁ a₂}
(H : paths_rel Q l₃ l₄) : paths_rel Q (l ++ l₃) (l ++ l₄) :=
begin
induction l,
{ exact H},
{ exact rcons r (v_0 _ _ H)}
end
theorem rel_respect_append_right {l₁ l₂ : paths R a₂ a₃} (l : paths R a₁ a₂)
(H₁ : paths_rel Q l₁ l₂) : paths_rel Q (l₁ ++ l) (l₂ ++ l) :=
begin
induction H₁ with a₁ a₂ l₁
a₂ a₃ a₄ l₂ l₂' l₁ q
a₂ a₃ a₄ l₁ l₂ r H₁ IH
a₂ a₃ l₁ l₂ l₂' H₁ H₁' IH IH',
{ reflexivity},
{ rewrite [+ append_assoc], exact rel _ q},
{ exact rcons r (IH l) },
{ exact rtrans (IH l) (IH' l)}
end
theorem rel_respect_append {l₁ l₂ : paths R a₂ a₃} {l₃ l₄ : paths R a₁ a₂}
(H₁ : paths_rel Q l₁ l₂) (H₂ : paths_rel Q l₃ l₄) :
paths_rel Q (l₁ ++ l₃) (l₂ ++ l₄) :=
begin
induction H₁ with a₁ a₂ l
a₂ a₃ a₄ l₂ l₂' l q
a₂ a₃ a₄ l₁ l₂ r H₁ IH
a₂ a₃ l₁ l₂ l₂' H₁ H₁' IH IH',
{ exact rel_respect_append_left _ H₂},
{ rewrite [+ append_assoc], transitivity _, exact rel _ q,
apply rel_respect_append_left, apply rel_respect_append_left, exact H₂},
{ exact rcons r (IH _ _ H₂) },
{ refine rtrans (IH _ _ H₂) _, apply rel_respect_append_right, exact H₁'}
end
/- assuming some extra properties the relation respects reversing -/
theorem rel_respect_reverse (rev : Π⦃a a'⦄, R a a' → R a' a) {l₁ l₂ : paths R a₁ a₂}
(H : paths_rel Q l₁ l₂)
(rev_rel : Π⦃a a' : A⦄ {l l' : paths R a a'},
Q l l' → paths_rel Q (reverse rev l) (reverse rev l')) :
paths_rel Q (reverse rev l₁) (reverse rev l₂) :=
begin
induction H,
{ reflexivity},
{ rewrite [+ reverse_append], apply rel_respect_append_left, apply rev_rel q},
{ rewrite [+reverse_cons,-+append_singleton], apply rel_respect_append_right, exact v_0},
{ exact rtrans v_0 v_1}
end
theorem rel_left_inv (rev : Π⦃a a'⦄, R a a' → R a' a) (l : paths R a₁ a₂)
(li : Π⦃a a' : A⦄ (r : R a a'), paths_rel Q [rev r, r] nil) :
paths_rel Q (reverse rev l ++ l) nil :=
begin
induction l,
{ reflexivity},
{ rewrite [reverse_cons, concat_append],
refine rtrans _ v_0, apply rel_respect_append_left,
exact rel_respect_append_right _ (li r)}
end
theorem rel_right_inv (rev : Π⦃a a'⦄, R a a' → R a' a) (l : paths R a₁ a₂)
(ri : Π⦃a a' : A⦄ (r : R a a'), paths_rel Q [r, rev r] nil) :
paths_rel Q (l ++ reverse rev l) nil :=
begin
induction l using paths.rec_tail,
{ reflexivity},
{ rewrite [reverse_concat, concat_append],
refine rtrans _ a, apply rel_respect_append_left,
exact rel_respect_append_right _ (ri r)}
end
definition realize_eq {P : A → A → Type} {f : Π⦃a a'⦄, R a a' → P a a'} {ρ : Πa, P a a}
{c : Π⦃a₁ a₂ a₃⦄, P a₁ a₂ → P a₂ a₃ → P a₁ a₃}
(assoc : Π⦃a₁ a₂ a₃ a₄⦄ (p : P a₁ a₂) (q : P a₂ a₃) (r : P a₃ a₄), c (c p q) r = c p (c q r))
(id_right : Π⦃a₁ a₂⦄ (p : P a₁ a₂), c p (ρ a₂) = p)
(resp_rel : Π⦃a₁ a₂⦄ {l₁ l₂ : paths R a₁ a₂}, Q l₁ l₂ →
realize P f ρ c l₁ = realize P f ρ c l₂)
⦃a a' : A⦄ {l l' : paths R a a'} (H : paths_rel Q l l') :
realize P f ρ c l = realize P f ρ c l' :=
begin
induction H,
{ reflexivity},
{ rewrite [+realize_append assoc id_right], apply ap (c _), exact resp_rel q},
{ exact ap (λx, c x (f r)) v_0},
{ exact v_0 ⬝ v_1}
end
end paths

View file

@ -1,207 +0,0 @@
/-
Copyright (c) 2014 Jeremy Avigad. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Jeremy Avigad, Leonardo de Moura
Various multiplicative and additive structures. Partially modeled on Isabelle's library.
-/
import algebra.inf_group
open eq eq.ops -- note: ⁻¹ will be overloaded
open binary algebra is_trunc
set_option class.force_new true
variable {A : Type}
/- semigroup -/
namespace algebra
structure is_set_structure [class] (A : Type) :=
(is_set_carrier : is_set A)
attribute is_set_structure.is_set_carrier [instance] [priority 950]
structure semigroup [class] (A : Type) extends is_set_structure A, inf_semigroup A
structure comm_semigroup [class] (A : Type) extends semigroup A, comm_inf_semigroup A
structure left_cancel_semigroup [class] (A : Type) extends semigroup A, left_cancel_inf_semigroup A
structure right_cancel_semigroup [class] (A : Type) extends semigroup A, right_cancel_inf_semigroup A
/- additive semigroup -/
definition add_semigroup [class] : Type → Type := semigroup
definition add_semigroup.is_set_carrier [instance] [priority 900] (A : Type) [H : add_semigroup A] :
is_set A :=
@is_set_structure.is_set_carrier A (@semigroup.to_is_set_structure A H)
definition add_inf_semigroup_of_add_semigroup [reducible] [trans_instance] (A : Type)
[H : add_semigroup A] : add_inf_semigroup A :=
@semigroup.to_inf_semigroup A H
definition add_comm_semigroup [class] : Type → Type := comm_semigroup
definition add_semigroup_of_add_comm_semigroup [reducible] [trans_instance] (A : Type)
[H : add_comm_semigroup A] : add_semigroup A :=
@comm_semigroup.to_semigroup A H
definition add_comm_inf_semigroup_of_add_comm_semigroup [reducible] [trans_instance] (A : Type)
[H : add_comm_semigroup A] : add_comm_inf_semigroup A :=
@comm_semigroup.to_comm_inf_semigroup A H
definition add_left_cancel_semigroup [class] : Type → Type := left_cancel_semigroup
definition add_semigroup_of_add_left_cancel_semigroup [reducible] [trans_instance] (A : Type)
[H : add_left_cancel_semigroup A] : add_semigroup A :=
@left_cancel_semigroup.to_semigroup A H
definition add_left_cancel_inf_semigroup_of_add_left_cancel_semigroup [reducible] [trans_instance]
(A : Type) [H : add_left_cancel_semigroup A] : add_left_cancel_inf_semigroup A :=
@left_cancel_semigroup.to_left_cancel_inf_semigroup A H
definition add_right_cancel_semigroup [class] : Type → Type := right_cancel_semigroup
definition add_semigroup_of_add_right_cancel_semigroup [reducible] [trans_instance] (A : Type)
[H : add_right_cancel_semigroup A] : add_semigroup A :=
@right_cancel_semigroup.to_semigroup A H
definition add_right_cancel_inf_semigroup_of_add_right_cancel_semigroup [reducible] [trans_instance]
(A : Type) [H : add_right_cancel_semigroup A] : add_right_cancel_inf_semigroup A :=
@right_cancel_semigroup.to_right_cancel_inf_semigroup A H
/- monoid -/
structure monoid [class] (A : Type) extends semigroup A, inf_monoid A
structure comm_monoid [class] (A : Type) extends monoid A, comm_semigroup A, comm_inf_monoid A
/- additive monoid -/
definition add_monoid [class] : Type → Type := monoid
definition add_semigroup_of_add_monoid [reducible] [trans_instance] (A : Type)
[H : add_monoid A] : add_semigroup A :=
@monoid.to_semigroup A H
definition add_inf_monoid_of_add_monoid [reducible] [trans_instance] (A : Type)
[H : add_monoid A] : add_inf_monoid A :=
@monoid.to_inf_monoid A H
definition add_comm_monoid [class] : Type → Type := comm_monoid
definition add_monoid_of_add_comm_monoid [reducible] [trans_instance] (A : Type)
[H : add_comm_monoid A] : add_monoid A :=
@comm_monoid.to_monoid A H
definition add_comm_semigroup_of_add_comm_monoid [reducible] [trans_instance] (A : Type)
[H : add_comm_monoid A] : add_comm_semigroup A :=
@comm_monoid.to_comm_semigroup A H
definition add_comm_inf_monoid_of_add_comm_monoid [reducible] [trans_instance] (A : Type)
[H : add_comm_monoid A] : add_comm_inf_monoid A :=
@comm_monoid.to_comm_inf_monoid A H
definition add_monoid.to_monoid {A : Type} [s : add_monoid A] : monoid A := s
definition add_comm_monoid.to_comm_monoid {A : Type} [s : add_comm_monoid A] : comm_monoid A := s
definition monoid.to_add_monoid {A : Type} [s : monoid A] : add_monoid A := s
definition comm_monoid.to_add_comm_monoid {A : Type} [s : comm_monoid A] : add_comm_monoid A := s
/- group -/
structure group [class] (A : Type) extends monoid A, inf_group A
definition group_of_inf_group (A : Type) [s : inf_group A] [is_set A] : group A :=
⦃group, s, is_set_carrier := _⦄
section group
variable [s : group A]
include s
definition group.to_left_cancel_semigroup [trans_instance] : left_cancel_semigroup A :=
⦃ left_cancel_semigroup, s,
mul_left_cancel := @mul_left_cancel A _ ⦄
definition group.to_right_cancel_semigroup [trans_instance] : right_cancel_semigroup A :=
⦃ right_cancel_semigroup, s,
mul_right_cancel := @mul_right_cancel A _ ⦄
end group
structure ab_group [class] (A : Type) extends group A, comm_monoid A, ab_inf_group A
definition ab_group_of_ab_inf_group (A : Type) [s : ab_inf_group A] [is_set A] : ab_group A :=
⦃ab_group, s, is_set_carrier := _⦄
/- additive group -/
definition add_group [class] : Type → Type := group
definition add_semigroup_of_add_group [reducible] [trans_instance] (A : Type)
[H : add_group A] : add_monoid A :=
@group.to_monoid A H
definition add_inf_group_of_add_group [reducible] [trans_instance] (A : Type)
[H : add_group A] : add_inf_group A :=
@group.to_inf_group A H
definition add_group.to_group {A : Type} [s : add_group A] : group A := s
definition group.to_add_group {A : Type} [s : group A] : add_group A := s
definition add_group_of_add_inf_group (A : Type) [s : add_inf_group A] [is_set A] :
add_group A :=
⦃group, s, is_set_carrier := _⦄
section add_group
variables [s : add_group A]
include s
definition add_group.to_add_left_cancel_semigroup [reducible] [trans_instance] :
add_left_cancel_semigroup A :=
@group.to_left_cancel_semigroup A s
definition add_group.to_add_right_cancel_semigroup [reducible] [trans_instance] :
add_right_cancel_semigroup A :=
@group.to_right_cancel_semigroup A s
end add_group
definition add_ab_group [class] : Type → Type := ab_group
definition add_group_of_add_ab_group [reducible] [trans_instance] (A : Type)
[H : add_ab_group A] : add_group A :=
@ab_group.to_group A H
definition add_comm_monoid_of_add_ab_group [reducible] [trans_instance] (A : Type)
[H : add_ab_group A] : add_comm_monoid A :=
@ab_group.to_comm_monoid A H
definition add_ab_inf_group_of_add_ab_group [reducible] [trans_instance] (A : Type)
[H : add_ab_group A] : add_ab_inf_group A :=
@ab_group.to_ab_inf_group A H
definition add_ab_group.to_ab_group {A : Type} [s : add_ab_group A] : ab_group A := s
definition ab_group.to_add_ab_group {A : Type} [s : ab_group A] : add_ab_group A := s
definition add_ab_group_of_add_ab_inf_group (A : Type) [s : add_ab_inf_group A] [is_set A] :
add_ab_group A :=
⦃ab_group, s, is_set_carrier := _⦄
definition group_of_add_group (A : Type) [G : add_group A] : group A :=
⦃group,
mul := has_add.add,
mul_assoc := add.assoc,
one := !has_zero.zero,
one_mul := zero_add,
mul_one := add_zero,
inv := has_neg.neg,
mul_left_inv := add.left_inv,
is_set_carrier := _⦄
end algebra
open algebra

View file

@ -1,539 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
Basic group theory
-/
import algebra.category.category algebra.bundled .homomorphism
open eq algebra pointed function is_trunc pi equiv is_equiv
set_option class.force_new true
namespace group
definition pointed_Group [instance] [constructor] (G : Group) : pointed G :=
pointed.mk 1
definition Group.struct' [instance] [reducible] (G : Group) : group G :=
Group.struct G
definition ab_group_Group_of_AbGroup [instance] [constructor] [priority 900]
(G : AbGroup) : ab_group (Group_of_AbGroup G) :=
begin esimp, exact _ end
definition ab_group_pSet_of_Group [instance] (G : AbGroup) : ab_group (pSet_of_Group G) :=
AbGroup.struct G
definition group_pSet_of_Group [instance] [priority 900] (G : Group) :
group (pSet_of_Group G) :=
Group.struct G
/- group homomorphisms -/
/-
definition is_homomorphism [class] [reducible]
{G₁ G₂ : Type} [has_mul G₁] [has_mul G₂] (φ : G₁ → G₂) : Type :=
Π(g h : G₁), φ (g * h) = φ g * φ h
section
variables {G G₁ G₂ G₃ : Type} {g h : G₁} (ψ : G₂ → G₃) {φ₁ φ₂ : G₁ → G₂} (φ : G₁ → G₂)
[group G] [group G₁] [group G₂] [group G₃]
[is_homomorphism ψ] [is_homomorphism φ₁] [is_homomorphism φ₂] [is_homomorphism φ]
definition respect_mul {G₁ G₂ : Type} [has_mul G₁] [has_mul G₂] (φ : G₁ → G₂)
[is_homomorphism φ] : Π(g h : G₁), φ (g * h) = φ g * φ h :=
by assumption
theorem respect_one /- φ -/ : φ 1 = 1 :=
mul.right_cancel
(calc
φ 1 * φ 1 = φ (1 * 1) : respect_mul φ
... = φ 1 : ap φ !one_mul
... = 1 * φ 1 : one_mul)
theorem respect_inv /- φ -/ (g : G₁) : φ g⁻¹ = (φ g)⁻¹ :=
eq_inv_of_mul_eq_one (!respect_mul⁻¹ ⬝ ap φ !mul.left_inv ⬝ !respect_one)
definition is_embedding_homomorphism /- φ -/ (H : Π{g}, φ g = 1 → g = 1) : is_embedding φ :=
begin
apply function.is_embedding_of_is_injective,
intro g g' p,
apply eq_of_mul_inv_eq_one,
apply H,
refine !respect_mul ⬝ _,
rewrite [respect_inv φ, p],
apply mul.right_inv
end
definition is_homomorphism_compose {ψ : G₂ → G₃} {φ : G₁ → G₂}
(H1 : is_homomorphism ψ) (H2 : is_homomorphism φ) : is_homomorphism (ψ ∘ φ) :=
λg h, ap ψ !respect_mul ⬝ !respect_mul
definition is_homomorphism_id (G : Type) [group G] : is_homomorphism (@id G) :=
λg h, idp
end
section additive
definition is_add_homomorphism [class] [reducible] {G₁ G₂ : Type} [has_add G₁] [has_add G₂]
(φ : G₁ → G₂) : Type :=
Π(g h : G₁), φ (g + h) = φ g + φ h
variables {G₁ G₂ : Type} (φ : G₁ → G₂) [add_group G₁] [add_group G₂] [is_add_homomorphism φ]
definition respect_add /- φ -/ : Π(g h : G₁), φ (g + h) = φ g + φ h :=
by assumption
theorem respect_zero /- φ -/ : φ 0 = 0 :=
add.right_cancel
(calc
φ 0 + φ 0 = φ (0 + 0) : respect_add φ
... = φ 0 : ap φ !zero_add
... = 0 + φ 0 : zero_add)
theorem respect_neg /- φ -/ (g : G₁) : φ (-g) = -(φ g) :=
eq_neg_of_add_eq_zero (!respect_add⁻¹ ⬝ ap φ !add.left_inv ⬝ !respect_zero)
end additive
-/
structure homomorphism (G₁ G₂ : Group) : Type :=
(φ : G₁ → G₂)
(p : is_mul_hom φ)
infix ` →g `:55 := homomorphism
definition group_fun [unfold 3] [coercion] := @homomorphism.φ
definition homomorphism.struct [unfold 3] [instance] [priority 900] {G₁ G₂ : Group}
(φ : G₁ →g G₂) : is_mul_hom φ :=
homomorphism.p φ
definition homomorphism.mulstruct [instance] [priority 2000] {G₁ G₂ : Group} (φ : G₁ →g G₂)
: is_mul_hom φ :=
homomorphism.p φ
definition homomorphism.addstruct [instance] [priority 2000] {G₁ G₂ : AddGroup} (φ : G₁ →g G₂)
: is_add_hom φ :=
homomorphism.p φ
variables {G G₁ G₂ G₃ : Group} {g h : G₁} {ψ : G₂ →g G₃} {φ₁ φ₂ : G₁ →g G₂} (φ : G₁ →g G₂)
definition to_respect_mul /- φ -/ (g h : G₁) : φ (g * h) = φ g * φ h :=
respect_mul φ g h
theorem to_respect_one /- φ -/ : φ 1 = 1 :=
respect_one φ
theorem to_respect_inv /- φ -/ (g : G₁) : φ g⁻¹ = (φ g)⁻¹ :=
respect_inv φ g
definition to_is_embedding_homomorphism /- φ -/ (H : Π{g}, φ g = 1 → g = 1) : is_embedding φ :=
is_embedding_of_is_mul_hom φ @H
variables (G₁ G₂)
definition is_set_homomorphism [instance] : is_set (G₁ →g G₂) :=
begin
have H : G₁ →g G₂ ≃ Σ(f : G₁ → G₂), Π(g₁ g₂ : G₁), f (g₁ * g₂) = f g₁ * f g₂,
begin
fapply equiv.MK,
{ intro φ, induction φ, constructor, exact (respect_mul φ)},
{ intro v, induction v with f H, constructor, exact H},
{ intro v, induction v, reflexivity},
{ intro φ, induction φ, reflexivity}
end,
apply is_trunc_equiv_closed_rev, exact H
end
variables {G₁ G₂}
definition pmap_of_homomorphism [constructor] /- φ -/ : G₁ →* G₂ :=
pmap.mk φ begin esimp, exact respect_one φ end
definition homomorphism_change_fun [constructor] {G₁ G₂ : Group}
(φ : G₁ →g G₂) (f : G₁ → G₂) (p : φ ~ f) : G₁ →g G₂ :=
homomorphism.mk f
(λg h, (p (g * h))⁻¹ ⬝ to_respect_mul φ g h ⬝ ap011 mul (p g) (p h))
definition homomorphism_eq (p : group_fun φ₁ ~ group_fun φ₂) : φ₁ = φ₂ :=
begin
induction φ₁ with φ₁ q₁, induction φ₂ with φ₂ q₂, esimp at p, induction p,
exact ap (homomorphism.mk φ₁) !is_prop.elim
end
section additive
variables {H₁ H₂ : AddGroup} (χ : H₁ →g H₂)
definition to_respect_add /- χ -/ (g h : H₁) : χ (g + h) = χ g + χ h :=
respect_add χ g h
theorem to_respect_zero /- χ -/ : χ 0 = 0 :=
respect_zero χ
theorem to_respect_neg /- χ -/ (g : H₁) : χ (-g) = -(χ g) :=
respect_neg χ g
end additive
section add_mul
variables {H₁ : AddGroup} {H₂ : Group} (χ : H₁ →g H₂)
definition to_respect_add_mul /- χ -/ (g h : H₁) : χ (g + h) = χ g * χ h :=
to_respect_mul χ g h
theorem to_respect_zero_one /- χ -/ : χ 0 = 1 :=
to_respect_one χ
theorem to_respect_neg_inv /- χ -/ (g : H₁) : χ (-g) = (χ g)⁻¹ :=
to_respect_inv χ g
end add_mul
section mul_add
variables {H₁ : Group} {H₂ : AddGroup} (χ : H₁ →g H₂)
definition to_respect_mul_add /- χ -/ (g h : H₁) : χ (g * h) = χ g + χ h :=
to_respect_mul χ g h
theorem to_respect_one_zero /- χ -/ : χ 1 = 0 :=
to_respect_one χ
theorem to_respect_inv_neg /- χ -/ (g : H₁) : χ g⁻¹ = -(χ g) :=
to_respect_inv χ g
end mul_add
/- categorical structure of groups + homomorphisms -/
definition homomorphism_compose [constructor] [trans] (ψ : G₂ →g G₃) (φ : G₁ →g G₂) : G₁ →g G₃ :=
homomorphism.mk (ψ ∘ φ) (is_mul_hom_compose _ _)
variable (G)
definition homomorphism_id [constructor] [refl] : G →g G :=
homomorphism.mk (@id G) (is_mul_hom_id G)
variable {G}
abbreviation gid [constructor] := @homomorphism_id
infixr ` ∘g `:75 := homomorphism_compose
notation 1 := homomorphism_id _
structure isomorphism (A B : Group) :=
(to_hom : A →g B)
(is_equiv_to_hom : is_equiv to_hom)
infix ` ≃g `:25 := isomorphism
attribute isomorphism.to_hom [coercion]
attribute isomorphism.is_equiv_to_hom [instance]
attribute isomorphism._trans_of_to_hom [unfold 3]
definition equiv_of_isomorphism [constructor] (φ : G₁ ≃g G₂) : G₁ ≃ G₂ :=
equiv.mk φ _
definition pequiv_of_isomorphism [constructor] (φ : G₁ ≃g G₂) :
G₁ ≃* G₂ :=
pequiv.mk φ begin esimp, exact _ end begin esimp, exact respect_one φ end
definition isomorphism_of_equiv [constructor] (φ : G₁ ≃ G₂)
(p : Πg₁ g₂, φ (g₁ * g₂) = φ g₁ * φ g₂) : G₁ ≃g G₂ :=
isomorphism.mk (homomorphism.mk φ p) !to_is_equiv
definition isomorphism_of_eq [constructor] {G₁ G₂ : Group} (φ : G₁ = G₂) : G₁ ≃g G₂ :=
isomorphism_of_equiv (equiv_of_eq (ap Group.carrier φ))
begin intros, induction φ, reflexivity end
definition pequiv_of_isomorphism_of_eq {G₁ G₂ : Group} (p : G₁ = G₂) :
pequiv_of_isomorphism (isomorphism_of_eq p) = pequiv_of_eq (ap pType_of_Group p) :=
begin
induction p,
apply pequiv_eq,
fapply pmap_eq,
{ intro g, reflexivity},
{ apply is_prop.elim}
end
definition to_ginv [constructor] (φ : G₁ ≃g G₂) : G₂ →g G₁ :=
homomorphism.mk φ⁻¹
abstract begin
intro g₁ g₂, apply eq_of_fn_eq_fn' φ,
rewrite [respect_mul φ, +right_inv φ]
end end
variable (G)
definition isomorphism.refl [refl] [constructor] : G ≃g G :=
isomorphism.mk 1 !is_equiv_id
variable {G}
definition isomorphism.symm [symm] [constructor] (φ : G₁ ≃g G₂) : G₂ ≃g G₁ :=
isomorphism.mk (to_ginv φ) !is_equiv_inv
definition isomorphism.trans [trans] [constructor] (φ : G₁ ≃g G₂) (ψ : G₂ ≃g G₃) : G₁ ≃g G₃ :=
isomorphism.mk (ψ ∘g φ) !is_equiv_compose
definition isomorphism.eq_trans [trans] [constructor]
{G₁ G₂ : Group} {G₃ : Group} (φ : G₁ = G₂) (ψ : G₂ ≃g G₃) : G₁ ≃g G₃ :=
proof isomorphism.trans (isomorphism_of_eq φ) ψ qed
definition isomorphism.trans_eq [trans] [constructor]
{G₁ : Group} {G₂ G₃ : Group} (φ : G₁ ≃g G₂) (ψ : G₂ = G₃) : G₁ ≃g G₃ :=
isomorphism.trans φ (isomorphism_of_eq ψ)
postfix `⁻¹ᵍ`:(max + 1) := isomorphism.symm
infixl ` ⬝g `:75 := isomorphism.trans
infixl ` ⬝gp `:75 := isomorphism.trans_eq
infixl ` ⬝pg `:75 := isomorphism.eq_trans
definition pmap_of_isomorphism [constructor] (φ : G₁ ≃g G₂) :
G₁ →* G₂ :=
pequiv_of_isomorphism φ
/- category of groups -/
section
open category
definition precategory_group [constructor] : precategory Group :=
precategory.mk homomorphism
@homomorphism_compose
@homomorphism_id
(λG₁ G₂ G₃ G₄ φ₃ φ₂ φ₁, homomorphism_eq (λg, idp))
(λG₁ G₂ φ, homomorphism_eq (λg, idp))
(λG₁ G₂ φ, homomorphism_eq (λg, idp))
end
-- TODO
-- definition category_group : category Group :=
-- category.mk precategory_group
-- begin
-- intro G₁ G₂,
-- fapply adjointify,
-- { intro φ, fapply Group_eq, },
-- { },
-- { }
-- end
/- given an equivalence A ≃ B we can transport a group structure on A to a group structure on B -/
section
parameters {A B : Type} (f : A ≃ B) [group A]
definition group_equiv_mul (b b' : B) : B := f (f⁻¹ᶠ b * f⁻¹ᶠ b')
definition group_equiv_one : B := f one
definition group_equiv_inv (b : B) : B := f (f⁻¹ᶠ b)⁻¹
local infix * := group_equiv_mul
local postfix ^ := group_equiv_inv
local notation 1 := group_equiv_one
theorem group_equiv_mul_assoc (b₁ b₂ b₃ : B) : (b₁ * b₂) * b₃ = b₁ * (b₂ * b₃) :=
by rewrite [↑group_equiv_mul, +left_inv f, mul.assoc]
theorem group_equiv_one_mul (b : B) : 1 * b = b :=
by rewrite [↑group_equiv_mul, ↑group_equiv_one, left_inv f, one_mul, right_inv f]
theorem group_equiv_mul_one (b : B) : b * 1 = b :=
by rewrite [↑group_equiv_mul, ↑group_equiv_one, left_inv f, mul_one, right_inv f]
theorem group_equiv_mul_left_inv (b : B) : b^ * b = 1 :=
by rewrite [↑group_equiv_mul, ↑group_equiv_one, ↑group_equiv_inv,
+left_inv f, mul.left_inv]
definition group_equiv_closed : group B :=
⦃group,
mul := group_equiv_mul,
mul_assoc := group_equiv_mul_assoc,
one := group_equiv_one,
one_mul := group_equiv_one_mul,
mul_one := group_equiv_mul_one,
inv := group_equiv_inv,
mul_left_inv := group_equiv_mul_left_inv,
is_set_carrier := is_trunc_equiv_closed 0 f⦄
end
variable (G)
/- the trivial group -/
open unit
definition trivial_group [constructor] : group unit :=
group.mk _ (λx y, star) (λx y z, idp) star (unit.rec idp) (unit.rec idp) (λx, star) (λx, idp)
definition Trivial_group [constructor] : Group :=
Group.mk _ trivial_group
abbreviation G0 := Trivial_group
definition trivial_group_of_is_contr [H : is_contr G] : G ≃g G0 :=
begin
fapply isomorphism_of_equiv,
{ apply equiv_unit_of_is_contr},
{ intros, reflexivity}
end
variable {G}
/-
A group where the point in the pointed type corresponds with 1 in the group.
We need this structure when we are given a pointed type, and want to say that there is a group
structure on it which is compatible with the point. This is used in chain complexes.
-/
structure pgroup [class] (X : Type*) extends semigroup X, has_inv X :=
(pt_mul : Πa, mul pt a = a)
(mul_pt : Πa, mul a pt = a)
(mul_left_inv_pt : Πa, mul (inv a) a = pt)
definition group_of_pgroup [reducible] [instance] (X : Type*) [H : pgroup X]
: group X :=
⦃group, H,
one := pt,
one_mul := pgroup.pt_mul ,
mul_one := pgroup.mul_pt,
mul_left_inv := pgroup.mul_left_inv_pt⦄
definition pgroup_of_group (X : Type*) [H : group X] (p : one = pt :> X) : pgroup X :=
begin
cases X with X x, esimp at *, induction p,
exact ⦃pgroup, H,
pt_mul := one_mul,
mul_pt := mul_one,
mul_left_inv_pt := mul.left_inv⦄
end
definition Group_of_pgroup (G : Type*) [pgroup G] : Group :=
Group.mk G _
definition pgroup_Group [instance] (G : Group) : pgroup G :=
⦃ pgroup, Group.struct G,
pt_mul := one_mul,
mul_pt := mul_one,
mul_left_inv_pt := mul.left_inv ⦄
-- infinity pgroups
structure inf_pgroup [class] (X : Type*) extends inf_semigroup X, has_inv X :=
(pt_mul : Πa, mul pt a = a)
(mul_pt : Πa, mul a pt = a)
(mul_left_inv_pt : Πa, mul (inv a) a = pt)
definition inf_group_of_inf_pgroup [reducible] [instance] (X : Type*) [H : inf_pgroup X]
: inf_group X :=
⦃inf_group, H,
one := pt,
one_mul := inf_pgroup.pt_mul ,
mul_one := inf_pgroup.mul_pt,
mul_left_inv := inf_pgroup.mul_left_inv_pt⦄
definition inf_pgroup_of_inf_group (X : Type*) [H : inf_group X] (p : one = pt :> X) : inf_pgroup X :=
begin
cases X with X x, esimp at *, induction p,
exact ⦃inf_pgroup, H,
pt_mul := one_mul,
mul_pt := mul_one,
mul_left_inv_pt := mul.left_inv⦄
end
definition inf_Group_of_inf_pgroup (G : Type*) [inf_pgroup G] : InfGroup :=
InfGroup.mk G _
definition inf_pgroup_InfGroup [instance] (G : InfGroup) : inf_pgroup G :=
⦃ inf_pgroup, InfGroup.struct G,
pt_mul := one_mul,
mul_pt := mul_one,
mul_left_inv_pt := mul.left_inv ⦄
/- equality of groups and abelian groups -/
definition group.to_has_mul {A : Type} (H : group A) : has_mul A := _
definition group.to_has_inv {A : Type} (H : group A) : has_inv A := _
definition group.to_has_one {A : Type} (H : group A) : has_one A := _
local attribute group.to_has_mul group.to_has_inv [coercion]
universe variable l
variables {A B : Type.{l}}
definition group_eq {G H : group A} (same_mul' : Π(g h : A), @mul A G g h = @mul A H g h)
: G = H :=
begin
have foo : Π(g : A), @inv A G g = (@inv A G g * g) * @inv A H g,
from λg, !mul_inv_cancel_right⁻¹,
cases G with Gs Gm Gh1 G1 Gh2 Gh3 Gi Gh4,
cases H with Hs Hm Hh1 H1 Hh2 Hh3 Hi Hh4,
have same_mul : Gm = Hm, from eq_of_homotopy2 same_mul',
cases same_mul,
have same_one : G1 = H1, from calc
G1 = Hm G1 H1 : Hh3
... = H1 : Gh2,
have same_inv : Gi = Hi, from eq_of_homotopy (take g, calc
Gi g = Hm (Hm (Gi g) g) (Hi g) : foo
... = Hm G1 (Hi g) : by rewrite Gh4
... = Hi g : Gh2),
cases same_one, cases same_inv,
have ps : Gs = Hs, from !is_prop.elim,
have ph1 : Gh1 = Hh1, from !is_prop.elim,
have ph2 : Gh2 = Hh2, from !is_prop.elim,
have ph3 : Gh3 = Hh3, from !is_prop.elim,
have ph4 : Gh4 = Hh4, from !is_prop.elim,
cases ps, cases ph1, cases ph2, cases ph3, cases ph4, reflexivity
end
definition group_pathover {G : group A} {H : group B} {p : A = B}
(resp_mul : Π(g h : A), cast p (g * h) = cast p g * cast p h) : G =[p] H :=
begin
induction p,
apply pathover_idp_of_eq, exact group_eq (resp_mul)
end
definition Group_eq_of_eq {G H : Group} (p : Group.carrier G = Group.carrier H)
(resp_mul : Π(g h : G), cast p (g * h) = cast p g * cast p h) : G = H :=
begin
cases G with Gc G, cases H with Hc H,
apply (apd011 Group.mk p),
exact group_pathover resp_mul
end
definition Group_eq {G H : Group} (f : Group.carrier G ≃ Group.carrier H)
(resp_mul : Π(g h : G), f (g * h) = f g * f h) : G = H :=
Group_eq_of_eq (ua f) (λg h, !cast_ua ⬝ resp_mul g h ⬝ ap011 mul !cast_ua⁻¹ !cast_ua⁻¹)
definition eq_of_isomorphism {G₁ G₂ : Group} (φ : G₁ ≃g G₂) : G₁ = G₂ :=
Group_eq (equiv_of_isomorphism φ) (respect_mul φ)
definition ab_group.to_has_mul {A : Type} (H : ab_group A) : has_mul A := _
local attribute ab_group.to_has_mul [coercion]
definition ab_group_eq {A : Type} {G H : ab_group A}
(same_mul : Π(g h : A), @mul A G g h = @mul A H g h)
: G = H :=
begin
have g_eq : @ab_group.to_group A G = @ab_group.to_group A H, from group_eq same_mul,
cases G with Gs Gm Gh1 G1 Gh2 Gh3 Gi Gh4 Gh5,
cases H with Hs Hm Hh1 H1 Hh2 Hh3 Hi Hh4 Hh5,
have pm : Gm = Hm, from ap (@mul _ ∘ group.to_has_mul) g_eq,
have pi : Gi = Hi, from ap (@inv _ ∘ group.to_has_inv) g_eq,
have p1 : G1 = H1, from ap (@one _ ∘ group.to_has_one) g_eq,
induction pm, induction pi, induction p1,
have ps : Gs = Hs, from !is_prop.elim,
have ph1 : Gh1 = Hh1, from !is_prop.elim,
have ph2 : Gh2 = Hh2, from !is_prop.elim,
have ph3 : Gh3 = Hh3, from !is_prop.elim,
have ph4 : Gh4 = Hh4, from !is_prop.elim,
have ph5 : Gh5 = Hh5, from !is_prop.elim,
induction ps, induction ph1, induction ph2, induction ph3, induction ph4, induction ph5,
reflexivity
end
definition ab_group_pathover {A B : Type} {G : ab_group A} {H : ab_group B} {p : A = B}
(resp_mul : Π(g h : A), cast p (g * h) = cast p g * cast p h) : G =[p] H :=
begin
induction p,
apply pathover_idp_of_eq, exact ab_group_eq (resp_mul)
end
definition AbGroup_eq_of_isomorphism {G₁ G₂ : AbGroup} (φ : G₁ ≃g G₂) : G₁ = G₂ :=
begin
induction G₁, induction G₂,
apply apd011 AbGroup.mk (ua (equiv_of_isomorphism φ)),
apply ab_group_pathover,
intro g h, exact !cast_ua ⬝ respect_mul φ g h ⬝ ap011 mul !cast_ua⁻¹ !cast_ua⁻¹
end
definition trivial_group_of_is_contr' (G : Group) [H : is_contr G] : G = G0 :=
eq_of_isomorphism (trivial_group_of_is_contr G)
end group

View file

@ -1,162 +0,0 @@
/-
Copyright (c) 2016 Jeremy Avigad. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Jeremy Avigad
Homomorphisms between structures.
-/
import algebra.ring algebra.category.category
open eq function is_trunc
namespace algebra
/- additive structures -/
variables {A B C : Type}
definition is_add_hom [class] [has_add A] [has_add B] (f : A → B) : Type :=
∀ a₁ a₂, f (a₁ + a₂) = f a₁ + f a₂
definition respect_add [has_add A] [has_add B] (f : A → B) [H : is_add_hom f] (a₁ a₂ : A) :
f (a₁ + a₂) = f a₁ + f a₂ := H a₁ a₂
definition is_prop_is_add_hom [instance] [has_add A] [has_add B] [is_set B] (f : A → B) :
is_prop (is_add_hom f) :=
by unfold is_add_hom; apply _
definition is_add_hom_id (A : Type) [has_add A] : is_add_hom (@id A) :=
take a₁ a₂, rfl
definition is_add_hom_compose [has_add A] [has_add B] [has_add C]
(f : B → C) (g : A → B) [is_add_hom f] [is_add_hom g] : is_add_hom (f ∘ g) :=
take a₁ a₂, begin esimp, rewrite [respect_add g, respect_add f] end
section add_group_A_B
variables [add_group A] [add_group B]
definition respect_zero (f : A → B) [is_add_hom f] :
f (0 : A) = 0 :=
have f 0 + f 0 = f 0 + 0, by rewrite [-respect_add f, +add_zero],
eq_of_add_eq_add_left this
definition respect_neg (f : A → B) [is_add_hom f] (a : A) :
f (- a) = - f a :=
have f (- a) + f a = 0, by rewrite [-respect_add f, add.left_inv, respect_zero f],
eq_neg_of_add_eq_zero this
definition respect_sub (f : A → B) [is_add_hom f] (a₁ a₂ : A) :
f (a₁ - a₂) = f a₁ - f a₂ :=
by rewrite [*sub_eq_add_neg, *(respect_add f), (respect_neg f)]
definition is_embedding_of_is_add_hom [add_group B] (f : A → B) [is_add_hom f]
(H : ∀ x, f x = 0 → x = 0) :
is_embedding f :=
is_embedding_of_is_injective
(take x₁ x₂,
suppose f x₁ = f x₂,
have f (x₁ - x₂) = 0, by rewrite [respect_sub f, this, sub_self],
have x₁ - x₂ = 0, from H _ this,
eq_of_sub_eq_zero this)
definition eq_zero_of_is_add_hom [add_group B] {f : A → B} [is_add_hom f]
[is_embedding f] {a : A} (fa0 : f a = 0) :
a = 0 :=
have f a = f 0, by rewrite [fa0, respect_zero f],
show a = 0, from is_injective_of_is_embedding this
end add_group_A_B
/- multiplicative structures -/
definition is_mul_hom [class] [has_mul A] [has_mul B] (f : A → B) : Type :=
∀ a₁ a₂, f (a₁ * a₂) = f a₁ * f a₂
definition respect_mul [has_mul A] [has_mul B] (f : A → B) [H : is_mul_hom f] (a₁ a₂ : A) :
f (a₁ * a₂) = f a₁ * f a₂ := H a₁ a₂
definition is_prop_is_mul_hom [instance] [has_mul A] [has_mul B] [is_set B] (f : A → B) :
is_prop (is_mul_hom f) :=
begin unfold is_mul_hom, apply _ end
definition is_mul_hom_id (A : Type) [has_mul A] : is_mul_hom (@id A) :=
take a₁ a₂, rfl
definition is_mul_hom_compose [has_mul A] [has_mul B] [has_mul C]
(f : B → C) (g : A → B) [is_mul_hom f] [is_mul_hom g] : is_mul_hom (f ∘ g) :=
take a₁ a₂, begin esimp, rewrite [respect_mul g, respect_mul f] end
section group_A_B
variables [group A] [group B]
definition respect_one (f : A → B) [is_mul_hom f] :
f (1 : A) = 1 :=
have f 1 * f 1 = f 1 * 1, by rewrite [-respect_mul f, *mul_one],
eq_of_mul_eq_mul_left' this
definition respect_inv (f : A → B) [is_mul_hom f] (a : A) :
f (a⁻¹) = (f a)⁻¹ :=
have f (a⁻¹) * f a = 1, by rewrite [-respect_mul f, mul.left_inv, respect_one f],
eq_inv_of_mul_eq_one this
definition is_embedding_of_is_mul_hom [group B] (f : A → B) [is_mul_hom f]
(H : ∀ x, f x = 1 → x = 1) :
is_embedding f :=
is_embedding_of_is_injective
(take x₁ x₂,
suppose f x₁ = f x₂,
have f (x₁ * x₂⁻¹) = 1, by rewrite [respect_mul f, respect_inv f, this, mul.right_inv],
have x₁ * x₂⁻¹ = 1, from H _ this,
eq_of_mul_inv_eq_one this)
definition eq_one_of_is_mul_hom [add_group B] {f : A → B} [is_mul_hom f]
[is_embedding f] {a : A} (fa1 : f a = 1) :
a = 1 :=
have f a = f 1, by rewrite [fa1, respect_one f],
show a = 1, from is_injective_of_is_embedding this
end group_A_B
/- rings -/
definition is_ring_hom [class] {R₁ R₂ : Type} [semiring R₁] [semiring R₂] (f : R₁ → R₂) :=
is_add_hom f × is_mul_hom f × f 1 = 1
definition is_ring_hom.mk {R₁ R₂ : Type} [semiring R₁] [semiring R₂] (f : R₁ → R₂)
(h₁ : is_add_hom f) (h₂ : is_mul_hom f) (h₃ : f 1 = 1) : is_ring_hom f :=
pair h₁ (pair h₂ h₃)
definition is_add_hom_of_is_ring_hom [instance] {R₁ R₂ : Type} [semiring R₁] [semiring R₂]
(f : R₁ → R₂) [H : is_ring_hom f] : is_add_hom f :=
prod.pr1 H
definition is_mul_hom_of_is_ring_hom [instance] {R₁ R₂ : Type} [semiring R₁] [semiring R₂]
(f : R₁ → R₂) [H : is_ring_hom f] : is_mul_hom f :=
prod.pr1 (prod.pr2 H)
definition is_ring_hom.respect_one {R₁ R₂ : Type} [semiring R₁] [semiring R₂]
(f : R₁ → R₂) [H : is_ring_hom f] : f 1 = 1 :=
prod.pr2 (prod.pr2 H)
definition is_prop_is_ring_hom [instance] {R₁ R₂ : Type} [semiring R₁] [semiring R₂] (f : R₁ → R₂) :
is_prop (is_ring_hom f) :=
have h₁ : is_prop (is_add_hom f), from _,
have h₂ : is_prop (is_mul_hom f), from _,
have h₃ : is_prop (f 1 = 1), from _,
begin unfold is_ring_hom, apply _ end
section semiring
variables {R₁ R₂ R₃ : Type} [semiring R₁] [semiring R₂] [semiring R₃]
variables (g : R₂ → R₃) (f : R₁ → R₂) [is_ring_hom g] [is_ring_hom f]
definition is_ring_hom_id : is_ring_hom (@id R₁) :=
is_ring_hom.mk id (λ a₁ a₂, rfl) (λ a₁ a₂, rfl) rfl
definition is_ring_hom_comp : is_ring_hom (g ∘ f) :=
is_ring_hom.mk _
(take a₁ a₂, begin esimp, rewrite [respect_add f, respect_add g] end)
(take r a, by esimp; rewrite [respect_mul f, respect_mul g])
(by esimp; rewrite *is_ring_hom.respect_one)
definition respect_mul_add_mul (a b c d : R₁) : f (a * b + c * d) = f a * f b + f c * f d :=
by rewrite [respect_add f, +(respect_mul f)]
end semiring
end algebra

View file

@ -1,271 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
homotopy groups of a pointed space
-/
import .trunc_group types.trunc .group_theory types.nat.hott
open nat eq pointed trunc is_trunc algebra group function equiv unit is_equiv nat
-- TODO: consistently make n an argument before A
-- TODO: rename cghomotopy_group to aghomotopy_group
-- TODO: rename homotopy_group_functor_compose to homotopy_group_functor_pcompose
namespace eq
definition inf_pgroup_loop [constructor] [instance] (A : Type*) : inf_pgroup (Ω A) :=
inf_pgroup.mk concat con.assoc inverse idp_con con_idp con.left_inv
definition inf_group_loop [constructor] (A : Type*) : inf_group (Ω A) := _
definition ab_inf_group_loop [constructor] [instance] (A : Type*) : ab_inf_group (Ω (Ω A)) :=
⦃ab_inf_group, inf_group_loop _, mul_comm := eckmann_hilton⦄
definition gloop [constructor] (A : Type*) : InfGroup :=
InfGroup.mk (Ω A) (inf_group_loop A)
definition homotopy_group [reducible] [constructor] (n : ) (A : Type*) : Set* :=
ptrunc 0 (Ω[n] A)
notation `π[`:95 n:0 `]`:0 := homotopy_group n
definition group_homotopy_group [instance] [constructor] [reducible] (n : ) (A : Type*)
: group (π[succ n] A) :=
trunc_group (Ω[succ n] A)
definition group_homotopy_group2 [instance] (k : ) (A : Type*) :
group (carrier (ptrunctype.to_pType (π[k + 1] A))) :=
group_homotopy_group k A
definition ab_group_homotopy_group [constructor] [reducible] (n : ) (A : Type*)
: ab_group (π[succ (succ n)] A) :=
trunc_ab_group (Ω[succ (succ n)] A)
local attribute ab_group_homotopy_group [instance]
definition ghomotopy_group [constructor] : Π(n : ) [is_succ n] (A : Type*), Group
| (succ n) x A := Group.mk (π[succ n] A) _
definition cghomotopy_group [constructor] :
Π(n : ) [is_at_least_two n] (A : Type*), AbGroup
| (succ (succ n)) x A := AbGroup.mk (π[succ (succ n)] A) _
definition fundamental_group [constructor] (A : Type*) : Group :=
ghomotopy_group 1 A
notation `πg[`:95 n:0 `]`:0 := ghomotopy_group n
notation `πag[`:95 n:0 `]`:0 := cghomotopy_group n
notation `π₁` := fundamental_group -- should this be notation for the group or pointed type?
definition tr_mul_tr {n : } {A : Type*} (p q : Ω[n + 1] A) :
tr p *[πg[n+1] A] tr q = tr (p ⬝ q) :=
by reflexivity
definition tr_mul_tr' {n : } {A : Type*} (p q : Ω[succ n] A)
: tr p *[π[succ n] A] tr q = tr (p ⬝ q) :=
idp
definition homotopy_group_pequiv [constructor] (n : ) {A B : Type*} (H : A ≃* B)
: π[n] A ≃* π[n] B :=
ptrunc_pequiv_ptrunc 0 (loopn_pequiv_loopn n H)
definition homotopy_group_pequiv_loop_ptrunc [constructor] (k : ) (A : Type*) :
π[k] A ≃* Ω[k] (ptrunc k A) :=
begin
refine !loopn_ptrunc_pequiv⁻¹ᵉ* ⬝e* _,
exact loopn_pequiv_loopn k (pequiv_of_eq begin rewrite [trunc_index.zero_add] end)
end
open trunc_index
definition homotopy_group_ptrunc_of_le [constructor] {k n : } (H : k ≤ n) (A : Type*) :
π[k] (ptrunc n A) ≃* π[k] A :=
calc
π[k] (ptrunc n A) ≃* Ω[k] (ptrunc k (ptrunc n A))
: homotopy_group_pequiv_loop_ptrunc k (ptrunc n A)
... ≃* Ω[k] (ptrunc k A)
: loopn_pequiv_loopn k (ptrunc_ptrunc_pequiv_left A (of_nat_le_of_nat H))
... ≃* π[k] A : (homotopy_group_pequiv_loop_ptrunc k A)⁻¹ᵉ*
definition homotopy_group_ptrunc [constructor] (k : ) (A : Type*) :
π[k] (ptrunc k A) ≃* π[k] A :=
homotopy_group_ptrunc_of_le (le.refl k) A
theorem trivial_homotopy_of_is_set (A : Type*) [H : is_set A] (n : ) : πg[n+1] A ≃g G0 :=
begin
apply trivial_group_of_is_contr,
apply is_trunc_trunc_of_is_trunc,
apply is_contr_loop_of_is_trunc,
apply is_trunc_succ_succ_of_is_set
end
definition homotopy_group_succ_out (A : Type*) (n : ) : π[n + 1] A = π₁ (Ω[n] A) := idp
definition homotopy_group_succ_in (A : Type*) (n : ) : π[n + 1] A ≃* π[n] (Ω A) :=
ptrunc_pequiv_ptrunc 0 (loopn_succ_in A n)
definition ghomotopy_group_succ_out (A : Type*) (n : ) : πg[n + 1] A = π₁ (Ω[n] A) := idp
definition homotopy_group_succ_in_con {A : Type*} {n : } (g h : πg[n + 2] A) :
homotopy_group_succ_in A (succ n) (g * h) =
homotopy_group_succ_in A (succ n) g * homotopy_group_succ_in A (succ n) h :=
begin
induction g with p, induction h with q, esimp,
apply ap tr, apply loopn_succ_in_con
end
definition ghomotopy_group_succ_in [constructor] (A : Type*) (n : ) :
πg[n + 2] A ≃g πg[n + 1] (Ω A) :=
begin
fapply isomorphism_of_equiv,
{ exact homotopy_group_succ_in A (succ n)},
{ exact homotopy_group_succ_in_con},
end
definition homotopy_group_functor [constructor] (n : ) {A B : Type*} (f : A →* B)
: π[n] A →* π[n] B :=
ptrunc_functor 0 (apn n f)
notation `π→[`:95 n:0 `]`:0 := homotopy_group_functor n
definition homotopy_group_functor_phomotopy [constructor] (n : ) {A B : Type*} {f g : A →* B}
(p : f ~* g) : π→[n] f ~* π→[n] g :=
ptrunc_functor_phomotopy 0 (apn_phomotopy n p)
definition homotopy_group_functor_pid (n : ) (A : Type*) : π→[n] (pid A) ~* pid (π[n] A) :=
ptrunc_functor_phomotopy 0 !apn_pid ⬝* !ptrunc_functor_pid
definition homotopy_group_functor_compose [constructor] (n : ) {A B C : Type*} (g : B →* C)
(f : A →* B) : π→[n] (g ∘* f) ~* π→[n] g ∘* π→[n] f :=
ptrunc_functor_phomotopy 0 !apn_pcompose ⬝* !ptrunc_functor_pcompose
definition is_equiv_homotopy_group_functor [constructor] (n : ) {A B : Type*} (f : A →* B)
[is_equiv f] : is_equiv (π→[n] f) :=
@(is_equiv_trunc_functor 0 _) !is_equiv_apn
definition homotopy_group_functor_succ_phomotopy_in (n : ) {A B : Type*} (f : A →* B) :
homotopy_group_succ_in B n ∘* π→[n + 1] f ~*
π→[n] (Ω→ f) ∘* homotopy_group_succ_in A n :=
begin
refine !ptrunc_functor_pcompose⁻¹* ⬝* _ ⬝* !ptrunc_functor_pcompose,
exact ptrunc_functor_phomotopy 0 (apn_succ_phomotopy_in n f)
end
definition is_equiv_homotopy_group_functor_ap1 (n : ) {A B : Type*} (f : A →* B)
[is_equiv (π→[n + 1] f)] : is_equiv (π→[n] (Ω→ f)) :=
have is_equiv (homotopy_group_succ_in B n ∘* π→[n + 1] f),
from is_equiv_compose _ (π→[n + 1] f),
have is_equiv (π→[n] (Ω→ f) ∘ homotopy_group_succ_in A n),
from is_equiv.homotopy_closed _ (homotopy_group_functor_succ_phomotopy_in n f),
is_equiv.cancel_right (homotopy_group_succ_in A n) _
definition tinverse [constructor] {X : Type*} : π[1] X →* π[1] X :=
ptrunc_functor 0 pinverse
definition is_equiv_tinverse [constructor] (A : Type*) : is_equiv (@tinverse A) :=
by apply @is_equiv_trunc_functor; apply is_equiv_eq_inverse
definition ptrunc_functor_pinverse [constructor] {X : Type*}
: ptrunc_functor 0 (@pinverse X) ~* @tinverse X :=
begin
fapply phomotopy.mk,
{ reflexivity},
{ reflexivity}
end
definition homotopy_group_functor_mul [constructor] (n : ) {A B : Type*} (g : A →* B)
(p q : πg[n+1] A) :
(π→[n + 1] g) (p *[πg[n+1] A] q) = (π→[n+1] g) p *[πg[n+1] B] (π→[n + 1] g) q :=
begin
unfold [ghomotopy_group, homotopy_group] at *,
refine @trunc.rec _ _ _ (λq, !is_trunc_eq) _ p, clear p, intro p,
refine @trunc.rec _ _ _ (λq, !is_trunc_eq) _ q, clear q, intro q,
apply ap tr, apply apn_con
end
definition homotopy_group_homomorphism [constructor] (n : ) [H : is_succ n] {A B : Type*}
(f : A →* B) : πg[n] A →g πg[n] B :=
begin
induction H with n, fconstructor,
{ exact homotopy_group_functor (n+1) f},
{ apply homotopy_group_functor_mul}
end
notation `π→g[`:95 n:0 `]`:0 := homotopy_group_homomorphism n
definition homotopy_group_isomorphism_of_pequiv [constructor] (n : ) {A B : Type*} (f : A ≃* B)
: πg[n+1] A ≃g πg[n+1] B :=
begin
apply isomorphism.mk (homotopy_group_homomorphism (succ n) f),
esimp, apply is_equiv_trunc_functor, apply is_equiv_apn,
end
definition homotopy_group_add (A : Type*) (n m : ) :
πg[n+m+1] A ≃g πg[n+1] (Ω[m] A) :=
begin
revert A, induction m with m IH: intro A,
{ reflexivity},
{ esimp [loopn, nat.add], refine !ghomotopy_group_succ_in ⬝g _, refine !IH ⬝g _,
apply homotopy_group_isomorphism_of_pequiv,
exact !loopn_succ_in⁻¹ᵉ*}
end
theorem trivial_homotopy_add_of_is_set_loopn {A : Type*} {n : } (m : )
(H : is_set (Ω[n] A)) : πg[m+n+1] A ≃g G0 :=
!homotopy_group_add ⬝g !trivial_homotopy_of_is_set
theorem trivial_homotopy_le_of_is_set_loopn {A : Type*} {n : } (m : ) (H1 : n ≤ m)
(H2 : is_set (Ω[n] A)) : πg[m+1] A ≃g G0 :=
obtain (k : ) (p : n + k = m), from le.elim H1,
isomorphism_of_eq (ap (λx, πg[x+1] A) (p⁻¹ ⬝ add.comm n k)) ⬝g
trivial_homotopy_add_of_is_set_loopn k H2
definition homotopy_group_pequiv_loop_ptrunc_con {k : } {A : Type*} (p q : πg[k +1] A) :
homotopy_group_pequiv_loop_ptrunc (succ k) A (p * q) =
homotopy_group_pequiv_loop_ptrunc (succ k) A p ⬝
homotopy_group_pequiv_loop_ptrunc (succ k) A q :=
begin
refine _ ⬝ !loopn_pequiv_loopn_con,
exact ap (loopn_pequiv_loopn _ _) !loopn_ptrunc_pequiv_inv_con
end
definition homotopy_group_pequiv_loop_ptrunc_inv_con {k : } {A : Type*}
(p q : Ω[succ k] (ptrunc (succ k) A)) :
(homotopy_group_pequiv_loop_ptrunc (succ k) A)⁻¹ᵉ* (p ⬝ q) =
(homotopy_group_pequiv_loop_ptrunc (succ k) A)⁻¹ᵉ* p *
(homotopy_group_pequiv_loop_ptrunc (succ k) A)⁻¹ᵉ* q :=
inv_preserve_binary (homotopy_group_pequiv_loop_ptrunc (succ k) A) mul concat
(@homotopy_group_pequiv_loop_ptrunc_con k A) p q
definition ghomotopy_group_ptrunc [constructor] (k : ) (A : Type*) :
πg[k+1] (ptrunc (k+1) A) ≃g πg[k+1] A :=
begin
fapply isomorphism_of_equiv,
{ exact homotopy_group_ptrunc (k+1) A},
{ intro g₁ g₂,
refine _ ⬝ !homotopy_group_pequiv_loop_ptrunc_inv_con,
apply ap ((homotopy_group_pequiv_loop_ptrunc (k+1) A)⁻¹ᵉ*),
refine _ ⬝ !loopn_pequiv_loopn_con ,
apply ap (loopn_pequiv_loopn (k+1) _),
apply homotopy_group_pequiv_loop_ptrunc_con}
end
/- some homomorphisms -/
-- definition is_homomorphism_cast_loopn_succ_eq_in {A : Type*} (n : ) :
-- is_homomorphism (loopn_succ_in A (succ n) : πg[n+1+1] A → πg[n+1] (Ω A)) :=
-- begin
-- intro g h, induction g with g, induction h with h,
-- xrewrite [tr_mul_tr, - + fn_cast_eq_cast_fn _ (λn, tr), tr_mul_tr, ↑cast, -tr_compose,
-- loopn_succ_eq_in_concat, - + tr_compose],
-- end
definition is_mul_hom_inverse (A : Type*) (n : )
: is_mul_hom (λp, p⁻¹ : (πag[n+2] A) → (πag[n+2] A)) :=
begin
intro g h, exact ap inv (mul.comm g h) ⬝ mul_inv h g,
end
end eq

View file

@ -1,722 +0,0 @@
/-
Copyright (c) 2014 Jeremy Avigad. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Jeremy Avigad, Leonardo de Moura
-/
import algebra.binary algebra.priority
open eq eq.ops -- note: ⁻¹ will be overloaded
open binary algebra is_trunc
set_option class.force_new true
variable {A : Type}
/- inf_semigroup -/
namespace algebra
structure inf_semigroup [class] (A : Type) extends has_mul A :=
(mul_assoc : Πa b c, mul (mul a b) c = mul a (mul b c))
definition mul.assoc [s : inf_semigroup A] (a b c : A) : a * b * c = a * (b * c) :=
!inf_semigroup.mul_assoc
structure comm_inf_semigroup [class] (A : Type) extends inf_semigroup A :=
(mul_comm : Πa b, mul a b = mul b a)
definition mul.comm [s : comm_inf_semigroup A] (a b : A) : a * b = b * a :=
!comm_inf_semigroup.mul_comm
theorem mul.left_comm [s : comm_inf_semigroup A] (a b c : A) : a * (b * c) = b * (a * c) :=
binary.left_comm (@mul.comm A _) (@mul.assoc A _) a b c
theorem mul.right_comm [s : comm_inf_semigroup A] (a b c : A) : (a * b) * c = (a * c) * b :=
binary.right_comm (@mul.comm A _) (@mul.assoc A _) a b c
structure left_cancel_inf_semigroup [class] (A : Type) extends inf_semigroup A :=
(mul_left_cancel : Πa b c, mul a b = mul a c → b = c)
theorem mul.left_cancel [s : left_cancel_inf_semigroup A] {a b c : A} :
a * b = a * c → b = c :=
!left_cancel_inf_semigroup.mul_left_cancel
abbreviation eq_of_mul_eq_mul_left' := @mul.left_cancel
structure right_cancel_inf_semigroup [class] (A : Type) extends inf_semigroup A :=
(mul_right_cancel : Πa b c, mul a b = mul c b → a = c)
definition mul.right_cancel [s : right_cancel_inf_semigroup A] {a b c : A} :
a * b = c * b → a = c :=
!right_cancel_inf_semigroup.mul_right_cancel
abbreviation eq_of_mul_eq_mul_right' := @mul.right_cancel
/- additive inf_semigroup -/
definition add_inf_semigroup [class] : Type → Type := inf_semigroup
definition has_add_of_add_inf_semigroup [reducible] [trans_instance] (A : Type) [H : add_inf_semigroup A] :
has_add A :=
has_add.mk (@inf_semigroup.mul A H)
definition add.assoc [s : add_inf_semigroup A] (a b c : A) : a + b + c = a + (b + c) :=
@mul.assoc A s a b c
definition add_comm_inf_semigroup [class] : Type → Type := comm_inf_semigroup
definition add_inf_semigroup_of_add_comm_inf_semigroup [reducible] [trans_instance] (A : Type)
[H : add_comm_inf_semigroup A] : add_inf_semigroup A :=
@comm_inf_semigroup.to_inf_semigroup A H
definition add.comm [s : add_comm_inf_semigroup A] (a b : A) : a + b = b + a :=
@mul.comm A s a b
theorem add.left_comm [s : add_comm_inf_semigroup A] (a b c : A) :
a + (b + c) = b + (a + c) :=
binary.left_comm (@add.comm A _) (@add.assoc A _) a b c
theorem add.right_comm [s : add_comm_inf_semigroup A] (a b c : A) : (a + b) + c = (a + c) + b :=
binary.right_comm (@add.comm A _) (@add.assoc A _) a b c
definition add_left_cancel_inf_semigroup [class] : Type → Type := left_cancel_inf_semigroup
definition add_inf_semigroup_of_add_left_cancel_inf_semigroup [reducible] [trans_instance] (A : Type)
[H : add_left_cancel_inf_semigroup A] : add_inf_semigroup A :=
@left_cancel_inf_semigroup.to_inf_semigroup A H
definition add.left_cancel [s : add_left_cancel_inf_semigroup A] {a b c : A} :
a + b = a + c → b = c :=
@mul.left_cancel A s a b c
abbreviation eq_of_add_eq_add_left := @add.left_cancel
definition add_right_cancel_inf_semigroup [class] : Type → Type := right_cancel_inf_semigroup
definition add_inf_semigroup_of_add_right_cancel_inf_semigroup [reducible] [trans_instance] (A : Type)
[H : add_right_cancel_inf_semigroup A] : add_inf_semigroup A :=
@right_cancel_inf_semigroup.to_inf_semigroup A H
definition add.right_cancel [s : add_right_cancel_inf_semigroup A] {a b c : A} :
a + b = c + b → a = c :=
@mul.right_cancel A s a b c
abbreviation eq_of_add_eq_add_right := @add.right_cancel
/- inf_monoid -/
structure inf_monoid [class] (A : Type) extends inf_semigroup A, has_one A :=
(one_mul : Πa, mul one a = a) (mul_one : Πa, mul a one = a)
definition one_mul [s : inf_monoid A] (a : A) : 1 * a = a := !inf_monoid.one_mul
definition mul_one [s : inf_monoid A] (a : A) : a * 1 = a := !inf_monoid.mul_one
structure comm_inf_monoid [class] (A : Type) extends inf_monoid A, comm_inf_semigroup A
/- additive inf_monoid -/
definition add_inf_monoid [class] : Type → Type := inf_monoid
definition add_inf_semigroup_of_add_inf_monoid [reducible] [trans_instance] (A : Type)
[H : add_inf_monoid A] : add_inf_semigroup A :=
@inf_monoid.to_inf_semigroup A H
definition has_zero_of_add_inf_monoid [reducible] [trans_instance] (A : Type)
[H : add_inf_monoid A] : has_zero A :=
has_zero.mk (@inf_monoid.one A H)
definition zero_add [s : add_inf_monoid A] (a : A) : 0 + a = a := @inf_monoid.one_mul A s a
definition add_zero [s : add_inf_monoid A] (a : A) : a + 0 = a := @inf_monoid.mul_one A s a
definition add_comm_inf_monoid [class] : Type → Type := comm_inf_monoid
definition add_inf_monoid_of_add_comm_inf_monoid [reducible] [trans_instance] (A : Type)
[H : add_comm_inf_monoid A] : add_inf_monoid A :=
@comm_inf_monoid.to_inf_monoid A H
definition add_comm_inf_semigroup_of_add_comm_inf_monoid [reducible] [trans_instance] (A : Type)
[H : add_comm_inf_monoid A] : add_comm_inf_semigroup A :=
@comm_inf_monoid.to_comm_inf_semigroup A H
section add_comm_inf_monoid
variables [s : add_comm_inf_monoid A]
include s
theorem add_comm_three (a b c : A) : a + b + c = c + b + a :=
by rewrite [{a + _}add.comm, {_ + c}add.comm, -*add.assoc]
theorem add.comm4 : Π (n m k l : A), n + m + (k + l) = n + k + (m + l) :=
comm4 add.comm add.assoc
end add_comm_inf_monoid
/- group -/
structure inf_group [class] (A : Type) extends inf_monoid A, has_inv A :=
(mul_left_inv : Πa, mul (inv a) a = one)
-- Note: with more work, we could derive the axiom one_mul
section inf_group
variable [s : inf_group A]
include s
definition mul.left_inv (a : A) : a⁻¹ * a = 1 := !inf_group.mul_left_inv
theorem inv_mul_cancel_left (a b : A) : a⁻¹ * (a * b) = b :=
by rewrite [-mul.assoc, mul.left_inv, one_mul]
theorem inv_mul_cancel_right (a b : A) : a * b⁻¹ * b = a :=
by rewrite [mul.assoc, mul.left_inv, mul_one]
theorem inv_eq_of_mul_eq_one {a b : A} (H : a * b = 1) : a⁻¹ = b :=
by rewrite [-mul_one a⁻¹, -H, inv_mul_cancel_left]
theorem one_inv : 1⁻¹ = (1 : A) := inv_eq_of_mul_eq_one (one_mul 1)
theorem inv_inv (a : A) : (a⁻¹)⁻¹ = a := inv_eq_of_mul_eq_one (mul.left_inv a)
theorem inv.inj {a b : A} (H : a⁻¹ = b⁻¹) : a = b :=
by rewrite [-inv_inv a, H, inv_inv b]
theorem inv_eq_inv_iff_eq (a b : A) : a⁻¹ = b⁻¹ ↔ a = b :=
iff.intro (assume H, inv.inj H) (assume H, ap _ H)
theorem inv_eq_one_iff_eq_one (a : A) : a⁻¹ = 1 ↔ a = 1 :=
one_inv ▸ inv_eq_inv_iff_eq a 1
theorem inv_eq_one {a : A} (H : a = 1) : a⁻¹ = 1 :=
iff.mpr (inv_eq_one_iff_eq_one a) H
theorem eq_one_of_inv_eq_one (a : A) : a⁻¹ = 1 → a = 1 :=
iff.mp !inv_eq_one_iff_eq_one
theorem eq_inv_of_eq_inv {a b : A} (H : a = b⁻¹) : b = a⁻¹ :=
by rewrite [H, inv_inv]
theorem eq_inv_iff_eq_inv (a b : A) : a = b⁻¹ ↔ b = a⁻¹ :=
iff.intro !eq_inv_of_eq_inv !eq_inv_of_eq_inv
theorem eq_inv_of_mul_eq_one {a b : A} (H : a * b = 1) : a = b⁻¹ :=
begin apply eq_inv_of_eq_inv, symmetry, exact inv_eq_of_mul_eq_one H end
theorem mul.right_inv (a : A) : a * a⁻¹ = 1 :=
calc
a * a⁻¹ = (a⁻¹)⁻¹ * a⁻¹ : inv_inv
... = 1 : mul.left_inv
theorem mul_inv_cancel_left (a b : A) : a * (a⁻¹ * b) = b :=
calc
a * (a⁻¹ * b) = a * a⁻¹ * b : by rewrite mul.assoc
... = 1 * b : mul.right_inv
... = b : one_mul
theorem mul_inv_cancel_right (a b : A) : a * b * b⁻¹ = a :=
calc
a * b * b⁻¹ = a * (b * b⁻¹) : mul.assoc
... = a * 1 : mul.right_inv
... = a : mul_one
theorem mul_inv (a b : A) : (a * b)⁻¹ = b⁻¹ * a⁻¹ :=
inv_eq_of_mul_eq_one
(calc
a * b * (b⁻¹ * a⁻¹) = a * (b * (b⁻¹ * a⁻¹)) : mul.assoc
... = a * a⁻¹ : mul_inv_cancel_left
... = 1 : mul.right_inv)
theorem eq_of_mul_inv_eq_one {a b : A} (H : a * b⁻¹ = 1) : a = b :=
calc
a = a * b⁻¹ * b : by rewrite inv_mul_cancel_right
... = 1 * b : H
... = b : one_mul
theorem eq_mul_inv_of_mul_eq {a b c : A} (H : a * c = b) : a = b * c⁻¹ :=
by rewrite [-H, mul_inv_cancel_right]
theorem eq_inv_mul_of_mul_eq {a b c : A} (H : b * a = c) : a = b⁻¹ * c :=
by rewrite [-H, inv_mul_cancel_left]
theorem inv_mul_eq_of_eq_mul {a b c : A} (H : b = a * c) : a⁻¹ * b = c :=
by rewrite [H, inv_mul_cancel_left]
theorem mul_inv_eq_of_eq_mul {a b c : A} (H : a = c * b) : a * b⁻¹ = c :=
by rewrite [H, mul_inv_cancel_right]
theorem eq_mul_of_mul_inv_eq {a b c : A} (H : a * c⁻¹ = b) : a = b * c :=
!inv_inv ▸ (eq_mul_inv_of_mul_eq H)
theorem eq_mul_of_inv_mul_eq {a b c : A} (H : b⁻¹ * a = c) : a = b * c :=
!inv_inv ▸ (eq_inv_mul_of_mul_eq H)
theorem mul_eq_of_eq_inv_mul {a b c : A} (H : b = a⁻¹ * c) : a * b = c :=
!inv_inv ▸ (inv_mul_eq_of_eq_mul H)
theorem mul_eq_of_eq_mul_inv {a b c : A} (H : a = c * b⁻¹) : a * b = c :=
!inv_inv ▸ (mul_inv_eq_of_eq_mul H)
theorem mul_eq_iff_eq_inv_mul (a b c : A) : a * b = c ↔ b = a⁻¹ * c :=
iff.intro eq_inv_mul_of_mul_eq mul_eq_of_eq_inv_mul
theorem mul_eq_iff_eq_mul_inv (a b c : A) : a * b = c ↔ a = c * b⁻¹ :=
iff.intro eq_mul_inv_of_mul_eq mul_eq_of_eq_mul_inv
theorem mul_left_cancel {a b c : A} (H : a * b = a * c) : b = c :=
by rewrite [-inv_mul_cancel_left a b, H, inv_mul_cancel_left]
theorem mul_right_cancel {a b c : A} (H : a * b = c * b) : a = c :=
by rewrite [-mul_inv_cancel_right a b, H, mul_inv_cancel_right]
theorem mul_eq_one_of_mul_eq_one {a b : A} (H : b * a = 1) : a * b = 1 :=
by rewrite [-inv_eq_of_mul_eq_one H, mul.left_inv]
theorem mul_eq_one_iff_mul_eq_one (a b : A) : a * b = 1 ↔ b * a = 1 :=
iff.intro !mul_eq_one_of_mul_eq_one !mul_eq_one_of_mul_eq_one
definition conj_by (g a : A) := g * a * g⁻¹
definition is_conjugate (a b : A) := Σ x, conj_by x b = a
local infixl ` ~ ` := is_conjugate
local infixr ` ∘c `:55 := conj_by
lemma conj_compose (f g a : A) : f ∘c g ∘c a = f*g ∘c a :=
calc f ∘c g ∘c a = f * (g * a * g⁻¹) * f⁻¹ : rfl
... = f * (g * a) * g⁻¹ * f⁻¹ : mul.assoc
... = f * g * a * g⁻¹ * f⁻¹ : mul.assoc
... = f * g * a * (g⁻¹ * f⁻¹) : mul.assoc
... = f * g * a * (f * g)⁻¹ : mul_inv
lemma conj_id (a : A) : 1 ∘c a = a :=
calc 1 * a * 1⁻¹ = a * 1⁻¹ : one_mul
... = a * 1 : one_inv
... = a : mul_one
lemma conj_one (g : A) : g ∘c 1 = 1 :=
calc g * 1 * g⁻¹ = g * g⁻¹ : mul_one
... = 1 : mul.right_inv
lemma conj_inv_cancel (g : A) : Π a, g⁻¹ ∘c g ∘c a = a :=
assume a, calc
g⁻¹ ∘c g ∘c a = g⁻¹*g ∘c a : conj_compose
... = 1 ∘c a : mul.left_inv
... = a : conj_id
lemma conj_inv (g : A) : Π a, (g ∘c a)⁻¹ = g ∘c a⁻¹ :=
take a, calc
(g * a * g⁻¹)⁻¹ = g⁻¹⁻¹ * (g * a)⁻¹ : mul_inv
... = g⁻¹⁻¹ * (a⁻¹ * g⁻¹) : mul_inv
... = g⁻¹⁻¹ * a⁻¹ * g⁻¹ : mul.assoc
... = g * a⁻¹ * g⁻¹ : inv_inv
lemma is_conj.refl (a : A) : a ~ a := sigma.mk 1 (conj_id a)
lemma is_conj.symm (a b : A) : a ~ b → b ~ a :=
assume Pab, obtain x (Pconj : x ∘c b = a), from Pab,
have Pxinv : x⁻¹ ∘c x ∘c b = x⁻¹ ∘c a, begin congruence, assumption end,
sigma.mk x⁻¹ (inverse (conj_inv_cancel x b ▸ Pxinv))
lemma is_conj.trans (a b c : A) : a ~ b → b ~ c → a ~ c :=
assume Pab, assume Pbc,
obtain x (Px : x ∘c b = a), from Pab,
obtain y (Py : y ∘c c = b), from Pbc,
sigma.mk (x*y) (calc
x*y ∘c c = x ∘c y ∘c c : conj_compose
... = x ∘c b : Py
... = a : Px)
definition inf_group.to_left_cancel_inf_semigroup [trans_instance] : left_cancel_inf_semigroup A :=
⦃ left_cancel_inf_semigroup, s,
mul_left_cancel := @mul_left_cancel A s ⦄
definition inf_group.to_right_cancel_inf_semigroup [trans_instance] : right_cancel_inf_semigroup A :=
⦃ right_cancel_inf_semigroup, s,
mul_right_cancel := @mul_right_cancel A s ⦄
end inf_group
structure ab_inf_group [class] (A : Type) extends inf_group A, comm_inf_monoid A
/- additive inf_group -/
definition add_inf_group [class] : Type → Type := inf_group
definition add_inf_semigroup_of_add_inf_group [reducible] [trans_instance] (A : Type)
[H : add_inf_group A] : add_inf_monoid A :=
@inf_group.to_inf_monoid A H
definition has_neg_of_add_inf_group [reducible] [trans_instance] (A : Type)
[H : add_inf_group A] : has_neg A :=
has_neg.mk (@inf_group.inv A H)
section add_inf_group
variables [s : add_inf_group A]
include s
theorem add.left_inv (a : A) : -a + a = 0 := @inf_group.mul_left_inv A s a
theorem neg_add_cancel_left (a b : A) : -a + (a + b) = b :=
by rewrite [-add.assoc, add.left_inv, zero_add]
theorem neg_add_cancel_right (a b : A) : a + -b + b = a :=
by rewrite [add.assoc, add.left_inv, add_zero]
theorem neg_eq_of_add_eq_zero {a b : A} (H : a + b = 0) : -a = b :=
by rewrite [-add_zero (-a), -H, neg_add_cancel_left]
theorem neg_zero : -0 = (0 : A) := neg_eq_of_add_eq_zero (zero_add 0)
theorem neg_neg (a : A) : -(-a) = a := neg_eq_of_add_eq_zero (add.left_inv a)
theorem eq_neg_of_add_eq_zero {a b : A} (H : a + b = 0) : a = -b :=
by rewrite [-neg_eq_of_add_eq_zero H, neg_neg]
theorem neg.inj {a b : A} (H : -a = -b) : a = b :=
calc
a = -(-a) : neg_neg
... = b : neg_eq_of_add_eq_zero (H⁻¹ ▸ (add.left_inv _))
theorem neg_eq_neg_iff_eq (a b : A) : -a = -b ↔ a = b :=
iff.intro (assume H, neg.inj H) (assume H, ap _ H)
theorem eq_of_neg_eq_neg {a b : A} : -a = -b → a = b :=
iff.mp !neg_eq_neg_iff_eq
theorem neg_eq_zero_iff_eq_zero (a : A) : -a = 0 ↔ a = 0 :=
neg_zero ▸ !neg_eq_neg_iff_eq
theorem eq_zero_of_neg_eq_zero {a : A} : -a = 0 → a = 0 :=
iff.mp !neg_eq_zero_iff_eq_zero
theorem eq_neg_of_eq_neg {a b : A} (H : a = -b) : b = -a :=
H⁻¹ ▸ (neg_neg b)⁻¹
theorem eq_neg_iff_eq_neg (a b : A) : a = -b ↔ b = -a :=
iff.intro !eq_neg_of_eq_neg !eq_neg_of_eq_neg
theorem add.right_inv (a : A) : a + -a = 0 :=
calc
a + -a = -(-a) + -a : neg_neg
... = 0 : add.left_inv
theorem add_neg_cancel_left (a b : A) : a + (-a + b) = b :=
by rewrite [-add.assoc, add.right_inv, zero_add]
theorem add_neg_cancel_right (a b : A) : a + b + -b = a :=
by rewrite [add.assoc, add.right_inv, add_zero]
theorem neg_add_rev (a b : A) : -(a + b) = -b + -a :=
neg_eq_of_add_eq_zero
begin
rewrite [add.assoc, add_neg_cancel_left, add.right_inv]
end
-- TODO: delete these in favor of sub rules?
theorem eq_add_neg_of_add_eq {a b c : A} (H : a + c = b) : a = b + -c :=
H ▸ !add_neg_cancel_right⁻¹
theorem eq_neg_add_of_add_eq {a b c : A} (H : b + a = c) : a = -b + c :=
H ▸ !neg_add_cancel_left⁻¹
theorem neg_add_eq_of_eq_add {a b c : A} (H : b = a + c) : -a + b = c :=
H⁻¹ ▸ !neg_add_cancel_left
theorem add_neg_eq_of_eq_add {a b c : A} (H : a = c + b) : a + -b = c :=
H⁻¹ ▸ !add_neg_cancel_right
theorem eq_add_of_add_neg_eq {a b c : A} (H : a + -c = b) : a = b + c :=
!neg_neg ▸ (eq_add_neg_of_add_eq H)
theorem eq_add_of_neg_add_eq {a b c : A} (H : -b + a = c) : a = b + c :=
!neg_neg ▸ (eq_neg_add_of_add_eq H)
theorem add_eq_of_eq_neg_add {a b c : A} (H : b = -a + c) : a + b = c :=
!neg_neg ▸ (neg_add_eq_of_eq_add H)
theorem add_eq_of_eq_add_neg {a b c : A} (H : a = c + -b) : a + b = c :=
!neg_neg ▸ (add_neg_eq_of_eq_add H)
theorem add_eq_iff_eq_neg_add (a b c : A) : a + b = c ↔ b = -a + c :=
iff.intro eq_neg_add_of_add_eq add_eq_of_eq_neg_add
theorem add_eq_iff_eq_add_neg (a b c : A) : a + b = c ↔ a = c + -b :=
iff.intro eq_add_neg_of_add_eq add_eq_of_eq_add_neg
theorem add_left_cancel {a b c : A} (H : a + b = a + c) : b = c :=
calc b = -a + (a + b) : !neg_add_cancel_left⁻¹
... = -a + (a + c) : H
... = c : neg_add_cancel_left
theorem add_right_cancel {a b c : A} (H : a + b = c + b) : a = c :=
calc a = (a + b) + -b : !add_neg_cancel_right⁻¹
... = (c + b) + -b : H
... = c : add_neg_cancel_right
definition add_inf_group.to_add_left_cancel_inf_semigroup [reducible] [trans_instance] :
add_left_cancel_inf_semigroup A :=
@inf_group.to_left_cancel_inf_semigroup A s
definition add_inf_group.to_add_right_cancel_inf_semigroup [reducible] [trans_instance] :
add_right_cancel_inf_semigroup A :=
@inf_group.to_right_cancel_inf_semigroup A s
theorem add_neg_eq_neg_add_rev {a b : A} : a + -b = -(b + -a) :=
by rewrite [neg_add_rev, neg_neg]
/- sub -/
-- TODO: derive corresponding facts for div in a field
protected definition algebra.sub [reducible] (a b : A) : A := a + -b
definition add_inf_group_has_sub [instance] : has_sub A :=
has_sub.mk algebra.sub
theorem sub_eq_add_neg (a b : A) : a - b = a + -b := rfl
theorem sub_self (a : A) : a - a = 0 := !add.right_inv
theorem sub_add_cancel (a b : A) : a - b + b = a := !neg_add_cancel_right
theorem add_sub_cancel (a b : A) : a + b - b = a := !add_neg_cancel_right
theorem eq_of_sub_eq_zero {a b : A} (H : a - b = 0) : a = b :=
calc
a = (a - b) + b : !sub_add_cancel⁻¹
... = 0 + b : H
... = b : zero_add
theorem eq_iff_sub_eq_zero (a b : A) : a = b ↔ a - b = 0 :=
iff.intro (assume H, H ▸ !sub_self) (assume H, eq_of_sub_eq_zero H)
theorem zero_sub (a : A) : 0 - a = -a := !zero_add
theorem sub_zero (a : A) : a - 0 = a :=
by rewrite [sub_eq_add_neg, neg_zero, add_zero]
theorem sub_neg_eq_add (a b : A) : a - (-b) = a + b :=
by change a + -(-b) = a + b; rewrite neg_neg
theorem neg_sub (a b : A) : -(a - b) = b - a :=
neg_eq_of_add_eq_zero
(calc
a - b + (b - a) = a - b + b - a : by krewrite -add.assoc
... = a - a : sub_add_cancel
... = 0 : sub_self)
theorem add_sub (a b c : A) : a + (b - c) = a + b - c := !add.assoc⁻¹
theorem sub_add_eq_sub_sub_swap (a b c : A) : a - (b + c) = a - c - b :=
calc
a - (b + c) = a + (-c - b) : by rewrite [sub_eq_add_neg, neg_add_rev]
... = a - c - b : by krewrite -add.assoc
theorem sub_eq_iff_eq_add (a b c : A) : a - b = c ↔ a = c + b :=
iff.intro (assume H, eq_add_of_add_neg_eq H) (assume H, add_neg_eq_of_eq_add H)
theorem eq_sub_iff_add_eq (a b c : A) : a = b - c ↔ a + c = b :=
iff.intro (assume H, add_eq_of_eq_add_neg H) (assume H, eq_add_neg_of_add_eq H)
theorem eq_iff_eq_of_sub_eq_sub {a b c d : A} (H : a - b = c - d) : a = b ↔ c = d :=
calc
a = b ↔ a - b = 0 : eq_iff_sub_eq_zero
... = (c - d = 0) : H
... ↔ c = d : iff.symm (eq_iff_sub_eq_zero c d)
theorem eq_sub_of_add_eq {a b c : A} (H : a + c = b) : a = b - c :=
!eq_add_neg_of_add_eq H
theorem sub_eq_of_eq_add {a b c : A} (H : a = c + b) : a - b = c :=
!add_neg_eq_of_eq_add H
theorem eq_add_of_sub_eq {a b c : A} (H : a - c = b) : a = b + c :=
eq_add_of_add_neg_eq H
theorem add_eq_of_eq_sub {a b c : A} (H : a = c - b) : a + b = c :=
add_eq_of_eq_add_neg H
end add_inf_group
definition add_ab_inf_group [class] : Type → Type := ab_inf_group
definition add_inf_group_of_add_ab_inf_group [reducible] [trans_instance] (A : Type)
[H : add_ab_inf_group A] : add_inf_group A :=
@ab_inf_group.to_inf_group A H
definition add_comm_inf_monoid_of_add_ab_inf_group [reducible] [trans_instance] (A : Type)
[H : add_ab_inf_group A] : add_comm_inf_monoid A :=
@ab_inf_group.to_comm_inf_monoid A H
section add_ab_inf_group
variable [s : add_ab_inf_group A]
include s
theorem sub_add_eq_sub_sub (a b c : A) : a - (b + c) = a - b - c :=
!add.comm ▸ !sub_add_eq_sub_sub_swap
theorem neg_add_eq_sub (a b : A) : -a + b = b - a := !add.comm
theorem neg_add (a b : A) : -(a + b) = -a + -b := add.comm (-b) (-a) ▸ neg_add_rev a b
theorem sub_add_eq_add_sub (a b c : A) : a - b + c = a + c - b := !add.right_comm
theorem sub_sub (a b c : A) : a - b - c = a - (b + c) :=
by rewrite [▸ a + -b + -c = _, add.assoc, -neg_add]
theorem add_sub_add_left_eq_sub (a b c : A) : (c + a) - (c + b) = a - b :=
by rewrite [sub_add_eq_sub_sub, (add.comm c a), add_sub_cancel]
theorem eq_sub_of_add_eq' {a b c : A} (H : c + a = b) : a = b - c :=
!eq_sub_of_add_eq (!add.comm ▸ H)
theorem sub_eq_of_eq_add' {a b c : A} (H : a = b + c) : a - b = c :=
!sub_eq_of_eq_add (!add.comm ▸ H)
theorem eq_add_of_sub_eq' {a b c : A} (H : a - b = c) : a = b + c :=
!add.comm ▸ eq_add_of_sub_eq H
theorem add_eq_of_eq_sub' {a b c : A} (H : b = c - a) : a + b = c :=
!add.comm ▸ add_eq_of_eq_sub H
theorem sub_sub_self (a b : A) : a - (a - b) = b :=
by rewrite [sub_eq_add_neg, neg_sub, add.comm, sub_add_cancel]
theorem add_sub_comm (a b c d : A) : a + b - (c + d) = (a - c) + (b - d) :=
by rewrite [sub_add_eq_sub_sub, -sub_add_eq_add_sub a c b, add_sub]
theorem sub_eq_sub_add_sub (a b c : A) : a - b = c - b + (a - c) :=
by rewrite [add_sub, sub_add_cancel] ⬝ !add.comm
theorem neg_neg_sub_neg (a b : A) : - (-a - -b) = a - b :=
by rewrite [neg_sub, sub_neg_eq_add, neg_add_eq_sub]
end add_ab_inf_group
definition inf_group_of_add_inf_group (A : Type) [G : add_inf_group A] : inf_group A :=
⦃inf_group,
mul := has_add.add,
mul_assoc := add.assoc,
one := !has_zero.zero,
one_mul := zero_add,
mul_one := add_zero,
inv := has_neg.neg,
mul_left_inv := add.left_inv ⦄
namespace norm_num
definition add1 [s : has_add A] [s' : has_one A] (a : A) : A := add a one
theorem add_comm_four [s : add_comm_inf_semigroup A] (a b : A) : a + a + (b + b) = (a + b) + (a + b) :=
by rewrite [-add.assoc at {1}, add.comm, {a + b}add.comm at {1}, *add.assoc]
theorem add_comm_middle [s : add_comm_inf_semigroup A] (a b c : A) : a + b + c = a + c + b :=
by rewrite [add.assoc, add.comm b, -add.assoc]
theorem bit0_add_bit0 [s : add_comm_inf_semigroup A] (a b : A) : bit0 a + bit0 b = bit0 (a + b) :=
!add_comm_four
theorem bit0_add_bit0_helper [s : add_comm_inf_semigroup A] (a b t : A) (H : a + b = t) :
bit0 a + bit0 b = bit0 t :=
by rewrite -H; apply bit0_add_bit0
theorem bit1_add_bit0 [s : add_comm_inf_semigroup A] [s' : has_one A] (a b : A) :
bit1 a + bit0 b = bit1 (a + b) :=
begin
rewrite [↑bit0, ↑bit1, add_comm_middle], congruence, apply add_comm_four
end
theorem bit1_add_bit0_helper [s : add_comm_inf_semigroup A] [s' : has_one A] (a b t : A)
(H : a + b = t) : bit1 a + bit0 b = bit1 t :=
by rewrite -H; apply bit1_add_bit0
theorem bit0_add_bit1 [s : add_comm_inf_semigroup A] [s' : has_one A] (a b : A) :
bit0 a + bit1 b = bit1 (a + b) :=
by rewrite [{bit0 a + bit1 b}add.comm,{a + b}add.comm]; exact bit1_add_bit0 b a
theorem bit0_add_bit1_helper [s : add_comm_inf_semigroup A] [s' : has_one A] (a b t : A)
(H : a + b = t) : bit0 a + bit1 b = bit1 t :=
by rewrite -H; apply bit0_add_bit1
theorem bit1_add_bit1 [s : add_comm_inf_semigroup A] [s' : has_one A] (a b : A) :
bit1 a + bit1 b = bit0 (add1 (a + b)) :=
begin
rewrite ↑[bit0, bit1, add1, add.assoc],
rewrite [*add.assoc, {_ + (b + 1)}add.comm, {_ + (b + 1 + _)}add.comm,
{_ + (b + 1 + _ + _)}add.comm, *add.assoc, {1 + a}add.comm, -{b + (a + 1)}add.assoc,
{b + a}add.comm, *add.assoc]
end
theorem bit1_add_bit1_helper [s : add_comm_inf_semigroup A] [s' : has_one A] (a b t s: A)
(H : (a + b) = t) (H2 : add1 t = s) : bit1 a + bit1 b = bit0 s :=
begin rewrite [-H2, -H], apply bit1_add_bit1 end
theorem bin_add_zero [s : add_inf_monoid A] (a : A) : a + zero = a := !add_zero
theorem bin_zero_add [s : add_inf_monoid A] (a : A) : zero + a = a := !zero_add
theorem one_add_bit0 [s : add_comm_inf_semigroup A] [s' : has_one A] (a : A) : one + bit0 a = bit1 a :=
begin rewrite ↑[bit0, bit1], rewrite add.comm end
theorem bit0_add_one [s : has_add A] [s' : has_one A] (a : A) : bit0 a + one = bit1 a :=
rfl
theorem bit1_add_one [s : has_add A] [s' : has_one A] (a : A) : bit1 a + one = add1 (bit1 a) :=
rfl
theorem bit1_add_one_helper [s : has_add A] [s' : has_one A] (a t : A) (H : add1 (bit1 a) = t) :
bit1 a + one = t :=
by rewrite -H
theorem one_add_bit1 [s : add_comm_inf_semigroup A] [s' : has_one A] (a : A) :
one + bit1 a = add1 (bit1 a) := !add.comm
theorem one_add_bit1_helper [s : add_comm_inf_semigroup A] [s' : has_one A] (a t : A)
(H : add1 (bit1 a) = t) : one + bit1 a = t :=
by rewrite -H; apply one_add_bit1
theorem add1_bit0 [s : has_add A] [s' : has_one A] (a : A) : add1 (bit0 a) = bit1 a :=
rfl
theorem add1_bit1 [s : add_comm_inf_semigroup A] [s' : has_one A] (a : A) :
add1 (bit1 a) = bit0 (add1 a) :=
begin
rewrite ↑[add1, bit1, bit0],
rewrite [add.assoc, add_comm_four]
end
theorem add1_bit1_helper [s : add_comm_inf_semigroup A] [s' : has_one A] (a t : A) (H : add1 a = t) :
add1 (bit1 a) = bit0 t :=
by rewrite -H; apply add1_bit1
theorem add1_one [s : has_add A] [s' : has_one A] : add1 (one : A) = bit0 one :=
rfl
theorem add1_zero [s : add_inf_monoid A] [s' : has_one A] : add1 (zero : A) = one :=
begin
rewrite [↑add1, zero_add]
end
theorem one_add_one [s : has_add A] [s' : has_one A] : (one : A) + one = bit0 one :=
rfl
theorem subst_into_sum [s : has_add A] (l r tl tr t : A) (prl : l = tl) (prr : r = tr)
(prt : tl + tr = t) : l + r = t :=
by rewrite [prl, prr, prt]
theorem neg_zero_helper [s : add_inf_group A] (a : A) (H : a = 0) : - a = 0 :=
by rewrite [H, neg_zero]
end norm_num
end algebra
open algebra
attribute [simp]
zero_add add_zero one_mul mul_one
at simplifier.unit
attribute [simp]
neg_neg sub_eq_add_neg
at simplifier.neg
attribute [simp]
add.assoc add.comm add.left_comm
mul.left_comm mul.comm mul.assoc
at simplifier.ac

View file

@ -1,114 +0,0 @@
/-
Copyright (c) 2014 Jeremy Avigad. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Jeremy Avigad
-/
import .order
open eq
variable {A : Type}
set_option class.force_new true
/- lattices (we could split this to upper- and lower-semilattices, if needed) -/
namespace algebra
structure lattice [class] (A : Type) extends weak_order A :=
(inf : A → A → A)
(sup : A → A → A)
(inf_le_left : Π a b, le (inf a b) a)
(inf_le_right : Π a b, le (inf a b) b)
(le_inf : Πa b c, le c a → le c b → le c (inf a b))
(le_sup_left : Π a b, le a (sup a b))
(le_sup_right : Π a b, le b (sup a b))
(sup_le : Π a b c, le a c → le b c → le (sup a b) c)
definition inf := @lattice.inf
definition sup := @lattice.sup
infix ` ⊓ `:70 := inf
infix ` ⊔ `:65 := sup
section
variable [s : lattice A]
include s
theorem inf_le_left (a b : A) : a ⊓ b ≤ a := !lattice.inf_le_left
theorem inf_le_right (a b : A) : a ⊓ b ≤ b := !lattice.inf_le_right
theorem le_inf {a b c : A} (H₁ : c ≤ a) (H₂ : c ≤ b) : c ≤ a ⊓ b := !lattice.le_inf H₁ H₂
theorem le_sup_left (a b : A) : a ≤ a ⊔ b := !lattice.le_sup_left
theorem le_sup_right (a b : A) : b ≤ a ⊔ b := !lattice.le_sup_right
theorem sup_le {a b c : A} (H₁ : a ≤ c) (H₂ : b ≤ c) : a ⊔ b ≤ c := !lattice.sup_le H₁ H₂
/- inf -/
theorem eq_inf {a b c : A} (H₁ : c ≤ a) (H₂ : c ≤ b) (H₃ : Π{d}, d ≤ a → d ≤ b → d ≤ c) :
c = a ⊓ b :=
le.antisymm (le_inf H₁ H₂) (H₃ !inf_le_left !inf_le_right)
theorem inf.comm (a b : A) : a ⊓ b = b ⊓ a :=
eq_inf !inf_le_right !inf_le_left (λ c H₁ H₂, le_inf H₂ H₁)
theorem inf.assoc (a b c : A) : (a ⊓ b) ⊓ c = a ⊓ (b ⊓ c) :=
begin
apply eq_inf,
{ apply le.trans, apply inf_le_left, apply inf_le_left },
{ apply le_inf, apply le.trans, apply inf_le_left, apply inf_le_right, apply inf_le_right },
{ intros [d, H₁, H₂], apply le_inf, apply le_inf H₁, apply le.trans H₂, apply inf_le_left,
apply le.trans H₂, apply inf_le_right }
end
theorem inf.left_comm (a b c : A) : a ⊓ (b ⊓ c) = b ⊓ (a ⊓ c) :=
binary.left_comm (@inf.comm A s) (@inf.assoc A s) a b c
theorem inf.right_comm (a b c : A) : (a ⊓ b) ⊓ c = (a ⊓ c) ⊓ b :=
binary.right_comm (@inf.comm A s) (@inf.assoc A s) a b c
theorem inf_self (a : A) : a ⊓ a = a :=
by apply inverse; apply eq_inf (le.refl a) !le.refl; intros; assumption
theorem inf_eq_left {a b : A} (H : a ≤ b) : a ⊓ b = a :=
by apply inverse; apply eq_inf !le.refl H; intros; assumption
theorem inf_eq_right {a b : A} (H : b ≤ a) : a ⊓ b = b :=
eq.subst !inf.comm (inf_eq_left H)
/- sup -/
theorem eq_sup {a b c : A} (H₁ : a ≤ c) (H₂ : b ≤ c) (H₃ : Π{d}, a ≤ d → b ≤ d → c ≤ d) :
c = a ⊔ b :=
le.antisymm (H₃ !le_sup_left !le_sup_right) (sup_le H₁ H₂)
theorem sup.comm (a b : A) : a ⊔ b = b ⊔ a :=
eq_sup !le_sup_right !le_sup_left (λ c H₁ H₂, sup_le H₂ H₁)
theorem sup.assoc (a b c : A) : (a ⊔ b) ⊔ c = a ⊔ (b ⊔ c) :=
begin
apply eq_sup,
{ apply le.trans, apply le_sup_left a b, apply le_sup_left },
{ apply sup_le, apply le.trans, apply le_sup_right a b, apply le_sup_left, apply le_sup_right },
{ intros [d, H₁, H₂], apply sup_le, apply sup_le H₁, apply le.trans !le_sup_left H₂,
apply le.trans !le_sup_right H₂}
end
theorem sup.left_comm (a b c : A) : a ⊔ (b ⊔ c) = b ⊔ (a ⊔ c) :=
binary.left_comm (@sup.comm A s) (@sup.assoc A s) a b c
theorem sup.right_comm (a b c : A) : (a ⊔ b) ⊔ c = (a ⊔ c) ⊔ b :=
binary.right_comm (@sup.comm A s) (@sup.assoc A s) a b c
theorem sup_self (a : A) : a ⊔ a = a :=
by apply inverse; apply eq_sup (le.refl a) !le.refl; intros; assumption
theorem sup_eq_left {a b : A} (H : b ≤ a) : a ⊔ b = a :=
by apply inverse; apply eq_sup !le.refl H; intros; assumption
theorem sup_eq_right {a b : A} (H : a ≤ b) : a ⊔ b = b :=
eq.subst !sup.comm (sup_eq_left H)
end
end algebra

View file

@ -1,446 +0,0 @@
/-
Copyright (c) 2014 Jeremy Avigad. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Jeremy Avigad
Weak orders "≤", strict orders "<", and structures that include both.
-/
import algebra.binary algebra.priority
open eq eq.ops algebra
-- set_option class.force_new true
variable {A : Type}
/- weak orders -/
namespace algebra
structure weak_order [class] (A : Type) extends has_le A :=
(le_refl : Πa, le a a)
(le_trans : Πa b c, le a b → le b c → le a c)
(le_antisymm : Πa b, le a b → le b a → a = b)
section
variable [s : weak_order A]
include s
definition le.refl [refl] (a : A) : a ≤ a := !weak_order.le_refl
definition le_of_eq {a b : A} (H : a = b) : a ≤ b := H ▸ le.refl a
definition le.trans [trans] {a b c : A} : a ≤ b → b ≤ c → a ≤ c := !weak_order.le_trans
definition ge.trans [trans] {a b c : A} (H1 : a ≥ b) (H2: b ≥ c) : a ≥ c := le.trans H2 H1
definition le.antisymm {a b : A} : a ≤ b → b ≤ a → a = b := !weak_order.le_antisymm
-- Alternate syntax. (Abbreviations do not migrate well.)
definition eq_of_le_of_ge {a b : A} : a ≤ b → b ≤ a → a = b := !le.antisymm
end
structure linear_weak_order [class] (A : Type) extends weak_order A :=
(le_total : Πa b, le a b ⊎ le b a)
section
variables [linear_weak_order A]
theorem le.total (a b : A) : a ≤ b ⊎ b ≤ a := !linear_weak_order.le_total
theorem le_of_not_ge {a b : A} (H : ¬ a ≥ b) : a ≤ b := sum.resolve_left !le.total H
definition le_by_cases (a b : A) {P : Type} (H1 : a ≤ b → P) (H2 : b ≤ a → P) : P :=
begin
cases (le.total a b) with H H,
{ exact H1 H},
{ exact H2 H}
end
end
/- strict orders -/
structure strict_order [class] (A : Type) extends has_lt A :=
(lt_irrefl : Πa, ¬ lt a a)
(lt_trans : Πa b c, lt a b → lt b c → lt a c)
section
variable [s : strict_order A]
include s
definition lt.irrefl (a : A) : ¬ a < a := !strict_order.lt_irrefl
definition not_lt_self (a : A) : ¬ a < a := !lt.irrefl -- alternate syntax
theorem lt_self_iff_empty (a : A) : a < a ↔ empty :=
iff_empty_intro (lt.irrefl a)
definition lt.trans [trans] {a b c : A} : a < b → b < c → a < c := !strict_order.lt_trans
definition gt.trans [trans] {a b c : A} (H1 : a > b) (H2: b > c) : a > c := lt.trans H2 H1
theorem ne_of_lt {a b : A} (lt_ab : a < b) : a ≠ b :=
assume eq_ab : a = b,
show empty, from lt.irrefl b (eq_ab ▸ lt_ab)
theorem ne_of_gt {a b : A} (gt_ab : a > b) : a ≠ b :=
ne.symm (ne_of_lt gt_ab)
theorem lt.asymm {a b : A} (H : a < b) : ¬ b < a :=
assume H1 : b < a, lt.irrefl _ (lt.trans H H1)
theorem not_lt_of_gt {a b : A} (H : a > b) : ¬ a < b := !lt.asymm H -- alternate syntax
end
/- well-founded orders -/
structure wf_strict_order [class] (A : Type) extends strict_order A :=
(wf_rec : ΠP : A → Type, (Πx, (Πy, lt y x → P y) → P x) → Πx, P x)
definition wf.rec_on {A : Type} [s : wf_strict_order A] {P : A → Type}
(x : A) (H : Πx, (Πy, wf_strict_order.lt y x → P y) → P x) : P x :=
wf_strict_order.wf_rec P H x
/- structures with a weak and a strict order -/
structure order_pair [class] (A : Type) extends weak_order A, has_lt A :=
(le_of_lt : Π a b, lt a b → le a b)
(lt_of_lt_of_le : Π a b c, lt a b → le b c → lt a c)
(lt_of_le_of_lt : Π a b c, le a b → lt b c → lt a c)
(lt_irrefl : Π a, ¬ lt a a)
section
variable [s : order_pair A]
variables {a b c : A}
include s
definition le_of_lt : a < b → a ≤ b := !order_pair.le_of_lt
definition lt_of_lt_of_le [trans] : a < b → b ≤ c → a < c := !order_pair.lt_of_lt_of_le
definition lt_of_le_of_lt [trans] : a ≤ b → b < c → a < c := !order_pair.lt_of_le_of_lt
private definition lt_irrefl (s' : order_pair A) (a : A) : ¬ a < a := !order_pair.lt_irrefl
private theorem lt_trans (s' : order_pair A) (a b c: A) (lt_ab : a < b) (lt_bc : b < c) : a < c :=
lt_of_lt_of_le lt_ab (le_of_lt lt_bc)
definition order_pair.to_strict_order [trans_instance] : strict_order A :=
⦃ strict_order, s, lt_irrefl := lt_irrefl s, lt_trans := lt_trans s ⦄
definition gt_of_gt_of_ge [trans] (H1 : a > b) (H2 : b ≥ c) : a > c := lt_of_le_of_lt H2 H1
definition gt_of_ge_of_gt [trans] (H1 : a ≥ b) (H2 : b > c) : a > c := lt_of_lt_of_le H2 H1
theorem not_le_of_gt (H : a > b) : ¬ a ≤ b :=
assume H1 : a ≤ b,
lt.irrefl _ (lt_of_lt_of_le H H1)
theorem not_lt_of_ge (H : a ≥ b) : ¬ a < b :=
assume H1 : a < b,
lt.irrefl _ (lt_of_le_of_lt H H1)
end
structure strong_order_pair [class] (A : Type) extends weak_order A, has_lt A :=
(le_iff_lt_sum_eq : Πa b, le a b ↔ lt a b ⊎ a = b)
(lt_irrefl : Π a, ¬ lt a a)
definition le_iff_lt_sum_eq [s : strong_order_pair A] {a b : A} : a ≤ b ↔ a < b ⊎ a = b :=
!strong_order_pair.le_iff_lt_sum_eq
theorem lt_sum_eq_of_le [s : strong_order_pair A] {a b : A} (le_ab : a ≤ b) : a < b ⊎ a = b :=
iff.mp le_iff_lt_sum_eq le_ab
theorem le_of_lt_sum_eq [s : strong_order_pair A] {a b : A} (lt_sum_eq : a < b ⊎ a = b) : a ≤ b :=
iff.mpr le_iff_lt_sum_eq lt_sum_eq
private definition lt_irrefl' [s : strong_order_pair A] (a : A) : ¬ a < a :=
!strong_order_pair.lt_irrefl
private theorem le_of_lt' [s : strong_order_pair A] (a b : A) : a < b → a ≤ b :=
take Hlt, le_of_lt_sum_eq (sum.inl Hlt)
private theorem lt_iff_le_prod_ne [s : strong_order_pair A] {a b : A} : a < b ↔ (a ≤ b × a ≠ b) :=
iff.intro
(take Hlt, pair (le_of_lt_sum_eq (sum.inl Hlt)) (take Hab, absurd (Hab ▸ Hlt) !lt_irrefl'))
(take Hand,
have Hor : a < b ⊎ a = b, from lt_sum_eq_of_le (prod.pr1 Hand),
sum_resolve_left Hor (prod.pr2 Hand))
theorem lt_of_le_of_ne [s : strong_order_pair A] {a b : A} : a ≤ b → a ≠ b → a < b :=
take H1 H2, iff.mpr lt_iff_le_prod_ne (pair H1 H2)
private theorem ne_of_lt' [s : strong_order_pair A] {a b : A} (H : a < b) : a ≠ b :=
prod.pr2 ((iff.mp (@lt_iff_le_prod_ne _ _ _ _)) H)
private theorem lt_of_lt_of_le' [s : strong_order_pair A] (a b c : A) : a < b → b ≤ c → a < c :=
assume lt_ab : a < b,
assume le_bc : b ≤ c,
have le_ac : a ≤ c, from le.trans (le_of_lt' _ _ lt_ab) le_bc,
have ne_ac : a ≠ c, from
assume eq_ac : a = c,
have le_ba : b ≤ a, from eq_ac⁻¹ ▸ le_bc,
have eq_ab : a = b, from le.antisymm (le_of_lt' _ _ lt_ab) le_ba,
show empty, from ne_of_lt' lt_ab eq_ab,
show a < c, from iff.mpr (lt_iff_le_prod_ne) (pair le_ac ne_ac)
theorem lt_of_le_of_lt' [s : strong_order_pair A] (a b c : A) : a ≤ b → b < c → a < c :=
assume le_ab : a ≤ b,
assume lt_bc : b < c,
have le_ac : a ≤ c, from le.trans le_ab (le_of_lt' _ _ lt_bc),
have ne_ac : a ≠ c, from
assume eq_ac : a = c,
have le_cb : c ≤ b, from eq_ac ▸ le_ab,
have eq_bc : b = c, from le.antisymm (le_of_lt' _ _ lt_bc) le_cb,
show empty, from ne_of_lt' lt_bc eq_bc,
show a < c, from iff.mpr (lt_iff_le_prod_ne) (pair le_ac ne_ac)
definition strong_order_pair.to_order_pair [trans_instance] [s : strong_order_pair A] : order_pair A :=
⦃ order_pair, s,
lt_irrefl := lt_irrefl',
le_of_lt := le_of_lt',
lt_of_le_of_lt := lt_of_le_of_lt',
lt_of_lt_of_le := lt_of_lt_of_le' ⦄
/- linear orders -/
structure linear_order_pair [class] (A : Type) extends order_pair A, linear_weak_order A
structure linear_strong_order_pair [class] (A : Type) extends strong_order_pair A,
linear_weak_order A
definition linear_strong_order_pair.to_linear_order_pair [trans_instance]
[s : linear_strong_order_pair A] : linear_order_pair A :=
⦃ linear_order_pair, s, strong_order_pair.to_order_pair ⦄
section
variable [s : linear_strong_order_pair A]
variables (a b c : A)
include s
theorem lt.trichotomy : a < b ⊎ a = b ⊎ b < a :=
sum.elim (le.total a b)
(assume H : a ≤ b,
sum.elim (iff.mp !le_iff_lt_sum_eq H) (assume H1, sum.inl H1) (assume H1, sum.inr (sum.inl H1)))
(assume H : b ≤ a,
sum.elim (iff.mp !le_iff_lt_sum_eq H)
(assume H1, sum.inr (sum.inr H1))
(assume H1, sum.inr (sum.inl (H1⁻¹))))
definition lt.by_cases {a b : A} {P : Type}
(H1 : a < b → P) (H2 : a = b → P) (H3 : b < a → P) : P :=
sum.elim !lt.trichotomy
(assume H, H1 H)
(assume H, sum.elim H (assume H', H2 H') (assume H', H3 H'))
definition lt_ge_by_cases {a b : A} {P : Type} (H1 : a < b → P) (H2 : a ≥ b → P) : P :=
lt.by_cases H1 (λH, H2 (H ▸ le.refl a)) (λH, H2 (le_of_lt H))
theorem le_of_not_gt {a b : A} (H : ¬ a > b) : a ≤ b :=
lt.by_cases (assume H', absurd H' H) (assume H', H' ▸ !le.refl) (assume H', le_of_lt H')
theorem lt_of_not_ge {a b : A} (H : ¬ a ≥ b) : a < b :=
lt.by_cases
(assume H', absurd (le_of_lt H') H)
(assume H', absurd (H' ▸ !le.refl) H)
(assume H', H')
theorem lt_sum_ge : a < b ⊎ a ≥ b :=
lt.by_cases
(assume H1 : a < b, sum.inl H1)
(assume H1 : a = b, sum.inr (H1 ▸ le.refl a))
(assume H1 : a > b, sum.inr (le_of_lt H1))
theorem le_sum_gt : a ≤ b ⊎ a > b :=
!sum.swap (lt_sum_ge b a)
theorem lt_sum_gt_of_ne {a b : A} (H : a ≠ b) : a < b ⊎ a > b :=
lt.by_cases (assume H1, sum.inl H1) (assume H1, absurd H1 H) (assume H1, sum.inr H1)
end
open decidable
structure decidable_linear_order [class] (A : Type) extends linear_strong_order_pair A :=
(decidable_lt : decidable_rel lt)
section
variable [s : decidable_linear_order A]
variables {a b c d : A}
include s
open decidable
definition decidable_lt [instance] : decidable (a < b) :=
@decidable_linear_order.decidable_lt _ _ _ _
definition decidable_le [instance] : decidable (a ≤ b) :=
by_cases
(assume H : a < b, inl (le_of_lt H))
(assume H : ¬ a < b,
have H1 : b ≤ a, from le_of_not_gt H,
by_cases
(assume H2 : b < a, inr (not_le_of_gt H2))
(assume H2 : ¬ b < a, inl (le_of_not_gt H2)))
definition has_decidable_eq [instance] : decidable (a = b) :=
by_cases
(assume H : a ≤ b,
by_cases
(assume H1 : b ≤ a, inl (le.antisymm H H1))
(assume H1 : ¬ b ≤ a, inr (assume H2 : a = b, H1 (H2 ▸ le.refl a))))
(assume H : ¬ a ≤ b,
(inr (assume H1 : a = b, H (H1 ▸ !le.refl))))
theorem eq_sum_lt_of_not_lt {a b : A} (H : ¬ a < b) : a = b ⊎ b < a :=
if Heq : a = b then sum.inl Heq else sum.inr (lt_of_not_ge (λ Hge, H (lt_of_le_of_ne Hge Heq)))
theorem eq_sum_lt_of_le {a b : A} (H : a ≤ b) : a = b ⊎ a < b :=
begin
cases eq_sum_lt_of_not_lt (not_lt_of_ge H),
exact sum.inl a_1⁻¹,
exact sum.inr a_1
end
-- testing equality first may result in more definitional equalities
definition lt.cases {B : Type} (a b : A) (t_lt t_eq t_gt : B) : B :=
if a = b then t_eq else (if a < b then t_lt else t_gt)
theorem lt.cases_of_eq {B : Type} {a b : A} {t_lt t_eq t_gt : B} (H : a = b) :
lt.cases a b t_lt t_eq t_gt = t_eq := if_pos H
theorem lt.cases_of_lt {B : Type} {a b : A} {t_lt t_eq t_gt : B} (H : a < b) :
lt.cases a b t_lt t_eq t_gt = t_lt :=
if_neg (ne_of_lt H) ⬝ if_pos H
theorem lt.cases_of_gt {B : Type} {a b : A} {t_lt t_eq t_gt : B} (H : a > b) :
lt.cases a b t_lt t_eq t_gt = t_gt :=
if_neg (ne.symm (ne_of_lt H)) ⬝ if_neg (lt.asymm H)
definition min (a b : A) : A := if a ≤ b then a else b
definition max (a b : A) : A := if a ≤ b then b else a
/- these show min and max form a lattice -/
theorem min_le_left (a b : A) : min a b ≤ a :=
by_cases
(assume H : a ≤ b, by rewrite [↑min, if_pos H])
(assume H : ¬ a ≤ b, by rewrite [↑min, if_neg H]; apply le_of_lt (lt_of_not_ge H))
theorem min_le_right (a b : A) : min a b ≤ b :=
by_cases
(assume H : a ≤ b, by rewrite [↑min, if_pos H]; apply H)
(assume H : ¬ a ≤ b, by rewrite [↑min, if_neg H])
theorem le_min {a b c : A} (H₁ : c ≤ a) (H₂ : c ≤ b) : c ≤ min a b :=
by_cases
(assume H : a ≤ b, by rewrite [↑min, if_pos H]; apply H₁)
(assume H : ¬ a ≤ b, by rewrite [↑min, if_neg H]; apply H₂)
theorem le_max_left (a b : A) : a ≤ max a b :=
by_cases
(assume H : a ≤ b, by rewrite [↑max, if_pos H]; apply H)
(assume H : ¬ a ≤ b, by rewrite [↑max, if_neg H])
theorem le_max_right (a b : A) : b ≤ max a b :=
by_cases
(assume H : a ≤ b, by rewrite [↑max, if_pos H])
(assume H : ¬ a ≤ b, by rewrite [↑max, if_neg H]; apply le_of_lt (lt_of_not_ge H))
theorem max_le {a b c : A} (H₁ : a ≤ c) (H₂ : b ≤ c) : max a b ≤ c :=
by_cases
(assume H : a ≤ b, by rewrite [↑max, if_pos H]; apply H₂)
(assume H : ¬ a ≤ b, by rewrite [↑max, if_neg H]; apply H₁)
theorem le_max_left_iff_unit (a b : A) : a ≤ max a b ↔ unit :=
iff_unit_intro (le_max_left a b)
theorem le_max_right_iff_unit (a b : A) : b ≤ max a b ↔ unit :=
iff_unit_intro (le_max_right a b)
/- these are also proved for lattices, but with inf and sup in place of min and max -/
theorem eq_min {a b c : A} (H₁ : c ≤ a) (H₂ : c ≤ b) (H₃ : Π{d}, d ≤ a → d ≤ b → d ≤ c) :
c = min a b :=
le.antisymm (le_min H₁ H₂) (H₃ !min_le_left !min_le_right)
theorem min.comm (a b : A) : min a b = min b a :=
eq_min !min_le_right !min_le_left (λ c H₁ H₂, le_min H₂ H₁)
theorem min.assoc (a b c : A) : min (min a b) c = min a (min b c) :=
begin
apply eq_min,
{ apply le.trans, apply min_le_left, apply min_le_left },
{ apply le_min, apply le.trans, apply min_le_left, apply min_le_right, apply min_le_right },
{ intros [d, H₁, H₂], apply le_min, apply le_min H₁, apply le.trans H₂, apply min_le_left,
apply le.trans H₂, apply min_le_right }
end
theorem min.left_comm (a b c : A) : min a (min b c) = min b (min a c) :=
binary.left_comm (@min.comm A s) (@min.assoc A s) a b c
theorem min.right_comm (a b c : A) : min (min a b) c = min (min a c) b :=
binary.right_comm (@min.comm A s) (@min.assoc A s) a b c
theorem min_self (a : A) : min a a = a :=
by apply inverse; apply eq_min (le.refl a) !le.refl; intros; assumption
theorem min_eq_left {a b : A} (H : a ≤ b) : min a b = a :=
by apply inverse; apply eq_min !le.refl H; intros; assumption
theorem min_eq_right {a b : A} (H : b ≤ a) : min a b = b :=
eq.subst !min.comm (min_eq_left H)
theorem eq_max {a b c : A} (H₁ : a ≤ c) (H₂ : b ≤ c) (H₃ : Π{d}, a ≤ d → b ≤ d → c ≤ d) :
c = max a b :=
le.antisymm (H₃ !le_max_left !le_max_right) (max_le H₁ H₂)
theorem max.comm (a b : A) : max a b = max b a :=
eq_max !le_max_right !le_max_left (λ c H₁ H₂, max_le H₂ H₁)
theorem max.assoc (a b c : A) : max (max a b) c = max a (max b c) :=
begin
apply eq_max,
{ apply le.trans, apply le_max_left a b, apply le_max_left },
{ apply max_le, apply le.trans, apply le_max_right a b, apply le_max_left, apply le_max_right },
{ intros [d, H₁, H₂], apply max_le, apply max_le H₁, apply le.trans !le_max_left H₂,
apply le.trans !le_max_right H₂}
end
theorem max.left_comm (a b c : A) : max a (max b c) = max b (max a c) :=
binary.left_comm (@max.comm A s) (@max.assoc A s) a b c
theorem max.right_comm (a b c : A) : max (max a b) c = max (max a c) b :=
binary.right_comm (@max.comm A s) (@max.assoc A s) a b c
theorem max_self (a : A) : max a a = a :=
by apply inverse; apply eq_max (le.refl a) !le.refl; intros; assumption
theorem max_eq_left {a b : A} (H : b ≤ a) : max a b = a :=
by apply inverse; apply eq_max !le.refl H; intros; assumption
theorem max_eq_right {a b : A} (H : a ≤ b) : max a b = b :=
eq.subst !max.comm (max_eq_left H)
/- these rely on lt_of_lt -/
theorem min_eq_left_of_lt {a b : A} (H : a < b) : min a b = a :=
min_eq_left (le_of_lt H)
theorem min_eq_right_of_lt {a b : A} (H : b < a) : min a b = b :=
min_eq_right (le_of_lt H)
theorem max_eq_left_of_lt {a b : A} (H : b < a) : max a b = a :=
max_eq_left (le_of_lt H)
theorem max_eq_right_of_lt {a b : A} (H : a < b) : max a b = b :=
max_eq_right (le_of_lt H)
/- these use the fact that it is a linear ordering -/
theorem lt_min {a b c : A} (H₁ : a < b) (H₂ : a < c) : a < min b c :=
sum.elim !le_sum_gt
(assume H : b ≤ c, by rewrite (min_eq_left H); apply H₁)
(assume H : b > c, by rewrite (min_eq_right_of_lt H); apply H₂)
theorem max_lt {a b c : A} (H₁ : a < c) (H₂ : b < c) : max a b < c :=
sum.elim !le_sum_gt
(assume H : a ≤ b, by rewrite (max_eq_right H); apply H₂)
(assume H : a > b, by rewrite (max_eq_left_of_lt H); apply H₁)
end
end algebra

View file

@ -1,518 +0,0 @@
/-
Copyright (c) 2014 Robert Lewis. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Robert Lewis
-/
import algebra.ordered_ring algebra.field
open eq eq.ops algebra
set_option class.force_new true
namespace algebra
structure linear_ordered_field [class] (A : Type) extends linear_ordered_ring A, field A
section linear_ordered_field
variable {A : Type}
variables [s : linear_ordered_field A] {a b c d : A}
include s
-- helpers for following
theorem mul_zero_lt_mul_inv_of_pos (H : 0 < a) : a * 0 < a * (1 / a) :=
calc
a * 0 = 0 : mul_zero
... < 1 : zero_lt_one
... = a * a⁻¹ : mul_inv_cancel (ne.symm (ne_of_lt H))
... = a * (1 / a) : inv_eq_one_div
theorem mul_zero_lt_mul_inv_of_neg (H : a < 0) : a * 0 < a * (1 / a) :=
calc
a * 0 = 0 : mul_zero
... < 1 : zero_lt_one
... = a * a⁻¹ : mul_inv_cancel (ne_of_lt H)
... = a * (1 / a) : inv_eq_one_div
theorem one_div_pos_of_pos (H : 0 < a) : 0 < 1 / a :=
lt_of_mul_lt_mul_left (mul_zero_lt_mul_inv_of_pos H) (le_of_lt H)
theorem one_div_neg_of_neg (H : a < 0) : 1 / a < 0 :=
gt_of_mul_lt_mul_neg_left (mul_zero_lt_mul_inv_of_neg H) (le_of_lt H)
theorem le_mul_of_ge_one_right (Hb : b ≥ 0) (H : a ≥ 1) : b ≤ b * a :=
mul_one _ ▸ (mul_le_mul_of_nonneg_left H Hb)
theorem lt_mul_of_gt_one_right (Hb : b > 0) (H : a > 1) : b < b * a :=
mul_one _ ▸ (mul_lt_mul_of_pos_left H Hb)
theorem one_le_div_iff_le (a : A) {b : A} (Hb : b > 0) : 1 ≤ a / b ↔ b ≤ a :=
have Hb' : b ≠ 0, from ne.symm (ne_of_lt Hb),
iff.intro
(assume H : 1 ≤ a / b,
calc
b = b : refl
... ≤ b * (a / b) : le_mul_of_ge_one_right (le_of_lt Hb) H
... = a : mul_div_cancel' Hb')
(assume H : b ≤ a,
have Hbinv : 1 / b > 0, from one_div_pos_of_pos Hb, calc
1 = b * (1 / b) : mul_one_div_cancel Hb'
... ≤ a * (1 / b) : mul_le_mul_of_nonneg_right H (le_of_lt Hbinv)
... = a / b : div_eq_mul_one_div)
theorem le_of_one_le_div (Hb : b > 0) (H : 1 ≤ a / b) : b ≤ a :=
(iff.mp (!one_le_div_iff_le Hb)) H
theorem one_le_div_of_le (Hb : b > 0) (H : b ≤ a) : 1 ≤ a / b :=
(iff.mpr (!one_le_div_iff_le Hb)) H
theorem one_lt_div_iff_lt (a : A) {b : A} (Hb : b > 0) : 1 < a / b ↔ b < a :=
have Hb' : b ≠ 0, from ne.symm (ne_of_lt Hb),
iff.intro
(assume H : 1 < a / b,
calc
b < b * (a / b) : lt_mul_of_gt_one_right Hb H
... = a : mul_div_cancel' Hb')
(assume H : b < a,
have Hbinv : 1 / b > 0, from one_div_pos_of_pos Hb, calc
1 = b * (1 / b) : mul_one_div_cancel Hb'
... < a * (1 / b) : mul_lt_mul_of_pos_right H Hbinv
... = a / b : div_eq_mul_one_div)
theorem lt_of_one_lt_div (Hb : b > 0) (H : 1 < a / b) : b < a :=
(iff.mp (!one_lt_div_iff_lt Hb)) H
theorem one_lt_div_of_lt (Hb : b > 0) (H : b < a) : 1 < a / b :=
(iff.mpr (!one_lt_div_iff_lt Hb)) H
theorem exists_lt (a : A) : Σ x, x < a :=
have H : a - 1 < a, from add_lt_of_le_of_neg (le.refl _) zero_gt_neg_one,
sigma.mk _ H
theorem exists_gt (a : A) : Σ x, x > a :=
have H : a + 1 > a, from lt_add_of_le_of_pos (le.refl _) zero_lt_one,
sigma.mk _ H
-- the following theorems amount to four iffs, for <, ≤, ≥, >.
theorem mul_le_of_le_div (Hc : 0 < c) (H : a ≤ b / c) : a * c ≤ b :=
!div_mul_cancel (ne.symm (ne_of_lt Hc)) ▸ mul_le_mul_of_nonneg_right H (le_of_lt Hc)
theorem le_div_of_mul_le (Hc : 0 < c) (H : a * c ≤ b) : a ≤ b / c :=
calc
a = a * c * (1 / c) : !mul_mul_div (ne.symm (ne_of_lt Hc))
... ≤ b * (1 / c) : mul_le_mul_of_nonneg_right H (le_of_lt (one_div_pos_of_pos Hc))
... = b / c : div_eq_mul_one_div
theorem mul_lt_of_lt_div (Hc : 0 < c) (H : a < b / c) : a * c < b :=
!div_mul_cancel (ne.symm (ne_of_lt Hc)) ▸ mul_lt_mul_of_pos_right H Hc
theorem lt_div_of_mul_lt (Hc : 0 < c) (H : a * c < b) : a < b / c :=
calc
a = a * c * (1 / c) : !mul_mul_div (ne.symm (ne_of_lt Hc))
... < b * (1 / c) : mul_lt_mul_of_pos_right H (one_div_pos_of_pos Hc)
... = b / c : div_eq_mul_one_div
theorem mul_le_of_div_le_of_neg (Hc : c < 0) (H : b / c ≤ a) : a * c ≤ b :=
!div_mul_cancel (ne_of_lt Hc) ▸ mul_le_mul_of_nonpos_right H (le_of_lt Hc)
theorem div_le_of_mul_le_of_neg (Hc : c < 0) (H : a * c ≤ b) : b / c ≤ a :=
calc
a = a * c * (1 / c) : !mul_mul_div (ne_of_lt Hc)
... ≥ b * (1 / c) : mul_le_mul_of_nonpos_right H (le_of_lt (one_div_neg_of_neg Hc))
... = b / c : div_eq_mul_one_div
theorem mul_lt_of_gt_div_of_neg (Hc : c < 0) (H : a > b / c) : a * c < b :=
!div_mul_cancel (ne_of_lt Hc) ▸ mul_lt_mul_of_neg_right H Hc
theorem div_lt_of_mul_gt_of_neg (Hc : c < 0) (H : a * c < b) : b / c < a :=
calc
a = a * c * (1 / c) : !mul_mul_div (ne_of_lt Hc)
... > b * (1 / c) : mul_lt_mul_of_neg_right H (one_div_neg_of_neg Hc)
... = b / c : div_eq_mul_one_div
theorem div_le_of_le_mul (Hb : b > 0) (H : a ≤ b * c) : a / b ≤ c :=
calc
a / b = a * (1 / b) : div_eq_mul_one_div
... ≤ (b * c) * (1 / b) : mul_le_mul_of_nonneg_right H (le_of_lt (one_div_pos_of_pos Hb))
... = (b * c) / b : div_eq_mul_one_div
... = c : mul_div_cancel_left (ne.symm (ne_of_lt Hb))
theorem le_mul_of_div_le (Hc : c > 0) (H : a / c ≤ b) : a ≤ b * c :=
calc
a = a / c * c : !div_mul_cancel (ne.symm (ne_of_lt Hc))
... ≤ b * c : mul_le_mul_of_nonneg_right H (le_of_lt Hc)
-- following these in the isabelle file, there are 8 biconditionals for the above with - signs
-- skipping for now
theorem mul_sub_mul_div_mul_neg (Hc : c ≠ 0) (Hd : d ≠ 0) (H : a / c < b / d) :
(a * d - b * c) / (c * d) < 0 :=
have H1 : a / c - b / d < 0, from calc
a / c - b / d < b / d - b / d : sub_lt_sub_right H
... = 0 : sub_self,
calc
0 > a / c - b / d : H1
... = (a * d - c * b) / (c * d) : !div_sub_div Hc Hd
... = (a * d - b * c) / (c * d) : mul.comm
theorem mul_sub_mul_div_mul_nonpos (Hc : c ≠ 0) (Hd : d ≠ 0) (H : a / c ≤ b / d) :
(a * d - b * c) / (c * d) ≤ 0 :=
have H1 : a / c - b / d ≤ 0, from calc
a / c - b / d ≤ b / d - b / d : sub_le_sub_right H
... = 0 : sub_self,
calc
0 ≥ a / c - b / d : H1
... = (a * d - c * b) / (c * d) : !div_sub_div Hc Hd
... = (a * d - b * c) / (c * d) : mul.comm
theorem div_lt_div_of_mul_sub_mul_div_neg (Hc : c ≠ 0) (Hd : d ≠ 0)
(H : (a * d - b * c) / (c * d) < 0) : a / c < b / d :=
have H1 : (a * d - c * b) / (c * d) < 0, by rewrite [mul.comm c b]; exact H,
have H2 : a / c - b / d < 0, by rewrite [!div_sub_div Hc Hd]; exact H1,
have H3 : a / c - b / d + b / d < 0 + b / d, from add_lt_add_right H2 _,
begin rewrite [zero_add at H3, sub_eq_add_neg at H3, neg_add_cancel_right at H3], exact H3 end
theorem div_le_div_of_mul_sub_mul_div_nonpos (Hc : c ≠ 0) (Hd : d ≠ 0)
(H : (a * d - b * c) / (c * d) ≤ 0) : a / c ≤ b / d :=
have H1 : (a * d - c * b) / (c * d) ≤ 0, by rewrite [mul.comm c b]; exact H,
have H2 : a / c - b / d ≤ 0, by rewrite [!div_sub_div Hc Hd]; exact H1,
have H3 : a / c - b / d + b / d ≤ 0 + b / d, from add_le_add_right H2 _,
begin rewrite [zero_add at H3, sub_eq_add_neg at H3, neg_add_cancel_right at H3], exact H3 end
theorem div_pos_of_pos_of_pos (Ha : 0 < a) (Hb : 0 < b) : 0 < a / b :=
begin
rewrite div_eq_mul_one_div,
apply mul_pos,
exact Ha,
apply one_div_pos_of_pos,
exact Hb
end
theorem div_nonneg_of_nonneg_of_pos (Ha : 0 ≤ a) (Hb : 0 < b) : 0 ≤ a / b :=
begin
rewrite div_eq_mul_one_div,
apply mul_nonneg,
exact Ha,
apply le_of_lt,
apply one_div_pos_of_pos,
exact Hb
end
theorem div_neg_of_neg_of_pos (Ha : a < 0) (Hb : 0 < b) : a / b < 0:=
begin
rewrite div_eq_mul_one_div,
apply mul_neg_of_neg_of_pos,
exact Ha,
apply one_div_pos_of_pos,
exact Hb
end
theorem div_nonpos_of_nonpos_of_pos (Ha : a ≤ 0) (Hb : 0 < b) : a / b ≤ 0 :=
begin
rewrite div_eq_mul_one_div,
apply mul_nonpos_of_nonpos_of_nonneg,
exact Ha,
apply le_of_lt,
apply one_div_pos_of_pos,
exact Hb
end
theorem div_neg_of_pos_of_neg (Ha : 0 < a) (Hb : b < 0) : a / b < 0 :=
begin
rewrite div_eq_mul_one_div,
apply mul_neg_of_pos_of_neg,
exact Ha,
apply one_div_neg_of_neg,
exact Hb
end
theorem div_nonpos_of_nonneg_of_neg (Ha : 0 ≤ a) (Hb : b < 0) : a / b ≤ 0 :=
begin
rewrite div_eq_mul_one_div,
apply mul_nonpos_of_nonneg_of_nonpos,
exact Ha,
apply le_of_lt,
apply one_div_neg_of_neg,
exact Hb
end
theorem div_pos_of_neg_of_neg (Ha : a < 0) (Hb : b < 0) : 0 < a / b :=
begin
rewrite div_eq_mul_one_div,
apply mul_pos_of_neg_of_neg,
exact Ha,
apply one_div_neg_of_neg,
exact Hb
end
theorem div_nonneg_of_nonpos_of_neg (Ha : a ≤ 0) (Hb : b < 0) : 0 ≤ a / b :=
begin
rewrite div_eq_mul_one_div,
apply mul_nonneg_of_nonpos_of_nonpos,
exact Ha,
apply le_of_lt,
apply one_div_neg_of_neg,
exact Hb
end
theorem div_lt_div_of_lt_of_pos (H : a < b) (Hc : 0 < c) : a / c < b / c :=
begin
rewrite [{a/c}div_eq_mul_one_div, {b/c}div_eq_mul_one_div],
exact mul_lt_mul_of_pos_right H (one_div_pos_of_pos Hc)
end
theorem div_le_div_of_le_of_pos (H : a ≤ b) (Hc : 0 < c) : a / c ≤ b / c :=
begin
rewrite [{a/c}div_eq_mul_one_div, {b/c}div_eq_mul_one_div],
exact mul_le_mul_of_nonneg_right H (le_of_lt (one_div_pos_of_pos Hc))
end
theorem div_lt_div_of_lt_of_neg (H : b < a) (Hc : c < 0) : a / c < b / c :=
begin
rewrite [{a/c}div_eq_mul_one_div, {b/c}div_eq_mul_one_div],
exact mul_lt_mul_of_neg_right H (one_div_neg_of_neg Hc)
end
theorem div_le_div_of_le_of_neg (H : b ≤ a) (Hc : c < 0) : a / c ≤ b / c :=
begin
rewrite [{a/c}div_eq_mul_one_div, {b/c}div_eq_mul_one_div],
exact mul_le_mul_of_nonpos_right H (le_of_lt (one_div_neg_of_neg Hc))
end
theorem two_pos : (1 : A) + 1 > 0 :=
add_pos zero_lt_one zero_lt_one
theorem one_add_one_ne_zero : 1 + 1 ≠ (0:A) :=
ne.symm (ne_of_lt two_pos)
theorem two_ne_zero : 2 ≠ (0:A) :=
by unfold bit0; apply one_add_one_ne_zero
theorem add_halves (a : A) : a / 2 + a / 2 = a :=
calc
a / 2 + a / 2 = (a + a) / 2 : by rewrite div_add_div_same
... = (a * 1 + a * 1) / 2 : by rewrite mul_one
... = (a * (1 + 1)) / 2 : by rewrite left_distrib
... = (a * 2) / 2 : by rewrite one_add_one_eq_two
... = a : by rewrite [@mul_div_cancel A _ _ _ two_ne_zero]
theorem sub_self_div_two (a : A) : a - a / 2 = a / 2 :=
by rewrite [-{a}add_halves at {1}, add_sub_cancel]
theorem add_midpoint {a b : A} (H : a < b) : a + (b - a) / 2 < b :=
begin
rewrite [-div_sub_div_same, sub_eq_add_neg, {b / 2 + _}add.comm, -add.assoc, -sub_eq_add_neg],
apply add_lt_of_lt_sub_right,
rewrite *sub_self_div_two,
apply div_lt_div_of_lt_of_pos H two_pos
end
theorem div_two_sub_self (a : A) : a / 2 - a = - (a / 2) :=
by rewrite [-{a}add_halves at {2}, sub_add_eq_sub_sub, sub_self, zero_sub]
theorem add_self_div_two (a : A) : (a + a) / 2 = a :=
symm (iff.mpr (!eq_div_iff_mul_eq (ne_of_gt (add_pos zero_lt_one zero_lt_one)))
(by krewrite [left_distrib, *mul_one]))
theorem two_ge_one : (2:A) ≥ 1 :=
calc (2:A) = 1+1 : one_add_one_eq_two
... ≥ 1+0 : add_le_add_left (le_of_lt zero_lt_one)
... = 1 : add_zero
theorem mul_le_mul_of_mul_div_le (H : a * (b / c) ≤ d) (Hc : c > 0) : b * a ≤ d * c :=
begin
rewrite [-mul_div_assoc at H, mul.comm b],
apply le_mul_of_div_le Hc H
end
theorem div_two_lt_of_pos (H : a > 0) : a / (1 + 1) < a :=
have Ha : a / (1 + 1) > 0, from div_pos_of_pos_of_pos H (add_pos zero_lt_one zero_lt_one),
calc
a / (1 + 1) < a / (1 + 1) + a / (1 + 1) : lt_add_of_pos_left Ha
... = a : add_halves
theorem div_mul_le_div_mul_of_div_le_div_pos {e : A} (Hb : b ≠ 0) (Hd : d ≠ 0) (H : a / b ≤ c / d)
(He : e > 0) : a / (b * e) ≤ c / (d * e) :=
begin
rewrite [!field.div_mul_eq_div_mul_one_div Hb (ne_of_gt He),
!field.div_mul_eq_div_mul_one_div Hd (ne_of_gt He)],
apply mul_le_mul_of_nonneg_right H,
apply le_of_lt,
apply one_div_pos_of_pos He
end
theorem exists_add_lt_prod_pos_of_lt (H : b < a) : Σ c : A, b + c < a × c > 0 :=
sigma.mk ((a - b) / (1 + 1))
(pair (have H2 : a + a > (b + b) + (a - b), from calc
a + a > b + a : add_lt_add_right H
... = b + a + b - b : by rewrite add_sub_cancel
... = b + b + a - b : by rewrite add.right_comm
... = (b + b) + (a - b) : by rewrite add_sub,
have H3 : (a + a) / 2 > ((b + b) + (a - b)) / 2,
from div_lt_div_of_lt_of_pos H2 two_pos,
by rewrite [one_add_one_eq_two, sub_eq_add_neg, add_self_div_two at H3, -div_add_div_same at H3, add_self_div_two at H3];
exact H3)
(div_pos_of_pos_of_pos (iff.mpr !sub_pos_iff_lt H) two_pos))
theorem ge_of_forall_ge_sub {a b : A} (H : Π ε : A, ε > 0 → a ≥ b - ε) : a ≥ b :=
begin
apply le_of_not_gt,
intro Hb,
cases exists_add_lt_prod_pos_of_lt Hb with [c, Hc],
let Hc' := H c (prod.pr2 Hc),
apply (not_le_of_gt (prod.pr1 Hc)) (iff.mpr !le_add_iff_sub_right_le Hc')
end
end linear_ordered_field
structure discrete_linear_ordered_field [class] (A : Type) extends linear_ordered_field A,
decidable_linear_ordered_comm_ring A :=
(inv_zero : inv zero = zero)
section discrete_linear_ordered_field
variable {A : Type}
variables [s : discrete_linear_ordered_field A] {a b c : A}
include s
definition dec_eq_of_dec_lt : Π x y : A, decidable (x = y) :=
take x y,
decidable.by_cases
(assume H : x < y, decidable.inr (ne_of_lt H))
(assume H : ¬ x < y,
decidable.by_cases
(assume H' : y < x, decidable.inr (ne.symm (ne_of_lt H')))
(assume H' : ¬ y < x,
decidable.inl (le.antisymm (le_of_not_gt H') (le_of_not_gt H))))
definition discrete_linear_ordered_field.to_discrete_field [trans_instance] : discrete_field A :=
⦃ discrete_field, s, has_decidable_eq := dec_eq_of_dec_lt⦄
theorem pos_of_one_div_pos (H : 0 < 1 / a) : 0 < a :=
have H1 : 0 < 1 / (1 / a), from one_div_pos_of_pos H,
have H2 : 1 / a ≠ 0, from
(assume H3 : 1 / a = 0,
have H4 : 1 / (1 / a) = 0, from H3⁻¹ ▸ !div_zero,
absurd H4 (ne.symm (ne_of_lt H1))),
(division_ring.one_div_one_div (ne_zero_of_one_div_ne_zero H2)) ▸ H1
theorem neg_of_one_div_neg (H : 1 / a < 0) : a < 0 :=
have H1 : 0 < - (1 / a), from neg_pos_of_neg H,
have Ha : a ≠ 0, from ne_zero_of_one_div_ne_zero (ne_of_lt H),
have H2 : 0 < 1 / (-a), from (division_ring.one_div_neg_eq_neg_one_div Ha)⁻¹ ▸ H1,
have H3 : 0 < -a, from pos_of_one_div_pos H2,
neg_of_neg_pos H3
theorem le_of_one_div_le_one_div (H : 0 < a) (Hl : 1 / a ≤ 1 / b) : b ≤ a :=
have Hb : 0 < b, from pos_of_one_div_pos (calc
0 < 1 / a : one_div_pos_of_pos H
... ≤ 1 / b : Hl),
have H' : 1 ≤ a / b, from (calc
1 = a / a : div_self (ne.symm (ne_of_lt H))
... = a * (1 / a) : div_eq_mul_one_div
... ≤ a * (1 / b) : mul_le_mul_of_nonneg_left Hl (le_of_lt H)
... = a / b : div_eq_mul_one_div
), le_of_one_le_div Hb H'
theorem le_of_one_div_le_one_div_of_neg (H : b < 0) (Hl : 1 / a ≤ 1 / b) : b ≤ a :=
have Ha : a ≠ 0, from ne_of_lt (neg_of_one_div_neg (calc
1 / a ≤ 1 / b : Hl
... < 0 : one_div_neg_of_neg H)),
have H' : -b > 0, from neg_pos_of_neg H,
have Hl' : - (1 / b) ≤ - (1 / a), from neg_le_neg Hl,
have Hl'' : 1 / - b ≤ 1 / - a, from calc
1 / -b = - (1 / b) : by rewrite [division_ring.one_div_neg_eq_neg_one_div (ne_of_lt H)]
... ≤ - (1 / a) : Hl'
... = 1 / -a : by rewrite [division_ring.one_div_neg_eq_neg_one_div Ha],
le_of_neg_le_neg (le_of_one_div_le_one_div H' Hl'')
theorem lt_of_one_div_lt_one_div (H : 0 < a) (Hl : 1 / a < 1 / b) : b < a :=
have Hb : 0 < b, from pos_of_one_div_pos (calc
0 < 1 / a : one_div_pos_of_pos H
... < 1 / b : Hl),
have H : 1 < a / b, from (calc
1 = a / a : div_self (ne.symm (ne_of_lt H))
... = a * (1 / a) : div_eq_mul_one_div
... < a * (1 / b) : mul_lt_mul_of_pos_left Hl H
... = a / b : div_eq_mul_one_div),
lt_of_one_lt_div Hb H
theorem lt_of_one_div_lt_one_div_of_neg (H : b < 0) (Hl : 1 / a < 1 / b) : b < a :=
have H1 : b ≤ a, from le_of_one_div_le_one_div_of_neg H (le_of_lt Hl),
have Hn : b ≠ a, from
(assume Hn' : b = a,
have Hl' : 1 / a = 1 / b, from Hn' ▸ refl _,
absurd Hl' (ne_of_lt Hl)),
lt_of_le_of_ne H1 Hn
theorem one_div_lt_one_div_of_lt (Ha : 0 < a) (H : a < b) : 1 / b < 1 / a :=
lt_of_not_ge
(assume H',
absurd H (not_lt_of_ge (le_of_one_div_le_one_div Ha H')))
theorem one_div_le_one_div_of_le (Ha : 0 < a) (H : a ≤ b) : 1 / b ≤ 1 / a :=
le_of_not_gt
(assume H',
absurd H (not_le_of_gt (lt_of_one_div_lt_one_div Ha H')))
theorem one_div_lt_one_div_of_lt_of_neg (Hb : b < 0) (H : a < b) : 1 / b < 1 / a :=
lt_of_not_ge
(assume H',
absurd H (not_lt_of_ge (le_of_one_div_le_one_div_of_neg Hb H')))
theorem one_div_le_one_div_of_le_of_neg (Hb : b < 0) (H : a ≤ b) : 1 / b ≤ 1 / a :=
le_of_not_gt
(assume H',
absurd H (not_le_of_gt (lt_of_one_div_lt_one_div_of_neg Hb H')))
theorem one_lt_one_div (H1 : 0 < a) (H2 : a < 1) : 1 < 1 / a :=
one_div_one ▸ one_div_lt_one_div_of_lt H1 H2
theorem one_le_one_div (H1 : 0 < a) (H2 : a ≤ 1) : 1 ≤ 1 / a :=
one_div_one ▸ one_div_le_one_div_of_le H1 H2
theorem one_div_lt_neg_one (H1 : a < 0) (H2 : -1 < a) : 1 / a < -1 :=
one_div_neg_one_eq_neg_one ▸ one_div_lt_one_div_of_lt_of_neg H1 H2
theorem one_div_le_neg_one (H1 : a < 0) (H2 : -1 ≤ a) : 1 / a ≤ -1 :=
one_div_neg_one_eq_neg_one ▸ one_div_le_one_div_of_le_of_neg H1 H2
theorem div_lt_div_of_pos_of_lt_of_pos (Hb : 0 < b) (H : b < a) (Hc : 0 < c) : c / a < c / b :=
begin
apply iff.mp !sub_neg_iff_lt,
rewrite [div_eq_mul_one_div, {c / b}div_eq_mul_one_div, -mul_sub_left_distrib],
apply mul_neg_of_pos_of_neg,
exact Hc,
apply iff.mpr !sub_neg_iff_lt,
apply one_div_lt_one_div_of_lt,
repeat assumption
end
theorem div_mul_le_div_mul_of_div_le_div_pos' {d e : A} (H : a / b ≤ c / d)
(He : e > 0) : a / (b * e) ≤ c / (d * e) :=
begin
rewrite [2 div_mul_eq_div_mul_one_div],
apply mul_le_mul_of_nonneg_right H,
apply le_of_lt,
apply one_div_pos_of_pos He
end
theorem abs_one_div (a : A) : abs (1 / a) = 1 / abs a :=
if H : a > 0 then
by rewrite [abs_of_pos H, abs_of_pos (one_div_pos_of_pos H)]
else
(if H' : a < 0 then
by rewrite [abs_of_neg H', abs_of_neg (one_div_neg_of_neg H'),
-(division_ring.one_div_neg_eq_neg_one_div (ne_of_lt H'))]
else
have Heq : a = 0, from eq_of_le_of_ge (le_of_not_gt H) (le_of_not_gt H'),
by rewrite [Heq, div_zero, *abs_zero, div_zero])
theorem sign_eq_div_abs (a : A) : sign a = a / (abs a) :=
decidable.by_cases
(suppose a = 0, by subst a; rewrite [zero_div, sign_zero])
(suppose a ≠ 0,
have abs a ≠ 0, from assume H, this (eq_zero_of_abs_eq_zero H),
!eq_div_of_mul_eq this !eq_sign_mul_abs⁻¹)
end discrete_linear_ordered_field
end algebra

View file

@ -1,869 +0,0 @@
/-
Copyright (c) 2014 Jeremy Avigad. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Jeremy Avigad
Partially ordered additive groups, modeled on Isabelle's library. These classes can be refined
if necessary.
-/
import algebra.binary algebra.group algebra.order
open eq eq.ops algebra -- note: ⁻¹ will be overloaded
set_option class.force_new true
variable {A : Type}
/- partially ordered monoids, such as the natural numbers -/
namespace algebra
structure ordered_mul_cancel_comm_monoid [class] (A : Type) extends comm_monoid A,
left_cancel_semigroup A, right_cancel_semigroup A, order_pair A :=
(mul_le_mul_left : Πa b, le a b → Πc, le (mul c a) (mul c b))
(le_of_mul_le_mul_left : Πa b c, le (mul a b) (mul a c) → le b c)
(mul_lt_mul_left : Πa b, lt a b → Πc, lt (mul c a) (mul c b))
(lt_of_mul_lt_mul_left : Πa b c, lt (mul a b) (mul a c) → lt b c)
definition ordered_cancel_comm_monoid [class] : Type → Type := ordered_mul_cancel_comm_monoid
definition add_comm_monoid_of_ordered_cancel_comm_monoid [reducible] [trans_instance]
(A : Type) [H : ordered_cancel_comm_monoid A] : add_comm_monoid A :=
@ordered_mul_cancel_comm_monoid.to_comm_monoid A H
definition add_left_cancel_semigroup_of_ordered_cancel_comm_monoid [reducible] [trans_instance]
(A : Type) [H : ordered_cancel_comm_monoid A] : add_left_cancel_semigroup A :=
@ordered_mul_cancel_comm_monoid.to_left_cancel_semigroup A H
definition add_right_cancel_semigroup_of_ordered_cancel_comm_monoid [reducible] [trans_instance]
(A : Type) [H : ordered_cancel_comm_monoid A] : add_right_cancel_semigroup A :=
@ordered_mul_cancel_comm_monoid.to_right_cancel_semigroup A H
definition order_pair_of_ordered_cancel_comm_monoid [reducible] [trans_instance]
(A : Type) [H : ordered_cancel_comm_monoid A] : order_pair A :=
@ordered_mul_cancel_comm_monoid.to_order_pair A H
section
variables [s : ordered_cancel_comm_monoid A]
variables {a b c d e : A}
include s
theorem add_lt_add_left (H : a < b) (c : A) : c + a < c + b :=
@ordered_mul_cancel_comm_monoid.mul_lt_mul_left A s a b H c
theorem add_lt_add_right (H : a < b) (c : A) : a + c < b + c :=
begin
rewrite [add.comm, {b + _}add.comm],
exact (add_lt_add_left H c)
end
theorem add_le_add_left (H : a ≤ b) (c : A) : c + a ≤ c + b :=
@ordered_mul_cancel_comm_monoid.mul_le_mul_left A s a b H c
theorem add_le_add_right (H : a ≤ b) (c : A) : a + c ≤ b + c :=
(add.comm c a) ▸ (add.comm c b) ▸ (add_le_add_left H c)
theorem add_le_add (Hab : a ≤ b) (Hcd : c ≤ d) : a + c ≤ b + d :=
le.trans (add_le_add_right Hab c) (add_le_add_left Hcd b)
theorem le_add_of_nonneg_right (H : b ≥ 0) : a ≤ a + b :=
begin
have H1 : a + b ≥ a + 0, from add_le_add_left H a,
rewrite add_zero at H1,
exact H1
end
theorem le_add_of_nonneg_left (H : b ≥ 0) : a ≤ b + a :=
begin
have H1 : 0 + a ≤ b + a, from add_le_add_right H a,
rewrite zero_add at H1,
exact H1
end
theorem add_lt_add (Hab : a < b) (Hcd : c < d) : a + c < b + d :=
lt.trans (add_lt_add_right Hab c) (add_lt_add_left Hcd b)
theorem add_lt_add_of_le_of_lt (Hab : a ≤ b) (Hcd : c < d) : a + c < b + d :=
lt_of_le_of_lt (add_le_add_right Hab c) (add_lt_add_left Hcd b)
theorem add_lt_add_of_lt_of_le (Hab : a < b) (Hcd : c ≤ d) : a + c < b + d :=
lt_of_lt_of_le (add_lt_add_right Hab c) (add_le_add_left Hcd b)
theorem lt_add_of_pos_right (H : b > 0) : a < a + b := !add_zero ▸ add_lt_add_left H a
theorem lt_add_of_pos_left (H : b > 0) : a < b + a := !zero_add ▸ add_lt_add_right H a
-- here we start using le_of_add_le_add_left.
theorem le_of_add_le_add_left (H : a + b ≤ a + c) : b ≤ c :=
@ordered_mul_cancel_comm_monoid.le_of_mul_le_mul_left A s a b c H
theorem le_of_add_le_add_right (H : a + b ≤ c + b) : a ≤ c :=
le_of_add_le_add_left (show b + a ≤ b + c, begin rewrite [add.comm, {b + _}add.comm], exact H end)
theorem lt_of_add_lt_add_left (H : a + b < a + c) : b < c :=
@ordered_mul_cancel_comm_monoid.lt_of_mul_lt_mul_left A s a b c H
theorem lt_of_add_lt_add_right (H : a + b < c + b) : a < c :=
lt_of_add_lt_add_left ((add.comm a b) ▸ (add.comm c b) ▸ H)
theorem add_le_add_left_iff (a b c : A) : a + b ≤ a + c ↔ b ≤ c :=
iff.intro le_of_add_le_add_left (assume H, add_le_add_left H _)
theorem add_le_add_right_iff (a b c : A) : a + b ≤ c + b ↔ a ≤ c :=
iff.intro le_of_add_le_add_right (assume H, add_le_add_right H _)
theorem add_lt_add_left_iff (a b c : A) : a + b < a + c ↔ b < c :=
iff.intro lt_of_add_lt_add_left (assume H, add_lt_add_left H _)
theorem add_lt_add_right_iff (a b c : A) : a + b < c + b ↔ a < c :=
iff.intro lt_of_add_lt_add_right (assume H, add_lt_add_right H _)
-- here we start using properties of zero.
theorem add_nonneg (Ha : 0 ≤ a) (Hb : 0 ≤ b) : 0 ≤ a + b :=
!zero_add ▸ (add_le_add Ha Hb)
theorem add_pos (Ha : 0 < a) (Hb : 0 < b) : 0 < a + b :=
!zero_add ▸ (add_lt_add Ha Hb)
theorem add_pos_of_pos_of_nonneg (Ha : 0 < a) (Hb : 0 ≤ b) : 0 < a + b :=
!zero_add ▸ (add_lt_add_of_lt_of_le Ha Hb)
theorem add_pos_of_nonneg_of_pos (Ha : 0 ≤ a) (Hb : 0 < b) : 0 < a + b :=
!zero_add ▸ (add_lt_add_of_le_of_lt Ha Hb)
theorem add_nonpos (Ha : a ≤ 0) (Hb : b ≤ 0) : a + b ≤ 0 :=
!zero_add ▸ (add_le_add Ha Hb)
theorem add_neg (Ha : a < 0) (Hb : b < 0) : a + b < 0 :=
!zero_add ▸ (add_lt_add Ha Hb)
theorem add_neg_of_neg_of_nonpos (Ha : a < 0) (Hb : b ≤ 0) : a + b < 0 :=
!zero_add ▸ (add_lt_add_of_lt_of_le Ha Hb)
theorem add_neg_of_nonpos_of_neg (Ha : a ≤ 0) (Hb : b < 0) : a + b < 0 :=
!zero_add ▸ (add_lt_add_of_le_of_lt Ha Hb)
-- TODO: add nonpos version (will be easier with simplifier)
theorem add_eq_zero_iff_eq_zero_prod_eq_zero_of_nonneg_of_nonneg
(Ha : 0 ≤ a) (Hb : 0 ≤ b) : a + b = 0 ↔ a = 0 × b = 0 :=
iff.intro
(assume Hab : a + b = 0,
have Ha' : a ≤ 0, from
calc
a = a + 0 : by rewrite add_zero
... ≤ a + b : add_le_add_left Hb
... = 0 : Hab,
have Haz : a = 0, from le.antisymm Ha' Ha,
have Hb' : b ≤ 0, from
calc
b = 0 + b : by rewrite zero_add
... ≤ a + b : by exact add_le_add_right Ha _
... = 0 : Hab,
have Hbz : b = 0, from le.antisymm Hb' Hb,
pair Haz Hbz)
(assume Hab : a = 0 × b = 0,
obtain Ha' Hb', from Hab,
by rewrite [Ha', Hb', add_zero])
theorem le_add_of_nonneg_of_le (Ha : 0 ≤ a) (Hbc : b ≤ c) : b ≤ a + c :=
!zero_add ▸ add_le_add Ha Hbc
theorem le_add_of_le_of_nonneg (Hbc : b ≤ c) (Ha : 0 ≤ a) : b ≤ c + a :=
!add_zero ▸ add_le_add Hbc Ha
theorem lt_add_of_pos_of_le (Ha : 0 < a) (Hbc : b ≤ c) : b < a + c :=
!zero_add ▸ add_lt_add_of_lt_of_le Ha Hbc
theorem lt_add_of_le_of_pos (Hbc : b ≤ c) (Ha : 0 < a) : b < c + a :=
!add_zero ▸ add_lt_add_of_le_of_lt Hbc Ha
theorem add_le_of_nonpos_of_le (Ha : a ≤ 0) (Hbc : b ≤ c) : a + b ≤ c :=
!zero_add ▸ add_le_add Ha Hbc
theorem add_le_of_le_of_nonpos (Hbc : b ≤ c) (Ha : a ≤ 0) : b + a ≤ c :=
!add_zero ▸ add_le_add Hbc Ha
theorem add_lt_of_neg_of_le (Ha : a < 0) (Hbc : b ≤ c) : a + b < c :=
!zero_add ▸ add_lt_add_of_lt_of_le Ha Hbc
theorem add_lt_of_le_of_neg (Hbc : b ≤ c) (Ha : a < 0) : b + a < c :=
!add_zero ▸ add_lt_add_of_le_of_lt Hbc Ha
theorem lt_add_of_nonneg_of_lt (Ha : 0 ≤ a) (Hbc : b < c) : b < a + c :=
!zero_add ▸ add_lt_add_of_le_of_lt Ha Hbc
theorem lt_add_of_lt_of_nonneg (Hbc : b < c) (Ha : 0 ≤ a) : b < c + a :=
!add_zero ▸ add_lt_add_of_lt_of_le Hbc Ha
theorem lt_add_of_pos_of_lt (Ha : 0 < a) (Hbc : b < c) : b < a + c :=
!zero_add ▸ add_lt_add Ha Hbc
theorem lt_add_of_lt_of_pos (Hbc : b < c) (Ha : 0 < a) : b < c + a :=
!add_zero ▸ add_lt_add Hbc Ha
theorem add_lt_of_nonpos_of_lt (Ha : a ≤ 0) (Hbc : b < c) : a + b < c :=
!zero_add ▸ add_lt_add_of_le_of_lt Ha Hbc
theorem add_lt_of_lt_of_nonpos (Hbc : b < c) (Ha : a ≤ 0) : b + a < c :=
!add_zero ▸ add_lt_add_of_lt_of_le Hbc Ha
theorem add_lt_of_neg_of_lt (Ha : a < 0) (Hbc : b < c) : a + b < c :=
!zero_add ▸ add_lt_add Ha Hbc
theorem add_lt_of_lt_of_neg (Hbc : b < c) (Ha : a < 0) : b + a < c :=
!add_zero ▸ add_lt_add Hbc Ha
end
/- partially ordered groups -/
structure ordered_mul_ab_group [class] (A : Type) extends ab_group A, order_pair A :=
(mul_le_mul_left : Πa b, le a b → Πc, le (mul c a) (mul c b))
(mul_lt_mul_left : Πa b, lt a b → Π c, lt (mul c a) (mul c b))
definition ordered_ab_group [class] : Type → Type := ordered_mul_ab_group
definition add_ab_group_of_ordered_ab_group [reducible] [trans_instance] (A : Type)
[H : ordered_ab_group A] : add_ab_group A :=
@ordered_mul_ab_group.to_ab_group A H
theorem ordered_mul_ab_group.le_of_mul_le_mul_left [s : ordered_mul_ab_group A] {a b c : A}
(H : a * b ≤ a * c) : b ≤ c :=
have H' : a⁻¹ * (a * b) ≤ a⁻¹ * (a * c), from ordered_mul_ab_group.mul_le_mul_left _ _ H _,
by rewrite *inv_mul_cancel_left at H'; exact H'
theorem ordered_mul_ab_group.lt_of_mul_lt_mul_left [s : ordered_mul_ab_group A] {a b c : A}
(H : a * b < a * c) : b < c :=
have H' : a⁻¹ * (a * b) < a⁻¹ * (a * c), from ordered_mul_ab_group.mul_lt_mul_left _ _ H _,
by rewrite *inv_mul_cancel_left at H'; exact H'
definition ordered_mul_ab_group.to_ordered_mul_cancel_comm_monoid [reducible] [trans_instance]
[s : ordered_mul_ab_group A] : ordered_mul_cancel_comm_monoid A :=
⦃ ordered_mul_cancel_comm_monoid, s,
mul_left_cancel := @mul.left_cancel A _,
mul_right_cancel := @mul.right_cancel A _,
le_of_mul_le_mul_left := @ordered_mul_ab_group.le_of_mul_le_mul_left A _,
lt_of_mul_lt_mul_left := @ordered_mul_ab_group.lt_of_mul_lt_mul_left A _⦄
definition ordered_ab_group.to_ordered_cancel_comm_monoid [reducible] [trans_instance]
[s : ordered_ab_group A] : ordered_cancel_comm_monoid A :=
@ordered_mul_ab_group.to_ordered_mul_cancel_comm_monoid A s
section
variables [s : ordered_ab_group A] (a b c d e : A)
include s
theorem neg_le_neg {a b : A} (H : a ≤ b) : -b ≤ -a :=
have H1 : 0 ≤ -a + b, from !add.left_inv ▸ !(add_le_add_left H),
!add_neg_cancel_right ▸ !zero_add ▸ add_le_add_right H1 (-b)
theorem le_of_neg_le_neg {a b : A} (H : -b ≤ -a) : a ≤ b :=
neg_neg a ▸ neg_neg b ▸ neg_le_neg H
theorem neg_le_neg_iff_le : -a ≤ -b ↔ b ≤ a :=
iff.intro le_of_neg_le_neg neg_le_neg
theorem nonneg_of_neg_nonpos {a : A} (H : -a ≤ 0) : 0 ≤ a :=
le_of_neg_le_neg (neg_zero⁻¹ ▸ H)
theorem neg_nonpos_of_nonneg {a : A} (H : 0 ≤ a) : -a ≤ 0 :=
neg_zero ▸ neg_le_neg H
theorem neg_nonpos_iff_nonneg : -a ≤ 0 ↔ 0 ≤ a :=
iff.intro nonneg_of_neg_nonpos neg_nonpos_of_nonneg
theorem nonpos_of_neg_nonneg {a : A} (H : 0 ≤ -a) : a ≤ 0 :=
le_of_neg_le_neg (neg_zero⁻¹ ▸ H)
theorem neg_nonneg_of_nonpos {a : A} (H : a ≤ 0) : 0 ≤ -a :=
neg_zero ▸ neg_le_neg H
theorem neg_nonneg_iff_nonpos : 0 ≤ -a ↔ a ≤ 0 :=
iff.intro nonpos_of_neg_nonneg neg_nonneg_of_nonpos
theorem neg_lt_neg {a b : A} (H : a < b) : -b < -a :=
have H1 : 0 < -a + b, from !add.left_inv ▸ !(add_lt_add_left H),
!add_neg_cancel_right ▸ !zero_add ▸ add_lt_add_right H1 (-b)
theorem lt_of_neg_lt_neg {a b : A} (H : -b < -a) : a < b :=
neg_neg a ▸ neg_neg b ▸ neg_lt_neg H
theorem neg_lt_neg_iff_lt : -a < -b ↔ b < a :=
iff.intro lt_of_neg_lt_neg neg_lt_neg
theorem pos_of_neg_neg {a : A} (H : -a < 0) : 0 < a :=
lt_of_neg_lt_neg (neg_zero⁻¹ ▸ H)
theorem neg_neg_of_pos {a : A} (H : 0 < a) : -a < 0 :=
neg_zero ▸ neg_lt_neg H
theorem neg_neg_iff_pos : -a < 0 ↔ 0 < a :=
iff.intro pos_of_neg_neg neg_neg_of_pos
theorem neg_of_neg_pos {a : A} (H : 0 < -a) : a < 0 :=
lt_of_neg_lt_neg (neg_zero⁻¹ ▸ H)
theorem neg_pos_of_neg {a : A} (H : a < 0) : 0 < -a :=
neg_zero ▸ neg_lt_neg H
theorem neg_pos_iff_neg : 0 < -a ↔ a < 0 :=
iff.intro neg_of_neg_pos neg_pos_of_neg
theorem le_neg_iff_le_neg : a ≤ -b ↔ b ≤ -a := !neg_neg ▸ !neg_le_neg_iff_le
theorem le_neg_of_le_neg {a b : A} : a ≤ -b → b ≤ -a := iff.mp !le_neg_iff_le_neg
theorem neg_le_iff_neg_le : -a ≤ b ↔ -b ≤ a := !neg_neg ▸ !neg_le_neg_iff_le
theorem neg_le_of_neg_le {a b : A} : -a ≤ b → -b ≤ a := iff.mp !neg_le_iff_neg_le
theorem lt_neg_iff_lt_neg : a < -b ↔ b < -a := !neg_neg ▸ !neg_lt_neg_iff_lt
theorem lt_neg_of_lt_neg {a b : A} : a < -b → b < -a := iff.mp !lt_neg_iff_lt_neg
theorem neg_lt_iff_neg_lt : -a < b ↔ -b < a := !neg_neg ▸ !neg_lt_neg_iff_lt
theorem neg_lt_of_neg_lt {a b : A} : -a < b → -b < a := iff.mp !neg_lt_iff_neg_lt
theorem sub_nonneg_iff_le : 0 ≤ a - b ↔ b ≤ a := !sub_self ▸ !add_le_add_right_iff
theorem sub_nonneg_of_le {a b : A} : b ≤ a → 0 ≤ a - b := iff.mpr !sub_nonneg_iff_le
theorem le_of_sub_nonneg {a b : A} : 0 ≤ a - b → b ≤ a := iff.mp !sub_nonneg_iff_le
theorem sub_nonpos_iff_le : a - b ≤ 0 ↔ a ≤ b := !sub_self ▸ !add_le_add_right_iff
theorem sub_nonpos_of_le {a b : A} : a ≤ b → a - b ≤ 0 := iff.mpr !sub_nonpos_iff_le
theorem le_of_sub_nonpos {a b : A} : a - b ≤ 0 → a ≤ b := iff.mp !sub_nonpos_iff_le
theorem sub_pos_iff_lt : 0 < a - b ↔ b < a := !sub_self ▸ !add_lt_add_right_iff
theorem sub_pos_of_lt {a b : A} : b < a → 0 < a - b := iff.mpr !sub_pos_iff_lt
theorem lt_of_sub_pos {a b : A} : 0 < a - b → b < a := iff.mp !sub_pos_iff_lt
theorem sub_neg_iff_lt : a - b < 0 ↔ a < b := !sub_self ▸ !add_lt_add_right_iff
theorem sub_neg_of_lt {a b : A} : a < b → a - b < 0 := iff.mpr !sub_neg_iff_lt
theorem lt_of_sub_neg {a b : A} : a - b < 0 → a < b := iff.mp !sub_neg_iff_lt
theorem add_le_iff_le_neg_add : a + b ≤ c ↔ b ≤ -a + c :=
have H: a + b ≤ c ↔ -a + (a + b) ≤ -a + c, from iff.symm (!add_le_add_left_iff),
!neg_add_cancel_left ▸ H
theorem add_le_of_le_neg_add {a b c : A} : b ≤ -a + c → a + b ≤ c :=
iff.mpr !add_le_iff_le_neg_add
theorem le_neg_add_of_add_le {a b c : A} : a + b ≤ c → b ≤ -a + c :=
iff.mp !add_le_iff_le_neg_add
theorem add_le_iff_le_sub_left : a + b ≤ c ↔ b ≤ c - a :=
by rewrite [sub_eq_add_neg, {c+_}add.comm]; apply add_le_iff_le_neg_add
theorem add_le_of_le_sub_left {a b c : A} : b ≤ c - a → a + b ≤ c :=
iff.mpr !add_le_iff_le_sub_left
theorem le_sub_left_of_add_le {a b c : A} : a + b ≤ c → b ≤ c - a :=
iff.mp !add_le_iff_le_sub_left
theorem add_le_iff_le_sub_right : a + b ≤ c ↔ a ≤ c - b :=
have H: a + b ≤ c ↔ a + b - b ≤ c - b, from iff.symm (!add_le_add_right_iff),
!add_neg_cancel_right ▸ H
theorem add_le_of_le_sub_right {a b c : A} : a ≤ c - b → a + b ≤ c :=
iff.mpr !add_le_iff_le_sub_right
theorem le_sub_right_of_add_le {a b c : A} : a + b ≤ c → a ≤ c - b :=
iff.mp !add_le_iff_le_sub_right
theorem le_add_iff_neg_add_le : a ≤ b + c ↔ -b + a ≤ c :=
have H: a ≤ b + c ↔ -b + a ≤ -b + (b + c), from iff.symm (!add_le_add_left_iff),
by rewrite neg_add_cancel_left at H; exact H
theorem le_add_of_neg_add_le {a b c : A} : -b + a ≤ c → a ≤ b + c :=
iff.mpr !le_add_iff_neg_add_le
theorem neg_add_le_of_le_add {a b c : A} : a ≤ b + c → -b + a ≤ c :=
iff.mp !le_add_iff_neg_add_le
theorem le_add_iff_sub_left_le : a ≤ b + c ↔ a - b ≤ c :=
by rewrite [sub_eq_add_neg, {a+_}add.comm]; apply le_add_iff_neg_add_le
theorem le_add_of_sub_left_le {a b c : A} : a - b ≤ c → a ≤ b + c :=
iff.mpr !le_add_iff_sub_left_le
theorem sub_left_le_of_le_add {a b c : A} : a ≤ b + c → a - b ≤ c :=
iff.mp !le_add_iff_sub_left_le
theorem le_add_iff_sub_right_le : a ≤ b + c ↔ a - c ≤ b :=
have H: a ≤ b + c ↔ a - c ≤ b + c - c, from iff.symm (!add_le_add_right_iff),
by rewrite [sub_eq_add_neg (b+c) c at H, add_neg_cancel_right at H]; exact H
theorem le_add_of_sub_right_le {a b c : A} : a - c ≤ b → a ≤ b + c :=
iff.mpr !le_add_iff_sub_right_le
theorem sub_right_le_of_le_add {a b c : A} : a ≤ b + c → a - c ≤ b :=
iff.mp !le_add_iff_sub_right_le
theorem le_add_iff_neg_add_le_left : a ≤ b + c ↔ -b + a ≤ c :=
have H: a ≤ b + c ↔ -b + a ≤ -b + (b + c), from iff.symm (!add_le_add_left_iff),
by rewrite neg_add_cancel_left at H; exact H
theorem le_add_of_neg_add_le_left {a b c : A} : -b + a ≤ c → a ≤ b + c :=
iff.mpr !le_add_iff_neg_add_le_left
theorem neg_add_le_left_of_le_add {a b c : A} : a ≤ b + c → -b + a ≤ c :=
iff.mp !le_add_iff_neg_add_le_left
theorem le_add_iff_neg_add_le_right : a ≤ b + c ↔ -c + a ≤ b :=
by rewrite add.comm; apply le_add_iff_neg_add_le_left
theorem le_add_of_neg_add_le_right {a b c : A} : -c + a ≤ b → a ≤ b + c :=
iff.mpr !le_add_iff_neg_add_le_right
theorem neg_add_le_right_of_le_add {a b c : A} : a ≤ b + c → -c + a ≤ b :=
iff.mp !le_add_iff_neg_add_le_right
theorem le_add_iff_neg_le_sub_left : c ≤ a + b ↔ -a ≤ b - c :=
have H : c ≤ a + b ↔ -a + c ≤ b, from !le_add_iff_neg_add_le,
have H' : -a + c ≤ b ↔ -a ≤ b - c, from !add_le_iff_le_sub_right,
iff.trans H H'
theorem le_add_of_neg_le_sub_left {a b c : A} : -a ≤ b - c → c ≤ a + b :=
iff.mpr !le_add_iff_neg_le_sub_left
theorem neg_le_sub_left_of_le_add {a b c : A} : c ≤ a + b → -a ≤ b - c :=
iff.mp !le_add_iff_neg_le_sub_left
theorem le_add_iff_neg_le_sub_right : c ≤ a + b ↔ -b ≤ a - c :=
by rewrite add.comm; apply le_add_iff_neg_le_sub_left
theorem le_add_of_neg_le_sub_right {a b c : A} : -b ≤ a - c → c ≤ a + b :=
iff.mpr !le_add_iff_neg_le_sub_right
theorem neg_le_sub_right_of_le_add {a b c : A} : c ≤ a + b → -b ≤ a - c :=
iff.mp !le_add_iff_neg_le_sub_right
theorem add_lt_iff_lt_neg_add_left : a + b < c ↔ b < -a + c :=
have H: a + b < c ↔ -a + (a + b) < -a + c, from iff.symm (!add_lt_add_left_iff),
begin rewrite neg_add_cancel_left at H, exact H end
theorem add_lt_of_lt_neg_add_left {a b c : A} : b < -a + c → a + b < c :=
iff.mpr !add_lt_iff_lt_neg_add_left
theorem lt_neg_add_left_of_add_lt {a b c : A} : a + b < c → b < -a + c :=
iff.mp !add_lt_iff_lt_neg_add_left
theorem add_lt_iff_lt_neg_add_right : a + b < c ↔ a < -b + c :=
by rewrite add.comm; apply add_lt_iff_lt_neg_add_left
theorem add_lt_of_lt_neg_add_right {a b c : A} : a < -b + c → a + b < c :=
iff.mpr !add_lt_iff_lt_neg_add_right
theorem lt_neg_add_right_of_add_lt {a b c : A} : a + b < c → a < -b + c :=
iff.mp !add_lt_iff_lt_neg_add_right
theorem add_lt_iff_lt_sub_left : a + b < c ↔ b < c - a :=
begin
rewrite [sub_eq_add_neg, {c+_}add.comm],
apply add_lt_iff_lt_neg_add_left
end
theorem add_lt_of_lt_sub_left {a b c : A} : b < c - a → a + b < c :=
iff.mpr !add_lt_iff_lt_sub_left
theorem lt_sub_left_of_add_lt {a b c : A} : a + b < c → b < c - a :=
iff.mp !add_lt_iff_lt_sub_left
theorem add_lt_iff_lt_sub_right : a + b < c ↔ a < c - b :=
have H: a + b < c ↔ a + b - b < c - b, from iff.symm (!add_lt_add_right_iff),
by rewrite [sub_eq_add_neg at H, add_neg_cancel_right at H]; exact H
theorem add_lt_of_lt_sub_right {a b c : A} : a < c - b → a + b < c :=
iff.mpr !add_lt_iff_lt_sub_right
theorem lt_sub_right_of_add_lt {a b c : A} : a + b < c → a < c - b :=
iff.mp !add_lt_iff_lt_sub_right
theorem lt_add_iff_neg_add_lt_left : a < b + c ↔ -b + a < c :=
have H: a < b + c ↔ -b + a < -b + (b + c), from iff.symm (!add_lt_add_left_iff),
by rewrite neg_add_cancel_left at H; exact H
theorem lt_add_of_neg_add_lt_left {a b c : A} : -b + a < c → a < b + c :=
iff.mpr !lt_add_iff_neg_add_lt_left
theorem neg_add_lt_left_of_lt_add {a b c : A} : a < b + c → -b + a < c :=
iff.mp !lt_add_iff_neg_add_lt_left
theorem lt_add_iff_neg_add_lt_right : a < b + c ↔ -c + a < b :=
by rewrite add.comm; apply lt_add_iff_neg_add_lt_left
theorem lt_add_of_neg_add_lt_right {a b c : A} : -c + a < b → a < b + c :=
iff.mpr !lt_add_iff_neg_add_lt_right
theorem neg_add_lt_right_of_lt_add {a b c : A} : a < b + c → -c + a < b :=
iff.mp !lt_add_iff_neg_add_lt_right
theorem lt_add_iff_sub_lt_left : a < b + c ↔ a - b < c :=
by rewrite [sub_eq_add_neg, {a + _}add.comm]; apply lt_add_iff_neg_add_lt_left
theorem lt_add_of_sub_lt_left {a b c : A} : a - b < c → a < b + c :=
iff.mpr !lt_add_iff_sub_lt_left
theorem sub_lt_left_of_lt_add {a b c : A} : a < b + c → a - b < c :=
iff.mp !lt_add_iff_sub_lt_left
theorem lt_add_iff_sub_lt_right : a < b + c ↔ a - c < b :=
by rewrite add.comm; apply lt_add_iff_sub_lt_left
theorem lt_add_of_sub_lt_right {a b c : A} : a - c < b → a < b + c :=
iff.mpr !lt_add_iff_sub_lt_right
theorem sub_lt_right_of_lt_add {a b c : A} : a < b + c → a - c < b :=
iff.mp !lt_add_iff_sub_lt_right
theorem sub_lt_of_sub_lt {a b c : A} : a - b < c → a - c < b :=
begin
intro H,
apply sub_lt_left_of_lt_add,
apply lt_add_of_sub_lt_right H
end
theorem sub_le_of_sub_le {a b c : A} : a - b ≤ c → a - c ≤ b :=
begin
intro H,
apply sub_left_le_of_le_add,
apply le_add_of_sub_right_le H
end
-- TODO: the Isabelle library has varations on a + b ≤ b ↔ a ≤ 0
theorem le_iff_le_of_sub_eq_sub {a b c d : A} (H : a - b = c - d) : a ≤ b ↔ c ≤ d :=
calc
a ≤ b ↔ a - b ≤ 0 : iff.symm (sub_nonpos_iff_le a b)
... = (c - d ≤ 0) : by rewrite H
... ↔ c ≤ d : sub_nonpos_iff_le c d
theorem lt_iff_lt_of_sub_eq_sub {a b c d : A} (H : a - b = c - d) : a < b ↔ c < d :=
calc
a < b ↔ a - b < 0 : iff.symm (sub_neg_iff_lt a b)
... = (c - d < 0) : by rewrite H
... ↔ c < d : sub_neg_iff_lt c d
theorem sub_le_sub_left {a b : A} (H : a ≤ b) (c : A) : c - b ≤ c - a :=
add_le_add_left (neg_le_neg H) c
theorem sub_le_sub_right {a b : A} (H : a ≤ b) (c : A) : a - c ≤ b - c := add_le_add_right H (-c)
theorem sub_le_sub {a b c d : A} (Hab : a ≤ b) (Hcd : c ≤ d) : a - d ≤ b - c :=
add_le_add Hab (neg_le_neg Hcd)
theorem sub_lt_sub_left {a b : A} (H : a < b) (c : A) : c - b < c - a :=
add_lt_add_left (neg_lt_neg H) c
theorem sub_lt_sub_right {a b : A} (H : a < b) (c : A) : a - c < b - c := add_lt_add_right H (-c)
theorem sub_lt_sub {a b c d : A} (Hab : a < b) (Hcd : c < d) : a - d < b - c :=
add_lt_add Hab (neg_lt_neg Hcd)
theorem sub_lt_sub_of_le_of_lt {a b c d : A} (Hab : a ≤ b) (Hcd : c < d) : a - d < b - c :=
add_lt_add_of_le_of_lt Hab (neg_lt_neg Hcd)
theorem sub_lt_sub_of_lt_of_le {a b c d : A} (Hab : a < b) (Hcd : c ≤ d) : a - d < b - c :=
add_lt_add_of_lt_of_le Hab (neg_le_neg Hcd)
theorem sub_le_self (a : A) {b : A} (H : b ≥ 0) : a - b ≤ a :=
calc
a - b = a + -b : rfl
... ≤ a + 0 : add_le_add_left (neg_nonpos_of_nonneg H)
... = a : by rewrite add_zero
theorem sub_lt_self (a : A) {b : A} (H : b > 0) : a - b < a :=
calc
a - b = a + -b : rfl
... < a + 0 : add_lt_add_left (neg_neg_of_pos H)
... = a : by rewrite add_zero
theorem add_le_add_three {a b c d e f : A} (H1 : a ≤ d) (H2 : b ≤ e) (H3 : c ≤ f) :
a + b + c ≤ d + e + f :=
begin
apply le.trans,
apply add_le_add,
apply add_le_add,
repeat assumption,
apply le.refl
end
theorem sub_le_of_nonneg {b : A} (H : b ≥ 0) : a - b ≤ a :=
add_le_of_le_of_nonpos (le.refl a) (neg_nonpos_of_nonneg H)
theorem sub_lt_of_pos {b : A} (H : b > 0) : a - b < a :=
add_lt_of_le_of_neg (le.refl a) (neg_neg_of_pos H)
theorem neg_add_neg_le_neg_of_pos {a : A} (H : a > 0) : -a + -a ≤ -a :=
!neg_add ▸ neg_le_neg (le_add_of_nonneg_left (le_of_lt H))
end
/- linear ordered group with decidable order -/
structure decidable_linear_ordered_mul_ab_group [class] (A : Type)
extends ab_group A, decidable_linear_order A :=
(mul_le_mul_left : Π a b, le a b → Π c, le (mul c a) (mul c b))
(mul_lt_mul_left : Π a b, lt a b → Π c, lt (mul c a) (mul c b))
definition decidable_linear_ordered_ab_group [class] : Type → Type :=
decidable_linear_ordered_mul_ab_group
definition add_ab_group_of_decidable_linear_ordered_ab_group [reducible] [trans_instance] (A : Type)
[H : decidable_linear_ordered_ab_group A] : add_ab_group A :=
@decidable_linear_ordered_mul_ab_group.to_ab_group A H
definition decidable_linear_order_of_decidable_linear_ordered_ab_group [reducible]
[trans_instance] (A : Type) [H : decidable_linear_ordered_ab_group A] :
decidable_linear_order A :=
@decidable_linear_ordered_mul_ab_group.to_decidable_linear_order A H
definition decidable_linear_ordered_mul_ab_group.to_ordered_mul_ab_group [reducible]
[trans_instance] (A : Type) [s : decidable_linear_ordered_mul_ab_group A] :
ordered_mul_ab_group A :=
⦃ ordered_mul_ab_group, s,
le_of_lt := @le_of_lt A _,
lt_of_le_of_lt := @lt_of_le_of_lt A _,
lt_of_lt_of_le := @lt_of_lt_of_le A _ ⦄
definition decidable_linear_ordered_ab_group.to_ordered_ab_group [reducible] [trans_instance]
(A : Type) [s : decidable_linear_ordered_ab_group A] : ordered_ab_group A :=
@decidable_linear_ordered_mul_ab_group.to_ordered_mul_ab_group A s
section
variables [s : decidable_linear_ordered_ab_group A]
variables {a b c d e : A}
include s
/- these can be generalized to a lattice ordered group -/
theorem min_add_add_left : min (a + b) (a + c) = a + min b c :=
inverse (eq_min
(show a + min b c ≤ a + b, from add_le_add_left !min_le_left _)
(show a + min b c ≤ a + c, from add_le_add_left !min_le_right _)
(take d,
assume H₁ : d ≤ a + b,
assume H₂ : d ≤ a + c,
have H : d - a ≤ min b c,
from le_min (iff.mp !le_add_iff_sub_left_le H₁) (iff.mp !le_add_iff_sub_left_le H₂),
show d ≤ a + min b c, from iff.mpr !le_add_iff_sub_left_le H))
theorem min_add_add_right : min (a + c) (b + c) = min a b + c :=
by rewrite [add.comm a c, add.comm b c, add.comm _ c]; apply min_add_add_left
theorem max_add_add_left : max (a + b) (a + c) = a + max b c :=
inverse (eq_max
(add_le_add_left !le_max_left _)
(add_le_add_left !le_max_right _)
(λ d H₁ H₂,
have H : max b c ≤ d - a,
from max_le (iff.mp !add_le_iff_le_sub_left H₁) (iff.mp !add_le_iff_le_sub_left H₂),
show a + max b c ≤ d, from iff.mpr !add_le_iff_le_sub_left H))
theorem max_add_add_right : max (a + c) (b + c) = max a b + c :=
by rewrite [add.comm a c, add.comm b c, add.comm _ c]; apply max_add_add_left
theorem max_neg_neg : max (-a) (-b) = - min a b :=
inverse (eq_max
(show -a ≤ -(min a b), from neg_le_neg !min_le_left)
(show -b ≤ -(min a b), from neg_le_neg !min_le_right)
(take d,
assume H₁ : -a ≤ d,
assume H₂ : -b ≤ d,
have H : -d ≤ min a b,
from le_min (!iff.mp !neg_le_iff_neg_le H₁) (!iff.mp !neg_le_iff_neg_le H₂),
show -(min a b) ≤ d, from !iff.mp !neg_le_iff_neg_le H))
theorem min_eq_neg_max_neg_neg : min a b = - max (-a) (-b) :=
by rewrite [max_neg_neg, neg_neg]
theorem min_neg_neg : min (-a) (-b) = - max a b :=
by rewrite [min_eq_neg_max_neg_neg, *neg_neg]
theorem max_eq_neg_min_neg_neg : max a b = - min (-a) (-b) :=
by rewrite [min_neg_neg, neg_neg]
/- absolute value -/
variables {a b c}
definition abs (a : A) : A := max a (-a)
theorem abs_of_nonneg (H : a ≥ 0) : abs a = a :=
have H' : -a ≤ a, from le.trans (neg_nonpos_of_nonneg H) H,
max_eq_left H'
theorem abs_of_pos (H : a > 0) : abs a = a :=
abs_of_nonneg (le_of_lt H)
theorem abs_of_nonpos (H : a ≤ 0) : abs a = -a :=
have H' : a ≤ -a, from le.trans H (neg_nonneg_of_nonpos H),
max_eq_right H'
theorem abs_of_neg (H : a < 0) : abs a = -a := abs_of_nonpos (le_of_lt H)
theorem abs_zero : abs 0 = (0:A) := abs_of_nonneg (le.refl _)
theorem abs_neg (a : A) : abs (-a) = abs a :=
by rewrite [↑abs, max.comm, neg_neg]
theorem abs_pos_of_pos (H : a > 0) : abs a > 0 :=
by rewrite (abs_of_pos H); exact H
theorem abs_pos_of_neg (H : a < 0) : abs a > 0 :=
!abs_neg ▸ abs_pos_of_pos (neg_pos_of_neg H)
theorem abs_sub (a b : A) : abs (a - b) = abs (b - a) :=
by rewrite [-neg_sub, abs_neg]
theorem ne_zero_of_abs_ne_zero {a : A} (H : abs a ≠ 0) : a ≠ 0 :=
assume Ha, H (Ha⁻¹ ▸ abs_zero)
/- these assume a linear order -/
theorem eq_zero_of_neg_eq (H : -a = a) : a = 0 :=
lt.by_cases
(assume H1 : a < 0,
have H2: a > 0, from H ▸ neg_pos_of_neg H1,
absurd H1 (lt.asymm H2))
(assume H1 : a = 0, H1)
(assume H1 : a > 0,
have H2: a < 0, from H ▸ neg_neg_of_pos H1,
absurd H1 (lt.asymm H2))
theorem abs_nonneg (a : A) : abs a ≥ 0 :=
sum.elim (le.total 0 a)
(assume H : 0 ≤ a, by rewrite (abs_of_nonneg H); exact H)
(assume H : a ≤ 0,
calc
0 ≤ -a : neg_nonneg_of_nonpos H
... = abs a : abs_of_nonpos H)
theorem abs_abs (a : A) : abs (abs a) = abs a := abs_of_nonneg !abs_nonneg
theorem le_abs_self (a : A) : a ≤ abs a :=
sum.elim (le.total 0 a)
(assume H : 0 ≤ a, abs_of_nonneg H ▸ !le.refl)
(assume H : a ≤ 0, le.trans H !abs_nonneg)
theorem neg_le_abs_self (a : A) : -a ≤ abs a :=
!abs_neg ▸ !le_abs_self
theorem eq_zero_of_abs_eq_zero (H : abs a = 0) : a = 0 :=
have H1 : a ≤ 0, from H ▸ le_abs_self a,
have H2 : -a ≤ 0, from H ▸ abs_neg a ▸ le_abs_self (-a),
le.antisymm H1 (nonneg_of_neg_nonpos H2)
theorem abs_eq_zero_iff_eq_zero (a : A) : abs a = 0 ↔ a = 0 :=
iff.intro eq_zero_of_abs_eq_zero (assume H, ap abs H ⬝ !abs_zero)
theorem eq_of_abs_sub_eq_zero {a b : A} (H : abs (a - b) = 0) : a = b :=
have a - b = 0, from eq_zero_of_abs_eq_zero H,
show a = b, from eq_of_sub_eq_zero this
theorem abs_pos_of_ne_zero (H : a ≠ 0) : abs a > 0 :=
sum.elim (lt_sum_gt_of_ne H) abs_pos_of_neg abs_pos_of_pos
theorem abs.by_cases {P : A → Type} {a : A} (H1 : P a) (H2 : P (-a)) : P (abs a) :=
sum.elim (le.total 0 a)
(assume H : 0 ≤ a, (abs_of_nonneg H)⁻¹ ▸ H1)
(assume H : a ≤ 0, (abs_of_nonpos H)⁻¹ ▸ H2)
theorem abs_le_of_le_of_neg_le (H1 : a ≤ b) (H2 : -a ≤ b) : abs a ≤ b :=
abs.by_cases H1 H2
theorem abs_lt_of_lt_of_neg_lt (H1 : a < b) (H2 : -a < b) : abs a < b :=
abs.by_cases H1 H2
-- the triangle inequality
section
private lemma aux1 {a b : A} (H1 : a + b ≥ 0) (H2 : a ≥ 0) : abs (a + b) ≤ abs a + abs b :=
decidable.by_cases
(assume H3 : b ≥ 0,
calc
abs (a + b) ≤ abs (a + b) : le.refl
... = a + b : by rewrite (abs_of_nonneg H1)
... = abs a + b : by rewrite (abs_of_nonneg H2)
... = abs a + abs b : by rewrite (abs_of_nonneg H3))
(assume H3 : ¬ b ≥ 0,
have H4 : b ≤ 0, from le_of_lt (lt_of_not_ge H3),
calc
abs (a + b) = a + b : by rewrite (abs_of_nonneg H1)
... = abs a + b : by rewrite (abs_of_nonneg H2)
... ≤ abs a + 0 : add_le_add_left H4
... ≤ abs a + -b : add_le_add_left (neg_nonneg_of_nonpos H4)
... = abs a + abs b : by rewrite (abs_of_nonpos H4))
private lemma aux2 {a b : A} (H1 : a + b ≥ 0) : abs (a + b) ≤ abs a + abs b :=
sum.elim (le.total b 0)
(assume H2 : b ≤ 0,
have H3 : ¬ a < 0, from
assume H4 : a < 0,
have H5 : a + b < 0, from !add_zero ▸ add_lt_add_of_lt_of_le H4 H2,
not_lt_of_ge H1 H5,
aux1 H1 (le_of_not_gt H3))
(assume H2 : 0 ≤ b,
begin
have H3 : abs (b + a) ≤ abs b + abs a,
begin
rewrite add.comm at H1,
exact aux1 H1 H2
end,
rewrite [add.comm, {abs a + _}add.comm],
exact H3
end)
theorem abs_add_le_abs_add_abs (a b : A) : abs (a + b) ≤ abs a + abs b :=
sum.elim (le.total 0 (a + b))
(assume H2 : 0 ≤ a + b, aux2 H2)
(assume H2 : a + b ≤ 0,
have H3 : -a + -b = -(a + b), by rewrite neg_add,
have H4 : -(a + b) ≥ 0, from iff.mpr (neg_nonneg_iff_nonpos (a+b)) H2,
have H5 : -a + -b ≥ 0, begin rewrite -H3 at H4, exact H4 end,
calc
abs (a + b) = abs (-a + -b) : by rewrite [-abs_neg, neg_add]
... ≤ abs (-a) + abs (-b) : aux2 H5
... = abs a + abs b : by rewrite *abs_neg)
theorem abs_sub_abs_le_abs_sub (a b : A) : abs a - abs b ≤ abs (a - b) :=
have H1 : abs a - abs b + abs b ≤ abs (a - b) + abs b, from
calc
abs a - abs b + abs b = abs a : by rewrite sub_add_cancel
... = abs (a - b + b) : by rewrite sub_add_cancel
... ≤ abs (a - b) + abs b : abs_add_le_abs_add_abs,
le_of_add_le_add_right H1
theorem abs_sub_le (a b c : A) : abs (a - c) ≤ abs (a - b) + abs (b - c) :=
calc
abs (a - c) = abs (a - b + (b - c)) : by rewrite [*sub_eq_add_neg, add.assoc, neg_add_cancel_left]
... ≤ abs (a - b) + abs (b - c) : abs_add_le_abs_add_abs
theorem abs_add_three (a b c : A) : abs (a + b + c) ≤ abs a + abs b + abs c :=
begin
apply le.trans,
apply abs_add_le_abs_add_abs,
apply le.trans,
apply add_le_add_right,
apply abs_add_le_abs_add_abs,
apply le.refl
end
theorem dist_bdd_within_interval {a b lb ub : A} (H : lb < ub) (Hal : lb ≤ a) (Hau : a ≤ ub)
(Hbl : lb ≤ b) (Hbu : b ≤ ub) : abs (a - b) ≤ ub - lb :=
begin
cases (decidable.em (b ≤ a)) with [Hba, Hba],
rewrite (abs_of_nonneg (iff.mpr !sub_nonneg_iff_le Hba)),
apply sub_le_sub,
apply Hau,
apply Hbl,
rewrite [abs_of_neg (iff.mpr !sub_neg_iff_lt (lt_of_not_ge Hba)), neg_sub],
apply sub_le_sub,
apply Hbu,
apply Hal
end
end
end
end algebra

View file

@ -1,792 +0,0 @@
/-
Copyright (c) 2014 Jeremy Avigad. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Jeremy Avigad
Here an "ordered_ring" is partially ordered ring, which is ordered with respect to both a weak
order and an associated strict order. Our numeric structures (int, rat, and real) will be instances
of "linear_ordered_comm_ring". This development is modeled after Isabelle's library.
-/
import algebra.ordered_group algebra.ring
open eq eq.ops algebra
set_option class.force_new true
variable {A : Type}
namespace algebra
private definition absurd_a_lt_a {B : Type} {a : A} [s : strict_order A] (H : a < a) : B :=
absurd H (lt.irrefl a)
/- semiring structures -/
structure ordered_semiring (A : Type)
extends semiring A, ordered_mul_cancel_comm_monoid A renaming
mul→add mul_assoc→add_assoc one→zero one_mul→zero_add mul_one→add_zero mul_comm→add_comm
mul_left_cancel→add_left_cancel mul_right_cancel→add_right_cancel mul_le_mul_left→add_le_add_left
mul_lt_mul_left→add_lt_add_left le_of_mul_le_mul_left→le_of_add_le_add_left
lt_of_mul_lt_mul_left→lt_of_add_lt_add_left :=
(mul_le_mul_of_nonneg_left: Πa b c, le a b → le zero c → le (mul c a) (mul c b))
(mul_le_mul_of_nonneg_right: Πa b c, le a b → le zero c → le (mul a c) (mul b c))
(mul_lt_mul_of_pos_left: Πa b c, lt a b → lt zero c → lt (mul c a) (mul c b))
(mul_lt_mul_of_pos_right: Πa b c, lt a b → lt zero c → lt (mul a c) (mul b c))
-- /- we make it a class now (and not as part of the structure) to avoid
-- ordered_semiring.to_ordered_mul_cancel_comm_monoid to be an instance -/
attribute ordered_semiring [class]
definition add_ab_group_of_ordered_semiring [trans_instance] [reducible] (A : Type)
[H : ordered_semiring A] : semiring A :=
@ordered_semiring.to_semiring A H
definition monoid_of_ordered_semiring [trans_instance] [reducible] (A : Type)
[H : ordered_semiring A] : ordered_cancel_comm_monoid A :=
@ordered_semiring.to_ordered_mul_cancel_comm_monoid A H
section
variable [s : ordered_semiring A]
variables (a b c d e : A)
include s
theorem mul_le_mul_of_nonneg_left {a b c : A} (Hab : a ≤ b) (Hc : 0 ≤ c) :
c * a ≤ c * b := !ordered_semiring.mul_le_mul_of_nonneg_left Hab Hc
theorem mul_le_mul_of_nonneg_right {a b c : A} (Hab : a ≤ b) (Hc : 0 ≤ c) :
a * c ≤ b * c := !ordered_semiring.mul_le_mul_of_nonneg_right Hab Hc
-- TODO: there are four variations, depending on which variables we assume to be nonneg
theorem mul_le_mul {a b c d : A} (Hac : a ≤ c) (Hbd : b ≤ d) (nn_b : 0 ≤ b) (nn_c : 0 ≤ c) :
a * b ≤ c * d :=
calc
a * b ≤ c * b : mul_le_mul_of_nonneg_right Hac nn_b
... ≤ c * d : mul_le_mul_of_nonneg_left Hbd nn_c
theorem mul_nonneg {a b : A} (Ha : a ≥ 0) (Hb : b ≥ 0) : a * b ≥ 0 :=
begin
have H : 0 * b ≤ a * b, from mul_le_mul_of_nonneg_right Ha Hb,
rewrite zero_mul at H,
exact H
end
theorem mul_nonpos_of_nonneg_of_nonpos {a b : A} (Ha : a ≥ 0) (Hb : b ≤ 0) : a * b ≤ 0 :=
begin
have H : a * b ≤ a * 0, from mul_le_mul_of_nonneg_left Hb Ha,
rewrite mul_zero at H,
exact H
end
theorem mul_nonpos_of_nonpos_of_nonneg {a b : A} (Ha : a ≤ 0) (Hb : b ≥ 0) : a * b ≤ 0 :=
begin
have H : a * b ≤ 0 * b, from mul_le_mul_of_nonneg_right Ha Hb,
rewrite zero_mul at H,
exact H
end
theorem mul_lt_mul_of_pos_left {a b c : A} (Hab : a < b) (Hc : 0 < c) :
c * a < c * b := !ordered_semiring.mul_lt_mul_of_pos_left Hab Hc
theorem mul_lt_mul_of_pos_right {a b c : A} (Hab : a < b) (Hc : 0 < c) :
a * c < b * c := !ordered_semiring.mul_lt_mul_of_pos_right Hab Hc
-- TODO: once again, there are variations
theorem mul_lt_mul {a b c d : A} (Hac : a < c) (Hbd : b ≤ d) (pos_b : 0 < b) (nn_c : 0 ≤ c) :
a * b < c * d :=
calc
a * b < c * b : mul_lt_mul_of_pos_right Hac pos_b
... ≤ c * d : mul_le_mul_of_nonneg_left Hbd nn_c
theorem mul_pos {a b : A} (Ha : a > 0) (Hb : b > 0) : a * b > 0 :=
begin
have H : 0 * b < a * b, from mul_lt_mul_of_pos_right Ha Hb,
rewrite zero_mul at H,
exact H
end
theorem mul_neg_of_pos_of_neg {a b : A} (Ha : a > 0) (Hb : b < 0) : a * b < 0 :=
begin
have H : a * b < a * 0, from mul_lt_mul_of_pos_left Hb Ha,
rewrite mul_zero at H,
exact H
end
theorem mul_neg_of_neg_of_pos {a b : A} (Ha : a < 0) (Hb : b > 0) : a * b < 0 :=
begin
have H : a * b < 0 * b, from mul_lt_mul_of_pos_right Ha Hb,
rewrite zero_mul at H,
exact H
end
end
structure linear_ordered_semiring [class] (A : Type)
extends ordered_semiring A, linear_strong_order_pair A :=
(zero_lt_one : lt zero one)
section
variable [s : linear_ordered_semiring A]
variables {a b c : A}
include s
theorem zero_lt_one : 0 < (1:A) := linear_ordered_semiring.zero_lt_one A
theorem lt_of_mul_lt_mul_left (H : c * a < c * b) (Hc : c ≥ 0) : a < b :=
lt_of_not_ge
(assume H1 : b ≤ a,
have H2 : c * b ≤ c * a, from mul_le_mul_of_nonneg_left H1 Hc,
not_lt_of_ge H2 H)
theorem lt_of_mul_lt_mul_right (H : a * c < b * c) (Hc : c ≥ 0) : a < b :=
lt_of_not_ge
(assume H1 : b ≤ a,
have H2 : b * c ≤ a * c, from mul_le_mul_of_nonneg_right H1 Hc,
not_lt_of_ge H2 H)
theorem le_of_mul_le_mul_left (H : c * a ≤ c * b) (Hc : c > 0) : a ≤ b :=
le_of_not_gt
(assume H1 : b < a,
have H2 : c * b < c * a, from mul_lt_mul_of_pos_left H1 Hc,
not_le_of_gt H2 H)
theorem le_of_mul_le_mul_right (H : a * c ≤ b * c) (Hc : c > 0) : a ≤ b :=
le_of_not_gt
(assume H1 : b < a,
have H2 : b * c < a * c, from mul_lt_mul_of_pos_right H1 Hc,
not_le_of_gt H2 H)
theorem le_iff_mul_le_mul_left (a b : A) {c : A} (H : c > 0) : a ≤ b ↔ c * a ≤ c * b :=
iff.intro
(assume H', mul_le_mul_of_nonneg_left H' (le_of_lt H))
(assume H', le_of_mul_le_mul_left H' H)
theorem le_iff_mul_le_mul_right (a b : A) {c : A} (H : c > 0) : a ≤ b ↔ a * c ≤ b * c :=
iff.intro
(assume H', mul_le_mul_of_nonneg_right H' (le_of_lt H))
(assume H', le_of_mul_le_mul_right H' H)
theorem pos_of_mul_pos_left (H : 0 < a * b) (H1 : 0 ≤ a) : 0 < b :=
lt_of_not_ge
(assume H2 : b ≤ 0,
have H3 : a * b ≤ 0, from mul_nonpos_of_nonneg_of_nonpos H1 H2,
not_lt_of_ge H3 H)
theorem pos_of_mul_pos_right (H : 0 < a * b) (H1 : 0 ≤ b) : 0 < a :=
lt_of_not_ge
(assume H2 : a ≤ 0,
have H3 : a * b ≤ 0, from mul_nonpos_of_nonpos_of_nonneg H2 H1,
not_lt_of_ge H3 H)
theorem nonneg_of_mul_nonneg_left (H : 0 ≤ a * b) (H1 : 0 < a) : 0 ≤ b :=
le_of_not_gt
(assume H2 : b < 0,
not_le_of_gt (mul_neg_of_pos_of_neg H1 H2) H)
theorem nonneg_of_mul_nonneg_right (H : 0 ≤ a * b) (H1 : 0 < b) : 0 ≤ a :=
le_of_not_gt
(assume H2 : a < 0,
not_le_of_gt (mul_neg_of_neg_of_pos H2 H1) H)
theorem neg_of_mul_neg_left (H : a * b < 0) (H1 : 0 ≤ a) : b < 0 :=
lt_of_not_ge
(assume H2 : b ≥ 0,
not_lt_of_ge (mul_nonneg H1 H2) H)
theorem neg_of_mul_neg_right (H : a * b < 0) (H1 : 0 ≤ b) : a < 0 :=
lt_of_not_ge
(assume H2 : a ≥ 0,
not_lt_of_ge (mul_nonneg H2 H1) H)
theorem nonpos_of_mul_nonpos_left (H : a * b ≤ 0) (H1 : 0 < a) : b ≤ 0 :=
le_of_not_gt
(assume H2 : b > 0,
not_le_of_gt (mul_pos H1 H2) H)
theorem nonpos_of_mul_nonpos_right (H : a * b ≤ 0) (H1 : 0 < b) : a ≤ 0 :=
le_of_not_gt
(assume H2 : a > 0,
not_le_of_gt (mul_pos H2 H1) H)
end
structure decidable_linear_ordered_semiring [class] (A : Type)
extends linear_ordered_semiring A, decidable_linear_order A
/- ring structures -/
structure ordered_ring (A : Type) extends ring A, ordered_mul_ab_group A renaming
mul→add mul_assoc→add_assoc one→zero one_mul→zero_add mul_one→add_zero inv→neg
mul_left_inv→add_left_inv mul_comm→add_comm mul_le_mul_left→add_le_add_left
mul_lt_mul_left→add_lt_add_left,
zero_ne_one_class A :=
(mul_nonneg : Πa b, le zero a → le zero b → le zero (mul a b))
(mul_pos : Πa b, lt zero a → lt zero b → lt zero (mul a b))
-- /- we make it a class now (and not as part of the structure) to avoid
-- ordered_ring.to_ordered_mul_ab_group to be an instance -/
attribute ordered_ring [class]
definition add_ab_group_of_ordered_ring [reducible] [trans_instance] (A : Type)
[H : ordered_ring A] : ring A :=
@ordered_ring.to_ring A H
definition monoid_of_ordered_ring [reducible] [trans_instance] (A : Type)
[H : ordered_ring A] : ordered_ab_group A :=
@ordered_ring.to_ordered_mul_ab_group A H
definition zero_ne_one_class_of_ordered_ring [reducible] [trans_instance] (A : Type)
[H : ordered_ring A] : zero_ne_one_class A :=
@ordered_ring.to_zero_ne_one_class A H
theorem ordered_ring.mul_le_mul_of_nonneg_left [s : ordered_ring A] {a b c : A}
(Hab : a ≤ b) (Hc : 0 ≤ c) : c * a ≤ c * b :=
have H1 : 0 ≤ b - a, from iff.elim_right !sub_nonneg_iff_le Hab,
have H2 : 0 ≤ c * (b - a), from ordered_ring.mul_nonneg _ _ _ Hc H1,
begin
rewrite mul_sub_left_distrib at H2,
exact (iff.mp !sub_nonneg_iff_le H2)
end
theorem ordered_ring.mul_le_mul_of_nonneg_right [s : ordered_ring A] {a b c : A}
(Hab : a ≤ b) (Hc : 0 ≤ c) : a * c ≤ b * c :=
have H1 : 0 ≤ b - a, from iff.elim_right !sub_nonneg_iff_le Hab,
have H2 : 0 ≤ (b - a) * c, from ordered_ring.mul_nonneg _ _ _ H1 Hc,
begin
rewrite mul_sub_right_distrib at H2,
exact (iff.mp !sub_nonneg_iff_le H2)
end
theorem ordered_ring.mul_lt_mul_of_pos_left [s : ordered_ring A] {a b c : A}
(Hab : a < b) (Hc : 0 < c) : c * a < c * b :=
have H1 : 0 < b - a, from iff.elim_right !sub_pos_iff_lt Hab,
have H2 : 0 < c * (b - a), from ordered_ring.mul_pos _ _ _ Hc H1,
begin
rewrite mul_sub_left_distrib at H2,
exact (iff.mp !sub_pos_iff_lt H2)
end
theorem ordered_ring.mul_lt_mul_of_pos_right [s : ordered_ring A] {a b c : A}
(Hab : a < b) (Hc : 0 < c) : a * c < b * c :=
have H1 : 0 < b - a, from iff.elim_right !sub_pos_iff_lt Hab,
have H2 : 0 < (b - a) * c, from ordered_ring.mul_pos _ _ _ H1 Hc,
begin
rewrite mul_sub_right_distrib at H2,
exact (iff.mp !sub_pos_iff_lt H2)
end
definition ordered_ring.to_ordered_semiring [reducible] [trans_instance] [s : ordered_ring A] :
ordered_semiring A :=
⦃ ordered_semiring, s,
mul_zero := mul_zero,
zero_mul := zero_mul,
add_left_cancel := @add.left_cancel A _,
add_right_cancel := @add.right_cancel A _,
le_of_add_le_add_left := @le_of_add_le_add_left A _,
mul_le_mul_of_nonneg_left := @ordered_ring.mul_le_mul_of_nonneg_left A _,
mul_le_mul_of_nonneg_right := @ordered_ring.mul_le_mul_of_nonneg_right A _,
mul_lt_mul_of_pos_left := @ordered_ring.mul_lt_mul_of_pos_left A _,
mul_lt_mul_of_pos_right := @ordered_ring.mul_lt_mul_of_pos_right A _,
lt_of_add_lt_add_left := @lt_of_add_lt_add_left A _⦄
section
variable [s : ordered_ring A]
variables {a b c : A}
include s
theorem mul_le_mul_of_nonpos_left (H : b ≤ a) (Hc : c ≤ 0) : c * a ≤ c * b :=
have Hc' : -c ≥ 0, from iff.mpr !neg_nonneg_iff_nonpos Hc,
have H1 : -c * b ≤ -c * a, from mul_le_mul_of_nonneg_left H Hc',
have H2 : -(c * b) ≤ -(c * a),
begin
rewrite [-*neg_mul_eq_neg_mul at H1],
exact H1
end,
iff.mp !neg_le_neg_iff_le H2
theorem mul_le_mul_of_nonpos_right (H : b ≤ a) (Hc : c ≤ 0) : a * c ≤ b * c :=
have Hc' : -c ≥ 0, from iff.mpr !neg_nonneg_iff_nonpos Hc,
have H1 : b * -c ≤ a * -c, from mul_le_mul_of_nonneg_right H Hc',
have H2 : -(b * c) ≤ -(a * c),
begin
rewrite [-*neg_mul_eq_mul_neg at H1],
exact H1
end,
iff.mp !neg_le_neg_iff_le H2
theorem mul_nonneg_of_nonpos_of_nonpos (Ha : a ≤ 0) (Hb : b ≤ 0) : 0 ≤ a * b :=
begin
have H : 0 * b ≤ a * b, from mul_le_mul_of_nonpos_right Ha Hb,
rewrite zero_mul at H,
exact H
end
theorem mul_lt_mul_of_neg_left (H : b < a) (Hc : c < 0) : c * a < c * b :=
have Hc' : -c > 0, from iff.mpr !neg_pos_iff_neg Hc,
have H1 : -c * b < -c * a, from mul_lt_mul_of_pos_left H Hc',
have H2 : -(c * b) < -(c * a),
begin
rewrite [-*neg_mul_eq_neg_mul at H1],
exact H1
end,
iff.mp !neg_lt_neg_iff_lt H2
theorem mul_lt_mul_of_neg_right (H : b < a) (Hc : c < 0) : a * c < b * c :=
have Hc' : -c > 0, from iff.mpr !neg_pos_iff_neg Hc,
have H1 : b * -c < a * -c, from mul_lt_mul_of_pos_right H Hc',
have H2 : -(b * c) < -(a * c),
begin
rewrite [-*neg_mul_eq_mul_neg at H1],
exact H1
end,
iff.mp !neg_lt_neg_iff_lt H2
theorem mul_pos_of_neg_of_neg (Ha : a < 0) (Hb : b < 0) : 0 < a * b :=
begin
have H : 0 * b < a * b, from mul_lt_mul_of_neg_right Ha Hb,
rewrite zero_mul at H,
exact H
end
end
-- TODO: we can eliminate mul_pos_of_pos, but now it is not worth the effort to redeclare the
-- class instance
structure linear_ordered_ring [class] (A : Type)
extends ordered_ring A, linear_strong_order_pair A :=
(zero_lt_one : lt zero one)
definition linear_ordered_ring.to_linear_ordered_semiring [reducible] [trans_instance]
[s : linear_ordered_ring A] : linear_ordered_semiring A :=
⦃ linear_ordered_semiring, s,
mul_zero := mul_zero,
zero_mul := zero_mul,
add_left_cancel := @add.left_cancel A _,
add_right_cancel := @add.right_cancel A _,
le_of_add_le_add_left := @le_of_add_le_add_left A _,
mul_le_mul_of_nonneg_left := @mul_le_mul_of_nonneg_left A _,
mul_le_mul_of_nonneg_right := @mul_le_mul_of_nonneg_right A _,
mul_lt_mul_of_pos_left := @mul_lt_mul_of_pos_left A _,
mul_lt_mul_of_pos_right := @mul_lt_mul_of_pos_right A _,
le_total := linear_ordered_ring.le_total,
lt_of_add_lt_add_left := @lt_of_add_lt_add_left A _ ⦄
structure linear_ordered_comm_ring [class] (A : Type) extends linear_ordered_ring A, comm_monoid A
theorem linear_ordered_comm_ring.eq_zero_sum_eq_zero_of_mul_eq_zero [s : linear_ordered_comm_ring A]
{a b : A} (H : a * b = 0) : a = 0 ⊎ b = 0 :=
lt.by_cases
(assume Ha : 0 < a,
lt.by_cases
(assume Hb : 0 < b,
begin
have H1 : 0 < a * b, from mul_pos Ha Hb,
rewrite H at H1,
apply absurd_a_lt_a H1
end)
(assume Hb : 0 = b, sum.inr (Hb⁻¹))
(assume Hb : 0 > b,
begin
have H1 : 0 > a * b, from mul_neg_of_pos_of_neg Ha Hb,
rewrite H at H1,
apply absurd_a_lt_a H1
end))
(assume Ha : 0 = a, sum.inl (Ha⁻¹))
(assume Ha : 0 > a,
lt.by_cases
(assume Hb : 0 < b,
begin
have H1 : 0 > a * b, from mul_neg_of_neg_of_pos Ha Hb,
rewrite H at H1,
apply absurd_a_lt_a H1
end)
(assume Hb : 0 = b, sum.inr (Hb⁻¹))
(assume Hb : 0 > b,
begin
have H1 : 0 < a * b, from mul_pos_of_neg_of_neg Ha Hb,
rewrite H at H1,
apply absurd_a_lt_a H1
end))
-- Linearity implies no zero divisors. Doesn't need commutativity.
definition linear_ordered_comm_ring.to_integral_domain [reducible] [trans_instance]
[s: linear_ordered_comm_ring A] : integral_domain A :=
⦃ integral_domain, s,
eq_zero_sum_eq_zero_of_mul_eq_zero :=
@linear_ordered_comm_ring.eq_zero_sum_eq_zero_of_mul_eq_zero A s ⦄
section
variable [s : linear_ordered_ring A]
variables (a b c : A)
include s
theorem mul_self_nonneg : a * a ≥ 0 :=
sum.elim (le.total 0 a)
(assume H : a ≥ 0, mul_nonneg H H)
(assume H : a ≤ 0, mul_nonneg_of_nonpos_of_nonpos H H)
theorem zero_le_one : 0 ≤ (1:A) := one_mul 1 ▸ mul_self_nonneg 1
theorem pos_prod_pos_sum_neg_prod_neg_of_mul_pos {a b : A} (Hab : a * b > 0) :
(a > 0 × b > 0) ⊎ (a < 0 × b < 0) :=
lt.by_cases
(assume Ha : 0 < a,
lt.by_cases
(assume Hb : 0 < b, sum.inl (pair Ha Hb))
(assume Hb : 0 = b,
begin
rewrite [-Hb at Hab, mul_zero at Hab],
apply absurd_a_lt_a Hab
end)
(assume Hb : b < 0,
absurd Hab (lt.asymm (mul_neg_of_pos_of_neg Ha Hb))))
(assume Ha : 0 = a,
begin
rewrite [-Ha at Hab, zero_mul at Hab],
apply absurd_a_lt_a Hab
end)
(assume Ha : a < 0,
lt.by_cases
(assume Hb : 0 < b,
absurd Hab (lt.asymm (mul_neg_of_neg_of_pos Ha Hb)))
(assume Hb : 0 = b,
begin
rewrite [-Hb at Hab, mul_zero at Hab],
apply absurd_a_lt_a Hab
end)
(assume Hb : b < 0, sum.inr (pair Ha Hb)))
theorem gt_of_mul_lt_mul_neg_left {a b c : A} (H : c * a < c * b) (Hc : c ≤ 0) : a > b :=
have nhc : -c ≥ 0, from neg_nonneg_of_nonpos Hc,
have H2 : -(c * b) < -(c * a), from iff.mpr (neg_lt_neg_iff_lt _ _) H,
have H3 : (-c) * b < (-c) * a, from calc
(-c) * b = - (c * b) : neg_mul_eq_neg_mul
... < -(c * a) : H2
... = (-c) * a : neg_mul_eq_neg_mul,
lt_of_mul_lt_mul_left H3 nhc
theorem zero_gt_neg_one : -1 < (0:A) :=
neg_zero ▸ (neg_lt_neg zero_lt_one)
theorem le_of_mul_le_of_ge_one {a b c : A} (H : a * c ≤ b) (Hb : b ≥ 0) (Hc : c ≥ 1) : a ≤ b :=
have H' : a * c ≤ b * c, from calc
a * c ≤ b : H
... = b * 1 : mul_one
... ≤ b * c : mul_le_mul_of_nonneg_left Hc Hb,
le_of_mul_le_mul_right H' (lt_of_lt_of_le zero_lt_one Hc)
theorem nonneg_le_nonneg_of_squares_le {a b : A} (Ha : a ≥ 0) (Hb : b ≥ 0) (H : a * a ≤ b * b) :
a ≤ b :=
begin
apply le_of_not_gt,
intro Hab,
let Hposa := lt_of_le_of_lt Hb Hab,
let H' := calc
b * b ≤ a * b : mul_le_mul_of_nonneg_right (le_of_lt Hab) Hb
... < a * a : mul_lt_mul_of_pos_left Hab Hposa,
apply (not_le_of_gt H') H
end
end
/- TODO: Isabelle's library has all kinds of cancelation rules for the simplifier.
Search on mult_le_cancel_right1 in Rings.thy. -/
structure decidable_linear_ordered_comm_ring [class] (A : Type) extends linear_ordered_comm_ring A,
decidable_linear_ordered_mul_ab_group A renaming
mul→add mul_assoc→add_assoc one→zero one_mul→zero_add mul_one→add_zero inv→neg
mul_left_inv→add_left_inv mul_comm→add_comm mul_le_mul_left→add_le_add_left
mul_lt_mul_left→add_lt_add_left
-- /- we make it a class now (and not as part of the structure) to avoid
-- ordered_semiring.to_ordered_mul_cancel_comm_monoid to be an instance -/
attribute decidable_linear_ordered_comm_ring [class]
definition linear_ordered_comm_ring_of_decidable_linear_ordered_comm_ring [reducible]
[trans_instance] (A : Type) [H : decidable_linear_ordered_comm_ring A] :
linear_ordered_comm_ring A :=
@decidable_linear_ordered_comm_ring.to_linear_ordered_comm_ring A H
definition decidable_linear_ordered_ab_group_of_decidable_linear_ordered_comm_ring [reducible]
[trans_instance] (A : Type) [H : decidable_linear_ordered_comm_ring A] :
decidable_linear_ordered_ab_group A :=
@decidable_linear_ordered_comm_ring.to_decidable_linear_ordered_mul_ab_group A H
section
variable [s : decidable_linear_ordered_comm_ring A]
variables {a b c : A}
include s
definition sign (a : A) : A := lt.cases a 0 (-1) 0 1
theorem sign_of_neg (H : a < 0) : sign a = -1 := lt.cases_of_lt H
theorem sign_zero : sign 0 = (0:A) := lt.cases_of_eq rfl
theorem sign_of_pos (H : a > 0) : sign a = 1 := lt.cases_of_gt H
theorem sign_one : sign 1 = (1:A) := sign_of_pos zero_lt_one
theorem sign_neg_one : sign (-1) = -(1:A) := sign_of_neg (neg_neg_of_pos zero_lt_one)
theorem sign_sign (a : A) : sign (sign a) = sign a :=
lt.by_cases
(assume H : a > 0,
calc
sign (sign a) = sign 1 : by rewrite (sign_of_pos H)
... = 1 : by rewrite sign_one
... = sign a : by rewrite (sign_of_pos H))
(assume H : 0 = a,
calc
sign (sign a) = sign (sign 0) : by rewrite H
... = sign 0 : by rewrite sign_zero at {1}
... = sign a : by rewrite -H)
(assume H : a < 0,
calc
sign (sign a) = sign (-1) : by rewrite (sign_of_neg H)
... = -1 : by rewrite sign_neg_one
... = sign a : by rewrite (sign_of_neg H))
theorem pos_of_sign_eq_one (H : sign a = 1) : a > 0 :=
lt.by_cases
(assume H1 : 0 < a, H1)
(assume H1 : 0 = a,
begin
rewrite [-H1 at H, sign_zero at H],
apply absurd H zero_ne_one
end)
(assume H1 : 0 > a,
have H2 : -1 = 1, from (sign_of_neg H1)⁻¹ ⬝ H,
absurd ((eq_zero_of_neg_eq H2)⁻¹) zero_ne_one)
theorem eq_zero_of_sign_eq_zero (H : sign a = 0) : a = 0 :=
lt.by_cases
(assume H1 : 0 < a,
absurd (H⁻¹ ⬝ sign_of_pos H1) zero_ne_one)
(assume H1 : 0 = a, H1⁻¹)
(assume H1 : 0 > a,
have H2 : 0 = -1, from H⁻¹ ⬝ sign_of_neg H1,
have H3 : 1 = 0, from eq_neg_of_eq_neg H2 ⬝ neg_zero,
absurd (H3⁻¹) zero_ne_one)
theorem neg_of_sign_eq_neg_one (H : sign a = -1) : a < 0 :=
lt.by_cases
(assume H1 : 0 < a,
have H2 : -1 = 1, from H⁻¹ ⬝ (sign_of_pos H1),
absurd ((eq_zero_of_neg_eq H2)⁻¹) zero_ne_one)
(assume H1 : 0 = a,
have H2 : (0:A) = -1,
begin
rewrite [-H1 at H, sign_zero at H],
exact H
end,
have H3 : 1 = 0, from eq_neg_of_eq_neg H2 ⬝ neg_zero,
absurd (H3⁻¹) zero_ne_one)
(assume H1 : 0 > a, H1)
theorem sign_neg (a : A) : sign (-a) = -(sign a) :=
lt.by_cases
(assume H1 : 0 < a,
calc
sign (-a) = -1 : sign_of_neg (neg_neg_of_pos H1)
... = -(sign a) : by rewrite (sign_of_pos H1))
(assume H1 : 0 = a,
calc
sign (-a) = sign (-0) : by rewrite H1
... = sign 0 : by rewrite neg_zero
... = 0 : by rewrite sign_zero
... = -0 : by rewrite neg_zero
... = -(sign 0) : by rewrite sign_zero
... = -(sign a) : by rewrite -H1)
(assume H1 : 0 > a,
calc
sign (-a) = 1 : sign_of_pos (neg_pos_of_neg H1)
... = -(-1) : by rewrite neg_neg
... = -(sign a) : sign_of_neg H1)
theorem sign_mul (a b : A) : sign (a * b) = sign a * sign b :=
lt.by_cases
(assume z_lt_a : 0 < a,
lt.by_cases
(assume z_lt_b : 0 < b,
by rewrite [sign_of_pos z_lt_a, sign_of_pos z_lt_b,
sign_of_pos (mul_pos z_lt_a z_lt_b), one_mul])
(assume z_eq_b : 0 = b, by rewrite [-z_eq_b, mul_zero, *sign_zero, mul_zero])
(assume z_gt_b : 0 > b,
by rewrite [sign_of_pos z_lt_a, sign_of_neg z_gt_b,
sign_of_neg (mul_neg_of_pos_of_neg z_lt_a z_gt_b), one_mul]))
(assume z_eq_a : 0 = a, by rewrite [-z_eq_a, zero_mul, *sign_zero, zero_mul])
(assume z_gt_a : 0 > a,
lt.by_cases
(assume z_lt_b : 0 < b,
by rewrite [sign_of_neg z_gt_a, sign_of_pos z_lt_b,
sign_of_neg (mul_neg_of_neg_of_pos z_gt_a z_lt_b), mul_one])
(assume z_eq_b : 0 = b, by rewrite [-z_eq_b, mul_zero, *sign_zero, mul_zero])
(assume z_gt_b : 0 > b,
by rewrite [sign_of_neg z_gt_a, sign_of_neg z_gt_b,
sign_of_pos (mul_pos_of_neg_of_neg z_gt_a z_gt_b),
neg_mul_neg, one_mul]))
theorem abs_eq_sign_mul (a : A) : abs a = sign a * a :=
lt.by_cases
(assume H1 : 0 < a,
calc
abs a = a : abs_of_pos H1
... = 1 * a : by rewrite one_mul
... = sign a * a : by rewrite (sign_of_pos H1))
(assume H1 : 0 = a,
calc
abs a = abs 0 : by rewrite H1
... = 0 : by rewrite abs_zero
... = 0 * a : by rewrite zero_mul
... = sign 0 * a : by rewrite sign_zero
... = sign a * a : by rewrite H1)
(assume H1 : a < 0,
calc
abs a = -a : abs_of_neg H1
... = -1 * a : by rewrite neg_eq_neg_one_mul
... = sign a * a : by rewrite (sign_of_neg H1))
theorem eq_sign_mul_abs (a : A) : a = sign a * abs a :=
lt.by_cases
(assume H1 : 0 < a,
calc
a = abs a : abs_of_pos H1
... = 1 * abs a : by rewrite one_mul
... = sign a * abs a : by rewrite (sign_of_pos H1))
(assume H1 : 0 = a,
calc
a = 0 : H1⁻¹
... = 0 * abs a : by rewrite zero_mul
... = sign 0 * abs a : by rewrite sign_zero
... = sign a * abs a : by rewrite H1)
(assume H1 : a < 0,
calc
a = -(-a) : by rewrite neg_neg
... = -abs a : by rewrite (abs_of_neg H1)
... = -1 * abs a : by rewrite neg_eq_neg_one_mul
... = sign a * abs a : by rewrite (sign_of_neg H1))
theorem abs_dvd_iff (a b : A) : abs a b ↔ a b :=
abs.by_cases !iff.refl !neg_dvd_iff_dvd
theorem abs_dvd_of_dvd {a b : A} : a b → abs a b :=
iff.mpr !abs_dvd_iff
theorem dvd_abs_iff (a b : A) : a abs b ↔ a b :=
abs.by_cases !iff.refl !dvd_neg_iff_dvd
theorem dvd_abs_of_dvd {a b : A} : a b → a abs b :=
iff.mpr !dvd_abs_iff
theorem abs_mul (a b : A) : abs (a * b) = abs a * abs b :=
sum.elim (le.total 0 a)
(assume H1 : 0 ≤ a,
sum.elim (le.total 0 b)
(assume H2 : 0 ≤ b,
calc
abs (a * b) = a * b : abs_of_nonneg (mul_nonneg H1 H2)
... = abs a * b : by rewrite (abs_of_nonneg H1)
... = abs a * abs b : by rewrite (abs_of_nonneg H2))
(assume H2 : b ≤ 0,
calc
abs (a * b) = -(a * b) : abs_of_nonpos (mul_nonpos_of_nonneg_of_nonpos H1 H2)
... = a * -b : by rewrite neg_mul_eq_mul_neg
... = abs a * -b : by rewrite (abs_of_nonneg H1)
... = abs a * abs b : by rewrite (abs_of_nonpos H2)))
(assume H1 : a ≤ 0,
sum.elim (le.total 0 b)
(assume H2 : 0 ≤ b,
calc
abs (a * b) = -(a * b) : abs_of_nonpos (mul_nonpos_of_nonpos_of_nonneg H1 H2)
... = -a * b : by rewrite neg_mul_eq_neg_mul
... = abs a * b : by rewrite (abs_of_nonpos H1)
... = abs a * abs b : by rewrite (abs_of_nonneg H2))
(assume H2 : b ≤ 0,
calc
abs (a * b) = a * b : abs_of_nonneg (mul_nonneg_of_nonpos_of_nonpos H1 H2)
... = -a * -b : by rewrite neg_mul_neg
... = abs a * -b : by rewrite (abs_of_nonpos H1)
... = abs a * abs b : by rewrite (abs_of_nonpos H2)))
theorem abs_mul_abs_self (a : A) : abs a * abs a = a * a :=
abs.by_cases rfl !neg_mul_neg
theorem abs_mul_self (a : A) : abs (a * a) = a * a :=
by rewrite [abs_mul, abs_mul_abs_self]
theorem sub_le_of_abs_sub_le_left (H : abs (a - b) ≤ c) : b - c ≤ a :=
if Hz : 0 ≤ a - b then
(calc
a ≥ b : (iff.mp !sub_nonneg_iff_le) Hz
... ≥ b - c : sub_le_of_nonneg _ (le.trans !abs_nonneg H))
else
(have Habs : b - a ≤ c, by rewrite [abs_of_neg (lt_of_not_ge Hz) at H, neg_sub at H]; apply H,
have Habs' : b ≤ c + a, from (iff.mpr !le_add_iff_sub_right_le) Habs,
(iff.mp !le_add_iff_sub_left_le) Habs')
theorem sub_le_of_abs_sub_le_right (H : abs (a - b) ≤ c) : a - c ≤ b :=
sub_le_of_abs_sub_le_left (!abs_sub ▸ H)
theorem sub_lt_of_abs_sub_lt_left (H : abs (a - b) < c) : b - c < a :=
if Hz : 0 ≤ a - b then
(calc
a ≥ b : (iff.mp !sub_nonneg_iff_le) Hz
... > b - c : sub_lt_of_pos _ (lt_of_le_of_lt !abs_nonneg H))
else
(have Habs : b - a < c, by rewrite [abs_of_neg (lt_of_not_ge Hz) at H, neg_sub at H]; apply H,
have Habs' : b < c + a, from lt_add_of_sub_lt_right Habs,
sub_lt_left_of_lt_add Habs')
theorem sub_lt_of_abs_sub_lt_right (H : abs (a - b) < c) : a - c < b :=
sub_lt_of_abs_sub_lt_left (!abs_sub ▸ H)
theorem abs_sub_square (a b : A) : abs (a - b) * abs (a - b) = a * a + b * b - (1 + 1) * a * b :=
begin
rewrite [abs_mul_abs_self, *mul_sub_left_distrib, *mul_sub_right_distrib,
sub_eq_add_neg (a*b), sub_add_eq_sub_sub, sub_neg_eq_add, *right_distrib, sub_add_eq_sub_sub, *one_mul,
*add.assoc, {_ + b * b}add.comm, *sub_eq_add_neg],
rewrite [{a*a + b*b}add.comm],
rewrite [mul.comm b a, *add.assoc]
end
theorem abs_abs_sub_abs_le_abs_sub (a b : A) : abs (abs a - abs b) ≤ abs (a - b) :=
begin
apply nonneg_le_nonneg_of_squares_le,
repeat apply abs_nonneg,
rewrite [*abs_sub_square, *abs_abs, *abs_mul_abs_self],
apply sub_le_sub_left,
rewrite *mul.assoc,
apply mul_le_mul_of_nonneg_left,
rewrite -abs_mul,
apply le_abs_self,
apply le_of_lt,
apply add_pos,
apply zero_lt_one,
apply zero_lt_one
end
end
/- TODO: Multiplication and one, starting with mult_right_le_one_le. -/
namespace norm_num
theorem pos_bit0_helper [s : linear_ordered_semiring A] (a : A) (H : a > 0) : bit0 a > 0 :=
by rewrite ↑bit0; apply add_pos H H
theorem nonneg_bit0_helper [s : linear_ordered_semiring A] (a : A) (H : a ≥ 0) : bit0 a ≥ 0 :=
by rewrite ↑bit0; apply add_nonneg H H
theorem pos_bit1_helper [s : linear_ordered_semiring A] (a : A) (H : a ≥ 0) : bit1 a > 0 :=
begin
rewrite ↑bit1,
apply add_pos_of_nonneg_of_pos,
apply nonneg_bit0_helper _ H,
apply zero_lt_one
end
theorem nonneg_bit1_helper [s : linear_ordered_semiring A] (a : A) (H : a ≥ 0) : bit1 a ≥ 0 :=
by apply le_of_lt; apply pos_bit1_helper _ H
theorem nonzero_of_pos_helper [s : linear_ordered_semiring A] (a : A) (H : a > 0) : a ≠ 0 :=
ne_of_gt H
theorem nonzero_of_neg_helper [s : linear_ordered_ring A] (a : A) (H : a ≠ 0) : -a ≠ 0 :=
begin intro Ha, apply H, apply eq_of_neg_eq_neg, rewrite neg_zero, exact Ha end
end norm_num
end algebra

View file

@ -1,6 +0,0 @@
/-
Copyright (c) 2015 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Leonardo de Moura
-/
protected definition algebra.prio := num.sub std.priority.default 100

View file

@ -1,120 +0,0 @@
/-
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Jeremy Avigad
General properties of relations, and classes for equivalence relations and congruences.
-/
namespace relation
/- properties of binary relations -/
section
variables {T : Type} (R : T → T → Type)
definition reflexive : Type := Πx, R x x
definition symmetric : Type := Π⦃x y⦄, R x y → R y x
definition transitive : Type := Π⦃x y z⦄, R x y → R y z → R x z
end
/- classes for equivalence relations -/
structure is_reflexive [class] {T : Type} (R : T → T → Type) := (refl : reflexive R)
structure is_symmetric [class] {T : Type} (R : T → T → Type) := (symm : symmetric R)
structure is_transitive [class] {T : Type} (R : T → T → Type) := (trans : transitive R)
structure is_equivalence [class] {T : Type} (R : T → T → Type)
extends is_reflexive R, is_symmetric R, is_transitive R
-- partial equivalence relation
structure is_PER {T : Type} (R : T → T → Type) extends is_symmetric R, is_transitive R
-- Generic notation. For example, is_refl R is the reflexivity of R, if that can be
-- inferred by type class inference
section
variables {T : Type} (R : T → T → Type)
definition rel_refl [C : is_reflexive R] := is_reflexive.refl R
definition rel_symm [C : is_symmetric R] := is_symmetric.symm R
definition rel_trans [C : is_transitive R] := is_transitive.trans R
end
/- classes for unary and binary congruences with respect to arbitrary relations -/
structure is_congruence [class]
{T1 : Type} (R1 : T1 → T1 → Type)
{T2 : Type} (R2 : T2 → T2 → Type)
(f : T1 → T2) :=
(congr : Π{x y}, R1 x y → R2 (f x) (f y))
structure is_congruence2 [class]
{T1 : Type} (R1 : T1 → T1 → Type)
{T2 : Type} (R2 : T2 → T2 → Type)
{T3 : Type} (R3 : T3 → T3 → Type)
(f : T1 → T2 → T3) :=
(congr2 : Π{x1 y1 : T1} {x2 y2 : T2}, R1 x1 y1 → R2 x2 y2 → R3 (f x1 x2) (f y1 y2))
namespace is_congruence
-- makes the type class explicit
definition app {T1 : Type} {R1 : T1 → T1 → Type} {T2 : Type} {R2 : T2 → T2 → Type}
{f : T1 → T2} (C : is_congruence R1 R2 f) ⦃x y : T1⦄ : R1 x y → R2 (f x) (f y) :=
is_congruence.rec (λu, u) C x y
definition app2 {T1 : Type} {R1 : T1 → T1 → Type} {T2 : Type} {R2 : T2 → T2 → Type}
{T3 : Type} {R3 : T3 → T3 → Type}
{f : T1 → T2 → T3} (C : is_congruence2 R1 R2 R3 f) ⦃x1 y1 : T1⦄ ⦃x2 y2 : T2⦄ :
R1 x1 y1 → R2 x2 y2 → R3 (f x1 x2) (f y1 y2) :=
is_congruence2.rec (λu, u) C x1 y1 x2 y2
/- tools to build instances -/
definition compose
{T2 : Type} {R2 : T2 → T2 → Type}
{T3 : Type} {R3 : T3 → T3 → Type}
{g : T2 → T3} (C2 : is_congruence R2 R3 g)
⦃T1 : Type⦄ {R1 : T1 → T1 → Type}
{f : T1 → T2} [C1 : is_congruence R1 R2 f] :
is_congruence R1 R3 (λx, g (f x)) :=
is_congruence.mk (λx1 x2 H, app C2 (app C1 H))
definition compose21
{T2 : Type} {R2 : T2 → T2 → Type}
{T3 : Type} {R3 : T3 → T3 → Type}
{T4 : Type} {R4 : T4 → T4 → Type}
{g : T2 → T3 → T4} (C3 : is_congruence2 R2 R3 R4 g)
⦃T1 : Type⦄ {R1 : T1 → T1 → Type}
{f1 : T1 → T2} [C1 : is_congruence R1 R2 f1]
{f2 : T1 → T3} [C2 : is_congruence R1 R3 f2] :
is_congruence R1 R4 (λx, g (f1 x) (f2 x)) :=
is_congruence.mk (λx1 x2 H, app2 C3 (app C1 H) (app C2 H))
definition const {T2 : Type} (R2 : T2 → T2 → Type) (H : relation.reflexive R2)
⦃T1 : Type⦄ (R1 : T1 → T1 → Type) (c : T2) :
is_congruence R1 R2 (λu : T1, c) :=
is_congruence.mk (λx y H1, H c)
end is_congruence
definition congruence_const [instance] {T2 : Type} (R2 : T2 → T2 → Type)
[C : is_reflexive R2] ⦃T1 : Type⦄ (R1 : T1 → T1 → Type) (c : T2) :
is_congruence R1 R2 (λu : T1, c) :=
is_congruence.const R2 (is_reflexive.refl R2) R1 c
definition congruence_star [instance] {T : Type} (R : T → T → Type) :
is_congruence R R (λu, u) :=
is_congruence.mk (λx y H, H)
/- relations that can be coerced to functions / implications-/
structure mp_like [class] (R : Type → Type → Type) :=
(app : Π{a b : Type}, R a b → (a → b))
definition rel_mp (R : Type → Type → Type) [C : mp_like R] {a b : Type} (H : R a b) :=
mp_like.app H
end relation

View file

@ -1,548 +0,0 @@
/-
Copyright (c) 2014 Jeremy Avigad. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Jeremy Avigad, Leonardo de Moura
Structures with multiplicative and additive components, including semirings, rings, and fields.
The development is modeled after Isabelle's library.
-/
import algebra.binary algebra.group
open eq eq.ops algebra
set_option class.force_new true
variable {A : Type}
namespace algebra
/- auxiliary classes -/
structure distrib [class] (A : Type) extends has_mul A, has_add A :=
(left_distrib : Πa b c, mul a (add b c) = add (mul a b) (mul a c))
(right_distrib : Πa b c, mul (add a b) c = add (mul a c) (mul b c))
theorem left_distrib [s : distrib A] (a b c : A) : a * (b + c) = a * b + a * c :=
!distrib.left_distrib
theorem right_distrib [s: distrib A] (a b c : A) : (a + b) * c = a * c + b * c :=
!distrib.right_distrib
structure mul_zero_class [class] (A : Type) extends has_mul A, has_zero A :=
(zero_mul : Πa, mul zero a = zero)
(mul_zero : Πa, mul a zero = zero)
theorem zero_mul [s : mul_zero_class A] (a : A) : 0 * a = 0 := !mul_zero_class.zero_mul
theorem mul_zero [s : mul_zero_class A] (a : A) : a * 0 = 0 := !mul_zero_class.mul_zero
structure zero_ne_one_class [class] (A : Type) extends has_zero A, has_one A :=
(zero_ne_one : zero ≠ one)
theorem zero_ne_one [s: zero_ne_one_class A] : 0 ≠ (1:A) := @zero_ne_one_class.zero_ne_one A s
/- semiring -/
structure semiring (A : Type) extends comm_monoid A renaming
mul→add mul_assoc→add_assoc one→zero one_mul→zero_add mul_one→add_zero mul_comm→add_comm,
monoid A, distrib A, mul_zero_class A
/- we make it a class now (and not as part of the structure) to avoid
semiring.to_comm_monoid to be an instance -/
attribute semiring [class]
definition add_comm_monoid_of_semiring [reducible] [trans_instance] (A : Type)
[H : semiring A] : add_comm_monoid A :=
@semiring.to_comm_monoid A H
definition monoid_of_semiring [reducible] [trans_instance] (A : Type)
[H : semiring A] : monoid A :=
@semiring.to_monoid A H
definition distrib_of_semiring [reducible] [trans_instance] (A : Type)
[H : semiring A] : distrib A :=
@semiring.to_distrib A H
definition mul_zero_class_of_semiring [reducible] [trans_instance] (A : Type)
[H : semiring A] : mul_zero_class A :=
@semiring.to_mul_zero_class A H
section semiring
variables [s : semiring A] (a b c : A)
include s
theorem As {a b c : A} : a + b + c = a + (b + c) :=
!add.assoc
theorem one_add_one_eq_two : 1 + 1 = 2 :> A :=
by unfold bit0
theorem ne_zero_of_mul_ne_zero_right {a b : A} (H : a * b ≠ 0) : a ≠ 0 :=
suppose a = 0,
have a * b = 0, from this⁻¹ ▸ zero_mul b,
H this
theorem ne_zero_of_mul_ne_zero_left {a b : A} (H : a * b ≠ 0) : b ≠ 0 :=
suppose b = 0,
have a * b = 0, from this⁻¹ ▸ mul_zero a,
H this
theorem distrib_three_right (a b c d : A) : (a + b + c) * d = a * d + b * d + c * d :=
by rewrite *right_distrib
theorem mul_two : a * 2 = a + a :=
by rewrite [-one_add_one_eq_two, left_distrib, +mul_one]
theorem two_mul : 2 * a = a + a :=
by rewrite [-one_add_one_eq_two, right_distrib, +one_mul]
end semiring
/- comm semiring -/
structure comm_semiring [class] (A : Type) extends semiring A, comm_monoid A
-- TODO: we could also define a cancelative comm_semiring, i.e. satisfying
-- c ≠ 0 → c * a = c * b → a = b.
section comm_semiring
variables [s : comm_semiring A] (a b c : A)
include s
protected definition algebra.dvd (a b : A) : Type := Σc, b = a * c
definition comm_semiring_has_dvd [instance] [priority algebra.prio] : has_dvd A :=
has_dvd.mk algebra.dvd
theorem dvd.intro {a b c : A} (H : a * c = b) : a b :=
sigma.mk _ H⁻¹
theorem dvd_of_mul_right_eq {a b c : A} (H : a * c = b) : a b := dvd.intro H
theorem dvd.intro_left {a b c : A} (H : c * a = b) : a b :=
dvd.intro (!mul.comm ▸ H)
theorem dvd_of_mul_left_eq {a b c : A} (H : c * a = b) : a b := dvd.intro_left H
theorem exists_eq_mul_right_of_dvd {a b : A} (H : a b) : Σc, b = a * c := H
theorem dvd.elim {P : Type} {a b : A} (H₁ : a b) (H₂ : Πc, b = a * c → P) : P :=
sigma.rec_on H₁ H₂
theorem exists_eq_mul_left_of_dvd {a b : A} (H : a b) : Σc, b = c * a :=
dvd.elim H (take c, assume H1 : b = a * c, sigma.mk c (H1 ⬝ !mul.comm))
theorem dvd.elim_left {P : Type} {a b : A} (H₁ : a b) (H₂ : Πc, b = c * a → P) : P :=
sigma.rec_on (exists_eq_mul_left_of_dvd H₁) (take c, assume H₃ : b = c * a, H₂ c H₃)
theorem dvd.refl : a a := dvd.intro !mul_one
theorem dvd.trans {a b c : A} (H₁ : a b) (H₂ : b c) : a c :=
dvd.elim H₁
(take d, assume H₃ : b = a * d,
dvd.elim H₂
(take e, assume H₄ : c = b * e,
dvd.intro
(show a * (d * e) = c, by rewrite [-mul.assoc, -H₃, H₄])))
theorem eq_zero_of_zero_dvd {a : A} (H : 0 a) : a = 0 :=
dvd.elim H (take c, assume H' : a = 0 * c, H' ⬝ !zero_mul)
theorem dvd_zero : a 0 := dvd.intro !mul_zero
theorem one_dvd : 1 a := dvd.intro !one_mul
theorem dvd_mul_right : a a * b := dvd.intro rfl
theorem dvd_mul_left : a b * a := mul.comm a b ▸ dvd_mul_right a b
theorem dvd_mul_of_dvd_left {a b : A} (H : a b) (c : A) : a b * c :=
dvd.elim H
(take d,
suppose b = a * d,
dvd.intro
(show a * (d * c) = b * c, from by rewrite [-mul.assoc]; substvars))
theorem dvd_mul_of_dvd_right {a b : A} (H : a b) (c : A) : a c * b :=
!mul.comm ▸ (dvd_mul_of_dvd_left H _)
theorem mul_dvd_mul {a b c d : A} (dvd_ab : a b) (dvd_cd : c d) : a * c b * d :=
dvd.elim dvd_ab
(take e, suppose b = a * e,
dvd.elim dvd_cd
(take f, suppose d = c * f,
dvd.intro
(show a * c * (e * f) = b * d,
by rewrite [mul.assoc, {c*_}mul.left_comm, -mul.assoc]; substvars)))
theorem dvd_of_mul_right_dvd {a b c : A} (H : a * b c) : a c :=
dvd.elim H (take d, assume Habdc : c = a * b * d, dvd.intro (!mul.assoc⁻¹ ⬝ Habdc⁻¹))
theorem dvd_of_mul_left_dvd {a b c : A} (H : a * b c) : b c :=
dvd_of_mul_right_dvd (mul.comm a b ▸ H)
theorem dvd_add {a b c : A} (Hab : a b) (Hac : a c) : a b + c :=
dvd.elim Hab
(take d, suppose b = a * d,
dvd.elim Hac
(take e, suppose c = a * e,
dvd.intro (show a * (d + e) = b + c,
by rewrite [left_distrib]; substvars)))
end comm_semiring
/- ring -/
structure ring (A : Type) extends ab_group A renaming mul→add mul_assoc→add_assoc
one→zero one_mul→zero_add mul_one→add_zero inv→neg mul_left_inv→add_left_inv mul_comm→add_comm,
monoid A, distrib A
/- we make it a class now (and not as part of the structure) to avoid
ring.to_ab_group to be an instance -/
attribute ring [class]
definition add_ab_group_of_ring [reducible] [trans_instance] (A : Type)
[H : ring A] : add_ab_group A :=
@ring.to_ab_group A H
definition monoid_of_ring [reducible] [trans_instance] (A : Type)
[H : ring A] : monoid A :=
@ring.to_monoid A H
definition distrib_of_ring [reducible] [trans_instance] (A : Type)
[H : ring A] : distrib A :=
@ring.to_distrib A H
theorem ring.mul_zero [s : ring A] (a : A) : a * 0 = 0 :=
have a * 0 + 0 = a * 0 + a * 0, from calc
a * 0 + 0 = a * 0 : by rewrite add_zero
... = a * (0 + 0) : by rewrite add_zero
... = a * 0 + a * 0 : by rewrite {a*_}ring.left_distrib,
show a * 0 = 0, from (add.left_cancel this)⁻¹
theorem ring.zero_mul [s : ring A] (a : A) : 0 * a = 0 :=
have 0 * a + 0 = 0 * a + 0 * a, from calc
0 * a + 0 = 0 * a : by rewrite add_zero
... = (0 + 0) * a : by rewrite add_zero
... = 0 * a + 0 * a : by rewrite {_*a}ring.right_distrib,
show 0 * a = 0, from (add.left_cancel this)⁻¹
definition ring.to_semiring [reducible] [trans_instance] [s : ring A] : semiring A :=
⦃ semiring, s,
mul_zero := ring.mul_zero,
zero_mul := ring.zero_mul ⦄
section
variables [s : ring A] (a b c d e : A)
include s
theorem neg_mul_eq_neg_mul : -(a * b) = -a * b :=
neg_eq_of_add_eq_zero
begin
rewrite [-right_distrib, add.right_inv, zero_mul]
end
theorem neg_mul_eq_mul_neg : -(a * b) = a * -b :=
neg_eq_of_add_eq_zero
begin
rewrite [-left_distrib, add.right_inv, mul_zero]
end
theorem neg_mul_eq_neg_mul_symm : - a * b = - (a * b) := inverse !neg_mul_eq_neg_mul
theorem mul_neg_eq_neg_mul_symm : a * - b = - (a * b) := inverse !neg_mul_eq_mul_neg
theorem neg_mul_neg : -a * -b = a * b :=
calc
-a * -b = -(a * -b) : by rewrite -neg_mul_eq_neg_mul
... = - -(a * b) : by rewrite -neg_mul_eq_mul_neg
... = a * b : by rewrite neg_neg
theorem neg_mul_comm : -a * b = a * -b := !neg_mul_eq_neg_mul⁻¹ ⬝ !neg_mul_eq_mul_neg
theorem neg_eq_neg_one_mul : -a = -1 * a :=
calc
-a = -(1 * a) : by rewrite one_mul
... = -1 * a : by rewrite neg_mul_eq_neg_mul
theorem mul_sub_left_distrib : a * (b - c) = a * b - a * c :=
calc
a * (b - c) = a * b + a * -c : left_distrib
... = a * b + - (a * c) : by rewrite -neg_mul_eq_mul_neg
... = a * b - a * c : rfl
theorem mul_sub_right_distrib : (a - b) * c = a * c - b * c :=
calc
(a - b) * c = a * c + -b * c : right_distrib
... = a * c + - (b * c) : by rewrite neg_mul_eq_neg_mul
... = a * c - b * c : rfl
-- TODO: can calc mode be improved to make this easier?
-- TODO: there is also the other direction. It will be easier when we
-- have the simplifier.
theorem mul_add_eq_mul_add_iff_sub_mul_add_eq : a * e + c = b * e + d ↔ (a - b) * e + c = d :=
calc
a * e + c = b * e + d ↔ a * e + c = d + b * e : by rewrite {b*e+_}add.comm
... ↔ a * e + c - b * e = d : iff.symm !sub_eq_iff_eq_add
... ↔ a * e - b * e + c = d : by rewrite sub_add_eq_add_sub
... ↔ (a - b) * e + c = d : by rewrite mul_sub_right_distrib
theorem mul_add_eq_mul_add_of_sub_mul_add_eq : (a - b) * e + c = d → a * e + c = b * e + d :=
iff.mpr !mul_add_eq_mul_add_iff_sub_mul_add_eq
theorem sub_mul_add_eq_of_mul_add_eq_mul_add : a * e + c = b * e + d → (a - b) * e + c = d :=
iff.mp !mul_add_eq_mul_add_iff_sub_mul_add_eq
theorem mul_neg_one_eq_neg : a * (-1) = -a :=
have a + a * -1 = 0, from calc
a + a * -1 = a * 1 + a * -1 : mul_one
... = a * (1 + -1) : left_distrib
... = a * 0 : by rewrite add.right_inv
... = 0 : mul_zero,
symm (neg_eq_of_add_eq_zero this)
theorem ne_zero_prod_ne_zero_of_mul_ne_zero {a b : A} (H : a * b ≠ 0) : a ≠ 0 × b ≠ 0 :=
have a ≠ 0, from
(suppose a = 0,
have a * b = 0, by rewrite [this, zero_mul],
absurd this H),
have b ≠ 0, from
(suppose b = 0,
have a * b = 0, by rewrite [this, mul_zero],
absurd this H),
prod.mk `a ≠ 0` `b ≠ 0`
end
structure comm_ring [class] (A : Type) extends ring A, comm_semigroup A
definition comm_ring.to_comm_semiring [reducible] [trans_instance] [s : comm_ring A] :
comm_semiring A :=
⦃ comm_semiring, s,
mul_zero := mul_zero,
zero_mul := zero_mul ⦄
section
variables [s : comm_ring A] (a b c d e : A)
include s
theorem mul_self_sub_mul_self_eq : a * a - b * b = (a + b) * (a - b) :=
begin
krewrite [left_distrib, *right_distrib, add.assoc],
rewrite [-{b*a + _}add.assoc,
-*neg_mul_eq_mul_neg, {a*b}mul.comm, add.right_inv, zero_add]
end
theorem mul_self_sub_one_eq : a * a - 1 = (a + 1) * (a - 1) :=
by rewrite [-mul_self_sub_mul_self_eq, mul_one]
theorem dvd_neg_iff_dvd : (a -b) ↔ (a b) :=
iff.intro
(suppose a -b,
dvd.elim this
(take c, suppose -b = a * c,
dvd.intro
(show a * -c = b,
by rewrite [-neg_mul_eq_mul_neg, -this, neg_neg])))
(suppose a b,
dvd.elim this
(take c, suppose b = a * c,
dvd.intro
(show a * -c = -b,
by rewrite [-neg_mul_eq_mul_neg, -this])))
theorem dvd_neg_of_dvd : (a b) → (a -b) :=
iff.mpr !dvd_neg_iff_dvd
theorem dvd_of_dvd_neg : (a -b) → (a b) :=
iff.mp !dvd_neg_iff_dvd
theorem neg_dvd_iff_dvd : (-a b) ↔ (a b) :=
iff.intro
(suppose -a b,
dvd.elim this
(take c, suppose b = -a * c,
dvd.intro
(show a * -c = b, by rewrite [-neg_mul_comm, this])))
(suppose a b,
dvd.elim this
(take c, suppose b = a * c,
dvd.intro
(show -a * -c = b, by rewrite [neg_mul_neg, this])))
theorem neg_dvd_of_dvd : (a b) → (-a b) :=
iff.mpr !neg_dvd_iff_dvd
theorem dvd_of_neg_dvd : (-a b) → (a b) :=
iff.mp !neg_dvd_iff_dvd
theorem dvd_sub (H₁ : (a b)) (H₂ : (a c)) : (a b - c) :=
dvd_add H₁ (!dvd_neg_of_dvd H₂)
end
/- integral domains -/
structure no_zero_divisors [class] (A : Type) extends has_mul A, has_zero A :=
(eq_zero_sum_eq_zero_of_mul_eq_zero : Πa b, mul a b = zero → a = zero ⊎ b = zero)
definition eq_zero_sum_eq_zero_of_mul_eq_zero {A : Type} [s : no_zero_divisors A] {a b : A}
(H : a * b = 0) :
a = 0 ⊎ b = 0 := !no_zero_divisors.eq_zero_sum_eq_zero_of_mul_eq_zero H
structure integral_domain [class] (A : Type) extends comm_ring A, no_zero_divisors A,
zero_ne_one_class A
section
variables [s : integral_domain A] (a b c d e : A)
include s
theorem mul_ne_zero {a b : A} (H1 : a ≠ 0) (H2 : b ≠ 0) : a * b ≠ 0 :=
suppose a * b = 0,
sum.elim (eq_zero_sum_eq_zero_of_mul_eq_zero this) (assume H3, H1 H3) (assume H4, H2 H4)
theorem eq_of_mul_eq_mul_right {a b c : A} (Ha : a ≠ 0) (H : b * a = c * a) : b = c :=
have b * a - c * a = 0, from iff.mp !eq_iff_sub_eq_zero H,
have (b - c) * a = 0, by rewrite [mul_sub_right_distrib, this],
have b - c = 0, from sum_resolve_left (eq_zero_sum_eq_zero_of_mul_eq_zero this) Ha,
iff.elim_right !eq_iff_sub_eq_zero this
theorem eq_of_mul_eq_mul_left {a b c : A} (Ha : a ≠ 0) (H : a * b = a * c) : b = c :=
have a * b - a * c = 0, from iff.mp !eq_iff_sub_eq_zero H,
have a * (b - c) = 0, by rewrite [mul_sub_left_distrib, this],
have b - c = 0, from sum_resolve_right (eq_zero_sum_eq_zero_of_mul_eq_zero this) Ha,
iff.elim_right !eq_iff_sub_eq_zero this
-- TODO: do we want the iff versions?
theorem eq_zero_of_mul_eq_self_right {a b : A} (H₁ : b ≠ 1) (H₂ : a * b = a) : a = 0 :=
have b - 1 ≠ 0, from
suppose b - 1 = 0, H₁ (!zero_add ▸ eq_add_of_sub_eq this),
have a * b - a = 0, by rewrite H₂; apply sub_self,
have a * (b - 1) = 0, by rewrite [mul_sub_left_distrib, mul_one]; apply this,
show a = 0, from sum_resolve_left (eq_zero_sum_eq_zero_of_mul_eq_zero this) `b - 1 ≠ 0`
theorem eq_zero_of_mul_eq_self_left {a b : A} (H₁ : b ≠ 1) (H₂ : b * a = a) : a = 0 :=
eq_zero_of_mul_eq_self_right H₁ (!mul.comm ▸ H₂)
theorem mul_self_eq_mul_self_iff (a b : A) : a * a = b * b ↔ a = b ⊎ a = -b :=
iff.intro
(suppose a * a = b * b,
have (a - b) * (a + b) = 0,
by rewrite [mul.comm, -mul_self_sub_mul_self_eq, this, sub_self],
have a - b = 0 ⊎ a + b = 0, from !eq_zero_sum_eq_zero_of_mul_eq_zero this,
sum.elim this
(suppose a - b = 0, sum.inl (eq_of_sub_eq_zero this))
(suppose a + b = 0, sum.inr (eq_neg_of_add_eq_zero this)))
(suppose a = b ⊎ a = -b, sum.elim this
(suppose a = b, by rewrite this)
(suppose a = -b, by rewrite [this, neg_mul_neg]))
theorem mul_self_eq_one_iff (a : A) : a * a = 1 ↔ a = 1 ⊎ a = -1 :=
have a * a = 1 * 1 ↔ a = 1 ⊎ a = -1, from mul_self_eq_mul_self_iff a 1,
by rewrite mul_one at this; exact this
-- TODO: c - b * c → c = 0 ⊎ b = 1 and variants
theorem dvd_of_mul_dvd_mul_left {a b c : A} (Ha : a ≠ 0) (Hdvd : (a * b a * c)) : (b c) :=
dvd.elim Hdvd
(take d,
suppose a * c = a * b * d,
have b * d = c, from eq_of_mul_eq_mul_left Ha (mul.assoc a b d ▸ this⁻¹),
dvd.intro this)
theorem dvd_of_mul_dvd_mul_right {a b c : A} (Ha : a ≠ 0) (Hdvd : (b * a c * a)) : (b c) :=
dvd.elim Hdvd
(take d,
suppose c * a = b * a * d,
have b * d * a = c * a, from by rewrite [mul.right_comm, -this],
have b * d = c, from eq_of_mul_eq_mul_right Ha this,
dvd.intro this)
end
namespace norm_num
theorem mul_zero [s : mul_zero_class A] (a : A) : a * zero = zero :=
by rewrite [↑zero, mul_zero]
theorem zero_mul [s : mul_zero_class A] (a : A) : zero * a = zero :=
by rewrite [↑zero, zero_mul]
theorem mul_one [s : monoid A] (a : A) : a * one = a :=
by rewrite [↑one, mul_one]
theorem mul_bit0 [s : distrib A] (a b : A) : a * (bit0 b) = bit0 (a * b) :=
by rewrite [↑bit0, left_distrib]
theorem mul_bit0_helper [s : distrib A] (a b t : A) (H : a * b = t) : a * (bit0 b) = bit0 t :=
by rewrite -H; apply mul_bit0
theorem mul_bit1 [s : semiring A] (a b : A) : a * (bit1 b) = bit0 (a * b) + a :=
by rewrite [↑bit1, ↑bit0, +left_distrib, ↑one, mul_one]
theorem mul_bit1_helper [s : semiring A] (a b s t : A) (Hs : a * b = s) (Ht : bit0 s + a = t) :
a * (bit1 b) = t :=
begin rewrite [-Ht, -Hs, mul_bit1] end
theorem subst_into_prod [s : has_mul A] (l r tl tr t : A) (prl : l = tl) (prr : r = tr)
(prt : tl * tr = t) :
l * r = t :=
by rewrite [prl, prr, prt]
theorem mk_cong (op : A → A) (a b : A) (H : a = b) : op a = op b :=
by congruence; exact H
theorem mk_eq (a : A) : a = a := rfl
theorem neg_add_neg_eq_of_add_add_eq_zero [s : add_ab_group A] (a b c : A) (H : c + a + b = 0) :
-a + -b = c :=
begin
apply add_neg_eq_of_eq_add,
apply neg_eq_of_add_eq_zero,
rewrite [add.comm, add.assoc, add.comm b, -add.assoc, H]
end
theorem neg_add_neg_helper [s : add_ab_group A] (a b c : A) (H : a + b = c) : -a + -b = -c :=
begin apply iff.mp !neg_eq_neg_iff_eq, rewrite [neg_add, *neg_neg, H] end
theorem neg_add_pos_eq_of_eq_add [s : add_ab_group A] (a b c : A) (H : b = c + a) : -a + b = c :=
begin apply neg_add_eq_of_eq_add, rewrite add.comm, exact H end
theorem neg_add_pos_helper1 [s : add_ab_group A] (a b c : A) (H : b + c = a) : -a + b = -c :=
begin apply neg_add_eq_of_eq_add, apply eq_add_neg_of_add_eq H end
theorem neg_add_pos_helper2 [s : add_ab_group A] (a b c : A) (H : a + c = b) : -a + b = c :=
begin apply neg_add_eq_of_eq_add, rewrite H end
theorem pos_add_neg_helper [s : add_ab_group A] (a b c : A) (H : b + a = c) : a + b = c :=
by rewrite [add.comm, H]
theorem sub_eq_add_neg_helper [s : add_ab_group A] (t₁ t₂ e w₁ w₂: A) (H₁ : t₁ = w₁)
(H₂ : t₂ = w₂) (H : w₁ + -w₂ = e) : t₁ - t₂ = e :=
by rewrite [sub_eq_add_neg, H₁, H₂, H]
theorem pos_add_pos_helper [s : add_ab_group A] (a b c h₁ h₂ : A) (H₁ : a = h₁) (H₂ : b = h₂)
(H : h₁ + h₂ = c) : a + b = c :=
by rewrite [H₁, H₂, H]
theorem subst_into_subtr [s : add_group A] (l r t : A) (prt : l + -r = t) : l - r = t :=
by rewrite [sub_eq_add_neg, prt]
theorem neg_neg_helper [s : add_group A] (a b : A) (H : a = -b) : -a = b :=
by rewrite [H, neg_neg]
theorem neg_mul_neg_helper [s : ring A] (a b c : A) (H : a * b = c) : (-a) * (-b) = c :=
begin rewrite [neg_mul_neg, H] end
theorem neg_mul_pos_helper [s : ring A] (a b c : A) (H : a * b = c) : (-a) * b = -c :=
begin rewrite [-neg_mul_eq_neg_mul, H] end
theorem pos_mul_neg_helper [s : ring A] (a b c : A) (H : a * b = c) : a * (-b) = -c :=
begin rewrite [-neg_mul_comm, -neg_mul_eq_neg_mul, H] end
end norm_num
end algebra
open algebra
attribute [simp]
zero_mul mul_zero
at simplifier.unit
attribute [simp]
neg_mul_eq_neg_mul_symm mul_neg_eq_neg_mul_symm
at simplifier.neg
attribute [simp]
left_distrib right_distrib
at simplifier.distrib

View file

@ -1,101 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
truncating an ∞-group to a group
-/
import hit.trunc algebra.bundled
open eq is_trunc trunc
namespace algebra
section
parameters (n : trunc_index) {A : Type} [inf_group A]
local abbreviation G := trunc n A
definition trunc_mul [unfold 9 10] (g h : G) : G :=
begin
induction g with p,
induction h with q,
exact tr (p * q)
end
definition trunc_inv [unfold 9] (g : G) : G :=
begin
induction g with p,
exact tr p⁻¹
end
definition trunc_one [constructor] : G :=
tr 1
local notation 1 := trunc_one
local postfix ⁻¹ := trunc_inv
local infix * := trunc_mul
theorem trunc_mul_assoc (g₁ g₂ g₃ : G) : g₁ * g₂ * g₃ = g₁ * (g₂ * g₃) :=
begin
induction g₁ with p₁,
induction g₂ with p₂,
induction g₃ with p₃,
exact ap tr !mul.assoc,
end
theorem trunc_one_mul (g : G) : 1 * g = g :=
begin
induction g with p,
exact ap tr !one_mul
end
theorem trunc_mul_one (g : G) : g * 1 = g :=
begin
induction g with p,
exact ap tr !mul_one
end
theorem trunc_mul_left_inv (g : G) : g⁻¹ * g = 1 :=
begin
induction g with p,
exact ap tr !mul.left_inv
end
parameter (A)
definition trunc_inf_group [constructor] [instance] : inf_group (trunc n A) :=
⦃inf_group,
mul := algebra.trunc_mul n,
mul_assoc := algebra.trunc_mul_assoc n,
one := algebra.trunc_one n,
one_mul := algebra.trunc_one_mul n,
mul_one := algebra.trunc_mul_one n,
inv := algebra.trunc_inv n,
mul_left_inv := algebra.trunc_mul_left_inv n⦄
definition trunc_group [constructor] : group (trunc 0 A) :=
group_of_inf_group _
end
section
variables (n : trunc_index) {A : Type} [ab_inf_group A]
theorem trunc_mul_comm (g h : trunc n A) : trunc_mul n g h = trunc_mul n h g :=
begin
induction g with p,
induction h with q,
exact ap tr !mul.comm
end
variable (A)
definition trunc_ab_inf_group [constructor] [instance] : ab_inf_group (trunc n A) :=
⦃ab_inf_group, trunc_inf_group n A, mul_comm := algebra.trunc_mul_comm n⦄
definition trunc_ab_group [constructor] : ab_group (trunc 0 A) :=
ab_group_of_ab_inf_group _
end
end algebra

View file

@ -1,249 +0,0 @@
/-
Copyright (c) 2014 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Floris van Doorn
Theorems about functions with multiple arguments
-/
variables {A U V W X Y Z : Type} {B : A → Type} {C : Πa, B a → Type} {D : Πa b, C a b → Type}
{E : Πa b c, D a b c → Type} {F : Πa b c d, E a b c d → Type}
{G : Πa b c d e, F a b c d e → Type} {H : Πa b c d e f, G a b c d e f → Type}
variables {a a' : A} {u u' : U} {v v' : V} {w w' : W} {x x' x'' : X} {y y' : Y} {z z' : Z}
{b : B a} {b' : B a'}
{c : C a b} {c' : C a' b'}
{d : D a b c} {d' : D a' b' c'}
{e : E a b c d} {e' : E a' b' c' d'}
{ff : F a b c d e} {f' : F a' b' c' d' e'}
{g : G a b c d e ff} {g' : G a' b' c' d' e' f'}
{h : H a b c d e ff g} {h' : H a' b' c' d' e' f' g'}
namespace eq
/-
Naming convention:
The theorem which states how to construct an path between two function applications is
api₀i₁...iₙ.
Here i₀, ... iₙ are digits, n is the arity of the function(s),
and iⱼ specifies the dimension of the path between the jᵗʰ argument
(i₀ specifies the dimension of the path between the functions).
A value iⱼ ≡ 0 means that the jᵗʰ arguments are definitionally equal
The functions are non-dependent, except when the theorem name contains trailing zeroes
(where the function is dependent only in the arguments where it doesn't result in any
transports in the theorem statement).
For the fully-dependent versions (except that the conclusion doesn't contain a transport)
we write
apdi₀i₁...iₙ.
For versions where only some arguments depend on some other arguments,
or for versions with transport in the conclusion (like apdt), we don't have a
consistent naming scheme (yet).
We don't prove each theorem systematically, but prove only the ones which we actually need.
-/
definition homotopy2 [reducible] (f g : Πa b, C a b) : Type :=
Πa b, f a b = g a b
definition homotopy3 [reducible] (f g : Πa b c, D a b c) : Type :=
Πa b c, f a b c = g a b c
definition homotopy4 [reducible] (f g : Πa b c d, E a b c d) : Type :=
Πa b c d, f a b c d = g a b c d
infix ` ~2 `:50 := homotopy2
infix ` ~3 `:50 := homotopy3
definition ap0111 (f : U → V → W → X) (Hu : u = u') (Hv : v = v') (Hw : w = w')
: f u v w = f u' v' w' :=
by cases Hu; congruence; repeat assumption
definition ap01111 (f : U → V → W → X → Y)
(Hu : u = u') (Hv : v = v') (Hw : w = w') (Hx : x = x')
: f u v w x = f u' v' w' x' :=
by cases Hu; congruence; repeat assumption
definition ap011111 (f : U → V → W → X → Y → Z)
(Hu : u = u') (Hv : v = v') (Hw : w = w') (Hx : x = x') (Hy : y = y')
: f u v w x y = f u' v' w' x' y' :=
by cases Hu; congruence; repeat assumption
definition ap0111111 (f : U → V → W → X → Y → Z → A)
(Hu : u = u') (Hv : v = v') (Hw : w = w') (Hx : x = x') (Hy : y = y') (Hz : z = z')
: f u v w x y z = f u' v' w' x' y' z' :=
by cases Hu; congruence; repeat assumption
definition ap010 (f : X → Πa, B a) (Hx : x = x') : f x ~ f x' :=
by intros; cases Hx; reflexivity
definition ap0100 (f : X → Πa b, C a b) (Hx : x = x') : f x ~2 f x' :=
by intros; cases Hx; reflexivity
definition ap01000 (f : X → Πa b c, D a b c) (Hx : x = x') : f x ~3 f x' :=
by intros; cases Hx; reflexivity
definition apdt011 (f : Πa, B a → Z) (Ha : a = a') (Hb : transport B Ha b = b')
: f a b = f a' b' :=
by cases Ha; cases Hb; reflexivity
definition apdt0111 (f : Πa b, C a b → Z) (Ha : a = a') (Hb : transport B Ha b = b')
(Hc : cast (apdt011 C Ha Hb) c = c')
: f a b c = f a' b' c' :=
by cases Ha; cases Hb; cases Hc; reflexivity
definition apdt01111 (f : Πa b c, D a b c → Z) (Ha : a = a') (Hb : transport B Ha b = b')
(Hc : cast (apdt011 C Ha Hb) c = c') (Hd : cast (apdt0111 D Ha Hb Hc) d = d')
: f a b c d = f a' b' c' d' :=
by cases Ha; cases Hb; cases Hc; cases Hd; reflexivity
definition apdt011111 (f : Πa b c d, E a b c d → Z) (Ha : a = a') (Hb : transport B Ha b = b')
(Hc : cast (apdt011 C Ha Hb) c = c') (Hd : cast (apdt0111 D Ha Hb Hc) d = d')
(He : cast (apdt01111 E Ha Hb Hc Hd) e = e')
: f a b c d e = f a' b' c' d' e' :=
by cases Ha; cases Hb; cases Hc; cases Hd; cases He; reflexivity
definition apdt0111111 (f : Πa b c d e, F a b c d e → Z) (Ha : a = a') (Hb : transport B Ha b = b')
(Hc : cast (apdt011 C Ha Hb) c = c') (Hd : cast (apdt0111 D Ha Hb Hc) d = d')
(He : cast (apdt01111 E Ha Hb Hc Hd) e = e') (Hf : cast (apdt011111 F Ha Hb Hc Hd He) ff = f')
: f a b c d e ff = f a' b' c' d' e' f' :=
begin cases Ha, cases Hb, cases Hc, cases Hd, cases He, cases Hf, reflexivity end
-- definition apd0111111 (f : Πa b c d e ff, G a b c d e ff → Z) (Ha : a = a') (Hb : transport B Ha b = b')
-- (Hc : cast (apd011 C Ha Hb) c = c') (Hd : cast (apd0111 D Ha Hb Hc) d = d')
-- (He : cast (apd01111 E Ha Hb Hc Hd) e = e') (Hf : cast (apd011111 F Ha Hb Hc Hd He) ff = f')
-- (Hg : cast (apd0111111 G Ha Hb Hc Hd He Hf) g = g')
-- : f a b c d e ff g = f a' b' c' d' e' f' g' :=
-- by cases Ha; cases Hb; cases Hc; cases Hd; cases He; cases Hf; cases Hg; reflexivity
-- definition apd01111111 (f : Πa b c d e ff g, G a b c d e ff g → Z) (Ha : a = a') (Hb : transport B Ha b = b')
-- (Hc : cast (apd011 C Ha Hb) c = c') (Hd : cast (apd0111 D Ha Hb Hc) d = d')
-- (He : cast (apd01111 E Ha Hb Hc Hd) e = e') (Hf : cast (apd011111 F Ha Hb Hc Hd He) ff = f')
-- (Hg : cast (apd0111111 G Ha Hb Hc Hd He Hf) g = g') (Hh : cast (apd01111111 H Ha Hb Hc Hd He Hf Hg) h = h')
-- : f a b c d e ff g h = f a' b' c' d' e' f' g' h' :=
-- by cases Ha; cases Hb; cases Hc; cases Hd; cases He; cases Hf; cases Hg; cases Hh; reflexivity
definition apd100 [unfold 6] {f g : Πa b, C a b} (p : f = g) : f ~2 g :=
λa b, apd10 (apd10 p a) b
definition apd1000 [unfold 7] {f g : Πa b c, D a b c} (p : f = g) : f ~3 g :=
λa b c, apd100 (apd10 p a) b c
/- some properties of these variants of ap -/
-- we only prove what we currently need
definition ap010_con (f : X → Πa, B a) (p : x = x') (q : x' = x'') :
ap010 f (p ⬝ q) a = ap010 f p a ⬝ ap010 f q a :=
eq.rec_on q (eq.rec_on p idp)
definition ap010_ap (f : X → Πa, B a) (g : Y → X) (p : y = y') :
ap010 f (ap g p) a = ap010 (λy, f (g y)) p a :=
eq.rec_on p idp
/- the following theorems are function extentionality for functions with multiple arguments -/
definition eq_of_homotopy2 {f g : Πa b, C a b} (H : f ~2 g) : f = g :=
eq_of_homotopy (λa, eq_of_homotopy (H a))
definition eq_of_homotopy3 {f g : Πa b c, D a b c} (H : f ~3 g) : f = g :=
eq_of_homotopy (λa, eq_of_homotopy2 (H a))
definition eq_of_homotopy2_id (f : Πa b, C a b)
: eq_of_homotopy2 (λa b, idpath (f a b)) = idpath f :=
begin
transitivity eq_of_homotopy (λ a, idpath (f a)),
{apply (ap eq_of_homotopy), apply eq_of_homotopy, intros, apply eq_of_homotopy_idp},
apply eq_of_homotopy_idp
end
definition eq_of_homotopy3_id (f : Πa b c, D a b c)
: eq_of_homotopy3 (λa b c, idpath (f a b c)) = idpath f :=
begin
transitivity _,
{apply (ap eq_of_homotopy), apply eq_of_homotopy, intros, apply eq_of_homotopy2_id},
apply eq_of_homotopy_idp
end
definition eq_of_homotopy2_inv {f g : Πa b, C a b} (H : f ~2 g)
: eq_of_homotopy2 (λa b, (H a b)⁻¹) = (eq_of_homotopy2 H)⁻¹ :=
ap eq_of_homotopy (eq_of_homotopy (λa, !eq_of_homotopy_inv)) ⬝ !eq_of_homotopy_inv
definition eq_of_homotopy3_inv {f g : Πa b c, D a b c} (H : f ~3 g)
: eq_of_homotopy3 (λa b c, (H a b c)⁻¹) = (eq_of_homotopy3 H)⁻¹ :=
ap eq_of_homotopy (eq_of_homotopy (λa, !eq_of_homotopy2_inv)) ⬝ !eq_of_homotopy_inv
definition eq_of_homotopy2_con {f g h : Πa b, C a b} (H1 : f ~2 g) (H2 : g ~2 h)
: eq_of_homotopy2 (λa b, H1 a b ⬝ H2 a b) = eq_of_homotopy2 H1 ⬝ eq_of_homotopy2 H2 :=
ap eq_of_homotopy (eq_of_homotopy (λa, !eq_of_homotopy_con)) ⬝ !eq_of_homotopy_con
definition eq_of_homotopy3_con {f g h : Πa b c, D a b c} (H1 : f ~3 g) (H2 : g ~3 h)
: eq_of_homotopy3 (λa b c, H1 a b c ⬝ H2 a b c) = eq_of_homotopy3 H1 ⬝ eq_of_homotopy3 H2 :=
ap eq_of_homotopy (eq_of_homotopy (λa, !eq_of_homotopy2_con)) ⬝ !eq_of_homotopy_con
end eq
open eq equiv is_equiv
namespace funext
definition is_equiv_apd100 [instance] (f g : Πa b, C a b)
: is_equiv (@apd100 A B C f g) :=
adjointify _
eq_of_homotopy2
begin
intro H, esimp [apd100, eq_of_homotopy2],
apply eq_of_homotopy, intro a,
apply concat, apply (ap (λx, apd10 (x a))), apply (right_inv apd10),
apply (right_inv apd10)
end
begin
intro p, cases p, apply eq_of_homotopy2_id
end
definition is_equiv_apd1000 [instance] (f g : Πa b c, D a b c)
: is_equiv (@apd1000 A B C D f g) :=
adjointify _
eq_of_homotopy3
begin
intro H, esimp,
apply eq_of_homotopy, intro a,
transitivity apd100 (eq_of_homotopy2 (H a)),
{apply ap (λx, apd100 (x a)),
apply right_inv apd10},
apply right_inv apd100
end
begin
intro p, cases p, apply eq_of_homotopy3_id
end
end funext
attribute funext.is_equiv_apd100 funext.is_equiv_apd1000 [constructor]
namespace eq
open funext
local attribute funext.is_equiv_apd100 [instance]
protected definition homotopy2.rec_on {f g : Πa b, C a b} {P : (f ~2 g) → Type}
(p : f ~2 g) (H : Π(q : f = g), P (apd100 q)) : P p :=
right_inv apd100 p ▸ H (eq_of_homotopy2 p)
protected definition homotopy3.rec_on {f g : Πa b c, D a b c} {P : (f ~3 g) → Type}
(p : f ~3 g) (H : Π(q : f = g), P (apd1000 q)) : P p :=
right_inv apd1000 p ▸ H (eq_of_homotopy3 p)
definition eq_equiv_homotopy2 [constructor] (f g : Πa b, C a b) : (f = g) ≃ (f ~2 g) :=
equiv.mk apd100 _
definition eq_equiv_homotopy3 [constructor] (f g : Πa b c, D a b c) : (f = g) ≃ (f ~3 g) :=
equiv.mk apd1000 _
definition apd10_ap (f : X → Πa, B a) (p : x = x')
: apd10 (ap f p) = ap010 f p :=
eq.rec_on p idp
definition eq_of_homotopy_ap010 (f : X → Πa, B a) (p : x = x')
: eq_of_homotopy (ap010 f p) = ap f p :=
inv_eq_of_eq !apd10_ap⁻¹
definition ap_eq_ap_of_homotopy {f : X → Πa, B a} {p q : x = x'} (H : ap010 f p ~ ap010 f q)
: ap f p = ap f q :=
calc
ap f p = eq_of_homotopy (ap010 f p) : eq_of_homotopy_ap010
... = eq_of_homotopy (ap010 f q) : eq_of_homotopy H
... = ap f q : eq_of_homotopy_ap010
end eq

View file

@ -1,88 +0,0 @@
import types.trunc types.bool
open eq bool equiv sigma sigma.ops trunc is_trunc pi
namespace choice
universe variable u
-- 3.8.1. The axiom of choice.
definition AC [reducible] := Π (X : Type.{u}) (A : X -> Type.{u}) (P : Π x, A x -> Type.{u}),
is_set X -> (Π x, is_set (A x)) -> (Π x a, is_prop (P x a)) ->
(Π x, ∥ Σ a, P x a ∥) -> ∥ Σ f, Π x, P x (f x) ∥
-- 3.8.3. Corresponds to the assertion that
-- "the cartesian product of a family of nonempty sets is nonempty".
definition AC_cart [reducible] := Π (X : Type.{u}) (A : X -> Type.{u}),
is_set X -> (Π x, is_set (A x)) -> (Π x, ∥ A x ∥) -> ∥ Π x, A x ∥
-- A slight variant of AC with a modified (equivalent) codomain.
definition AC' [reducible] := Π (X : Type.{u}) (A : X -> Type.{u}) (P : Π x, A x -> Type.{u}),
is_set X -> (Π x, is_set (A x)) -> (Π x a, is_prop (P x a))
-> (Π x, ∥ Σ a, P x a ∥) -> ∥ Π x, Σ a : A x, P x a ∥
-- The equivalence of AC and AC' follows from the equivalence of their codomains.
definition AC_equiv_AC' : AC.{u} ≃ AC'.{u} :=
equiv_of_is_prop
(λ H X A P HX HA HP HI, trunc_functor _ (to_fun !sigma_pi_equiv_pi_sigma) (H X A P HX HA HP HI))
(λ H X A P HX HA HP HI, trunc_functor _ (to_inv !sigma_pi_equiv_pi_sigma) (H X A P HX HA HP HI))
-- AC_cart can be derived from AC' by setting P := λ _ _ , unit.
definition AC_cart_of_AC' : AC'.{u} -> AC_cart.{u} :=
λ H X A HX HA HI, trunc_functor _ (λ H0 x, (H0 x).1)
(H X A (λ x a, lift.{0 u} unit) HX HA (λ x a, !is_trunc_lift)
(λ x, trunc_functor _ (λ a, ⟨a, lift.up.{0 u} unit.star⟩) (HI x)))
-- And the converse, by setting A := λ x, Σ a, P x a.
definition AC'_of_AC_cart : AC_cart.{u} -> AC'.{u} :=
by intro H X A P HX HA HP HI;
apply H X (λ x, Σ a, P x a) HX (λ x, !is_trunc_sigma) HI
-- Which is enough to show AC' ≃ AC_cart, since both are props.
definition AC'_equiv_AC_cart : AC'.{u} ≃ AC_cart.{u} :=
equiv_of_is_prop AC_cart_of_AC'.{u} AC'_of_AC_cart.{u}
-- 3.8.2. AC ≃ AC_cart follows by transitivity.
definition AC_equiv_AC_cart : AC.{u} ≃ AC_cart.{u} :=
equiv.trans AC_equiv_AC' AC'_equiv_AC_cart
namespace example385
definition X : Type.{1} := Σ A : Type.{0}, ∥ A = bool ∥
definition x0 : X := ⟨bool, merely.intro _ rfl⟩
definition Y : X -> Type.{1} := λ x, x0 = x
definition not_is_set_X : ¬ is_set X :=
begin
intro H, apply not_is_prop_bool_eq_bool,
apply @is_trunc_equiv_closed (x0 = x0),
apply equiv.symm !equiv_subtype
end
definition is_set_x1 (x : X) : is_set x.1 :=
by cases x; induction a_1; cases a_1; exact _
definition is_set_Yx (x : X) : is_set (Y x) :=
begin
apply @is_trunc_equiv_closed _ _ _ !equiv_subtype,
apply @is_trunc_equiv_closed _ _ _ (equiv.symm !eq_equiv_equiv),
apply is_trunc_equiv; repeat (apply is_set_x1)
end
definition trunc_Yx (x : X) : ∥ Y x ∥ :=
begin
cases x, induction a_1, apply merely.intro,
apply to_fun !equiv_subtype, rewrite a_1
end
end example385
open example385
-- 3.8.5. There exists a type X and a family Y : X → U such that each Y(x) is a set,
-- but such that (3.8.3) is false.
definition X_must_be_set : Σ (X : Type.{1}) (Y : X -> Type.{1})
(HA : Π x : X, is_set (Y x)), ¬ ((Π x : X, ∥ Y x ∥) -> ∥ Π x : X, Y x ∥) :=
⟨X, Y, is_set_Yx, λ H, trunc.rec_on (H trunc_Yx)
(λ H0, not_is_set_X (@is_trunc_of_is_contr _ _ (is_contr.mk x0 H0)))⟩
end choice

View file

@ -1,9 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
The core of the HoTT library
-/
import types cubical homotopy hit choice

View file

@ -1,349 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Floris van Doorn, Jakob von Raumer
Cubes
-/
import .square
open equiv is_equiv sigma sigma.ops
namespace eq
inductive cube {A : Type} {a₀₀₀ : A} : Π{a₂₀₀ a₀₂₀ a₂₂₀ a₀₀₂ a₂₀₂ a₀₂₂ a₂₂₂ : A}
{p₁₀₀ : a₀₀₀ = a₂₀₀} {p₀₁₀ : a₀₀₀ = a₀₂₀} {p₀₀₁ : a₀₀₀ = a₀₀₂}
{p₁₂₀ : a₀₂₀ = a₂₂₀} {p₂₁₀ : a₂₀₀ = a₂₂₀} {p₂₀₁ : a₂₀₀ = a₂₀₂}
{p₁₀₂ : a₀₀₂ = a₂₀₂} {p₀₁₂ : a₀₀₂ = a₀₂₂} {p₀₂₁ : a₀₂₀ = a₀₂₂}
{p₁₂₂ : a₀₂₂ = a₂₂₂} {p₂₁₂ : a₂₀₂ = a₂₂₂} {p₂₂₁ : a₂₂₀ = a₂₂₂}
(s₀₁₁ : square p₀₁₀ p₀₁₂ p₀₀₁ p₀₂₁)
(s₂₁₁ : square p₂₁₀ p₂₁₂ p₂₀₁ p₂₂₁)
(s₁₀₁ : square p₁₀₀ p₁₀₂ p₀₀₁ p₂₀₁)
(s₁₂₁ : square p₁₂₀ p₁₂₂ p₀₂₁ p₂₂₁)
(s₁₁₀ : square p₀₁₀ p₂₁₀ p₁₀₀ p₁₂₀)
(s₁₁₂ : square p₀₁₂ p₂₁₂ p₁₀₂ p₁₂₂), Type :=
idc : cube ids ids ids ids ids ids
variables {A B : Type} {a₀₀₀ a₂₀₀ a₀₂₀ a₂₂₀ a₀₀₂ a₂₀₂ a₀₂₂ a₂₂₂ a a' : A}
{p₁₀₀ : a₀₀₀ = a₂₀₀} {p₀₁₀ : a₀₀₀ = a₀₂₀} {p₀₀₁ : a₀₀₀ = a₀₀₂}
{p₁₂₀ : a₀₂₀ = a₂₂₀} {p₂₁₀ : a₂₀₀ = a₂₂₀} {p₂₀₁ : a₂₀₀ = a₂₀₂}
{p₁₀₂ : a₀₀₂ = a₂₀₂} {p₀₁₂ : a₀₀₂ = a₀₂₂} {p₀₂₁ : a₀₂₀ = a₀₂₂}
{p₁₂₂ : a₀₂₂ = a₂₂₂} {p₂₁₂ : a₂₀₂ = a₂₂₂} {p₂₂₁ : a₂₂₀ = a₂₂₂}
{s₁₁₀ : square p₀₁₀ p₂₁₀ p₁₀₀ p₁₂₀}
{s₁₁₂ : square p₀₁₂ p₂₁₂ p₁₀₂ p₁₂₂}
{s₀₁₁ : square p₀₁₀ p₀₁₂ p₀₀₁ p₀₂₁}
{s₂₁₁ : square p₂₁₀ p₂₁₂ p₂₀₁ p₂₂₁}
{s₁₀₁ : square p₁₀₀ p₁₀₂ p₀₀₁ p₂₀₁}
{s₁₂₁ : square p₁₂₀ p₁₂₂ p₀₂₁ p₂₂₁}
{b₁ b₂ b₃ b₄ : B}
(c : cube s₀₁₁ s₂₁₁ s₁₀₁ s₁₂₁ s₁₁₀ s₁₁₂)
definition idc [reducible] [constructor] := @cube.idc
definition idcube [reducible] [constructor] (a : A) := @cube.idc A a
variables (s₁₁₀ s₁₀₁)
definition refl1 : cube s₀₁₁ s₀₁₁ hrfl hrfl vrfl vrfl :=
by induction s₀₁₁; exact idc
definition refl2 : cube hrfl hrfl s₁₀₁ s₁₀₁ hrfl hrfl :=
by induction s₁₀₁; exact idc
definition refl3 : cube vrfl vrfl vrfl vrfl s₁₁₀ s₁₁₀ :=
by induction s₁₁₀; exact idc
variables {s₁₁₀ s₁₀₁}
definition rfl1 : cube s₀₁₁ s₀₁₁ hrfl hrfl vrfl vrfl := !refl1
definition rfl2 : cube hrfl hrfl s₁₀₁ s₁₀₁ hrfl hrfl := !refl2
definition rfl3 : cube vrfl vrfl vrfl vrfl s₁₁₀ s₁₁₀ := !refl3
-- Variables for composition
variables {a₄₀₀ a₄₀₂ a₄₂₀ a₄₂₂ a₀₄₀ a₀₄₂ a₂₄₀ a₂₄₂ a₀₀₄ a₀₂₄ a₂₀₄ a₂₂₄ : A}
{p₃₀₀ : a₂₀₀ = a₄₀₀} {p₃₀₂ : a₂₀₂ = a₄₀₂} {p₃₂₀ : a₂₂₀ = a₄₂₀} {p₃₂₂ : a₂₂₂ = a₄₂₂}
{p₄₀₁ : a₄₀₀ = a₄₀₂} {p₄₁₀ : a₄₀₀ = a₄₂₀} {p₄₁₂ : a₄₀₂ = a₄₂₂} {p₄₂₁ : a₄₂₀ = a₄₂₂}
{p₀₃₀ : a₀₂₀ = a₀₄₀} {p₀₃₂ : a₀₂₂ = a₀₄₂} {p₂₃₀ : a₂₂₀ = a₂₄₀} {p₂₃₂ : a₂₂₂ = a₂₄₂}
{p₀₄₁ : a₀₄₀ = a₀₄₂} {p₁₄₀ : a₀₄₀ = a₂₄₀} {p₁₄₂ : a₀₄₂ = a₂₄₂} {p₂₄₁ : a₂₄₀ = a₂₄₂}
{p₀₀₃ : a₀₀₂ = a₀₀₄} {p₀₂₃ : a₀₂₂ = a₀₂₄} {p₂₀₃ : a₂₀₂ = a₂₀₄} {p₂₂₃ : a₂₂₂ = a₂₂₄}
{p₀₁₄ : a₀₀₄ = a₀₂₄} {p₁₀₄ : a₀₀₄ = a₂₀₄} {p₁₂₄ : a₀₂₄ = a₂₂₄} {p₂₁₄ : a₂₀₄ = a₂₂₄}
{s₃₀₁ : square p₃₀₀ p₃₀₂ p₂₀₁ p₄₀₁} {s₃₁₀ : square p₂₁₀ p₄₁₀ p₃₀₀ p₃₂₀}
{s₃₁₂ : square p₂₁₂ p₄₁₂ p₃₀₂ p₃₂₂} {s₃₂₁ : square p₃₂₀ p₃₂₂ p₂₂₁ p₄₂₁}
{s₄₁₁ : square p₄₁₀ p₄₁₂ p₄₀₁ p₄₂₁}
{s₀₃₁ : square p₀₃₀ p₀₃₂ p₀₂₁ p₀₄₁} {s₁₃₀ : square p₀₃₀ p₂₃₀ p₁₂₀ p₁₄₀}
{s₁₃₂ : square p₀₃₂ p₂₃₂ p₁₂₂ p₁₄₂} {s₂₃₁ : square p₂₃₀ p₂₃₂ p₂₂₁ p₂₄₁}
{s₁₄₁ : square p₁₄₀ p₁₄₂ p₀₄₁ p₂₄₁}
{s₀₁₃ : square p₀₁₂ p₀₁₄ p₀₀₃ p₀₂₃} {s₁₀₃ : square p₁₀₂ p₁₀₄ p₀₀₃ p₂₀₃}
{s₁₂₃ : square p₁₂₂ p₁₂₄ p₀₂₃ p₂₂₃} {s₂₁₃ : square p₂₁₂ p₂₁₄ p₂₀₃ p₂₂₃}
{s₁₁₄ : square p₀₁₄ p₂₁₄ p₁₀₄ p₁₂₄}
(d : cube s₂₁₁ s₄₁₁ s₃₀₁ s₃₂₁ s₃₁₀ s₃₁₂)
(e : cube s₀₃₁ s₂₃₁ s₁₂₁ s₁₄₁ s₁₃₀ s₁₃₂)
(f : cube s₀₁₃ s₂₁₃ s₁₀₃ s₁₂₃ s₁₁₂ s₁₁₄)
/- Composition of Cubes -/
include c d
definition cube_concat1 : cube s₀₁₁ s₄₁₁ (s₁₀₁ ⬝h s₃₀₁) (s₁₂₁ ⬝h s₃₂₁) (s₁₁₀ ⬝v s₃₁₀) (s₁₁₂ ⬝v s₃₁₂) :=
by induction d; exact c
omit d
include e
definition cube_concat2 : cube (s₀₁₁ ⬝h s₀₃₁) (s₂₁₁ ⬝h s₂₃₁) s₁₀₁ s₁₄₁ (s₁₁₀ ⬝h s₁₃₀) (s₁₁₂ ⬝h s₁₃₂) :=
by induction e; exact c
omit e
include f
definition cube_concat3 : cube (s₀₁₁ ⬝v s₀₁₃) (s₂₁₁ ⬝v s₂₁₃) (s₁₀₁ ⬝v s₁₀₃) (s₁₂₁ ⬝v s₁₂₃) s₁₁₀ s₁₁₄ :=
by induction f; exact c
omit f c
definition eq_of_cube (c : cube s₀₁₁ s₂₁₁ s₁₀₁ s₁₂₁ s₁₁₀ s₁₁₂) :
transpose s₁₀₁⁻¹ᵛ ⬝h s₁₁₀ ⬝h transpose s₁₂₁ =
whisker_square (eq_bot_of_square s₀₁₁) (eq_bot_of_square s₂₁₁) idp idp s₁₁₂ :=
by induction c; reflexivity
definition eq_of_deg12_cube {s s' : square p₀₁₀ p₂₁₀ p₁₀₀ p₁₂₀}
(c : cube vrfl vrfl vrfl vrfl s s') : s = s' :=
by induction s; exact eq_of_cube c
definition square_pathover {A B : Type} {a a' : A} {b₁ b₂ b₃ b₄ : A → B}
{f₁ : b₁ ~ b₂} {f₂ : b₃ ~ b₄} {f₃ : b₁ ~ b₃} {f₄ : b₂ ~ b₄} {p : a = a'}
{q : square (f₁ a) (f₂ a) (f₃ a) (f₄ a)}
{r : square (f₁ a') (f₂ a') (f₃ a') (f₄ a')}
(s : cube (natural_square f₁ p) (natural_square f₂ p)
(natural_square f₃ p) (natural_square f₄ p) q r) : q =[p] r :=
by induction p; apply pathover_idp_of_eq; exact eq_of_deg12_cube s
-- a special case where the endpoints do not depend on `p`
definition square_pathover'
{f₁ : A → b₁ = b₂} {f₂ : A → b₃ = b₄} {f₃ : A → b₁ = b₃} {f₄ : A → b₂ = b₄}
{p : a = a'}
{q : square (f₁ a) (f₂ a) (f₃ a) (f₄ a)}
{r : square (f₁ a') (f₂ a') (f₃ a') (f₄ a')}
(s : cube (vdeg_square (ap f₁ p)) (vdeg_square (ap f₂ p))
(vdeg_square (ap f₃ p)) (vdeg_square (ap f₄ p)) q r) : q =[p] r :=
by induction p;apply pathover_idp_of_eq;exact eq_of_deg12_cube s
/- Transporting along a square -/
definition cube_transport110 {s₁₁₀' : square p₀₁₀ p₂₁₀ p₁₀₀ p₁₂₀}
(p : s₁₁₀ = s₁₁₀') (c : cube s₀₁₁ s₂₁₁ s₁₀₁ s₁₂₁ s₁₁₀ s₁₁₂) :
cube s₀₁₁ s₂₁₁ s₁₀₁ s₁₂₁ s₁₁₀' s₁₁₂ :=
by induction p; exact c
definition cube_transport112 {s₁₁₂' : square p₀₁₂ p₂₁₂ p₁₀₂ p₁₂₂}
(p : s₁₁₂ = s₁₁₂') (c : cube s₀₁₁ s₂₁₁ s₁₀₁ s₁₂₁ s₁₁₀ s₁₁₂) :
cube s₀₁₁ s₂₁₁ s₁₀₁ s₁₂₁ s₁₁₀ s₁₁₂':=
by induction p; exact c
definition cube_transport011 {s₀₁₁' : square p₀₁₀ p₀₁₂ p₀₀₁ p₀₂₁}
(p : s₀₁₁ = s₀₁₁') (c : cube s₀₁₁ s₂₁₁ s₁₀₁ s₁₂₁ s₁₁₀ s₁₁₂) :
cube s₀₁₁' s₂₁₁ s₁₀₁ s₁₂₁ s₁₁₀ s₁₁₂ :=
by induction p; exact c
definition cube_transport211 {s₂₁₁' : square p₂₁₀ p₂₁₂ p₂₀₁ p₂₂₁}
(p : s₂₁₁ = s₂₁₁') (c : cube s₀₁₁ s₂₁₁ s₁₀₁ s₁₂₁ s₁₁₀ s₁₁₂) :
cube s₀₁₁ s₂₁₁' s₁₀₁ s₁₂₁ s₁₁₀ s₁₁₂ :=
by induction p; exact c
definition cube_transport101 {s₁₀₁' : square p₁₀₀ p₁₀₂ p₀₀₁ p₂₀₁}
(p : s₁₀₁ = s₁₀₁') (c : cube s₀₁₁ s₂₁₁ s₁₀₁ s₁₂₁ s₁₁₀ s₁₁₂) :
cube s₀₁₁ s₂₁₁ s₁₀₁' s₁₂₁ s₁₁₀ s₁₁₂ :=
by induction p; exact c
definition cube_transport121 {s₁₂₁' : square p₁₂₀ p₁₂₂ p₀₂₁ p₂₂₁}
(p : s₁₂₁ = s₁₂₁') (c : cube s₀₁₁ s₂₁₁ s₁₀₁ s₁₂₁ s₁₁₀ s₁₁₂) :
cube s₀₁₁ s₂₁₁ s₁₀₁ s₁₂₁' s₁₁₀ s₁₁₂ :=
by induction p; exact c
/- Each equality between squares leads to a cube which is degenerate in one
dimension. -/
definition deg1_cube {s₁₁₀' : square p₀₁₀ p₂₁₀ p₁₀₀ p₁₂₀} (p : s₁₁₀ = s₁₁₀') :
cube s₁₁₀ s₁₁₀' hrfl hrfl vrfl vrfl :=
by induction p; exact rfl1
definition deg2_cube {s₁₁₀' : square p₀₁₀ p₂₁₀ p₁₀₀ p₁₂₀} (p : s₁₁₀ = s₁₁₀') :
cube hrfl hrfl s₁₁₀ s₁₁₀' hrfl hrfl :=
by induction p; exact rfl2
definition deg3_cube {s₁₁₀' : square p₀₁₀ p₂₁₀ p₁₀₀ p₁₂₀} (p : s₁₁₀ = s₁₁₀') :
cube vrfl vrfl vrfl vrfl s₁₁₀ s₁₁₀' :=
by induction p; exact rfl3
/- For each square of parralel equations, there are cubes where the square's
sides appear in a degenerated way and two opposite sides are ids's -/
section
variables {a₀ a₁ : A} {p₀₀ p₀₂ p₂₀ p₂₂ : a₀ = a₁} {s₁₀ : p₀₀ = p₂₀}
{s₁₂ : p₀₂ = p₂₂} {s₀₁ : p₀₀ = p₀₂} {s₂₁ : p₂₀ = p₂₂}
(sq : square s₁₀ s₁₂ s₀₁ s₂₁)
include sq
definition ids3_cube_of_square : cube (hdeg_square s₀₁)
(hdeg_square s₂₁) (hdeg_square s₁₀) (hdeg_square s₁₂) ids ids :=
by induction p₀₀; induction sq; apply idc
definition ids1_cube_of_square : cube ids ids
(vdeg_square s₁₀) (vdeg_square s₁₂) (hdeg_square s₀₁) (hdeg_square s₂₁) :=
by induction p₀₀; induction sq; apply idc
definition ids2_cube_of_square : cube (vdeg_square s₁₀) (vdeg_square s₁₂)
ids ids (vdeg_square s₀₁) (vdeg_square s₂₁) :=
by induction p₀₀; induction sq; apply idc
end
/- Cube fillers -/
section cube_fillers
variables (s₁₁₀ s₁₁₂ s₀₁₁ s₂₁₁ s₁₀₁ s₁₂₁)
definition cube_fill110 : Σ lid, cube s₀₁₁ s₂₁₁ s₁₀₁ s₁₂₁ lid s₁₁₂ :=
begin
induction s₀₁₁, induction s₂₁₁,
let fillsq := square_fill_l (eq_of_vdeg_square s₁₀₁)
(eq_of_hdeg_square s₁₁₂) (eq_of_vdeg_square s₁₂₁),
apply sigma.mk,
apply cube_transport101 (left_inv (vdeg_square_equiv _ _) s₁₀₁),
apply cube_transport112 (left_inv (hdeg_square_equiv _ _) s₁₁₂),
apply cube_transport121 (left_inv (vdeg_square_equiv _ _) s₁₂₁),
apply ids1_cube_of_square, exact fillsq.2
end
definition cube_fill112 : Σ lid, cube s₀₁₁ s₂₁₁ s₁₀₁ s₁₂₁ s₁₁₀ lid :=
begin
induction s₀₁₁, induction s₂₁₁,
let fillsq := square_fill_r (eq_of_vdeg_square s₁₀₁)
(eq_of_hdeg_square s₁₁₀) (eq_of_vdeg_square s₁₂₁),
apply sigma.mk,
apply cube_transport101 (left_inv (vdeg_square_equiv _ _) s₁₀₁),
apply cube_transport110 (left_inv (hdeg_square_equiv _ _) s₁₁₀),
apply cube_transport121 (left_inv (vdeg_square_equiv _ _) s₁₂₁),
apply ids1_cube_of_square, exact fillsq.2,
end
definition cube_fill011 : Σ lid, cube lid s₂₁₁ s₁₀₁ s₁₂₁ s₁₁₀ s₁₁₂ :=
begin
induction s₁₀₁, induction s₁₂₁,
let fillsq := square_fill_t (eq_of_vdeg_square s₁₁₀) (eq_of_vdeg_square s₁₁₂)
(eq_of_vdeg_square s₂₁₁),
apply sigma.mk,
apply cube_transport110 (left_inv (vdeg_square_equiv _ _) s₁₁₀),
apply cube_transport211 (left_inv (vdeg_square_equiv _ _) s₂₁₁),
apply cube_transport112 (left_inv (vdeg_square_equiv _ _) s₁₁₂),
apply ids2_cube_of_square, exact fillsq.2,
end
definition cube_fill211 : Σ lid, cube s₀₁₁ lid s₁₀₁ s₁₂₁ s₁₁₀ s₁₁₂ :=
begin
induction s₁₀₁, induction s₁₂₁,
let fillsq := square_fill_b (eq_of_vdeg_square s₀₁₁) (eq_of_vdeg_square s₁₁₀)
(eq_of_vdeg_square s₁₁₂),
apply sigma.mk,
apply cube_transport011 (left_inv (vdeg_square_equiv _ _) s₀₁₁),
apply cube_transport110 (left_inv (vdeg_square_equiv _ _) s₁₁₀),
apply cube_transport112 (left_inv (vdeg_square_equiv _ _) s₁₁₂),
apply ids2_cube_of_square, exact fillsq.2,
end
definition cube_fill101 : Σ lid, cube s₀₁₁ s₂₁₁ lid s₁₂₁ s₁₁₀ s₁₁₂ :=
begin
induction s₁₁₀, induction s₁₁₂,
let fillsq := square_fill_t (eq_of_hdeg_square s₀₁₁) (eq_of_hdeg_square s₂₁₁)
(eq_of_hdeg_square s₁₂₁),
apply sigma.mk,
apply cube_transport011 (left_inv (hdeg_square_equiv _ _) s₀₁₁),
apply cube_transport211 (left_inv (hdeg_square_equiv _ _) s₂₁₁),
apply cube_transport121 (left_inv (hdeg_square_equiv _ _) s₁₂₁),
apply ids3_cube_of_square, exact fillsq.2,
end
definition cube_fill121 : Σ lid, cube s₀₁₁ s₂₁₁ s₁₀₁ lid s₁₁₀ s₁₁₂ :=
begin
induction s₁₁₀, induction s₁₁₂,
let fillsq := square_fill_b (eq_of_hdeg_square s₁₀₁) (eq_of_hdeg_square s₀₁₁)
(eq_of_hdeg_square s₂₁₁),
apply sigma.mk,
apply cube_transport101 (left_inv (hdeg_square_equiv _ _) s₁₀₁),
apply cube_transport011 (left_inv (hdeg_square_equiv _ _) s₀₁₁),
apply cube_transport211 (left_inv (hdeg_square_equiv _ _) s₂₁₁),
apply ids3_cube_of_square, exact fillsq.2,
end
end cube_fillers
/- Apply a non-dependent function to an entire cube -/
include c
definition apc (f : A → B) :
cube (aps f s₀₁₁) (aps f s₂₁₁) (aps f s₁₀₁) (aps f s₁₂₁) (aps f s₁₁₀) (aps f s₁₁₂) :=
by cases c; exact idc
omit c
/- Transpose a cube (swap dimensions) -/
include c
definition transpose12 : cube s₁₀₁ s₁₂₁ s₀₁₁ s₂₁₁ (transpose s₁₁₀) (transpose s₁₁₂) :=
by cases c; exact idc
definition transpose13 : cube s₁₁₀ s₁₁₂ (transpose s₁₀₁) (transpose s₁₂₁) s₀₁₁ s₂₁₁ :=
by cases c; exact idc
definition transpose23 : cube (transpose s₀₁₁) (transpose s₂₁₁) (transpose s₁₁₀)
(transpose s₁₁₂) (transpose s₁₀₁) (transpose s₁₂₁) :=
by cases c; exact idc
omit c
/- Inverting a cube along one dimension -/
include c
definition cube_inverse1 : cube s₂₁₁ s₀₁₁ s₁₀₁⁻¹ʰ s₁₂₁⁻¹ʰ s₁₁₀⁻¹ᵛ s₁₁₂⁻¹ᵛ :=
by cases c; exact idc
definition cube_inverse2 : cube s₀₁₁⁻¹ʰ s₂₁₁⁻¹ʰ s₁₂₁ s₁₀₁ s₁₁₀⁻¹ʰ s₁₁₂⁻¹ʰ :=
by cases c; exact idc
definition cube_inverse3 : cube s₀₁₁⁻¹ᵛ s₂₁₁⁻¹ᵛ s₁₀₁⁻¹ᵛ s₁₂₁⁻¹ᵛ s₁₁₂ s₁₁₀ :=
by cases c; exact idc
omit c
definition eq_concat1 {s₀₁₁' : square p₀₁₀ p₀₁₂ p₀₀₁ p₀₂₁} (r : s₀₁₁' = s₀₁₁)
(c : cube s₀₁₁ s₂₁₁ s₁₀₁ s₁₂₁ s₁₁₀ s₁₁₂) : cube s₀₁₁' s₂₁₁ s₁₀₁ s₁₂₁ s₁₁₀ s₁₁₂ :=
by induction r; exact c
definition concat1_eq {s₂₁₁' : square p₂₁₀ p₂₁₂ p₂₀₁ p₂₂₁}
(c : cube s₀₁₁ s₂₁₁ s₁₀₁ s₁₂₁ s₁₁₀ s₁₁₂) (r : s₂₁₁ = s₂₁₁')
: cube s₀₁₁ s₂₁₁' s₁₀₁ s₁₂₁ s₁₁₀ s₁₁₂ :=
by induction r; exact c
definition eq_concat2 {s₁₀₁' : square p₁₀₀ p₁₀₂ p₀₀₁ p₂₀₁} (r : s₁₀₁' = s₁₀₁)
(c : cube s₀₁₁ s₂₁₁ s₁₀₁ s₁₂₁ s₁₁₀ s₁₁₂) : cube s₀₁₁ s₂₁₁ s₁₀₁' s₁₂₁ s₁₁₀ s₁₁₂ :=
by induction r; exact c
definition concat2_eq {s₁₂₁' : square p₁₂₀ p₁₂₂ p₀₂₁ p₂₂₁}
(c : cube s₀₁₁ s₂₁₁ s₁₀₁ s₁₂₁ s₁₁₀ s₁₁₂) (r : s₁₂₁ = s₁₂₁')
: cube s₀₁₁ s₂₁₁ s₁₀₁ s₁₂₁' s₁₁₀ s₁₁₂ :=
by induction r; exact c
definition eq_concat3 {s₁₁₀' : square p₀₁₀ p₂₁₀ p₁₀₀ p₁₂₀} (r : s₁₁₀' = s₁₁₀)
(c : cube s₀₁₁ s₂₁₁ s₁₀₁ s₁₂₁ s₁₁₀ s₁₁₂) : cube s₀₁₁ s₂₁₁ s₁₀₁ s₁₂₁ s₁₁₀' s₁₁₂ :=
by induction r; exact c
definition concat3_eq {s₁₁₂' : square p₀₁₂ p₂₁₂ p₁₀₂ p₁₂₂}
(c : cube s₀₁₁ s₂₁₁ s₁₀₁ s₁₂₁ s₁₁₀ s₁₁₂) (r : s₁₁₂ = s₁₁₂')
: cube s₀₁₁ s₂₁₁ s₁₀₁ s₁₂₁ s₁₁₀ s₁₁₂' :=
by induction r; exact c
infix ` ⬝1 `:75 := cube_concat1
infix ` ⬝2 `:75 := cube_concat2
infix ` ⬝3 `:75 := cube_concat3
infix ` ⬝p1 `:75 := eq_concat1
infix ` ⬝1p `:75 := concat1_eq
infix ` ⬝p2 `:75 := eq_concat3
infix ` ⬝2p `:75 := concat2_eq
infix ` ⬝p3 `:75 := eq_concat3
infix ` ⬝3p `:75 := concat3_eq
end eq

View file

@ -1,59 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Floris van Doorn
Cubeovers
-/
import .squareover .cube
open equiv is_equiv
namespace eq
-- we need to specify B explicitly, also in pathovers
inductive cubeover {A : Type} (B : A → Type) {a₀₀₀ : A} {b₀₀₀ : B a₀₀₀}
: Π{a₂₀₀ a₀₂₀ a₂₂₀ a₀₀₂ a₂₀₂ a₀₂₂ a₂₂₂ : A}
{p₁₀₀ : a₀₀₀ = a₂₀₀} {p₀₁₀ : a₀₀₀ = a₀₂₀} {p₀₀₁ : a₀₀₀ = a₀₀₂}
{p₁₂₀ : a₀₂₀ = a₂₂₀} {p₂₁₀ : a₂₀₀ = a₂₂₀} {p₂₀₁ : a₂₀₀ = a₂₀₂}
{p₁₀₂ : a₀₀₂ = a₂₀₂} {p₀₁₂ : a₀₀₂ = a₀₂₂} {p₀₂₁ : a₀₂₀ = a₀₂₂}
{p₁₂₂ : a₀₂₂ = a₂₂₂} {p₂₁₂ : a₂₀₂ = a₂₂₂} {p₂₂₁ : a₂₂₀ = a₂₂₂}
{s₁₁₀ : square p₀₁₀ p₂₁₀ p₁₀₀ p₁₂₀}
{s₁₁₂ : square p₀₁₂ p₂₁₂ p₁₀₂ p₁₂₂}
{s₀₁₁ : square p₀₁₀ p₀₁₂ p₀₀₁ p₀₂₁}
{s₂₁₁ : square p₂₁₀ p₂₁₂ p₂₀₁ p₂₂₁}
{s₁₀₁ : square p₁₀₀ p₁₀₂ p₀₀₁ p₂₀₁}
{s₁₂₁ : square p₁₂₀ p₁₂₂ p₀₂₁ p₂₂₁}
(c : cube s₀₁₁ s₂₁₁ s₁₀₁ s₁₂₁ s₁₁₀ s₁₁₂)
{b₀₂₀ : B a₀₂₀} {b₂₀₀ : B a₂₀₀} {b₂₂₀ : B a₂₂₀}
{b₀₀₂ : B a₀₀₂} {b₀₂₂ : B a₀₂₂} {b₂₀₂ : B a₂₀₂} {b₂₂₂ : B a₂₂₂}
{q₁₀₀ : pathover B b₀₀₀ p₁₀₀ b₂₀₀} {q₀₁₀ : pathover B b₀₀₀ p₀₁₀ b₀₂₀}
{q₀₀₁ : pathover B b₀₀₀ p₀₀₁ b₀₀₂} {q₁₂₀ : pathover B b₀₂₀ p₁₂₀ b₂₂₀}
{q₂₁₀ : pathover B b₂₀₀ p₂₁₀ b₂₂₀} {q₂₀₁ : pathover B b₂₀₀ p₂₀₁ b₂₀₂}
{q₁₀₂ : pathover B b₀₀₂ p₁₀₂ b₂₀₂} {q₀₁₂ : pathover B b₀₀₂ p₀₁₂ b₀₂₂}
{q₀₂₁ : pathover B b₀₂₀ p₀₂₁ b₀₂₂} {q₁₂₂ : pathover B b₀₂₂ p₁₂₂ b₂₂₂}
{q₂₁₂ : pathover B b₂₀₂ p₂₁₂ b₂₂₂} {q₂₂₁ : pathover B b₂₂₀ p₂₂₁ b₂₂₂}
(t₀₁₁ : squareover B s₀₁₁ q₀₁₀ q₀₁₂ q₀₀₁ q₀₂₁)
(t₂₁₁ : squareover B s₂₁₁ q₂₁₀ q₂₁₂ q₂₀₁ q₂₂₁)
(t₁₀₁ : squareover B s₁₀₁ q₁₀₀ q₁₀₂ q₀₀₁ q₂₀₁)
(t₁₂₁ : squareover B s₁₂₁ q₁₂₀ q₁₂₂ q₀₂₁ q₂₂₁)
(t₁₁₀ : squareover B s₁₁₀ q₀₁₀ q₂₁₀ q₁₀₀ q₁₂₀)
(t₁₁₂ : squareover B s₁₁₂ q₀₁₂ q₂₁₂ q₁₀₂ q₁₂₂), Type :=
idcubeo : cubeover B idc idso idso idso idso idso idso
-- variables {A : Type} {a₀₀₀ a₂₀₀ a₀₂₀ a₂₂₀ a₀₀₂ a₂₀₂ a₀₂₂ a₂₂₂ : A}
-- {p₁₀₀ : a₀₀₀ = a₂₀₀} {p₀₁₀ : a₀₀₀ = a₀₂₀} {p₀₀₁ : a₀₀₀ = a₀₀₂}
-- {p₁₂₀ : a₀₂₀ = a₂₂₀} {p₂₁₀ : a₂₀₀ = a₂₂₀} {p₂₀₁ : a₂₀₀ = a₂₀₂}
-- {p₁₀₂ : a₀₀₂ = a₂₀₂} {p₀₁₂ : a₀₀₂ = a₀₂₂} {p₀₂₁ : a₀₂₀ = a₀₂₂}
-- {p₁₂₂ : a₀₂₂ = a₂₂₂} {p₂₁₂ : a₂₀₂ = a₂₂₂} {p₂₂₁ : a₂₂₀ = a₂₂₂}
-- {s₁₁₀ : square p₀₁₀ p₂₁₀ p₁₀₀ p₁₂₀}
-- {s₁₁₂ : square p₀₁₂ p₂₁₂ p₁₀₂ p₁₂₂}
-- {s₁₀₁ : square p₁₀₀ p₁₀₂ p₀₀₁ p₂₀₁}
-- {s₁₂₁ : square p₁₂₀ p₁₂₂ p₀₂₁ p₂₂₁}
-- {s₀₁₁ : square p₀₁₀ p₀₁₂ p₀₀₁ p₀₂₁}
-- {s₂₁₁ : square p₂₁₀ p₂₁₂ p₂₀₁ p₂₂₁}
end eq

View file

@ -1,15 +0,0 @@
types.cubical
=============
Cubical Types:
The files [path](../init/path.hlean) and [pathover](../init/pathover.hlean) are in the [init/](../init/init.md) folder.
* [square](square.hlean): square in a type
* [cube](cube.hlean): cube in a type
* [squareover](squareover.hlean): square over a square
* [cubeover](cubeover.hlean): cube over a cube
The following files are higher coherence laws between operators defined in the basic files
* [pathover2](pathover2.hlean)
* [square2](square2.hlean)

View file

@ -1,7 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
-/
import .square .cube .squareover .cubeover

View file

@ -1,133 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Floris van Doorn
Coherence conditions for operations on pathovers
-/
open function equiv
namespace eq
variables {A A' A'' : Type} {B B' : A → Type} {B'' : A' → Type} {C : Π⦃a⦄, B a → Type}
{a a₂ a₃ a₄ : A} {p p' p'' : a = a₂} {p₂ p₂' : a₂ = a₃} {p₃ : a₃ = a₄} {p₁₃ : a = a₃}
{a' : A'}
{b b' : B a} {b₂ b₂' : B a₂} {b₃ : B a₃} {b₄ : B a₄}
{c : C b} {c₂ : C b₂}
definition pathover_ap_id (q : b =[p] b₂) : pathover_ap B id q = change_path (ap_id p)⁻¹ q :=
by induction q; reflexivity
definition pathover_ap_compose (B : A'' → Type) (g : A' → A'') (f : A → A')
{b : B (g (f a))} {b₂ : B (g (f a₂))} (q : b =[p] b₂) : pathover_ap B (g ∘ f) q
= change_path (ap_compose g f p)⁻¹ (pathover_ap B g (pathover_ap (B ∘ g) f q)) :=
by induction q; reflexivity
definition pathover_ap_compose_rev (B : A'' → Type) (g : A' → A'') (f : A → A')
{b : B (g (f a))} {b₂ : B (g (f a₂))} (q : b =[p] b₂) :
pathover_ap B g (pathover_ap (B ∘ g) f q)
= change_path (ap_compose g f p) (pathover_ap B (g ∘ f) q) :=
by induction q; reflexivity
definition pathover_of_tr_eq_idp (r : b = b') : pathover_of_tr_eq r = pathover_idp_of_eq r :=
idp
definition pathover_of_tr_eq_eq_concato (r : p ▸ b = b₂)
: pathover_of_tr_eq r = pathover_tr p b ⬝o pathover_idp_of_eq r :=
by induction r; induction p; reflexivity
definition apd011_eq_apo11_apd (f : Πa, B a → A') (p : a = a₂) (q : b =[p] b₂)
: apd011 f p q = apo11_constant_right (apd f p) q :=
by induction q; reflexivity
definition change_path_con (q : p = p') (q' : p' = p'') (r : b =[p] b₂) :
change_path (q ⬝ q') r = change_path q' (change_path q r) :=
by induction q; induction q'; reflexivity
definition change_path_invo (q : p = p') (r : b =[p] b₂) :
change_path (inverse2 q) r⁻¹ᵒ = (change_path q r)⁻¹ᵒ :=
by induction q; reflexivity
definition change_path_cono (q : p = p') (q₂ : p₂ = p₂') (r : b =[p] b₂) (r₂ : b₂ =[p₂] b₃):
change_path (q ◾ q₂) (r ⬝o r₂) = change_path q r ⬝o change_path q₂ r₂ :=
by induction q; induction q₂; reflexivity
definition pathover_of_pathover_ap_invo (B' : A' → Type) (f : A → A')
{b : B' (f a)} {b₂ : B' (f a₂)} (q : b =[ap f p] b₂) :
pathover_of_pathover_ap B' f (change_path (ap_inv f p)⁻¹ q⁻¹ᵒ) =
(pathover_of_pathover_ap B' f q)⁻¹ᵒ:=
by induction p; eapply idp_rec_on q; reflexivity
definition pathover_of_pathover_ap_cono (B' : A' → Type) (f : A → A')
{b : B' (f a)} {b₂ : B' (f a₂)} {b₃ : B' (f a₃)} (q : b =[ap f p] b₂) (q₂ : b₂ =[ap f p₂] b₃) :
pathover_of_pathover_ap B' f (change_path (ap_con f p p₂)⁻¹ (q ⬝o q₂)) =
pathover_of_pathover_ap B' f q ⬝o pathover_of_pathover_ap B' f q₂ :=
by induction p; induction p₂; eapply idp_rec_on q; eapply idp_rec_on q₂; reflexivity
definition pathover_ap_pathover_of_pathover_ap (P : A'' → Type) (g : A' → A'') (f : A → A')
{p : a = a₂} {b : P (g (f a))} {b₂ : P (g (f a₂))} (q : b =[ap f p] b₂) :
pathover_ap P (g ∘ f) (pathover_of_pathover_ap (P ∘ g) f q) =
change_path (ap_compose g f p)⁻¹ (pathover_ap P g q) :=
by induction p; eapply (idp_rec_on q); reflexivity
definition change_path_pathover_of_pathover_ap (B' : A' → Type) (f : A → A') {p p' : a = a₂}
(r : p = p') {b : B' (f a)} {b₂ : B' (f a₂)} (q : b =[ap f p] b₂) :
change_path r (pathover_of_pathover_ap B' f q) =
pathover_of_pathover_ap B' f (change_path (ap02 f r) q) :=
by induction r; reflexivity
definition pathover_ap_change_path (B' : A' → Type) (f : A → A') {p p' : a = a₂}
(r : p = p') {b : B' (f a)} {b₂ : B' (f a₂)} (q : b =[p] b₂) :
pathover_ap B' f (change_path r q) = change_path (ap02 f r) (pathover_ap B' f q) :=
by induction r; reflexivity
definition change_path_equiv [constructor] (b : B a) (b₂ : B a₂) (q : p = p')
: (b =[p] b₂) ≃ (b =[p'] b₂) :=
begin
fapply equiv.MK,
{ exact change_path q},
{ exact change_path q⁻¹},
{ intro r, induction q, reflexivity},
{ intro r, induction q, reflexivity},
end
definition apd_ap {B : A' → Type} (g : Πb, B b) (f : A → A') (p : a = a₂)
: apd g (ap f p) = pathover_ap B f (apd (λx, g (f x)) p) :=
by induction p; reflexivity
definition apd_eq_apd_ap {B : A' → Type} (g : Πb, B b) (f : A → A') (p : a = a₂)
: apd (λx, g (f x)) p = pathover_of_pathover_ap B f (apd g (ap f p)) :=
by induction p; reflexivity
definition ap_compose_ap02_constant {A B C : Type} {a a' : A} (p : a = a') (b : B) (c : C) :
ap_compose (λc, b) (λa, c) p ⬝ ap02 (λc, b) (ap_constant p c) = ap_constant p b :=
by induction p; reflexivity
theorem apd_constant (b : B'' a') (p : a = a) :
pathover_ap B'' (λa, a') (apd (λa, b) p) = change_path (ap_constant p a')⁻¹ idpo :=
begin
rewrite [apd_eq_apd_ap _ _ p],
let y := !change_path_of_pathover (apd (apd id) (ap_constant p b))⁻¹ᵒ,
rewrite -y, esimp,
refine !pathover_ap_pathover_of_pathover_ap ⬝ _,
rewrite pathover_ap_change_path,
rewrite -change_path_con, apply ap (λx, change_path x idpo),
unfold ap02, rewrite [ap_inv,-con_inv], apply inverse2,
apply ap_compose_ap02_constant
end
definition apd_change_path {B : A → Type} {a a₂ : A} (f : Πa, B a) {p p' : a = a₂} (s : p = p')
: apd f p' = change_path s (apd f p) :=
by induction s; reflexivity
definition cono_invo_eq_idpo {q q' : b =[p] b₂} (r : q = q')
: change_path (con.right_inv p) (q ⬝o q'⁻¹ᵒ) = idpo :=
by induction r; induction q; reflexivity
definition tr_eq_of_pathover_concato_eq {A : Type} {B : A → Type} {a a' : A} {p : a = a'}
{b : B a} {b' b'' : B a'} (q : b =[p] b') (r : b' = b'') :
tr_eq_of_pathover (q ⬝op r) = tr_eq_of_pathover q ⬝ r :=
by induction r; reflexivity
end eq

View file

@ -1,636 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn, Jakob von Raumer
Squares in a type
-/
import types.eq
open eq equiv is_equiv sigma
namespace eq
variables {A B : Type} {a a' a'' a₀₀ a₂₀ a₄₀ a₀₂ a₂₂ a₂₄ a₀₄ a₄₂ a₄₄ a₁ a₂ a₃ a₄ : A}
/-a₀₀-/ {p₁₀ p₁₀' : a₀₀ = a₂₀} /-a₂₀-/ {p₃₀ : a₂₀ = a₄₀} /-a₄₀-/
{p₀₁ p₀₁' : a₀₀ = a₀₂} /-s₁₁-/ {p₂₁ p₂₁' : a₂₀ = a₂₂} /-s₃₁-/ {p₄₁ : a₄₀ = a₄₂}
/-a₀₂-/ {p₁₂ p₁₂' : a₀₂ = a₂₂} /-a₂₂-/ {p₃₂ : a₂₂ = a₄₂} /-a₄₂-/
{p₀₃ : a₀₂ = a₀₄} /-s₁₃-/ {p₂₃ : a₂₂ = a₂₄} /-s₃₃-/ {p₄₃ : a₄₂ = a₄₄}
/-a₀₄-/ {p₁₄ : a₀₄ = a₂₄} /-a₂₄-/ {p₃₄ : a₂₄ = a₄₄} /-a₄₄-/
inductive square {A : Type} {a₀₀ : A}
: Π{a₂₀ a₀₂ a₂₂ : A}, a₀₀ = a₂₀ → a₀₂ = a₂₂ → a₀₀ = a₀₂ → a₂₀ = a₂₂ → Type :=
ids : square idp idp idp idp
/- square top bottom left right -/
variables {s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁} {s₃₁ : square p₃₀ p₃₂ p₂₁ p₄₁}
{s₁₃ : square p₁₂ p₁₄ p₀₃ p₂₃} {s₃₃ : square p₃₂ p₃₄ p₂₃ p₄₃}
definition ids [reducible] [constructor] := @square.ids
definition idsquare [reducible] [constructor] (a : A) := @square.ids A a
definition hrefl [unfold 4] (p : a = a') : square idp idp p p :=
by induction p; exact ids
definition vrefl [unfold 4] (p : a = a') : square p p idp idp :=
by induction p; exact ids
definition hrfl [reducible] [unfold 4] {p : a = a'} : square idp idp p p :=
!hrefl
definition vrfl [reducible] [unfold 4] {p : a = a'} : square p p idp idp :=
!vrefl
definition hdeg_square [unfold 6] {p q : a = a'} (r : p = q) : square idp idp p q :=
by induction r;apply hrefl
definition vdeg_square [unfold 6] {p q : a = a'} (r : p = q) : square p q idp idp :=
by induction r;apply vrefl
definition hdeg_square_idp (p : a = a') : hdeg_square (refl p) = hrfl :=
by reflexivity
definition vdeg_square_idp (p : a = a') : vdeg_square (refl p) = vrfl :=
by reflexivity
definition hconcat [unfold 16] (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁) (s₃₁ : square p₃₀ p₃₂ p₂₁ p₄₁)
: square (p₁₀ ⬝ p₃₀) (p₁₂ ⬝ p₃₂) p₀₁ p₄₁ :=
by induction s₃₁; exact s₁₁
definition vconcat [unfold 16] (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁) (s₁₃ : square p₁₂ p₁₄ p₀₃ p₂₃)
: square p₁₀ p₁₄ (p₀₁ ⬝ p₀₃) (p₂₁ ⬝ p₂₃) :=
by induction s₁₃; exact s₁₁
definition dconcat [unfold 14] {p₀₀ : a₀₀ = a} {p₂₂ : a = a₂₂}
(s₂₁ : square p₀₀ p₁₂ p₀₁ p₂₂) (s₁₂ : square p₁₀ p₂₂ p₀₀ p₂₁) : square p₁₀ p₁₂ p₀₁ p₂₁ :=
by induction s₁₂; exact s₂₁
definition hinverse [unfold 10] (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁) : square p₁₀⁻¹ p₁₂⁻¹ p₂₁ p₀₁ :=
by induction s₁₁;exact ids
definition vinverse [unfold 10] (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁) : square p₁₂ p₁₀ p₀₁⁻¹ p₂₁⁻¹ :=
by induction s₁₁;exact ids
definition eq_vconcat [unfold 11] {p : a₀₀ = a₂₀} (r : p = p₁₀) (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁) :
square p p₁₂ p₀₁ p₂₁ :=
by induction r; exact s₁₁
definition vconcat_eq [unfold 12] {p : a₀₂ = a₂₂} (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁) (r : p₁₂ = p) :
square p₁₀ p p₀₁ p₂₁ :=
by induction r; exact s₁₁
definition eq_hconcat [unfold 11] {p : a₀₀ = a₀₂} (r : p = p₀₁) (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁) :
square p₁₀ p₁₂ p p₂₁ :=
by induction r; exact s₁₁
definition hconcat_eq [unfold 12] {p : a₂₀ = a₂₂} (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁) (r : p₂₁ = p) :
square p₁₀ p₁₂ p₀₁ p :=
by induction r; exact s₁₁
infix ` ⬝h `:69 := hconcat --type using \tr
infix ` ⬝v `:70 := vconcat --type using \tr
infix ` ⬝hp `:71 := hconcat_eq --type using \tr
infix ` ⬝vp `:73 := vconcat_eq --type using \tr
infix ` ⬝ph `:72 := eq_hconcat --type using \tr
infix ` ⬝pv `:74 := eq_vconcat --type using \tr
postfix `⁻¹ʰ`:(max+1) := hinverse --type using \-1h
postfix `⁻¹ᵛ`:(max+1) := vinverse --type using \-1v
definition transpose [unfold 10] (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁) : square p₀₁ p₂₁ p₁₀ p₁₂ :=
by induction s₁₁;exact ids
definition aps [unfold 12] (f : A → B) (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁)
: square (ap f p₁₀) (ap f p₁₂) (ap f p₀₁) (ap f p₂₁) :=
by induction s₁₁;exact ids
/- canceling, whiskering and moving thinks along the sides of the square -/
definition whisker_tl (p : a = a₀₀) (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁)
: square (p ⬝ p₁₀) p₁₂ (p ⬝ p₀₁) p₂₁ :=
by induction s₁₁;induction p;constructor
definition whisker_br (p : a₂₂ = a) (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁)
: square p₁₀ (p₁₂ ⬝ p) p₀₁ (p₂₁ ⬝ p) :=
by induction p;exact s₁₁
definition whisker_rt (p : a = a₂₀) (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁)
: square (p₁₀ ⬝ p⁻¹) p₁₂ p₀₁ (p ⬝ p₂₁) :=
by induction s₁₁;induction p;constructor
definition whisker_tr (p : a₂₀ = a) (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁)
: square (p₁₀ ⬝ p) p₁₂ p₀₁ (p⁻¹ ⬝ p₂₁) :=
by induction s₁₁;induction p;constructor
definition whisker_bl (p : a = a₀₂) (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁)
: square p₁₀ (p ⬝ p₁₂) (p₀₁ ⬝ p⁻¹) p₂₁ :=
by induction s₁₁;induction p;constructor
definition whisker_lb (p : a₀₂ = a) (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁)
: square p₁₀ (p⁻¹ ⬝ p₁₂) (p₀₁ ⬝ p) p₂₁ :=
by induction s₁₁;induction p;constructor
definition cancel_tl (p : a = a₀₀) (s₁₁ : square (p ⬝ p₁₀) p₁₂ (p ⬝ p₀₁) p₂₁)
: square p₁₀ p₁₂ p₀₁ p₂₁ :=
by induction p; rewrite +idp_con at s₁₁; exact s₁₁
definition cancel_br (p : a₂₂ = a) (s₁₁ : square p₁₀ (p₁₂ ⬝ p) p₀₁ (p₂₁ ⬝ p))
: square p₁₀ p₁₂ p₀₁ p₂₁ :=
by induction p;exact s₁₁
definition cancel_rt (p : a = a₂₀) (s₁₁ : square (p₁₀ ⬝ p⁻¹) p₁₂ p₀₁ (p ⬝ p₂₁))
: square p₁₀ p₁₂ p₀₁ p₂₁ :=
by induction p; rewrite idp_con at s₁₁; exact s₁₁
definition cancel_tr (p : a₂₀ = a) (s₁₁ : square (p₁₀ ⬝ p) p₁₂ p₀₁ (p⁻¹ ⬝ p₂₁))
: square p₁₀ p₁₂ p₀₁ p₂₁ :=
by induction p; rewrite [▸* at s₁₁,idp_con at s₁₁]; exact s₁₁
definition cancel_bl (p : a = a₀₂) (s₁₁ : square p₁₀ (p ⬝ p₁₂) (p₀₁ ⬝ p⁻¹) p₂₁)
: square p₁₀ p₁₂ p₀₁ p₂₁ :=
by induction p; rewrite idp_con at s₁₁; exact s₁₁
definition cancel_lb (p : a₀₂ = a) (s₁₁ : square p₁₀ (p⁻¹ ⬝ p₁₂) (p₀₁ ⬝ p) p₂₁)
: square p₁₀ p₁₂ p₀₁ p₂₁ :=
by induction p; rewrite [▸* at s₁₁,idp_con at s₁₁]; exact s₁₁
definition move_top_of_left {p : a₀₀ = a} {q : a = a₀₂} (s : square p₁₀ p₁₂ (p ⬝ q) p₂₁)
: square (p⁻¹ ⬝ p₁₀) p₁₂ q p₂₁ :=
by apply cancel_tl p; rewrite con_inv_cancel_left; exact s
definition move_top_of_left' {p : a = a₀₀} {q : a = a₀₂} (s : square p₁₀ p₁₂ (p⁻¹ ⬝ q) p₂₁)
: square (p ⬝ p₁₀) p₁₂ q p₂₁ :=
by apply cancel_tl p⁻¹; rewrite inv_con_cancel_left; exact s
definition move_left_of_top {p : a₀₀ = a} {q : a = a₂₀} (s : square (p ⬝ q) p₁₂ p₀₁ p₂₁)
: square q p₁₂ (p⁻¹ ⬝ p₀₁) p₂₁ :=
by apply cancel_tl p; rewrite con_inv_cancel_left; exact s
definition move_left_of_top' {p : a = a₀₀} {q : a = a₂₀} (s : square (p⁻¹ ⬝ q) p₁₂ p₀₁ p₂₁)
: square q p₁₂ (p ⬝ p₀₁) p₂₁ :=
by apply cancel_tl p⁻¹; rewrite inv_con_cancel_left; exact s
definition move_bot_of_right {p : a₂₀ = a} {q : a = a₂₂} (s : square p₁₀ p₁₂ p₀₁ (p ⬝ q))
: square p₁₀ (p₁₂ ⬝ q⁻¹) p₀₁ p :=
by apply cancel_br q; rewrite inv_con_cancel_right; exact s
definition move_bot_of_right' {p : a₂₀ = a} {q : a₂₂ = a} (s : square p₁₀ p₁₂ p₀₁ (p ⬝ q⁻¹))
: square p₁₀ (p₁₂ ⬝ q) p₀₁ p :=
by apply cancel_br q⁻¹; rewrite con_inv_cancel_right; exact s
definition move_right_of_bot {p : a₀₂ = a} {q : a = a₂₂} (s : square p₁₀ (p ⬝ q) p₀₁ p₂₁)
: square p₁₀ p p₀₁ (p₂₁ ⬝ q⁻¹) :=
by apply cancel_br q; rewrite inv_con_cancel_right; exact s
definition move_right_of_bot' {p : a₀₂ = a} {q : a₂₂ = a} (s : square p₁₀ (p ⬝ q⁻¹) p₀₁ p₂₁)
: square p₁₀ p p₀₁ (p₂₁ ⬝ q) :=
by apply cancel_br q⁻¹; rewrite con_inv_cancel_right; exact s
definition move_top_of_right {p : a₂₀ = a} {q : a = a₂₂} (s : square p₁₀ p₁₂ p₀₁ (p ⬝ q))
: square (p₁₀ ⬝ p) p₁₂ p₀₁ q :=
by apply cancel_rt p; rewrite con_inv_cancel_right; exact s
definition move_right_of_top {p : a₀₀ = a} {q : a = a₂₀} (s : square (p ⬝ q) p₁₂ p₀₁ p₂₁)
: square p p₁₂ p₀₁ (q ⬝ p₂₁) :=
by apply cancel_tr q; rewrite inv_con_cancel_left; exact s
definition move_bot_of_left {p : a₀₀ = a} {q : a = a₀₂} (s : square p₁₀ p₁₂ (p ⬝ q) p₂₁)
: square p₁₀ (q ⬝ p₁₂) p p₂₁ :=
by apply cancel_lb q; rewrite inv_con_cancel_left; exact s
definition move_left_of_bot {p : a₀₂ = a} {q : a = a₂₂} (s : square p₁₀ (p ⬝ q) p₀₁ p₂₁)
: square p₁₀ q (p₀₁ ⬝ p) p₂₁ :=
by apply cancel_bl p; rewrite con_inv_cancel_right; exact s
/- some higher ∞-groupoid operations -/
definition vconcat_vrfl (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁)
: s₁₁ ⬝v vrefl p₁₂ = s₁₁ :=
by induction s₁₁; reflexivity
definition hconcat_hrfl (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁)
: s₁₁ ⬝h hrefl p₂₁ = s₁₁ :=
by induction s₁₁; reflexivity
/- equivalences -/
definition eq_of_square [unfold 10] (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁) : p₁₀ ⬝ p₂₁ = p₀₁ ⬝ p₁₂ :=
by induction s₁₁; apply idp
definition square_of_eq (r : p₁₀ ⬝ p₂₁ = p₀₁ ⬝ p₁₂) : square p₁₀ p₁₂ p₀₁ p₂₁ :=
by induction p₁₂; esimp at r; induction r; induction p₂₁; induction p₁₀; exact ids
definition eq_top_of_square [unfold 10] (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁)
: p₁₀ = p₀₁ ⬝ p₁₂ ⬝ p₂₁⁻¹ :=
by induction s₁₁; apply idp
definition square_of_eq_top (r : p₁₀ = p₀₁ ⬝ p₁₂ ⬝ p₂₁⁻¹) : square p₁₀ p₁₂ p₀₁ p₂₁ :=
by induction p₂₁; induction p₁₂; esimp at r;induction r;induction p₁₀;exact ids
definition eq_bot_of_square [unfold 10] (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁)
: p₁₂ = p₀₁⁻¹ ⬝ p₁₀ ⬝ p₂₁ :=
by induction s₁₁; apply idp
definition square_of_eq_bot (r : p₀₁⁻¹ ⬝ p₁₀ ⬝ p₂₁ = p₁₂) : square p₁₀ p₁₂ p₀₁ p₂₁ :=
by induction p₂₁; induction p₁₀; esimp at r; induction r; induction p₀₁; exact ids
definition square_equiv_eq [constructor] (t : a₀₀ = a₀₂) (b : a₂₀ = a₂₂)
(l : a₀₀ = a₂₀) (r : a₀₂ = a₂₂) : square t b l r ≃ t ⬝ r = l ⬝ b :=
begin
fapply equiv.MK,
{ exact eq_of_square},
{ exact square_of_eq},
{ intro s, induction b, esimp [concat] at s, induction s, induction r, induction t, apply idp},
{ intro s, induction s, apply idp},
end
definition hdeg_square_equiv' [constructor] (p q : a = a') : square idp idp p q ≃ p = q :=
by transitivity _;apply square_equiv_eq;transitivity _;apply eq_equiv_eq_symm;
apply equiv_eq_closed_right;apply idp_con
definition vdeg_square_equiv' [constructor] (p q : a = a') : square p q idp idp ≃ p = q :=
by transitivity _;apply square_equiv_eq;apply equiv_eq_closed_right; apply idp_con
definition eq_of_hdeg_square [reducible] {p q : a = a'} (s : square idp idp p q) : p = q :=
to_fun !hdeg_square_equiv' s
definition eq_of_vdeg_square [reducible] {p q : a = a'} (s : square p q idp idp) : p = q :=
to_fun !vdeg_square_equiv' s
definition top_deg_square (l : a₁ = a₂) (b : a₂ = a₃) (r : a₄ = a₃)
: square (l ⬝ b ⬝ r⁻¹) b l r :=
by induction r;induction b;induction l;constructor
definition bot_deg_square (l : a₁ = a₂) (t : a₁ = a₃) (r : a₃ = a₄)
: square t (l⁻¹ ⬝ t ⬝ r) l r :=
by induction r;induction t;induction l;constructor
/-
the following two equivalences have as underlying inverse function the functions
hdeg_square and vdeg_square, respectively.
See example below the definition
-/
definition hdeg_square_equiv [constructor] (p q : a = a') :
square idp idp p q ≃ p = q :=
begin
fapply equiv_change_fun,
{ fapply equiv_change_inv, apply hdeg_square_equiv', exact hdeg_square,
intro s, induction s, induction p, reflexivity},
{ exact eq_of_hdeg_square},
{ reflexivity}
end
definition vdeg_square_equiv [constructor] (p q : a = a') :
square p q idp idp ≃ p = q :=
begin
fapply equiv_change_fun,
{ fapply equiv_change_inv, apply vdeg_square_equiv',exact vdeg_square,
intro s, induction s, induction p, reflexivity},
{ exact eq_of_vdeg_square},
{ reflexivity}
end
example (p q : a = a') : to_inv (hdeg_square_equiv p q) = hdeg_square := idp
/-
characterization of pathovers in a equality type. The type B of the equality is fixed here.
A version where B may also varies over the path p is given in the file squareover
-/
definition eq_pathover [unfold 7] {f g : A → B} {p : a = a'} {q : f a = g a} {r : f a' = g a'}
(s : square q r (ap f p) (ap g p)) : q =[p] r :=
begin induction p, apply pathover_idp_of_eq, exact eq_of_vdeg_square s end
definition eq_pathover_constant_left {g : A → B} {p : a = a'} {b : B} {q : b = g a} {r : b = g a'}
(s : square q r idp (ap g p)) : q =[p] r :=
eq_pathover (ap_constant p b ⬝ph s)
definition eq_pathover_id_left {g : A → A} {p : a = a'} {q : a = g a} {r : a' = g a'}
(s : square q r p (ap g p)) : q =[p] r :=
eq_pathover (ap_id p ⬝ph s)
definition eq_pathover_constant_right {f : A → B} {p : a = a'} {b : B} {q : f a = b} {r : f a' = b}
(s : square q r (ap f p) idp) : q =[p] r :=
eq_pathover (s ⬝hp (ap_constant p b)⁻¹)
definition eq_pathover_id_right {f : A → A} {p : a = a'} {q : f a = a} {r : f a' = a'}
(s : square q r (ap f p) p) : q =[p] r :=
eq_pathover (s ⬝hp (ap_id p)⁻¹)
definition square_of_pathover [unfold 7]
{f g : A → B} {p : a = a'} {q : f a = g a} {r : f a' = g a'}
(s : q =[p] r) : square q r (ap f p) (ap g p) :=
by induction p;apply vdeg_square;exact eq_of_pathover_idp s
definition eq_pathover_constant_left_id_right {p : a = a'} {a₀ : A} {q : a₀ = a} {r : a₀ = a'}
(s : square q r idp p) : q =[p] r :=
eq_pathover (ap_constant p a₀ ⬝ph s ⬝hp (ap_id p)⁻¹)
definition eq_pathover_id_left_constant_right {p : a = a'} {a₀ : A} {q : a = a₀} {r : a' = a₀}
(s : square q r p idp) : q =[p] r :=
eq_pathover (ap_id p ⬝ph s ⬝hp (ap_constant p a₀)⁻¹)
definition loop_pathover {p : a = a'} {q : a = a} {r : a' = a'} (s : square q r p p) : q =[p] r :=
eq_pathover (ap_id p ⬝ph s ⬝hp (ap_id p)⁻¹)
/- interaction of equivalences with operations on squares -/
definition eq_pathover_equiv_square [constructor] {f g : A → B}
(p : a = a') (q : f a = g a) (r : f a' = g a') : q =[p] r ≃ square q r (ap f p) (ap g p) :=
equiv.MK square_of_pathover
eq_pathover
begin
intro s, induction p, esimp [square_of_pathover,eq_pathover],
exact ap vdeg_square (to_right_inv !pathover_idp (eq_of_vdeg_square s))
⬝ to_left_inv !vdeg_square_equiv s
end
begin
intro s, induction p, esimp [square_of_pathover,eq_pathover],
exact ap pathover_idp_of_eq (to_right_inv !vdeg_square_equiv (eq_of_pathover_idp s))
⬝ to_left_inv !pathover_idp s
end
definition square_of_pathover_eq_concato {f g : A → B} {p : a = a'} {q q' : f a = g a}
{r : f a' = g a'} (s' : q = q') (s : q' =[p] r)
: square_of_pathover (s' ⬝po s) = s' ⬝pv square_of_pathover s :=
by induction s;induction s';reflexivity
definition square_of_pathover_concato_eq {f g : A → B} {p : a = a'} {q : f a = g a}
{r r' : f a' = g a'} (s' : r = r') (s : q =[p] r)
: square_of_pathover (s ⬝op s') = square_of_pathover s ⬝vp s' :=
by induction s;induction s';reflexivity
definition square_of_pathover_concato {f g : A → B} {p : a = a'} {p' : a' = a''} {q : f a = g a}
{q' : f a' = g a'} {q'' : f a'' = g a''} (s : q =[p] q') (s' : q' =[p'] q'')
: square_of_pathover (s ⬝o s')
= ap_con f p p' ⬝ph (square_of_pathover s ⬝v square_of_pathover s') ⬝hp (ap_con g p p')⁻¹ :=
by induction s';induction s;esimp [ap_con,hconcat_eq];exact !vconcat_vrfl⁻¹
definition eq_of_square_hrfl [unfold 4] (p : a = a') : eq_of_square hrfl = idp_con p :=
by induction p;reflexivity
definition eq_of_square_vrfl [unfold 4] (p : a = a') : eq_of_square vrfl = (idp_con p)⁻¹ :=
by induction p;reflexivity
definition eq_of_square_hdeg_square {p q : a = a'} (r : p = q)
: eq_of_square (hdeg_square r) = !idp_con ⬝ r⁻¹ :=
by induction r;induction p;reflexivity
definition eq_of_square_vdeg_square {p q : a = a'} (r : p = q)
: eq_of_square (vdeg_square r) = r ⬝ !idp_con⁻¹ :=
by induction r;induction p;reflexivity
definition eq_of_square_eq_vconcat {p : a₀₀ = a₂₀} (r : p = p₁₀) (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁)
: eq_of_square (r ⬝pv s₁₁) = whisker_right p₂₁ r ⬝ eq_of_square s₁₁ :=
by induction s₁₁;cases r;reflexivity
definition eq_of_square_eq_hconcat {p : a₀₀ = a₀₂} (r : p = p₀₁) (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁)
: eq_of_square (r ⬝ph s₁₁) = eq_of_square s₁₁ ⬝ (whisker_right p₁₂ r)⁻¹ :=
by induction r;reflexivity
definition eq_of_square_vconcat_eq {p : a₀₂ = a₂₂} (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁) (r : p₁₂ = p)
: eq_of_square (s₁₁ ⬝vp r) = eq_of_square s₁₁ ⬝ whisker_left p₀₁ r :=
by induction r;reflexivity
definition eq_of_square_hconcat_eq {p : a₂₀ = a₂₂} (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁) (r : p₂₁ = p)
: eq_of_square (s₁₁ ⬝hp r) = (whisker_left p₁₀ r)⁻¹ ⬝ eq_of_square s₁₁ :=
by induction s₁₁; induction r;reflexivity
definition change_path_eq_pathover {A B : Type} {a a' : A} {f g : A → B}
{p p' : a = a'} (r : p = p')
{q : f a = g a} {q' : f a' = g a'}
(s : square q q' (ap f p) (ap g p)) :
change_path r (eq_pathover s) = eq_pathover ((ap02 f r)⁻¹ ⬝ph s ⬝hp (ap02 g r)) :=
by induction r; reflexivity
definition eq_hconcat_hdeg_square {A : Type} {a a' : A} {p₁ p₂ p₃ : a = a'} (q₁ : p₁ = p₂)
(q₂ : p₂ = p₃) : q₁ ⬝ph hdeg_square q₂ = hdeg_square (q₁ ⬝ q₂) :=
by induction q₁; induction q₂; reflexivity
definition hdeg_square_hconcat_eq {A : Type} {a a' : A} {p₁ p₂ p₃ : a = a'} (q₁ : p₁ = p₂)
(q₂ : p₂ = p₃) : hdeg_square q₁ ⬝hp q₂ = hdeg_square (q₁ ⬝ q₂) :=
by induction q₁; induction q₂; reflexivity
definition eq_hconcat_eq_hdeg_square {A : Type} {a a' : A} {p₁ p₂ p₃ p₄ : a = a'} (q₁ : p₁ = p₂)
(q₂ : p₂ = p₃) (q₃ : p₃ = p₄) : q₁ ⬝ph hdeg_square q₂ ⬝hp q₃ = hdeg_square (q₁ ⬝ q₂ ⬝ q₃) :=
by induction q₃; apply eq_hconcat_hdeg_square
-- definition vconcat_eq [unfold 11] {p : a₀₂ = a₂₂} (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁) (r : p₁₂ = p) :
-- square p₁₀ p p₀₁ p₂₁ :=
-- by induction r; exact s₁₁
-- definition eq_hconcat [unfold 11] {p : a₀₀ = a₀₂} (r : p = p₀₁)
-- (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁) : square p₁₀ p₁₂ p p₂₁ :=
-- by induction r; exact s₁₁
-- definition hconcat_eq [unfold 11] {p : a₂₀ = a₂₂}
-- (s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁) (r : p₂₁ = p) : square p₁₀ p₁₂ p₀₁ p :=
-- by induction r; exact s₁₁
-- the following definition is very slow, maybe it's interesting to see why?
-- definition eq_pathover_equiv_square' {f g : A → B}(p : a = a') (q : f a = g a) (r : f a' = g a')
-- : square q r (ap f p) (ap g p) ≃ q =[p] r :=
-- equiv.MK eq_pathover
-- square_of_pathover
-- (λs, begin
-- induction p, rewrite [↑[square_of_pathover,eq_pathover],
-- to_right_inv !vdeg_square_equiv (eq_of_pathover_idp s),
-- to_left_inv !pathover_idp s]
-- end)
-- (λs, begin
-- induction p, rewrite [↑[square_of_pathover,eq_pathover],▸*,
-- to_right_inv !(@pathover_idp A) (eq_of_vdeg_square s),
-- to_left_inv !vdeg_square_equiv s]
-- end)
/- recursors for squares where some sides are reflexivity -/
definition rec_on_b [recursor] {a₀₀ : A}
{P : Π{a₂₀ a₁₂ : A} {t : a₀₀ = a₂₀} {l : a₀₀ = a₁₂} {r : a₂₀ = a₁₂}, square t idp l r → Type}
{a₂₀ a₁₂ : A} {t : a₀₀ = a₂₀} {l : a₀₀ = a₁₂} {r : a₂₀ = a₁₂}
(s : square t idp l r) (H : P ids) : P s :=
have H2 : P (square_of_eq (eq_of_square s)),
from eq.rec_on (eq_of_square s : t ⬝ r = l) (by induction r; induction t; exact H),
left_inv (to_fun !square_equiv_eq) s ▸ H2
definition rec_on_r [recursor] {a₀₀ : A}
{P : Π{a₀₂ a₂₁ : A} {t : a₀₀ = a₂₁} {b : a₀₂ = a₂₁} {l : a₀₀ = a₀₂}, square t b l idp → Type}
{a₀₂ a₂₁ : A} {t : a₀₀ = a₂₁} {b : a₀₂ = a₂₁} {l : a₀₀ = a₀₂}
(s : square t b l idp) (H : P ids) : P s :=
let p : l ⬝ b = t := (eq_of_square s)⁻¹ in
have H2 : P (square_of_eq (eq_of_square s)⁻¹⁻¹),
from @eq.rec_on _ _ (λx p, P (square_of_eq p⁻¹)) _ p (by induction b; induction l; exact H),
left_inv (to_fun !square_equiv_eq) s ▸ !inv_inv ▸ H2
definition rec_on_l [recursor] {a₀₁ : A}
{P : Π {a₂₀ a₂₂ : A} {t : a₀₁ = a₂₀} {b : a₀₁ = a₂₂} {r : a₂₀ = a₂₂},
square t b idp r → Type}
{a₂₀ a₂₂ : A} {t : a₀₁ = a₂₀} {b : a₀₁ = a₂₂} {r : a₂₀ = a₂₂}
(s : square t b idp r) (H : P ids) : P s :=
let p : t ⬝ r = b := eq_of_square s ⬝ !idp_con in
have H2 : P (square_of_eq (p ⬝ !idp_con⁻¹)),
from eq.rec_on p (by induction r; induction t; exact H),
left_inv (to_fun !square_equiv_eq) s ▸ !con_inv_cancel_right ▸ H2
definition rec_on_t [recursor] {a₁₀ : A}
{P : Π {a₀₂ a₂₂ : A} {b : a₀₂ = a₂₂} {l : a₁₀ = a₀₂} {r : a₁₀ = a₂₂}, square idp b l r → Type}
{a₀₂ a₂₂ : A} {b : a₀₂ = a₂₂} {l : a₁₀ = a₀₂} {r : a₁₀ = a₂₂}
(s : square idp b l r) (H : P ids) : P s :=
let p : l ⬝ b = r := (eq_of_square s)⁻¹ ⬝ !idp_con in
have H2 : P (square_of_eq ((p ⬝ !idp_con⁻¹)⁻¹)),
from eq.rec_on p (by induction b; induction l; exact H),
have H3 : P (square_of_eq ((eq_of_square s)⁻¹⁻¹)),
from eq.rec_on !con_inv_cancel_right H2,
have H4 : P (square_of_eq (eq_of_square s)),
from eq.rec_on !inv_inv H3,
proof
left_inv (to_fun !square_equiv_eq) s ▸ H4
qed
definition rec_on_tb [recursor] {a : A}
{P : Π{b : A} {l : a = b} {r : a = b}, square idp idp l r → Type}
{b : A} {l : a = b} {r : a = b}
(s : square idp idp l r) (H : P ids) : P s :=
have H2 : P (square_of_eq (eq_of_square s)),
from eq.rec_on (eq_of_square s : idp ⬝ r = l) (by induction r; exact H),
left_inv (to_fun !square_equiv_eq) s ▸ H2
definition rec_on_lr [recursor] {a : A}
{P : Π{a' : A} {t : a = a'} {b : a = a'}, square t b idp idp → Type}
{a' : A} {t : a = a'} {b : a = a'}
(s : square t b idp idp) (H : P ids) : P s :=
let p : idp ⬝ b = t := (eq_of_square s)⁻¹ in
have H2 : P (square_of_eq (eq_of_square s)⁻¹⁻¹),
from @eq.rec_on _ _ (λx q, P (square_of_eq q⁻¹)) _ p (by induction b; exact H),
to_left_inv (!square_equiv_eq) s ▸ !inv_inv ▸ H2
--we can also do the other recursors (tl, tr, bl, br, tbl, tbr, tlr, blr), but let's postpone this until they are needed
definition whisker_square [unfold 14 15 16 17] (r₁₀ : p₁₀ = p₁₀') (r₁₂ : p₁₂ = p₁₂')
(r₀₁ : p₀₁ = p₀₁') (r₂₁ : p₂₁ = p₂₁') (s : square p₁₀ p₁₂ p₀₁ p₂₁)
: square p₁₀' p₁₂' p₀₁' p₂₁' :=
by induction r₁₀; induction r₁₂; induction r₀₁; induction r₂₁; exact s
/- squares commute with some operations on 2-paths -/
definition square_inv2 {p₁ p₂ p₃ p₄ : a = a'}
{t : p₁ = p₂} {b : p₃ = p₄} {l : p₁ = p₃} {r : p₂ = p₄} (s : square t b l r)
: square (inverse2 t) (inverse2 b) (inverse2 l) (inverse2 r) :=
by induction s;constructor
definition square_con2 {p₁ p₂ p₃ p₄ : a₁ = a₂} {q₁ q₂ q₃ q₄ : a₂ = a₃}
{t₁ : p₁ = p₂} {b₁ : p₃ = p₄} {l₁ : p₁ = p₃} {r₁ : p₂ = p₄}
{t₂ : q₁ = q₂} {b₂ : q₃ = q₄} {l₂ : q₁ = q₃} {r₂ : q₂ = q₄}
(s₁ : square t₁ b₁ l₁ r₁) (s₂ : square t₂ b₂ l₂ r₂)
: square (t₁ ◾ t₂) (b₁ ◾ b₂) (l₁ ◾ l₂) (r₁ ◾ r₂) :=
by induction s₂;induction s₁;constructor
open is_trunc
definition is_set.elims [H : is_set A] : square p₁₀ p₁₂ p₀₁ p₂₁ :=
square_of_eq !is_set.elim
definition is_trunc_square [instance] (n : trunc_index) [H : is_trunc n .+2 A]
: is_trunc n (square p₁₀ p₁₂ p₀₁ p₂₁) :=
is_trunc_equiv_closed_rev n !square_equiv_eq
-- definition square_of_con_inv_hsquare {p₁ p₂ p₃ p₄ : a₁ = a₂}
-- {t : p₁ = p₂} {b : p₃ = p₄} {l : p₁ = p₃} {r : p₂ = p₄}
-- (s : square (con_inv_eq_idp t) (con_inv_eq_idp b) (l ◾ r⁻²) idp)
-- : square t b l r :=
-- sorry --by induction s
/- Square fillers -/
-- TODO replace by "more algebraic" fillers?
variables (p₁₀ p₁₂ p₀₁ p₂₁)
definition square_fill_t : Σ (p : a₀₀ = a₂₀), square p p₁₂ p₀₁ p₂₁ :=
by induction p₀₁; induction p₂₁; exact ⟨_, !vrefl⟩
definition square_fill_b : Σ (p : a₀₂ = a₂₂), square p₁₀ p p₀₁ p₂₁ :=
by induction p₀₁; induction p₂₁; exact ⟨_, !vrefl⟩
definition square_fill_l : Σ (p : a₀₀ = a₀₂), square p₁₀ p₁₂ p p₂₁ :=
by induction p₁₀; induction p₁₂; exact ⟨_, !hrefl⟩
definition square_fill_r : Σ (p : a₂₀ = a₂₂) , square p₁₀ p₁₂ p₀₁ p :=
by induction p₁₀; induction p₁₂; exact ⟨_, !hrefl⟩
/- Squares having an 'ap' term on one face -/
--TODO find better names
definition square_Flr_ap_idp {c : B} {f : A → B} (p : Π a, f a = c)
{a b : A} (q : a = b) : square (p a) (p b) (ap f q) idp :=
by induction q; apply vrfl
definition square_Flr_idp_ap {c : B} {f : A → B} (p : Π a, c = f a)
{a b : A} (q : a = b) : square (p a) (p b) idp (ap f q) :=
by induction q; apply vrfl
definition square_ap_idp_Flr {b : B} {f : A → B} (p : Π a, f a = b)
{a b : A} (q : a = b) : square (ap f q) idp (p a) (p b) :=
by induction q; apply hrfl
/- Matching eq_hconcat with hconcat etc. -/
-- TODO maybe rename hconcat_eq and the like?
variable (s₁₁)
definition ph_eq_pv_h_vp {p : a₀₀ = a₀₂} (r : p = p₀₁) :
r ⬝ph s₁₁ = !idp_con⁻¹ ⬝pv ((hdeg_square r) ⬝h s₁₁) ⬝vp !idp_con :=
by cases r; cases s₁₁; esimp
definition hdeg_h_eq_pv_ph_vp {p : a₀₀ = a₀₂} (r : p = p₀₁) :
hdeg_square r ⬝h s₁₁ = !idp_con ⬝pv (r ⬝ph s₁₁) ⬝vp !idp_con⁻¹ :=
by cases r; cases s₁₁; esimp
definition hp_eq_h {p : a₂₀ = a₂₂} (r : p₂₁ = p) :
s₁₁ ⬝hp r = s₁₁ ⬝h hdeg_square r :=
by cases r; cases s₁₁; esimp
definition pv_eq_ph_vdeg_v_vh {p : a₀₀ = a₂₀} (r : p = p₁₀) :
r ⬝pv s₁₁ = !idp_con⁻¹ ⬝ph ((vdeg_square r) ⬝v s₁₁) ⬝hp !idp_con :=
by cases r; cases s₁₁; esimp
definition vdeg_v_eq_ph_pv_hp {p : a₀₀ = a₂₀} (r : p = p₁₀) :
vdeg_square r ⬝v s₁₁ = !idp_con ⬝ph (r ⬝pv s₁₁) ⬝hp !idp_con⁻¹ :=
by cases r; cases s₁₁; esimp
definition vp_eq_v {p : a₀₂ = a₂₂} (r : p₁₂ = p) :
s₁₁ ⬝vp r = s₁₁ ⬝v vdeg_square r :=
by cases r; cases s₁₁; esimp
definition natural_square [unfold 8] {f g : A → B} (p : f ~ g) (q : a = a') :
square (p a) (p a') (ap f q) (ap g q) :=
square_of_pathover (apd p q)
definition natural_square_tr [unfold 8] {f g : A → B} (p : f ~ g) (q : a = a') :
square (ap f q) (ap g q) (p a) (p a') :=
transpose (natural_square p q)
definition natural_square011 {A A' : Type} {B : A → Type}
{a a' : A} {p : a = a'} {b : B a} {b' : B a'} (q : b =[p] b')
{l r : Π⦃a⦄, B a → A'} (g : Π⦃a⦄ (b : B a), l b = r b)
: square (apd011 l p q) (apd011 r p q) (g b) (g b') :=
begin
induction q, exact hrfl
end
definition natural_square0111' {A A' : Type} {B : A → Type} (C : Π⦃a⦄, B a → Type)
{a a' : A} {p : a = a'} {b : B a} {b' : B a'} {q : b =[p] b'}
{c : C b} {c' : C b'} (s : c =[apd011 C p q] c')
{l r : Π⦃a⦄ {b : B a}, C b → A'}
(g : Π⦃a⦄ {b : B a} (c : C b), l c = r c)
: square (apd0111 l p q s) (apd0111 r p q s) (g c) (g c') :=
begin
induction q, esimp at s, induction s using idp_rec_on, exact hrfl
end
-- this can be generalized a bit, by making the domain and codomain of k different, and also have
-- a function at the RHS of s (similar to m)
definition natural_square0111 {A A' : Type} {B : A → Type} (C : Π⦃a⦄, B a → Type)
{a a' : A} {p : a = a'} {b : B a} {b' : B a'} {q : b =[p] b'}
{c : C b} {c' : C b'} (r : c =[apd011 C p q] c')
{k : A → A} {l : Π⦃a⦄, B a → B (k a)} (m : Π⦃a⦄ {b : B a}, C b → C (l b))
{f : Π⦃a⦄ {b : B a}, C b → A'}
(s : Π⦃a⦄ {b : B a} (c : C b), f (m c) = f c)
: square (apd0111 (λa b c, f (m c)) p q r) (apd0111 f p q r) (s c) (s c') :=
begin
induction q, esimp at r, induction r using idp_rec_on, exact hrfl
end
end eq

View file

@ -1,52 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Floris van Doorn
Coherence conditions for operations on squares
-/
import .square
open equiv
namespace eq
variables {A B C : Type} {a a' a'' a₀₀ a₂₀ a₄₀ a₀₂ a₂₂ a₂₄ a₀₄ a₄₂ a₄₄ a₁ a₂ a₃ a₄ : A}
{f : A → B} {b : B} {c : C}
/-a₀₀-/ {p₁₀ p₁₀' : a₀₀ = a₂₀} /-a₂₀-/ {p₃₀ : a₂₀ = a₄₀} /-a₄₀-/
{p₀₁ p₀₁' : a₀₀ = a₀₂} /-s₁₁-/ {p₂₁ p₂₁' : a₂₀ = a₂₂} /-s₃₁-/ {p₄₁ : a₄₀ = a₄₂}
/-a₀₂-/ {p₁₂ p₁₂' : a₀₂ = a₂₂} /-a₂₂-/ {p₃₂ : a₂₂ = a₄₂} /-a₄₂-/
{p₀₃ : a₀₂ = a₀₄} /-s₁₃-/ {p₂₃ : a₂₂ = a₂₄} /-s₃₃-/ {p₄₃ : a₄₂ = a₄₄}
/-a₀₄-/ {p₁₄ : a₀₄ = a₂₄} /-a₂₄-/ {p₃₄ : a₂₄ = a₄₄} /-a₄₄-/
theorem whisker_bl_whisker_tl_eq (p : a = a')
: whisker_bl p (whisker_tl p ids) = con.right_inv p ⬝ph vrfl :=
by induction p; reflexivity
theorem ap_is_constant_natural_square {g : B → C} {f : A → B} (H : Πa, g (f a) = c) (p : a = a') :
(ap_is_constant H p)⁻¹ ⬝ph natural_square H p ⬝hp ap_constant p c =
whisker_bl (H a') (whisker_tl (H a) ids) :=
begin induction p, esimp, rewrite inv_inv, rewrite whisker_bl_whisker_tl_eq end
definition inv_ph_eq_of_eq_ph {p : a₀₀ = a₀₂} {r : p₀₁ = p} {s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁}
{s₁₁' : square p₁₀ p₁₂ p p₂₁} (t : s₁₁ = r ⬝ph s₁₁') : r⁻¹ ⬝ph s₁₁ = s₁₁' :=
by induction r; exact t
-- the following is used for torus.elim_surf
theorem whisker_square_aps_eq
{q₁₀ : f a₀₀ = f a₂₀} {q₀₁ : f a₀₀ = f a₀₂} {q₂₁ : f a₂₀ = f a₂₂} {q₁₂ : f a₀₂ = f a₂₂}
{r₁₀ : ap f p₁₀ = q₁₀} {r₀₁ : ap f p₀₁ = q₀₁} {r₂₁ : ap f p₂₁ = q₂₁} {r₁₂ : ap f p₁₂ = q₁₂}
{s₁₁ : p₁₀ ⬝ p₂₁ = p₀₁ ⬝ p₁₂} {t₁₁ : square q₁₀ q₁₂ q₀₁ q₂₁}
(u : square (ap02 f s₁₁) (eq_of_square t₁₁)
(ap_con f p₁₀ p₂₁ ⬝ (r₁₀ ◾ r₂₁)) (ap_con f p₀₁ p₁₂ ⬝ (r₀₁ ◾ r₁₂)))
: whisker_square r₁₀ r₁₂ r₀₁ r₂₁ (aps f (square_of_eq s₁₁)) = t₁₁ :=
begin
induction r₁₀, induction r₀₁, induction r₁₂, induction r₂₁,
induction p₁₂, induction p₁₀, induction p₂₁, esimp at *, induction s₁₁, esimp at *,
esimp [square_of_eq],
apply eq_of_fn_eq_fn !square_equiv_eq, esimp,
exact (eq_bot_of_square u)⁻¹
end
end eq

View file

@ -1,307 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Floris van Doorn
Squareovers
-/
import .square
open eq equiv is_equiv sigma
namespace eq
-- we give the argument B explicitly, because Lean would find (λa, B a) by itself, which
-- makes the type uglier (of course the two terms are definitionally equal)
inductive squareover {A : Type} (B : A → Type) {a₀₀ : A} {b₀₀ : B a₀₀} :
Π{a₂₀ a₀₂ a₂₂ : A}
{p₁₀ : a₀₀ = a₂₀} {p₁₂ : a₀₂ = a₂₂} {p₀₁ : a₀₀ = a₀₂} {p₂₁ : a₂₀ = a₂₂}
(s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁)
{b₂₀ : B a₂₀} {b₀₂ : B a₀₂} {b₂₂ : B a₂₂}
(q₁₀ : pathover B b₀₀ p₁₀ b₂₀) (q₁₂ : pathover B b₀₂ p₁₂ b₂₂)
(q₀₁ : pathover B b₀₀ p₀₁ b₀₂) (q₂₁ : pathover B b₂₀ p₂₁ b₂₂),
Type :=
idsquareo : squareover B ids idpo idpo idpo idpo
variables {A A' : Type} {B : A → Type}
{a a' a'' a₀₀ a₂₀ a₄₀ a₀₂ a₂₂ a₂₄ a₀₄ a₄₂ a₄₄ : A}
/-a₀₀-/ {p₁₀ : a₀₀ = a₂₀} /-a₂₀-/ {p₃₀ : a₂₀ = a₄₀} /-a₄₀-/
{p₀₁ : a₀₀ = a₀₂} /-s₁₁-/ {p₂₁ : a₂₀ = a₂₂} /-s₃₁-/ {p₄₁ : a₄₀ = a₄₂}
/-a₀₂-/ {p₁₂ : a₀₂ = a₂₂} /-a₂₂-/ {p₃₂ : a₂₂ = a₄₂} /-a₄₂-/
{p₀₃ : a₀₂ = a₀₄} /-s₁₃-/ {p₂₃ : a₂₂ = a₂₄} /-s₃₃-/ {p₄₃ : a₄₂ = a₄₄}
/-a₀₄-/ {p₁₄ : a₀₄ = a₂₄} /-a₂₄-/ {p₃₄ : a₂₄ = a₄₄} /-a₄₄-/
{s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁} {s₃₁ : square p₃₀ p₃₂ p₂₁ p₄₁}
{s₁₃ : square p₁₂ p₁₄ p₀₃ p₂₃} {s₃₃ : square p₃₂ p₃₄ p₂₃ p₄₃}
{b₀₀ : B a₀₀} {b₂₀ : B a₂₀} {b₄₀ : B a₄₀}
{b₀₂ : B a₀₂} {b₂₂ : B a₂₂} {b₄₂ : B a₄₂}
{b₀₄ : B a₀₄} {b₂₄ : B a₂₄} {b₄₄ : B a₄₄}
/-b₀₀-/ {q₁₀ : b₀₀ =[p₁₀] b₂₀} /-b₂₀-/ {q₃₀ : b₂₀ =[p₃₀] b₄₀} /-b₄₀-/
{q₀₁ : b₀₀ =[p₀₁] b₀₂} /-t₁₁-/ {q₂₁ : b₂₀ =[p₂₁] b₂₂} /-t₃₁-/ {q₄₁ : b₄₀ =[p₄₁] b₄₂}
/-b₀₂-/ {q₁₂ : b₀₂ =[p₁₂] b₂₂} /-b₂₂-/ {q₃₂ : b₂₂ =[p₃₂] b₄₂} /-b₄₂-/
{q₀₃ : b₀₂ =[p₀₃] b₀₄} /-t₁₃-/ {q₂₃ : b₂₂ =[p₂₃] b₂₄} /-t₃₃-/ {q₄₃ : b₄₂ =[p₄₃] b₄₄}
/-b₀₄-/ {q₁₄ : b₀₄ =[p₁₄] b₂₄} /-b₂₄-/ {q₃₄ : b₂₄ =[p₃₄] b₄₄} /-b₄₄-/
definition squareo := @squareover A B a₀₀
definition idsquareo [reducible] [constructor] (b₀₀ : B a₀₀) := @squareover.idsquareo A B a₀₀ b₀₀
definition idso [reducible] [constructor] := @squareover.idsquareo A B a₀₀ b₀₀
definition apds (f : Πa, B a) (s : square p₁₀ p₁₂ p₀₁ p₂₁)
: squareover B s (apd f p₁₀) (apd f p₁₂) (apd f p₀₁) (apd f p₂₁) :=
square.rec_on s idso
definition vrflo : squareover B vrfl q₁₀ q₁₀ idpo idpo :=
by induction q₁₀; exact idso
definition hrflo : squareover B hrfl idpo idpo q₁₀ q₁₀ :=
by induction q₁₀; exact idso
definition vdeg_squareover {p₁₀'} {s : p₁₀ = p₁₀'} {q₁₀' : b₀₀ =[p₁₀'] b₂₀}
(r : change_path s q₁₀ = q₁₀')
: squareover B (vdeg_square s) q₁₀ q₁₀' idpo idpo :=
by induction s; esimp at *; induction r; exact vrflo
definition hdeg_squareover {p₀₁'} {s : p₀₁ = p₀₁'} {q₀₁' : b₀₀ =[p₀₁'] b₀₂}
(r : change_path s q₀₁ = q₀₁')
: squareover B (hdeg_square s) idpo idpo q₀₁ q₀₁' :=
by induction s; esimp at *; induction r; exact hrflo
definition hconcato
(t₁₁ : squareover B s₁₁ q₁₀ q₁₂ q₀₁ q₂₁) (t₃₁ : squareover B s₃₁ q₃₀ q₃₂ q₂₁ q₄₁)
: squareover B (hconcat s₁₁ s₃₁) (q₁₀ ⬝o q₃₀) (q₁₂ ⬝o q₃₂) q₀₁ q₄₁ :=
by induction t₃₁; exact t₁₁
definition vconcato
(t₁₁ : squareover B s₁₁ q₁₀ q₁₂ q₀₁ q₂₁) (t₁₃ : squareover B s₁₃ q₁₂ q₁₄ q₀₃ q₂₃)
: squareover B (vconcat s₁₁ s₁₃) q₁₀ q₁₄ (q₀₁ ⬝o q₀₃) (q₂₁ ⬝o q₂₃) :=
by induction t₁₃; exact t₁₁
definition hinverseo (t₁₁ : squareover B s₁₁ q₁₀ q₁₂ q₀₁ q₂₁)
: squareover B (hinverse s₁₁) q₁₀⁻¹ᵒ q₁₂⁻¹ᵒ q₂₁ q₀₁ :=
by induction t₁₁; constructor
definition vinverseo (t₁₁ : squareover B s₁₁ q₁₀ q₁₂ q₀₁ q₂₁)
: squareover B (vinverse s₁₁) q₁₂ q₁₀ q₀₁⁻¹ᵒ q₂₁⁻¹ᵒ :=
by induction t₁₁; constructor
definition eq_vconcato {q : b₀₀ =[p₁₀] b₂₀}
(r : q = q₁₀) (t₁₁ : squareover B s₁₁ q₁₀ q₁₂ q₀₁ q₂₁) : squareover B s₁₁ q q₁₂ q₀₁ q₂₁ :=
by induction r; exact t₁₁
definition vconcato_eq {q : b₀₂ =[p₁₂] b₂₂}
(t₁₁ : squareover B s₁₁ q₁₀ q₁₂ q₀₁ q₂₁) (r : q₁₂ = q) : squareover B s₁₁ q₁₀ q q₀₁ q₂₁ :=
by induction r; exact t₁₁
definition eq_hconcato {q : b₀₀ =[p₀₁] b₀₂}
(r : q = q₀₁) (t₁₁ : squareover B s₁₁ q₁₀ q₁₂ q₀₁ q₂₁) : squareover B s₁₁ q₁₀ q₁₂ q q₂₁ :=
by induction r; exact t₁₁
definition hconcato_eq {q : b₂₀ =[p₂₁] b₂₂}
(t₁₁ : squareover B s₁₁ q₁₀ q₁₂ q₀₁ q₂₁) (r : q₂₁ = q) : squareover B s₁₁ q₁₀ q₁₂ q₀₁ q :=
by induction r; exact t₁₁
definition pathover_vconcato {p : a₀₀ = a₂₀} {sp : p = p₁₀} {q : b₀₀ =[p] b₂₀}
(r : change_path sp q = q₁₀) (t₁₁ : squareover B s₁₁ q₁₀ q₁₂ q₀₁ q₂₁)
: squareover B (sp ⬝pv s₁₁) q q₁₂ q₀₁ q₂₁ :=
by induction sp; induction r; exact t₁₁
definition vconcato_pathover {p : a₀₂ = a₂₂} {sp : p₁₂ = p} {q : b₀₂ =[p] b₂₂}
(t₁₁ : squareover B s₁₁ q₁₀ q₁₂ q₀₁ q₂₁) (r : change_path sp q₁₂ = q)
: squareover B (s₁₁ ⬝vp sp) q₁₀ q q₀₁ q₂₁ :=
by induction sp; induction r; exact t₁₁
definition pathover_hconcato {p : a₀₀ = a₀₂} {sp : p = p₀₁} {q : b₀₀ =[p] b₀₂}
(r : change_path sp q = q₀₁) (t₁₁ : squareover B s₁₁ q₁₀ q₁₂ q₀₁ q₂₁) :
squareover B (sp ⬝ph s₁₁) q₁₀ q₁₂ q q₂₁ :=
by induction sp; induction r; exact t₁₁
definition hconcato_pathover {p : a₂₀ = a₂₂} {sp : p₂₁ = p} {q : b₂₀ =[p] b₂₂}
(t₁₁ : squareover B s₁₁ q₁₀ q₁₂ q₀₁ q₂₁) (r : change_path sp q₂₁ = q) :
squareover B (s₁₁ ⬝hp sp) q₁₀ q₁₂ q₀₁ q :=
by induction sp; induction r; exact t₁₁
infix ` ⬝ho `:69 := hconcato --type using \tr
infix ` ⬝vo `:70 := vconcato --type using \tr
infix ` ⬝hop `:72 := hconcato_eq --type using \tr
infix ` ⬝vop `:74 := vconcato_eq --type using \tr
infix ` ⬝pho `:71 := eq_hconcato --type using \tr
infix ` ⬝pvo `:73 := eq_vconcato --type using \tr
-- relating squareovers to squares
definition square_of_squareover (t₁₁ : squareover B s₁₁ q₁₀ q₁₂ q₀₁ q₂₁) :
square (!con_tr ⬝ ap (λa, p₂₁ ▸ a) (tr_eq_of_pathover q₁₀))
(tr_eq_of_pathover q₁₂)
(ap (λq, q ▸ b₀₀) (eq_of_square s₁₁) ⬝ !con_tr ⬝ ap (λa, p₁₂ ▸ a) (tr_eq_of_pathover q₀₁))
(tr_eq_of_pathover q₂₁) :=
by induction t₁₁; esimp; constructor
/-
definition squareover_of_square
(q : square (!con_tr ⬝ ap (λa, p₂₁ ▸ a) (tr_eq_of_pathover q₁₀))
(tr_eq_of_pathover q₁₂)
(ap (λq, q ▸ b₀₀) (eq_of_square s₁₁) ⬝ !con_tr ⬝ ap (λa, p₁₂ ▸ a) (tr_eq_of_pathover q₀₁))
(tr_eq_of_pathover q₂₁))
: squareover B s₁₁ q₁₀ q₁₂ q₀₁ q₂₁ :=
sorry
-/
definition square_of_squareover_ids {b₀₀ b₀₂ b₂₀ b₂₂ : B a}
{t : b₀₀ = b₂₀} {b : b₀₂ = b₂₂} {l : b₀₀ = b₀₂} {r : b₂₀ = b₂₂}
(so : squareover B ids (pathover_idp_of_eq t)
(pathover_idp_of_eq b)
(pathover_idp_of_eq l)
(pathover_idp_of_eq r)) : square t b l r :=
begin
note H := square_of_squareover so, -- use apply ... in
rewrite [▸* at H,+idp_con at H,+ap_id at H,↑pathover_idp_of_eq at H],
rewrite [+to_right_inv !(pathover_equiv_tr_eq (refl a)) at H],
exact H
end
definition squareover_ids_of_square {b₀₀ b₀₂ b₂₀ b₂₂ : B a}
{t : b₀₀ = b₂₀} {b : b₀₂ = b₂₂} {l : b₀₀ = b₀₂} {r : b₂₀ = b₂₂} (q : square t b l r)
: squareover B ids (pathover_idp_of_eq t)
(pathover_idp_of_eq b)
(pathover_idp_of_eq l)
(pathover_idp_of_eq r) :=
square.rec_on q idso
-- relating pathovers to squareovers
definition pathover_of_squareover' (t₁₁ : squareover B s₁₁ q₁₀ q₁₂ q₀₁ q₂₁)
: q₁₀ ⬝o q₂₁ =[eq_of_square s₁₁] q₀₁ ⬝o q₁₂ :=
by induction t₁₁; constructor
definition pathover_of_squareover {s : p₁₀ ⬝ p₂₁ = p₀₁ ⬝ p₁₂}
(t₁₁ : squareover B (square_of_eq s) q₁₀ q₁₂ q₀₁ q₂₁)
: q₁₀ ⬝o q₂₁ =[s] q₀₁ ⬝o q₁₂ :=
begin
revert s t₁₁, refine equiv_rect' !square_equiv_eq⁻¹ᵉ (λa b, squareover B b _ _ _ _ → _) _,
intro s, exact pathover_of_squareover'
end
definition squareover_of_pathover {s : p₁₀ ⬝ p₂₁ = p₀₁ ⬝ p₁₂}
(r : q₁₀ ⬝o q₂₁ =[s] q₀₁ ⬝o q₁₂) : squareover B (square_of_eq s) q₁₀ q₁₂ q₀₁ q₂₁ :=
by induction q₁₂; esimp [concato] at r;induction r;induction q₂₁;induction q₁₀;constructor
definition pathover_top_of_squareover (t₁₁ : squareover B s₁₁ q₁₀ q₁₂ q₀₁ q₂₁)
: q₁₀ =[eq_top_of_square s₁₁] q₀₁ ⬝o q₁₂ ⬝o q₂₁⁻¹ᵒ :=
by induction t₁₁; constructor
definition squareover_of_pathover_top {s : p₁₀ = p₀₁ ⬝ p₁₂ ⬝ p₂₁⁻¹}
(r : q₁₀ =[s] q₀₁ ⬝o q₁₂ ⬝o q₂₁⁻¹ᵒ)
: squareover B (square_of_eq_top s) q₁₀ q₁₂ q₀₁ q₂₁ :=
by induction q₂₁; induction q₁₂; esimp at r;induction r;induction q₁₀;constructor
definition pathover_of_hdeg_squareover {p₀₁' : a₀₀ = a₀₂} {r : p₀₁ = p₀₁'} {q₀₁' : b₀₀ =[p₀₁'] b₀₂}
(t : squareover B (hdeg_square r) idpo idpo q₀₁ q₀₁') : q₀₁ =[r] q₀₁' :=
by induction r; induction q₀₁'; exact (pathover_of_squareover' t)⁻¹ᵒ
definition pathover_of_vdeg_squareover {p₁₀' : a₀₀ = a₂₀} {r : p₁₀ = p₁₀'} {q₁₀' : b₀₀ =[p₁₀'] b₂₀}
(t : squareover B (vdeg_square r) q₁₀ q₁₀' idpo idpo) : q₁₀ =[r] q₁₀' :=
by induction r; induction q₁₀'; exact pathover_of_squareover' t
definition squareover_of_eq_top (r : change_path (eq_top_of_square s₁₁) q₁₀ = q₀₁ ⬝o q₁₂ ⬝o q₂₁⁻¹ᵒ)
: squareover B s₁₁ q₁₀ q₁₂ q₀₁ q₂₁ :=
begin
induction s₁₁, revert q₁₂ q₁₀ r,
eapply idp_rec_on q₂₁, clear q₂₁,
intro q₁₂,
eapply idp_rec_on q₁₂, clear q₁₂,
esimp, intros,
induction r, eapply idp_rec_on q₁₀,
constructor
end
definition eq_top_of_squareover (r : squareover B s₁₁ q₁₀ q₁₂ q₀₁ q₂₁)
: change_path (eq_top_of_square s₁₁) q₁₀ = q₀₁ ⬝o q₁₂ ⬝o q₂₁⁻¹ᵒ :=
by induction r; reflexivity
definition change_square {s₁₁'} (p : s₁₁ = s₁₁') (r : squareover B s₁₁ q₁₀ q₁₂ q₀₁ q₂₁)
: squareover B s₁₁' q₁₀ q₁₂ q₀₁ q₂₁ :=
p ▸ r
/-
definition squareover_equiv_pathover (q₁₀ : b₀₀ =[p₁₀] b₂₀) (q₁₂ : b₀₂ =[p₁₂] b₂₂)
(q₀₁ : b₀₀ =[p₀₁] b₀₂) (q₂₁ : b₂₀ =[p₂₁] b₂₂)
: squareover B s₁₁ q₁₀ q₁₂ q₀₁ q₂₁ ≃ q₁₀ ⬝o q₂₁ =[eq_of_square s₁₁] q₀₁ ⬝o q₁₂ :=
begin
fapply equiv.MK,
{ exact pathover_of_squareover},
{ intro r, rewrite [-to_left_inv !square_equiv_eq s₁₁], apply squareover_of_pathover, exact r},
{ intro r, }, --need characterization of squareover lying over ids.
{ intro s, induction s, apply idp},
end
-/
definition eq_of_vdeg_squareover {q₁₀' : b₀₀ =[p₁₀] b₂₀}
(p : squareover B vrfl q₁₀ q₁₀' idpo idpo) : q₁₀ = q₁₀' :=
begin
note H := square_of_squareover p, -- use apply ... in
induction p₁₀, -- if needed we can remove this induction and use con_tr_idp in types/eq2
rewrite [▸* at H,idp_con at H,+ap_id at H],
let H' := eq_of_vdeg_square H,
exact eq_of_fn_eq_fn !pathover_equiv_tr_eq H'
end
-- definition vdeg_tr_squareover {q₁₂ : p₀₁ ▸ b₀₀ =[p₁₂] p₂₁ ▸ b₂₀} (r : q₁₀ =[_] q₁₂)
-- : squareover B s₁₁ q₁₀ q₁₂ !pathover_tr !pathover_tr :=
-- by induction p;exact vrflo
/- A version of eq_pathover where the type of the equality also varies -/
definition eq_pathover_dep {f g : Πa, B a} {p : a = a'} {q : f a = g a}
{r : f a' = g a'} (s : squareover B hrfl (pathover_idp_of_eq q) (pathover_idp_of_eq r)
(apd f p) (apd g p)) : q =[p] r :=
begin
induction p, apply pathover_idp_of_eq, apply eq_of_vdeg_square, exact square_of_squareover_ids s
end
/- charcaterization of pathovers in pathovers -/
-- in this version the fibration (B) of the pathover does not depend on the variable (a)
definition pathover_pathover {a' a₂' : A'} {p : a' = a₂'} {f g : A' → A}
{b : Πa, B (f a)} {b₂ : Πa, B (g a)} {q : Π(a' : A'), f a' = g a'}
(r : pathover B (b a') (q a') (b₂ a'))
(r₂ : pathover B (b a₂') (q a₂') (b₂ a₂'))
(s : squareover B (natural_square q p) r r₂
(pathover_ap B f (apd b p)) (pathover_ap B g (apd b₂ p)))
: pathover (λa, pathover B (b a) (q a) (b₂ a)) r p r₂ :=
begin
induction p, esimp at s, apply pathover_idp_of_eq, apply eq_of_vdeg_squareover, exact s
end
definition squareover_change_path_left {p₀₁' : a₀₀ = a₀₂} (r : p₀₁' = p₀₁)
{q₀₁ : b₀₀ =[p₀₁'] b₀₂} (t : squareover B (r ⬝ph s₁₁) q₁₀ q₁₂ q₀₁ q₂₁)
: squareover B s₁₁ q₁₀ q₁₂ (change_path r q₀₁) q₂₁ :=
by induction r; exact t
definition squareover_change_path_right {p₂₁' : a₂₀ = a₂₂} (r : p₂₁' = p₂₁)
{q₂₁ : b₂₀ =[p₂₁'] b₂₂} (t : squareover B (s₁₁ ⬝hp r⁻¹) q₁₀ q₁₂ q₀₁ q₂₁)
: squareover B s₁₁ q₁₀ q₁₂ q₀₁ (change_path r q₂₁) :=
by induction r; exact t
definition squareover_change_path_right' {p₂₁' : a₂₀ = a₂₂} (r : p₂₁ = p₂₁')
{q₂₁ : b₂₀ =[p₂₁'] b₂₂} (t : squareover B (s₁₁ ⬝hp r) q₁₀ q₁₂ q₀₁ q₂₁)
: squareover B s₁₁ q₁₀ q₁₂ q₀₁ (change_path r⁻¹ q₂₁) :=
by induction r; exact t
/- You can construct a square in a sigma-type by giving a squareover -/
definition square_dpair_eq_dpair {a₀₀ a₂₀ a₀₂ a₂₂ : A}
{p₁₀ : a₀₀ = a₂₀} {p₀₁ : a₀₀ = a₀₂} {p₂₁ : a₂₀ = a₂₂} {p₁₂ : a₀₂ = a₂₂}
(s₁₁ : square p₁₀ p₁₂ p₀₁ p₂₁) {b₀₀ : B a₀₀} {b₂₀ : B a₂₀} {b₀₂ : B a₀₂} {b₂₂ : B a₂₂}
{q₁₀ : b₀₀ =[p₁₀] b₂₀} {q₀₁ : b₀₀ =[p₀₁] b₀₂} {q₂₁ : b₂₀ =[p₂₁] b₂₂} {q₁₂ : b₀₂ =[p₁₂] b₂₂}
(t₁₁ : squareover B s₁₁ q₁₀ q₁₂ q₀₁ q₂₁) :
square (dpair_eq_dpair p₁₀ q₁₀) (dpair_eq_dpair p₁₂ q₁₂)
(dpair_eq_dpair p₀₁ q₀₁) (dpair_eq_dpair p₂₁ q₂₁) :=
by induction t₁₁; constructor
definition sigma_square {v₀₀ v₂₀ v₀₂ v₂₂ : Σa, B a}
{p₁₀ : v₀₀ = v₂₀} {p₀₁ : v₀₀ = v₀₂} {p₂₁ : v₂₀ = v₂₂} {p₁₂ : v₀₂ = v₂₂}
(s₁₁ : square p₁₀..1 p₁₂..1 p₀₁..1 p₂₁..1)
(t₁₁ : squareover B s₁₁ p₁₀..2 p₁₂..2 p₀₁..2 p₂₁..2) : square p₁₀ p₁₂ p₀₁ p₂₁ :=
begin
induction v₀₀, induction v₂₀, induction v₀₂, induction v₂₂,
rewrite [▸* at *, -sigma_eq_eta p₁₀, -sigma_eq_eta p₁₂, -sigma_eq_eta p₀₁, -sigma_eq_eta p₂₁],
exact square_dpair_eq_dpair s₁₁ t₁₁
end
end eq

View file

@ -1,144 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Floris van Doorn
Theorems about 2-dimensional paths
-/
import .cubical.square
open function
namespace eq
variables {A B C : Type} {f : A → B} {a a' a₁ a₂ a₃ a₄ : A} {b b' : B}
theorem ap_is_constant_eq (p : Πx, f x = b) (q : a = a') :
ap_is_constant p q =
eq_con_inv_of_con_eq ((eq_of_square (square_of_pathover (apd p q)))⁻¹ ⬝
whisker_left (p a) (ap_constant q b)) :=
begin
induction q, esimp, generalize (p a), intro p, cases p, apply idpath idp
end
definition ap_inv2 {p q : a = a'} (r : p = q)
: square (ap (ap f) (inverse2 r))
(inverse2 (ap (ap f) r))
(ap_inv f p)
(ap_inv f q) :=
by induction r;exact hrfl
definition ap_con2 {p₁ q₁ : a₁ = a₂} {p₂ q₂ : a₂ = a₃} (r₁ : p₁ = q₁) (r₂ : p₂ = q₂)
: square (ap (ap f) (r₁ ◾ r₂))
(ap (ap f) r₁ ◾ ap (ap f) r₂)
(ap_con f p₁ p₂)
(ap_con f q₁ q₂) :=
by induction r₂;induction r₁;exact hrfl
theorem ap_con_right_inv_sq {A B : Type} {a1 a2 : A} (f : A → B) (p : a1 = a2) :
square (ap (ap f) (con.right_inv p))
(con.right_inv (ap f p))
(ap_con f p p⁻¹ ⬝ whisker_left _ (ap_inv f p))
idp :=
by cases p;apply hrefl
theorem ap_con_left_inv_sq {A B : Type} {a1 a2 : A} (f : A → B) (p : a1 = a2) :
square (ap (ap f) (con.left_inv p))
(con.left_inv (ap f p))
(ap_con f p⁻¹ p ⬝ whisker_right _ (ap_inv f p))
idp :=
by cases p;apply vrefl
definition ap02_compose {A B C : Type} (g : B → C) (f : A → B) {a a' : A}
{p₁ p₂ : a = a'} (q : p₁ = p₂) :
square (ap_compose g f p₁) (ap_compose g f p₂) (ap02 (g ∘ f) q) (ap02 g (ap02 f q)) :=
by induction q; exact vrfl
definition ap02_id {A : Type} {a a' : A}
{p₁ p₂ : a = a'} (q : p₁ = p₂) :
square (ap_id p₁) (ap_id p₂) (ap02 id q) q :=
by induction q; exact vrfl
theorem ap_ap_is_constant {A B C : Type} (g : B → C) {f : A → B} {b : B}
(p : Πx, f x = b) {x y : A} (q : x = y) :
square (ap (ap g) (ap_is_constant p q))
(ap_is_constant (λa, ap g (p a)) q)
(ap_compose g f q)⁻¹
(!ap_con ⬝ whisker_left _ !ap_inv) :=
begin
induction q, esimp, generalize (p x), intro p, cases p, apply ids
-- induction q, rewrite [↑ap_compose,ap_inv], apply hinverse, apply ap_con_right_inv_sq,
end
theorem ap_ap_compose {A B C D : Type} (h : C → D) (g : B → C) (f : A → B)
{x y : A} (p : x = y) :
square (ap_compose (h ∘ g) f p)
(ap (ap h) (ap_compose g f p))
(ap_compose h (g ∘ f) p)
(ap_compose h g (ap f p)) :=
by induction p;exact ids
theorem ap_compose_inv {A B C : Type} (g : B → C) (f : A → B)
{x y : A} (p : x = y) :
square (ap_compose g f p⁻¹)
(inverse2 (ap_compose g f p) ⬝ (ap_inv g (ap f p))⁻¹)
(ap_inv (g ∘ f) p)
(ap (ap g) (ap_inv f p)) :=
by induction p;exact ids
theorem ap_compose_con (g : B → C) (f : A → B) (p : a₁ = a₂) (q : a₂ = a₃) :
square (ap_compose g f (p ⬝ q))
(ap_compose g f p ◾ ap_compose g f q ⬝ (ap_con g (ap f p) (ap f q))⁻¹)
(ap_con (g ∘ f) p q)
(ap (ap g) (ap_con f p q)) :=
by induction q;induction p;exact ids
theorem ap_compose_natural {A B C : Type} (g : B → C) (f : A → B)
{x y : A} {p q : x = y} (r : p = q) :
square (ap (ap (g ∘ f)) r)
(ap (ap g ∘ ap f) r)
(ap_compose g f p)
(ap_compose g f q) :=
natural_square_tr (ap_compose g f) r
theorem whisker_right_eq_of_con_inv_eq_idp {p q : a₁ = a₂} (r : p ⬝ q⁻¹ = idp) :
whisker_right q⁻¹ (eq_of_con_inv_eq_idp r) ⬝ con.right_inv q = r :=
by induction q; esimp at r; cases r; reflexivity
theorem ap_eq_of_con_inv_eq_idp (f : A → B) {p q : a₁ = a₂} (r : p ⬝ q⁻¹ = idp)
: ap02 f (eq_of_con_inv_eq_idp r) =
eq_of_con_inv_eq_idp (whisker_left _ !ap_inv⁻¹ ⬝ !ap_con⁻¹ ⬝ ap02 f r)
:=
by induction q;esimp at *;cases r;reflexivity
theorem eq_of_con_inv_eq_idp_con2 {p p' q q' : a₁ = a₂} (r : p = p') (s : q = q')
(t : p' ⬝ q'⁻¹ = idp)
: eq_of_con_inv_eq_idp (r ◾ inverse2 s ⬝ t) = r ⬝ eq_of_con_inv_eq_idp t ⬝ s⁻¹ :=
by induction s;induction r;induction q;reflexivity
definition naturality_apd_eq {A : Type} {B : A → Type} {a a₂ : A} {f g : Πa, B a}
(H : f ~ g) (p : a = a₂)
: apd f p = concato_eq (eq_concato (H a) (apd g p)) (H a₂)⁻¹ :=
begin
induction p, esimp,
generalizes [H a, g a], intro ga Ha, induction Ha,
reflexivity
end
theorem con_tr_idp {P : A → Type} {x y : A} (q : x = y) (u : P x) :
con_tr idp q u = ap (λp, p ▸ u) (idp_con q) :=
by induction q;reflexivity
definition eq_transport_Fl_idp_left {A B : Type} {a : A} {b : B} (f : A → B) (q : f a = b)
: eq_transport_Fl idp q = !idp_con⁻¹ :=
by induction q; reflexivity
definition whisker_left_idp_con_eq_assoc
{A : Type} {a₁ a₂ a₃ : A} (p : a₁ = a₂) (q : a₂ = a₃)
: whisker_left p (idp_con q)⁻¹ = con.assoc p idp q :=
by induction q; reflexivity
definition whisker_left_inverse2 {A : Type} {a : A} {p : a = a} (q : p = idp)
: whisker_left p q⁻² ⬝ q = con.right_inv p :=
by cases q; reflexivity
end eq

View file

@ -1,312 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Floris van Doorn
Ported from Coq HoTT
Theorems about embeddings and surjections
-/
import hit.trunc types.equiv cubical.square
open equiv sigma sigma.ops eq trunc is_trunc pi is_equiv fiber prod
variables {A B C : Type} (f : A → B) {b : B}
/- the image of a map is the (-1)-truncated fiber -/
definition image' [constructor] (f : A → B) (b : B) : Type := ∥ fiber f b ∥
definition is_prop_image' [instance] (f : A → B) (b : B) : is_prop (image' f b) := !is_trunc_trunc
definition image [constructor] (f : A → B) (b : B) : Prop := Prop.mk (image' f b) _
definition image.mk [constructor] {f : A → B} {b : B} (a : A) (p : f a = b)
: image f b :=
tr (fiber.mk a p)
protected definition image.rec [unfold 8] [recursor 8] {f : A → B} {b : B} {P : image' f b → Type}
[H : Πv, is_prop (P v)] (H : Π(a : A) (p : f a = b), P (image.mk a p)) (v : image' f b) : P v :=
begin unfold [image'] at *, induction v with v, induction v with a p, exact H a p end
definition is_embedding [class] (f : A → B) := Π(a a' : A), is_equiv (ap f : a = a' → f a = f a')
definition is_surjective [class] (f : A → B) := Π(b : B), image f b
definition is_split_surjective [class] (f : A → B) := Π(b : B), fiber f b
structure is_retraction [class] (f : A → B) :=
(sect : B → A)
(right_inverse : Π(b : B), f (sect b) = b)
structure is_section [class] (f : A → B) :=
(retr : B → A)
(left_inverse : Π(a : A), retr (f a) = a)
definition is_weakly_constant [class] (f : A → B) := Π(a a' : A), f a = f a'
structure is_constant [class] (f : A → B) :=
(pt : B)
(eq : Π(a : A), f a = pt)
structure is_conditionally_constant [class] (f : A → B) :=
(g : ∥A∥ → B)
(eq : Π(a : A), f a = g (tr a))
namespace function
abbreviation sect [unfold 4] := @is_retraction.sect
abbreviation right_inverse [unfold 4] := @is_retraction.right_inverse
abbreviation retr [unfold 4] := @is_section.retr
abbreviation left_inverse [unfold 4] := @is_section.left_inverse
definition is_equiv_ap_of_embedding [instance] [H : is_embedding f] (a a' : A)
: is_equiv (ap f : a = a' → f a = f a') :=
H a a'
definition ap_inv_idp {a : A} {H : is_equiv (ap f : a = a → f a = f a)}
: (ap f)⁻¹ᶠ idp = idp :> a = a :=
!left_inv
variable {f}
definition is_injective_of_is_embedding [reducible] [H : is_embedding f] {a a' : A}
: f a = f a' → a = a' :=
(ap f)⁻¹
definition is_embedding_of_is_injective [HA : is_set A] [HB : is_set B]
(H : Π(a a' : A), f a = f a' → a = a') : is_embedding f :=
begin
intro a a',
fapply adjointify,
{exact (H a a')},
{intro p, apply is_set.elim},
{intro p, apply is_set.elim}
end
variable (f)
definition is_prop_is_embedding [instance] : is_prop (is_embedding f) :=
by unfold is_embedding; exact _
definition is_embedding_equiv_is_injective [HA : is_set A] [HB : is_set B]
: is_embedding f ≃ (Π(a a' : A), f a = f a' → a = a') :=
begin
fapply equiv.MK,
{ apply @is_injective_of_is_embedding},
{ apply is_embedding_of_is_injective},
{ intro H, apply is_prop.elim},
{ intro H, apply is_prop.elim, }
end
definition is_prop_fiber_of_is_embedding [H : is_embedding f] (b : B) :
is_prop (fiber f b) :=
begin
apply is_prop.mk, intro v w,
induction v with a p, induction w with a' q, induction q,
fapply fiber_eq,
{ esimp, apply is_injective_of_is_embedding p},
{ esimp [is_injective_of_is_embedding], symmetry, apply right_inv}
end
definition is_prop_fun_of_is_embedding [H : is_embedding f] : is_trunc_fun -1 f :=
is_prop_fiber_of_is_embedding f
definition is_embedding_of_is_prop_fun [constructor] [H : is_trunc_fun -1 f] : is_embedding f :=
begin
intro a a', fapply adjointify,
{ intro p, exact ap point (@is_prop.elim (fiber f (f a')) _ (fiber.mk a p) (fiber.mk a' idp))},
{ intro p, rewrite [-ap_compose], esimp, apply ap_con_eq (@point_eq _ _ f (f a'))},
{ intro p, induction p, apply ap (ap point), apply is_prop_elim_self}
end
variable {f}
definition is_surjective_rec_on {P : Type} (H : is_surjective f) (b : B) [Pt : is_prop P]
(IH : fiber f b → P) : P :=
trunc.rec_on (H b) IH
variable (f)
definition is_surjective_of_is_split_surjective [instance] [H : is_split_surjective f]
: is_surjective f :=
λb, tr (H b)
definition is_prop_is_surjective [instance] : is_prop (is_surjective f) :=
begin unfold is_surjective, exact _ end
definition is_surjective_cancel_right {A B C : Type} (g : B → C) (f : A → B)
[H : is_surjective (g ∘ f)] : is_surjective g :=
begin
intro c,
induction H c with a p,
exact tr (fiber.mk (f a) p)
end
definition is_weakly_constant_ap [instance] [H : is_weakly_constant f] (a a' : A) :
is_weakly_constant (ap f : a = a' → f a = f a') :=
take p q : a = a',
have Π{b c : A} {r : b = c}, (H a b)⁻¹ ⬝ H a c = ap f r, from
(λb c r, eq.rec_on r !con.left_inv),
this⁻¹ ⬝ this
definition is_constant_ap [unfold 4] [instance] [H : is_constant f] (a a' : A)
: is_constant (ap f : a = a' → f a = f a') :=
begin
induction H with b q,
fapply is_constant.mk,
{ exact q a ⬝ (q a')⁻¹},
{ intro p, induction p, exact !con.right_inv⁻¹}
end
definition is_contr_is_retraction [instance] [H : is_equiv f] : is_contr (is_retraction f) :=
begin
have H2 : (Σ(g : B → A), Πb, f (g b) = b) ≃ is_retraction f,
begin
fapply equiv.MK,
{intro x, induction x with g p, constructor, exact p},
{intro h, induction h, apply sigma.mk, assumption},
{intro h, induction h, reflexivity},
{intro x, induction x, reflexivity},
end,
apply is_trunc_equiv_closed, exact H2,
apply is_equiv.is_contr_right_inverse
end
definition is_contr_is_section [instance] [H : is_equiv f] : is_contr (is_section f) :=
begin
have H2 : (Σ(g : B → A), Πa, g (f a) = a) ≃ is_section f,
begin
fapply equiv.MK,
{intro x, induction x with g p, constructor, exact p},
{intro h, induction h, apply sigma.mk, assumption},
{intro h, induction h, reflexivity},
{intro x, induction x, reflexivity},
end,
apply is_trunc_equiv_closed, exact H2,
fapply is_trunc_equiv_closed,
{apply sigma_equiv_sigma_right, intro g, apply eq_equiv_homotopy},
fapply is_trunc_equiv_closed,
{apply fiber.sigma_char},
fapply is_contr_fiber_of_is_equiv,
exact to_is_equiv (arrow_equiv_arrow_left_rev A (equiv.mk f H)),
end
definition is_embedding_of_is_equiv [instance] [H : is_equiv f] : is_embedding f :=
λa a', _
definition is_equiv_of_is_surjective_of_is_embedding
[H : is_embedding f] [H' : is_surjective f] : is_equiv f :=
@is_equiv_of_is_contr_fun _ _ _
(λb, is_surjective_rec_on H' b
(λa, is_contr.mk a
(λa',
fiber_eq ((ap f)⁻¹ ((point_eq a) ⬝ (point_eq a')⁻¹))
(by rewrite (right_inv (ap f)); rewrite inv_con_cancel_right))))
definition is_split_surjective_of_is_retraction [H : is_retraction f] : is_split_surjective f :=
λb, fiber.mk (sect f b) (right_inverse f b)
definition is_constant_compose_point [constructor] [instance] (b : B)
: is_constant (f ∘ point : fiber f b → B) :=
is_constant.mk b (λv, by induction v with a p;exact p)
definition is_embedding_of_is_prop_fiber [H : Π(b : B), is_prop (fiber f b)] : is_embedding f :=
is_embedding_of_is_prop_fun _
definition is_retraction_of_is_equiv [instance] [H : is_equiv f] : is_retraction f :=
is_retraction.mk f⁻¹ (right_inv f)
definition is_section_of_is_equiv [instance] [H : is_equiv f] : is_section f :=
is_section.mk f⁻¹ (left_inv f)
definition is_equiv_of_is_section_of_is_retraction [H1 : is_retraction f] [H2 : is_section f]
: is_equiv f :=
let g := sect f in let h := retr f in
adjointify f
g
(right_inverse f)
(λa, calc
g (f a) = h (f (g (f a))) : left_inverse
... = h (f a) : right_inverse f
... = a : left_inverse)
section
local attribute is_equiv_of_is_section_of_is_retraction [instance] [priority 10000]
local attribute trunctype.struct [instance] [priority 1] -- remove after #842 is closed
variable (f)
definition is_prop_is_retraction_prod_is_section : is_prop (is_retraction f × is_section f) :=
begin
apply is_prop_of_imp_is_contr, intro H, induction H with H1 H2,
exact _,
end
end
definition is_retraction_trunc_functor [instance] (r : A → B) [H : is_retraction r]
(n : trunc_index) : is_retraction (trunc_functor n r) :=
is_retraction.mk
(trunc_functor n (sect r))
(λb,
((trunc_functor_compose n (sect r) r) b)⁻¹
⬝ trunc_homotopy n (right_inverse r) b
⬝ trunc_functor_id n B b)
-- Lemma 3.11.7
definition is_contr_retract (r : A → B) [H : is_retraction r] : is_contr A → is_contr B :=
begin
intro CA,
apply is_contr.mk (r (center A)),
intro b,
exact ap r (center_eq (is_retraction.sect r b)) ⬝ (is_retraction.right_inverse r b)
end
local attribute is_prop_is_retraction_prod_is_section [instance]
definition is_retraction_prod_is_section_equiv_is_equiv [constructor]
: (is_retraction f × is_section f) ≃ is_equiv f :=
begin
apply equiv_of_is_prop,
intro H, induction H, apply is_equiv_of_is_section_of_is_retraction,
intro H, split, repeat exact _
end
definition is_retraction_equiv_is_split_surjective :
is_retraction f ≃ is_split_surjective f :=
begin
fapply equiv.MK,
{ intro H, induction H with g p, intro b, constructor, exact p b},
{ intro H, constructor, intro b, exact point_eq (H b)},
{ intro H, esimp, apply eq_of_homotopy, intro b, esimp, induction H b, reflexivity},
{ intro H, induction H with g p, reflexivity},
end
definition is_embedding_compose (g : B → C) (f : A → B)
(H₁ : is_embedding g) (H₂ : is_embedding f) : is_embedding (g ∘ f) :=
begin
intros, apply @(is_equiv.homotopy_closed (ap g ∘ ap f)),
{ apply is_equiv_compose},
symmetry, exact ap_compose g f
end
definition is_surjective_compose (g : B → C) (f : A → B)
(H₁ : is_surjective g) (H₂ : is_surjective f) : is_surjective (g ∘ f) :=
begin
intro c, induction H₁ c with b p, induction H₂ b with a q,
exact image.mk a (ap g q ⬝ p)
end
definition is_split_surjective_compose (g : B → C) (f : A → B)
(H₁ : is_split_surjective g) (H₂ : is_split_surjective f) : is_split_surjective (g ∘ f) :=
begin
intro c, induction H₁ c with b p, induction H₂ b with a q,
exact fiber.mk a (ap g q ⬝ p)
end
definition is_injective_compose (g : B → C) (f : A → B)
(H₁ : Π⦃b b'⦄, g b = g b' → b = b') (H₂ : Π⦃a a'⦄, f a = f a' → a = a')
⦃a a' : A⦄ (p : g (f a) = g (f a')) : a = a' :=
H₂ (H₁ p)
/-
The definitions
is_surjective_of_is_equiv
is_equiv_equiv_is_embedding_times_is_surjective
are in types.trunc
See types.arrow_2 for retractions
-/
end function

View file

@ -1,156 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
Declaration of the coequalizer
-/
import types.equiv .quotient
open quotient eq equiv is_trunc sigma sigma.ops
namespace coeq
section
universe u
parameters {A B : Type.{u}} (f g : A → B)
inductive coeq_rel : B → B → Type :=
| Rmk : Π(x : A), coeq_rel (f x) (g x)
open coeq_rel
local abbreviation R := coeq_rel
definition coeq : Type := quotient coeq_rel -- TODO: define this in root namespace
definition coeq_i (x : B) : coeq :=
class_of R x
/- cp is the name Coq uses. I don't know what it abbreviates, but at least it's short :-) -/
definition cp (x : A) : coeq_i (f x) = coeq_i (g x) :=
eq_of_rel coeq_rel (Rmk f g x)
protected definition rec {P : coeq → Type} (P_i : Π(x : B), P (coeq_i x))
(Pcp : Π(x : A), P_i (f x) =[cp x] P_i (g x)) (y : coeq) : P y :=
begin
induction y,
{ apply P_i},
{ cases H, apply Pcp}
end
protected definition rec_on [reducible] {P : coeq → Type} (y : coeq)
(P_i : Π(x : B), P (coeq_i x)) (Pcp : Π(x : A), P_i (f x) =[cp x] P_i (g x)) : P y :=
rec P_i Pcp y
theorem rec_cp {P : coeq → Type} (P_i : Π(x : B), P (coeq_i x))
(Pcp : Π(x : A), P_i (f x) =[cp x] P_i (g x))
(x : A) : apd (rec P_i Pcp) (cp x) = Pcp x :=
!rec_eq_of_rel
protected definition elim {P : Type} (P_i : B → P)
(Pcp : Π(x : A), P_i (f x) = P_i (g x)) (y : coeq) : P :=
rec P_i (λx, pathover_of_eq _ (Pcp x)) y
protected definition elim_on [reducible] {P : Type} (y : coeq) (P_i : B → P)
(Pcp : Π(x : A), P_i (f x) = P_i (g x)) : P :=
elim P_i Pcp y
theorem elim_cp {P : Type} (P_i : B → P) (Pcp : Π(x : A), P_i (f x) = P_i (g x))
(x : A) : ap (elim P_i Pcp) (cp x) = Pcp x :=
begin
apply eq_of_fn_eq_fn_inv !(pathover_constant (cp x)),
rewrite [▸*,-apd_eq_pathover_of_eq_ap,↑elim,rec_cp],
end
protected definition elim_type (P_i : B → Type)
(Pcp : Π(x : A), P_i (f x) ≃ P_i (g x)) (y : coeq) : Type :=
elim P_i (λx, ua (Pcp x)) y
protected definition elim_type_on [reducible] (y : coeq) (P_i : B → Type)
(Pcp : Π(x : A), P_i (f x) ≃ P_i (g x)) : Type :=
elim_type P_i Pcp y
theorem elim_type_cp (P_i : B → Type) (Pcp : Π(x : A), P_i (f x) ≃ P_i (g x))
(x : A) : transport (elim_type P_i Pcp) (cp x) = Pcp x :=
by rewrite [tr_eq_cast_ap_fn,↑elim_type,elim_cp];apply cast_ua_fn
protected definition rec_prop {P : coeq → Type} [H : Πx, is_prop (P x)]
(P_i : Π(x : B), P (coeq_i x)) (y : coeq) : P y :=
rec P_i (λa, !is_prop.elimo) y
protected definition elim_prop {P : Type} [H : is_prop P] (P_i : B → P) (y : coeq) : P :=
elim P_i (λa, !is_prop.elim) y
end
end coeq
attribute coeq.coeq_i [constructor]
attribute coeq.rec coeq.elim [unfold 8] [recursor 8]
attribute coeq.elim_type [unfold 7]
attribute coeq.rec_on coeq.elim_on [unfold 6]
attribute coeq.elim_type_on [unfold 5]
/- Flattening -/
namespace coeq
section
open function
universe u
parameters {A B : Type.{u}} (f g : A → B) (P_i : B → Type)
(Pcp : Πx : A, P_i (f x) ≃ P_i (g x))
local abbreviation P := coeq.elim_type f g P_i Pcp
local abbreviation F : sigma (P_i ∘ f) → sigma P_i :=
λz, ⟨f z.1, z.2⟩
local abbreviation G : sigma (P_i ∘ f) → sigma P_i :=
λz, ⟨g z.1, Pcp z.1 z.2⟩
local abbreviation Pr : Π⦃b b' : B⦄,
coeq_rel f g b b' → P_i b ≃ P_i b' :=
@coeq_rel.rec A B f g _ Pcp
local abbreviation P' := quotient.elim_type P_i Pr
protected definition flattening : sigma P ≃ coeq F G :=
begin
have H : Πz, P z ≃ P' z,
begin
intro z, apply equiv_of_eq,
have H1 : coeq.elim_type f g P_i Pcp = quotient.elim_type P_i Pr,
begin
change
quotient.rec P_i
(λb b' r, coeq_rel.cases_on r (λx, pathover_of_eq _ (ua (Pcp x))))
= quotient.rec P_i
(λb b' r, pathover_of_eq _ (ua (coeq_rel.cases_on r Pcp))),
have H2 : Π⦃b b' : B⦄ (r : coeq_rel f g b b'),
coeq_rel.cases_on r (λx, pathover_of_eq _ (ua (Pcp x)))
= pathover_of_eq _ (ua (coeq_rel.cases_on r Pcp))
:> P_i b =[eq_of_rel (coeq_rel f g) r] P_i b',
begin intros b b' r, cases r, reflexivity end,
rewrite (eq_of_homotopy3 H2)
end,
apply ap10 H1
end,
apply equiv.trans (sigma_equiv_sigma_right H),
apply equiv.trans !quotient.flattening.flattening_lemma,
fapply quotient.equiv,
{ reflexivity },
{ intros bp bp',
fapply equiv.MK,
{ intro r, induction r with b b' r p,
induction r with x, exact coeq_rel.Rmk F G ⟨x, p⟩ },
{ esimp, intro r, induction r with xp,
induction xp with x p,
exact quotient.flattening.flattening_rel.mk Pr
(coeq_rel.Rmk f g x) p },
{ esimp, intro r, induction r with xp,
induction xp with x p, reflexivity },
{ intro r, induction r with b b' r p,
induction r with x, reflexivity } }
end
end
end coeq

View file

@ -1,203 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
Definition of general colimits and sequential colimits.
-/
/- definition of a general colimit -/
open eq nat quotient sigma equiv is_trunc
namespace colimit
section
parameters {I J : Type} (A : I → Type) (dom cod : J → I)
(f : Π(j : J), A (dom j) → A (cod j))
variables {i : I} (a : A i) (j : J) (b : A (dom j))
local abbreviation B := Σ(i : I), A i
inductive colim_rel : B → B → Type :=
| Rmk : Π{j : J} (a : A (dom j)), colim_rel ⟨cod j, f j a⟩ ⟨dom j, a⟩
open colim_rel
local abbreviation R := colim_rel
-- TODO: define this in root namespace
definition colimit : Type :=
quotient colim_rel
definition incl : colimit :=
class_of R ⟨i, a⟩
abbreviation ι := @incl
definition cglue : ι (f j b) = ι b :=
eq_of_rel colim_rel (Rmk f b)
protected definition rec {P : colimit → Type}
(Pincl : Π⦃i : I⦄ (x : A i), P (ι x))
(Pglue : Π(j : J) (x : A (dom j)), Pincl (f j x) =[cglue j x] Pincl x)
(y : colimit) : P y :=
begin
fapply (quotient.rec_on y),
{ intro a, cases a, apply Pincl},
{ intro a a' H, cases H, apply Pglue}
end
protected definition rec_on [reducible] {P : colimit → Type} (y : colimit)
(Pincl : Π⦃i : I⦄ (x : A i), P (ι x))
(Pglue : Π(j : J) (x : A (dom j)), Pincl (f j x) =[cglue j x] Pincl x) : P y :=
rec Pincl Pglue y
theorem rec_cglue {P : colimit → Type}
(Pincl : Π⦃i : I⦄ (x : A i), P (ι x))
(Pglue : Π(j : J) (x : A (dom j)), Pincl (f j x) =[cglue j x] Pincl x)
{j : J} (x : A (dom j)) : apd (rec Pincl Pglue) (cglue j x) = Pglue j x :=
!rec_eq_of_rel
protected definition elim {P : Type} (Pincl : Π⦃i : I⦄ (x : A i), P)
(Pglue : Π(j : J) (x : A (dom j)), Pincl (f j x) = Pincl x) (y : colimit) : P :=
rec Pincl (λj a, pathover_of_eq _ (Pglue j a)) y
protected definition elim_on [reducible] {P : Type} (y : colimit)
(Pincl : Π⦃i : I⦄ (x : A i), P)
(Pglue : Π(j : J) (x : A (dom j)), Pincl (f j x) = Pincl x) : P :=
elim Pincl Pglue y
theorem elim_cglue {P : Type}
(Pincl : Π⦃i : I⦄ (x : A i), P)
(Pglue : Π(j : J) (x : A (dom j)), Pincl (f j x) = Pincl x)
{j : J} (x : A (dom j)) : ap (elim Pincl Pglue) (cglue j x) = Pglue j x :=
begin
apply eq_of_fn_eq_fn_inv !(pathover_constant (cglue j x)),
rewrite [▸*,-apd_eq_pathover_of_eq_ap,↑elim,rec_cglue],
end
protected definition elim_type (Pincl : Π⦃i : I⦄ (x : A i), Type)
(Pglue : Π(j : J) (x : A (dom j)), Pincl (f j x) ≃ Pincl x) (y : colimit) : Type :=
elim Pincl (λj a, ua (Pglue j a)) y
protected definition elim_type_on [reducible] (y : colimit)
(Pincl : Π⦃i : I⦄ (x : A i), Type)
(Pglue : Π(j : J) (x : A (dom j)), Pincl (f j x) ≃ Pincl x) : Type :=
elim_type Pincl Pglue y
theorem elim_type_cglue (Pincl : Π⦃i : I⦄ (x : A i), Type)
(Pglue : Π(j : J) (x : A (dom j)), Pincl (f j x) ≃ Pincl x)
{j : J} (x : A (dom j)) : transport (elim_type Pincl Pglue) (cglue j x) = Pglue j x :=
by rewrite [tr_eq_cast_ap_fn,↑elim_type,elim_cglue];apply cast_ua_fn
protected definition rec_prop {P : colimit → Type} [H : Πx, is_prop (P x)]
(Pincl : Π⦃i : I⦄ (x : A i), P (ι x)) (y : colimit) : P y :=
rec Pincl (λa b, !is_prop.elimo) y
protected definition elim_prop {P : Type} [H : is_prop P] (Pincl : Π⦃i : I⦄ (x : A i), P)
(y : colimit) : P :=
elim Pincl (λa b, !is_prop.elim) y
end
end colimit
/- definition of a sequential colimit -/
namespace seq_colim
section
/-
we define it directly in terms of quotients. An alternative definition could be
definition seq_colim := colimit.colimit A id succ f
-/
parameters {A : → Type} (f : Π⦃n⦄, A n → A (succ n))
variables {n : } (a : A n)
local abbreviation B := Σ(n : ), A n
inductive seq_rel : B → B → Type :=
| Rmk : Π{n : } (a : A n), seq_rel ⟨succ n, f a⟩ ⟨n, a⟩
open seq_rel
local abbreviation R := seq_rel
-- TODO: define this in root namespace
definition seq_colim : Type :=
quotient seq_rel
definition inclusion : seq_colim :=
class_of R ⟨n, a⟩
abbreviation sι := @inclusion
definition glue : sι (f a) = sι a :=
eq_of_rel seq_rel (Rmk f a)
protected definition rec {P : seq_colim → Type}
(Pincl : Π⦃n : ℕ⦄ (a : A n), P (sι a))
(Pglue : Π(n : ) (a : A n), Pincl (f a) =[glue a] Pincl a) (aa : seq_colim) : P aa :=
begin
fapply (quotient.rec_on aa),
{ intro a, cases a, apply Pincl},
{ intro a a' H, cases H, apply Pglue}
end
protected definition rec_on [reducible] {P : seq_colim → Type} (aa : seq_colim)
(Pincl : Π⦃n : ℕ⦄ (a : A n), P (sι a))
(Pglue : Π⦃n : ℕ⦄ (a : A n), Pincl (f a) =[glue a] Pincl a)
: P aa :=
rec Pincl Pglue aa
theorem rec_glue {P : seq_colim → Type} (Pincl : Π⦃n : ℕ⦄ (a : A n), P (sι a))
(Pglue : Π⦃n : ℕ⦄ (a : A n), Pincl (f a) =[glue a] Pincl a) {n : } (a : A n)
: apd (rec Pincl Pglue) (glue a) = Pglue a :=
!rec_eq_of_rel
protected definition elim {P : Type} (Pincl : Π⦃n : ℕ⦄ (a : A n), P)
(Pglue : Π⦃n : ℕ⦄ (a : A n), Pincl (f a) = Pincl a) : seq_colim → P :=
rec Pincl (λn a, pathover_of_eq _ (Pglue a))
protected definition elim_on [reducible] {P : Type} (aa : seq_colim)
(Pincl : Π⦃n : ℕ⦄ (a : A n), P)
(Pglue : Π⦃n : ℕ⦄ (a : A n), Pincl (f a) = Pincl a) : P :=
elim Pincl Pglue aa
theorem elim_glue {P : Type} (Pincl : Π⦃n : ℕ⦄ (a : A n), P)
(Pglue : Π⦃n : ℕ⦄ (a : A n), Pincl (f a) = Pincl a) {n : } (a : A n)
: ap (elim Pincl Pglue) (glue a) = Pglue a :=
begin
apply eq_of_fn_eq_fn_inv !(pathover_constant (glue a)),
rewrite [▸*,-apd_eq_pathover_of_eq_ap,↑elim,rec_glue],
end
protected definition elim_type (Pincl : Π⦃n : ℕ⦄ (a : A n), Type)
(Pglue : Π⦃n : ℕ⦄ (a : A n), Pincl (f a) ≃ Pincl a) : seq_colim → Type :=
elim Pincl (λn a, ua (Pglue a))
protected definition elim_type_on [reducible] (aa : seq_colim)
(Pincl : Π⦃n : ℕ⦄ (a : A n), Type)
(Pglue : Π⦃n : ℕ⦄ (a : A n), Pincl (f a) ≃ Pincl a) : Type :=
elim_type Pincl Pglue aa
theorem elim_type_glue (Pincl : Π⦃n : ℕ⦄ (a : A n), Type)
(Pglue : Π⦃n : ℕ⦄ (a : A n), Pincl (f a) ≃ Pincl a) {n : } (a : A n)
: transport (elim_type Pincl Pglue) (glue a) = Pglue a :=
by rewrite [tr_eq_cast_ap_fn,↑elim_type,elim_glue]; apply cast_ua_fn
theorem elim_type_glue_inv (Pincl : Π⦃n : ℕ⦄ (a : A n), Type)
(Pglue : Π⦃n : ℕ⦄ (a : A n), Pincl (f a) ≃ Pincl a) {n : } (a : A n)
: transport (seq_colim.elim_type f Pincl Pglue) (glue a)⁻¹ = to_inv (Pglue a) :=
by rewrite [tr_eq_cast_ap_fn, ↑seq_colim.elim_type, ap_inv, elim_glue]; apply cast_ua_inv_fn
protected definition rec_prop {P : seq_colim → Type} [H : Πx, is_prop (P x)]
(Pincl : Π⦃n : ℕ⦄ (a : A n), P (sι a)) (aa : seq_colim) : P aa :=
rec Pincl (λa b, !is_prop.elimo) aa
protected definition elim_prop {P : Type} [H : is_prop P] (Pincl : Π⦃n : ℕ⦄ (a : A n), P)
: seq_colim → P :=
elim Pincl (λa b, !is_prop.elim)
end
end seq_colim
attribute colimit.incl seq_colim.inclusion [constructor]
attribute colimit.rec colimit.elim [unfold 10] [recursor 10]
attribute colimit.elim_type [unfold 9]
attribute colimit.rec_on colimit.elim_on [unfold 8]
attribute colimit.elim_type_on [unfold 7]
attribute seq_colim.rec seq_colim.elim [unfold 6] [recursor 6]
attribute seq_colim.elim_type [unfold 5]
attribute seq_colim.rec_on seq_colim.elim_on [unfold 4]
attribute seq_colim.elim_type_on [unfold 3]

View file

@ -1,8 +0,0 @@
/-
Copyright (c) 2016 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
-/
import .two_quotient .colimit .coeq .refl_quotient

View file

@ -1,247 +0,0 @@
/-
Copyright (c) 2015-16 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
The groupoid quotient. This is a 1-type which path spaces is the same as the morphisms
a given groupoid. We define it as the 1-truncation of a two quotient.
-/
import algebra.category.groupoid .two_quotient homotopy.connectedness
algebra.group_theory
open trunc_two_quotient eq bool unit relation category e_closure iso is_trunc trunc equiv is_equiv
group
namespace groupoid_quotient
section
parameter (G : Groupoid)
inductive groupoid_quotient_R : G → G → Type :=
| Rmk : Π{a b : G} (f : a ⟶ b), groupoid_quotient_R a b
open groupoid_quotient_R
local abbreviation R := groupoid_quotient_R
inductive groupoid_quotient_Q : Π⦃x y : G⦄,
e_closure groupoid_quotient_R x y → e_closure groupoid_quotient_R x y → Type :=
| Qconcat : Π{a b c : G} (g : b ⟶ c) (f : a ⟶ b),
groupoid_quotient_Q [Rmk (g ∘ f)] ([Rmk f] ⬝r [Rmk g])
open groupoid_quotient_Q
local abbreviation Q := groupoid_quotient_Q
definition groupoid_quotient := trunc_two_quotient 1 R Q
local attribute groupoid_quotient [reducible]
definition is_trunc_groupoid_quotient [instance] : is_trunc 1 groupoid_quotient := _
parameter {G}
variables {a b c : G}
definition elt (a : G) : groupoid_quotient := incl0 a
definition pth (f : a ⟶ b) : elt a = elt b := incl1 (Rmk f)
definition resp_comp (g : b ⟶ c) (f : a ⟶ b) : pth (g ∘ f) = pth f ⬝ pth g := incl2 (Qconcat g f)
definition resp_id (a : G) : pth (ID a) = idp :=
begin
apply cancel_right (pth (id)), refine _ ⬝ !idp_con⁻¹,
refine !resp_comp⁻¹ ⬝ _,
exact ap pth !id_id,
end
definition resp_inv (f : a ⟶ b) : pth (f⁻¹) = (pth f)⁻¹ :=
begin
apply eq_inv_of_con_eq_idp',
refine !resp_comp⁻¹ ⬝ _,
refine ap pth !right_inverse ⬝ _,
apply resp_id
end
protected definition rec {P : groupoid_quotient → Type} [Πx, is_trunc 1 (P x)]
(Pe : Πg, P (elt g)) (Pp : Π⦃a b⦄ (f : a ⟶ b), Pe a =[pth f] Pe b)
(Pcomp : Π⦃a b c⦄ (g : b ⟶ c) (f : a ⟶ b),
change_path (resp_comp g f) (Pp (g ∘ f)) = Pp f ⬝o Pp g)
(x : groupoid_quotient) : P x :=
begin
induction x,
{ apply Pe},
{ induction s with a b f, apply Pp},
{ induction q with a b c g f,
apply Pcomp}
end
protected definition rec_on {P : groupoid_quotient → Type} [Πx, is_trunc 1 (P x)]
(x : groupoid_quotient)
(Pe : Πg, P (elt g)) (Pp : Π⦃a b⦄ (f : a ⟶ b), Pe a =[pth f] Pe b)
(Pcomp : Π⦃a b c⦄ (g : b ⟶ c) (f : a ⟶ b),
change_path (resp_comp g f) (Pp (g ∘ f)) = Pp f ⬝o Pp g) : P x :=
rec Pe Pp Pcomp x
protected definition set_rec {P : groupoid_quotient → Type} [Πx, is_set (P x)]
(Pe : Πg, P (elt g)) (Pp : Π⦃a b⦄ (f : a ⟶ b), Pe a =[pth f] Pe b)
(x : groupoid_quotient) : P x :=
rec Pe Pp !center x
protected definition prop_rec {P : groupoid_quotient → Type} [Πx, is_prop (P x)]
(Pe : Πg, P (elt g)) (x : groupoid_quotient) : P x :=
rec Pe !center !center x
definition rec_pth {P : groupoid_quotient → Type} [Πx, is_trunc 1 (P x)]
{Pe : Πg, P (elt g)} {Pp : Π⦃a b⦄ (f : a ⟶ b), Pe a =[pth f] Pe b}
(Pcomp : Π⦃a b c⦄ (g : b ⟶ c) (f : a ⟶ b),
change_path (resp_comp g f) (Pp (g ∘ f)) = Pp f ⬝o Pp g)
{a b : G} (f : a ⟶ b) : apd (rec Pe Pp Pcomp) (pth f) = Pp f :=
proof !rec_incl1 qed
protected definition elim {P : Type} [is_trunc 1 P] (Pe : G → P)
(Pp : Π⦃a b⦄ (f : a ⟶ b), Pe a = Pe b)
(Pcomp : Π⦃a b c⦄ (g : b ⟶ c) (f : a ⟶ b), Pp (g ∘ f) = Pp f ⬝ Pp g)
(x : groupoid_quotient) : P :=
begin
induction x,
{ exact Pe a},
{ induction s with a b f, exact Pp f},
{ induction q with a b c g f,
exact Pcomp g f}
end
protected definition elim_on [reducible] {P : Type} [is_trunc 1 P] (x : groupoid_quotient)
(Pe : G → P) (Pp : Π⦃a b⦄ (f : a ⟶ b), Pe a = Pe b)
(Pcomp : Π⦃a b c⦄ (g : b ⟶ c) (f : a ⟶ b), Pp (g ∘ f) = Pp f ⬝ Pp g) : P :=
elim Pe Pp Pcomp x
protected definition set_elim [reducible] {P : Type} [is_set P] (Pe : G → P)
(Pp : Π⦃a b⦄ (f : a ⟶ b), Pe a = Pe b)
(x : groupoid_quotient) : P :=
elim Pe Pp !center x
protected definition prop_elim [reducible] {P : Type} [is_prop P] (Pe : G → P)
(x : groupoid_quotient) : P :=
elim Pe !center !center x
definition elim_pth {P : Type} [is_trunc 1 P] {Pe : G → P} {Pp : Π⦃a b⦄ (f : a ⟶ b), Pe a = Pe b}
(Pcomp : Π⦃a b c⦄ (g : b ⟶ c) (f : a ⟶ b), Pp (g ∘ f) = Pp f ⬝ Pp g) {a b : G} (f : a ⟶ b) :
ap (elim Pe Pp Pcomp) (pth f) = Pp f :=
!elim_incl1
-- The following rule is also true because P is a 1-type, and can be proven by `!is_set.elims`
-- The following is the canonical proofs which holds for any truncated two-quotient.
theorem elim_resp_comp {P : Type} [is_trunc 1 P] {Pe : G → P}
{Pp : Π⦃a b⦄ (f : a ⟶ b), Pe a = Pe b}
(Pcomp : Π⦃a b c⦄ (g : b ⟶ c) (f : a ⟶ b), Pp (g ∘ f) = Pp f ⬝ Pp g)
{a b c : G} (g : b ⟶ c) (f : a ⟶ b)
: square (ap02 (elim Pe Pp Pcomp) (resp_comp g f))
(Pcomp g f)
(elim_pth Pcomp (g ∘ f))
(!ap_con ⬝ (elim_pth Pcomp f ◾ elim_pth Pcomp g)) :=
proof !elim_incl2 qed
protected definition elim_set.{u} (Pe : G → Set.{u}) (Pp : Π⦃a b⦄ (f : a ⟶ b), Pe a ≃ Pe b)
(Pcomp : Π⦃a b c⦄ (g : b ⟶ c) (f : a ⟶ b) (x : Pe a), Pp (g ∘ f) x = Pp g (Pp f x))
(x : groupoid_quotient) : Set.{u} :=
elim Pe (λa b f, tua (Pp f)) (λa b c g f, ap tua (equiv_eq (Pcomp g f)) ⬝ !tua_trans) x
theorem elim_set_pth {Pe : G → Set} {Pp : Π⦃a b⦄ (f : a ⟶ b), Pe a ≃ Pe b}
(Pcomp : Π⦃a b c⦄ (g : b ⟶ c) (f : a ⟶ b) (x : Pe a), Pp (g ∘ f) x = Pp g (Pp f x))
{a b : G} (f : a ⟶ b) :
transport (elim_set Pe Pp Pcomp) (pth f) = Pp f :=
by rewrite [tr_eq_cast_ap_fn, ↑elim_set, ▸*, ap_compose' trunctype.carrier, elim_pth];
apply tcast_tua_fn
end
end groupoid_quotient
attribute groupoid_quotient.elt [constructor]
attribute groupoid_quotient.rec groupoid_quotient.elim [unfold 7] [recursor 7]
attribute groupoid_quotient.rec_on groupoid_quotient.elim_on [unfold 4]
attribute groupoid_quotient.set_rec groupoid_quotient.set_elim [unfold 6]
attribute groupoid_quotient.prop_rec groupoid_quotient.prop_elim
groupoid_quotient.elim_set [unfold 5]
open sigma pi is_conn function
namespace groupoid_quotient
section
universe variables u v
variables {G : Groupoid.{u v}} (a : G) {b c : G}
include a
protected definition code [unfold 3] (x : groupoid_quotient G) : Set.{v} :=
begin
refine groupoid_quotient.elim_set _ _ _ x,
{ intro b, exact homset a b},
{ intro b c g, exact equiv_postcompose g},
{ intro b c d h g f, esimp at *, apply assoc'}
end
omit a
local abbreviation code [unfold 3] := @groupoid_quotient.code G a
variable {a}
protected definition encode [unfold 4] (x : groupoid_quotient G) (p : elt a = x) : code a x :=
transport (code a) p (ID a)
protected definition decode [unfold 3] (x : groupoid_quotient G) (z : code a x) : elt a = x :=
begin
induction x using groupoid_quotient.set_rec with b b c g,
{ esimp, exact pth z},
{ apply arrow_pathover_left, esimp, intro f, apply eq_pathover_constant_left_id_right,
apply square_of_eq, refine !resp_comp⁻¹ ⬝ _ ⬝ !idp_con⁻¹, rewrite elim_set_pth}
end
local abbreviation encode [unfold_full] := @groupoid_quotient.encode G a
local abbreviation decode [unfold_full] := @groupoid_quotient.decode G a
protected definition decode_encode (x : groupoid_quotient G) (p : elt a = x) :
decode x (encode x p) = p :=
begin induction p, esimp, apply resp_id end
protected definition encode_decode (x : groupoid_quotient G) (z : code a x) :
encode x (decode x z) = z :=
begin
induction x using groupoid_quotient.prop_rec with b,
esimp, refine ap10 !elim_set_pth.{u v v} (ID a) ⬝ _, esimp,
apply id_right
end
definition decode_comp (z : code a (elt b)) (z' : code b (elt c)) :
decode (elt c) (z' ∘ z) = decode (elt b) z ⬝ decode (elt c) z' :=
!resp_comp
variables (a b)
definition elt_eq_elt_equiv [constructor] : (elt a = elt b) ≃ (a ⟶ b) :=
equiv.MK (encode (elt b)) (decode (elt b))
(groupoid_quotient.encode_decode (elt b)) (groupoid_quotient.decode_encode (elt b))
variables {a b}
definition encode_con (p : elt a = elt b)
(q : elt b = elt c) : encode (elt c) (p ⬝ q) = encode (elt c) q ∘ encode (elt b) p :=
begin
apply eq_of_fn_eq_fn (elt_eq_elt_equiv a c)⁻¹ᵉ,
refine !right_inv ⬝ _ ⬝ !decode_comp⁻¹,
apply concat2, do 2 exact (to_left_inv !elt_eq_elt_equiv _)⁻¹
end
variable (G)
definition is_conn_groupoid_quotient [H : is_conn 0 G] : is_conn 0 (groupoid_quotient G) :=
begin
have g : trunc 0 G, from !center,
induction g with g,
have p : Πh, ∥ g = h ∥,
begin
intro h, refine !tr_eq_tr_equiv _, apply is_prop.elim
end,
fapply is_contr.mk,
{ apply trunc_functor 0 elt (tr g)},
{ intro x, induction x with x,
induction x using groupoid_quotient.prop_rec with b, esimp,
induction p b with q, exact ap (tr ∘ elt) q}
end
end
end groupoid_quotient
export [unfold] groupoid_quotient

View file

@ -1,28 +0,0 @@
hit
===
Declaration and theorems of higher inductive types in Lean. We take
two higher inductive types (hits) as primitive notions in Lean. We
define all other hits in terms of these two hits. The hits which are
primitive are n-truncation and quotients. These are defined in
[init.hit](../init/hit.hlean) and they have definitional computation
rules on the point constructors.
Here we find hits related to the basic structure theory of HoTT. The
hits related to homotopy theory are defined in
[homotopy](../homotopy/homotopy.md).
Files in this folder:
* [quotient](quotient.hlean): quotients, primitive
* [trunc](trunc.hlean): truncation, primitive
* [colimit](colimit.hlean): Colimits of arbitrary diagrams and sequential colimits, defined using quotients
* [pushout](pushout.hlean): Pushouts, defined using quotients
* [coeq](coeq.hlean): Co-equalizers, defined using quotients
* [set_quotient](set_quotient.hlean): Set-quotients, defined using quotients and set-truncation
* [prop_trunc](prop_trunc.hlean): The construction of the propositional truncation from quotients.
The following hits have also 2-constructors. They are defined only using quotients.
* [two_quotient](two_quotient.hlean): Quotients where you can also specify 2-paths. These are used for all hits which have 2-constructors, and they are almost fully general for such hits, as long as they are nonrecursive
* [refl_quotient](refl_quotient.hlean): Quotients where you can also specify 2-paths
* [groupoid_quotient](groupoid_quotient.hlean): The realization or quotient of a groupoid.

View file

@ -1,427 +0,0 @@
import function types.trunc hit.colimit homotopy.connectedness --types.nat.hott hit.trunc cubical.square
open eq is_trunc unit quotient seq_colim pi nat equiv sum algebra is_conn function
/-
In this file we define the propositional truncation, which, given (X : Type)
has constructors
* tr : X → trunc X
* is_prop_trunc : is_prop (trunc X)
and with a recursor which recurses to any family of mere propositions.
The construction uses a "one step truncation" of X, with two constructors:
* tr : X → one_step_tr X
* tr_eq : Π(a b : X), tr a = tr b
This is like a truncation, but taking out the recursive part.
Martin Escardo calls this construction the generalized circle, since the one step truncation of the
unit type is the circle.
Then we can repeat this n times:
A 0 = X,
A (n + 1) = one_step_tr (A n)
We have a map
f {n : } : A n → A (n + 1) := tr
Then trunc is defined as the sequential colimit of (A, f).
Both the one step truncation and the sequential colimit can be defined as a quotient, which is a
primitive HIT in Lean. Here, with a quotient, we mean the following HIT:
Given {X : Type} (R : X → X → Type) we have the constructors
* class_of : X → quotient R
* eq_of_rel : Π{a a' : X}, R a a' → a = a'
See the comment below for a sketch of the proof that (trunc A) is actually a mere proposition.
-/
/- definition of "one step truncation" in terms of quotients -/
namespace one_step_tr
section
parameters {A : Type}
variables (a a' : A)
protected definition R (a a' : A) : Type₀ := unit
parameter (A)
definition one_step_tr : Type := quotient R
parameter {A}
definition tr : one_step_tr :=
class_of R a
definition tr_eq : tr a = tr a' :=
eq_of_rel _ star
protected definition rec {P : one_step_tr → Type} (Pt : Π(a : A), P (tr a))
(Pe : Π(a a' : A), Pt a =[tr_eq a a'] Pt a') (x : one_step_tr) : P x :=
begin
fapply (quotient.rec_on x),
{ intro a, apply Pt},
{ intro a a' H, cases H, apply Pe}
end
protected definition rec_on [reducible] {P : one_step_tr → Type} (x : one_step_tr)
(Pt : Π(a : A), P (tr a)) (Pe : Π(a a' : A), Pt a =[tr_eq a a'] Pt a') : P x :=
rec Pt Pe x
protected definition elim {P : Type} (Pt : A → P)
(Pe : Π(a a' : A), Pt a = Pt a') (x : one_step_tr) : P :=
rec Pt (λa a', pathover_of_eq _ (Pe a a')) x
protected definition elim_on [reducible] {P : Type} (x : one_step_tr) (Pt : A → P)
(Pe : Π(a a' : A), Pt a = Pt a') : P :=
elim Pt Pe x
theorem rec_tr_eq {P : one_step_tr → Type} (Pt : Π(a : A), P (tr a))
(Pe : Π(a a' : A), Pt a =[tr_eq a a'] Pt a') (a a' : A)
: apd (rec Pt Pe) (tr_eq a a') = Pe a a' :=
!rec_eq_of_rel
theorem elim_tr_eq {P : Type} (Pt : A → P)
(Pe : Π(a a' : A), Pt a = Pt a') (a a' : A)
: ap (elim Pt Pe) (tr_eq a a') = Pe a a' :=
begin
apply eq_of_fn_eq_fn_inv !(pathover_constant (tr_eq a a')),
rewrite [▸*,-apd_eq_pathover_of_eq_ap,↑elim,rec_tr_eq],
end
end
definition n_step_tr [reducible] (A : Type) (n : ) : Type :=
nat.rec_on n A (λn' A', one_step_tr A')
end one_step_tr
attribute one_step_tr.rec one_step_tr.elim [recursor 5] [unfold 5]
attribute one_step_tr.rec_on one_step_tr.elim_on [unfold 2]
attribute one_step_tr.tr [constructor]
namespace one_step_tr
/- Theorems about the one-step truncation -/
open homotopy trunc prod
theorem tr_eq_ne_idp {A : Type} (a : A) : tr_eq a a ≠ idp :=
begin
intro p,
have H2 : Π{X : Type₁} {x : X} {q : x = x}, q = idp,
from λX x q, calc
q = ap (one_step_tr.elim (λa, x) (λa b, q)) (tr_eq a a) : elim_tr_eq
... = ap (one_step_tr.elim (λa, x) (λa b, q)) (refl (one_step_tr.tr a)) : by rewrite p
... = idp : idp,
exact bool.eq_bnot_ne_idp H2
end
theorem tr_eq_ne_ap_tr {A : Type} {a b : A} (p : a = b) : tr_eq a b ≠ ap tr p :=
by induction p; apply tr_eq_ne_idp
theorem not_inhabited_set_trunc_one_step_tr (A : Type)
: ¬(trunc 1 (one_step_tr A) × is_set (trunc 1 (one_step_tr A))) :=
begin
intro H, induction H with x H,
refine trunc.elim_on x _, clear x, intro x,
induction x,
{ have q : trunc -1 ((tr_eq a a) = idp),
begin
refine to_fun !tr_eq_tr_equiv _,
refine @is_prop.elim _ _ _ _, apply is_trunc_equiv_closed, apply tr_eq_tr_equiv
end,
refine trunc.elim_on q _, clear q, intro p, exact !tr_eq_ne_idp p},
{ apply is_prop.elim}
end
theorem not_is_conn_one_step_tr (A : Type) : ¬is_conn 1 (one_step_tr A) :=
λH, not_inhabited_set_trunc_one_step_tr A (!center, _)
theorem is_prop_trunc_one_step_tr (A : Type) : is_prop (trunc 0 (one_step_tr A)) :=
begin
apply is_prop.mk,
intro x y,
refine trunc.rec_on x _, refine trunc.rec_on y _, clear x y, intro y x,
induction x,
{ induction y,
{ exact ap trunc.tr !tr_eq},
{ apply is_prop.elimo}},
{ apply is_prop.elimo}
end
local attribute is_prop_trunc_one_step_tr [instance]
theorem trunc_0_one_step_tr_equiv (A : Type) : trunc 0 (one_step_tr A) ≃ ∥ A ∥ :=
begin
apply equiv_of_is_prop,
{ intro x, refine trunc.rec _ x, clear x, intro x, induction x,
{ exact trunc.tr a},
{ apply is_prop.elim}},
{ intro x, refine trunc.rec _ x, clear x, intro a, exact trunc.tr (tr a)},
end
definition one_step_tr_functor [unfold 4] {A B : Type} (f : A → B) (x : one_step_tr A)
: one_step_tr B :=
begin
induction x,
{ exact tr (f a)},
{ apply tr_eq}
end
definition one_step_tr_universal_property [constructor] (A B : Type)
: (one_step_tr A → B) ≃ Σ(f : A → B), Π(x y : A), f x = f y :=
begin
fapply equiv.MK,
{ intro f, fconstructor, intro a, exact f (tr a), intros, exact ap f !tr_eq},
{ intro v a, induction v with f p, induction a, exact f a, apply p},
{ intro v, induction v with f p, esimp, apply ap (sigma.mk _), apply eq_of_homotopy2,
intro a a', apply elim_tr_eq},
{ intro f, esimp, apply eq_of_homotopy, intro a, induction a,
reflexivity,
apply eq_pathover, apply hdeg_square, rewrite [▸*,elim_tr_eq]},
end
end one_step_tr
open one_step_tr
namespace prop_trunc
namespace hide
section
parameter {X : Type}
/- basic constructors -/
definition A [reducible] (n : ) : Type := nat.rec_on n X (λn' X', one_step_tr X')
definition f [reducible] ⦃n : ℕ⦄ (a : A n) : A (succ n) := tr a
definition f_eq [reducible] {n : } (a a' : A n) : f a = f a' := tr_eq a a'
definition truncX [reducible] : Type := @seq_colim A f
definition i [reducible] {n : } (a : A n) : truncX := inclusion f a
definition g [reducible] {n : } (a : A n) : i (f a) = i a := glue f a
/- defining the normal recursor is easy -/
definition rec {P : truncX → Type} [Pt : Πx, is_prop (P x)]
(H : Π(a : X), P (@i 0 a)) (x : truncX) : P x :=
begin
induction x,
{ induction n with n IH,
{ exact H a},
{ induction a,
{ exact !g⁻¹ ▸ IH a},
{ apply is_prop.elimo}}},
{ apply is_prop.elimo}
end
/-
The main effort is to prove that truncX is a mere proposition.
We prove
Π(a b : truncX), a = b
first by induction on a, using the induction principle we just proven and then by induction on b
On the point level we need to construct
(1) a : A n, b : A m ⊢ p a b : i a = i b
On the path level (for the induction on b) we need to show that
(2) a : A n, b : A m ⊢ p a (f b) ⬝ g b = p a b
The path level for a is automatic, since (Πb, a = b) is a mere proposition
Thanks to Egbert Rijke for pointing this out
For (1) we distinguish the cases n ≤ m and n ≥ m,
and we prove that the two constructions coincide for n = m
For (2) we distinguish the cases n ≤ m and n > m
During the proof we heavily use induction on inequalities.
(n ≤ m), or (le n m), is defined as an inductive family:
inductive le (n : ) : → Type₀ :=
| refl : le n n
| step : Π {m}, le n m → le n (succ m)
-/
/- point operations -/
definition fr [reducible] [unfold 2] (n : ) (a : X) : A n :=
begin
induction n with n x,
{ exact a},
{ exact f x},
end
/- path operations -/
definition i_fr [unfold 2] (n : ) (a : X) : i (fr n a) = @i 0 a :=
begin
induction n with n p,
{ reflexivity},
{ exact g (fr n a) ⬝ p},
end
definition eq_same {n : } (a a' : A n) : i a = i a' :=
calc
i a = i (f a) : g
... = i (f a') : ap i (f_eq a a')
... = i a' : g
definition eq_constructors {n : } (a : X) (b : A n) : @i 0 a = i b :=
calc
i a = i (fr n a) : i_fr
... = i b : eq_same
/- 2-dimensional path operations -/
theorem ap_i_ap_f {n : } {a a' : A n} (p : a = a') : !g⁻¹ ⬝ ap i (ap !f p) ⬝ !g = ap i p :=
by induction p; apply con.left_inv
theorem ap_i_eq_ap_i_same {n : } {a a' : A n} (p q : a = a') : ap i p = ap i q :=
@(is_weakly_constant_ap i) eq_same a a' p q
theorem ap_f_eq_f {n : } (a a' : A n)
: !g⁻¹ ⬝ ap i (f_eq (f a) (f a')) ⬝ !g = ap i (f_eq a a') :=
ap _ !ap_i_eq_ap_i_same ⬝ !ap_i_ap_f
theorem eq_same_f {n : } (a a' : A n)
: (g a)⁻¹ ⬝ eq_same (f a) (f a') ⬝ g a' = eq_same a a' :=
begin
esimp [eq_same],
apply (ap (λx, _ ⬝ x ⬝ _)),
apply (ap_f_eq_f a a'),
end
theorem eq_constructors_comp {n : } (a : X) (b : A n)
: eq_constructors a (f b) ⬝ g b = eq_constructors a b :=
begin
rewrite [↑eq_constructors,▸*,↓fr n a,↓i_fr n a,con_inv,+con.assoc],
apply ap (λx, _ ⬝ x),
rewrite -con.assoc, exact !eq_same_f
end
theorem is_prop_truncX : is_prop truncX :=
begin
apply is_prop_of_imp_is_contr,
intro a,
refine @rec _ _ _ a,
clear a, intro a,
fapply is_contr.mk,
exact @i 0 a,
intro b,
induction b with n b n b,
{ apply eq_constructors},
{ apply (equiv.to_inv !eq_pathover_equiv_r), apply eq_constructors_comp}
end
end
end hide
end prop_trunc
namespace prop_trunc
open hide
definition ptrunc.{u} (A : Type.{u}) : Type.{u} := @truncX A
definition ptr {A : Type} : A → ptrunc A := @i A 0
definition is_prop_trunc (A : Type) : is_prop (ptrunc A) := is_prop_truncX
protected definition ptrunc.rec {A : Type} {P : ptrunc A → Type}
[Pt : Π(x : ptrunc A), is_prop (P x)]
(H : Π(a : A), P (ptr a)) : Π(x : ptrunc A), P x := @rec A P Pt H
example {A : Type} {P : ptrunc A → Type} [Pt : Πaa, is_prop (P aa)]
(H : Πa, P (ptr a)) (a : A) : (ptrunc.rec H) (ptr a) = H a := by reflexivity
open sigma prod
-- the constructed truncation is equivalent to the "standard" propositional truncation
-- (called _root_.trunc -1 below)
open trunc
attribute is_prop_trunc [instance]
definition ptrunc_equiv_trunc (A : Type) : ptrunc A ≃ trunc -1 A :=
begin
fapply equiv.MK,
{ intro x, induction x using ptrunc.rec with a, exact tr a},
{ intro x, refine trunc.rec _ x, intro a, exact ptr a},
{ intro x, induction x with a, reflexivity},
{ intro x, induction x using ptrunc.rec with a, reflexivity}
end
-- some other recursors we get from this construction:
definition trunc.elim2 {A P : Type} (h : Π{n}, n_step_tr A n → P)
(coh : Π(n : ) (a : n_step_tr A n), h (f a) = h a) (x : ptrunc A) : P :=
begin
induction x,
{ exact h a},
{ apply coh}
end
definition trunc.rec2 {A : Type} {P : truncX → Type} (h : Π{n} (a : n_step_tr A n), P (i a))
(coh : Π(n : ) (a : n_step_tr A n), h (f a) =[g a] h a)
(x : ptrunc A) : P x :=
begin
induction x,
{ exact h a},
{ apply coh}
end
definition elim2_equiv [constructor] (A P : Type) : (ptrunc A → P) ≃
Σ(h : Π{n}, n_step_tr A n → P),
Π(n : ) (a : n_step_tr A n), @h (succ n) (one_step_tr.tr a) = h a :=
begin
fapply equiv.MK,
{ intro h, fconstructor,
{ intro n a, refine h (i a)},
{ intro n a, exact ap h (g a)}},
{ intro x a, induction x with h p, induction a,
exact h a,
apply p},
{ intro x, induction x with h p, fapply sigma_eq,
{ reflexivity},
{ esimp, apply pathover_idp_of_eq, apply eq_of_homotopy2, intro n a, xrewrite elim_glue}},
{ intro h, apply eq_of_homotopy, intro a, esimp, induction a,
esimp,
apply eq_pathover, apply hdeg_square, esimp, rewrite elim_glue}
end
open sigma.ops
definition conditionally_constant_equiv {A P : Type} (k : A → P) :
(Σ(g : ptrunc A → P), Πa, g (ptr a) = k a) ≃
Σ(h : Π{n}, n_step_tr A n → P),
(Π(n : ) (a : n_step_tr A n), h (f a) = h a) × (Πa, @h 0 a = k a) :=
calc
(Σ(g : ptrunc A → P), Πa, g (ptr a) = k a)
≃ Σ(v : Σ(h : Π{n}, n_step_tr A n → P), Π(n : ) (a : n_step_tr A n), h (f a) = h a),
Πa, (v.1) 0 a = k a
: sigma_equiv_sigma !elim2_equiv (λg, equiv.rfl)
... ≃ Σ(h : Π{n}, n_step_tr A n → P) (p : Π(n : ) (a : n_step_tr A n), h (f a) = h a),
Πa, @h 0 a = k a
: sigma_assoc_equiv
... ≃ Σ(h : Π{n}, n_step_tr A n → P),
(Π(n : ) (a : n_step_tr A n), h (f a) = h a) × (Πa, @h 0 a = k a)
: sigma_equiv_sigma_right (λa, !equiv_prod)
definition cocone_of_is_collapsible {A : Type} (f : A → A) (p : Πa a', f a = f a')
(n : ) (x : n_step_tr A n) : A :=
begin
apply f,
induction n with n h,
{ exact x},
{ apply to_inv !one_step_tr_universal_property ⟨f, p⟩, exact one_step_tr_functor h x}
end
definition has_split_support_of_is_collapsible {A : Type} (f : A → A) (p : Πa a', f a = f a')
: ptrunc A → A :=
begin
fapply to_inv !elim2_equiv,
fconstructor,
{ exact cocone_of_is_collapsible f p},
{ intro n a, apply p}
end
end prop_trunc
open prop_trunc trunc
-- Corollaries for the actual truncation.
namespace is_trunc
local attribute is_prop_trunc_one_step_tr [instance]
definition is_prop.elim_set {A : Type} {P : Type} [is_set P] (f : A → P)
(p : Πa a', f a = f a') (x : trunc -1 A) : P :=
begin
have y : trunc 0 (one_step_tr A),
by induction x; exact trunc.tr (one_step_tr.tr a),
induction y with y,
induction y,
{ exact f a},
{ exact p a a'}
end
definition is_prop.elim_set_tr {A : Type} {P : Type} {H : is_set P} (f : A → P)
(p : Πa a', f a = f a') (a : A) : is_prop.elim_set f p (tr a) = f a :=
by reflexivity
end is_trunc

View file

@ -1,378 +0,0 @@
/-
Copyright (c) 2015-16 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn, Ulrik Buchholtz, Jakob von Raumer
Declaration and properties of the pushout
-/
import .quotient types.sigma types.arrow_2
open quotient eq sum equiv is_trunc pointed
namespace pushout
section
parameters {TL BL TR : Type} (f : TL → BL) (g : TL → TR)
local abbreviation A := BL + TR
inductive pushout_rel : A → A → Type :=
| Rmk : Π(x : TL), pushout_rel (inl (f x)) (inr (g x))
open pushout_rel
local abbreviation R := pushout_rel
definition pushout : Type := quotient R -- TODO: define this in root namespace
parameters {f g}
definition inl (x : BL) : pushout :=
class_of R (inl x)
definition inr (x : TR) : pushout :=
class_of R (inr x)
definition glue (x : TL) : inl (f x) = inr (g x) :=
eq_of_rel pushout_rel (Rmk f g x)
protected definition rec {P : pushout → Type} (Pinl : Π(x : BL), P (inl x))
(Pinr : Π(x : TR), P (inr x)) (Pglue : Π(x : TL), Pinl (f x) =[glue x] Pinr (g x))
(y : pushout) : P y :=
begin
induction y,
{ cases a,
apply Pinl,
apply Pinr},
{ cases H, apply Pglue}
end
protected definition rec_on [reducible] {P : pushout → Type} (y : pushout)
(Pinl : Π(x : BL), P (inl x)) (Pinr : Π(x : TR), P (inr x))
(Pglue : Π(x : TL), Pinl (f x) =[glue x] Pinr (g x)) : P y :=
rec Pinl Pinr Pglue y
theorem rec_glue {P : pushout → Type} (Pinl : Π(x : BL), P (inl x))
(Pinr : Π(x : TR), P (inr x)) (Pglue : Π(x : TL), Pinl (f x) =[glue x] Pinr (g x))
(x : TL) : apd (rec Pinl Pinr Pglue) (glue x) = Pglue x :=
!rec_eq_of_rel
protected definition elim {P : Type} (Pinl : BL → P) (Pinr : TR → P)
(Pglue : Π(x : TL), Pinl (f x) = Pinr (g x)) (y : pushout) : P :=
rec Pinl Pinr (λx, pathover_of_eq _ (Pglue x)) y
protected definition elim_on [reducible] {P : Type} (y : pushout) (Pinl : BL → P)
(Pinr : TR → P) (Pglue : Π(x : TL), Pinl (f x) = Pinr (g x)) : P :=
elim Pinl Pinr Pglue y
theorem elim_glue {P : Type} (Pinl : BL → P) (Pinr : TR → P)
(Pglue : Π(x : TL), Pinl (f x) = Pinr (g x)) (x : TL)
: ap (elim Pinl Pinr Pglue) (glue x) = Pglue x :=
begin
apply eq_of_fn_eq_fn_inv !(pathover_constant (glue x)),
rewrite [▸*,-apd_eq_pathover_of_eq_ap,↑pushout.elim,rec_glue],
end
protected definition elim_type (Pinl : BL → Type) (Pinr : TR → Type)
(Pglue : Π(x : TL), Pinl (f x) ≃ Pinr (g x)) : pushout → Type :=
quotient.elim_type (sum.rec Pinl Pinr)
begin intro v v' r, induction r, apply Pglue end
protected definition elim_type_on [reducible] (y : pushout) (Pinl : BL → Type)
(Pinr : TR → Type) (Pglue : Π(x : TL), Pinl (f x) ≃ Pinr (g x)) : Type :=
elim_type Pinl Pinr Pglue y
theorem elim_type_glue (Pinl : BL → Type) (Pinr : TR → Type)
(Pglue : Π(x : TL), Pinl (f x) ≃ Pinr (g x)) (x : TL)
: transport (elim_type Pinl Pinr Pglue) (glue x) = Pglue x :=
!elim_type_eq_of_rel_fn
theorem elim_type_glue_inv (Pinl : BL → Type) (Pinr : TR → Type)
(Pglue : Π(x : TL), Pinl (f x) ≃ Pinr (g x)) (x : TL)
: transport (elim_type Pinl Pinr Pglue) (glue x)⁻¹ = to_inv (Pglue x) :=
!elim_type_eq_of_rel_inv
protected definition rec_prop {P : pushout → Type} [H : Πx, is_prop (P x)]
(Pinl : Π(x : BL), P (inl x)) (Pinr : Π(x : TR), P (inr x)) (y : pushout) :=
rec Pinl Pinr (λx, !is_prop.elimo) y
protected definition elim_prop {P : Type} [H : is_prop P] (Pinl : BL → P) (Pinr : TR → P)
(y : pushout) : P :=
elim Pinl Pinr (λa, !is_prop.elim) y
end
end pushout
attribute pushout.inl pushout.inr [constructor]
attribute pushout.rec pushout.elim [unfold 10] [recursor 10]
attribute pushout.elim_type [unfold 9]
attribute pushout.rec_on pushout.elim_on [unfold 7]
attribute pushout.elim_type_on [unfold 6]
open sigma
namespace pushout
variables {TL BL TR : Type} (f : TL → BL) (g : TL → TR)
/- The non-dependent universal property -/
definition pushout_arrow_equiv (C : Type)
: (pushout f g → C) ≃ (Σ(i : BL → C) (j : TR → C), Πc, i (f c) = j (g c)) :=
begin
fapply equiv.MK,
{ intro f, exact ⟨λx, f (inl x), λx, f (inr x), λx, ap f (glue x)⟩},
{ intro v x, induction v with i w, induction w with j p, induction x,
exact (i a), exact (j a), exact (p x)},
{ intro v, induction v with i w, induction w with j p, esimp,
apply ap (λp, ⟨i, j, p⟩), apply eq_of_homotopy, intro x, apply elim_glue},
{ intro f, apply eq_of_homotopy, intro x, induction x: esimp,
apply eq_pathover, apply hdeg_square, esimp, apply elim_glue},
end
/- glue squares -/
protected definition glue_square {x x' : TL} (p : x = x')
: square (glue x) (glue x') (ap inl (ap f p)) (ap inr (ap g p)) :=
by cases p; apply vrefl
end pushout
open function sigma.ops
namespace pushout
/- The flattening lemma -/
section
universe variable u
parameters {TL BL TR : Type} (f : TL → BL) (g : TL → TR)
(Pinl : BL → Type.{u}) (Pinr : TR → Type.{u})
(Pglue : Π(x : TL), Pinl (f x) ≃ Pinr (g x))
include Pglue
local abbreviation A := BL + TR
local abbreviation R : A → A → Type := pushout_rel f g
local abbreviation P [unfold 5] := pushout.elim_type Pinl Pinr Pglue
local abbreviation F : sigma (Pinl ∘ f) → sigma Pinl :=
λz, ⟨ f z.1 , z.2 ⟩
local abbreviation G : sigma (Pinl ∘ f) → sigma Pinr :=
λz, ⟨ g z.1 , Pglue z.1 z.2 ⟩
protected definition flattening : sigma P ≃ pushout F G :=
begin
apply equiv.trans !quotient.flattening.flattening_lemma,
fapply equiv.MK,
{ intro q, induction q with z z z' fr,
{ induction z with a p, induction a with x x,
{ exact inl ⟨x, p⟩ },
{ exact inr ⟨x, p⟩ } },
{ induction fr with a a' r p, induction r with x,
exact glue ⟨x, p⟩ } },
{ intro q, induction q with xp xp xp,
{ exact class_of _ ⟨sum.inl xp.1, xp.2⟩ },
{ exact class_of _ ⟨sum.inr xp.1, xp.2⟩ },
{ apply eq_of_rel, constructor } },
{ intro q, induction q with xp xp xp: induction xp with x p,
{ apply ap inl, reflexivity },
{ apply ap inr, reflexivity },
{ unfold F, unfold G, apply eq_pathover,
rewrite [ap_id,ap_compose' (quotient.elim _ _)],
krewrite elim_glue, krewrite elim_eq_of_rel, apply hrefl } },
{ intro q, induction q with z z z' fr,
{ induction z with a p, induction a with x x,
{ reflexivity },
{ reflexivity } },
{ induction fr with a a' r p, induction r with x,
esimp, apply eq_pathover,
rewrite [ap_id,ap_compose' (pushout.elim _ _ _)],
krewrite elim_eq_of_rel, krewrite elim_glue, apply hrefl } }
end
end
-- Commutativity of pushouts
section
variables {TL BL TR : Type} (f : TL → BL) (g : TL → TR)
protected definition transpose [unfold 6] : pushout f g → pushout g f :=
begin
intro x, induction x, apply inr a, apply inl a, apply !glue⁻¹
end
--TODO prove without krewrite?
protected definition transpose_involutive (x : pushout f g) :
pushout.transpose g f (pushout.transpose f g x) = x :=
begin
induction x, apply idp, apply idp,
apply eq_pathover, refine _ ⬝hp !ap_id⁻¹,
refine !(ap_compose (pushout.transpose _ _)) ⬝ph _, esimp[pushout.transpose],
krewrite [elim_glue, ap_inv, elim_glue, inv_inv], apply hrfl
end
protected definition symm : pushout f g ≃ pushout g f :=
begin
fapply equiv.MK, do 2 exact !pushout.transpose,
do 2 (intro x; apply pushout.transpose_involutive),
end
end
-- Functoriality of pushouts
section
section lemmas
variables {X : Type} {x₀ x₁ x₂ x₃ : X}
(p : x₀ = x₁) (q : x₁ = x₂) (r : x₂ = x₃)
private definition is_equiv_functor_lemma₁
: (r ⬝ ((p ⬝ q ⬝ r)⁻¹ ⬝ p)) = q⁻¹ :=
by cases p; cases r; cases q; reflexivity
private definition is_equiv_functor_lemma₂
: (p ⬝ q ⬝ r)⁻¹ ⬝ (p ⬝ q) = r⁻¹ :=
by cases p; cases r; cases q; reflexivity
end lemmas
variables {TL BL TR : Type} {f : TL → BL} {g : TL → TR}
{TL' BL' TR' : Type} {f' : TL' → BL'} {g' : TL' → TR'}
(tl : TL → TL') (bl : BL → BL') (tr : TR → TR')
(fh : bl ∘ f ~ f' ∘ tl) (gh : tr ∘ g ~ g' ∘ tl)
include fh gh
protected definition functor [reducible] : pushout f g → pushout f' g' :=
begin
intro x, induction x with a b z,
{ exact inl (bl a) },
{ exact inr (tr b) },
{ exact (ap inl (fh z)) ⬝ glue (tl z) ⬝ (ap inr (gh z)⁻¹) }
end
protected definition ap_functor_inl [unfold 18] {x x' : BL} (p : x = x')
: ap (pushout.functor tl bl tr fh gh) (ap inl p) = ap inl (ap bl p) :=
by cases p; reflexivity
protected definition ap_functor_inr [unfold 18] {x x' : TR} (p : x = x')
: ap (pushout.functor tl bl tr fh gh) (ap inr p) = ap inr (ap tr p) :=
by cases p; reflexivity
variables [ietl : is_equiv tl] [iebl : is_equiv bl] [ietr : is_equiv tr]
include ietl iebl ietr
open equiv is_equiv arrow
protected definition is_equiv_functor [instance]
: is_equiv (pushout.functor tl bl tr fh gh) :=
adjointify
(pushout.functor tl bl tr fh gh)
(pushout.functor tl⁻¹ bl⁻¹ tr⁻¹
(inv_commute_of_commute tl bl f f' fh)
(inv_commute_of_commute tl tr g g' gh))
abstract begin
intro x', induction x' with a' b' z',
{ apply ap inl, apply right_inv },
{ apply ap inr, apply right_inv },
{ apply eq_pathover,
rewrite [ap_id,ap_compose' (pushout.functor tl bl tr fh gh)],
krewrite elim_glue,
rewrite [ap_inv,ap_con,ap_inv],
krewrite [pushout.ap_functor_inr], rewrite ap_con,
krewrite [pushout.ap_functor_inl,elim_glue],
apply transpose,
apply move_top_of_right, apply move_top_of_left',
krewrite [-(ap_inv inl),-ap_con,-(ap_inv inr),-ap_con],
apply move_top_of_right, apply move_top_of_left',
krewrite [-ap_con,-(ap_inv inl),-ap_con],
rewrite ap_bot_inv_commute_of_commute,
apply eq_hconcat (ap02 inl
(is_equiv_functor_lemma₁
(right_inv bl (f' z'))
(ap f' (right_inv tl z')⁻¹)
(fh (tl⁻¹ z'))⁻¹)),
rewrite [ap_inv f',inv_inv],
rewrite ap_bot_inv_commute_of_commute,
refine hconcat_eq _ (ap02 inr
(is_equiv_functor_lemma₁
(right_inv tr (g' z'))
(ap g' (right_inv tl z')⁻¹)
(gh (tl⁻¹ z'))⁻¹))⁻¹,
rewrite [ap_inv g',inv_inv],
apply pushout.glue_square }
end end
abstract begin
intro x, induction x with a b z,
{ apply ap inl, apply left_inv },
{ apply ap inr, apply left_inv },
{ apply eq_pathover,
rewrite [ap_id,ap_compose'
(pushout.functor tl⁻¹ bl⁻¹ tr⁻¹ _ _)
(pushout.functor tl bl tr _ _)],
krewrite elim_glue,
rewrite [ap_inv,ap_con,ap_inv],
krewrite [pushout.ap_functor_inr], rewrite ap_con,
krewrite [pushout.ap_functor_inl,elim_glue],
apply transpose,
apply move_top_of_right, apply move_top_of_left',
krewrite [-(ap_inv inl),-ap_con,-(ap_inv inr),-ap_con],
apply move_top_of_right, apply move_top_of_left',
krewrite [-ap_con,-(ap_inv inl),-ap_con],
rewrite inv_commute_of_commute_top,
apply eq_hconcat (ap02 inl
(is_equiv_functor_lemma₂
(ap bl⁻¹ (fh z))⁻¹
(left_inv bl (f z))
(ap f (left_inv tl z)⁻¹))),
rewrite [ap_inv f,inv_inv],
rewrite inv_commute_of_commute_top,
refine hconcat_eq _ (ap02 inr
(is_equiv_functor_lemma₂
(ap tr⁻¹ (gh z))⁻¹
(left_inv tr (g z))
(ap g (left_inv tl z)⁻¹)))⁻¹,
rewrite [ap_inv g,inv_inv],
apply pushout.glue_square }
end end
end
/- version giving the equivalence -/
section
variables {TL BL TR : Type} (f : TL → BL) (g : TL → TR)
{TL' BL' TR' : Type} (f' : TL' → BL') (g' : TL' → TR')
(tl : TL ≃ TL') (bl : BL ≃ BL') (tr : TR ≃ TR')
(fh : bl ∘ f ~ f' ∘ tl) (gh : tr ∘ g ~ g' ∘ tl)
include fh gh
protected definition equiv : pushout f g ≃ pushout f' g' :=
equiv.mk (pushout.functor tl bl tr fh gh) _
end
definition pointed_pushout [instance] [constructor] {TL BL TR : Type} [HTL : pointed TL]
[HBL : pointed BL] [HTR : pointed TR] (f : TL → BL) (g : TL → TR) : pointed (pushout f g) :=
pointed.mk (inl (point _))
end pushout open pushout
definition ppushout [constructor] {TL BL TR : Type*} (f : TL →* BL) (g : TL →* TR) : Type* :=
pointed.mk' (pushout f g)
namespace pushout
section
parameters {TL BL TR : Type*} (f : TL →* BL) (g : TL →* TR)
parameters {f g}
definition pinl [constructor] : BL →* ppushout f g :=
pmap.mk inl idp
definition pinr [constructor] : TR →* ppushout f g :=
pmap.mk inr ((ap inr (respect_pt g))⁻¹ ⬝ !glue⁻¹ ⬝ (ap inl (respect_pt f)))
definition pglue (x : TL) : pinl (f x) = pinr (g x) := -- TODO do we need this?
!glue
end
section
variables {TL BL TR : Type*} (f : TL →* BL) (g : TL →* TR)
protected definition psymm [constructor] : ppushout f g ≃* ppushout g f :=
begin
fapply pequiv_of_equiv,
{ apply pushout.symm },
{ exact ap inr (respect_pt f)⁻¹ ⬝ !glue⁻¹ ⬝ ap inl (respect_pt g) }
end
end
end pushout

View file

@ -1,320 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn, Ulrik Buchholtz
Quotients. This is a quotient without truncation for an arbitrary type-valued binary relation.
See also .set_quotient
-/
/-
The hit quotient is primitive, declared in init.hit.
The constructors are, given {A : Type} (R : A → A → Type),
* class_of : A → quotient R (A implicit, R explicit)
* eq_of_rel : Π{a a' : A}, R a a' → class_of a = class_of a' (R explicit)
-/
import arity cubical.squareover types.arrow cubical.pathover2 types.pointed
open eq equiv sigma sigma.ops pi is_trunc pointed
namespace quotient
variables {A : Type} {R : A → A → Type}
protected definition elim {P : Type} (Pc : A → P) (Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a = Pc a')
(x : quotient R) : P :=
quotient.rec Pc (λa a' H, pathover_of_eq _ (Pp H)) x
protected definition elim_on [reducible] {P : Type} (x : quotient R)
(Pc : A → P) (Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a = Pc a') : P :=
quotient.elim Pc Pp x
theorem elim_eq_of_rel {P : Type} (Pc : A → P)
(Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a = Pc a') {a a' : A} (H : R a a')
: ap (quotient.elim Pc Pp) (eq_of_rel R H) = Pp H :=
begin
apply eq_of_fn_eq_fn_inv !(pathover_constant (eq_of_rel R H)),
rewrite [▸*,-apd_eq_pathover_of_eq_ap,↑quotient.elim,rec_eq_of_rel],
end
protected definition rec_prop {A : Type} {R : A → A → Type} {P : quotient R → Type}
[H : Πx, is_prop (P x)] (Pc : Π(a : A), P (class_of R a)) (x : quotient R) : P x :=
quotient.rec Pc (λa a' H, !is_prop.elimo) x
protected definition elim_prop {P : Type} [H : is_prop P] (Pc : A → P) (x : quotient R) : P :=
quotient.elim Pc (λa a' H, !is_prop.elim) x
protected definition elim_type (Pc : A → Type)
(Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a ≃ Pc a') : quotient R → Type :=
quotient.elim Pc (λa a' H, ua (Pp H))
protected definition elim_type_on [reducible] (x : quotient R) (Pc : A → Type)
(Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a ≃ Pc a') : Type :=
quotient.elim_type Pc Pp x
theorem elim_type_eq_of_rel_fn (Pc : A → Type)
(Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a ≃ Pc a') {a a' : A} (H : R a a')
: transport (quotient.elim_type Pc Pp) (eq_of_rel R H) = to_fun (Pp H) :=
by rewrite [tr_eq_cast_ap_fn, ↑quotient.elim_type, elim_eq_of_rel]; apply cast_ua_fn
-- rename to elim_type_eq_of_rel_fn_inv
theorem elim_type_eq_of_rel_inv (Pc : A → Type)
(Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a ≃ Pc a') {a a' : A} (H : R a a')
: transport (quotient.elim_type Pc Pp) (eq_of_rel R H)⁻¹ = to_inv (Pp H) :=
by rewrite [tr_eq_cast_ap_fn, ↑quotient.elim_type, ap_inv, elim_eq_of_rel]; apply cast_ua_inv_fn
-- remove '
theorem elim_type_eq_of_rel_inv' (Pc : A → Type)
(Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a ≃ Pc a') {a a' : A} (H : R a a') (x : Pc a')
: transport (quotient.elim_type Pc Pp) (eq_of_rel R H)⁻¹ x = to_inv (Pp H) x :=
ap10 (elim_type_eq_of_rel_inv Pc Pp H) x
theorem elim_type_eq_of_rel.{u} (Pc : A → Type.{u})
(Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a ≃ Pc a') {a a' : A} (H : R a a') (p : Pc a)
: transport (quotient.elim_type Pc Pp) (eq_of_rel R H) p = to_fun (Pp H) p :=
ap10 (elim_type_eq_of_rel_fn Pc Pp H) p
definition elim_type_eq_of_rel' (Pc : A → Type)
(Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a ≃ Pc a') {a a' : A} (H : R a a') (p : Pc a)
: pathover (quotient.elim_type Pc Pp) p (eq_of_rel R H) (to_fun (Pp H) p) :=
pathover_of_tr_eq (elim_type_eq_of_rel Pc Pp H p)
definition elim_type_uncurried (H : Σ(Pc : A → Type), Π⦃a a' : A⦄ (H : R a a'), Pc a ≃ Pc a')
: quotient R → Type :=
quotient.elim_type H.1 H.2
end quotient
attribute quotient.rec [recursor]
attribute quotient.elim [unfold 6] [recursor 6]
attribute quotient.elim_type [unfold 5]
attribute quotient.elim_on [unfold 4]
attribute quotient.elim_type_on [unfold 3]
namespace quotient
section
variables {A : Type} (R : A → A → Type)
/- The dependent universal property -/
definition quotient_pi_equiv (C : quotient R → Type) : (Πx, C x) ≃
(Σ(f : Π(a : A), C (class_of R a)), Π⦃a a' : A⦄ (H : R a a'), f a =[eq_of_rel R H] f a') :=
begin
fapply equiv.MK,
{ intro f, exact ⟨λa, f (class_of R a), λa a' H, apd f (eq_of_rel R H)⟩},
{ intro v x, induction v with i p, induction x,
exact (i a),
exact (p H)},
{ intro v, induction v with i p, esimp,
apply ap (sigma.mk i), apply eq_of_homotopy3, intro a a' H, apply rec_eq_of_rel},
{ intro f, apply eq_of_homotopy, intro x, induction x: esimp,
apply eq_pathover_dep, esimp, rewrite rec_eq_of_rel, exact hrflo},
end
end
definition pquotient [constructor] {A : Type*} (R : A → A → Type) : Type* :=
pType.mk (quotient R) (class_of R pt)
/- the flattening lemma -/
namespace flattening
section
parameters {A : Type} (R : A → A → Type) (C : A → Type) (f : Π⦃a a'⦄, R a a' → C a ≃ C a')
include f
variables {a a' : A} {r : R a a'}
local abbreviation P [unfold 5] := quotient.elim_type C f
definition flattening_type : Type := Σa, C a
local abbreviation X := flattening_type
inductive flattening_rel : X → X → Type :=
| mk : Π⦃a a' : A⦄ (r : R a a') (c : C a), flattening_rel ⟨a, c⟩ ⟨a', f r c⟩
definition Ppt [constructor] (c : C a) : sigma P :=
⟨class_of R a, c⟩
definition Peq (r : R a a') (c : C a) : Ppt c = Ppt (f r c) :=
begin
fapply sigma_eq: esimp,
{ apply eq_of_rel R r},
{ refine elim_type_eq_of_rel' C f r c}
end
definition rec {Q : sigma P → Type} (Qpt : Π{a : A} (x : C a), Q (Ppt x))
(Qeq : Π⦃a a' : A⦄ (r : R a a') (c : C a), Qpt c =[Peq r c] Qpt (f r c))
(v : sigma P) : Q v :=
begin
induction v with q p,
induction q,
{ exact Qpt p},
{ apply pi_pathover_left', esimp, intro c,
refine _ ⬝op apdt Qpt (elim_type_eq_of_rel C f H c)⁻¹ᵖ,
refine _ ⬝op (tr_compose Q Ppt _ _)⁻¹ ,
rewrite ap_inv,
refine pathover_cancel_right _ !tr_pathover⁻¹ᵒ,
refine change_path _ (Qeq H c),
symmetry, rewrite [↑[Ppt, Peq]],
refine whisker_left _ !ap_dpair ⬝ _,
refine !dpair_eq_dpair_con⁻¹ ⬝ _, esimp,
apply ap (dpair_eq_dpair _),
esimp [elim_type_eq_of_rel',pathover_idp_of_eq],
exact !pathover_of_tr_eq_eq_concato⁻¹},
end
definition elim {Q : Type} (Qpt : Π{a : A}, C a → Q)
(Qeq : Π⦃a a' : A⦄ (r : R a a') (c : C a), Qpt c = Qpt (f r c))
(v : sigma P) : Q :=
begin
induction v with q p,
induction q,
{ exact Qpt p},
{ apply arrow_pathover_constant_right, esimp,
intro c, exact Qeq H c ⬝ ap Qpt (elim_type_eq_of_rel C f H c)⁻¹},
end
theorem elim_Peq {Q : Type} (Qpt : Π{a : A}, C a → Q)
(Qeq : Π⦃a a' : A⦄ (r : R a a') (c : C a), Qpt c = Qpt (f r c)) {a a' : A} (r : R a a')
(c : C a) : ap (elim @Qpt Qeq) (Peq r c) = Qeq r c :=
begin
refine !ap_dpair_eq_dpair ⬝ _,
refine !apd011_eq_apo11_apd ⬝ _,
rewrite [rec_eq_of_rel, ▸*],
refine !apo11_arrow_pathover_constant_right ⬝ _,
rewrite [↑elim_type_eq_of_rel', to_right_inv !pathover_equiv_tr_eq, ap_inv],
apply inv_con_cancel_right
end
open flattening_rel
definition flattening_lemma : sigma P ≃ quotient flattening_rel :=
begin
fapply equiv.MK,
{ refine elim _ _,
{ intro a c, exact class_of _ ⟨a, c⟩},
{ intro a a' r c, apply eq_of_rel, constructor}},
{ intro q, induction q with x x x' H,
{ exact Ppt x.2},
{ induction H, esimp, apply Peq}},
{ intro q, induction q with x x x' H: esimp,
{ induction x with a c, reflexivity},
{ induction H, esimp, apply eq_pathover, apply hdeg_square,
refine ap_compose (elim _ _) (quotient.elim _ _) _ ⬝ _,
rewrite [elim_eq_of_rel, ap_id, ▸*],
apply elim_Peq}},
{ refine rec (λa x, idp) _, intros,
apply eq_pathover, apply hdeg_square,
refine ap_compose (quotient.elim _ _) (elim _ _) _ ⬝ _,
rewrite [elim_Peq, ap_id, ▸*],
apply elim_eq_of_rel}
end
end
end flattening
section
open is_equiv equiv prod prod.ops
variables {A : Type} (R : A → A → Type)
{B : Type} (Q : B → B → Type)
(f : A → B) (k : Πa a' : A, R a a' → Q (f a) (f a'))
include f k
protected definition functor [reducible] : quotient R → quotient Q :=
quotient.elim (λa, class_of Q (f a)) (λa a' r, eq_of_rel Q (k a a' r))
variables [F : is_equiv f] [K : Πa a', is_equiv (k a a')]
include F K
protected definition functor_inv [reducible] : quotient Q → quotient R :=
quotient.elim (λb, class_of R (f⁻¹ b))
(λb b' q, eq_of_rel R ((k (f⁻¹ b) (f⁻¹ b'))⁻¹
((right_inv f b)⁻¹ ▸ (right_inv f b')⁻¹ ▸ q)))
protected definition is_equiv [instance]
: is_equiv (quotient.functor R Q f k):=
begin
fapply adjointify _ (quotient.functor_inv R Q f k),
{ intro qb, induction qb with b b b' q,
{ apply ap (class_of Q), apply right_inv },
{ apply eq_pathover, rewrite [ap_id,ap_compose' (quotient.elim _ _)],
do 2 krewrite elim_eq_of_rel, rewrite (right_inv (k (f⁻¹ b) (f⁻¹ b'))),
have H1 : pathover (λz : B × B, Q z.1 z.2)
((right_inv f b)⁻¹ ▸ (right_inv f b')⁻¹ ▸ q)
(prod_eq (right_inv f b) (right_inv f b')) q,
begin apply pathover_of_eq_tr, krewrite [prod_eq_inv,prod_eq_transport] end,
have H2 : square
(ap (λx : (Σz : B × B, Q z.1 z.2), class_of Q x.1.1)
(sigma_eq (prod_eq (right_inv f b) (right_inv f b')) H1))
(ap (λx : (Σz : B × B, Q z.1 z.2), class_of Q x.1.2)
(sigma_eq (prod_eq (right_inv f b) (right_inv f b')) H1))
(eq_of_rel Q ((right_inv f b)⁻¹ ▸ (right_inv f b')⁻¹ ▸ q))
(eq_of_rel Q q),
from
natural_square_tr (λw : (Σz : B × B, Q z.1 z.2), eq_of_rel Q w.2)
(sigma_eq (prod_eq (right_inv f b) (right_inv f b')) H1),
krewrite (ap_compose' (class_of Q)) at H2,
krewrite (ap_compose' (λz : B × B, z.1)) at H2,
rewrite sigma.ap_pr1 at H2, rewrite sigma_eq_pr1 at H2,
krewrite prod.ap_pr1 at H2, krewrite prod_eq_pr1 at H2,
krewrite (ap_compose' (class_of Q) (λx : (Σz : B × B, Q z.1 z.2), x.1.2)) at H2,
krewrite (ap_compose' (λz : B × B, z.2)) at H2,
rewrite sigma.ap_pr1 at H2, rewrite sigma_eq_pr1 at H2,
krewrite prod.ap_pr2 at H2, krewrite prod_eq_pr2 at H2,
apply H2 } },
{ intro qa, induction qa with a a a' r,
{ apply ap (class_of R), apply left_inv },
{ apply eq_pathover, rewrite [ap_id,(ap_compose' (quotient.elim _ _))],
do 2 krewrite elim_eq_of_rel,
have H1 : pathover (λz : A × A, R z.1 z.2)
((left_inv f a)⁻¹ ▸ (left_inv f a')⁻¹ ▸ r)
(prod_eq (left_inv f a) (left_inv f a')) r,
begin apply pathover_of_eq_tr, krewrite [prod_eq_inv,prod_eq_transport] end,
have H2 : square
(ap (λx : (Σz : A × A, R z.1 z.2), class_of R x.1.1)
(sigma_eq (prod_eq (left_inv f a) (left_inv f a')) H1))
(ap (λx : (Σz : A × A, R z.1 z.2), class_of R x.1.2)
(sigma_eq (prod_eq (left_inv f a) (left_inv f a')) H1))
(eq_of_rel R ((left_inv f a)⁻¹ ▸ (left_inv f a')⁻¹ ▸ r))
(eq_of_rel R r),
begin
exact
natural_square_tr (λw : (Σz : A × A, R z.1 z.2), eq_of_rel R w.2)
(sigma_eq (prod_eq (left_inv f a) (left_inv f a')) H1)
end,
krewrite (ap_compose' (class_of R)) at H2,
krewrite (ap_compose' (λz : A × A, z.1)) at H2,
rewrite sigma.ap_pr1 at H2, rewrite sigma_eq_pr1 at H2,
krewrite prod.ap_pr1 at H2, krewrite prod_eq_pr1 at H2,
krewrite (ap_compose' (class_of R) (λx : (Σz : A × A, R z.1 z.2), x.1.2)) at H2,
krewrite (ap_compose' (λz : A × A, z.2)) at H2,
rewrite sigma.ap_pr1 at H2, rewrite sigma_eq_pr1 at H2,
krewrite prod.ap_pr2 at H2, krewrite prod_eq_pr2 at H2,
have H3 :
(k (f⁻¹ (f a)) (f⁻¹ (f a')))⁻¹
((right_inv f (f a))⁻¹ ▸ (right_inv f (f a'))⁻¹ ▸ k a a' r)
= (left_inv f a)⁻¹ ▸ (left_inv f a')⁻¹ ▸ r,
begin
rewrite [adj f a,adj f a',ap_inv',ap_inv'],
rewrite [-(tr_compose _ f (left_inv f a')⁻¹ (k a a' r)),
-(tr_compose _ f (left_inv f a)⁻¹)],
rewrite [-(fn_tr_eq_tr_fn (left_inv f a')⁻¹ (λx, k a x) r),
-(fn_tr_eq_tr_fn (left_inv f a)⁻¹
(λx, k x (f⁻¹ (f a')))),
left_inv (k _ _)]
end,
rewrite H3, apply H2 } }
end
end
section
variables {A : Type} (R : A → A → Type)
{B : Type} (Q : B → B → Type)
(f : A ≃ B) (k : Πa a' : A, R a a' ≃ Q (f a) (f a'))
include f k
/- This could also be proved using ua, but then it wouldn't compute -/
protected definition equiv : quotient R ≃ quotient Q :=
equiv.mk (quotient.functor R Q f k) _
end
end quotient

View file

@ -1,84 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
Quotient of a reflexive relation
-/
import homotopy.circle cubical.squareover .two_quotient
open eq simple_two_quotient e_closure
namespace refl_quotient
section
parameters {A : Type} (R : A → A → Type) (ρ : Πa, R a a)
inductive refl_quotient_Q : Π⦃a : A⦄, e_closure R a a → Type :=
| Qmk {} : Π(a : A), refl_quotient_Q [ρ a]
open refl_quotient_Q
local abbreviation Q := refl_quotient_Q
definition refl_quotient : Type := simple_two_quotient R Q
definition rclass_of (a : A) : refl_quotient := incl0 R Q a
definition req_of_rel ⦃a a' : A⦄ (r : R a a') : rclass_of a = rclass_of a' :=
incl1 R Q r
definition pρ (a : A) : req_of_rel (ρ a) = idp :=
incl2 R Q (Qmk a)
protected definition rec {P : refl_quotient → Type} (Pc : Π(a : A), P (rclass_of a))
(Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a =[req_of_rel H] Pc a')
(Pr : Π(a : A), change_path (pρ a) (Pp (ρ a)) = idpo) (x : refl_quotient) : P x :=
begin
induction x,
exact Pc a,
exact Pp s,
induction q, apply Pr
end
protected definition rec_on [reducible] {P : refl_quotient → Type} (x : refl_quotient)
(Pc : Π(a : A), P (rclass_of a)) (Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a =[req_of_rel H] Pc a')
(Pr : Π(a : A), change_path (pρ a) (Pp (ρ a)) = idpo) : P x :=
rec Pc Pp Pr x
definition rec_req_of_rel {P : Type} {P : refl_quotient → Type} (Pc : Π(a : A), P (rclass_of a))
(Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a =[req_of_rel H] Pc a')
(Pr : Π(a : A), change_path (pρ a) (Pp (ρ a)) = idpo) ⦃a a' : A⦄ (r : R a a')
: apd (rec Pc Pp Pr) (req_of_rel r) = Pp r :=
!rec_incl1
protected definition elim {P : Type} (Pc : Π(a : A), P)
(Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a = Pc a') (Pr : Π(a : A), Pp (ρ a) = idp)
(x : refl_quotient) : P :=
begin
induction x,
exact Pc a,
exact Pp s,
induction q, apply Pr
end
protected definition elim_on [reducible] {P : Type} (x : refl_quotient) (Pc : Π(a : A), P)
(Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a = Pc a') (Pr : Π(a : A), Pp (ρ a) = idp) : P :=
elim Pc Pp Pr x
definition elim_req_of_rel {P : Type} {Pc : Π(a : A), P}
{Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a = Pc a'} (Pr : Π(a : A), Pp (ρ a) = idp)
⦃a a' : A⦄ (r : R a a') : ap (elim Pc Pp Pr) (req_of_rel r) = Pp r :=
!elim_incl1
theorem elim_pρ {P : Type} (Pc : Π(a : A), P)
(Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a = Pc a') (Pr : Π(a : A), Pp (ρ a) = idp) (a : A)
: square (ap02 (elim Pc Pp Pr) (pρ a)) (Pr a) (elim_req_of_rel Pr (ρ a)) idp :=
!elim_incl2
end
end refl_quotient
attribute refl_quotient.rclass_of [constructor]
attribute refl_quotient.rec refl_quotient.elim [unfold 8] [recursor 8]
--attribute refl_quotient.elim_type [unfold 9]
attribute refl_quotient.rec_on refl_quotient.elim_on [unfold 5]
--attribute refl_quotient.elim_type_on [unfold 6]

View file

@ -1,145 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
Declaration of set-quotients, i.e. quotient of a mere relation which is then set-truncated.
-/
import function algebra.relation types.trunc types.eq hit.quotient
open eq is_trunc trunc quotient equiv
namespace set_quotient
section
parameters {A : Type} (R : A → A → Prop)
-- set-quotients are just set-truncations of (type) quotients
definition set_quotient : Type := trunc 0 (quotient R)
parameter {R}
definition class_of (a : A) : set_quotient :=
tr (class_of _ a)
definition eq_of_rel {a a' : A} (H : R a a') : class_of a = class_of a' :=
ap tr (eq_of_rel _ H)
theorem is_set_set_quotient [instance] : is_set set_quotient :=
begin unfold set_quotient, exact _ end
protected definition rec {P : set_quotient → Type} [Pt : Πaa, is_set (P aa)]
(Pc : Π(a : A), P (class_of a)) (Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a =[eq_of_rel H] Pc a')
(x : set_quotient) : P x :=
begin
apply (@trunc.rec_on _ _ P x),
{ intro x', apply Pt},
{ intro y, induction y,
{ apply Pc},
{ exact pathover_of_pathover_ap P tr (Pp H)}}
end
protected definition rec_on [reducible] {P : set_quotient → Type} (x : set_quotient)
[Pt : Πaa, is_set (P aa)] (Pc : Π(a : A), P (class_of a))
(Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a =[eq_of_rel H] Pc a') : P x :=
rec Pc Pp x
theorem rec_eq_of_rel {P : set_quotient → Type} [Pt : Πaa, is_set (P aa)]
(Pc : Π(a : A), P (class_of a)) (Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a =[eq_of_rel H] Pc a')
{a a' : A} (H : R a a') : apd (rec Pc Pp) (eq_of_rel H) = Pp H :=
!is_set.elimo
protected definition elim {P : Type} [Pt : is_set P] (Pc : A → P)
(Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a = Pc a') (x : set_quotient) : P :=
rec Pc (λa a' H, pathover_of_eq _ (Pp H)) x
protected definition elim_on [reducible] {P : Type} (x : set_quotient) [Pt : is_set P]
(Pc : A → P) (Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a = Pc a') : P :=
elim Pc Pp x
theorem elim_eq_of_rel {P : Type} [Pt : is_set P] (Pc : A → P)
(Pp : Π⦃a a' : A⦄ (H : R a a'), Pc a = Pc a') {a a' : A} (H : R a a')
: ap (elim Pc Pp) (eq_of_rel H) = Pp H :=
begin
apply eq_of_fn_eq_fn_inv !(pathover_constant (eq_of_rel H)),
rewrite [▸*,-apd_eq_pathover_of_eq_ap,↑elim,rec_eq_of_rel],
end
protected definition rec_prop {P : set_quotient → Type} [Pt : Πaa, is_prop (P aa)]
(Pc : Π(a : A), P (class_of a)) (x : set_quotient) : P x :=
rec Pc (λa a' H, !is_prop.elimo) x
protected definition elim_prop {P : Type} [Pt : is_prop P] (Pc : A → P) (x : set_quotient)
: P :=
elim Pc (λa a' H, !is_prop.elim) x
end
end set_quotient
attribute set_quotient.class_of [constructor]
attribute set_quotient.rec set_quotient.elim [unfold 7] [recursor 7]
attribute set_quotient.rec_on set_quotient.elim_on [unfold 4]
open sigma relation function
namespace set_quotient
variables {A B C : Type} (R : A → A → Prop) (S : B → B → Prop) (T : C → C → Prop)
definition is_surjective_class_of : is_surjective (class_of : A → set_quotient R) :=
λx, set_quotient.rec_on x (λa, tr (fiber.mk a idp)) (λa a' r, !is_prop.elimo)
/- non-dependent universal property -/
definition set_quotient_arrow_equiv (B : Type) [H : is_set B] :
(set_quotient R → B) ≃ (Σ(f : A → B), Π(a a' : A), R a a' → f a = f a') :=
begin
fapply equiv.MK,
{ intro f, exact ⟨λa, f (class_of a), λa a' r, ap f (eq_of_rel r)⟩},
{ intro v x, induction v with f p, exact set_quotient.elim_on x f p},
{ intro v, induction v with f p, esimp, apply ap (sigma.mk f),
apply eq_of_homotopy3, intro a a' r, apply elim_eq_of_rel},
{ intro f, apply eq_of_homotopy, intro x, refine set_quotient.rec_on x _ _: esimp,
intro a, reflexivity,
intro a a' r, apply eq_pathover, apply hdeg_square, apply elim_eq_of_rel}
end
protected definition code [unfold 4] (a : A) (x : set_quotient R) [H : is_equivalence R]
: Prop :=
set_quotient.elim_on x (R a)
begin
intros a' a'' H1,
refine to_inv !trunctype_eq_equiv _, esimp,
apply ua,
apply equiv_of_is_prop,
{ intro H2, exact is_transitive.trans R H2 H1},
{ intro H2, apply is_transitive.trans R H2, exact is_symmetric.symm R H1}
end
protected definition encode {a : A} {x : set_quotient R} (p : class_of a = x)
[H : is_equivalence R] : set_quotient.code R a x :=
begin
induction p, esimp, apply is_reflexive.refl R
end
definition rel_of_eq {a a' : A} (p : class_of a = class_of a' :> set_quotient R)
[H : is_equivalence R] : R a a' :=
set_quotient.encode R p
variables {R S T}
definition quotient_unary_map [unfold 7] (f : A → B) (H : Π{a a'} (r : R a a'), S (f a) (f a')) :
set_quotient R → set_quotient S :=
set_quotient.elim (class_of ∘ f) (λa a' r, eq_of_rel (H r))
definition quotient_binary_map [unfold 11 12] (f : A → B → C)
(H : Π{a a'} (r : R a a') {b b'} (s : S b b'), T (f a b) (f a' b'))
[HR : is_reflexive R] [HS : is_reflexive S] :
set_quotient R → set_quotient S → set_quotient T :=
begin
refine set_quotient.elim _ _,
{ intro a, refine set_quotient.elim _ _,
{ intro b, exact class_of (f a b)},
{ intro b b' s, apply eq_of_rel, apply H, apply is_reflexive.refl R, exact s}},
{ intro a a' r, apply eq_of_homotopy, refine set_quotient.rec _ _,
{ intro b, esimp, apply eq_of_rel, apply H, exact r, apply is_reflexive.refl S},
{ intro b b' s, apply eq_pathover, esimp, apply is_set.elims}}
end
end set_quotient

View file

@ -1,158 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
n-truncation of types.
Ported from Coq HoTT
-/
/- The hit n-truncation is primitive, declared in init.hit. -/
import types.sigma types.pointed
open is_trunc eq equiv is_equiv function prod sum sigma
namespace trunc
protected definition elim {n : trunc_index} {A : Type} {P : Type}
[Pt : is_trunc n P] (H : A → P) : trunc n A → P :=
trunc.rec H
protected definition elim_on {n : trunc_index} {A : Type} {P : Type} (aa : trunc n A)
[Pt : is_trunc n P] (H : A → P) : P :=
trunc.elim H aa
end trunc
attribute trunc.elim_on [unfold 4]
attribute trunc.rec [recursor 6]
attribute trunc.elim [recursor 6] [unfold 6]
namespace trunc
variables {X Y Z : Type} {P : X → Type} (n : trunc_index) (A B : Type)
local attribute is_trunc_eq [instance]
variables {A n}
definition untrunc_of_is_trunc [reducible] [unfold 4] [H : is_trunc n A] : trunc n A → A :=
trunc.rec id
variables (A n)
definition is_equiv_tr [instance] [constructor] [H : is_trunc n A] : is_equiv (@tr n A) :=
adjointify _
(untrunc_of_is_trunc)
(λaa, trunc.rec_on aa (λa, idp))
(λa, idp)
definition trunc_equiv [constructor] [H : is_trunc n A] : trunc n A ≃ A :=
(equiv.mk tr _)⁻¹ᵉ
definition is_trunc_of_is_equiv_tr [H : is_equiv (@tr n A)] : is_trunc n A :=
is_trunc_is_equiv_closed n (@tr n _)⁻¹
/- Functoriality -/
definition trunc_functor [unfold 5] (f : X → Y) : trunc n X → trunc n Y :=
λxx, trunc.rec_on xx (λx, tr (f x))
definition trunc_functor_compose [unfold 7] (f : X → Y) (g : Y → Z)
: trunc_functor n (g ∘ f) ~ trunc_functor n g ∘ trunc_functor n f :=
λxx, trunc.rec_on xx (λx, idp)
definition trunc_functor_id : trunc_functor n (@id A) ~ id :=
λxx, trunc.rec_on xx (λx, idp)
definition trunc_functor_cast {X Y : Type} (n : ℕ₋₂) (p : X = Y) :
trunc_functor n (cast p) ~ cast (ap (trunc n) p) :=
begin
intro x, induction x with x, esimp,
exact fn_tr_eq_tr_fn p (λy, tr) x ⬝ !tr_compose
end
definition is_equiv_trunc_functor [constructor] (f : X → Y) [H : is_equiv f]
: is_equiv (trunc_functor n f) :=
adjointify _
(trunc_functor n f⁻¹)
(λyy, trunc.rec_on yy (λy, ap tr !right_inv))
(λxx, trunc.rec_on xx (λx, ap tr !left_inv))
definition trunc_homotopy {f g : X → Y} (p : f ~ g) : trunc_functor n f ~ trunc_functor n g :=
λxx, trunc.rec_on xx (λx, ap tr (p x))
section
definition trunc_equiv_trunc [constructor] (f : X ≃ Y) : trunc n X ≃ trunc n Y :=
equiv.mk _ (is_equiv_trunc_functor n f)
end
section
open prod.ops
definition trunc_prod_equiv [constructor] : trunc n (X × Y) ≃ trunc n X × trunc n Y :=
begin
fapply equiv.MK,
{exact (λpp, trunc.rec_on pp (λp, (tr p.1, tr p.2)))},
{intro p, cases p with xx yy,
apply (trunc.rec_on xx), intro x,
apply (trunc.rec_on yy), intro y, exact (tr (x,y))},
{intro p, cases p with xx yy,
apply (trunc.rec_on xx), intro x,
apply (trunc.rec_on yy), intro y, apply idp},
{intro pp, apply (trunc.rec_on pp), intro p, cases p, apply idp}
end
end
/- Propositional truncation -/
definition ttrunc [constructor] (n : ℕ₋₂) (X : Type) : n-Type :=
trunctype.mk (trunc n X) _
-- should this live in Prop?
definition merely [reducible] [constructor] (A : Type) : Prop := ttrunc -1 A
notation `||`:max A `||`:0 := merely A
notation `∥`:max A `∥`:0 := merely A
definition Exists [reducible] [constructor] (P : X → Type) : Prop := ∥ sigma P ∥
definition or [reducible] [constructor] (A B : Type) : Prop := ∥ A ⊎ B ∥
notation `exists` binders `,` r:(scoped P, Exists P) := r
notation `∃` binders `,` r:(scoped P, Exists P) := r
notation A ` \/ ` B := or A B
notation A B := or A B
definition merely.intro [reducible] [constructor] (a : A) : ∥ A ∥ := tr a
definition exists.intro [reducible] [constructor] (x : X) (p : P x) : ∃x, P x := tr ⟨x, p⟩
definition or.intro_left [reducible] [constructor] (x : X) : X Y := tr (inl x)
definition or.intro_right [reducible] [constructor] (y : Y) : X Y := tr (inr y)
definition is_contr_of_merely_prop [H : is_prop A] (aa : merely A) : is_contr A :=
is_contr_of_inhabited_prop (trunc.rec_on aa id)
section
open sigma.ops
definition trunc_sigma_equiv [constructor] : trunc n (Σ x, P x) ≃ trunc n (Σ x, trunc n (P x)) :=
equiv.MK (λpp, trunc.rec_on pp (λp, tr ⟨p.1, tr p.2⟩))
(λpp, trunc.rec_on pp (λp, trunc.rec_on p.2 (λb, tr ⟨p.1, b⟩)))
(λpp, trunc.rec_on pp (λp, sigma.rec_on p (λa bb, trunc.rec_on bb (λb, by esimp))))
(λpp, trunc.rec_on pp (λp, sigma.rec_on p (λa b, by esimp)))
definition trunc_sigma_equiv_of_is_trunc [H : is_trunc n X]
: trunc n (Σ x, P x) ≃ Σ x, trunc n (P x) :=
calc
trunc n (Σ x, P x) ≃ trunc n (Σ x, trunc n (P x)) : trunc_sigma_equiv
... ≃ Σ x, trunc n (P x) : !trunc_equiv
end
/- the (non-dependent) universal property -/
definition trunc_arrow_equiv [constructor] [H : is_trunc n B] :
(trunc n A → B) ≃ (A → B) :=
begin
fapply equiv.MK,
{ intro g a, exact g (tr a)},
{ intro f x, exact trunc.rec_on x f},
{ intro f, apply eq_of_homotopy, intro a, reflexivity},
{ intro g, apply eq_of_homotopy, intro x, exact trunc.rec_on x (λa, idp)},
end
end trunc

View file

@ -1,658 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
-/
import homotopy.circle eq2 algebra.e_closure cubical.squareover cubical.cube cubical.square2
open quotient eq circle sum sigma equiv function relation e_closure
/-
This files defines a general class of nonrecursive 2-HITs using just quotients.
We can define any HIT X which has
- a single 0-constructor
f : A → X (for some type A)
- a single 1-constructor
e : Π{a a' : A}, R a a' → a = a' (for some (type-valued) relation R on A)
and furthermore has 2-constructors which are all of the form
p = p'
where p, p' are of the form
- refl (f a), for some a : A;
- e r, for some r : R a a';
- ap f q, where q : a = a' :> A;
- inverses of such paths;
- concatenations of such paths.
so an example 2-constructor could be (as long as it typechecks):
ap f q' ⬝ ((e r)⁻¹ ⬝ ap f q)⁻¹ ⬝ e r' = idp
We first define "simple two quotients" which have as requirement that the right hand side is idp
Then we define "two quotients" which can have an arbitrary path on the right hand side
Then we define "truncated two quotients", which is a two quotient followed by n-truncation,
and show that this satisfies the desired induction principle and computation rule.
Caveat: for none of these constructions we show that the induction priniciple computes on
2-paths. However, with truncated two quotients, if the truncation is a 1-truncation, then this
computation rule follows automatically, since the target is a 1-type.
-/
namespace simple_two_quotient
section
parameters {A : Type}
(R : A → A → Type)
local abbreviation T := e_closure R -- the (type-valued) equivalence closure of R
parameter (Q : Π⦃a⦄, T a a → Type)
variables ⦃a a' : A⦄ {s : R a a'} {r : T a a}
local abbreviation B := A ⊎ Σ(a : A) (r : T a a), Q r
inductive pre_two_quotient_rel : B → B → Type :=
| pre_Rmk {} : Π⦃a a'⦄ (r : R a a'), pre_two_quotient_rel (inl a) (inl a')
--BUG: if {} not provided, the alias for pre_Rmk is wrong
definition pre_two_quotient := quotient pre_two_quotient_rel
open pre_two_quotient_rel
local abbreviation C := quotient pre_two_quotient_rel
protected definition j [constructor] (a : A) : C := class_of pre_two_quotient_rel (inl a)
protected definition pre_aux [constructor] (q : Q r) : C :=
class_of pre_two_quotient_rel (inr ⟨a, r, q⟩)
protected definition e (s : R a a') : j a = j a' := eq_of_rel _ (pre_Rmk s)
protected definition et (t : T a a') : j a = j a' := e_closure.elim e t
protected definition f [unfold 7] (q : Q r) : S¹ → C :=
circle.elim (j a) (et r)
protected definition pre_rec [unfold 8] {P : C → Type}
(Pj : Πa, P (j a)) (Pa : Π⦃a : A⦄ ⦃r : T a a⦄ (q : Q r), P (pre_aux q))
(Pe : Π⦃a a' : A⦄ (s : R a a'), Pj a =[e s] Pj a') (x : C) : P x :=
begin
induction x with p,
{ induction p,
{ apply Pj},
{ induction a with a1 a2, induction a2, apply Pa}},
{ induction H, esimp, apply Pe},
end
protected definition pre_elim [unfold 8] {P : Type} (Pj : A → P)
(Pa : Π⦃a : A⦄ ⦃r : T a a⦄, Q r → P) (Pe : Π⦃a a' : A⦄ (s : R a a'), Pj a = Pj a') (x : C)
: P :=
pre_rec Pj Pa (λa a' s, pathover_of_eq _ (Pe s)) x
protected theorem rec_e {P : C → Type}
(Pj : Πa, P (j a)) (Pa : Π⦃a : A⦄ ⦃r : T a a⦄ (q : Q r), P (pre_aux q))
(Pe : Π⦃a a' : A⦄ (s : R a a'), Pj a =[e s] Pj a') ⦃a a' : A⦄ (s : R a a')
: apd (pre_rec Pj Pa Pe) (e s) = Pe s :=
!rec_eq_of_rel
protected theorem elim_e {P : Type} (Pj : A → P) (Pa : Π⦃a : A⦄ ⦃r : T a a⦄, Q r → P)
(Pe : Π⦃a a' : A⦄ (s : R a a'), Pj a = Pj a') ⦃a a' : A⦄ (s : R a a')
: ap (pre_elim Pj Pa Pe) (e s) = Pe s :=
begin
apply eq_of_fn_eq_fn_inv !(pathover_constant (e s)),
rewrite [▸*,-apd_eq_pathover_of_eq_ap,↑pre_elim,rec_e],
end
protected definition elim_et {P : Type} (Pj : A → P) (Pa : Π⦃a : A⦄ ⦃r : T a a⦄, Q r → P)
(Pe : Π⦃a a' : A⦄ (s : R a a'), Pj a = Pj a') ⦃a a' : A⦄ (t : T a a')
: ap (pre_elim Pj Pa Pe) (et t) = e_closure.elim Pe t :=
ap_e_closure_elim_h e (elim_e Pj Pa Pe) t
protected definition rec_et {P : C → Type}
(Pj : Πa, P (j a)) (Pa : Π⦃a : A⦄ ⦃r : T a a⦄ (q : Q r), P (pre_aux q))
(Pe : Π⦃a a' : A⦄ (s : R a a'), Pj a =[e s] Pj a') ⦃a a' : A⦄ (t : T a a')
: apd (pre_rec Pj Pa Pe) (et t) = e_closure.elimo e Pe t :=
ap_e_closure_elimo_h e Pe (rec_e Pj Pa Pe) t
inductive simple_two_quotient_rel : C → C → Type :=
| Rmk {} : Π{a : A} {r : T a a} (q : Q r) (x : circle),
simple_two_quotient_rel (f q x) (pre_aux q)
open simple_two_quotient_rel
definition simple_two_quotient := quotient simple_two_quotient_rel
local abbreviation D := simple_two_quotient
local abbreviation i := class_of simple_two_quotient_rel
definition incl0 (a : A) : D := i (j a)
protected definition aux (q : Q r) : D := i (pre_aux q)
definition incl1 (s : R a a') : incl0 a = incl0 a' := ap i (e s)
definition inclt (t : T a a') : incl0 a = incl0 a' := e_closure.elim incl1 t
-- "wrong" version inclt, which is ap i (p ⬝ q) instead of ap i p ⬝ ap i q
-- it is used in the proof, because incltw is easier to work with
protected definition incltw (t : T a a') : incl0 a = incl0 a' := ap i (et t)
protected definition inclt_eq_incltw (t : T a a') : inclt t = incltw t :=
(ap_e_closure_elim i e t)⁻¹
definition incl2' (q : Q r) (x : S¹) : i (f q x) = aux q :=
eq_of_rel simple_two_quotient_rel (Rmk q x)
protected definition incl2w (q : Q r) : incltw r = idp :=
(ap02 i (elim_loop (j a) (et r))⁻¹) ⬝
(ap_compose i (f q) loop)⁻¹ ⬝
ap_is_constant (incl2' q) loop ⬝
!con.right_inv
definition incl2 (q : Q r) : inclt r = idp :=
inclt_eq_incltw r ⬝ incl2w q
local attribute simple_two_quotient f i D incl0 aux incl1 incl2' inclt [reducible]
local attribute i aux incl0 [constructor]
parameters {R Q}
protected definition rec {P : D → Type} (P0 : Π(a : A), P (incl0 a))
(P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a =[incl1 s] P0 a')
(P2 : Π⦃a : A⦄ ⦃r : T a a⦄ (q : Q r),
change_path (incl2 q) (e_closure.elimo incl1 P1 r) = idpo) (x : D) : P x :=
begin
induction x,
{ refine (pre_rec _ _ _ a),
{ exact P0},
{ intro a r q, exact incl2' q base ▸ P0 a},
{ intro a a' s, exact pathover_of_pathover_ap P i (P1 s)}},
{ exact abstract [irreducible] begin induction H, induction x,
{ esimp, exact pathover_tr (incl2' q base) (P0 a)},
{ apply pathover_pathover,
esimp, fold [i, incl2' q],
refine eq_hconcato _ _, apply _,
{ transitivity _,
{ apply ap (pathover_ap _ _),
transitivity _, apply apd_compose2 (pre_rec P0 _ _) (f q) loop,
apply ap (pathover_of_pathover_ap _ _),
transitivity _, apply apd_change_path, exact !elim_loop⁻¹,
transitivity _,
apply ap (change_path _),
transitivity _, apply rec_et,
transitivity (pathover_of_pathover_ap P i (change_path (inclt_eq_incltw r)
(e_closure.elimo incl1 (λ (a a' : A) (s : R a a'), P1 s) r))),
apply e_closure_elimo_ap,
exact idp,
apply change_path_pathover_of_pathover_ap},
esimp, transitivity _, apply pathover_ap_pathover_of_pathover_ap P i (f q),
transitivity _, apply ap (change_path _), apply to_right_inv !pathover_compose,
do 2 (transitivity _; exact !change_path_con⁻¹),
transitivity _, apply ap (change_path _),
exact (to_left_inv (change_path_equiv _ _ (incl2 q)) _)⁻¹, esimp,
rewrite P2, transitivity _; exact !change_path_con⁻¹, apply ap (λx, change_path x _),
rewrite [↑incl2, con_inv], transitivity _, exact !con.assoc⁻¹,
rewrite [inv_con_cancel_right, ↑incl2w, ↑ap02, +con_inv, +ap_inv, +inv_inv, -+con.assoc,
+con_inv_cancel_right], reflexivity},
rewrite [change_path_con, apd_constant],
apply squareover_change_path_left, apply squareover_change_path_right',
apply squareover_change_path_left,
refine change_square _ vrflo,
symmetry, apply inv_ph_eq_of_eq_ph, rewrite [ap_is_constant_natural_square],
apply whisker_bl_whisker_tl_eq} end end},
end
protected definition rec_on [reducible] {P : D → Type} (x : D) (P0 : Π(a : A), P (incl0 a))
(P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a =[incl1 s] P0 a')
(P2 : Π⦃a : A⦄ ⦃r : T a a⦄ (q : Q r),
change_path (incl2 q) (e_closure.elimo incl1 P1 r) = idpo) : P x :=
rec P0 P1 P2 x
theorem rec_incl1 {P : D → Type} (P0 : Π(a : A), P (incl0 a))
(P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a =[incl1 s] P0 a')
(P2 : Π⦃a : A⦄ ⦃r : T a a⦄ (q : Q r),
change_path (incl2 q) (e_closure.elimo incl1 P1 r) = idpo) ⦃a a' : A⦄ (s : R a a')
: apd (rec P0 P1 P2) (incl1 s) = P1 s :=
begin
unfold [rec, incl1], refine !apd_ap ⬝ _, esimp, rewrite rec_e,
apply to_right_inv !pathover_compose
end
theorem rec_inclt {P : D → Type} (P0 : Π(a : A), P (incl0 a))
(P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a =[incl1 s] P0 a')
(P2 : Π⦃a : A⦄ ⦃r : T a a⦄ (q : Q r),
change_path (incl2 q) (e_closure.elimo incl1 P1 r) = idpo) ⦃a a' : A⦄ (t : T a a')
: apd (rec P0 P1 P2) (inclt t) = e_closure.elimo incl1 P1 t :=
ap_e_closure_elimo_h incl1 P1 (rec_incl1 P0 P1 P2) t
protected definition elim {P : Type} (P0 : A → P)
(P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a = P0 a')
(P2 : Π⦃a : A⦄ ⦃r : T a a⦄ (q : Q r), e_closure.elim P1 r = idp)
(x : D) : P :=
begin
induction x,
{ refine (pre_elim _ _ _ a),
{ exact P0},
{ intro a r q, exact P0 a},
{ exact P1}},
{ exact abstract begin induction H, induction x,
{ exact idpath (P0 a)},
{ unfold f, apply eq_pathover, apply hdeg_square,
exact abstract ap_compose (pre_elim P0 _ P1) (f q) loop ⬝
ap _ !elim_loop ⬝
!elim_et ⬝
P2 q ⬝
!ap_constant⁻¹ end} end end},
end
local attribute elim [unfold 8]
protected definition elim_on {P : Type} (x : D) (P0 : A → P)
(P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a = P0 a')
(P2 : Π⦃a : A⦄ ⦃r : T a a⦄ (q : Q r), e_closure.elim P1 r = idp)
: P :=
elim P0 P1 P2 x
definition elim_incl1 {P : Type} {P0 : A → P}
{P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a = P0 a'}
(P2 : Π⦃a : A⦄ ⦃r : T a a⦄ (q : Q r), e_closure.elim P1 r = idp)
⦃a a' : A⦄ (s : R a a') : ap (elim P0 P1 P2) (incl1 s) = P1 s :=
(ap_compose (elim P0 P1 P2) i (e s))⁻¹ ⬝ !elim_e
definition elim_inclt {P : Type} {P0 : A → P}
{P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a = P0 a'}
(P2 : Π⦃a : A⦄ ⦃r : T a a⦄ (q : Q r), e_closure.elim P1 r = idp)
⦃a a' : A⦄ (t : T a a') : ap (elim P0 P1 P2) (inclt t) = e_closure.elim P1 t :=
ap_e_closure_elim_h incl1 (elim_incl1 P2) t
protected definition elim_incltw {P : Type} {P0 : A → P}
{P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a = P0 a'}
(P2 : Π⦃a : A⦄ ⦃r : T a a⦄ (q : Q r), e_closure.elim P1 r = idp)
⦃a a' : A⦄ (t : T a a') : ap (elim P0 P1 P2) (incltw t) = e_closure.elim P1 t :=
(ap_compose (elim P0 P1 P2) i (et t))⁻¹ ⬝ !elim_et
protected theorem elim_inclt_eq_elim_incltw {P : Type} {P0 : A → P}
{P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a = P0 a'}
(P2 : Π⦃a : A⦄ ⦃r : T a a⦄ (q : Q r), e_closure.elim P1 r = idp)
⦃a a' : A⦄ (t : T a a')
: elim_inclt P2 t = ap (ap (elim P0 P1 P2)) (inclt_eq_incltw t) ⬝ elim_incltw P2 t :=
begin
unfold [elim_inclt,elim_incltw,inclt_eq_incltw,et],
refine !ap_e_closure_elim_h_eq ⬝ _,
rewrite [ap_inv,-con.assoc],
xrewrite [eq_of_square (ap_ap_e_closure_elim i (elim P0 P1 P2) e t)⁻¹ʰ],
rewrite [↓incl1,con.assoc], apply whisker_left,
rewrite [↑[elim_et,elim_incl1],+ap_e_closure_elim_h_eq,con_inv,↑[i,function.compose]],
rewrite [-con.assoc (_ ⬝ _),con.assoc _⁻¹,con.left_inv,▸*,-ap_inv,-ap_con],
apply ap (ap _),
krewrite [-eq_of_homotopy3_inv,-eq_of_homotopy3_con]
end
definition elim_incl2' {P : Type} {P0 : A → P}
{P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a = P0 a'}
(P2 : Π⦃a : A⦄ ⦃r : T a a⦄ (q : Q r), e_closure.elim P1 r = idp)
⦃a : A⦄ ⦃r : T a a⦄ (q : Q r) : ap (elim P0 P1 P2) (incl2' q base) = idpath (P0 a) :=
!elim_eq_of_rel
local attribute whisker_right [reducible]
protected theorem elim_incl2w {P : Type} (P0 : A → P)
(P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a = P0 a')
(P2 : Π⦃a : A⦄ ⦃r : T a a⦄ (q : Q r), e_closure.elim P1 r = idp)
⦃a : A⦄ ⦃r : T a a⦄ (q : Q r)
: square (ap02 (elim P0 P1 P2) (incl2w q)) (P2 q) (elim_incltw P2 r) idp :=
begin
esimp [incl2w,ap02],
rewrite [+ap_con (ap _),▸*],
xrewrite [-ap_compose (ap _) (ap i)],
rewrite [+ap_inv],
xrewrite [eq_top_of_square
((ap_compose_natural (elim P0 P1 P2) i (elim_loop (j a) (et r)))⁻¹ʰ⁻¹ᵛ ⬝h
(ap_ap_compose (elim P0 P1 P2) i (f q) loop)⁻¹ʰ⁻¹ᵛ ⬝h
ap_ap_is_constant (elim P0 P1 P2) (incl2' q) loop ⬝h
ap_con_right_inv_sq (elim P0 P1 P2) (incl2' q base)),
↑[elim_incltw]],
apply whisker_tl,
rewrite [ap_is_constant_eq],
xrewrite [naturality_apd_eq (λx, !elim_eq_of_rel) loop],
rewrite [↑elim_2,rec_loop,square_of_pathover_concato_eq,square_of_pathover_eq_concato,
eq_of_square_vconcat_eq,eq_of_square_eq_vconcat],
apply eq_vconcat,
{ apply ap (λx, _ ⬝ eq_con_inv_of_con_eq ((_ ⬝ x ⬝ _)⁻¹ ⬝ _) ⬝ _),
transitivity _, apply ap eq_of_square,
apply to_right_inv !eq_pathover_equiv_square (hdeg_square (elim_1 P A R Q P0 P1 a r q P2)),
transitivity _, apply eq_of_square_hdeg_square,
unfold elim_1, reflexivity},
rewrite [+con_inv,whisker_left_inv,+inv_inv,-whisker_right_inv,
con.assoc (whisker_left _ _),con.assoc _ (whisker_right _ _),▸*,
whisker_right_con_whisker_left _ !ap_constant],
xrewrite [-con.assoc _ _ (whisker_right _ _)],
rewrite [con.assoc _ _ (whisker_left _ _),idp_con_whisker_left,▸*,
con.assoc _ !ap_constant⁻¹,con.left_inv],
xrewrite [eq_con_inv_of_con_eq_whisker_left,▸*],
rewrite [+con.assoc _ _ !con.right_inv,
right_inv_eq_idp (
(λ(x : ap (elim P0 P1 P2) (incl2' q base) = idpath
(elim P0 P1 P2 (class_of simple_two_quotient_rel (f q base)))), x)
(elim_incl2' P2 q)),
↑[whisker_left]],
xrewrite [con2_con_con2],
rewrite [idp_con,↑elim_incl2',con.left_inv,whisker_right_inv,↑whisker_right],
xrewrite [con.assoc _ _ (_ ◾ _)],
rewrite [con.left_inv,▸*,-+con.assoc,con.assoc _⁻¹,↑[elim,function.compose],con.left_inv,
▸*,↑j,con.left_inv,idp_con],
apply square_of_eq, reflexivity
end
theorem elim_incl2 {P : Type} (P0 : A → P)
(P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a = P0 a')
(P2 : Π⦃a : A⦄ ⦃r : T a a⦄ (q : Q r), e_closure.elim P1 r = idp)
⦃a : A⦄ ⦃r : T a a⦄ (q : Q r)
: square (ap02 (elim P0 P1 P2) (incl2 q)) (P2 q) (elim_inclt P2 r) idp :=
begin
rewrite [↑incl2,↑ap02,ap_con,elim_inclt_eq_elim_incltw],
apply whisker_tl,
apply elim_incl2w
end
end
end simple_two_quotient
export [unfold] simple_two_quotient
attribute simple_two_quotient.j simple_two_quotient.incl0 [constructor]
attribute simple_two_quotient.rec simple_two_quotient.elim [unfold 8] [recursor 8]
--attribute simple_two_quotient.elim_type [unfold 9] -- TODO
attribute simple_two_quotient.rec_on simple_two_quotient.elim_on [unfold 5]
--attribute simple_two_quotient.elim_type_on [unfold 6] -- TODO
namespace two_quotient
open simple_two_quotient
section
parameters {A : Type}
(R : A → A → Type)
local abbreviation T := e_closure R -- the (type-valued) equivalence closure of R
parameter (Q : Π⦃a a'⦄, T a a' → T a a' → Type)
variables ⦃a a' a'' : A⦄ {s : R a a'} {t t' : T a a'}
inductive two_quotient_Q : Π⦃a : A⦄, e_closure R a a → Type :=
| Qmk : Π⦃a a' : A⦄ ⦃t t' : T a a'⦄, Q t t' → two_quotient_Q (t ⬝r t'⁻¹ʳ)
open two_quotient_Q
local abbreviation Q2 := two_quotient_Q
definition two_quotient := simple_two_quotient R Q2
definition incl0 (a : A) : two_quotient := incl0 _ _ a
definition incl1 (s : R a a') : incl0 a = incl0 a' := incl1 _ _ s
definition inclt (t : T a a') : incl0 a = incl0 a' := e_closure.elim incl1 t
definition incl2 (q : Q t t') : inclt t = inclt t' :=
eq_of_con_inv_eq_idp (incl2 _ _ (Qmk R q))
parameters {R Q}
protected definition rec {P : two_quotient → Type} (P0 : Π(a : A), P (incl0 a))
(P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a =[incl1 s] P0 a')
(P2 : Π⦃a a' : A⦄ ⦃t t' : T a a'⦄ (q : Q t t'),
change_path (incl2 q) (e_closure.elimo incl1 P1 t) = e_closure.elimo incl1 P1 t')
(x : two_quotient) : P x :=
begin
induction x,
{ exact P0 a},
{ exact P1 s},
{ exact abstract [irreducible] begin induction q with a a' t t' q,
rewrite [elimo_trans (simple_two_quotient.incl1 R Q2) P1,
elimo_symm (simple_two_quotient.incl1 R Q2) P1,
-whisker_right_eq_of_con_inv_eq_idp (simple_two_quotient.incl2 R Q2 (Qmk R q)),
change_path_con],
xrewrite [change_path_cono],
refine ap (λx, change_path _ (_ ⬝o x)) !change_path_invo ⬝ _, esimp,
apply cono_invo_eq_idpo, apply P2 end end}
end
protected definition rec_on [reducible] {P : two_quotient → Type} (x : two_quotient)
(P0 : Π(a : A), P (incl0 a))
(P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a =[incl1 s] P0 a')
(P2 : Π⦃a a' : A⦄ ⦃t t' : T a a'⦄ (q : Q t t'),
change_path (incl2 q) (e_closure.elimo incl1 P1 t) = e_closure.elimo incl1 P1 t') : P x :=
rec P0 P1 P2 x
theorem rec_incl1 {P : two_quotient → Type} (P0 : Π(a : A), P (incl0 a))
(P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a =[incl1 s] P0 a')
(P2 : Π⦃a a' : A⦄ ⦃t t' : T a a'⦄ (q : Q t t'),
change_path (incl2 q) (e_closure.elimo incl1 P1 t) = e_closure.elimo incl1 P1 t')
⦃a a' : A⦄ (s : R a a') : apd (rec P0 P1 P2) (incl1 s) = P1 s :=
rec_incl1 _ _ _ s
theorem rec_inclt {P : two_quotient → Type} (P0 : Π(a : A), P (incl0 a))
(P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a =[incl1 s] P0 a')
(P2 : Π⦃a a' : A⦄ ⦃t t' : T a a'⦄ (q : Q t t'),
change_path (incl2 q) (e_closure.elimo incl1 P1 t) = e_closure.elimo incl1 P1 t')
⦃a a' : A⦄ (t : T a a') : apd (rec P0 P1 P2) (inclt t) = e_closure.elimo incl1 P1 t :=
rec_inclt _ _ _ t
protected definition elim {P : Type} (P0 : A → P)
(P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a = P0 a')
(P2 : Π⦃a a' : A⦄ ⦃t t' : T a a'⦄ (q : Q t t'), e_closure.elim P1 t = e_closure.elim P1 t')
(x : two_quotient) : P :=
begin
induction x,
{ exact P0 a},
{ exact P1 s},
{ exact abstract [unfold 10] begin induction q with a a' t t' q,
esimp [e_closure.elim],
apply con_inv_eq_idp, exact P2 q end end},
end
local attribute elim [unfold 8]
protected definition elim_on {P : Type} (x : two_quotient) (P0 : A → P)
(P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a = P0 a')
(P2 : Π⦃a a' : A⦄ ⦃t t' : T a a'⦄ (q : Q t t'), e_closure.elim P1 t = e_closure.elim P1 t')
: P :=
elim P0 P1 P2 x
definition elim_incl1 {P : Type} {P0 : A → P}
{P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a = P0 a'}
(P2 : Π⦃a a' : A⦄ ⦃t t' : T a a'⦄ (q : Q t t'), e_closure.elim P1 t = e_closure.elim P1 t')
⦃a a' : A⦄ (s : R a a') : ap (elim P0 P1 P2) (incl1 s) = P1 s :=
!elim_incl1
definition elim_inclt {P : Type} {P0 : A → P}
{P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a = P0 a'}
(P2 : Π⦃a a' : A⦄ ⦃t t' : T a a'⦄ (q : Q t t'), e_closure.elim P1 t = e_closure.elim P1 t')
⦃a a' : A⦄ (t : T a a') : ap (elim P0 P1 P2) (inclt t) = e_closure.elim P1 t :=
ap_e_closure_elim_h incl1 (elim_incl1 P2) t
theorem elim_incl2 {P : Type} (P0 : A → P)
(P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a = P0 a')
(P2 : Π⦃a a' : A⦄ ⦃t t' : T a a'⦄ (q : Q t t'), e_closure.elim P1 t = e_closure.elim P1 t')
⦃a a' : A⦄ ⦃t t' : T a a'⦄ (q : Q t t')
: square (ap02 (elim P0 P1 P2) (incl2 q)) (P2 q) (elim_inclt P2 t) (elim_inclt P2 t') :=
begin
rewrite [↑[incl2,elim],ap_eq_of_con_inv_eq_idp],
xrewrite [eq_top_of_square (elim_incl2 P0 P1 (elim_1 A R Q P P0 P1 P2) (Qmk R q))],
xrewrite [{simple_two_quotient.elim_inclt (elim_1 A R Q P P0 P1 P2)
(t ⬝r t'⁻¹ʳ)}
idpath (ap_con (simple_two_quotient.elim P0 P1 (elim_1 A R Q P P0 P1 P2))
(inclt t) (inclt t')⁻¹ ⬝
(simple_two_quotient.elim_inclt (elim_1 A R Q P P0 P1 P2) t ◾
(ap_inv (simple_two_quotient.elim P0 P1 (elim_1 A R Q P P0 P1 P2))
(inclt t') ⬝
inverse2 (simple_two_quotient.elim_inclt (elim_1 A R Q P P0 P1 P2) t')))),▸*],
rewrite [-con.assoc _ _ (con_inv_eq_idp _),-con.assoc _ _ (_ ◾ _),con.assoc _ _ (ap_con _ _ _),
con.left_inv,↑whisker_left,con2_con_con2,-con.assoc (ap_inv _ _)⁻¹,
con.left_inv,+idp_con,eq_of_con_inv_eq_idp_con2],
xrewrite [to_left_inv !eq_equiv_con_inv_eq_idp (P2 q)],
apply top_deg_square
end
definition elim_inclt_rel [unfold_full] {P : Type} {P0 : A → P}
{P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a = P0 a'}
(P2 : Π⦃a a' : A⦄ ⦃t t' : T a a'⦄ (q : Q t t'), e_closure.elim P1 t = e_closure.elim P1 t')
⦃a a' : A⦄ (r : R a a') : elim_inclt P2 [r] = elim_incl1 P2 r :=
idp
definition elim_inclt_inv [unfold_full] {P : Type} {P0 : A → P}
{P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a = P0 a'}
(P2 : Π⦃a a' : A⦄ ⦃t t' : T a a'⦄ (q : Q t t'), e_closure.elim P1 t = e_closure.elim P1 t')
⦃a a' : A⦄ (t : T a a')
: elim_inclt P2 t⁻¹ʳ = ap_inv (elim P0 P1 P2) (inclt t) ⬝ (elim_inclt P2 t)⁻² :=
idp
definition elim_inclt_con [unfold_full] {P : Type} {P0 : A → P}
{P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a = P0 a'}
(P2 : Π⦃a a' : A⦄ ⦃t t' : T a a'⦄ (q : Q t t'), e_closure.elim P1 t = e_closure.elim P1 t')
⦃a a' a'' : A⦄ (t : T a a') (t': T a' a'')
: elim_inclt P2 (t ⬝r t') =
ap_con (elim P0 P1 P2) (inclt t) (inclt t') ⬝ (elim_inclt P2 t ◾ elim_inclt P2 t') :=
idp
definition inclt_rel [unfold_full] (r : R a a') : inclt [r] = incl1 r := idp
definition inclt_inv [unfold_full] (t : T a a') : inclt t⁻¹ʳ = (inclt t)⁻¹ := idp
definition inclt_con [unfold_full] (t : T a a') (t' : T a' a'')
: inclt (t ⬝r t') = inclt t ⬝ inclt t' := idp
end
end two_quotient
attribute two_quotient.incl0 [constructor]
attribute two_quotient.rec two_quotient.elim [unfold 8] [recursor 8]
--attribute two_quotient.elim_type [unfold 9]
attribute two_quotient.rec_on two_quotient.elim_on [unfold 5]
--attribute two_quotient.elim_type_on [unfold 6]
open two_quotient is_trunc trunc
namespace trunc_two_quotient
section
parameters (n : ℕ₋₂) {A : Type}
(R : A → A → Type)
local abbreviation T := e_closure R -- the (type-valued) equivalence closure of R
parameter (Q : Π⦃a a'⦄, T a a' → T a a' → Type)
variables ⦃a a' a'' : A⦄ {s : R a a'} {t t' : T a a'}
definition trunc_two_quotient := trunc n (two_quotient R Q)
parameters {n R Q}
definition incl0 (a : A) : trunc_two_quotient := tr (!incl0 a)
definition incl1 (s : R a a') : incl0 a = incl0 a' := ap tr (!incl1 s)
definition incltw (t : T a a') : incl0 a = incl0 a' := ap tr (!inclt t)
definition inclt (t : T a a') : incl0 a = incl0 a' := e_closure.elim incl1 t
definition incl2w (q : Q t t') : incltw t = incltw t' :=
ap02 tr (!incl2 q)
definition incl2 (q : Q t t') : inclt t = inclt t' :=
!ap_e_closure_elim⁻¹ ⬝ ap02 tr (!incl2 q) ⬝ !ap_e_closure_elim
local attribute trunc_two_quotient incl0 [reducible]
definition is_trunc_trunc_two_quotient [instance] : is_trunc n trunc_two_quotient := _
protected definition rec {P : trunc_two_quotient → Type} [H : Πx, is_trunc n (P x)]
(P0 : Π(a : A), P (incl0 a))
(P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a =[incl1 s] P0 a')
(P2 : Π⦃a a' : A⦄ ⦃t t' : T a a'⦄ (q : Q t t'),
change_path (incl2 q) (e_closure.elimo incl1 P1 t) = e_closure.elimo incl1 P1 t')
(x : trunc_two_quotient) : P x :=
begin
induction x,
induction a,
{ exact P0 a},
{ exact !pathover_of_pathover_ap (P1 s)},
{ exact abstract [irreducible]
by rewrite [+ e_closure_elimo_ap, ↓incl1, -P2 q, change_path_pathover_of_pathover_ap,
- + change_path_con, ↑incl2, con_inv_cancel_right] end}
end
protected definition rec_on [reducible] {P : trunc_two_quotient → Type} [H : Πx, is_trunc n (P x)]
(x : trunc_two_quotient)
(P0 : Π(a : A), P (incl0 a))
(P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a =[incl1 s] P0 a')
(P2 : Π⦃a a' : A⦄ ⦃t t' : T a a'⦄ (q : Q t t'),
change_path (incl2 q) (e_closure.elimo incl1 P1 t) = e_closure.elimo incl1 P1 t') : P x :=
rec P0 P1 P2 x
theorem rec_incl1 {P : trunc_two_quotient → Type} [H : Πx, is_trunc n (P x)]
(P0 : Π(a : A), P (incl0 a))
(P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a =[incl1 s] P0 a')
(P2 : Π⦃a a' : A⦄ ⦃t t' : T a a'⦄ (q : Q t t'),
change_path (incl2 q) (e_closure.elimo incl1 P1 t) = e_closure.elimo incl1 P1 t')
⦃a a' : A⦄ (s : R a a') : apd (rec P0 P1 P2) (incl1 s) = P1 s :=
!apd_ap ⬝ ap !pathover_ap !rec_incl1 ⬝ to_right_inv !pathover_compose (P1 s)
theorem rec_inclt {P : trunc_two_quotient → Type} [H : Πx, is_trunc n (P x)]
(P0 : Π(a : A), P (incl0 a))
(P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a =[incl1 s] P0 a')
(P2 : Π⦃a a' : A⦄ ⦃t t' : T a a'⦄ (q : Q t t'),
change_path (incl2 q) (e_closure.elimo incl1 P1 t) = e_closure.elimo incl1 P1 t')
⦃a a' : A⦄ (t : T a a') : apd (rec P0 P1 P2) (inclt t) = e_closure.elimo incl1 P1 t :=
ap_e_closure_elimo_h incl1 P1 (rec_incl1 P0 P1 P2) t
protected definition elim {P : Type} (P0 : A → P) [H : is_trunc n P]
(P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a = P0 a')
(P2 : Π⦃a a' : A⦄ ⦃t t' : T a a'⦄ (q : Q t t'), e_closure.elim P1 t = e_closure.elim P1 t')
(x : trunc_two_quotient) : P :=
begin
induction x,
induction a,
{ exact P0 a},
{ exact P1 s},
{ exact P2 q},
end
local attribute elim [unfold 10]
protected definition elim_on {P : Type} [H : is_trunc n P] (x : trunc_two_quotient) (P0 : A → P)
(P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a = P0 a')
(P2 : Π⦃a a' : A⦄ ⦃t t' : T a a'⦄ (q : Q t t'), e_closure.elim P1 t = e_closure.elim P1 t')
: P :=
elim P0 P1 P2 x
definition elim_incl1 {P : Type} [H : is_trunc n P] {P0 : A → P}
{P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a = P0 a'}
(P2 : Π⦃a a' : A⦄ ⦃t t' : T a a'⦄ (q : Q t t'), e_closure.elim P1 t = e_closure.elim P1 t')
⦃a a' : A⦄ (s : R a a') : ap (elim P0 P1 P2) (incl1 s) = P1 s :=
!ap_compose⁻¹ ⬝ !elim_incl1
definition elim_inclt {P : Type} [H : is_trunc n P] {P0 : A → P}
{P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a = P0 a'}
(P2 : Π⦃a a' : A⦄ ⦃t t' : T a a'⦄ (q : Q t t'), e_closure.elim P1 t = e_closure.elim P1 t')
⦃a a' : A⦄ (t : T a a') : ap (elim P0 P1 P2) (inclt t) = e_closure.elim P1 t :=
ap_e_closure_elim_h incl1 (elim_incl1 P2) t
open function
theorem elim_incl2 {P : Type} [H : is_trunc n P] (P0 : A → P)
(P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a = P0 a')
(P2 : Π⦃a a' : A⦄ ⦃t t' : T a a'⦄ (q : Q t t'), e_closure.elim P1 t = e_closure.elim P1 t')
⦃a a' : A⦄ ⦃t t' : T a a'⦄ (q : Q t t')
: square (ap02 (elim P0 P1 P2) (incl2 q)) (P2 q) (elim_inclt P2 t) (elim_inclt P2 t') :=
begin
note Ht' := ap_ap_e_closure_elim tr (elim P0 P1 P2) (two_quotient.incl1 R Q) t',
note Ht := ap_ap_e_closure_elim tr (elim P0 P1 P2) (two_quotient.incl1 R Q) t,
note Hn := natural_square_tr (ap_compose (elim P0 P1 P2) tr) (two_quotient.incl2 R Q q),
note H7 := eq_top_of_square (Ht⁻¹ʰ ⬝h Hn⁻¹ᵛ ⬝h Ht'), clear [Hn, Ht, Ht'],
unfold [ap02,incl2], rewrite [+ap_con,ap_inv,-ap_compose (ap _)],
xrewrite [H7, ↑function.compose, eq_top_of_square (elim_incl2 P0 P1 P2 q)], clear [H7],
have H : Π(t : T a a'),
ap_e_closure_elim (elim P0 P1 P2) (λa a' (r : R a a'), ap tr (two_quotient.incl1 R Q r)) t ⬝
(ap_e_closure_elim_h (two_quotient.incl1 R Q)
(λa a' (s : R a a'), ap_compose (elim P0 P1 P2) tr (two_quotient.incl1 R Q s)) t)⁻¹ ⬝
two_quotient.elim_inclt P2 t = elim_inclt P2 t, from
ap_e_closure_elim_h_zigzag (elim P0 P1 P2)
(two_quotient.incl1 R Q)
(two_quotient.elim_incl1 P2),
rewrite [con.assoc5, con.assoc5, H t, -inv_con_inv_right, -con_inv], xrewrite [H t'],
apply top_deg_square
end
definition elim_inclt_rel [unfold_full] {P : Type} [is_trunc n P] {P0 : A → P}
{P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a = P0 a'}
(P2 : Π⦃a a' : A⦄ ⦃t t' : T a a'⦄ (q : Q t t'), e_closure.elim P1 t = e_closure.elim P1 t')
⦃a a' : A⦄ (r : R a a') : elim_inclt P2 [r] = elim_incl1 P2 r :=
idp
definition elim_inclt_inv [unfold_full] {P : Type} [is_trunc n P] {P0 : A → P}
{P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a = P0 a'}
(P2 : Π⦃a a' : A⦄ ⦃t t' : T a a'⦄ (q : Q t t'), e_closure.elim P1 t = e_closure.elim P1 t')
⦃a a' : A⦄ (t : T a a')
: elim_inclt P2 t⁻¹ʳ = ap_inv (elim P0 P1 P2) (inclt t) ⬝ (elim_inclt P2 t)⁻² :=
idp
definition elim_inclt_con [unfold_full] {P : Type} [is_trunc n P] {P0 : A → P}
{P1 : Π⦃a a' : A⦄ (s : R a a'), P0 a = P0 a'}
(P2 : Π⦃a a' : A⦄ ⦃t t' : T a a'⦄ (q : Q t t'), e_closure.elim P1 t = e_closure.elim P1 t')
⦃a a' a'' : A⦄ (t : T a a') (t': T a' a'')
: elim_inclt P2 (t ⬝r t') =
ap_con (elim P0 P1 P2) (inclt t) (inclt t') ⬝ (elim_inclt P2 t ◾ elim_inclt P2 t') :=
idp
definition inclt_rel [unfold_full] (r : R a a') : inclt [r] = incl1 r := idp
definition inclt_inv [unfold_full] (t : T a a') : inclt t⁻¹ʳ = (inclt t)⁻¹ := idp
definition inclt_con [unfold_full] (t : T a a') (t' : T a' a'')
: inclt (t ⬝r t') = inclt t ⬝ inclt t' := idp
end
end trunc_two_quotient
attribute trunc_two_quotient.incl0 [constructor]
attribute trunc_two_quotient.rec trunc_two_quotient.elim [unfold 10] [recursor 10]
attribute trunc_two_quotient.rec_on trunc_two_quotient.elim_on [unfold 7]

View file

@ -1,512 +0,0 @@
/-
Copyright (c) 2016 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
Eilenberg MacLane spaces
-/
import hit.groupoid_quotient homotopy.hopf homotopy.freudenthal homotopy.homotopy_group
open algebra pointed nat eq category group is_trunc iso unit trunc equiv is_conn function is_equiv
trunc_index
namespace EM
open groupoid_quotient
variables {G : Group}
definition EM1' (G : Group) : Type :=
groupoid_quotient (Groupoid_of_Group G)
definition EM1 [constructor] (G : Group) : Type* :=
pointed.MK (EM1' G) (elt star)
definition base : EM1' G := elt star
definition pth : G → base = base := pth
definition resp_mul (g h : G) : pth (g * h) = pth g ⬝ pth h := resp_comp h g
definition resp_one : pth (1 : G) = idp :=
resp_id star
definition resp_inv (g : G) : pth (g⁻¹) = (pth g)⁻¹ :=
resp_inv g
local attribute pointed.MK pointed.carrier EM1 EM1' [reducible]
protected definition rec {P : EM1' G → Type} [H : Π(x : EM1' G), is_trunc 1 (P x)]
(Pb : P base) (Pp : Π(g : G), Pb =[pth g] Pb)
(Pmul : Π(g h : G), change_path (resp_mul g h) (Pp (g * h)) = Pp g ⬝o Pp h) (x : EM1' G) :
P x :=
begin
induction x,
{ induction g, exact Pb},
{ induction a, induction b, exact Pp f},
{ induction a, induction b, induction c, exact Pmul f g}
end
protected definition rec_on {P : EM1' G → Type} [H : Π(x : EM1' G), is_trunc 1 (P x)]
(x : EM1' G) (Pb : P base) (Pp : Π(g : G), Pb =[pth g] Pb)
(Pmul : Π(g h : G), change_path (resp_mul g h) (Pp (g * h)) = Pp g ⬝o Pp h) : P x :=
EM.rec Pb Pp Pmul x
protected definition set_rec {P : EM1' G → Type} [H : Π(x : EM1' G), is_set (P x)]
(Pb : P base) (Pp : Π(g : G), Pb =[pth g] Pb) (x : EM1' G) : P x :=
EM.rec Pb Pp !center x
protected definition prop_rec {P : EM1' G → Type} [H : Π(x : EM1' G), is_prop (P x)]
(Pb : P base) (x : EM1' G) : P x :=
EM.rec Pb !center !center x
definition rec_pth {P : EM1' G → Type} [H : Π(x : EM1' G), is_trunc 1 (P x)]
{Pb : P base} {Pp : Π(g : G), Pb =[pth g] Pb}
(Pmul : Π(g h : G), change_path (resp_mul g h) (Pp (g * h)) = Pp g ⬝o Pp h)
(g : G) : apd (EM.rec Pb Pp Pmul) (pth g) = Pp g :=
proof !rec_pth qed
protected definition elim {P : Type} [is_trunc 1 P] (Pb : P) (Pp : Π(g : G), Pb = Pb)
(Pmul : Π(g h : G), Pp (g * h) = Pp g ⬝ Pp h) (x : EM1' G) : P :=
begin
induction x,
{ exact Pb},
{ exact Pp f},
{ exact Pmul f g}
end
protected definition elim_on [reducible] {P : Type} [is_trunc 1 P] (x : EM1' G)
(Pb : P) (Pp : G → Pb = Pb) (Pmul : Π(g h : G), Pp (g * h) = Pp g ⬝ Pp h) : P :=
EM.elim Pb Pp Pmul x
protected definition set_elim [reducible] {P : Type} [is_set P] (Pb : P) (Pp : G → Pb = Pb)
(x : EM1' G) : P :=
EM.elim Pb Pp !center x
protected definition prop_elim [reducible] {P : Type} [is_prop P] (Pb : P) (x : EM1' G) : P :=
EM.elim Pb !center !center x
definition elim_pth {P : Type} [is_trunc 1 P] {Pb : P} {Pp : G → Pb = Pb}
(Pmul : Π(g h : G), Pp (g * h) = Pp g ⬝ Pp h) (g : G) : ap (EM.elim Pb Pp Pmul) (pth g) = Pp g :=
proof !elim_pth qed
protected definition elim_set.{u} (Pb : Set.{u}) (Pp : Π(g : G), Pb ≃ Pb)
(Pmul : Π(g h : G) (x : Pb), Pp (g * h) x = Pp h (Pp g x)) (x : EM1' G) : Set.{u} :=
groupoid_quotient.elim_set (λu, Pb) (λu v, Pp) (λu v w g h, proof Pmul h g qed) x
theorem elim_set_pth {Pb : Set} {Pp : Π(g : G), Pb ≃ Pb}
(Pmul : Π(g h : G) (x : Pb), Pp (g * h) x = Pp h (Pp g x)) (g : G) :
transport (EM.elim_set Pb Pp Pmul) (pth g) = Pp g :=
!elim_set_pth
end EM
attribute EM.base [constructor]
attribute EM.rec EM.elim [unfold 7] [recursor 7]
attribute EM.rec_on EM.elim_on [unfold 4]
attribute EM.set_rec EM.set_elim [unfold 6]
attribute EM.prop_rec EM.prop_elim EM.elim_set [unfold 5]
namespace EM
open groupoid_quotient
variables (G : Group)
definition base_eq_base_equiv : (base = base :> EM1 G) ≃ G :=
!elt_eq_elt_equiv
definition fundamental_group_EM1 : π₁ (EM1 G) ≃g G :=
begin
fapply isomorphism_of_equiv,
{ exact trunc_equiv_trunc 0 !base_eq_base_equiv ⬝e trunc_equiv 0 G},
{ intros g h, induction g with p, induction h with q,
exact encode_con p q}
end
proposition is_trunc_EM1 [instance] : is_trunc 1 (EM1 G) :=
!is_trunc_groupoid_quotient
proposition is_trunc_EM1' [instance] : is_trunc 1 (EM1' G) :=
!is_trunc_groupoid_quotient
proposition is_conn_EM1' [instance] : is_conn 0 (EM1' G) :=
by apply @is_conn_groupoid_quotient; esimp; exact _
proposition is_conn_EM1 [instance] : is_conn 0 (EM1 G) :=
is_conn_EM1' G
variable {G}
definition EM1_map [unfold 7] {X : Type*} (e : G → Ω X)
(r : Πg h, e (g * h) = e g ⬝ e h) [is_conn 0 X] [is_trunc 1 X] : EM1 G → X :=
begin
intro x, induction x using EM.elim,
{ exact Point X },
{ exact e g },
{ exact r g h }
end
/- Uniqueness of K(G, 1) -/
definition EM1_pmap [constructor] {X : Type*} (e : G → Ω X)
(r : Πg h, e (g * h) = e g ⬝ e h) [is_conn 0 X] [is_trunc 1 X] : EM1 G →* X :=
pmap.mk (EM1_map e r) idp
variable (G)
definition loop_EM1 [constructor] : G ≃* Ω (EM1 G) :=
(pequiv_of_equiv (base_eq_base_equiv G) idp)⁻¹ᵉ*
variable {G}
definition loop_EM1_pmap {X : Type*} (e : G →* Ω X)
(r : Πg h, e (g * h) = e g ⬝ e h) [is_conn 0 X] [is_trunc 1 X] :
Ω→(EM1_pmap e r) ∘* loop_EM1 G ~* e :=
begin
fapply phomotopy.mk,
{ intro g, refine !idp_con ⬝ elim_pth r g },
{ apply is_set.elim }
end
definition EM1_pequiv'.{u} {G : Group.{u}} {X : pType.{u}} (e : G ≃* Ω X)
(r : Πg h, e (g * h) = e g ⬝ e h) [is_conn 0 X] [is_trunc 1 X] : EM1 G ≃* X :=
begin
apply pequiv_of_pmap (EM1_pmap e r),
apply whitehead_principle_pointed 1,
intro k, cases k with k,
{ apply @is_equiv_of_is_contr,
all_goals (esimp; exact _)},
{ cases k with k,
{ apply is_equiv_trunc_functor, esimp,
apply is_equiv.homotopy_closed, rotate 1,
{ symmetry, exact phomotopy_pinv_right_of_phomotopy (loop_EM1_pmap _ _) },
apply is_equiv_compose e },
{ apply @is_equiv_of_is_contr,
do 2 exact trivial_homotopy_group_of_is_trunc _ (succ_lt_succ !zero_lt_succ)}}
end
definition EM1_pequiv.{u} {G : Group.{u}} {X : pType.{u}} (e : G ≃g π₁ X)
[is_conn 0 X] [is_trunc 1 X] : EM1 G ≃* X :=
begin
apply EM1_pequiv' (pequiv_of_isomorphism e ⬝e* ptrunc_pequiv 0 (Ω X)),
refine is_equiv.preserve_binary_of_inv_preserve _ mul concat _,
intro p q,
exact to_respect_mul e⁻¹ᵍ (tr p) (tr q)
end
definition EM1_pequiv_type (X : Type*) [is_conn 0 X] [is_trunc 1 X] : EM1 (π₁ X) ≃* X :=
EM1_pequiv !isomorphism.refl
end EM
open hopf susp
namespace EM
/- EM1 G is an h-space if G is an abelian group. This allows us to construct K(G,n) for n ≥ 2 -/
variables {G : AbGroup} (n : )
definition EM1_mul [unfold 2 3] (x x' : EM1' G) : EM1' G :=
begin
induction x,
{ exact x'},
{ induction x' using EM.set_rec,
{ exact pth g},
{ exact abstract begin apply loop_pathover, apply square_of_eq,
refine !resp_mul⁻¹ ⬝ _ ⬝ !resp_mul,
exact ap pth !mul.comm end end}},
{ refine EM.prop_rec _ x', apply resp_mul }
end
variable (G)
definition EM1_mul_one (x : EM1' G) : EM1_mul x base = x :=
begin
induction x using EM.set_rec,
{ reflexivity},
{ apply eq_pathover_id_right, apply hdeg_square, refine EM.elim_pth _ g}
end
definition h_space_EM1 [constructor] [instance] : h_space (EM1' G) :=
begin
fapply h_space.mk,
{ exact EM1_mul},
{ exact base},
{ intro x', reflexivity},
{ apply EM1_mul_one}
end
/- K(G, n+1) -/
definition EMadd1 : → Type*
| 0 := EM1 G
| (n+1) := ptrunc (n+2) (psusp (EMadd1 n))
definition EMadd1_succ [unfold_full] (n : ) :
EMadd1 G (succ n) = ptrunc (n.+2) (psusp (EMadd1 G n)) :=
idp
definition loop_EM2 : Ω[1] (EMadd1 G 1) ≃* EM1 G :=
hopf.delooping (EM1' G) idp
definition is_conn_EMadd1 [instance] (n : ) : is_conn n (EMadd1 G n) :=
begin
induction n with n IH,
{ apply is_conn_EM1 },
{ rewrite EMadd1_succ, esimp, exact _ }
end
definition is_trunc_EMadd1 [instance] (n : ) : is_trunc (n+1) (EMadd1 G n) :=
begin
cases n with n,
{ apply is_trunc_EM1 },
{ apply is_trunc_trunc }
end
/- loops of an EM-space -/
definition loop_EMadd1 (n : ) : EMadd1 G n ≃* Ω (EMadd1 G (succ n)) :=
begin
cases n with n,
{ exact !loop_EM2⁻¹ᵉ* },
{ rewrite [EMadd1_succ G (succ n)],
refine (ptrunc_pequiv (succ n + 1) _)⁻¹ᵉ* ⬝e* _ ⬝e* (loop_ptrunc_pequiv _ _)⁻¹ᵉ*,
have succ n + 1 ≤ 2 * succ n, from add_mul_le_mul_add n 1 1,
refine freudenthal_pequiv _ this }
end
definition loopn_EMadd1_pequiv_EM1 (G : AbGroup) (n : ) : EM1 G ≃* Ω[n] (EMadd1 G n) :=
begin
induction n with n e,
{ reflexivity },
{ refine _ ⬝e* !loopn_succ_in⁻¹ᵉ*,
refine _ ⬝e* loopn_pequiv_loopn n !loop_EMadd1,
exact e }
end
-- use loopn_EMadd1_pequiv_EM1 in this definition?
definition loopn_EMadd1 (G : AbGroup) (n : ) : G ≃* Ω[succ n] (EMadd1 G n) :=
begin
induction n with n e,
{ apply loop_EM1 },
{ refine _ ⬝e* !loopn_succ_in⁻¹ᵉ*,
refine _ ⬝e* loopn_pequiv_loopn (succ n) !loop_EMadd1,
exact e }
end
definition loopn_EMadd1_succ [unfold_full] (G : AbGroup) (n : ) : loopn_EMadd1 G (succ n) ~*
!loopn_succ_in⁻¹ᵉ* ∘* apn (succ n) !loop_EMadd1 ∘* loopn_EMadd1 G n :=
by reflexivity
definition EM_up {G : AbGroup} {X : Type*} {n : } (e : Ω[succ (succ n)] X ≃* G)
: Ω[succ n] (Ω X) ≃* G :=
!loopn_succ_in⁻¹ᵉ* ⬝e* e
definition is_homomorphism_EM_up {G : AbGroup} {X : Type*} {n : }
(e : Ω[succ (succ n)] X ≃* G)
(r : Π(p q : Ω[succ (succ n)] X), e (p ⬝ q) = e p * e q)
(p q : Ω[succ n] (Ω X)) : EM_up e (p ⬝ q) = EM_up e p * EM_up e q :=
begin
refine _ ⬝ !r, apply ap e, esimp, apply apn_con
end
definition EMadd1_pmap [unfold 8] {G : AbGroup} {X : Type*} (n : )
(e : Ω[succ n] X ≃* G)
(r : Πp q, e (p ⬝ q) = e p * e q)
[H1 : is_conn n X] [H2 : is_trunc (n.+1) X] : EMadd1 G n →* X :=
begin
revert X e r H1 H2, induction n with n f: intro X e r H1 H2,
{ exact EM1_pmap e⁻¹ᵉ* (equiv.inv_preserve_binary e concat mul r) },
rewrite [EMadd1_succ],
exact ptrunc.elim ((succ n).+1)
(psusp.elim (f _ (EM_up e) (is_homomorphism_EM_up e r) _ _)),
end
definition EMadd1_pmap_succ {G : AbGroup} {X : Type*} (n : ) (e : Ω[succ (succ n)] X ≃* G)
r [H1 : is_conn (succ n) X] [H2 : is_trunc ((succ n).+1) X] : EMadd1_pmap (succ n) e r =
ptrunc.elim ((succ n).+1) (psusp.elim (EMadd1_pmap n (EM_up e) (is_homomorphism_EM_up e r))) :=
by reflexivity
definition loop_EMadd1_pmap {G : AbGroup} {X : Type*} {n : } (e : Ω[succ (succ n)] X ≃* G)
(r : Πp q, e (p ⬝ q) = e p * e q)
[H1 : is_conn (succ n) X] [H2 : is_trunc ((succ n).+1) X] :
Ω→(EMadd1_pmap (succ n) e r) ∘* loop_EMadd1 G n ~*
EMadd1_pmap n (EM_up e) (is_homomorphism_EM_up e r) :=
begin
cases n with n,
{ apply hopf_delooping_elim },
{ refine !passoc⁻¹* ⬝* _,
rewrite [EMadd1_pmap_succ (succ n)],
refine pwhisker_right _ !ap1_ptrunc_elim ⬝* _,
refine !passoc⁻¹* ⬝* _,
refine pwhisker_right _ (ptrunc_elim_freudenthal_pequiv
(succ n) (succ (succ n)) (add_mul_le_mul_add n 1 1) _) ⬝* _,
reflexivity }
end
definition loopn_EMadd1_pmap' {G : AbGroup} {X : Type*} {n : } (e : Ω[succ n] X ≃* G)
(r : Πp q, e (p ⬝ q) = e p * e q)
[H1 : is_conn n X] [H2 : is_trunc (n.+1) X] :
Ω→[succ n](EMadd1_pmap n e r) ∘* loopn_EMadd1 G n ~* e⁻¹ᵉ* :=
begin
revert X e r H1 H2, induction n with n IH: intro X e r H1 H2,
{ apply loop_EM1_pmap },
refine pwhisker_left _ !loopn_EMadd1_succ ⬝* _,
refine !passoc⁻¹* ⬝* _,
refine pwhisker_right _ !loopn_succ_in_inv_natural ⬝* _,
refine !passoc ⬝* _,
refine pwhisker_left _ (!passoc⁻¹* ⬝*
pwhisker_right _ (!apn_pcompose⁻¹* ⬝* apn_phomotopy _ !loop_EMadd1_pmap) ⬝*
!IH ⬝* !pinv_trans_pinv_left) ⬝* _,
apply pinv_pcompose_cancel_left
end
definition EMadd1_pequiv' {G : AbGroup} {X : Type*} (n : ) (e : Ω[succ n] X ≃* G)
(r : Π(p q : Ω[succ n] X), e (p ⬝ q) = e p * e q)
[H1 : is_conn n X] [H2 : is_trunc (n.+1) X] : EMadd1 G n ≃* X :=
begin
apply pequiv_of_pmap (EMadd1_pmap n e r),
have is_conn 0 (EMadd1 G n), from is_conn_of_le _ (zero_le_of_nat n),
have is_trunc (n.+1) (EMadd1 G n), from !is_trunc_EMadd1,
refine whitehead_principle_pointed (n.+1) _ _,
intro k, apply @nat.lt_by_cases k (succ n): intro H,
{ apply @is_equiv_of_is_contr,
do 2 exact trivial_homotopy_group_of_is_conn _ (le_of_lt_succ H)},
{ cases H, esimp, apply is_equiv_trunc_functor, esimp,
apply is_equiv.homotopy_closed, rotate 1,
{ symmetry, exact phomotopy_pinv_right_of_phomotopy (loopn_EMadd1_pmap' _ _) },
apply is_equiv_compose (e⁻¹ᵉ*)},
{ apply @is_equiv_of_is_contr,
do 2 exact trivial_homotopy_group_of_is_trunc _ H}
end
definition EMadd1_pequiv {G : AbGroup} {X : Type*} (n : ) (e : πg[n+1] X ≃g G)
[H1 : is_conn n X] [H2 : is_trunc (n.+1) X] : EMadd1 G n ≃* X :=
begin
have is_set (Ω[succ n] X), from !is_set_loopn,
apply EMadd1_pequiv' n ((ptrunc_pequiv _ _)⁻¹ᵉ* ⬝e* pequiv_of_isomorphism e),
intro p q, esimp, exact to_respect_mul e (tr p) (tr q)
end
definition EMadd1_pequiv_succ {G : AbGroup} {X : Type*} (n : ) (e : πag[n+2] X ≃g G)
[H1 : is_conn (n.+1) X] [H2 : is_trunc (n.+2) X] : EMadd1 G (succ n) ≃* X :=
EMadd1_pequiv (succ n) e
definition ghomotopy_group_EMadd1 (n : ) : πg[n+1] (EMadd1 G n) ≃g G :=
begin
change π₁ (Ω[n] (EMadd1 G n)) ≃g G,
refine homotopy_group_isomorphism_of_pequiv 0 (loopn_EMadd1_pequiv_EM1 G n)⁻¹ᵉ* ⬝g _,
apply fundamental_group_EM1,
end
definition EMadd1_pequiv_type (X : Type*) (n : ) [is_conn (n+1) X] [is_trunc (n+1+1) X]
: EMadd1 (πag[n+2] X) (succ n) ≃* X :=
EMadd1_pequiv_succ n !isomorphism.refl
/- K(G, n) -/
definition EM (G : AbGroup) : → Type*
| 0 := G
| (k+1) := EMadd1 G k
namespace ops
abbreviation K := @EM
end ops
open ops
definition homotopy_group_EM (n : ) : π[n] (EM G n) ≃* G :=
begin
cases n with n,
{ rexact ptrunc_pequiv 0 G },
{ exact pequiv_of_isomorphism (ghomotopy_group_EMadd1 G n)}
end
definition ghomotopy_group_EM (n : ) : πg[n+1] (EM G (n+1)) ≃g G :=
ghomotopy_group_EMadd1 G n
definition is_conn_EM [instance] (n : ) : is_conn (n.-1) (EM G n) :=
begin
cases n with n,
{ apply is_conn_minus_one, apply tr, unfold [EM], exact 1},
{ apply is_conn_EMadd1}
end
definition is_conn_EM_succ [instance] (n : ) : is_conn n (EM G (succ n)) :=
is_conn_EM G (succ n)
definition is_trunc_EM [instance] (n : ) : is_trunc n (EM G n) :=
begin
cases n with n,
{ unfold [EM], apply semigroup.is_set_carrier},
{ apply is_trunc_EMadd1}
end
definition loop_EM (n : ) : Ω (K G (succ n)) ≃* K G n :=
begin
cases n with n,
{ refine _ ⬝e* pequiv_of_isomorphism (fundamental_group_EM1 G),
symmetry, apply ptrunc_pequiv },
{ exact !loop_EMadd1⁻¹ᵉ* }
end
open circle int
definition EM_pequiv_circle : K ag 1 ≃* S¹* :=
EM1_pequiv fundamental_group_of_circle⁻¹ᵍ
/- Functorial action of Eilenberg-Maclane spaces -/
definition EM1_functor [constructor] {G H : Group} (φ : G →g H) : EM1 G →* EM1 H :=
begin
fconstructor,
{ intro g, induction g,
{ exact base },
{ exact pth (φ g) },
{ exact ap pth (to_respect_mul φ g h) ⬝ resp_mul (φ g) (φ h) }},
{ reflexivity }
end
definition EMadd1_functor [constructor] {G H : AbGroup} (φ : G →g H) (n : ) :
EMadd1 G n →* EMadd1 H n :=
begin
induction n with n ψ,
{ exact EM1_functor φ },
{ apply ptrunc_functor, apply psusp_functor, exact ψ }
end
definition EM_functor [unfold 4] {G H : AbGroup} (φ : G →g H) (n : ) :
K G n →* K H n :=
begin
cases n with n,
{ exact pmap_of_homomorphism φ },
{ exact EMadd1_functor φ n }
end
-- TODO: (K G n →* K H n) ≃ (G →g H)
/- Equivalence of Groups and pointed connected 1-truncated types -/
definition ptruncconntype10_pequiv (X Y : 1-Type*[0]) (e : π₁ X ≃g π₁ Y) : X ≃* Y :=
(EM1_pequiv !isomorphism.refl)⁻¹ᵉ* ⬝e* EM1_pequiv e
definition EM1_pequiv_ptruncconntype10 (X : 1-Type*[0]) : EM1 (π₁ X) ≃* X :=
EM1_pequiv_type X
definition Group_equiv_ptruncconntype10 [constructor] : Group ≃ 1-Type*[0] :=
equiv.MK (λG, ptruncconntype.mk (EM1 G) _ pt !is_conn_EM1)
(λX, π₁ X)
begin intro X, apply ptruncconntype_eq, esimp, exact EM1_pequiv_type X end
begin intro G, apply eq_of_isomorphism, apply fundamental_group_EM1 end
/- Equivalence of AbGroups and pointed n-connected (n+1)-truncated types (n ≥ 1) -/
open trunc_index
definition ptruncconntype_pequiv : Π(n : ) (X Y : (n.+1)-Type*[n])
(e : πg[n+1] X ≃g πg[n+1] Y), X ≃* Y
| 0 X Y e := ptruncconntype10_pequiv X Y e
| (succ n) X Y e :=
begin
refine (EMadd1_pequiv_succ n _)⁻¹ᵉ* ⬝e* EMadd1_pequiv_succ n !isomorphism.refl,
exact e
end
definition EM1_pequiv_ptruncconntype (n : ) (X : (n+1+1)-Type*[n+1]) :
EMadd1 (πag[n+2] X) (succ n) ≃* X :=
EMadd1_pequiv_type X n
definition AbGroup_equiv_ptruncconntype' [constructor] (n : ) :
AbGroup ≃ (n + 1 + 1)-Type*[n+1] :=
equiv.MK
(λG, ptruncconntype.mk (EMadd1 G (n+1)) _ pt _)
(λX, πag[n+2] X)
begin intro X, apply ptruncconntype_eq, apply EMadd1_pequiv_type end
begin intro G, apply AbGroup_eq_of_isomorphism, exact ghomotopy_group_EMadd1 G (n+1) end
definition AbGroup_equiv_ptruncconntype [constructor] (n : ) :
AbGroup ≃ (n.+2)-Type*[n.+1] :=
AbGroup_equiv_ptruncconntype' n
end EM

View file

@ -1,817 +0,0 @@
/-
Copyright (c) 2016 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
We define the fiber sequence of a pointed map f : X →* Y. We mostly follow the proof in section 8.4
of the book.
PART 1:
We define a sequence fiber_sequence as in Definition 8.4.3.
It has types X(n) : Type*
X(0) := Y,
X(1) := X,
X(n+1) := fiber (f(n))
with functions f(n) : X(n+1) →* X(n)
f(0) := f
f(n+1) := point (f(n)) [this is the first projection]
We prove that this is an exact sequence.
Then we prove Lemma 8.4.3, by showing that X(n+3) ≃* Ω(X(n)) and that this equivalence sends
the pointed map f(n+3) to -Ω(f(n)), i.e. the composition of Ω(f(n)) with path inversion.
Using this equivalence we get a boundary_map : Ω(Y) → pfiber f.
PART 2:
Now we can define a new fiber sequence X'(n) : Type*, and here we slightly diverge from the book.
We define it as
X'(0) := Y,
X'(1) := X,
X'(2) := fiber f
X'(n+3) := Ω(X'(n))
with maps f'(n) : X'(n+1) →* X'(n)
f'(0) := f
f'(1) := point f
f'(2) := boundary_map
f'(n+3) := Ω(f'(n))
This sequence is not equivalent to the previous sequence. The difference is in the signs.
The sequence f has negative signs (i.e. is composed with the inverse maps) for n ≡ 3, 4, 5 mod 6.
This sign information is captured by e : X'(n) ≃* X'(n) such that
e(k) := 1 for k = 0,1,2,3
e(k+3) := Ω(e(k)) ∘ (-)⁻¹ for k > 0
Now the sequence (X', f' ∘ e) is equivalent to (X, f), Hence (X', f' ∘ e) is an exact sequence.
We then prove that (X', f') is an exact sequence by using that there are other equivalences
eₗ and eᵣ such that
f' = eᵣ ∘ f' ∘ e
f' ∘ eₗ = e ∘ f'.
(this fact is type_chain_complex_cancel_aut and is_exact_at_t_cancel_aut in the file chain_complex)
eₗ and eᵣ are almost the same as e, except that the places where the inverse is taken is
slightly shifted:
eᵣ = (-)⁻¹ for n ≡ 3, 4, 5 mod 6 and eᵣ = 1 otherwise
e = (-)⁻¹ for n ≡ 4, 5, 6 mod 6 (except for n = 0) and e = 1 otherwise
eₗ = (-)⁻¹ for n ≡ 5, 6, 7 mod 6 (except for n = 0, 1) and eₗ = 1 otherwise
PART 3:
We change the type over which the sequence of types and maps are indexed from to × 3
(where 3 is the finite type with 3 elements). The reason is that we have that X'(3n) = Ωⁿ(Y), but
this equality is not definitionally true. Hence we cannot even state whether f'(3n) = Ωⁿ(f) without
using transports. This gets ugly. However, if we use as index type × 3, we can do this. We can
define
Y : × 3 → Type* as
Y(n, 0) := Ωⁿ(Y)
Y(n, 1) := Ωⁿ(X)
Y(n, 2) := Ωⁿ(fiber f)
with maps g(n) : Y(S n) →* Y(n) (where the successor is defined in the obvious way)
g(n, 0) := Ωⁿ(f)
g(n, 1) := Ωⁿ(point f)
g(n, 2) := Ωⁿ(boundary_map) ∘ cast
Here "cast" is the transport over the equality Ωⁿ⁺¹(Y) = Ωⁿ(Ω(Y)). We show that the sequence
(, X', f') is equivalent to ( × 3, Y, g).
PART 4:
We get the long exact sequence of homotopy groups by taking the set-truncation of (Y, g).
-/
import .chain_complex algebra.homotopy_group eq2
open eq pointed sigma fiber equiv is_equiv sigma.ops is_trunc nat trunc algebra function sum
/--------------
PART 1
--------------/
namespace chain_complex
definition fiber_sequence_helper [constructor] (v : Σ(X Y : Type*), X →* Y)
: Σ(Z X : Type*), Z →* X :=
⟨pfiber v.2.2, v.1, ppoint v.2.2⟩
definition fiber_sequence_helpern (v : Σ(X Y : Type*), X →* Y) (n : )
: Σ(Z X : Type*), Z →* X :=
iterate fiber_sequence_helper n v
section
universe variable u
parameters {X Y : pType.{u}} (f : X →* Y)
include f
definition fiber_sequence_carrier (n : ) : Type* :=
(fiber_sequence_helpern ⟨X, Y, f⟩ n).2.1
definition fiber_sequence_fun (n : )
: fiber_sequence_carrier (n + 1) →* fiber_sequence_carrier n :=
(fiber_sequence_helpern ⟨X, Y, f⟩ n).2.2
/- Definition 8.4.3 -/
definition fiber_sequence : type_chain_complex.{0 u} + :=
begin
fconstructor,
{ exact fiber_sequence_carrier},
{ exact fiber_sequence_fun},
{ intro n x, cases n with n,
{ exact point_eq x},
{ exact point_eq x}}
end
definition is_exact_fiber_sequence : is_exact_t fiber_sequence :=
λn x p, fiber.mk (fiber.mk x p) rfl
/- (generalization of) Lemma 8.4.4(i)(ii) -/
definition fiber_sequence_carrier_equiv (n : )
: fiber_sequence_carrier (n+3) ≃ Ω(fiber_sequence_carrier n) :=
calc
fiber_sequence_carrier (n+3) ≃ fiber (fiber_sequence_fun (n+1)) pt : erfl
... ≃ Σ(x : fiber_sequence_carrier _), fiber_sequence_fun (n+1) x = pt
: fiber.sigma_char
... ≃ Σ(x : fiber (fiber_sequence_fun n) pt), fiber_sequence_fun _ x = pt
: erfl
... ≃ Σ(v : Σ(x : fiber_sequence_carrier _), fiber_sequence_fun _ x = pt),
fiber_sequence_fun _ (fiber.mk v.1 v.2) = pt
: by exact sigma_equiv_sigma !fiber.sigma_char (λa, erfl)
... ≃ Σ(v : Σ(x : fiber_sequence_carrier _), fiber_sequence_fun _ x = pt),
v.1 = pt
: erfl
... ≃ Σ(v : Σ(x : fiber_sequence_carrier _), x = pt),
fiber_sequence_fun _ v.1 = pt
: sigma_assoc_comm_equiv
... ≃ fiber_sequence_fun _ !center.1 = pt
: @(sigma_equiv_of_is_contr_left _) !is_contr_sigma_eq'
... ≃ fiber_sequence_fun _ pt = pt
: erfl
... ≃ pt = pt
: by exact !equiv_eq_closed_left !respect_pt
... ≃ Ω(fiber_sequence_carrier n) : erfl
/- computation rule -/
definition fiber_sequence_carrier_equiv_eq (n : )
(x : fiber_sequence_carrier (n+1)) (p : fiber_sequence_fun n x = pt)
(q : fiber_sequence_fun (n+1) (fiber.mk x p) = pt)
: fiber_sequence_carrier_equiv n (fiber.mk (fiber.mk x p) q)
= !respect_pt⁻¹ ⬝ ap (fiber_sequence_fun n) q⁻¹ ⬝ p :=
begin
refine _ ⬝ !con.assoc⁻¹,
apply whisker_left,
refine eq_transport_Fl _ _ ⬝ _,
apply whisker_right,
refine inverse2 !ap_inv ⬝ !inv_inv ⬝ _,
refine ap_compose (fiber_sequence_fun n) pr₁ _ ⬝
ap02 (fiber_sequence_fun n) !ap_pr1_center_eq_sigma_eq',
end
definition fiber_sequence_carrier_equiv_inv_eq (n : )
(p : Ω(fiber_sequence_carrier n)) : (fiber_sequence_carrier_equiv n)⁻¹ᵉ p =
fiber.mk (fiber.mk pt (respect_pt (fiber_sequence_fun n) ⬝ p)) idp :=
begin
apply inv_eq_of_eq,
refine _ ⬝ !fiber_sequence_carrier_equiv_eq⁻¹, esimp,
exact !inv_con_cancel_left⁻¹
end
definition fiber_sequence_carrier_pequiv (n : )
: fiber_sequence_carrier (n+3) ≃* Ω(fiber_sequence_carrier n) :=
pequiv_of_equiv (fiber_sequence_carrier_equiv n)
begin
esimp,
apply con.left_inv
end
definition fiber_sequence_carrier_pequiv_eq (n : )
(x : fiber_sequence_carrier (n+1)) (p : fiber_sequence_fun n x = pt)
(q : fiber_sequence_fun (n+1) (fiber.mk x p) = pt)
: fiber_sequence_carrier_pequiv n (fiber.mk (fiber.mk x p) q)
= !respect_pt⁻¹ ⬝ ap (fiber_sequence_fun n) q⁻¹ ⬝ p :=
fiber_sequence_carrier_equiv_eq n x p q
definition fiber_sequence_carrier_pequiv_inv_eq (n : )
(p : Ω(fiber_sequence_carrier n)) : (fiber_sequence_carrier_pequiv n)⁻¹ᵉ* p =
fiber.mk (fiber.mk pt (respect_pt (fiber_sequence_fun n) ⬝ p)) idp :=
by rexact fiber_sequence_carrier_equiv_inv_eq n p
/- Lemma 8.4.4(iii) -/
definition fiber_sequence_fun_eq_helper (n : )
(p : Ω(fiber_sequence_carrier (n + 1))) :
fiber_sequence_carrier_pequiv n
(fiber_sequence_fun (n + 3)
((fiber_sequence_carrier_pequiv (n + 1))⁻¹ᵉ* p)) =
ap1 (fiber_sequence_fun n) p⁻¹ :=
begin
refine ap (λx, fiber_sequence_carrier_pequiv n (fiber_sequence_fun (n + 3) x))
(fiber_sequence_carrier_pequiv_inv_eq (n+1) p) ⬝ _,
/- the following three lines are rewriting some reflexivities: -/
-- replace (n + 3) with (n + 2 + 1),
-- refine ap (fiber_sequence_carrier_pequiv n)
-- (fiber_sequence_fun_eq1 (n+2) _ idp) ⬝ _,
refine fiber_sequence_carrier_pequiv_eq n pt (respect_pt (fiber_sequence_fun n)) _ ⬝ _,
esimp,
apply whisker_right,
apply whisker_left,
apply ap02, apply inverse2, apply idp_con,
end
theorem fiber_sequence_carrier_pequiv_eq_point_eq_idp (n : ) :
fiber_sequence_carrier_pequiv_eq n
(Point (fiber_sequence_carrier (n+1)))
(respect_pt (fiber_sequence_fun n))
(respect_pt (fiber_sequence_fun (n + 1))) = idp :=
begin
apply con_inv_eq_idp,
refine ap (λx, whisker_left _ (_ ⬝ x)) _ ⬝ _,
{ reflexivity},
{ reflexivity},
refine ap (whisker_left _)
(eq_transport_Fl_idp_left (fiber_sequence_fun n)
(respect_pt (fiber_sequence_fun n))) ⬝ _,
apply whisker_left_idp_con_eq_assoc
end
theorem fiber_sequence_fun_phomotopy_helper (n : ) :
(fiber_sequence_carrier_pequiv n ∘*
fiber_sequence_fun (n + 3)) ∘*
(fiber_sequence_carrier_pequiv (n + 1))⁻¹ᵉ* ~*
ap1 (fiber_sequence_fun n) ∘* pinverse :=
begin
fapply phomotopy.mk,
{ exact chain_complex.fiber_sequence_fun_eq_helper f n},
{ esimp, rewrite [idp_con], refine _ ⬝ whisker_left _ !idp_con⁻¹,
apply whisker_right,
apply whisker_left,
exact chain_complex.fiber_sequence_carrier_pequiv_eq_point_eq_idp f n}
end
theorem fiber_sequence_fun_eq (n : ) : Π(x : fiber_sequence_carrier (n + 4)),
fiber_sequence_carrier_pequiv n (fiber_sequence_fun (n + 3) x) =
ap1 (fiber_sequence_fun n) (fiber_sequence_carrier_pequiv (n + 1) x)⁻¹ :=
begin
apply homotopy_of_inv_homotopy_pre (fiber_sequence_carrier_pequiv (n + 1)),
apply fiber_sequence_fun_eq_helper n
end
theorem fiber_sequence_fun_phomotopy (n : ) :
fiber_sequence_carrier_pequiv n ∘*
fiber_sequence_fun (n + 3) ~*
(ap1 (fiber_sequence_fun n) ∘* pinverse) ∘* fiber_sequence_carrier_pequiv (n + 1) :=
begin
apply phomotopy_of_pinv_right_phomotopy,
apply fiber_sequence_fun_phomotopy_helper
end
definition boundary_map : Ω Y →* pfiber f :=
fiber_sequence_fun 2 ∘* (fiber_sequence_carrier_pequiv 0)⁻¹ᵉ*
/--------------
PART 2
--------------/
/- Now we are ready to define the long exact sequence of homotopy groups.
First we define its carrier -/
definition loop_spaces : → Type*
| 0 := Y
| 1 := X
| 2 := pfiber f
| (k+3) := Ω (loop_spaces k)
/- The maps between the homotopy groups -/
definition loop_spaces_fun
: Π(n : ), loop_spaces (n+1) →* loop_spaces n
| 0 := proof f qed
| 1 := proof ppoint f qed
| 2 := proof boundary_map qed
| (k+3) := proof ap1 (loop_spaces_fun k) qed
definition loop_spaces_fun_add3 [unfold_full] (n : ) :
loop_spaces_fun (n + 3) = ap1 (loop_spaces_fun n) :=
proof idp qed
definition fiber_sequence_pequiv_loop_spaces :
Πn, fiber_sequence_carrier n ≃* loop_spaces n
| 0 := by reflexivity
| 1 := by reflexivity
| 2 := by reflexivity
| (k+3) :=
begin
refine fiber_sequence_carrier_pequiv k ⬝e* _,
apply loop_pequiv_loop,
exact fiber_sequence_pequiv_loop_spaces k
end
definition fiber_sequence_pequiv_loop_spaces_add3 (n : )
: fiber_sequence_pequiv_loop_spaces (n + 3) =
ap1 (fiber_sequence_pequiv_loop_spaces n) ∘* fiber_sequence_carrier_pequiv n :=
by reflexivity
definition fiber_sequence_pequiv_loop_spaces_3_phomotopy
: fiber_sequence_pequiv_loop_spaces 3 ~* proof fiber_sequence_carrier_pequiv nat.zero qed :=
begin
refine pwhisker_right _ ap1_pid ⬝* _,
apply pid_pcompose
end
definition pid_or_pinverse : Π(n : ), loop_spaces n ≃* loop_spaces n
| 0 := pequiv.rfl
| 1 := pequiv.rfl
| 2 := pequiv.rfl
| 3 := pequiv.rfl
| (k+4) := !pequiv_pinverse ⬝e* loop_pequiv_loop (pid_or_pinverse (k+1))
definition pid_or_pinverse_add4 (n : )
: pid_or_pinverse (n + 4) = !pequiv_pinverse ⬝e* loop_pequiv_loop (pid_or_pinverse (n + 1)) :=
by reflexivity
definition pid_or_pinverse_add4_rev : Π(n : ),
pid_or_pinverse (n + 4) ~* pinverse ∘* Ω→(pid_or_pinverse (n + 1))
| 0 := begin rewrite [pid_or_pinverse_add4, + to_pmap_pequiv_trans],
replace pid_or_pinverse (0 + 1) with pequiv.refl X,
refine pwhisker_right _ !loop_pequiv_loop_rfl ⬝* _, refine !pid_pcompose ⬝* _,
exact !pcompose_pid⁻¹* ⬝* pwhisker_left _ !ap1_pid⁻¹* end
| 1 := begin rewrite [pid_or_pinverse_add4, + to_pmap_pequiv_trans],
replace pid_or_pinverse (1 + 1) with pequiv.refl (pfiber f),
refine pwhisker_right _ !loop_pequiv_loop_rfl ⬝* _, refine !pid_pcompose ⬝* _,
exact !pcompose_pid⁻¹* ⬝* pwhisker_left _ !ap1_pid⁻¹* end
| 2 := begin rewrite [pid_or_pinverse_add4, + to_pmap_pequiv_trans],
replace pid_or_pinverse (2 + 1) with pequiv.refl (Ω Y),
refine pwhisker_right _ !loop_pequiv_loop_rfl ⬝* _, refine !pid_pcompose ⬝* _,
exact !pcompose_pid⁻¹* ⬝* pwhisker_left _ !ap1_pid⁻¹* end
| (k+3) :=
begin
replace (k + 3 + 1) with (k + 4),
rewrite [+ pid_or_pinverse_add4, + to_pmap_pequiv_trans],
refine _ ⬝* pwhisker_left _ !ap1_pcompose⁻¹*,
refine _ ⬝* !passoc,
apply pconcat2,
{ refine ap1_phomotopy (pid_or_pinverse_add4_rev k) ⬝* _,
refine !ap1_pcompose ⬝* _, apply pwhisker_right, apply ap1_pinverse},
{ refine !ap1_pinverse⁻¹*}
end
theorem fiber_sequence_phomotopy_loop_spaces : Π(n : ),
fiber_sequence_pequiv_loop_spaces n ∘* fiber_sequence_fun n ~*
(loop_spaces_fun n ∘* pid_or_pinverse (n + 1)) ∘* fiber_sequence_pequiv_loop_spaces (n + 1)
| 0 := proof proof phomotopy.rfl qed ⬝* pwhisker_right _ !pcompose_pid⁻¹* qed
| 1 := by reflexivity
| 2 :=
begin
refine !pid_pcompose ⬝* _,
replace loop_spaces_fun 2 with boundary_map,
refine _ ⬝* pwhisker_left _ fiber_sequence_pequiv_loop_spaces_3_phomotopy⁻¹*,
apply phomotopy_of_pinv_right_phomotopy,
exact !pid_pcompose⁻¹*
end
| (k+3) :=
begin
replace (k + 3 + 1) with (k + 1 + 3),
rewrite [fiber_sequence_pequiv_loop_spaces_add3 k,
fiber_sequence_pequiv_loop_spaces_add3 (k+1)],
refine !passoc ⬝* _,
refine pwhisker_left _ (fiber_sequence_fun_phomotopy k) ⬝* _,
refine !passoc⁻¹* ⬝* _ ⬝* !passoc,
apply pwhisker_right,
replace (k + 1 + 3) with (k + 4),
xrewrite [loop_spaces_fun_add3, pid_or_pinverse_add4, to_pmap_pequiv_trans],
refine _ ⬝* !passoc⁻¹*,
refine _ ⬝* pwhisker_left _ !passoc⁻¹*,
refine _ ⬝* pwhisker_left _ (pwhisker_left _ !ap1_pcompose_pinverse),
refine !passoc⁻¹* ⬝* _ ⬝* !passoc ⬝* !passoc,
apply pwhisker_right,
refine !ap1_pcompose⁻¹* ⬝* _ ⬝* !ap1_pcompose ⬝* pwhisker_right _ !ap1_pcompose,
apply ap1_phomotopy,
exact fiber_sequence_phomotopy_loop_spaces k
end
definition pid_or_pinverse_right : Π(n : ), loop_spaces n →* loop_spaces n
| 0 := !pid
| 1 := !pid
| 2 := !pid
| (k+3) := Ω→(pid_or_pinverse_right k) ∘* pinverse
definition pid_or_pinverse_left : Π(n : ), loop_spaces n →* loop_spaces n
| 0 := pequiv.rfl
| 1 := pequiv.rfl
| 2 := pequiv.rfl
| 3 := pequiv.rfl
| 4 := pequiv.rfl
| (k+5) := Ω→(pid_or_pinverse_left (k+2)) ∘* pinverse
definition pid_or_pinverse_right_add3 (n : )
: pid_or_pinverse_right (n + 3) = Ω→(pid_or_pinverse_right n) ∘* pinverse :=
by reflexivity
definition pid_or_pinverse_left_add5 (n : )
: pid_or_pinverse_left (n + 5) = Ω→(pid_or_pinverse_left (n+2)) ∘* pinverse :=
by reflexivity
theorem pid_or_pinverse_commute_right : Π(n : ),
loop_spaces_fun n ~* pid_or_pinverse_right n ∘* loop_spaces_fun n ∘* pid_or_pinverse (n + 1)
| 0 := proof !pcompose_pid⁻¹* ⬝* !pid_pcompose⁻¹* qed
| 1 := proof !pcompose_pid⁻¹* ⬝* !pid_pcompose⁻¹* qed
| 2 := proof !pcompose_pid⁻¹* ⬝* !pid_pcompose⁻¹* qed
| (k+3) :=
begin
replace (k + 3 + 1) with (k + 4),
rewrite [pid_or_pinverse_right_add3, loop_spaces_fun_add3],
refine _ ⬝* pwhisker_left _ (pwhisker_left _ !pid_or_pinverse_add4_rev⁻¹*),
refine ap1_phomotopy (pid_or_pinverse_commute_right k) ⬝* _,
refine !ap1_pcompose ⬝* _ ⬝* !passoc⁻¹*,
apply pwhisker_left,
refine !ap1_pcompose ⬝* _ ⬝* !passoc ⬝* !passoc,
apply pwhisker_right,
refine _ ⬝* pwhisker_right _ !ap1_pcompose_pinverse,
refine _ ⬝* !passoc⁻¹*,
refine !pcompose_pid⁻¹* ⬝* pwhisker_left _ _,
symmetry, apply pinverse_pinverse
end
theorem pid_or_pinverse_commute_left : Π(n : ),
loop_spaces_fun n ∘* pid_or_pinverse_left (n + 1) ~* pid_or_pinverse n ∘* loop_spaces_fun n
| 0 := proof !pcompose_pid ⬝* !pid_pcompose⁻¹* qed
| 1 := proof !pcompose_pid ⬝* !pid_pcompose⁻¹* qed
| 2 := proof !pcompose_pid ⬝* !pid_pcompose⁻¹* qed
| 3 := proof !pcompose_pid ⬝* !pid_pcompose⁻¹* qed
| (k+4) :=
begin
replace (k + 4 + 1) with (k + 5),
rewrite [pid_or_pinverse_left_add5, pid_or_pinverse_add4, to_pmap_pequiv_trans],
replace (k + 4) with (k + 1 + 3),
rewrite [loop_spaces_fun_add3],
refine !passoc⁻¹* ⬝* _ ⬝* !passoc⁻¹*,
refine _ ⬝* pwhisker_left _ !ap1_pcompose_pinverse,
refine _ ⬝* !passoc,
apply pwhisker_right,
refine !ap1_pcompose⁻¹* ⬝* _ ⬝* !ap1_pcompose,
exact ap1_phomotopy (pid_or_pinverse_commute_left (k+1))
end
definition LES_of_loop_spaces' [constructor] : type_chain_complex + :=
transfer_type_chain_complex
fiber_sequence
(λn, loop_spaces_fun n ∘* pid_or_pinverse (n + 1))
fiber_sequence_pequiv_loop_spaces
fiber_sequence_phomotopy_loop_spaces
definition LES_of_loop_spaces [constructor] : type_chain_complex + :=
type_chain_complex_cancel_aut
LES_of_loop_spaces'
loop_spaces_fun
pid_or_pinverse
pid_or_pinverse_right
(λn x, idp)
pid_or_pinverse_commute_right
definition is_exact_LES_of_loop_spaces : is_exact_t LES_of_loop_spaces :=
begin
intro n,
refine is_exact_at_t_cancel_aut n pid_or_pinverse_left _ _ pid_or_pinverse_commute_left _,
apply is_exact_at_t_transfer,
apply is_exact_fiber_sequence
end
open prod succ_str fin
/--------------
PART 3
--------------/
definition loop_spaces2 [reducible] : +3 → Type*
| (n, fin.mk 0 H) := Ω[n] Y
| (n, fin.mk 1 H) := Ω[n] X
| (n, fin.mk k H) := Ω[n] (pfiber f)
definition loop_spaces2_add1 (n : ) : Π(x : fin 3),
loop_spaces2 (n+1, x) = Ω (loop_spaces2 (n, x))
| (fin.mk 0 H) := by reflexivity
| (fin.mk 1 H) := by reflexivity
| (fin.mk 2 H) := by reflexivity
| (fin.mk (k+3) H) := begin exfalso, apply lt_le_antisymm H, apply le_add_left end
definition loop_spaces_fun2 : Π(n : +3), loop_spaces2 (S n) →* loop_spaces2 n
| (n, fin.mk 0 H) := proof Ω→[n] f qed
| (n, fin.mk 1 H) := proof Ω→[n] (ppoint f) qed
| (n, fin.mk 2 H) := proof Ω→[n] boundary_map ∘* loopn_succ_in Y n qed
| (n, fin.mk (k+3) H) := begin exfalso, apply lt_le_antisymm H, apply le_add_left end
definition loop_spaces_fun2_add1_0 (n : ) (H : 0 < succ 2)
: loop_spaces_fun2 (n+1, fin.mk 0 H) ~*
cast proof idp qed ap1 (loop_spaces_fun2 (n, fin.mk 0 H)) :=
by reflexivity
definition loop_spaces_fun2_add1_1 (n : ) (H : 1 < succ 2)
: loop_spaces_fun2 (n+1, fin.mk 1 H) ~*
cast proof idp qed ap1 (loop_spaces_fun2 (n, fin.mk 1 H)) :=
by reflexivity
definition loop_spaces_fun2_add1_2 (n : ) (H : 2 < succ 2)
: loop_spaces_fun2 (n+1, fin.mk 2 H) ~*
cast proof idp qed ap1 (loop_spaces_fun2 (n, fin.mk 2 H)) :=
proof !ap1_pcompose⁻¹* qed
definition nat_of_str [unfold 2] [reducible] {n : } : × fin (succ n) → :=
λx, succ n * pr1 x + val (pr2 x)
definition str_of_nat {n : } : × fin (succ n) :=
λm, (m / (succ n), mk_mod n m)
definition nat_of_str_3S [unfold 2] [reducible]
: Π(x : stratified + 2), nat_of_str x + 1 = nat_of_str (@S (stratified + 2) x)
| (n, fin.mk 0 H) := by reflexivity
| (n, fin.mk 1 H) := by reflexivity
| (n, fin.mk 2 H) := by reflexivity
| (n, fin.mk (k+3) H) := begin exfalso, apply lt_le_antisymm H, apply le_add_left end
definition fin_prod_nat_equiv_nat [constructor] (n : ) : × fin (succ n) ≃ :=
equiv.MK nat_of_str str_of_nat
abstract begin
intro m, unfold [nat_of_str, str_of_nat, mk_mod],
refine _ ⬝ (eq_div_mul_add_mod m (succ n))⁻¹,
rewrite [mul.comm]
end end
abstract begin
intro x, cases x with m k,
cases k with k H,
apply prod_eq: esimp [str_of_nat],
{ rewrite [add.comm, add_mul_div_self_left _ _ (!zero_lt_succ), ▸*,
div_eq_zero_of_lt H, zero_add]},
{ apply eq_of_veq, esimp [mk_mod],
rewrite [add.comm, add_mul_mod_self_left, ▸*, mod_eq_of_lt H]}
end end
/-
note: in the following theorem the (n+1) case is 3 times the same,
so maybe this can be simplified
-/
definition loop_spaces2_pequiv' : Π(n : ) (x : fin (nat.succ 2)),
loop_spaces (nat_of_str (n, x)) ≃* loop_spaces2 (n, x)
| 0 (fin.mk 0 H) := by reflexivity
| 0 (fin.mk 1 H) := by reflexivity
| 0 (fin.mk 2 H) := by reflexivity
| (n+1) (fin.mk 0 H) :=
begin
apply loop_pequiv_loop,
rexact loop_spaces2_pequiv' n (fin.mk 0 H)
end
| (n+1) (fin.mk 1 H) :=
begin
apply loop_pequiv_loop,
rexact loop_spaces2_pequiv' n (fin.mk 1 H)
end
| (n+1) (fin.mk 2 H) :=
begin
apply loop_pequiv_loop,
rexact loop_spaces2_pequiv' n (fin.mk 2 H)
end
| n (fin.mk (k+3) H) := begin exfalso, apply lt_le_antisymm H, apply le_add_left end
definition loop_spaces2_pequiv : Π(x : +3),
loop_spaces (nat_of_str x) ≃* loop_spaces2 x
| (n, x) := loop_spaces2_pequiv' n x
local attribute loop_pequiv_loop [reducible]
/- all cases where n>0 are basically the same -/
definition loop_spaces_fun2_phomotopy (x : +3) :
loop_spaces2_pequiv x ∘* loop_spaces_fun (nat_of_str x) ~*
(loop_spaces_fun2 x ∘* loop_spaces2_pequiv (S x))
∘* pcast (ap (loop_spaces) (nat_of_str_3S x)) :=
begin
cases x with n x, cases x with k H,
do 3 (cases k with k; rotate 1),
{ /-k≥3-/ exfalso, apply lt_le_antisymm H, apply le_add_left},
{ /-k=0-/
induction n with n IH,
{ refine !pid_pcompose ⬝* _ ⬝* !pcompose_pid⁻¹* ⬝* !pcompose_pid⁻¹*,
reflexivity},
{ refine _ ⬝* !pcompose_pid⁻¹*,
refine _ ⬝* pwhisker_right _ !loop_spaces_fun2_add1_0⁻¹*,
refine !ap1_pcompose⁻¹* ⬝* _ ⬝* !ap1_pcompose, apply ap1_phomotopy,
exact IH ⬝* !pcompose_pid}},
{ /-k=1-/
induction n with n IH,
{ refine !pid_pcompose ⬝* _ ⬝* !pcompose_pid⁻¹* ⬝* !pcompose_pid⁻¹*,
reflexivity},
{ refine _ ⬝* !pcompose_pid⁻¹*,
refine _ ⬝* pwhisker_right _ !loop_spaces_fun2_add1_1⁻¹*,
refine !ap1_pcompose⁻¹* ⬝* _ ⬝* !ap1_pcompose, apply ap1_phomotopy,
exact IH ⬝* !pcompose_pid}},
{ /-k=2-/
induction n with n IH,
{ refine !pid_pcompose ⬝* _ ⬝* !pcompose_pid⁻¹*,
refine !pcompose_pid⁻¹* ⬝* pconcat2 _ _,
{ exact (pcompose_pid (chain_complex.boundary_map f))⁻¹*},
{ refine !loop_pequiv_loop_rfl⁻¹* }},
{ refine _ ⬝* !pcompose_pid⁻¹*,
refine _ ⬝* pwhisker_right _ !loop_spaces_fun2_add1_2⁻¹*,
refine !ap1_pcompose⁻¹* ⬝* _ ⬝* !ap1_pcompose, apply ap1_phomotopy,
exact IH ⬝* !pcompose_pid}},
end
definition LES_of_loop_spaces2 [constructor] : type_chain_complex +3 :=
transfer_type_chain_complex2
LES_of_loop_spaces
!fin_prod_nat_equiv_nat
nat_of_str_3S
@loop_spaces_fun2
@loop_spaces2_pequiv
begin
intro m x,
refine loop_spaces_fun2_phomotopy m x ⬝ _,
apply ap (loop_spaces_fun2 m), apply ap (loop_spaces2_pequiv (S m)),
esimp, exact ap010 cast !ap_compose⁻¹ x
end
definition is_exact_LES_of_loop_spaces2 : is_exact_t LES_of_loop_spaces2 :=
begin
intro n,
apply is_exact_at_t_transfer2,
apply is_exact_LES_of_loop_spaces
end
definition LES_of_homotopy_groups' [constructor] : chain_complex +3 :=
trunc_chain_complex LES_of_loop_spaces2
/--------------
PART 4
--------------/
definition homotopy_groups [reducible] : +3 → Set*
| (n, fin.mk 0 H) := π[n] Y
| (n, fin.mk 1 H) := π[n] X
| (n, fin.mk k H) := π[n] (pfiber f)
definition homotopy_groups_pequiv_loop_spaces2 [reducible]
: Π(n : +3), ptrunc 0 (loop_spaces2 n) ≃* homotopy_groups n
| (n, fin.mk 0 H) := by reflexivity
| (n, fin.mk 1 H) := by reflexivity
| (n, fin.mk 2 H) := by reflexivity
| (n, fin.mk (k+3) H) := begin exfalso, apply lt_le_antisymm H, apply le_add_left end
definition homotopy_groups_fun : Π(n : +3), homotopy_groups (S n) →* homotopy_groups n
| (n, fin.mk 0 H) := proof π→[n] f qed
| (n, fin.mk 1 H) := proof π→[n] (ppoint f) qed
| (n, fin.mk 2 H) :=
proof π→[n] boundary_map ∘* homotopy_group_succ_in Y n qed
| (n, fin.mk (k+3) H) := begin exfalso, apply lt_le_antisymm H, apply le_add_left end
definition homotopy_groups_fun_phomotopy_loop_spaces_fun2 [reducible]
: Π(n : +3), homotopy_groups_pequiv_loop_spaces2 n ∘* ptrunc_functor 0 (loop_spaces_fun2 n) ~*
homotopy_groups_fun n ∘* homotopy_groups_pequiv_loop_spaces2 (S n)
| (n, fin.mk 0 H) := by reflexivity
| (n, fin.mk 1 H) := by reflexivity
| (n, fin.mk 2 H) :=
begin
refine !pid_pcompose ⬝* _ ⬝* !pcompose_pid⁻¹*,
refine !ptrunc_functor_pcompose
end
| (n, fin.mk (k+3) H) := begin exfalso, apply lt_le_antisymm H, apply le_add_left end
definition LES_of_homotopy_groups [constructor] : chain_complex +3 :=
transfer_chain_complex
LES_of_homotopy_groups'
homotopy_groups_fun
homotopy_groups_pequiv_loop_spaces2
homotopy_groups_fun_phomotopy_loop_spaces_fun2
definition is_exact_LES_of_homotopy_groups : is_exact LES_of_homotopy_groups :=
begin
intro n,
apply is_exact_at_transfer,
apply is_exact_at_trunc,
apply is_exact_LES_of_loop_spaces2
end
variable (n : )
/- the carrier of the fiber sequence is definitionally what we want (as pointed sets) -/
example : LES_of_homotopy_groups (str_of_nat 6) = π[2] Y :> Set* := by reflexivity
example : LES_of_homotopy_groups (str_of_nat 7) = π[2] X :> Set* := by reflexivity
example : LES_of_homotopy_groups (str_of_nat 8) = π[2] (pfiber f) :> Set* := by reflexivity
example : LES_of_homotopy_groups (str_of_nat 9) = π[3] Y :> Set* := by reflexivity
example : LES_of_homotopy_groups (str_of_nat 10) = π[3] X :> Set* := by reflexivity
example : LES_of_homotopy_groups (str_of_nat 11) = π[3] (pfiber f) :> Set* := by reflexivity
definition LES_of_homotopy_groups_0 : LES_of_homotopy_groups (n, 0) = π[n] Y :=
by reflexivity
definition LES_of_homotopy_groups_1 : LES_of_homotopy_groups (n, 1) = π[n] X :=
by reflexivity
definition LES_of_homotopy_groups_2 : LES_of_homotopy_groups (n, 2) = π[n] (pfiber f) :=
by reflexivity
/-
the functions of the fiber sequence is definitionally what we want (as pointed function).
-/
definition LES_of_homotopy_groups_fun_0 :
cc_to_fn LES_of_homotopy_groups (n, 0) = π→[n] f :=
by reflexivity
definition LES_of_homotopy_groups_fun_1 :
cc_to_fn LES_of_homotopy_groups (n, 1) = π→[n] (ppoint f) :=
by reflexivity
definition LES_of_homotopy_groups_fun_2 : cc_to_fn LES_of_homotopy_groups (n, 2) =
π→[n] boundary_map ∘* homotopy_group_succ_in Y n :=
by reflexivity
open group
definition group_LES_of_homotopy_groups (n : ) : Π(x : fin (succ 2)),
group (LES_of_homotopy_groups (n + 1, x))
| (fin.mk 0 H) := begin rexact group_homotopy_group n Y end
| (fin.mk 1 H) := begin rexact group_homotopy_group n X end
| (fin.mk 2 H) := begin rexact group_homotopy_group n (pfiber f) end
| (fin.mk (k+3) H) := begin exfalso, apply lt_le_antisymm H, apply le_add_left end
definition ab_group_LES_of_homotopy_groups (n : ) : Π(x : fin (succ 2)),
ab_group (LES_of_homotopy_groups (n + 2, x))
| (fin.mk 0 H) := proof ab_group_homotopy_group n Y qed
| (fin.mk 1 H) := proof ab_group_homotopy_group n X qed
| (fin.mk 2 H) := proof ab_group_homotopy_group n (pfiber f) qed
| (fin.mk (k+3) H) := begin exfalso, apply lt_le_antisymm H, apply le_add_left end
definition Group_LES_of_homotopy_groups (x : +3) : Group.{u} :=
Group.mk (LES_of_homotopy_groups (nat.succ (pr1 x), pr2 x))
(group_LES_of_homotopy_groups (pr1 x) (pr2 x))
definition AbGroup_LES_of_homotopy_groups (n : +3) : AbGroup.{u} :=
AbGroup.mk (LES_of_homotopy_groups (pr1 n + 2, pr2 n))
(ab_group_LES_of_homotopy_groups (pr1 n) (pr2 n))
definition homomorphism_LES_of_homotopy_groups_fun : Π(k : +3),
Group_LES_of_homotopy_groups (S k) →g Group_LES_of_homotopy_groups k
| (k, fin.mk 0 H) :=
proof homomorphism.mk (cc_to_fn LES_of_homotopy_groups (k + 1, 0))
(homotopy_group_functor_mul _ _) qed
| (k, fin.mk 1 H) :=
proof homomorphism.mk (cc_to_fn LES_of_homotopy_groups (k + 1, 1))
(homotopy_group_functor_mul _ _) qed
| (k, fin.mk 2 H) :=
begin
apply homomorphism.mk (cc_to_fn LES_of_homotopy_groups (k + 1, 2)),
exact abstract begin rewrite [LES_of_homotopy_groups_fun_2],
refine homomorphism.struct ((π→g[k+1] boundary_map) ∘g ghomotopy_group_succ_in Y k),
end end
end
| (k, fin.mk (l+3) H) := begin exfalso, apply lt_le_antisymm H, apply le_add_left end
end
/-
Fibration sequences
This is a similar construction, but with as input data two pointed maps,
and a pointed equivalence between the domain of the second map and the fiber of the first map,
and a pointed homotopy.
-/
section
universe variable u
parameters {F X Y : pType.{u}} (f : X →* Y) (g : F →* X) (e : pfiber f ≃* F)
(p : ppoint f ~* g ∘* e)
include f p
open succ_str prod nat
definition fibration_sequence_car [reducible] : +3 → Type*
| (n, fin.mk 0 H) := Ω[n] Y
| (n, fin.mk 1 H) := Ω[n] X
| (n, fin.mk k H) := Ω[n] F
definition fibration_sequence_fun
: Π(n : +3), fibration_sequence_car (S n) →* fibration_sequence_car n
| (n, fin.mk 0 H) := proof Ω→[n] f qed
| (n, fin.mk 1 H) := proof Ω→[n] g qed
| (n, fin.mk 2 H) := proof Ω→[n] (e ∘* boundary_map f) ∘* loopn_succ_in Y n qed
| (n, fin.mk (k+3) H) := begin exfalso, apply lt_le_antisymm H, apply le_add_left end
definition fibration_sequence_pequiv : Π(x : +3),
loop_spaces2 f x ≃* fibration_sequence_car x
| (n, fin.mk 0 H) := by reflexivity
| (n, fin.mk 1 H) := by reflexivity
| (n, fin.mk 2 H) := loopn_pequiv_loopn n e
| (n, fin.mk (k+3) H) := begin exfalso, apply lt_le_antisymm H, apply le_add_left end
definition fibration_sequence_fun_phomotopy : Π(x : +3),
fibration_sequence_pequiv x ∘* loop_spaces_fun2 f x ~*
(fibration_sequence_fun x ∘* fibration_sequence_pequiv (S x))
| (n, fin.mk 0 H) := by reflexivity
| (n, fin.mk 1 H) :=
begin refine !pid_pcompose ⬝* _, refine apn_phomotopy n p ⬝* _,
refine !apn_pcompose ⬝* _, reflexivity end
| (n, fin.mk 2 H) := begin refine !passoc⁻¹* ⬝* _ ⬝* !pcompose_pid⁻¹*, apply pwhisker_right,
refine _ ⬝* !apn_pcompose⁻¹*, reflexivity end
| (n, fin.mk (k+3) H) := begin exfalso, apply lt_le_antisymm H, apply le_add_left end
definition type_fibration_sequence [constructor] : type_chain_complex +3 :=
transfer_type_chain_complex
(LES_of_loop_spaces2 f)
fibration_sequence_fun
fibration_sequence_pequiv
fibration_sequence_fun_phomotopy
definition is_exact_type_fibration_sequence : is_exact_t type_fibration_sequence :=
begin
intro n,
apply is_exact_at_t_transfer,
apply is_exact_LES_of_loop_spaces2
end
definition fibration_sequence [constructor] : chain_complex +3 :=
trunc_chain_complex type_fibration_sequence
end
end chain_complex

View file

@ -1,49 +0,0 @@
/-
Copyright (c) 2015 Ulrik Buchholtz. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Ulrik Buchholtz
-/
import types.trunc homotopy.sphere hit.pushout
open eq is_trunc is_equiv nat equiv trunc prod pushout sigma sphere_index unit
-- where should this be?
definition family : Type := ΣX, X → Type
namespace cellcomplex
/-
define by recursion on
both the type of fdccs of dimension n
and the realization map fdcc n → Type
in other words, we define a function
fdcc : → family
an alternative to the approach here (perhaps necessary) is to
define relative cell complexes relative to a type A, and then use
spherical indexing, so a -1-dimensional relative cell complex is
just star : unit with realization A
-/
definition fdcc_family [reducible] : → family :=
nat.rec
-- a zero-dimensional cell complex is just an set
-- with realization the identity map
⟨Set , λA, trunctype.carrier A⟩
(λn fdcc_family_n, -- sigma.rec (λ fdcc_n realize_n,
/- a (succ n)-dimensional cell complex is a triple of
an n-dimensional cell complex X, an set of (succ n)-cells A,
and an attaching map f : A × sphere n → |X| -/
⟨Σ X : pr1 fdcc_family_n , Σ A : Set, A × sphere n → pr2 fdcc_family_n X ,
/- the realization of such is the pushout of f with
canonical map A × sphere n → unit -/
sigma.rec (λX , sigma.rec (λA f, pushout (λx , star) f))
⟩)
definition fdcc (n : ) : Type := pr1 (fdcc_family n)
definition cell : Πn, fdcc n → Set :=
nat.cases (λA, A) (λn T, pr1 (pr2 T))
end cellcomplex

View file

@ -1,547 +0,0 @@
/-
Copyright (c) 2016 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
Chain complexes.
We define chain complexes in a general way as a sequence X of types indexes over an arbitrary type
N with a successor S. There are maps X (S n) → X n for n : N. We can vary N to have chain complexes
indexed by , , a finite type or something else, and for both and we can choose the maps to
go up or down. We also use the indexing × 3 for the LES of homotopy groups, because then it
computes better (see [LES_of_homotopy_groups]).
We have two separate notions of
chain complexes:
- type_chain_complex: sequence of types, where exactness is formulated using pure existence.
- chain_complex: sequence of sets, where exactness is formulated using mere existence.
-/
import types.int algebra.group_theory types.fin types.unit
open eq pointed int unit is_equiv equiv is_trunc trunc function algebra group sigma.ops
sum prod nat bool fin
structure succ_str : Type :=
(carrier : Type)
(succ : carrier → carrier)
attribute succ_str.carrier [coercion]
definition succ_str.S {X : succ_str} : X → X := succ_str.succ X
open succ_str
definition snat [reducible] [constructor] : succ_str := succ_str.mk nat.succ
definition snat' [reducible] [constructor] : succ_str := succ_str.mk nat.pred
definition sint [reducible] [constructor] : succ_str := succ_str.mk int.succ
definition sint' [reducible] [constructor] : succ_str := succ_str.mk int.pred
notation `+` := snat
notation `-` := snat'
notation `+` := sint
notation `-` := sint'
definition stratified_type [reducible] (N : succ_str) (n : ) : Type₀ := N × fin (succ n)
definition stratified_succ {N : succ_str} {n : } (x : stratified_type N n)
: stratified_type N n :=
(if val (pr2 x) = n then S (pr1 x) else pr1 x, cyclic_succ (pr2 x))
definition stratified [reducible] [constructor] (N : succ_str) (n : ) : succ_str :=
succ_str.mk (stratified_type N n) stratified_succ
notation `+3` := stratified + 2
notation `-3` := stratified - 2
notation `+3` := stratified + 2
notation `-3` := stratified - 2
notation `+6` := stratified + 5
notation `-6` := stratified - 5
notation `+6` := stratified + 5
notation `-6` := stratified - 5
namespace succ_str
protected definition add [reducible] {N : succ_str} (n : N) (k : ) : N :=
iterate S k n
infix ` +' `:65 := succ_str.add
definition add_succ {N : succ_str} (n : N) (k : ) : n +' (k + 1) = (S n) +' k :=
by induction k with k p; reflexivity; exact ap S p
end succ_str
namespace chain_complex
export [notation] succ_str
/-
We define "type chain complexes" which are chain complexes without the
"set"-requirement. Exactness is formulated without propositional truncation.
-/
structure type_chain_complex (N : succ_str) : Type :=
(car : N → Type*)
(fn : Π(n : N), car (S n) →* car n)
(is_chain_complex : Π(n : N) (x : car (S (S n))), fn n (fn (S n) x) = pt)
section
variables {N : succ_str} (X : type_chain_complex N) (n : N)
definition tcc_to_car [unfold 2] [coercion] := @type_chain_complex.car
definition tcc_to_fn [unfold 2] : X (S n) →* X n := type_chain_complex.fn X n
definition tcc_is_chain_complex [unfold 2]
: Π(x : X (S (S n))), tcc_to_fn X n (tcc_to_fn X (S n) x) = pt :=
type_chain_complex.is_chain_complex X n
-- important: these notions are shifted by one! (this is to avoid transports)
definition is_exact_at_t [reducible] /- X n -/ : Type :=
Π(x : X (S n)), tcc_to_fn X n x = pt → fiber (tcc_to_fn X (S n)) x
definition is_exact_t [reducible] /- X -/ : Type :=
Π(n : N), is_exact_at_t X n
-- A chain complex on + can be trivially extended to a chain complex on +
definition type_chain_complex_from_left (X : type_chain_complex +)
: type_chain_complex + :=
type_chain_complex.mk (int.rec X (λn, punit))
begin
intro n, fconstructor,
{ induction n with n n,
{ exact tcc_to_fn X n},
{ esimp, intro x, exact star}},
{ induction n with n n,
{ apply respect_pt},
{ reflexivity}}
end
begin
intro n, induction n with n n,
{ exact tcc_is_chain_complex X n},
{ esimp, intro x, reflexivity}
end
definition is_exact_t_from_left {X : type_chain_complex +} {n : }
(H : is_exact_at_t X n)
: is_exact_at_t (type_chain_complex_from_left X) (of_nat n) :=
H
/-
Given a natural isomorphism between a chain complex and any other sequence,
we can give the other sequence the structure of a chain complex, which is exact at the
positions where the original sequence is.
-/
definition transfer_type_chain_complex [constructor] /- X -/
{Y : N → Type*} (g : Π{n : N}, Y (S n) →* Y n) (e : Π{n}, X n ≃* Y n)
(p : Π{n} (x : X (S n)), e (tcc_to_fn X n x) = g (e x)) : type_chain_complex N :=
type_chain_complex.mk Y @g
abstract begin
intro n, apply equiv_rect (equiv_of_pequiv e), intro x,
refine ap g (p x)⁻¹ ⬝ _,
refine (p _)⁻¹ ⬝ _,
refine ap e (tcc_is_chain_complex X n _) ⬝ _,
apply respect_pt
end end
theorem is_exact_at_t_transfer {X : type_chain_complex N} {Y : N → Type*}
{g : Π{n : N}, Y (S n) →* Y n} (e : Π{n}, X n ≃* Y n)
(p : Π{n} (x : X (S n)), e (tcc_to_fn X n x) = g (e x)) {n : N}
(H : is_exact_at_t X n) : is_exact_at_t (transfer_type_chain_complex X @g @e @p) n :=
begin
intro y q, esimp at *,
have H2 : tcc_to_fn X n (e⁻¹ᵉ* y) = pt,
begin
refine (inv_commute (λn, equiv_of_pequiv e) _ _ @p _)⁻¹ᵖ ⬝ _,
refine ap _ q ⬝ _,
exact respect_pt e⁻¹ᵉ*
end,
cases (H _ H2) with x r,
refine fiber.mk (e x) _,
refine (p x)⁻¹ ⬝ _,
refine ap e r ⬝ _,
apply right_inv
end
/-
We want a theorem which states that if we have a chain complex, but with some
where the maps are composed by an equivalences, we want to remove this equivalence.
The following two theorems give sufficient conditions for when this is allowed.
We use this to transform the LES of homotopy groups where on the odd levels we have
maps -πₙ(...) into the LES of homotopy groups where we remove the minus signs (which
represents composition with path inversion).
-/
definition type_chain_complex_cancel_aut [constructor] /- X -/
(g : Π{n : N}, X (S n) →* X n) (e : Π{n}, X n ≃* X n)
(r : Π{n}, X n →* X n)
(p : Π{n : N} (x : X (S n)), g (e x) = tcc_to_fn X n x)
(pr : Π{n : N} (x : X (S n)), g x = r (g (e x))) : type_chain_complex N :=
type_chain_complex.mk X @g
abstract begin
have p' : Π{n : N} (x : X (S n)), g x = tcc_to_fn X n (e⁻¹ x),
from λn, homotopy_inv_of_homotopy_pre e _ _ p,
intro n x,
refine ap g !p' ⬝ !pr ⬝ _,
refine ap r !p ⬝ _,
refine ap r (tcc_is_chain_complex X n _) ⬝ _,
apply respect_pt
end end
theorem is_exact_at_t_cancel_aut {X : type_chain_complex N}
{g : Π{n : N}, X (S n) →* X n} {e : Π{n}, X n ≃* X n}
{r : Π{n}, X n →* X n} (l : Π{n}, X n →* X n)
(p : Π{n : N} (x : X (S n)), g (e x) = tcc_to_fn X n x)
(pr : Π{n : N} (x : X (S n)), g x = r (g (e x)))
(pl : Π{n : N} (x : X (S n)), g (l x) = e (g x))
(H : is_exact_at_t X n) : is_exact_at_t (type_chain_complex_cancel_aut X @g @e @r @p @pr) n :=
begin
intro y q, esimp at *,
have H2 : tcc_to_fn X n (e⁻¹ y) = pt,
from (homotopy_inv_of_homotopy_pre e _ _ p _)⁻¹ ⬝ q,
cases (H _ H2) with x s,
refine fiber.mk (l (e x)) _,
refine !pl ⬝ _,
refine ap e (!p ⬝ s) ⬝ _,
apply right_inv
end
/-
A more general transfer theorem.
Here the base type can also change by an equivalence.
-/
definition transfer_type_chain_complex2 [constructor] {M : succ_str} {Y : M → Type*}
(f : M ≃ N) (c : Π(m : M), S (f m) = f (S m))
(g : Π{m : M}, Y (S m) →* Y m) (e : Π{m}, X (f m) ≃* Y m)
(p : Π{m} (x : X (S (f m))), e (tcc_to_fn X (f m) x) = g (e (cast (ap (λx, X x) (c m)) x)))
: type_chain_complex M :=
type_chain_complex.mk Y @g
begin
intro m,
apply equiv_rect (equiv_of_pequiv e),
apply equiv_rect (equiv_of_eq (ap (λx, X x) (c (S m)))), esimp,
apply equiv_rect (equiv_of_eq (ap (λx, X (S x)) (c m))), esimp,
intro x, refine ap g (p _)⁻¹ ⬝ _,
refine ap g (ap e (fn_cast_eq_cast_fn (c m) (tcc_to_fn X) x)) ⬝ _,
refine (p _)⁻¹ ⬝ _,
refine ap e (tcc_is_chain_complex X (f m) _) ⬝ _,
apply respect_pt
end
definition is_exact_at_t_transfer2 {X : type_chain_complex N} {M : succ_str} {Y : M → Type*}
(f : M ≃ N) (c : Π(m : M), S (f m) = f (S m))
(g : Π{m : M}, Y (S m) →* Y m) (e : Π{m}, X (f m) ≃* Y m)
(p : Π{m} (x : X (S (f m))), e (tcc_to_fn X (f m) x) = g (e (cast (ap (λx, X x) (c m)) x)))
{m : M} (H : is_exact_at_t X (f m))
: is_exact_at_t (transfer_type_chain_complex2 X f c @g @e @p) m :=
begin
intro y q, esimp at *,
have H2 : tcc_to_fn X (f m) ((equiv_of_eq (ap (λx, X x) (c m)))⁻¹ᵉ (e⁻¹ y)) = pt,
begin
refine _ ⬝ ap e⁻¹ᵉ* q ⬝ (respect_pt (e⁻¹ᵉ*)), apply eq_inv_of_eq, clear q, revert y,
apply inv_homotopy_of_homotopy_pre e,
apply inv_homotopy_of_homotopy_pre, apply p
end,
induction (H _ H2) with x r,
refine fiber.mk (e (cast (ap (λx, X x) (c (S m))) (cast (ap (λx, X (S x)) (c m)) x))) _,
refine (p _)⁻¹ ⬝ _,
refine ap e (fn_cast_eq_cast_fn (c m) (tcc_to_fn X) x) ⬝ _,
refine ap (λx, e (cast _ x)) r ⬝ _,
esimp [equiv.symm], rewrite [-ap_inv],
refine ap e !cast_cast_inv ⬝ _,
apply right_inv
end
end
/- actual (set) chain complexes -/
structure chain_complex (N : succ_str) : Type :=
(car : N → Set*)
(fn : Π(n : N), car (S n) →* car n)
(is_chain_complex : Π(n : N) (x : car (S (S n))), fn n (fn (S n) x) = pt)
section
variables {N : succ_str} (X : chain_complex N) (n : N)
definition cc_to_car [unfold 2] [coercion] := @chain_complex.car
definition cc_to_fn [unfold 2] : X (S n) →* X n := @chain_complex.fn N X n
definition cc_is_chain_complex [unfold 2]
: Π(x : X (S (S n))), cc_to_fn X n (cc_to_fn X (S n) x) = pt :=
@chain_complex.is_chain_complex N X n
-- important: these notions are shifted by one! (this is to avoid transports)
definition is_exact_at [reducible] /- X n -/ : Type :=
Π(x : X (S n)), cc_to_fn X n x = pt → image (cc_to_fn X (S n)) x
definition is_exact [reducible] /- X -/ : Type := Π(n : N), is_exact_at X n
definition chain_complex_from_left (X : chain_complex +) : chain_complex + :=
chain_complex.mk (int.rec X (λn, punit))
begin
intro n, fconstructor,
{ induction n with n n,
{ exact cc_to_fn X n},
{ esimp, intro x, exact star}},
{ induction n with n n,
{ apply respect_pt},
{ reflexivity}}
end
begin
intro n, induction n with n n,
{ exact cc_is_chain_complex X n},
{ esimp, intro x, reflexivity}
end
definition is_exact_from_left {X : chain_complex +} {n : } (H : is_exact_at X n)
: is_exact_at (chain_complex_from_left X) (of_nat n) :=
H
definition transfer_chain_complex [constructor] {Y : N → Set*}
(g : Π{n : N}, Y (S n) →* Y n) (e : Π{n}, X n ≃* Y n)
(p : Π{n} (x : X (S n)), e (cc_to_fn X n x) = g (e x)) : chain_complex N :=
chain_complex.mk Y @g
abstract begin
intro n, apply equiv_rect (equiv_of_pequiv e), intro x,
refine ap g (p x)⁻¹ ⬝ _,
refine (p _)⁻¹ ⬝ _,
refine ap e (cc_is_chain_complex X n _) ⬝ _,
apply respect_pt
end end
theorem is_exact_at_transfer {X : chain_complex N} {Y : N → Set*}
(g : Π{n : N}, Y (S n) →* Y n) (e : Π{n}, X n ≃* Y n)
(p : Π{n} (x : X (S n)), e (cc_to_fn X n x) = g (e x))
{n : N} (H : is_exact_at X n) : is_exact_at (transfer_chain_complex X @g @e @p) n :=
begin
intro y q, esimp at *,
have H2 : cc_to_fn X n (e⁻¹ᵉ* y) = pt,
begin
refine (inv_commute (λn, equiv_of_pequiv e) _ _ @p _)⁻¹ᵖ ⬝ _,
refine ap _ q ⬝ _,
exact respect_pt e⁻¹ᵉ*
end,
induction (H _ H2) with x r,
refine image.mk (e x) _,
refine (p x)⁻¹ ⬝ _,
refine ap e r ⬝ _,
apply right_inv
end
/- A type chain complex can be set-truncated to a chain complex -/
definition trunc_chain_complex [constructor] (X : type_chain_complex N)
: chain_complex N :=
chain_complex.mk
(λn, ptrunc 0 (X n))
(λn, ptrunc_functor 0 (tcc_to_fn X n))
begin
intro n x, esimp at *,
refine @trunc.rec _ _ _ (λH, !is_trunc_eq) _ x,
clear x, intro x, esimp,
exact ap tr (tcc_is_chain_complex X n x)
end
definition is_exact_at_trunc (X : type_chain_complex N) {n : N}
(H : is_exact_at_t X n) : is_exact_at (trunc_chain_complex X) n :=
begin
intro x p, esimp at *,
induction x with x, esimp at *,
note q := !tr_eq_tr_equiv p,
induction q with q,
induction H x q with y r,
refine image.mk (tr y) _,
esimp, exact ap tr r
end
definition transfer_chain_complex2 [constructor] {M : succ_str} {Y : M → Set*}
(f : N ≃ M) (c : Π(n : N), f (S n) = S (f n))
(g : Π{m : M}, Y (S m) →* Y m) (e : Π{n}, X n ≃* Y (f n))
(p : Π{n} (x : X (S n)), e (cc_to_fn X n x) = g (c n ▸ e x)) : chain_complex M :=
chain_complex.mk Y @g
begin
refine equiv_rect f _ _, intro n,
have H : Π (x : Y (f (S (S n)))), g (c n ▸ g (c (S n) ▸ x)) = pt,
begin
apply equiv_rect (equiv_of_pequiv e), intro x,
refine ap (λx, g (c n ▸ x)) (@p (S n) x)⁻¹ᵖ ⬝ _,
refine (p _)⁻¹ ⬝ _,
refine ap e (cc_is_chain_complex X n _) ⬝ _,
apply respect_pt
end,
refine pi.pi_functor _ _ H,
{ intro x, exact (c (S n))⁻¹ ▸ (c n)⁻¹ ▸ x}, -- with implicit arguments, this is:
-- transport (λx, Y x) (c (S n))⁻¹ (transport (λx, Y (S x)) (c n)⁻¹ x)
{ intro x, intro p, refine _ ⬝ p, rewrite [tr_inv_tr, fn_tr_eq_tr_fn (c n)⁻¹ @g, tr_inv_tr]}
end
definition is_exact_at_transfer2 {X : chain_complex N} {M : succ_str} {Y : M → Set*}
(f : N ≃ M) (c : Π(n : N), f (S n) = S (f n))
(g : Π{m : M}, Y (S m) →* Y m) (e : Π{n}, X n ≃* Y (f n))
(p : Π{n} (x : X (S n)), e (cc_to_fn X n x) = g (c n ▸ e x))
{n : N} (H : is_exact_at X n) : is_exact_at (transfer_chain_complex2 X f c @g @e @p) (f n) :=
begin
intro y q, esimp at *,
have H2 : cc_to_fn X n (e⁻¹ᵉ* ((c n)⁻¹ ▸ y)) = pt,
begin
refine (inv_commute (λn, equiv_of_pequiv e) _ _ @p _)⁻¹ᵖ ⬝ _,
rewrite [tr_inv_tr, q],
exact respect_pt e⁻¹ᵉ*
end,
induction (H _ H2) with x r,
refine image.mk (c n ▸ c (S n) ▸ e x) _,
rewrite [fn_tr_eq_tr_fn (c n) @g],
refine ap (λx, c n ▸ x) (p x)⁻¹ ⬝ _,
refine ap (λx, c n ▸ e x) r ⬝ _,
refine ap (λx, c n ▸ x) !right_inv ⬝ _,
apply tr_inv_tr,
end
/-
This is a start of a development of chain complexes consisting only on groups.
This might be useful to have in stable algebraic topology, but in the unstable case it's less
useful, since the smallest terms usually don't have a group structure.
We don't use it yet, so it's commented out for now
-/
-- structure group_chain_complex : Type :=
-- (car : N → Group)
-- (fn : Π(n : N), car (S n) →g car n)
-- (is_chain_complex : Π{n : N} (x : car ((S n) + 1)), fn n (fn (S n) x) = 1)
-- structure group_chain_complex : Type := -- chain complex on the naturals with maps going down
-- (car : N → Group)
-- (fn : Π(n : N), car (S n) →g car n)
-- (is_chain_complex : Π{n : N} (x : car ((S n) + 1)), fn n (fn (S n) x) = 1)
-- structure right_group_chain_complex : Type := -- chain complex on the naturals with maps going up
-- (car : N → Group)
-- (fn : Π(n : N), car n →g car (S n))
-- (is_chain_complex : Π{n : N} (x : car n), fn (S n) (fn n x) = 1)
-- definition gcc_to_car [unfold 1] [coercion] := @group_chain_complex.car
-- definition gcc_to_fn [unfold 1] := @group_chain_complex.fn
-- definition gcc_is_chain_complex [unfold 1] := @group_chain_complex.is_chain_complex
-- definition lgcc_to_car [unfold 1] [coercion] := @left_group_chain_complex.car
-- definition lgcc_to_fn [unfold 1] := @left_group_chain_complex.fn
-- definition lgcc_is_chain_complex [unfold 1] := @left_group_chain_complex.is_chain_complex
-- definition rgcc_to_car [unfold 1] [coercion] := @right_group_chain_complex.car
-- definition rgcc_to_fn [unfold 1] := @right_group_chain_complex.fn
-- definition rgcc_is_chain_complex [unfold 1] := @right_group_chain_complex.is_chain_complex
-- -- important: these notions are shifted by one! (this is to avoid transports)
-- definition is_exact_at_g [reducible] (X : group_chain_complex) (n : N) : Type :=
-- Π(x : X (S n)), gcc_to_fn X n x = 1 → image (gcc_to_fn X (S n)) x
-- definition is_exact_at_lg [reducible] (X : left_group_chain_complex) (n : N) : Type :=
-- Π(x : X (S n)), lgcc_to_fn X n x = 1 → image (lgcc_to_fn X (S n)) x
-- definition is_exact_at_rg [reducible] (X : right_group_chain_complex) (n : N) : Type :=
-- Π(x : X (S n)), rgcc_to_fn X (S n) x = 1 → image (rgcc_to_fn X n) x
-- definition is_exact_g [reducible] (X : group_chain_complex) : Type :=
-- Π(n : N), is_exact_at_g X n
-- definition is_exact_lg [reducible] (X : left_group_chain_complex) : Type :=
-- Π(n : N), is_exact_at_lg X n
-- definition is_exact_rg [reducible] (X : right_group_chain_complex) : Type :=
-- Π(n : N), is_exact_at_rg X n
-- definition group_chain_complex_from_left (X : left_group_chain_complex) : group_chain_complex :=
-- group_chain_complex.mk (int.rec X (λn, G0))
-- begin
-- intro n, fconstructor,
-- { induction n with n n,
-- { exact @lgcc_to_fn X n},
-- { esimp, intro x, exact star}},
-- { induction n with n n,
-- { apply respect_mul},
-- { intro g h, reflexivity}}
-- end
-- begin
-- intro n, induction n with n n,
-- { exact lgcc_is_chain_complex X},
-- { esimp, intro x, reflexivity}
-- end
-- definition is_exact_g_from_left {X : left_group_chain_complex} {n : N} (H : is_exact_at_lg X n)
-- : is_exact_at_g (group_chain_complex_from_left X) n :=
-- H
-- definition transfer_left_group_chain_complex [constructor] (X : left_group_chain_complex)
-- {Y : N → Group} (g : Π{n : N}, Y (S n) →g Y n) (e : Π{n}, X n ≃* Y n)
-- (p : Π{n} (x : X (S n)), e (lgcc_to_fn X n x) = g (e x)) : left_group_chain_complex :=
-- left_group_chain_complex.mk Y @g
-- begin
-- intro n, apply equiv_rect (pequiv_of_equiv e), intro x,
-- refine ap g (p x)⁻¹ ⬝ _,
-- refine (p _)⁻¹ ⬝ _,
-- refine ap e (lgcc_is_chain_complex X _) ⬝ _,
-- exact respect_pt
-- end
-- definition is_exact_at_t_transfer {X : left_group_chain_complex} {Y : N → Type*}
-- {g : Π{n : N}, Y (S n) →* Y n} (e : Π{n}, X n ≃* Y n)
-- (p : Π{n} (x : X (S n)), e (lgcc_to_fn X n x) = g (e x)) {n : N}
-- (H : is_exact_at_lg X n) : is_exact_at_lg (transfer_left_group_chain_complex X @g @e @p) n :=
-- begin
-- intro y q, esimp at *,
-- have H2 : lgcc_to_fn X n (e⁻¹ᵉ* y) = pt,
-- begin
-- refine (inv_commute (λn, equiv_of_pequiv e) _ _ @p _)⁻¹ᵖ ⬝ _,
-- refine ap _ q ⬝ _,
-- exact respect_pt e⁻¹ᵉ*
-- end,
-- cases (H _ H2) with x r,
-- refine image.mk (e x) _,
-- refine (p x)⁻¹ ⬝ _,
-- refine ap e r ⬝ _,
-- apply right_inv
-- end
/-
The following theorems state that in a chain complex, if certain types are contractible, and
the chain complex is exact at the right spots, a map in the chain complex is an
embedding/surjection/equivalence. For the first and third we also need to assume that
the map is a group homomorphism (and hence that the two types around it are groups).
-/
definition is_embedding_of_trivial (X : chain_complex N) {n : N}
(H : is_exact_at X n) [HX : is_contr (X (S (S n)))]
[pgroup (X n)] [pgroup (X (S n))] [is_mul_hom (cc_to_fn X n)]
: is_embedding (cc_to_fn X n) :=
begin
apply is_embedding_of_is_mul_hom,
intro g p,
induction H g p with x q,
have r : pt = x, from !is_prop.elim,
induction r,
refine q⁻¹ ⬝ _,
apply respect_pt
end
definition is_surjective_of_trivial (X : chain_complex N) {n : N}
(H : is_exact_at X n) [HX : is_contr (X n)] : is_surjective (cc_to_fn X (S n)) :=
begin
intro g,
refine trunc.elim _ (H g !is_prop.elim),
apply tr
end
definition is_equiv_of_trivial (X : chain_complex N) {n : N}
(H1 : is_exact_at X n) (H2 : is_exact_at X (S n))
[HX1 : is_contr (X n)] [HX2 : is_contr (X (S (S (S n))))]
[pgroup (X (S n))] [pgroup (X (S (S n)))] [is_mul_hom (cc_to_fn X (S n))]
: is_equiv (cc_to_fn X (S n)) :=
begin
apply is_equiv_of_is_surjective_of_is_embedding,
{ apply is_embedding_of_trivial X, apply H2},
{ apply is_surjective_of_trivial X, apply H1},
end
definition is_contr_of_is_embedding_of_is_surjective {N : succ_str} (X : chain_complex N) {n : N}
(H : is_exact_at X (S n)) [is_embedding (cc_to_fn X n)]
[H2 : is_surjective (cc_to_fn X (S (S (S n))))] : is_contr (X (S (S n))) :=
begin
apply is_contr.mk pt, intro x,
have p : cc_to_fn X n (cc_to_fn X (S n) x) = cc_to_fn X n pt,
from !cc_is_chain_complex ⬝ !respect_pt⁻¹,
have q : cc_to_fn X (S n) x = pt, from is_injective_of_is_embedding p,
induction H x q with y r,
induction H2 y with z s,
exact (cc_is_chain_complex X _ z)⁻¹ ⬝ ap (cc_to_fn X _) s ⬝ r
end
end
end chain_complex

View file

@ -1,356 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
Declaration of the circle
-/
import .sphere
import types.int.hott
import algebra.homotopy_group .connectedness
open eq susp bool sphere_index is_equiv equiv is_trunc is_conn pi algebra pointed
definition circle : Type₀ := sphere 1
namespace circle
notation `S¹` := circle
definition base1 : S¹ := !north
definition base2 : S¹ := !south
definition seg1 : base1 = base2 := merid !north
definition seg2 : base1 = base2 := merid !south
definition base : S¹ := base1
definition loop : base = base := seg2 ⬝ seg1⁻¹
definition rec2 {P : S¹ → Type} (Pb1 : P base1) (Pb2 : P base2)
(Ps1 : Pb1 =[seg1] Pb2) (Ps2 : Pb1 =[seg2] Pb2) (x : S¹) : P x :=
begin
induction x with b,
{ exact Pb1},
{ exact Pb2},
{ esimp at *, induction b with y,
{ exact Ps1},
{ exact Ps2},
{ cases y}},
end
definition rec2_on [reducible] {P : S¹ → Type} (x : S¹) (Pb1 : P base1) (Pb2 : P base2)
(Ps1 : Pb1 =[seg1] Pb2) (Ps2 : Pb1 =[seg2] Pb2) : P x :=
circle.rec2 Pb1 Pb2 Ps1 Ps2 x
theorem rec2_seg1 {P : S¹ → Type} (Pb1 : P base1) (Pb2 : P base2)
(Ps1 : Pb1 =[seg1] Pb2) (Ps2 : Pb1 =[seg2] Pb2)
: apd (rec2 Pb1 Pb2 Ps1 Ps2) seg1 = Ps1 :=
!rec_merid
theorem rec2_seg2 {P : S¹ → Type} (Pb1 : P base1) (Pb2 : P base2)
(Ps1 : Pb1 =[seg1] Pb2) (Ps2 : Pb1 =[seg2] Pb2)
: apd (rec2 Pb1 Pb2 Ps1 Ps2) seg2 = Ps2 :=
!rec_merid
definition elim2 {P : Type} (Pb1 Pb2 : P) (Ps1 Ps2 : Pb1 = Pb2) (x : S¹) : P :=
rec2 Pb1 Pb2 (pathover_of_eq _ Ps1) (pathover_of_eq _ Ps2) x
definition elim2_on [reducible] {P : Type} (x : S¹) (Pb1 Pb2 : P)
(Ps1 : Pb1 = Pb2) (Ps2 : Pb1 = Pb2) : P :=
elim2 Pb1 Pb2 Ps1 Ps2 x
theorem elim2_seg1 {P : Type} (Pb1 Pb2 : P) (Ps1 : Pb1 = Pb2) (Ps2 : Pb1 = Pb2)
: ap (elim2 Pb1 Pb2 Ps1 Ps2) seg1 = Ps1 :=
begin
apply eq_of_fn_eq_fn_inv !(pathover_constant seg1),
rewrite [▸*,-apd_eq_pathover_of_eq_ap,↑elim2,rec2_seg1],
end
theorem elim2_seg2 {P : Type} (Pb1 Pb2 : P) (Ps1 : Pb1 = Pb2) (Ps2 : Pb1 = Pb2)
: ap (elim2 Pb1 Pb2 Ps1 Ps2) seg2 = Ps2 :=
begin
apply eq_of_fn_eq_fn_inv !(pathover_constant seg2),
rewrite [▸*,-apd_eq_pathover_of_eq_ap,↑elim2,rec2_seg2],
end
definition elim2_type (Pb1 Pb2 : Type) (Ps1 Ps2 : Pb1 ≃ Pb2) (x : S¹) : Type :=
elim2 Pb1 Pb2 (ua Ps1) (ua Ps2) x
definition elim2_type_on [reducible] (x : S¹) (Pb1 Pb2 : Type) (Ps1 Ps2 : Pb1 ≃ Pb2)
: Type :=
elim2_type Pb1 Pb2 Ps1 Ps2 x
theorem elim2_type_seg1 (Pb1 Pb2 : Type) (Ps1 Ps2 : Pb1 ≃ Pb2)
: transport (elim2_type Pb1 Pb2 Ps1 Ps2) seg1 = Ps1 :=
by rewrite [tr_eq_cast_ap_fn,↑elim2_type,elim2_seg1];apply cast_ua_fn
theorem elim2_type_seg2 (Pb1 Pb2 : Type) (Ps1 Ps2 : Pb1 ≃ Pb2)
: transport (elim2_type Pb1 Pb2 Ps1 Ps2) seg2 = Ps2 :=
by rewrite [tr_eq_cast_ap_fn,↑elim2_type,elim2_seg2];apply cast_ua_fn
protected definition rec {P : S¹ → Type} (Pbase : P base) (Ploop : Pbase =[loop] Pbase)
(x : S¹) : P x :=
begin
fapply (rec2_on x),
{ exact Pbase},
{ exact (transport P seg1 Pbase)},
{ apply pathover_tr},
{ apply pathover_tr_of_pathover, exact Ploop}
end
protected definition rec_on [reducible] {P : S¹ → Type} (x : S¹) (Pbase : P base)
(Ploop : Pbase =[loop] Pbase) : P x :=
circle.rec Pbase Ploop x
theorem rec_loop_helper {A : Type} (P : A → Type)
{x y z : A} {p : x = y} {p' : z = y} {u : P x} {v : P z} (q : u =[p ⬝ p'⁻¹] v) :
pathover_tr_of_pathover q ⬝o !pathover_tr⁻¹ᵒ = q :=
by cases p'; cases q; exact idp
definition con_refl {A : Type} {x y : A} (p : x = y) : p ⬝ refl _ = p :=
eq.rec_on p idp
theorem rec_loop {P : S¹ → Type} (Pbase : P base) (Ploop : Pbase =[loop] Pbase) :
apd (circle.rec Pbase Ploop) loop = Ploop :=
begin
rewrite [↑loop,apd_con,↑circle.rec,↑circle.rec2_on,↑base,rec2_seg2,apd_inv,rec2_seg1],
apply rec_loop_helper
end
protected definition elim {P : Type} (Pbase : P) (Ploop : Pbase = Pbase)
(x : S¹) : P :=
circle.rec Pbase (pathover_of_eq _ Ploop) x
protected definition elim_on [reducible] {P : Type} (x : S¹) (Pbase : P)
(Ploop : Pbase = Pbase) : P :=
circle.elim Pbase Ploop x
theorem elim_loop {P : Type} (Pbase : P) (Ploop : Pbase = Pbase) :
ap (circle.elim Pbase Ploop) loop = Ploop :=
begin
apply eq_of_fn_eq_fn_inv !(pathover_constant loop),
rewrite [▸*,-apd_eq_pathover_of_eq_ap,↑circle.elim,rec_loop],
end
theorem elim_seg1 {P : Type} (Pbase : P) (Ploop : Pbase = Pbase)
: ap (circle.elim Pbase Ploop) seg1 = (tr_constant seg1 Pbase)⁻¹ :=
begin
apply eq_of_fn_eq_fn_inv !(pathover_constant seg1),
rewrite [▸*,-apd_eq_pathover_of_eq_ap,↑circle.elim,↑circle.rec],
rewrite [↑circle.rec2_on,rec2_seg1], apply inverse,
apply pathover_of_eq_tr_constant_inv
end
theorem elim_seg2 {P : Type} (Pbase : P) (Ploop : Pbase = Pbase)
: ap (circle.elim Pbase Ploop) seg2 = Ploop ⬝ (tr_constant seg1 Pbase)⁻¹ :=
begin
apply eq_of_fn_eq_fn_inv !(pathover_constant seg2),
rewrite [▸*,-apd_eq_pathover_of_eq_ap,↑circle.elim,↑circle.rec],
rewrite [↑circle.rec2_on,rec2_seg2],
assert l : Π(A B : Type)(a a₂ a₂' : A)(b b' : B)(p : a = a₂)(p' : a₂' = a₂)
(q : b = b'),
pathover_tr_of_pathover (pathover_of_eq _ q)
= pathover_of_eq _ (q ⬝ (tr_constant p' b')⁻¹)
:> b =[p] p' ▸ b',
{ intros, cases q, cases p', cases p, reflexivity },
apply l
end
protected definition elim_type (Pbase : Type) (Ploop : Pbase ≃ Pbase)
(x : S¹) : Type :=
circle.elim Pbase (ua Ploop) x
protected definition elim_type_on [reducible] (x : S¹) (Pbase : Type)
(Ploop : Pbase ≃ Pbase) : Type :=
circle.elim_type Pbase Ploop x
theorem elim_type_loop (Pbase : Type) (Ploop : Pbase ≃ Pbase) :
transport (circle.elim_type Pbase Ploop) loop = Ploop :=
by rewrite [tr_eq_cast_ap_fn,↑circle.elim_type,elim_loop];apply cast_ua_fn
theorem elim_type_loop_inv (Pbase : Type) (Ploop : Pbase ≃ Pbase) :
transport (circle.elim_type Pbase Ploop) loop⁻¹ = to_inv Ploop :=
by rewrite [tr_inv_fn]; apply inv_eq_inv; apply elim_type_loop
end circle
attribute circle.base1 circle.base2 circle.base [constructor]
attribute circle.rec2 circle.elim2 [unfold 6] [recursor 6]
attribute circle.elim2_type [unfold 5]
attribute circle.rec2_on circle.elim2_on [unfold 2]
attribute circle.elim2_type [unfold 1]
attribute circle.rec circle.elim [unfold 4] [recursor 4]
attribute circle.elim_type [unfold 3]
attribute circle.rec_on circle.elim_on [unfold 2]
attribute circle.elim_type_on [unfold 1]
namespace circle
open sigma
/- universal property of the circle -/
definition circle_pi_equiv [constructor] (P : S¹ → Type)
: (Π(x : S¹), P x) ≃ Σ(p : P base), p =[loop] p :=
begin
fapply equiv.MK,
{ intro f, exact ⟨f base, apd f loop⟩},
{ intro v x, induction v with p q, induction x,
{ exact p},
{ exact q}},
{ intro v, induction v with p q, fapply sigma_eq,
{ reflexivity},
{ esimp, apply pathover_idp_of_eq, apply rec_loop}},
{ intro f, apply eq_of_homotopy, intro x, induction x,
{ reflexivity},
{ apply eq_pathover_dep, apply hdeg_squareover, esimp, apply rec_loop}}
end
definition circle_arrow_equiv [constructor] (P : Type)
: (S¹ → P) ≃ Σ(p : P), p = p :=
begin
fapply equiv.MK,
{ intro f, exact ⟨f base, ap f loop⟩},
{ intro v x, induction v with p q, induction x,
{ exact p},
{ exact q}},
{ intro v, induction v with p q, fapply sigma_eq,
{ reflexivity},
{ esimp, apply pathover_idp_of_eq, apply elim_loop}},
{ intro f, apply eq_of_homotopy, intro x, induction x,
{ reflexivity},
{ apply eq_pathover, apply hdeg_square, esimp, apply elim_loop}}
end
definition pointed_circle [instance] [constructor] : pointed S¹ :=
pointed.mk base
definition pcircle [constructor] : Type* := pointed.mk' S¹
notation `S¹*` := pcircle
definition loop_neq_idp : loop ≠ idp :=
assume H : loop = idp,
have H2 : Π{A : Type₁} {a : A} {p : a = a}, p = idp,
from λA a p, calc
p = ap (circle.elim a p) loop : elim_loop
... = ap (circle.elim a p) (refl base) : by rewrite H,
eq_bnot_ne_idp H2
definition circle_turn [reducible] (x : S¹) : x = x :=
begin
induction x,
{ exact loop },
{ apply eq_pathover, apply square_of_eq, rewrite ap_id }
end
definition turn_neq_idp : circle_turn ≠ (λx, idp) :=
assume H : circle_turn = λx, idp,
have H2 : loop = idp, from apd10 H base,
absurd H2 loop_neq_idp
open int
protected definition code [unfold 1] (x : S¹) : Type₀ :=
circle.elim_type_on x equiv_succ
definition transport_code_loop (a : ) : transport circle.code loop a = succ a :=
ap10 !elim_type_loop a
definition transport_code_loop_inv (a : ) : transport circle.code loop⁻¹ a = pred a :=
ap10 !elim_type_loop_inv a
protected definition encode [unfold 2] {x : S¹} (p : base = x) : circle.code x :=
transport circle.code p (0 : )
protected definition decode [unfold 1] {x : S¹} : circle.code x → base = x :=
begin
induction x,
{ exact power loop},
{ apply arrow_pathover_left, intro b, apply eq_pathover_constant_left_id_right,
apply square_of_eq, rewrite [idp_con, power_con,transport_code_loop]}
end
definition circle_eq_equiv [constructor] (x : S¹) : (base = x) ≃ circle.code x :=
begin
fapply equiv.MK,
{ exact circle.encode},
{ exact circle.decode},
{ exact abstract [irreducible] begin
induction x,
{ intro a, esimp, apply rec_nat_on a,
{ exact idp},
{ intros n p, rewrite [↑circle.encode, -power_con, con_tr, transport_code_loop],
exact ap succ p},
{ intros n p, rewrite [↑circle.encode, nat_succ_eq_int_succ, neg_succ, -power_con_inv,
@con_tr _ circle.code, transport_code_loop_inv, ↑[circle.encode] at p, p, -neg_succ] }},
{ apply pathover_of_tr_eq, apply eq_of_homotopy, intro a, apply @is_set.elim,
esimp, exact _} end end},
{ intro p, cases p, exact idp},
end
definition base_eq_base_equiv [constructor] : base = base ≃ :=
circle_eq_equiv base
definition decode_add (a b : ) : circle.decode (a +[] b) = circle.decode a ⬝ circle.decode b :=
!power_con_power⁻¹
definition encode_con (p q : base = base)
: circle.encode (p ⬝ q) = circle.encode p +[] circle.encode q :=
preserve_binary_of_inv_preserve base_eq_base_equiv concat (@add _) decode_add p q
--the carrier of π₁(S¹) is the set-truncation of base = base.
open algebra trunc group
definition fg_carrier_equiv_int : π[1](S¹*) ≃ :=
trunc_equiv_trunc 0 base_eq_base_equiv ⬝e @(trunc_equiv 0 ) proof _ qed
definition con_comm_base (p q : base = base) : p ⬝ q = q ⬝ p :=
eq_of_fn_eq_fn base_eq_base_equiv (by esimp;rewrite [+encode_con,add.comm])
definition fundamental_group_of_circle : π₁(S¹*) ≃g g :=
begin
apply (isomorphism_of_equiv fg_carrier_equiv_int),
intros g h,
induction g with g', induction h with h',
apply encode_con,
end
open nat
definition homotopy_group_of_circle (n : ) : πg[n+2] S¹* ≃g G0 :=
begin
refine @trivial_homotopy_add_of_is_set_loopn S¹* 1 n _,
apply is_trunc_equiv_closed_rev, apply base_eq_base_equiv
end
definition eq_equiv_Z (x : S¹) : x = x ≃ :=
begin
induction x,
{ apply base_eq_base_equiv},
{ apply equiv_pathover, intro p p' q, apply pathover_of_eq,
note H := eq_of_square (square_of_pathover q),
rewrite con_comm_base at H,
note H' := cancel_left _ H,
induction H', reflexivity}
end
proposition is_trunc_circle [instance] : is_trunc 1 S¹ :=
begin
apply is_trunc_succ_of_is_trunc_loop,
{ apply trunc_index.minus_one_le_succ},
{ intro x, apply is_trunc_equiv_closed_rev, apply eq_equiv_Z}
end
proposition is_conn_circle [instance] : is_conn 0 S¹ :=
sphere.is_conn_sphere -1.+2
definition is_conn_pcircle [instance] : is_conn 0 S¹* := !is_conn_circle
definition is_trunc_pcircle [instance] : is_trunc 1 S¹* := !is_trunc_circle
definition circle_mul [reducible] (x y : S¹) : S¹ :=
circle.elim y (circle_turn y) x
definition circle_mul_base (x : S¹) : circle_mul x base = x :=
begin
induction x,
{ reflexivity },
{ apply eq_pathover_id_right, apply hdeg_square, apply elim_loop }
end
definition circle_base_mul [reducible] (x : S¹) : circle_mul base x = x :=
idp
end circle

View file

@ -1,100 +0,0 @@
/-
Copyright (c) 2016 Jakob von Raumer. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Jakob von Raumer
The Cofiber Type
-/
import hit.pushout function .susp types.unit
open eq pushout unit pointed is_trunc is_equiv susp unit equiv
definition cofiber {A B : Type} (f : A → B) := pushout (λ (a : A), ⋆) f
namespace cofiber
section
parameters {A B : Type} (f : A → B)
protected definition base : cofiber f := inl ⋆
protected definition cod : B → cofiber f := inr
parameter {f}
protected definition glue (a : A) : cofiber.base f = cofiber.cod f (f a) :=
pushout.glue a
parameter (f)
protected definition contr_of_equiv [H : is_equiv f] : is_contr (cofiber f) :=
begin
fapply is_contr.mk, exact base,
intro a, induction a with [u, b],
{ cases u, reflexivity },
{ exact !glue ⬝ ap inr (right_inv f b) },
{ apply eq_pathover, refine _ ⬝hp !ap_id⁻¹, refine !ap_constant ⬝ph _,
apply move_bot_of_left, refine !idp_con ⬝ph _, apply transpose, esimp,
refine _ ⬝hp (ap (ap inr) !adj⁻¹), refine _ ⬝hp !ap_compose, apply square_Flr_idp_ap },
end
parameter {f}
protected definition rec {P : cofiber f → Type}
(Pbase : P base) (Pcod : Π (b : B), P (cod b))
(Pglue : Π (a : A), pathover P Pbase (glue a) (Pcod (f a))) :
(Π y, P y) :=
begin
intro y, induction y, induction x, exact Pbase, exact Pcod x, esimp, exact Pglue x,
end
protected definition rec_on {P : cofiber f → Type} (y : cofiber f)
(Pbase : P base) (Pcod : Π (b : B), P (cod b))
(Pglue : Π (a : A), pathover P Pbase (glue a) (Pcod (f a))) : P y :=
cofiber.rec Pbase Pcod Pglue y
protected definition elim {P : Type} (Pbase : P) (Pcod : B → P)
(Pglue : Π (x : A), Pbase = Pcod (f x)) (y : cofiber f) : P :=
pushout.elim (λu, Pbase) Pcod Pglue y
protected definition elim_on {P : Type} (y : cofiber f) (Pbase : P) (Pcod : B → P)
(Pglue : Π (x : A), Pbase = Pcod (f x)) : P :=
cofiber.elim Pbase Pcod Pglue y
protected theorem elim_glue {P : Type} (y : cofiber f) (Pbase : P) (Pcod : B → P)
(Pglue : Π (x : A), Pbase = Pcod (f x)) (a : A)
: ap (elim Pbase Pcod Pglue) (glue a) = Pglue a :=
!pushout.elim_glue
end
end cofiber
attribute cofiber.base cofiber.cod [constructor]
attribute cofiber.rec cofiber.elim [recursor 8] [unfold 8]
attribute cofiber.rec_on cofiber.elim_on [unfold 5]
-- pointed version
definition pcofiber [constructor] {A B : Type*} (f : A →* B) : Type* :=
pointed.MK (cofiber f) !cofiber.base
notation `` := pcofiber
namespace cofiber
variables (A : Type*)
definition cofiber_unit : pcofiber (pconst A punit) ≃* psusp A :=
begin
fapply pequiv_of_pmap,
{ fconstructor, intro x, induction x, exact north, exact south, exact merid x,
reflexivity },
{ esimp, fapply adjointify,
{ intro s, induction s, exact inl ⋆, exact inr ⋆, apply glue a },
{ intro s, induction s, do 2 reflexivity, esimp,
apply eq_pathover, refine _ ⬝hp !ap_id⁻¹, apply hdeg_square,
refine !(ap_compose (pushout.elim _ _ _)) ⬝ _,
refine ap _ !elim_merid ⬝ _, apply elim_glue },
{ intro c, induction c with s, reflexivity,
induction s, reflexivity, esimp, apply eq_pathover, apply hdeg_square,
refine _ ⬝ !ap_id⁻¹, refine !(ap_compose (pushout.elim _ _ _)) ⬝ _,
refine ap02 _ !elim_glue ⬝ _, apply elim_merid }},
end
end cofiber

View file

@ -1,53 +0,0 @@
/-
Copyright (c) 2016 Ulrik Buchholtz and Egbert Rijke. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Ulrik Buchholtz, Egbert Rijke, Floris van Doorn
The H-space structure on S¹ and the complex Hopf fibration
(the standard one).
-/
import .hopf .circle types.fin
open eq equiv is_equiv circle is_conn trunc is_trunc sphere susp pointed fiber sphere.ops function
namespace hopf
definition circle_h_space [instance] : h_space S¹ :=
⦃ h_space, one := base, mul := circle_mul,
one_mul := circle_base_mul, mul_one := circle_mul_base ⦄
definition circle_assoc (x y z : S¹) : (x * y) * z = x * (y * z) :=
begin
induction x,
{ reflexivity },
{ apply eq_pathover, induction y,
{ exact natural_square
(λa : S¹, ap (λb : S¹, b * z) (circle_mul_base a))
loop },
{ apply is_prop.elimo, apply is_trunc_square } }
end
open sphere_index
definition complex_hopf : S 3 → S 2 :=
begin
intro x, apply @sigma.pr1 (susp S¹) (hopf S¹),
apply inv (hopf.total S¹), apply inv (join.spheres 1 1), exact x
end
definition complex_phopf [constructor] : S* 3 →* S* 2 :=
proof pmap.mk complex_hopf idp qed
definition pfiber_complex_phopf : pfiber complex_phopf ≃* S* 1 :=
begin
fapply pequiv_of_equiv,
{ esimp, unfold [complex_hopf],
refine fiber.equiv_precompose (sigma.pr1 ∘ (hopf.total S¹)⁻¹ᵉ)
(join.spheres (of_nat 1) (of_nat 1))⁻¹ᵉ _ ⬝e _,
refine fiber.equiv_precompose _ (hopf.total S¹)⁻¹ᵉ _ ⬝e _,
apply fiber_pr1},
{ reflexivity}
end
end hopf

View file

@ -1,441 +0,0 @@
/-
Copyright (c) 2015 Ulrik Buchholtz. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Ulrik Buchholtz, Floris van Doorn
Connectedness of types and functions
-/
import types.trunc types.arrow_2 types.lift
open eq is_trunc is_equiv nat equiv trunc function fiber funext pi pointed
definition is_conn [reducible] (n : ℕ₋₂) (A : Type) : Type :=
is_contr (trunc n A)
definition is_conn_fun [reducible] (n : ℕ₋₂) {A B : Type} (f : A → B) : Type :=
Πb : B, is_conn n (fiber f b)
definition is_conn_inf [reducible] (A : Type) : Type := Πn, is_conn n A
definition is_conn_fun_inf [reducible] {A B : Type} (f : A → B) : Type := Πn, is_conn_fun n f
namespace is_conn
definition is_conn_equiv_closed (n : ℕ₋₂) {A B : Type}
: A ≃ B → is_conn n A → is_conn n B :=
begin
intros H C,
fapply @is_contr_equiv_closed (trunc n A) _,
apply trunc_equiv_trunc,
assumption
end
theorem is_conn_of_le (A : Type) {n k : ℕ₋₂} (H : n ≤ k) [is_conn k A] : is_conn n A :=
begin
apply is_contr_equiv_closed,
apply trunc_trunc_equiv_left _ H
end
theorem is_conn_fun_of_le {A B : Type} (f : A → B) {n k : ℕ₋₂} (H : n ≤ k)
[is_conn_fun k f] : is_conn_fun n f :=
λb, is_conn_of_le _ H
definition is_conn_of_is_conn_succ (n : ℕ₋₂) (A : Type) [is_conn (n.+1) A] : is_conn n A :=
is_trunc_trunc_of_le A -2 (trunc_index.self_le_succ n)
namespace is_conn_fun
section
parameters (n : ℕ₋₂) {A B : Type} {h : A → B}
(H : is_conn_fun n h) (P : B → Type) [Πb, is_trunc n (P b)]
private definition rec.helper : (Πa : A, P (h a)) → Πb : B, trunc n (fiber h b) → P b :=
λt b, trunc.rec (λx, point_eq x ▸ t (point x))
private definition rec.g : (Πa : A, P (h a)) → (Πb : B, P b) :=
λt b, rec.helper t b (@center (trunc n (fiber h b)) (H b))
-- induction principle for n-connected maps (Lemma 7.5.7)
protected definition rec : is_equiv (λs : Πb : B, P b, λa : A, s (h a)) :=
adjointify (λs a, s (h a)) rec.g
begin
intro t, apply eq_of_homotopy, intro a, unfold rec.g, unfold rec.helper,
rewrite [@center_eq _ (H (h a)) (tr (fiber.mk a idp))],
end
begin
intro k, apply eq_of_homotopy, intro b, unfold rec.g,
generalize (@center _ (H b)), apply trunc.rec, apply fiber.rec,
intros a p, induction p, reflexivity
end
protected definition elim : (Πa : A, P (h a)) → (Πb : B, P b) :=
@is_equiv.inv _ _ (λs a, s (h a)) rec
protected definition elim_β : Πf : (Πa : A, P (h a)), Πa : A, elim f (h a) = f a :=
λf, apd10 (@is_equiv.right_inv _ _ (λs a, s (h a)) rec f)
end
section
parameters (n k : ℕ₋₂) {A B : Type} {f : A → B}
(H : is_conn_fun n f) (P : B → Type) [HP : Πb, is_trunc (n +2+ k) (P b)]
include H HP
-- Lemma 8.6.1
proposition elim_general : is_trunc_fun k (pi_functor_left f P) :=
begin
revert P HP,
induction k with k IH: intro P HP t,
{ apply is_contr_fiber_of_is_equiv, apply is_conn_fun.rec, exact H, exact HP},
{ apply is_trunc_succ_intro,
intros x y, cases x with g p, cases y with h q,
have e : fiber (λr : g ~ h, (λa, r (f a))) (apd10 (p ⬝ q⁻¹))
≃ (fiber.mk g p = fiber.mk h q
:> fiber (λs : (Πb, P b), (λa, s (f a))) t),
begin
apply equiv.trans !fiber.sigma_char,
have e' : Πr : g ~ h,
((λa, r (f a)) = apd10 (p ⬝ q⁻¹))
≃ (ap (λv, (λa, v (f a))) (eq_of_homotopy r) ⬝ q = p),
begin
intro r,
refine equiv.trans _ (eq_con_inv_equiv_con_eq q p
(ap (λv a, v (f a)) (eq_of_homotopy r))),
rewrite [-(ap (λv a, v (f a)) (apd10_eq_of_homotopy r))],
rewrite [-(apd10_ap_precompose_dependent f (eq_of_homotopy r))],
apply equiv.symm,
apply eq_equiv_fn_eq (@apd10 A (λa, P (f a)) (λa, g (f a)) (λa, h (f a)))
end,
apply equiv.trans (sigma.sigma_equiv_sigma_right e'), clear e',
apply equiv.trans (equiv.symm (sigma.sigma_equiv_sigma_left
eq_equiv_homotopy)),
apply equiv.symm, apply equiv.trans !fiber_eq_equiv,
apply sigma.sigma_equiv_sigma_right, intro r,
apply eq_equiv_eq_symm
end,
apply @is_trunc_equiv_closed _ _ k e, clear e,
apply IH (λb : B, (g b = h b)) (λb, @is_trunc_eq (P b) (n +2+ k) (HP b) (g b) (h b))}
end
end
section
universe variables u v
parameters (n : ℕ₋₂) {A : Type.{u}} {B : Type.{v}} {h : A → B}
parameter sec : ΠP : B → trunctype.{max u v} n,
is_retraction (λs : (Πb : B, P b), λ a, s (h a))
private definition s := sec (λb, trunctype.mk' n (trunc n (fiber h b)))
include sec
-- the other half of Lemma 7.5.7
definition intro : is_conn_fun n h :=
begin
intro b,
apply is_contr.mk (@is_retraction.sect _ _ _ s (λa, tr (fiber.mk a idp)) b),
esimp, apply trunc.rec, apply fiber.rec, intros a p,
apply transport
(λz : (Σy, h a = y), @sect _ _ _ s (λa, tr (mk a idp)) (sigma.pr1 z) =
tr (fiber.mk a (sigma.pr2 z)))
(@center_eq _ (is_contr_sigma_eq (h a)) (sigma.mk b p)),
exact apd10 (@right_inverse _ _ _ s (λa, tr (fiber.mk a idp))) a
end
end
end is_conn_fun
-- Connectedness is related to maps to and from the unit type, first to
section
parameters (n : ℕ₋₂) (A : Type)
definition is_conn_of_map_to_unit
: is_conn_fun n (const A unit.star) → is_conn n A :=
begin
intro H, unfold is_conn_fun at H,
exact is_conn_equiv_closed n (fiber.fiber_star_equiv A) _,
end
definition is_conn_fun_to_unit_of_is_conn [H : is_conn n A] :
is_conn_fun n (const A unit.star) :=
begin
intro u, induction u,
exact is_conn_equiv_closed n (fiber.fiber_star_equiv A)⁻¹ᵉ _,
end
-- now maps from unit
definition is_conn_of_map_from_unit (a₀ : A) (H : is_conn_fun n (const unit a₀))
: is_conn n .+1 A :=
is_contr.mk (tr a₀)
begin
apply trunc.rec, intro a,
exact trunc.elim (λz : fiber (const unit a₀) a, ap tr (point_eq z))
(@center _ (H a))
end
definition is_conn_fun_from_unit (a₀ : A) [H : is_conn n .+1 A]
: is_conn_fun n (const unit a₀) :=
begin
intro a,
apply is_conn_equiv_closed n (equiv.symm (fiber_const_equiv A a₀ a)),
apply @is_contr_equiv_closed _ _ (tr_eq_tr_equiv n a₀ a),
end
end
-- as special case we get elimination principles for pointed connected types
namespace is_conn
open pointed unit
section
parameters (n : ℕ₋₂) {A : Type*}
[H : is_conn n .+1 A] (P : A → Type) [Πa, is_trunc n (P a)]
include H
protected definition rec : is_equiv (λs : Πa : A, P a, s (Point A)) :=
@is_equiv_compose
(Πa : A, P a) (unit → P (Point A)) (P (Point A))
(λf, f unit.star) (λs x, s (Point A))
(is_conn_fun.rec n (is_conn_fun_from_unit n A (Point A)) P)
(to_is_equiv (arrow_unit_left (P (Point A))))
protected definition elim : P (Point A) → (Πa : A, P a) :=
@is_equiv.inv _ _ (λs, s (Point A)) rec
protected definition elim_β (p : P (Point A)) : elim p (Point A) = p :=
@is_equiv.right_inv _ _ (λs, s (Point A)) rec p
end
section
parameters (n k : ℕ₋₂) {A : Type*}
[H : is_conn n .+1 A] (P : A → Type) [Πa, is_trunc (n +2+ k) (P a)]
include H
proposition elim_general (p : P (Point A))
: is_trunc k (fiber (λs : (Πa : A, P a), s (Point A)) p) :=
@is_trunc_equiv_closed
(fiber (λs x, s (Point A)) (λx, p))
(fiber (λs, s (Point A)) p)
k
(equiv.symm (fiber.equiv_postcompose _ (arrow_unit_left (P (Point A))) _))
(is_conn_fun.elim_general n k (is_conn_fun_from_unit n A (Point A)) P (λx, p))
end
end is_conn
-- Lemma 7.5.2
definition minus_one_conn_of_surjective {A B : Type} (f : A → B)
: is_surjective f → is_conn_fun -1 f :=
begin
intro H, intro b,
exact @is_contr_of_inhabited_prop (∥fiber f b∥) (is_trunc_trunc -1 (fiber f b)) (H b),
end
definition is_surjection_of_minus_one_conn {A B : Type} (f : A → B)
: is_conn_fun -1 f → is_surjective f :=
begin
intro H, intro b,
exact @center (∥fiber f b∥) (H b),
end
definition merely_of_minus_one_conn {A : Type} : is_conn -1 A → ∥A∥ :=
λH, @center (∥A∥) H
definition minus_one_conn_of_merely {A : Type} : ∥A∥ → is_conn -1 A :=
@is_contr_of_inhabited_prop (∥A∥) (is_trunc_trunc -1 A)
section
open arrow
variables {f g : arrow}
-- Lemma 7.5.4
definition retract_of_conn_is_conn [instance] (r : arrow_hom f g) [H : is_retraction r]
(n : ℕ₋₂) [K : is_conn_fun n f] : is_conn_fun n g :=
begin
intro b, unfold is_conn,
apply is_contr_retract (trunc_functor n (retraction_on_fiber r b)),
exact K (on_cod (arrow.is_retraction.sect r) b)
end
end
-- Corollary 7.5.5
definition is_conn_homotopy (n : ℕ₋₂) {A B : Type} {f g : A → B}
(p : f ~ g) (H : is_conn_fun n f) : is_conn_fun n g :=
@retract_of_conn_is_conn _ _
(arrow.arrow_hom_of_homotopy p) (arrow.is_retraction_arrow_hom_of_homotopy p) n H
-- all types are -2-connected
definition is_conn_minus_two (A : Type) : is_conn -2 A :=
_
-- merely inhabited types are -1-connected
definition is_conn_minus_one (A : Type) (a : ∥ A ∥) : is_conn -1 A :=
is_contr.mk a (is_prop.elim _)
definition is_conn_trunc [instance] (A : Type) (n k : ℕ₋₂) [H : is_conn n A]
: is_conn n (trunc k A) :=
begin
apply is_trunc_equiv_closed, apply trunc_trunc_equiv_trunc_trunc
end
definition is_conn_eq [instance] (n : ℕ₋₂) {A : Type} (a a' : A) [is_conn (n.+1) A] :
is_conn n (a = a') :=
begin
apply is_trunc_equiv_closed, apply tr_eq_tr_equiv,
end
definition is_conn_loop [instance] (n : ℕ₋₂) (A : Type*) [is_conn (n.+1) A] : is_conn n (Ω A) :=
!is_conn_eq
open pointed
definition is_conn_ptrunc [instance] (A : Type*) (n k : ℕ₋₂) [H : is_conn n A]
: is_conn n (ptrunc k A) :=
is_conn_trunc A n k
-- the following trivial cases are solved by type class inference
definition is_conn_of_is_contr (k : ℕ₋₂) (A : Type) [is_contr A] : is_conn k A := _
definition is_conn_fun_of_is_equiv (k : ℕ₋₂) {A B : Type} (f : A → B) [is_equiv f] :
is_conn_fun k f :=
_
-- Lemma 7.5.14
theorem is_equiv_trunc_functor_of_is_conn_fun [instance] {A B : Type} (n : ℕ₋₂) (f : A → B)
[H : is_conn_fun n f] : is_equiv (trunc_functor n f) :=
begin
fapply adjointify,
{ intro b, induction b with b, exact trunc_functor n point (center (trunc n (fiber f b)))},
{ intro b, induction b with b, esimp, generalize center (trunc n (fiber f b)), intro v,
induction v with v, induction v with a p, esimp, exact ap tr p},
{ intro a, induction a with a, esimp, rewrite [center_eq (tr (fiber.mk a idp))]}
end
theorem trunc_equiv_trunc_of_is_conn_fun {A B : Type} (n : ℕ₋₂) (f : A → B)
[H : is_conn_fun n f] : trunc n A ≃ trunc n B :=
equiv.mk (trunc_functor n f) (is_equiv_trunc_functor_of_is_conn_fun n f)
definition is_conn_fun_trunc_functor_of_le {n k : ℕ₋₂} {A B : Type} (f : A → B) (H : k ≤ n)
[H2 : is_conn_fun k f] : is_conn_fun k (trunc_functor n f) :=
begin
apply is_conn_fun.intro,
intro P, have Πb, is_trunc n (P b), from (λb, is_trunc_of_le _ H),
fconstructor,
{ intro f' b,
induction b with b,
refine is_conn_fun.elim k H2 _ _ b, intro a, exact f' (tr a)},
{ intro f', apply eq_of_homotopy, intro a,
induction a with a, esimp, rewrite [is_conn_fun.elim_β]}
end
definition is_conn_fun_trunc_functor_of_ge {n k : ℕ₋₂} {A B : Type} (f : A → B) (H : n ≤ k)
[H2 : is_conn_fun k f] : is_conn_fun k (trunc_functor n f) :=
begin
apply is_conn_fun_of_is_equiv,
apply is_equiv_trunc_functor_of_le f H
end
-- Exercise 7.18
definition is_conn_fun_trunc_functor {n k : ℕ₋₂} {A B : Type} (f : A → B)
[H2 : is_conn_fun k f] : is_conn_fun k (trunc_functor n f) :=
begin
eapply algebra.le_by_cases k n: intro H,
{ exact is_conn_fun_trunc_functor_of_le f H},
{ exact is_conn_fun_trunc_functor_of_ge f H}
end
open lift
definition is_conn_fun_lift_functor (n : ℕ₋₂) {A B : Type} (f : A → B) [is_conn_fun n f] :
is_conn_fun n (lift_functor f) :=
begin
intro b, cases b with b, apply is_trunc_equiv_closed_rev,
{ apply trunc_equiv_trunc, apply fiber_lift_functor}
end
open trunc_index
definition is_conn_fun_inf.mk_nat {A B : Type} {f : A → B} (H : Π(n : ), is_conn_fun n f)
: is_conn_fun_inf f :=
begin
intro n,
cases n with n, { exact _},
cases n with n, { have -1 ≤ of_nat 0, from dec_star, apply is_conn_fun_of_le f this},
rewrite -of_nat_add_two, exact _
end
definition is_conn_inf.mk_nat {A : Type} (H : Π(n : ), is_conn n A) : is_conn_inf A :=
begin
intro n,
cases n with n, { exact _},
cases n with n, { have -1 ≤ of_nat 0, from dec_star, apply is_conn_of_le A this},
rewrite -of_nat_add_two, exact _
end
end is_conn
/-
(bundled) connected types, possibly also truncated or with a point
The notation is n-Type*[k] for k-connected n-truncated pointed types, and you can remove
`n-`, `[k]` or `*` in any combination to remove some conditions
-/
structure conntype (n : ℕ₋₂) : Type :=
(carrier : Type)
(struct : is_conn n carrier)
notation `Type[`:95 n:0 `]`:0 := conntype n
attribute conntype.carrier [coercion]
attribute conntype.struct [instance] [priority 1300]
section
universe variable u
structure pconntype (n : ℕ₋₂) extends conntype.{u} n, pType.{u}
notation `Type*[`:95 n:0 `]`:0 := pconntype n
/-
There are multiple coercions from pconntype to Type. Type class inference doesn't recognize
that all of them are definitionally equal (for performance reasons). One instance is
automatically generated, and we manually add the missing instances.
-/
definition is_conn_pconntype [instance] {n : ℕ₋₂} (X : Type*[n]) : is_conn n X :=
conntype.struct X
structure truncconntype (n k : ℕ₋₂) extends trunctype.{u} n,
conntype.{u} k renaming struct→conn_struct
notation n `-Type[`:95 k:0 `]`:0 := truncconntype n k
definition is_conn_truncconntype [instance] {n k : ℕ₋₂} (X : n-Type[k]) :
is_conn k (truncconntype._trans_of_to_trunctype X) :=
conntype.struct X
definition is_trunc_truncconntype [instance] {n k : ℕ₋₂} (X : n-Type[k]) : is_trunc n X :=
trunctype.struct X
structure ptruncconntype (n k : ℕ₋₂) extends ptrunctype.{u} n,
pconntype.{u} k renaming struct→conn_struct
notation n `-Type*[`:95 k:0 `]`:0 := ptruncconntype n k
attribute ptruncconntype._trans_of_to_pconntype ptruncconntype._trans_of_to_ptrunctype
ptruncconntype._trans_of_to_pconntype_1 ptruncconntype._trans_of_to_ptrunctype_1
ptruncconntype._trans_of_to_pconntype_2 ptruncconntype._trans_of_to_ptrunctype_2
ptruncconntype.to_pconntype ptruncconntype.to_ptrunctype
truncconntype._trans_of_to_conntype truncconntype._trans_of_to_trunctype
truncconntype.to_conntype truncconntype.to_trunctype [unfold 3]
attribute pconntype._trans_of_to_conntype pconntype._trans_of_to_pType
pconntype.to_pType pconntype.to_conntype [unfold 2]
definition is_conn_ptruncconntype [instance] {n k : ℕ₋₂} (X : n-Type*[k]) :
is_conn k (ptruncconntype._trans_of_to_ptrunctype X) :=
conntype.struct X
definition is_trunc_ptruncconntype [instance] {n k : ℕ₋₂} (X : n-Type*[k]) :
is_trunc n (ptruncconntype._trans_of_to_pconntype X) :=
trunctype.struct X
definition ptruncconntype_eq {n k : ℕ₋₂} {X Y : n-Type*[k]} (p : X ≃* Y) : X = Y :=
begin
induction X with X Xt Xp Xc, induction Y with Y Yt Yp Yc,
note q := pType_eq_elim (eq_of_pequiv p),
cases q with r s, esimp at *, induction r,
exact ap0111 (ptruncconntype.mk X) !is_prop.elim (eq_of_pathover_idp s) !is_prop.elim
end
end

View file

@ -1,144 +0,0 @@
/-
Copyright (c) 2015 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
Declaration of mapping cylinders
-/
import hit.quotient types.fiber
open quotient eq sum equiv fiber
namespace cylinder
section
parameters {A B : Type} (f : A → B)
local abbreviation C := B + A
inductive cylinder_rel : C → C → Type :=
| Rmk : Π(a : A), cylinder_rel (inl (f a)) (inr a)
open cylinder_rel
local abbreviation R := cylinder_rel
definition cylinder := quotient cylinder_rel -- TODO: define this in root namespace
parameter {f}
definition base (b : B) : cylinder :=
class_of R (inl b)
definition top (a : A) : cylinder :=
class_of R (inr a)
definition seg (a : A) : base (f a) = top a :=
eq_of_rel cylinder_rel (Rmk f a)
protected definition rec {P : cylinder → Type}
(Pbase : Π(b : B), P (base b)) (Ptop : Π(a : A), P (top a))
(Pseg : Π(a : A), Pbase (f a) =[seg a] Ptop a) (x : cylinder) : P x :=
begin
induction x,
{ cases a,
apply Pbase,
apply Ptop},
{ cases H, apply Pseg}
end
protected definition rec_on [reducible] {P : cylinder → Type} (x : cylinder)
(Pbase : Π(b : B), P (base b)) (Ptop : Π(a : A), P (top a))
(Pseg : Π(a : A), Pbase (f a) =[seg a] Ptop a) : P x :=
rec Pbase Ptop Pseg x
theorem rec_seg {P : cylinder → Type}
(Pbase : Π(b : B), P (base b)) (Ptop : Π(a : A), P (top a))
(Pseg : Π(a : A), Pbase (f a) =[seg a] Ptop a)
(a : A) : apd (rec Pbase Ptop Pseg) (seg a) = Pseg a :=
!rec_eq_of_rel
protected definition elim {P : Type} (Pbase : B → P) (Ptop : A → P)
(Pseg : Π(a : A), Pbase (f a) = Ptop a) (x : cylinder) : P :=
rec Pbase Ptop (λa, pathover_of_eq _ (Pseg a)) x
protected definition elim_on [reducible] {P : Type} (x : cylinder) (Pbase : B → P) (Ptop : A → P)
(Pseg : Π(a : A), Pbase (f a) = Ptop a) : P :=
elim Pbase Ptop Pseg x
theorem elim_seg {P : Type} (Pbase : B → P) (Ptop : A → P)
(Pseg : Π(a : A), Pbase (f a) = Ptop a)
(a : A) : ap (elim Pbase Ptop Pseg) (seg a) = Pseg a :=
begin
apply eq_of_fn_eq_fn_inv !(pathover_constant (seg a)),
rewrite [▸*,-apd_eq_pathover_of_eq_ap,↑elim,rec_seg],
end
protected definition elim_type (Pbase : B → Type) (Ptop : A → Type)
(Pseg : Π(a : A), Pbase (f a) ≃ Ptop a) (x : cylinder) : Type :=
elim Pbase Ptop (λa, ua (Pseg a)) x
protected definition elim_type_on [reducible] (x : cylinder) (Pbase : B → Type) (Ptop : A → Type)
(Pseg : Π(a : A), Pbase (f a) ≃ Ptop a) : Type :=
elim_type Pbase Ptop Pseg x
theorem elim_type_seg (Pbase : B → Type) (Ptop : A → Type)
(Pseg : Π(a : A), Pbase (f a) ≃ Ptop a)
(a : A) : transport (elim_type Pbase Ptop Pseg) (seg a) = Pseg a :=
by rewrite [tr_eq_cast_ap_fn,↑elim_type,elim_seg];apply cast_ua_fn
end
end cylinder
attribute cylinder.base cylinder.top [constructor]
attribute cylinder.rec cylinder.elim [unfold 8] [recursor 8]
attribute cylinder.elim_type [unfold 7]
attribute cylinder.rec_on cylinder.elim_on [unfold 5]
attribute cylinder.elim_type_on [unfold 4]
namespace cylinder
open sigma sigma.ops
variables {A B : Type} (f : A → B)
/- cylinder as a dependent family -/
definition pr1 [unfold 4] : cylinder f → B :=
cylinder.elim id f (λa, idp)
definition fcylinder : B → Type := fiber (pr1 f)
definition cylinder_equiv_sigma_fcylinder [constructor] : cylinder f ≃ Σb, fcylinder f b :=
!sigma_fiber_equiv⁻¹ᵉ
variable {f}
definition fbase (b : B) : fcylinder f b :=
fiber.mk (base b) idp
definition ftop (a : A) : fcylinder f (f a) :=
fiber.mk (top a) idp
definition fseg (a : A) : fbase (f a) = ftop a :=
fiber_eq (seg a) !elim_seg⁻¹
-- TODO: define the induction principle for "fcylinder"
-- set_option pp.notation false
-- -- The induction principle for the dependent mapping cylinder (TODO)
-- protected definition frec {P : Π(b), fcylinder f b → Type}
-- (Pbase : Π(b : B), P _ (fbase b)) (Ptop : Π(a : A), P _ (ftop a))
-- (Pseg : Π(a : A), Pbase (f a) =[fseg a] Ptop a) {b : B} (x : fcylinder f b) : P _ x :=
-- begin
-- cases x with x p, induction p,
-- induction x: esimp,
-- { apply Pbase},
-- { apply Ptop},
-- { esimp, --fapply fiber_pathover,
-- --refine pathover_of_pathover_ap P (λx, fiber.mk x idp),
-- exact sorry}
-- end
-- theorem frec_fseg {P : Π(b), fcylinder f b → Type}
-- (Pbase : Π(b : B), P _ (fbase b)) (Ptop : Π(a : A), P _ (ftop a))
-- (Pseg : Π(a : A), Pbase (f a) =[fseg a] Ptop a) (a : A)
-- : apd (cylinder.frec Pbase Ptop Pseg) (fseg a) = Pseg a :=
-- sorry
end cylinder

View file

@ -1,8 +0,0 @@
/-
Copyright (c) 2016 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
-/
import .sphere2 .EM .torus .red_susp .quaternionic_hopf .smash .cellcomplex .interval .cylinder

Some files were not shown because too many files have changed in this diff Show more