Built with Alectryon, running Coq+SerAPI v8.19.0+0.19.3. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use ⌘ instead of Ctrl.
(** * Notions of Structure *)
[Loading ML file number_string_notation_plugin.cmxs (using legacy method) ... done]
Require Import HoTT.Basics HoTT.Types HSet.Set Universe Polymorphism.Set Implicit Arguments.Generalizable All Variables.Set Asymmetric Patterns.LocalOpen Scope category_scope.LocalOpen Scope morphism_scope.(** * Structures *)Declare Scope structure_scope.Declare Scope long_structure_scope.Delimit Scope structure_scope with structure.Delimit Scope long_structure_scope with long_structure.LocalOpen Scope structure_scope.(** Quoting the Homotopy Type Theory Book (with slight changes for notational consistency): *)(** ** 9.8 The structure identity principle The _structure identity principle_ is an informal principle that expresses that isomorphic structures are identical. We aim to prove a general abstract result which can be applied to a wide family of notions of structure, where structures may be many-sorted or even dependently-sorted, in-finitary, or even higher order. The simplest kind of single-sorted structure consists of a type with no additional structure. The univalence axiom expresses the structure identity principle for that notion of structure in a strong form: for types [A], [B], the canonical function [(A = B) → (A ≃ B)] is an equivalence. We start with a precategory [X]. In our application to single-sorted first order structures, [X] will be the category of [U]-small sets, where [U] is a univalent type universe. *)(** *** Notion of Structure *)(** Definition: A _notion of structure_ [(P,H)] over [X] consists of the following. We use [X₀] to denote the objects of [X], and [homₓ(x, y)] to denote the morphisms [morphism X x y] of [X]. (i) A type family [P : X₀ → Type]. For each [x : X₀] the elements of [P x] are called _[(P, H)]-structures_ on [x]. (ii) For [x y : X₀] and [α : P x], [β : P y], to each [f : homₓ(x, y)] a mere proposition [H_{αβ}(f)]. If [H_{αβ}(f)] is true, we say that [f] is a _[(P, H)]-homomorphism_ from [α] to [β]. (iii) For [x : X₀] and [α : P x], we have [H_{αα}(1ₓ)]. (iv) For [x y z : X₀] and [α : P x], [β : P y], [γ : P z], if [f : homₓ(x, y)], we have [H_{αβ}(f)→ H_{βγ}(g) → H_{αγ}(g ∘ f)]. *)(** Note: We rearrange some parameters to [H] to ease Coq's unification engine and typeclass machinery. *)RecordNotionOfStructure (X : PreCategory) :=
{
structure :> X -> Type;
is_structure_homomorphism : forallxy
(f : morphism X x y)
(a : structure x) (b : structure y),
Type;
istrunc_is_structure_homomorphism : forallxyabf,
IsHProp (@is_structure_homomorphism x y a b f);
is_structure_homomorphism_identity : forallx (a : structure x),
is_structure_homomorphism (identity x) a a;
is_structure_homomorphism_composition : forallxyz
(a : structure x)
(b : structure y)
(c : structure z)
(f : morphism X x y)
(g : morphism X y z),
is_structure_homomorphism f a b
-> is_structure_homomorphism g b c
-> is_structure_homomorphism (g o f) a c
}.(** It would be nice to make this a class, but we can't:<< Existing Class is_structure_homomorphism.>> gives<< Toplevel input, characters 0-41: Anomaly: Mismatched instance and context when building universe substitution. Please report.>> When we move to polyproj, it won't anymore. *)Existing Instanceistrunc_is_structure_homomorphism.Create HintDb structure_homomorphisms discriminated.#[export]
Hint Resolve is_structure_homomorphism_identity is_structure_homomorphism_composition : structure_homomorphisms.(** When [(P, H)] is a notion of structure, for [α β : P x] we define [(α ≤ₓ β) := H_{αβ}(1ₓ)].*)LocalNotation"a <=_{ x } b" := (is_structure_homomorphism _ x x (identity x) a b) : long_structure_scope.LocalNotation"a <= b" := (a <=_{ _ } b)%long_structure : structure_scope.(** By (iii) and (iv), this is a preorder with [P x] its type of objects. *)(** *** Being a structure homomorphism is a preorder *)
X: PreCategory P: NotionOfStructure X x: X
PreOrder (is_structure_homomorphism P x x 1)
X: PreCategory P: NotionOfStructure X x: X
PreOrder (is_structure_homomorphism P x x 1)
X: PreCategory P: NotionOfStructure X x: X x0, y, z: P x X0: x0 <= y X1: y <= z
x0 <= z
X: PreCategory P: NotionOfStructure X x: X x0, y, z: P x X0: x0 <= y X1: y <= z
is_structure_homomorphism P x x (1 o 1) x0 z
eauto with structure_homomorphisms.Defined.(** *** Standard notion of structure *)(** We say that [(P, H)] is a _standard notion of structure_ if this preorder is in fact a partial order, for all [x : X]. *)(** A partial order is an antisymmetric preorder, i.e., we must have [a <= b <= a -> a = b]. *)ClassIsStandardNotionOfStructureX (P : NotionOfStructure X) :=
antisymmetry_structure : forallx (ab : P x),
a <= b -> b <= a -> a = b.(** Note that for a standard notion of structure, each type [P x] must actually be a set. *)
X: PreCategory P: NotionOfStructure X H: IsStandardNotionOfStructure P x: X
IsHSet (P x)
X: PreCategory P: NotionOfStructure X H: IsStandardNotionOfStructure P x: X
IsHSet (P x)
X: PreCategory P: NotionOfStructure X H: IsStandardNotionOfStructure P x: X
Reflexive (funab : P x => (a <= b) * (b <= a))
X: PreCategory P: NotionOfStructure X H: IsStandardNotionOfStructure P x: X
forallx0y : P x, (x0 <= y) * (y <= x0) -> x0 = y
X: PreCategory P: NotionOfStructure X H: IsStandardNotionOfStructure P x: X
Reflexive (funab : P x => (a <= b) * (b <= a))
repeatintro; split; applyreflexivity.
X: PreCategory P: NotionOfStructure X H: IsStandardNotionOfStructure P x: X
forallx0y : P x, (x0 <= y) * (y <= x0) -> x0 = y
intros ? ? [? ?]; apply antisymmetry_structure; assumption.Defined.(** *** Precategory of structures *)(** We now define, for any notion of structure [(P, H)], a _precategory of [(P, H)]-structures_, [A = Str_{(P, H)}(X)]. - The type of objects of [A] is the type [A₀ := ∑ₓ P x]. If [a ≡ (x; α)], we may write [|a| := x]. - For [(x; α) : A₀] and [(y; β) : A₀], we define [hom_A((x; α), (y; β)) := { f : x → y | H_{αβ}(f) }]. The composition and identities are inherited from [X]; conditions (iii) and (iv) ensure that these lift to [A]. *)ModulePreCategoryOfStructures.Sectionprecategory.(** We use [Records] because they are faster than sigma types. *)VariableX : PreCategory.VariableP : NotionOfStructure X.Local Notationobject := { x : X | P x }.(*Lemma issig_object : { x : X | P x } <~> object. Proof. issig Build_object x a. Defined. Lemma path_object : forall xa yb (H : x xa = x yb), transport P H (a xa) = a yb -> xa = yb. Proof. intros [? ?] [? ?] H H'; simpl in *; path_induction; reflexivity. Defined.*)Recordmorphism (xayb : object) :=
{ f : Category.Core.morphism X xa.1 yb.1;
h : is_structure_homomorphism _ _ _ f xa.2 yb.2 }.
X: PreCategory P: NotionOfStructure X xa, yb: {x : X & P x}
{f : Core.morphism X xa.1 yb.1 &
is_structure_homomorphism P xa.1 yb.1 f xa.2 yb.2} <~>
morphism xa yb
X: PreCategory P: NotionOfStructure X xa, yb: {x : X & P x}
{f : Core.morphism X xa.1 yb.1 &
is_structure_homomorphism P xa.1 yb.1 f xa.2 yb.2} <~>
morphism xa yb
issig.Defined.
X: PreCategory P: NotionOfStructure X
forall (xayb : {x : X & P x})
(fhgi : morphism xa yb), f fh = f gi -> fh = gi
X: PreCategory P: NotionOfStructure X
forall (xayb : {x : X & P x})
(fhgi : morphism xa yb), f fh = f gi -> fh = gi
X: PreCategory P: NotionOfStructure X xa, yb: {x : X & P x} f0: Core.morphism X xa.1 yb.1 h0, h1: is_structure_homomorphism P xa.1 yb.1 f0 xa.2
yb.2
h0 = h1
apply path_ishprop.Defined.Endprecategory.(*Global Arguments path_object {X P xa yb} H _.*)GlobalArguments path_morphism {X P xa yb fh gi} H.EndPreCategoryOfStructures.Sectionprecategory.Import PreCategoryOfStructures.
X: PreCategory P: NotionOfStructure X
PreCategory
X: PreCategory P: NotionOfStructure X
PreCategory
refine (@Build_PreCategory
_
(@morphism _ P)
(funxa => {| f := identity xa.1;
h := is_structure_homomorphism_identity _ _ xa.2 |})
(funxaybzcgifh => {| f := (f gi) o (f fh);
h := is_structure_homomorphism_composition _ _ _ _ _ _ _ _ _ (h fh) (h gi) |})
_
_
_
(funsd => istrunc_equiv_istrunc _ (issig_morphism P s d)));
simpl;
abstract (
repeatmatch goal with
| |- @morphism _ P _ _ -> _ => intros [? ?]; simplin *
| |- _ -> _ => introend;
first [ apply path_morphism; exact (associativity _ _ _ _ _ _ _ _)
| apply path_morphism; exact (left_identity _ _ _ _)
| apply path_morphism; exact (right_identity _ _ _ _) ]
).Defined.Endprecategory.ModuleExport StructureCoreNotations.Notation"a <=_{ x } b" := (is_structure_homomorphism _ x x (identity x) a b) : long_structure_scope.Notation"a <= b" := (a <=_{ _ } b)%long_structure : structure_scope.EndStructureCoreNotations.