Last active
February 18, 2017 12:59
-
-
Save semorrison/0d74c8a95234e0e1d26d2355b12547fd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
open tactic | |
open smt_tactic | |
def pointwise_attribute : user_attribute := { | |
name := `pointwise, | |
descr := "A lemma that proves things are equal using the fact they are pointwise equal." | |
} | |
run_command attribute.register `pointwise_attribute | |
/- Try to apply one of the given lemas, it succeeds if one of them succeeds. -/ | |
meta def any_apply : list name → tactic unit | |
| [] := failed | |
| (c::cs) := (mk_const c >>= fapply) <|> any_apply cs | |
meta def smt : tactic unit := using_smt $ intros >> add_lemmas_from_facts >> try ematch >> try simp | |
meta def pointwise (and_then : tactic unit) : tactic unit := | |
do cs ← attribute.get_instances `pointwise, | |
try (any_apply cs >> and_then) | |
attribute [pointwise] funext | |
meta def blast : tactic unit := smt >> pointwise (repeat_at_most 2 blast) -- pointwise equality of functors creates two goals | |
-- In a timing test on 2017-02-18, I found that using `abstract { blast }` instead of just `blast` resulted in a 5x speed-up! | |
notation `♮` := by abstract { blast } | |
@[pointwise] lemma {u v} pair_equality {α : Type u} {β : Type v} { X: α × β }: (X^.fst, X^.snd) = X := begin induction X, blast end | |
@[pointwise] lemma {u v} pair_equality_1 {α : Type u} {β : Type v} { X: α × β } { A : α } ( p : A = X^.fst ) : (A, X^.snd) = X := begin induction X, blast end | |
@[pointwise] lemma {u v} pair_equality_2 {α : Type u} {β : Type v} { X: α × β } { B : β } ( p : B = X^.snd ) : (X^.fst, B) = X := begin induction X, blast end | |
attribute [pointwise] subtype.eq | |
def {u} auto_cast {α β : Type u} {h : α = β} (a : α) := cast h a | |
@[simp] lemma {u} auto_cast_identity {α : Type u} (a : α) : @auto_cast α α ♮ a = a := ♮ | |
notation `⟦` p `⟧` := @auto_cast _ _ ♮ p | |
universe variables u v | |
structure Category := | |
(Obj : Type u) | |
(Hom : Obj → Obj → Type v) | |
(identity : Π X : Obj, Hom X X) | |
(compose : Π { X Y Z : Obj }, Hom X Y → Hom Y Z → Hom X Z) | |
(left_identity : ∀ { X Y : Obj } (f : Hom X Y), compose (identity _) f = f) | |
(right_identity : ∀ { X Y : Obj } (f : Hom X Y), compose f (identity _) = f) | |
(associativity : ∀ { W X Y Z : Obj } (f : Hom W X) (g : Hom X Y) (h : Hom Y Z), | |
compose (compose f g) h = compose f (compose g h)) | |
attribute [simp] Category.left_identity | |
attribute [simp] Category.right_identity | |
@[reducible] definition CategoryOfTypes : Category := | |
{ | |
Obj := Type u, | |
Hom := λ a b, a → b, | |
identity := λ a, id, | |
compose := λ _ _ _ f g, g ∘ f, | |
left_identity := ♮, | |
right_identity := ♮, | |
associativity := ♮ | |
} | |
universe variables u1 v1 u2 v2 u3 v3 | |
structure Functor (C : Category.{ u1 v1 }) (D : Category.{ u2 v2 }) := | |
(onObjects : C^.Obj → D^.Obj) | |
(onMorphisms : Π { X Y : C^.Obj }, | |
C^.Hom X Y → D^.Hom (onObjects X) (onObjects Y)) | |
(identities : ∀ (X : C^.Obj), | |
onMorphisms (C^.identity X) = D^.identity (onObjects X)) | |
(functoriality : ∀ { X Y Z : C^.Obj } (f : C^.Hom X Y) (g : C^.Hom Y Z), | |
onMorphisms (C^.compose f g) = D^.compose (onMorphisms f) (onMorphisms g)) | |
attribute [simp] Functor.identities | |
attribute [simp] Functor.functoriality | |
-- We define a coercion so that we can write `F X` for the functor `F` applied to the object `X`. | |
-- One can still write out `onObjects F X` when needed. | |
instance Functor_to_onObjects { C D : Category }: has_coe_to_fun (Functor C D) := | |
{ F := λ f, C^.Obj -> D^.Obj, | |
coe := Functor.onObjects } | |
@[reducible] definition IdentityFunctor ( C: Category ) : Functor C C := | |
{ | |
onObjects := id, | |
onMorphisms := λ _ _ f, f, | |
identities := ♮, | |
functoriality := ♮ | |
} | |
@[reducible] definition FunctorComposition { C D E : Category } ( F : Functor C D ) ( G : Functor D E ) : Functor C E := | |
{ | |
onObjects := λ X, G (F X), | |
onMorphisms := λ _ _ f, G^.onMorphisms (F^.onMorphisms f), | |
identities := ♮, | |
functoriality := ♮ | |
} | |
namespace Functor | |
notation F `∘` G := FunctorComposition F G | |
end Functor | |
structure NaturalTransformation { C D : Category } ( F G : Functor C D ) := | |
(components: Π X : C^.Obj, D^.Hom (F X) (G X)) | |
(naturality: ∀ { X Y : C^.Obj } (f : C^.Hom X Y), | |
D^.compose (F^.onMorphisms f) (components Y) = D^.compose (components X) (G^.onMorphisms f)) | |
-- This defines a coercion so we can write `α X` for `components α X`. | |
instance NaturalTransformation_to_components { C D : Category } { F G : Functor C D } : has_coe_to_fun (NaturalTransformation F G) := | |
{ F := λ f, Π X : C^.Obj, D^.Hom (F X) (G X), | |
coe := NaturalTransformation.components } | |
-- We'll want to be able to prove that two natural transformations are equal if they are componentwise equal. | |
@[pointwise] lemma NaturalTransformations_componentwise_equal | |
{ C D : Category } | |
{ F G : Functor C D } | |
( α β : NaturalTransformation F G ) | |
( w : ∀ X : C^.Obj, α X = β X ) : α = β := | |
begin | |
induction α with αc, | |
induction β with βc, | |
have hc : αc = βc, from funext w, | |
by subst hc | |
end | |
@[reducible] definition IdentityNaturalTransformation { C D : Category } (F : Functor C D) : NaturalTransformation F F := | |
{ | |
components := λ X, D^.identity (F X), | |
naturality := ♮ | |
} | |
@[reducible] definition vertical_composition_of_NaturalTransformations | |
{ C D : Category } | |
{ F G H : Functor C D } | |
( α : NaturalTransformation F G ) | |
( β : NaturalTransformation G H ) : NaturalTransformation F H := | |
{ | |
components := λ X, D^.compose (α X) (β X), | |
naturality := begin | |
blast, | |
begin[smt] | |
eblast_using [ Category.associativity, NaturalTransformation.naturality ] | |
end, | |
end | |
} | |
@[reducible] definition horizontal_composition_of_NaturalTransformations | |
{ C D E : Category } | |
{ F G : Functor C D } | |
{ H I : Functor D E } | |
( α : NaturalTransformation F G ) | |
( β : NaturalTransformation H I ) : NaturalTransformation (FunctorComposition F H) (FunctorComposition G I) := | |
{ | |
components := λ X : C^.Obj, E^.compose (β (F X)) (I^.onMorphisms (α X)), | |
naturality := begin | |
blast, | |
begin[smt] | |
eblast_using [ Category.associativity, Functor.functoriality, NaturalTransformation.naturality ] | |
end, | |
end | |
} | |
definition whisker_on_left | |
{ C D E : Category } | |
( F : Functor C D ) | |
{ G H : Functor D E } | |
( α : NaturalTransformation G H ) : | |
NaturalTransformation (FunctorComposition F G) (FunctorComposition F H) := | |
horizontal_composition_of_NaturalTransformations (IdentityNaturalTransformation F) α | |
definition whisker_on_right | |
{ C D E : Category } | |
{ F G : Functor C D } | |
( α : NaturalTransformation F G ) | |
( H : Functor D E ) : | |
NaturalTransformation (FunctorComposition F H) (FunctorComposition G H) := | |
horizontal_composition_of_NaturalTransformations α (IdentityNaturalTransformation H) | |
@[reducible] definition ProductCategory (C : Category.{u1 v1}) (D : Category.{u2 v2}) : | |
Category := | |
{ | |
Obj := C^.Obj × D^.Obj, | |
Hom := (λ X Y : C^.Obj × D^.Obj, C^.Hom (X^.fst) (Y^.fst) × D^.Hom (X^.snd) (Y^.snd)), | |
identity := λ X, (C^.identity (X^.fst), D^.identity (X^.snd)), | |
compose := λ _ _ _ f g, (C^.compose (f^.fst) (g^.fst), D^.compose (f^.snd) (g^.snd)), | |
left_identity := ♮, | |
right_identity := ♮, | |
associativity := begin | |
blast, | |
begin[smt] | |
eblast_using [ Category.associativity ] | |
end | |
end | |
} | |
namespace ProductCategory | |
notation C `×` D := ProductCategory C D | |
end ProductCategory | |
@[reducible] definition ProductFunctor { A B C D : Category } ( F : Functor A B ) ( G : Functor C D ) : Functor (A × C) (B × D) := | |
{ | |
onObjects := λ X, (F X^.fst, G X^.snd), | |
onMorphisms := λ _ _ f, (F^.onMorphisms f^.fst, G^.onMorphisms f^.snd), | |
identities := ♮, | |
functoriality := ♮ | |
} | |
namespace ProductFunctor | |
notation F `×` G := ProductFunctor F G | |
end ProductFunctor | |
definition ProductNaturalTransformation { A B C D : Category } { F G : Functor A B } { H I : Functor C D } (α : NaturalTransformation F G) (β : NaturalTransformation H I) : NaturalTransformation (F × H) (G × I) := | |
{ | |
components := λ X, (α X^.fst, β X^.snd), | |
naturality := | |
begin | |
blast, | |
begin[smt] | |
eblast_using [ NaturalTransformation.naturality ] | |
end | |
end | |
} | |
namespace ProductNaturalTransformation | |
notation α `×` β := ProductNaturalTransformation α β | |
end ProductNaturalTransformation | |
definition ProductCategoryAssociator | |
( C : Category.{ u1 v1 } ) | |
( D : Category.{ u2 v2 } ) | |
( E : Category.{ u3 v3 } ) | |
: Functor ((C × D) × E) (C × (D × E)) := | |
{ | |
onObjects := λ X, (X^.fst^.fst, (X^.fst^.snd, X^.snd)), | |
onMorphisms := λ _ _ f, (f^.fst^.fst, (f^.fst^.snd, f^.snd)), | |
identities := ♮, | |
functoriality := ♮ | |
} | |
@[reducible] definition TensorProduct ( C: Category ) := Functor ( C × C ) C | |
structure PreMonoidalCategory := | |
(category : Category) | |
(tensor : TensorProduct category) | |
namespace PreMonoidalCategory | |
notation X `⊗` Y := (PreMonoidalCategory.tensor _)^.onObjects (X, Y) | |
notation f `⊗` g := (PreMonoidalCategory.tensor _)^.onMorphisms (f, g) | |
end PreMonoidalCategory | |
instance PreMonoidalCategory_coercion : has_coe PreMonoidalCategory Category := | |
⟨PreMonoidalCategory.category⟩ | |
-- Copying fields. TODO: automate | |
@[reducible] definition PreMonoidalCategory.Obj ( C : PreMonoidalCategory ) := @Category.Obj C^.category | |
@[reducible] definition PreMonoidalCategory.Hom ( C : PreMonoidalCategory ) := @Category.Hom C^.category | |
@[reducible] definition PreMonoidalCategory.identity ( C : PreMonoidalCategory ) := @Category.identity C^.category | |
@[reducible] definition PreMonoidalCategory.compose ( C : PreMonoidalCategory ) := @Category.compose C^.category | |
definition left_associated_triple_tensor ( C : PreMonoidalCategory.{ u v } ) : Functor ((C × C) × C) C := | |
FunctorComposition (C^.tensor × IdentityFunctor C) C^.tensor | |
definition right_associated_triple_tensor ( C : PreMonoidalCategory.{ u v } ) : Functor (C × (C × C)) C := | |
FunctorComposition (IdentityFunctor C × C^.tensor) C^.tensor | |
@[reducible] definition Associator ( C : PreMonoidalCategory.{ u v } ) := | |
NaturalTransformation | |
(left_associated_triple_tensor C) | |
(FunctorComposition (ProductCategoryAssociator C C C) (right_associated_triple_tensor C)) | |
definition pentagon_3step_1 { C : PreMonoidalCategory.{ u v } } ( α : Associator.{ u v } C ) := | |
whisker_on_right | |
(α × IdentityNaturalTransformation (IdentityFunctor C)) | |
C^.tensor | |
definition pentagon_3step_2 { C : PreMonoidalCategory.{ u v } } ( α : Associator.{ u v } C ) := | |
whisker_on_left | |
(FunctorComposition | |
(ProductCategoryAssociator C C C × IdentityFunctor C) | |
((IdentityFunctor C × C^.tensor) × IdentityFunctor C)) | |
α | |
definition pentagon_3step_3 { C : PreMonoidalCategory.{ u v } } ( α : Associator.{ u v } C ) := | |
whisker_on_left | |
(FunctorComposition | |
(ProductCategoryAssociator C C C × IdentityFunctor C) | |
(ProductCategoryAssociator C (↑C × ↑C) C)) | |
(whisker_on_right | |
(IdentityNaturalTransformation (IdentityFunctor C) × α) | |
C^.tensor) | |
definition pentagon_3step { C : PreMonoidalCategory.{ u v } } ( α : Associator.{ u v } C ) := | |
vertical_composition_of_NaturalTransformations | |
(vertical_composition_of_NaturalTransformations | |
(pentagon_3step_1 α) | |
(pentagon_3step_2 α)) | |
(pentagon_3step_3 α) | |
definition pentagon_2step_1 { C : PreMonoidalCategory.{ u v } } ( α : Associator.{ u v } C ) := | |
whisker_on_left | |
((C^.tensor × IdentityFunctor C) × IdentityFunctor C) | |
α | |
definition pentagon_2step_2 { C : PreMonoidalCategory.{ u v } } ( α : Associator.{ u v } C ) := | |
whisker_on_left | |
(FunctorComposition | |
(ProductCategoryAssociator (↑C × ↑C) C C) | |
(IdentityFunctor (↑C × ↑C) × C^.tensor)) | |
α | |
definition pentagon_2step { C : PreMonoidalCategory.{ u v } } ( α : Associator.{ u v } C ) := | |
vertical_composition_of_NaturalTransformations | |
(pentagon_2step_1 α) | |
(pentagon_2step_2 α) | |
structure MonoidalCategory := | |
(parent : PreMonoidalCategory) | |
(associator_transformation : Associator parent) | |
(pentagon : pentagon_3step associator_transformation = pentagon_2step associator_transformation) | |
instance MonoidalCategory_coercion : has_coe MonoidalCategory.{u v} PreMonoidalCategory.{u v} := | |
⟨MonoidalCategory.parent⟩ | |
-- Copying fields. TODO: automate | |
@[reducible] definition MonoidalCategory.Obj ( C : MonoidalCategory ) := @PreMonoidalCategory.Obj C^.parent | |
@[reducible] definition MonoidalCategory.Hom ( C : MonoidalCategory ) := @PreMonoidalCategory.Hom C^.parent | |
@[reducible] definition MonoidalCategory.identity ( C : MonoidalCategory ) := @PreMonoidalCategory.identity C^.parent | |
@[reducible] definition MonoidalCategory.compose ( C : MonoidalCategory ) := @PreMonoidalCategory.compose C^.parent | |
@[reducible] definition MonoidalCategory.tensor ( C : MonoidalCategory ) := @PreMonoidalCategory.tensor C^.parent | |
definition PreMonoidalCategoryOfTypes : PreMonoidalCategory := | |
{ | |
category := CategoryOfTypes, | |
tensor := { | |
onObjects := λ p, prod p.1 p.2, | |
onMorphisms := λ _ _ p, λ q, (p.1 q.1, p.2 q.2), | |
identities := ♮, | |
functoriality := ♮ | |
} | |
} | |
definition MonoidalCategoryOfTypes : MonoidalCategory := | |
{ | |
parent := PreMonoidalCategoryOfTypes, | |
associator_transformation := { | |
components := λ p, λ t, (t.1.1,(t.1.2, t.2)), | |
naturality := ♮ | |
}, | |
pentagon := ♮ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment