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.
(** This file defines [Algebra]. *)
[Loading ML file number_string_notation_plugin.cmxs (using legacy method) ... done]
Require Import
HoTT.Types
HoTT.Universes.HSet
HoTT.Spaces.List.Core.Import ne_list.notations.Declare Scope Algebra_scope.Delimit Scope Algebra_scope with Algebra.Open Scope Algebra_scope.DefinitionSymbolType_internal : Type → Type := ne_list.(** A [Signature] is used to characterise [Algebra]s. In particular a signature specifies which operations (functions) an algebra for the signature is expected to provide. A signature consists of - A type of [Sort]s. An algebra for the signature must provide a type for each [s : Sort]. - A type of function symbols [Symbol]. For each function symbol [u : Symbol], an algebra for the signature must provide a corresponding operation. - The field [symbol_types σ u] indicates which type the operation corresponding to [u] should have. *)RecordSignature : Type := BuildSignature
{ Sort : Type
; Symbol : Type
; symbol_types : Symbol → SymbolType_internal Sort }.(** We have this implicit coercion allowing us to use a signature [σ:Signature] as a map [Symbol σ → SymbolType σ] (see [SymbolType] below). *)Global Coercionsymbol_types : Signature >-> Funclass.(** A single sorted [Signature] is a signature with [Sort = Unit]. *)DefinitionBuildSingleSortedSignature (sym : Type) (arities : sym → nat)
: Signature
:= BuildSignature Unit sym (ne_list.replicate_Sn tt o arities).(** Let [σ:Signature]. For each symbol [u : Symbol σ], [σ u] associates [u] to a [SymbolType σ]. This represents the required type of the algebra operation corresponding to [u]. *)DefinitionSymbolType (σ : Signature) : Type := ne_list (Sort σ).(** For [s : SymbolType σ], [cod_symboltype σ] is the codomain of the symbol type [s]. *)Definitioncod_symboltype {σ} : SymbolType σ → Sort σ
:= ne_list.last.(** For [s : SymbolType σ], [cod_symboltype σ] is the domain of the symbol type [s]. *)Definitiondom_symboltype {σ} : SymbolType σ → list (Sort σ)
:= ne_list.front.(** For [s : SymbolType σ], [cod_symboltype σ] is the arity of the symbol type [s]. That is the number [n:nat] of arguments of the [SymbolType σ]. *)Definitionarity_symboltype {σ} : SymbolType σ → nat
:= length o dom_symboltype.(** An [Algebra] must provide a family of [Carriers σ] indexed by [Sort σ]. These carriers are the "objects" (types) of the algebra. *)(* [Carriers] is a notation because it will be used for an implicit coercion [Algebra >-> Funclass] below. *)NotationCarriers σ := (Sort σ → Type).(** The function [Operation] maps a family of carriers [A : Carriers σ] and [w : SymbolType σ] to the corresponding function type.<< Operation A [:s1; s2; ...; sn; t:] = A s1 → A s2 → ... → A sn → A t>> where [[:s1; s2; ...; sn; t:] : SymbolType σ] is a symbol type with domain [[s1; s2; ...; sn]] and codomain [t]. *)FixpointOperation {σ} (A : Carriers σ) (w : SymbolType σ) : Type
:= match w with
| [:s:] => A s
| s ::: w' => A s → Operation A w'
end.
induction w; exact _.Defined.(** Uncurry of an [f : Operation A w], such that<< ap_operation f (x1,x2,...,xn) = f x1 x2 ... xn>>*)Fixpointap_operation {σ} {A : Carriers σ} {w : SymbolType σ}
: Operation A w →
FamilyProd A (dom_symboltype w) →
A (cod_symboltype w)
:= match w with
| [:s:] => λf_, f
| s ::: w' => λf '(x, l), ap_operation (f x) l
end.(** Funext for uncurried [Operation A w]. If<< ap_operation f (x1,x2,...,xn) = ap_operation g (x1,x2,...,xn)>> for all [(x1,x2,...,xn) : A s1 * A s2 * ... * A sn], then [f = g]. *)Fixpointpath_forall_ap_operation `{Funext} {σ : Signature}
{A : Carriers σ} {w : SymbolType σ}
: ∀ (fg : Operation A w),
(∀a : FamilyProd A (dom_symboltype w),
ap_operation f a = ap_operation g a)
-> f = g
:= match w with
| [:s:] => λ (fg : A s) p, p tt
| s ::: w' =>
λ (fg : A s → Operation A w') p,
path_forall f g
(λx, path_forall_ap_operation (f x) (g x) (λa, p (x,a)))
end.(** An [Algebra σ] for a signature [σ] consists of a family [carriers : Carriers σ] indexed by the sorts [s : Sort σ], and for each symbol [u : Symbol σ], an operation of type [Operation carriers (σ u)], where [σ u : SymbolType σ] is the symbol type of [u]. *)RecordAlgebra {σ : Signature} : Type := BuildAlgebra
{ carriers : Carriers σ
; operations : ∀ (u : Symbol σ), Operation carriers (σ u) }.Arguments Algebra : clear implicits.Arguments BuildAlgebra {σ} carriers operations.(** We have a convenient implicit coercion from an algebra to the family of carriers. *)Global Coercioncarriers : Algebra >-> Funclass.Bind Scope Algebra_scope with Algebra.DefinitionSigAlgebra (σ : Signature) : Type
:= {c : Carriers σ | ∀ (u : Symbol σ), Operation c (σ u) }.
σ: Signature
SigAlgebra σ <~> Algebra σ
σ: Signature
SigAlgebra σ <~> Algebra σ
issig.Defined.ClassIsTruncAlgebra (n : trunc_index) {σ : Signature} (A : Algebra σ)
:= trunc_carriers_algebra :: ∀ (s : Sort σ), IsTrunc n (A s).NotationIsHSetAlgebra := (IsTruncAlgebra 0).
σ: Signature A, B: Algebra σ p: A = B q: transport
(λX : Carriers σ,
forallu : Symbol σ, Operation X (σ u)) p
(operations A) = operations B
ap carriers (path_algebra A B p q) = p
σ: Signature A, B: Algebra σ p: A = B q: transport
(λX : Carriers σ,
forallu : Symbol σ, Operation X (σ u)) p
(operations A) = operations B
ap carriers (path_algebra A B p q) = p
σ: Signature A: Carriers σ a: forallu : Symbol σ, Operation A (σ u) B: Carriers σ b: forallu : Symbol σ, Operation B (σ u) p: {| carriers := A; operations := a |} =
{| carriers := B; operations := b |} q: transport
(λX : Carriers σ,
forallu : Symbol σ, Operation X (σ u)) p
(operations {| carriers := A; operations := a |}) =
operations {| carriers := B; operations := b |}
ap carriers
(path_algebra {| carriers := A; operations := a |}
{| carriers := B; operations := b |} p q) = p
σ: Signature A: Carriers σ a: forallu : Symbol σ, Operation A (σ u) B: Carriers σ b: forallu : Symbol σ, Operation B (σ u) p: A = B q: transport
(λX : Carriers σ,
forallu : Symbol σ, Operation X (σ u)) p a = b
ap carriers
(path_algebra {| carriers := A; operations := a |}
{| carriers := B; operations := b |} p q) = p
bydestruct p,q.Defined.(** Suppose [p],[q] are paths in [Algebra σ]. To show that [p = q] it suffices to find a path [r] between the paths corresponding to [p] and [q] in [SigAlgebra σ]. *)
σ: Signature A, B: Algebra σ p, q: A = B r: ap (issig_algebra σ)^-1 p =
ap (issig_algebra σ)^-1 q
p = q
σ: Signature A, B: Algebra σ p, q: A = B r: ap (issig_algebra σ)^-1 p =
ap (issig_algebra σ)^-1 q
p = q
σ: Signature A, B: Algebra σ p, q: A = B r: ap (issig_algebra σ)^-1 p =
ap (issig_algebra σ)^-1 q e:= equiv_ap (issig_algebra σ)^-1 A B: A = B <~>
(issig_algebra σ)^-1 A = (issig_algebra σ)^-1 B
p = q
byapply (@equiv_inv _ _ (ap e) (Equivalences.isequiv_ap _ _)).Defined.(** If [p q : A = B] and [IsHSetAlgebra B]. Then [ap carriers p = ap carriers q] implies [p = q]. *)
H: Funext σ: Signature A, B: Algebra σ IsHSetAlgebra0: IsHSetAlgebra B p, q: A = B r: ap carriers p = ap carriers q
p = q
H: Funext σ: Signature A, B: Algebra σ IsHSetAlgebra0: IsHSetAlgebra B p, q: A = B r: ap carriers p = ap carriers q
p = q
H: Funext σ: Signature A, B: Algebra σ IsHSetAlgebra0: IsHSetAlgebra B p, q: A = B r: ap carriers p = ap carriers q
ap (issig_algebra σ)^-1 p = ap (issig_algebra σ)^-1 q
H: Funext σ: Signature A, B: Algebra σ IsHSetAlgebra0: IsHSetAlgebra B p, q: A = B r: ap carriers p = ap carriers q
(ap (issig_algebra σ)^-1 p) ..1 =
(ap (issig_algebra σ)^-1 q) ..1
H: Funext σ: Signature A, B: Algebra σ IsHSetAlgebra0: IsHSetAlgebra B p, q: A = B r: ap carriers p = ap carriers q
transport
(λx : ((issig_algebra σ)^-1 A).1 =
((issig_algebra σ)^-1 B).1,
transport
(λc : Carriers σ,
forallu : Symbol σ, Operation c (σ u)) x
((issig_algebra σ)^-1 A).2 =
((issig_algebra σ)^-1 B).2)
?r (ap (issig_algebra σ)^-1 p) ..2 =
(ap (issig_algebra σ)^-1 q) ..2
H: Funext σ: Signature A, B: Algebra σ IsHSetAlgebra0: IsHSetAlgebra B p, q: A = B r: ap carriers p = ap carriers q
(ap (issig_algebra σ)^-1 p) ..1 =
(ap (issig_algebra σ)^-1 q) ..1
H: Funext σ: Signature A, B: Algebra σ IsHSetAlgebra0: IsHSetAlgebra B p, q: A = B r: ap carriers p = ap carriers q
ap carriers p = (ap (issig_algebra σ)^-1 q) ..1
transitivity (ap carriers q); [exact r | bydestruct q].
H: Funext σ: Signature A, B: Algebra σ IsHSetAlgebra0: IsHSetAlgebra B p, q: A = B r: ap carriers p = ap carriers q
transport
(λx : ((issig_algebra σ)^-1 A).1 =
((issig_algebra σ)^-1 B).1,
transport
(λc : Carriers σ,
forallu : Symbol σ, Operation c (σ u)) x
((issig_algebra σ)^-1 A).2 =
((issig_algebra σ)^-1 B).2)
(match
p in (_ = a)
return
(IsHSetAlgebra a ->
forallq : A = a,
ap carriers p = ap carriers q ->
(ap (issig_algebra σ)^-1 p) ..1 =
ap carriers p)
with
| 1 =>
λ (_ : IsHSetAlgebra A) (q : A = A)
(_ : ap carriers 1 = ap carriers q), 1end IsHSetAlgebra0 q r @
(r @
match
q as p in (_ = a)
return
(IsHSetAlgebra a ->
forallp0 : A = a,
ap carriers p0 = ap carriers p ->
ap carriers p =
(ap (issig_algebra σ)^-1 p) ..1)
with
| 1 =>
λ (_ : IsHSetAlgebra A) (p : A = A)
(_ : ap carriers p = ap carriers 1), 1end IsHSetAlgebra0 p r))
(ap (issig_algebra σ)^-1 p) ..2 =
(ap (issig_algebra σ)^-1 q) ..2
apply path_ishprop.Defined.Modulealgebra_notations.(** Given [A : Algebra σ] and function symbol [u : Symbol σ], we use the notation [u .# A] to refer to the corresponding algebra operation of type [Operation A (σ u)]. *)GlobalNotation"u .# A" := (operations A u) : Algebra_scope.Endalgebra_notations.