Built with Alectryon, running Coq+SerAPI v8.16.0+0.16.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.
From Tealeaves Require Export
Classes.Monoid
Classes.Categorical.Applicative
Tactics.Debug.Import Monoid.Notations.#[local] Generalizable VariablesW M N ϕ.#[local] Arguments map F%function_scope {Map}
{A B}%type_scope f%function_scope _.(** * Inductive Definition of the Constant Functor *)(**********************************************************************)InductiveConstV (tag: Type): Type :=
| mkConst: V -> Const V tag.Arguments mkConst {V tag}%type_scope v: rename.Definitionunconst {Vtag}: Const V tag -> V :=
fun '(mkConst c) => c.
V, A: Type
forallv : V, unconst (mkConst v) = v
V, A: Type
forallv : V, unconst (mkConst v) = v
nowintros.Qed.
V, A: Type
forallx : Const V A, mkConst (unconst x) = x
V, A: Type
forallx : Const V A, mkConst (unconst x) = x
nowintros [?].Qed.Definitionretag {VAB}: Const V A -> Const V B :=
mkConst ∘ unconst.#[global] InstanceMap_Const {V}: Map (Const V) :=
funABfx => mkConst (unconst x).#[global, program] InstanceEnd_Const {V}: Functor (Const V).Solve All Obligations with
(intros; now ext [?]).#[local] Hint Immediate unconst_mkConst mkConst_unconst: tea_applicative.#[global] Hint Rewrite (@unconst_mkConst)
(@mkConst_unconst): tea_applicative.
forall (VAB : Type) (f : A -> B) (x : Const V A),
unconst (map (Const V) f x) = unconst x
forall (VAB : Type) (f : A -> B) (x : Const V A),
unconst (map (Const V) f x) = unconst x
V, A, B: Type f: A -> B x: Const V A
unconst (map (Const V) f x) = unconst x
nowdestruct x.Qed.DefinitionmapConst {AB} (f: A -> B) {C}: Const A C -> Const B C :=
fun '(mkConst a) => mkConst (f a).
A, B: Type f: A -> B C: Type x: Const A C
f (unconst x) = unconst (mapConst f x)
A, B: Type f: A -> B C: Type x: Const A C
f (unconst x) = unconst (mapConst f x)
A, B: Type f: A -> B C: Type a: A
f a = f a
reflexivity.Qed.
A, B: Type f: A -> B C: Type
f ∘ unconst = unconst ∘ mapConst f
A, B: Type f: A -> B C: Type
f ∘ unconst = unconst ∘ mapConst f
A, B: Type f: A -> B C: Type a: A
(f ∘ unconst) (mkConst a) =
(unconst ∘ mapConst f) (mkConst a)
A, B: Type f: A -> B C: Type a: A
(f ∘ unconst) (mkConst a) = f a
apply mapConst_1.Qed.(** ** Monoids as Constant Applicative Functors *)(**********************************************************************)Sectionconst_ops.Context
`{Monoid M}.#[global] InstancePure_Const: Pure (Const M) :=
fun (A: Type) (a: A) => mkConst (tag := A) Ƶ.#[global] InstanceMult_Const: Mult (Const M) :=
funAB (p: Const M A * Const M B) =>
mkConst (tag := A * B) (unconst (fst p) ● unconst (snd p)).#[global, program] InstanceApplicative_Const `{Monoid M}:
Applicative (Const M).Solve Obligations with
(intros; unfold transparent tcs in *; cbn; simpl_monoid;
nowauto with tea_applicative).Endconst_ops.
M1, M2: Type f: M1 -> M2 op: Monoid_op M1 unit0: Monoid_unit M1 H: Monoid M1 op0: Monoid_op M2 unit1: Monoid_unit M2 H0: Monoid M2 Monoid_Morphism0: Monoid_Morphism M1 M2 f monmor_src: Monoid M1 monmor_tgt: Monoid M2 monmor_unit: f Ƶ = Ƶ monmor_op: foralla1a2 : M1,
f (a1 ● a2) = f a1 ● f a2
forall (AB : Type) (f0 : A -> B) (x : Const M1 A),
mapConst f (map (Const M1) f0 x) =
map (Const M2) f0 (mapConst f x)
M1, M2: Type f: M1 -> M2 op: Monoid_op M1 unit0: Monoid_unit M1 H: Monoid M1 op0: Monoid_op M2 unit1: Monoid_unit M2 H0: Monoid M2 Monoid_Morphism0: Monoid_Morphism M1 M2 f monmor_src: Monoid M1 monmor_tgt: Monoid M2 monmor_unit: f Ƶ = Ƶ monmor_op: foralla1a2 : M1,
f (a1 ● a2) = f a1 ● f a2
forall (A : Type) (a : A),
mapConst f (pure a) = pure a
M1, M2: Type f: M1 -> M2 op: Monoid_op M1 unit0: Monoid_unit M1 H: Monoid M1 op0: Monoid_op M2 unit1: Monoid_unit M2 H0: Monoid M2 Monoid_Morphism0: Monoid_Morphism M1 M2 f monmor_src: Monoid M1 monmor_tgt: Monoid M2 monmor_unit: f Ƶ = Ƶ monmor_op: foralla1a2 : M1,
f (a1 ● a2) = f a1 ● f a2
forall (AB : Type) (x : Const M1 A) (y : Const M1 B),
mapConst f (mult (x, y)) =
mult (mapConst f x, mapConst f y)
M1, M2: Type f: M1 -> M2 op: Monoid_op M1 unit0: Monoid_unit M1 H: Monoid M1 op0: Monoid_op M2 unit1: Monoid_unit M2 H0: Monoid M2 Monoid_Morphism0: Monoid_Morphism M1 M2 f monmor_src: Monoid M1 monmor_tgt: Monoid M2 monmor_unit: f Ƶ = Ƶ monmor_op: foralla1a2 : M1,
f (a1 ● a2) = f a1 ● f a2
forall (AB : Type) (f0 : A -> B) (x : Const M1 A),
mapConst f (map (Const M1) f0 x) =
map (Const M2) f0 (mapConst f x)
M1, M2: Type f: M1 -> M2 op: Monoid_op M1 unit0: Monoid_unit M1 H: Monoid M1 op0: Monoid_op M2 unit1: Monoid_unit M2 H0: Monoid M2 Monoid_Morphism0: Monoid_Morphism M1 M2 f monmor_src: Monoid M1 monmor_tgt: Monoid M2 monmor_unit: f Ƶ = Ƶ monmor_op: foralla1a2 : M1,
f (a1 ● a2) = f a1 ● f a2 A, B: Type f0: A -> B x: Const M1 A
mapConst f (map (Const M1) f0 x) =
map (Const M2) f0 (mapConst f x)
M1, M2: Type f: M1 -> M2 op: Monoid_op M1 unit0: Monoid_unit M1 H: Monoid M1 op0: Monoid_op M2 unit1: Monoid_unit M2 H0: Monoid M2 Monoid_Morphism0: Monoid_Morphism M1 M2 f monmor_src: Monoid M1 monmor_tgt: Monoid M2 monmor_unit: f Ƶ = Ƶ monmor_op: foralla1a2 : M1,
f (a1 ● a2) = f a1 ● f a2 A, B: Type f0: A -> B m: M1
mapConst f (map (Const M1) f0 (mkConst m)) =
map (Const M2) f0 (mapConst f (mkConst m))
reflexivity.
M1, M2: Type f: M1 -> M2 op: Monoid_op M1 unit0: Monoid_unit M1 H: Monoid M1 op0: Monoid_op M2 unit1: Monoid_unit M2 H0: Monoid M2 Monoid_Morphism0: Monoid_Morphism M1 M2 f monmor_src: Monoid M1 monmor_tgt: Monoid M2 monmor_unit: f Ƶ = Ƶ monmor_op: foralla1a2 : M1,
f (a1 ● a2) = f a1 ● f a2
forall (A : Type) (a : A),
mapConst f (pure a) = pure a
M1, M2: Type f: M1 -> M2 op: Monoid_op M1 unit0: Monoid_unit M1 H: Monoid M1 op0: Monoid_op M2 unit1: Monoid_unit M2 H0: Monoid M2 Monoid_Morphism0: Monoid_Morphism M1 M2 f monmor_src: Monoid M1 monmor_tgt: Monoid M2 monmor_unit: f Ƶ = Ƶ monmor_op: foralla1a2 : M1,
f (a1 ● a2) = f a1 ● f a2 A: Type a: A
mapConst f (pure a) = pure a
M1, M2: Type f: M1 -> M2 op: Monoid_op M1 unit0: Monoid_unit M1 H: Monoid M1 op0: Monoid_op M2 unit1: Monoid_unit M2 H0: Monoid M2 Monoid_Morphism0: Monoid_Morphism M1 M2 f monmor_src: Monoid M1 monmor_tgt: Monoid M2 monmor_unit: f Ƶ = Ƶ monmor_op: foralla1a2 : M1,
f (a1 ● a2) = f a1 ● f a2 A: Type a: A
mkConst (f Ƶ) = pure a
M1, M2: Type f: M1 -> M2 op: Monoid_op M1 unit0: Monoid_unit M1 H: Monoid M1 op0: Monoid_op M2 unit1: Monoid_unit M2 H0: Monoid M2 Monoid_Morphism0: Monoid_Morphism M1 M2 f monmor_src: Monoid M1 monmor_tgt: Monoid M2 monmor_unit: f Ƶ = Ƶ monmor_op: foralla1a2 : M1,
f (a1 ● a2) = f a1 ● f a2 A: Type a: A
mkConst Ƶ = pure a
reflexivity.
M1, M2: Type f: M1 -> M2 op: Monoid_op M1 unit0: Monoid_unit M1 H: Monoid M1 op0: Monoid_op M2 unit1: Monoid_unit M2 H0: Monoid M2 Monoid_Morphism0: Monoid_Morphism M1 M2 f monmor_src: Monoid M1 monmor_tgt: Monoid M2 monmor_unit: f Ƶ = Ƶ monmor_op: foralla1a2 : M1,
f (a1 ● a2) = f a1 ● f a2
forall (AB : Type) (x : Const M1 A) (y : Const M1 B),
mapConst f (mult (x, y)) =
mult (mapConst f x, mapConst f y)
M1, M2: Type f: M1 -> M2 op: Monoid_op M1 unit0: Monoid_unit M1 H: Monoid M1 op0: Monoid_op M2 unit1: Monoid_unit M2 H0: Monoid M2 Monoid_Morphism0: Monoid_Morphism M1 M2 f monmor_src: Monoid M1 monmor_tgt: Monoid M2 monmor_unit: f Ƶ = Ƶ monmor_op: foralla1a2 : M1,
f (a1 ● a2) = f a1 ● f a2 A, B: Type x: Const M1 A y: Const M1 B
mapConst f (mult (x, y)) =
mult (mapConst f x, mapConst f y)
M1, M2: Type f: M1 -> M2 op: Monoid_op M1 unit0: Monoid_unit M1 H: Monoid M1 op0: Monoid_op M2 unit1: Monoid_unit M2 H0: Monoid M2 Monoid_Morphism0: Monoid_Morphism M1 M2 f monmor_src: Monoid M1 monmor_tgt: Monoid M2 monmor_unit: f Ƶ = Ƶ monmor_op: foralla1a2 : M1,
f (a1 ● a2) = f a1 ● f a2 A, B: Type m, m0: M1
mapConst f (mult (mkConst m, mkConst m0)) =
mult (mapConst f (mkConst m), mapConst f (mkConst m0))
M1, M2: Type f: M1 -> M2 op: Monoid_op M1 unit0: Monoid_unit M1 H: Monoid M1 op0: Monoid_op M2 unit1: Monoid_unit M2 H0: Monoid M2 Monoid_Morphism0: Monoid_Morphism M1 M2 f monmor_src: Monoid M1 monmor_tgt: Monoid M2 monmor_unit: f Ƶ = Ƶ monmor_op: foralla1a2 : M1,
f (a1 ● a2) = f a1 ● f a2 A, B: Type m, m0: M1
mkConst (f (m ● m0)) =
mult (mkConst (f m), mkConst (f m0))
M1, M2: Type f: M1 -> M2 op: Monoid_op M1 unit0: Monoid_unit M1 H: Monoid M1 op0: Monoid_op M2 unit1: Monoid_unit M2 H0: Monoid M2 Monoid_Morphism0: Monoid_Morphism M1 M2 f monmor_src: Monoid M1 monmor_tgt: Monoid M2 monmor_unit: f Ƶ = Ƶ monmor_op: foralla1a2 : M1,
f (a1 ● a2) = f a1 ● f a2 A, B: Type m, m0: M1
mkConst (f m ● f m0) =
mult (mkConst (f m), mkConst (f m0))
reflexivity.Qed.(** * Computational Definition of the Constant Functor *)(**********************************************************************)Sectionconstant_functor.Definitionretag_const {AXY: Type}:
const A X -> const A Y := @id A.(** First we establish that (const M) is an applicative functor. *)Sectionwith_monoid.Context
`{Monoid M}.#[global] InstanceMap_const: Map (const M) :=
funXYft => t.
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
forall (XY : Type) (f : X -> Y), map (const M) f = id
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
forall (XY : Type) (f : X -> Y), map (const M) f = id
reflexivity.Qed.(** ** Monoids as Constant Applicative Functors *)(******************************************************************)#[global] InstancePure_const: Pure (const M) :=
funXx => Ƶ.#[global] InstanceMult_const: Mult (const M) :=
funXY '(x, y) => x ● y.
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
Applicative (const M)
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
Applicative (const M)
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
Functor (const M)
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A, B, C: Type x: const M A y: const M B z: const M C
map (const M) associator (mult (mult (x, y), z)) =
mult (x, mult (y, z))
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A: Type x: const M A
map (const M) left_unitor (mult (pure tt, x)) = x
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A: Type x: const M A
map (const M) right_unitor (mult (x, pure tt)) = x
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A, B: Type a: A b: B
mult (pure a, pure b) = pure (a, b)
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
Functor (const M)
constructor; reflexivity.
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A, B, C: Type x: const M A y: const M B z: const M C
map (const M) associator (mult (mult (x, y), z)) =
mult (x, mult (y, z))
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A, B, C: Type x: const M A y: const M B z: const M C
(x ● y) ● z = x ● (y ● z)
now Monoid.simpl_monoid.
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A: Type x: const M A
map (const M) left_unitor (mult (pure tt, x)) = x
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A: Type x: const M A
pure tt ● x = x
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A: Type x: const M A
Ƶ ● x = x
now Monoid.simpl_monoid.
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A: Type x: const M A
map (const M) right_unitor (mult (x, pure tt)) = x
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A: Type x: const M A
x ● pure tt = x
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A: Type x: const M A
x ● Ƶ = x
now Monoid.simpl_monoid.
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A, B: Type a: A b: B
mult (pure a, pure b) = pure (a, b)
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A, B: Type a: A b: B
pure a ● pure b = pure (a, b)
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A, B: Type a: A b: B
Ƶ ● Ƶ = Ƶ
now Monoid.simpl_monoid.Qed.
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
ApplicativeMorphism (Const M) (const M)
(funX : Type => unconst)
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
ApplicativeMorphism (Const M) (const M)
(funX : Type => unconst)
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M N: Type op0: Monoid_op N unit1: Monoid_unit N H0: Monoid N ϕ: M -> N hom: Monoid_Morphism M N ϕ
ApplicativeMorphism (const M) (const N) (const ϕ)
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M N: Type op0: Monoid_op N unit1: Monoid_unit N H0: Monoid N ϕ: M -> N hom: Monoid_Morphism M N ϕ
ApplicativeMorphism (const M) (const N) (const ϕ)
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M N: Type op0: Monoid_op N unit1: Monoid_unit N H0: Monoid N ϕ: M -> N hom: Monoid_Morphism M N ϕ monmor_src: Monoid M monmor_tgt: Monoid N monmor_unit: ϕ Ƶ = Ƶ monmor_op: foralla1a2 : M,
ϕ (a1 ● a2) = ϕ a1 ● ϕ a2
ApplicativeMorphism (const M) (const N) (const ϕ)
constructor; nowtrytypeclasses eauto.Qed.
F: Type -> Type Map_F: Map F H: Functor F M: Type
Map_compose F (const M) = Map_const
F: Type -> Type Map_F: Map F H: Functor F M: Type
Map_compose F (const M) = Map_const
F: Type -> Type Map_F: Map F H: Functor F M, A', B': Type f': A' -> B' t: (F ∘ const M) A'
Map_compose F (const M) A' B' f' t =
Map_const A' B' f' t
F: Type -> Type Map_F: Map F H: Functor F M, A', B': Type f': A' -> B' t: (F ∘ const M) A'
map F (funt : const M A' => t) t = t
F: Type -> Type Map_F: Map F H: Functor F M, A', B': Type f': A' -> B' t: (F ∘ const M) A'
id t = t
reflexivity.Qed.
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G M: Type op: Monoid_op M unit0: Monoid_unit M H0: Monoid M
Mult_compose G (const M) = Mult_const
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G M: Type op: Monoid_op M unit0: Monoid_unit M H0: Monoid M
Mult_compose G (const M) = Mult_const
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G M: Type op: Monoid_op M unit0: Monoid_unit M H0: Monoid M A', B': Type m1: (G ∘ const M) A' m2: (G ∘ const M) B'
Mult_compose G (const M) A' B' (m1, m2) =
Mult_const A' B' (m1, m2)
reflexivity.Qed.Endconstant_functor.(** * Simplification Support *)(**********************************************************************)
forall (A : Type) (a : A) (M : Type)
(unit : Monoid_unit M), pure a = Ƶ
forall (A : Type) (a : A) (M : Type)
(unit : Monoid_unit M), pure a = Ƶ
reflexivity.Qed.
forall (M : Type) (op : Monoid_op M) (AB : Type)
(x : const M (A -> B)) (y : const M A),
ap (const M) x y = x ● y
forall (M : Type) (op : Monoid_op M) (AB : Type)
(x : const M (A -> B)) (y : const M A),
ap (const M) x y = x ● y
forall (M : Type) (op : Monoid_op M) (AB : Type)
(x : @const TypeType M (forall_ : A, B))
(y : @const TypeType M A),
@eq (@const TypeType M B)
(@ap (@const TypeType M) (@Map_const M)
(@Mult_const M op) A B x y) (@monoid_op M op x y)
M: Type op: Monoid_op M A, B: Type x: @const TypeType M (forall_ : A, B) y: @const TypeType M A
@eq (@const TypeType M B)
(@ap (@const TypeType M) (@Map_const M)
(@Mult_const M op) A B x y) (@monoid_op M op x y)
reflexivity.Qed.
forall (AB : Type) (f : forall_ : A, B) (X : Type),
@eq
(forall_ : @const TypeType X A,
@const TypeType X B)
(@map (@const TypeType X) (@Map_const X) A B f)
(@id X)
forall (AB : Type) (f : forall_ : A, B) (X : Type),
@eq
(forall_ : @const TypeType X A,
@const TypeType X B)
(@map (@const TypeType X) (@Map_const X) A B f)
(@id X)
reflexivity.Qed.(** ** Constant applicatives *)(**********************************************************************)Ltacsimplify_applicative_const :=
ltac_trace "simplify_applicative_const";
match goal with
| |- context [pure (F := const ?W) ?x] =>
rewrite pure_const_rw
| |- context[(ap (const ?W) ?x?y)] =>
rewrite ap_const_rw
end.Ltacsimplify_applicative_const_in :=
match goal with
| H: context [pure (F := const ?W) ?x] |- _ =>
rewrite pure_const_rw in H
| H: context[(ap (const ?W) ?x?y)] |- _ =>
rewrite ap_const_rw in H
end.(** ** Constant maps *)(**********************************************************************)Ltacsimplify_map_const :=
ltac_trace "simplify_map_const";
match goal with
| |- context[map (const ?X) ?f] =>
rewrite map_const_rw
end.Ltacsimplify_map_const_in :=
match goal with
| H: context[map (const ?X) ?f] |- _ =>
rewrite map_const_rw in H
end.