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
Misc.Prop
Classes.Functor
Classes.Monoid.From Tealeaves Require Import
Classes.Categorical.ApplicativeCommutativeIdempotent
Classes.Kleisli.Monad
Tactics.Debug.Import Kleisli.Monad.Notations.#[local] Generalizable VariablesA B.(** * Subsets *)(**********************************************************************)#[local] Notation"( -> B )" := (funA => A -> B) (at level50).#[local] Notation"'subset'" := ((-> Prop)).(** ** Operations *)(**********************************************************************)Definitionsubset_one {A}: A -> subset A := eq.Definitionsubset_empty {A}: subset A :=
const False.Definitionsubset_add {A}: subset A -> subset A -> subset A :=
funxyp => x p \/ y p.(** ** Notations and Tactics *)(**********************************************************************)ModuleNotations.Notation"∅" := subset_empty: tealeaves_scope.Notation"{{ x }}" := (subset_one x): tealeaves_scope.Infix"∪" :=
subset_add (at level61, left associativity): tealeaves_scope.Notation"( -> B )" :=
(funA => A -> B) (at level50): tealeaves_scope.Notation"'subset'" := ((-> Prop)): tealeaves_scope.EndNotations.Import Notations.Tactic Notation"simpl_subset" :=
(autorewrite with tea_set).Tactic Notation"simpl_subset""in" hyp(H) :=
(autorewrite with tea_set in H).Tactic Notation"simpl_subset""in""*" :=
(autorewrite with tea_set in *).Ltacunfold_subset :=
unfold subset_empty; unfold subset_add; unfold const.Ltacsolve_basic_subset :=
unfold transparent tcs; unfold_subset; unfold compose; try setext;
first [tauto | firstorder (subst; (solveauto + eauto)) ].(** * The <<subset>> Monoid *)(**********************************************************************)Sectionsubset_monoid.Context
{A: Type}.Implicit Types (st: subset A) (a: A).Definitionsubset_add_nil_l: foralls, s ∪ ∅ = s :=
ltac:(solve_basic_subset).Definitionsubset_add_nil_r: foralls, ∅ ∪ s = s :=
ltac:(solve_basic_subset).Definitionsubset_add_assoc: forallstu, s ∪ t ∪ u = s ∪ (t ∪ u) :=
ltac:(solve_basic_subset).Definitionsubset_add_comm: forallst, s ∪ t = t ∪ s :=
ltac:(solve_basic_subset).Definitionsubset_in_empty: foralla, ∅ a = False
:= ltac:(solve_basic_subset).Definitionsubset_in_add: forallsta, (s ∪ t) a = (s a \/ t a)
:= ltac:(solve_basic_subset).Definitionsubset_in_one: forallaa', {{a}} a' = (a = a')
:= ltac:(solve_basic_subset).Endsubset_monoid.#[export] Hint Rewrite @subset_add_nil_l @subset_add_nil_r
@subset_add_assoc @subset_in_empty @subset_in_add @subset_in_one: tea_set.#[export] InstanceMonoid_op_subset {A}:
Monoid_op (subset A) := @subset_add A.#[export] InstanceMonoid_unit_subset {A}:
Monoid_unit (subset A) := subset_empty.#[export, program] InstanceMonoid_subset {A}:
@Monoid (subset A) (@Monoid_op_subset A) (@Monoid_unit_subset A).Solve Obligations with
(intros; unfold transparent tcs; solve_basic_subset).
reflexivity.Qed.Ltacsimplify_monoid_subset :=
ltac_trace "simplify_monoid_subset";
match goal with
| |- context[monoid_op (Monoid_op := Monoid_op_subset) ?S1?S2] =>
rewrite monoid_subset_rw
| |- context[monoid_unit _ (Monoid_unit := Monoid_unit_subset)] =>
rewrite monoid_subset_unit_rw
end.(** ** Querying for an Element is a Monoid Homomorphism *)(**********************************************************************)
A: Type a: A
Monoid_Morphism (subset%tea A) Prop (evalAt a)
A: Type a: A
Monoid_Morphism (subset%tea A) Prop (evalAt a)
A: Type a: A
Monoid (A -> Prop)
A: Type a: A
Monoid Prop
A: Type a: A
evalAt a (monoid_unit (A -> Prop)) = monoid_unit Prop
A: Type a: A
foralla1a2 : A -> Prop,
evalAt a (monoid_op a1 a2) =
monoid_op (evalAt a a1) (evalAt a a2)
A: Type a: A
Monoid (A -> Prop)
typeclasses eauto.
A: Type a: A
Monoid Prop
typeclasses eauto.
A: Type a: A
evalAt a (monoid_unit (A -> Prop)) = monoid_unit Prop
reflexivity.
A: Type a: A
foralla1a2 : A -> Prop,
evalAt a (monoid_op a1 a2) =
monoid_op (evalAt a a1) (evalAt a a2)
reflexivity.Qed.(** * Functor Instance *)(**********************************************************************)(** ** The Map Operation *)(**********************************************************************)#[export] InstanceMap_subset: Map subset :=
funABfsb => exists (a: A), s a /\ f a = b.(** ** Rewriting Laws *)(**********************************************************************)Definitionmap_set_nil `{f: A -> B}:
map f ∅ = ∅ := ltac:(solve_basic_subset).
A, B: Type f: A -> B a: A
map f {{a}} = {{f a}}
A, B: Type f: A -> B a: A
map f {{a}} = {{f a}}
A, B: Type f: A -> B a: A b: B
map f {{a}} b = {{f a}} b
A, B: Type f: A -> B a: A b: B
map f {{a}} b -> {{f a}} b
A, B: Type f: A -> B a: A b: B
{{f a}} b -> map f {{a}} b
A, B: Type f: A -> B a: A b: B
map f {{a}} b -> {{f a}} b
A, B: Type f: A -> B a: A b: B a': A Hin: {{a}} a' Heq: f a' = b
{{f a}} b
A, B: Type f: A -> B a': A
{{f a'}} (f a')
solve_basic_subset.
A, B: Type f: A -> B a: A b: B
{{f a}} b -> map f {{a}} b
A, B: Type f: A -> B a: A b: B
f a = b -> existsa0 : A, a = a0 /\ f a0 = b
A, B: Type f: A -> B a: A
existsa0 : A, a = a0 /\ f a0 = f a
eauto.Qed.Definitionmap_set_add `{f: A -> B} {x y}:
map f (x ∪ y) = map f x ∪ map f y
:= ltac:(solve_basic_subset).#[export] Hint Rewrite
@map_set_nil @map_set_one @map_set_add
: tea_set.(** ** Functor Laws *)(**********************************************************************)
forallA : Type, map id = id
forallA : Type, map id = id
A: Type
map id = id
A: Type s: A -> Prop a: A
map id s a = id s a
A: Type s: A -> Prop a: A
(existsa0 : A, s a0 /\ a0 = a) = s a
A: Type s: A -> Prop a: A
(existsa0 : A, s a0 /\ a0 = a) -> s a
A: Type s: A -> Prop a: A
s a -> existsa0 : A, s a0 /\ a0 = a
A: Type s: A -> Prop a: A
(existsa0 : A, s a0 /\ a0 = a) -> s a
A: Type s: A -> Prop a, a': A Hin: s a' Heq: a' = a
s a
nowsubst.
A: Type s: A -> Prop a: A
s a -> existsa0 : A, s a0 /\ a0 = a
A: Type s: A -> Prop a: A H: s a
existsa0 : A, s a0 /\ a0 = a
eauto.Qed.
forall (ABC : Type) (f : A -> B) (g : B -> C),
map g ∘ map f = map (g ∘ f)
forall (ABC : Type) (f : A -> B) (g : B -> C),
map g ∘ map f = map (g ∘ f)
A, B, C: Type f: A -> B g: B -> C
map g ∘ map f = map (g ∘ f)
A, B, C: Type f: A -> B g: B -> C s: A -> Prop c: C
(map g ∘ map f) s c = map (g ∘ f) s c
A, B, C: Type f: A -> B g: B -> C s: A -> Prop c: C
map g (map f s) c = map (g ○ f) s c
A, B, C: Type f: A -> B g: B -> C s: A -> Prop c: C
(existsa : B,
(existsa0 : A, s a0 /\ f a0 = a) /\ g a = c) =
(existsa : A, s a /\ g (f a) = c)
A, B, C: Type f: A -> B g: B -> C s: A -> Prop c: C
(existsa : B,
(existsa0 : A, s a0 /\ f a0 = a) /\ g a = c) ->
existsa : A, s a /\ g (f a) = c
A, B, C: Type f: A -> B g: B -> C s: A -> Prop c: C
(existsa : A, s a /\ g (f a) = c) ->
existsa : B,
(existsa0 : A, s a0 /\ f a0 = a) /\ g a = c
A, B, C: Type f: A -> B g: B -> C s: A -> Prop c: C
(existsa : B,
(existsa0 : A, s a0 /\ f a0 = a) /\ g a = c) ->
existsa : A, s a /\ g (f a) = c
A, B, C: Type f: A -> B g: B -> C s: A -> Prop c: C b: B a: A Hina: s a Heqa: f a = b Heq: g b = c
existsa : A, s a /\ g (f a) = c
A, B, C: Type f: A -> B g: B -> C s: A -> Prop c: C b: B a: A Hina: s a Heqa: f a = b Heq: g b = c
s a /\ g (f a) = c
A, B, C: Type f: A -> B g: B -> C s: A -> Prop c: C b: B a: A Hina: s a Heqa: f a = b Heq: g b = c
s a /\ g b = c
eauto.
A, B, C: Type f: A -> B g: B -> C s: A -> Prop c: C
(existsa : A, s a /\ g (f a) = c) ->
existsa : B,
(existsa0 : A, s a0 /\ f a0 = a) /\ g a = c
A, B, C: Type f: A -> B g: B -> C s: A -> Prop c: C a: A Hin: s a Heq: g (f a) = c
existsa : B,
(existsa0 : A, s a0 /\ f a0 = a) /\ g a = c
eauto.Qed.#[export] InstanceFunctor_subset: Functor subset :=
{| fun_map_id := map_id_subset;
fun_map_map := map_map_subset;
|}.(** ** Mapping is a Monoid Homomorphism *)(**********************************************************************)
forall (AB : Type) (f : A -> B),
Monoid_Morphism (subset%tea A) (subset%tea B) (map f)
forall (AB : Type) (f : A -> B),
Monoid_Morphism (subset%tea A) (subset%tea B) (map f)
A, B: Type f: A -> B
Monoid_Morphism (subset%tea A) (subset%tea B) (map f)
A, B: Type f: A -> B
Monoid (A -> Prop)
A, B: Type f: A -> B
Monoid (B -> Prop)
A, B: Type f: A -> B
map f (monoid_unit (A -> Prop)) =
monoid_unit (B -> Prop)
A, B: Type f: A -> B
foralla1a2 : A -> Prop,
map f (monoid_op a1 a2) =
monoid_op (map f a1) (map f a2)
A, B: Type f: A -> B
Monoid (A -> Prop)
typeclasses eauto.
A, B: Type f: A -> B
Monoid (B -> Prop)
typeclasses eauto.
A, B: Type f: A -> B
map f (monoid_unit (A -> Prop)) =
monoid_unit (B -> Prop)
A, B: Type f: A -> B b: B
map f (monoid_unit (A -> Prop)) b =
monoid_unit (B -> Prop) b
A, B: Type f: A -> B b: B
map f (monoid_unit (A -> Prop)) b <->
monoid_unit (B -> Prop) b
firstorder.
A, B: Type f: A -> B
foralla1a2 : A -> Prop,
map f (monoid_op a1 a2) =
monoid_op (map f a1) (map f a2)
A, B: Type f: A -> B a1, a2: A -> Prop
map f (monoid_op a1 a2) =
monoid_op (map f a1) (map f a2)
A, B: Type f: A -> B a1, a2: A -> Prop b: B
map f (monoid_op a1 a2) b =
monoid_op (map f a1) (map f a2) b
A, B: Type f: A -> B a1, a2: A -> Prop b: B
map f (monoid_op a1 a2) b <->
monoid_op (map f a1) (map f a2) b
forall (AB : Type) (f : A -> B),
map f ∘ ret = ret ∘ map f
Functor (funA : Type => A)
typeclasses eauto.
Functor subset%tea
typeclasses eauto.
forall (AB : Type) (f : A -> B),
map f ∘ ret = ret ∘ map f
A, B: Type f: A -> B
map f ∘ ret = ret ∘ map f
A, B: Type f: A -> B a: A
(map f ∘ ret) a = (ret ∘ map f) a
A, B: Type f: A -> B a: A b: B
(map f ∘ ret) a b = (ret ∘ map f) a b
A, B: Type f: A -> B a: A b: B
((fun (s : A -> Prop) (b : B) =>
existsa : A, s a /\ f a = b)
∘ (funab : A => a = b)) a b =
((funab : B => a = b) ∘ f) a b
A, B: Type f: A -> B a: A b: B
(existsa0 : A, a = a0 /\ f a0 = b) = (f a = b)
A, B: Type f: A -> B a: A b: B
(existsa0 : A, a = a0 /\ f a0 = b) -> f a = b
A, B: Type f: A -> B a: A b: B
f a = b -> existsa0 : A, a = a0 /\ f a0 = b
A, B: Type f: A -> B a: A b: B
f a = b -> existsa0 : A, a = a0 /\ f a0 = b
firstorder (nowsubst).Qed.
forall (AB : Type) (f : A -> B),
map f ∘ Monad.join = Monad.join ∘ map f
forall (AB : Type) (f : A -> B),
map f ∘ Monad.join = Monad.join ∘ map f
A, B: Type f: A -> B
map f ∘ Monad.join = Monad.join ∘ map f
A, B: Type f: A -> B
map f ○ Monad.join = Monad.join ○ map f
A, B: Type f: A -> B
(fun (a : (A -> Prop) -> Prop) (b : B) =>
existsa0 : A,
(existsQ : A -> Prop, a Q /\ Q a0) /\ f a0 = b) =
(fun (a : (A -> Prop) -> Prop) (a0 : B) =>
existsQ : B -> Prop,
(existsa1 : A -> Prop,
a a1 /\
(funb : B => existsa2 : A, a1 a2 /\ f a2 = b) =
Q) /\ Q a0)
A, B: Type f: A -> B P: (A -> Prop) -> Prop b: B
(existsa : A,
(existsQ : A -> Prop, P Q /\ Q a) /\ f a = b) =
(existsQ : B -> Prop,
(existsa : A -> Prop,
P a /\
(funb : B => existsa0 : A, a a0 /\ f a0 = b) =
Q) /\ Q b)
A, B: Type f: A -> B P: (A -> Prop) -> Prop b: B
(existsa : A,
(existsQ : A -> Prop, P Q /\ Q a) /\ f a = b) ->
existsQ : B -> Prop,
(existsa : A -> Prop,
P a /\
(funb : B => existsa0 : A, a a0 /\ f a0 = b) =
Q) /\ Q b
A, B: Type f: A -> B P: (A -> Prop) -> Prop b: B
(existsQ : B -> Prop,
(existsa : A -> Prop,
P a /\
(funb : B => existsa0 : A, a a0 /\ f a0 = b) =
Q) /\ Q b) ->
existsa : A,
(existsQ : A -> Prop, P Q /\ Q a) /\ f a = b
A, B: Type f: A -> B P: (A -> Prop) -> Prop b: B
(existsa : A,
(existsQ : A -> Prop, P Q /\ Q a) /\ f a = b) ->
existsQ : B -> Prop,
(existsa : A -> Prop,
P a /\
(funb : B => existsa0 : A, a a0 /\ f a0 = b) =
Q) /\ Q b
A, B: Type f: A -> B P: (A -> Prop) -> Prop b: B a: A Q: A -> Prop PQ: P Q Qa: Q a Heq: f a = b
existsQ : B -> Prop,
(existsa : A -> Prop,
P a /\
(funb : B => existsa0 : A, a a0 /\ f a0 = b) =
Q) /\ Q b
A, B: Type f: A -> B P: (A -> Prop) -> Prop a: A Q: A -> Prop PQ: P Q Qa: Q a
existsQ : B -> Prop,
(existsa : A -> Prop,
P a /\
(funb : B => existsa0 : A, a a0 /\ f a0 = b) =
Q) /\ Q (f a)
A, B: Type f: A -> B P: (A -> Prop) -> Prop a: A Q: A -> Prop PQ: P Q Qa: Q a
(existsa : A -> Prop,
P a /\
(funb : B => existsa0 : A, a a0 /\ f a0 = b) =
map f Q) /\ map f Q (f a)
A, B: Type f: A -> B P: (A -> Prop) -> Prop a: A Q: A -> Prop PQ: P Q Qa: Q a
(existsa : A -> Prop,
P a /\
(funb : B => existsa0 : A, a a0 /\ f a0 = b) =
(funb : B => existsa0 : A, Q a0 /\ f a0 = b)) /\
(existsa0 : A, Q a0 /\ f a0 = f a)
A, B: Type f: A -> B P: (A -> Prop) -> Prop a: A Q: A -> Prop PQ: P Q Qa: Q a
existsa : A -> Prop,
P a /\
(funb : B => existsa0 : A, a a0 /\ f a0 = b) =
(funb : B => existsa0 : A, Q a0 /\ f a0 = b)
A, B: Type f: A -> B P: (A -> Prop) -> Prop a: A Q: A -> Prop PQ: P Q Qa: Q a
existsa0 : A, Q a0 /\ f a0 = f a
A, B: Type f: A -> B P: (A -> Prop) -> Prop a: A Q: A -> Prop PQ: P Q Qa: Q a
existsa : A -> Prop,
P a /\
(funb : B => existsa0 : A, a a0 /\ f a0 = b) =
(funb : B => existsa0 : A, Q a0 /\ f a0 = b)
A, B: Type f: A -> B P: (A -> Prop) -> Prop a: A Q: A -> Prop PQ: P Q Qa: Q a
P Q /\
(funb : B => existsa : A, Q a /\ f a = b) =
(funb : B => existsa : A, Q a /\ f a = b)
A, B: Type f: A -> B P: (A -> Prop) -> Prop a: A Q: A -> Prop PQ: P Q Qa: Q a
P Q
A, B: Type f: A -> B P: (A -> Prop) -> Prop a: A Q: A -> Prop PQ: P Q Qa: Q a
(funb : B => existsa : A, Q a /\ f a = b) =
(funb : B => existsa : A, Q a /\ f a = b)
A, B: Type f: A -> B P: (A -> Prop) -> Prop a: A Q: A -> Prop PQ: P Q Qa: Q a
P Q
assumption.
A, B: Type f: A -> B P: (A -> Prop) -> Prop a: A Q: A -> Prop PQ: P Q Qa: Q a
(funb : B => existsa : A, Q a /\ f a = b) =
(funb : B => existsa : A, Q a /\ f a = b)
A, B: Type f: A -> B P: (A -> Prop) -> Prop a: A Q: A -> Prop PQ: P Q Qa: Q a
(funb : B => existsa : A, Q a /\ f a = b) =
(funb : B => existsa : A, Q a /\ f a = b)
setext; firstorder.}
A, B: Type f: A -> B P: (A -> Prop) -> Prop a: A Q: A -> Prop PQ: P Q Qa: Q a
existsa0 : A, Q a0 /\ f a0 = f a
firstorder.
A, B: Type f: A -> B P: (A -> Prop) -> Prop b: B
(existsQ : B -> Prop,
(existsa : A -> Prop,
P a /\
(funb : B => existsa0 : A, a a0 /\ f a0 = b) =
Q) /\ Q b) ->
existsa : A,
(existsQ : A -> Prop, P Q /\ Q a) /\ f a = b
A, B: Type f: A -> B P: (A -> Prop) -> Prop b: B Qb: B -> Prop Qa: A -> Prop PQa: P Qa rest: (funb : B => existsa : A, Qa a /\ f a = b) =
Qb Qbb: Qb b
existsa : A,
(existsQ : A -> Prop, P Q /\ Q a) /\ f a = b
A, B: Type f: A -> B P: (A -> Prop) -> Prop b: B Qa: A -> Prop PQa: P Qa Qbb: existsa : A, Qa a /\ f a = b
existsa : A,
(existsQ : A -> Prop, P Q /\ Q a) /\ f a = b
firstorder.Qed.
Natural (@Monad.join subset%tea Join_subset)
Natural (@Monad.join subset%tea Join_subset)
Functor (subset%tea ∘ subset%tea)
Functor subset%tea
forall (AB : Type) (f : A -> B),
map f ∘ Monad.join = Monad.join ∘ map f
Functor (subset%tea ∘ subset%tea)
typeclasses eauto.
Functor subset%tea
typeclasses eauto.
forall (AB : Type) (f : A -> B),
map f ∘ Monad.join = Monad.join ∘ map f
apply natural_join_subset.Qed.
forallA : Type, Monad.join ∘ ret = id
forallA : Type, Monad.join ∘ ret = id
A: Type
Monad.join ∘ ret = id
A: Type P: A -> Prop
(Monad.join ∘ ret) P = id P
A: Type P: A -> Prop
(Monad.join ∘ ret) P = P
A: Type P: A -> Prop
Monad.join {{P}} = P
A: Type P: A -> Prop
(funa : A => existsQ : A -> Prop, {{P}} Q /\ Q a) =
P
A: Type P: A -> Prop a: A
(existsQ : A -> Prop, {{P}} Q /\ Q a) = P a
A: Type P: A -> Prop a: A
(existsQ : A -> Prop, {{P}} Q /\ Q a) -> P a
A: Type P: A -> Prop a: A
P a -> existsQ : A -> Prop, {{P}} Q /\ Q a
A: Type P: A -> Prop a: A
(existsQ : A -> Prop, {{P}} Q /\ Q a) -> P a
A: Type P: A -> Prop a: A
(existsQ : A -> Prop, {{P}} Q /\ Q a) -> P a
A: Type P: A -> Prop a: A Q: A -> Prop Qin: {{P}} Q Qa: Q a
P a
A: Type P: A -> Prop a: A Q: A -> Prop Qin: P = Q Qa: Q a
P a
nowsubst.
A: Type P: A -> Prop a: A
P a -> existsQ : A -> Prop, {{P}} Q /\ Q a
A: Type P: A -> Prop a: A H: P a
existsQ : A -> Prop, {{P}} Q /\ Q a
A: Type P: A -> Prop a: A H: P a
{{P}} P /\ P a
now simpl_subset.Qed.
forall (A : Type) (P : A -> Prop),
Monad.join {{P}} = P
forall (A : Type) (P : A -> Prop),
Monad.join {{P}} = P
A: Type P: A -> Prop
Monad.join {{P}} = P
A: Type P: A -> Prop
(Monad.join ∘ ret) P = P
A: Type P: A -> Prop
id P = P
reflexivity.Qed.
forallA : Type, Monad.join ∘ map ret = id
forallA : Type, Monad.join ∘ map ret = id
A: Type
Monad.join ∘ map ret = id
A: Type
Monad.join ○ map ret = (funx : A -> Prop => x)
A: Type P: A -> Prop a: A
Monad.join (map ret P) a = P a
A: Type P: A -> Prop a: A
(existsQ : A -> Prop,
(existsa : A, P a /\ {{a}} = Q) /\ Q a) = P a
A: Type P: A -> Prop a: A
(existsQ : A -> Prop,
(existsa : A, P a /\ {{a}} = Q) /\ Q a) -> P a
A: Type P: A -> Prop a: A
P a ->
existsQ : A -> Prop,
(existsa : A, P a /\ {{a}} = Q) /\ Q a
A: Type P: A -> Prop a: A
(existsQ : A -> Prop,
(existsa : A, P a /\ {{a}} = Q) /\ Q a) -> P a
A: Type P: A -> Prop a: A P': A -> Prop a': A Pa': P a' rest: {{a'}} = P' Ha': P' a
P a
A: Type P: A -> Prop a, a': A Pa': P a' Ha': {{a'}} a
P a
A: Type P: A -> Prop a, a': A Pa': P a' Ha': a' = a
P a
nowsubst.
A: Type P: A -> Prop a: A
P a ->
existsQ : A -> Prop,
(existsa : A, P a /\ {{a}} = Q) /\ Q a
A: Type P: A -> Prop a: A H: P a
existsQ : A -> Prop,
(existsa : A, P a /\ {{a}} = Q) /\ Q a
A, B, C: Type g: B -> subset%tea C f: A -> subset%tea B a: A -> Prop c: C
(existsa0 : A,
a a0 /\ (existsa : B, f a0 a /\ g a c)) ->
existsa0 : B,
(existsa1 : A, a a1 /\ f a1 a0) /\ g a0 c
A, B, C: Type g: B -> subset%tea C f: A -> subset%tea B a: A -> Prop c: C a': A ha1: a a' b: B hb1: f a' b hb2: g b c
existsa0 : B,
(existsa1 : A, a a1 /\ f a1 a0) /\ g a0 c
existsb; split; [existsa'; split; assumption | assumption].Qed.#[export] InstanceRightPreModule_subset: RightPreModule subset subset :=
{| kmod_bind1 := set_bind1;
kmod_bind2 := set_bind2;
|}.#[export] InstanceMonad_subset: Monad subset :=
{| kmon_bind0 := set_bind0;
|}.#[export] InstanceRightModule_subset: RightModule subset subset :=
{| kmod_monad := _;
|}.(** ** <<bind>> is a Monoid Homomorphism *)(**********************************************************************)#[export] InstanceMonmor_bind {ABf}:
Monoid_Morphism (subset A) (subset B) (bind f) :=
{| monmor_unit := @bind_set_nil A B f;
monmor_op := @bind_set_add A B f;
|}.(** ** <<{{ - }}>> is Injective *)(**********************************************************************)
forall (A : Type) (ab : A), {{a}} = {{b}} -> a = b
forall (A : Type) (ab : A), {{a}} = {{b}} -> a = b
A: Type a, b: A H: {{a}} = {{b}}
a = b
A: Type a, b: A H: {{a}} = {{b}}
forallx : A, {{a}} x = {{b}} x
A: Type a, b: A H: {{a}} = {{b}} lemma: forallx : A, {{a}} x = {{b}} x
a = b
A: Type a, b: A H: {{a}} = {{b}} x: A
{{a}} x = {{b}} x
A: Type a, b: A H: {{a}} = {{b}} lemma: forallx : A, {{a}} x = {{b}} x
a = b
A: Type a, b: A H: {{a}} = {{b}} lemma: forallx : A, {{a}} x = {{b}} x
a = b
A: Type a, b: A H: {{a}} = {{b}} lemma: {{a}} a = {{b}} a
a = b
A: Type a, b: A H: {{a}} = {{b}} lemma: (a = a) = (b = a)
a = b
A: Type a, b: A H: {{a}} = {{b}} lemma: (a = a) = (b = a)
b = a
nowrewrite <- lemma.Qed.(** * Applicative Instance *)(**********************************************************************)Sectionsubset_applicative_instance.Import Applicative.Notations.#[export] InstancePure_subset: Pure subset := @eq.#[export] InstanceMult_subset: Mult subset :=
funAB '(sa, sb) '(a, b) => sa a /\ sb b.
Applicative subset%tea
Applicative subset%tea
Functor subset%tea
forall (AB : Type) (f : A -> B) (x : A),
map f (pure x) = pure (f x)
forall (ABCD : Type) (f : A -> C) (g : B -> D)
(x : A -> Prop) (y : B -> Prop),
map f x ⊗ map g y = map (map_tensor f g) (x ⊗ y)
forall (ABC : Type) (x : A -> Prop) (y : B -> Prop)
(z : C -> Prop),
map associator (x ⊗ y ⊗ z) = x ⊗ (y ⊗ z)
forall (A : Type) (x : A -> Prop),
map left_unitor (pure tt ⊗ x) = x
forall (A : Type) (x : A -> Prop),
map right_unitor (x ⊗ pure tt) = x
forall (AB : Type) (a : A) (b : B),
pure a ⊗ pure b = pure (a, b)
Functor subset%tea
apply Functor_subset.
forall (AB : Type) (f : A -> B) (x : A),
map f (pure x) = pure (f x)
A, B: Type f: A -> B x: A
map f (pure x) = pure (f x)
A, B: Type f: A -> B x: A
map f {{x}} = {{f x}}
now simpl_subset.
forall (ABCD : Type) (f : A -> C) (g : B -> D)
(x : A -> Prop) (y : B -> Prop),
map f x ⊗ map g y = map (map_tensor f g) (x ⊗ y)
A, B, C, D: Type f: A -> C g: B -> D x: A -> Prop y: B -> Prop
map f x ⊗ map g y = map (map_tensor f g) (x ⊗ y)
A, B, C, D: Type f: A -> C g: B -> D x: A -> Prop y: B -> Prop
(fun '(a, b) => map f x a /\ map g y b) =
map (map_tensor f g) (fun '(a, b) => x a /\ y b)
A, B, C, D: Type f: A -> C g: B -> D x: A -> Prop y: B -> Prop c: C d: D
(map f x c /\ map g y d) =
map (map_tensor f g) (fun '(a, b) => x a /\ y b)
(c, d)
A, B, C, D: Type f: A -> C g: B -> D x: A -> Prop y: B -> Prop c: C d: D
((existsa : A, x a /\ f a = c) /\
(existsa : B, y a /\ g a = d)) =
(existsa : A * B,
(let '(a0, b) := a in x a0 /\ y b) /\
(let (x, y) := a in (f x, g y)) = (c, d))
A, B, C, D: Type f: A -> C g: B -> D x: A -> Prop y: B -> Prop c: C d: D
(existsa : A, x a /\ f a = c) /\
(existsa : B, y a /\ g a = d) ->
existsa : A * B,
(let '(a0, b) := a in x a0 /\ y b) /\
(let (x, y) := a in (f x, g y)) = (c, d)
A, B, C, D: Type f: A -> C g: B -> D x: A -> Prop y: B -> Prop c: C d: D
(existsa : A * B,
(let '(a0, b) := a in x a0 /\ y b) /\
(let (x, y) := a in (f x, g y)) = (c, d)) ->
(existsa : A, x a /\ f a = c) /\
(existsa : B, y a /\ g a = d)
A, B, C, D: Type f: A -> C g: B -> D x: A -> Prop y: B -> Prop c: C d: D
(existsa : A, x a /\ f a = c) /\
(existsa : B, y a /\ g a = d) ->
existsa : A * B,
(let '(a0, b) := a in x a0 /\ y b) /\
(let (x, y) := a in (f x, g y)) = (c, d)
A, B, C, D: Type f: A -> C g: B -> D x: A -> Prop y: B -> Prop c: C d: D a: A Ha1: x a Ha2: f a = c b: B Hb1: y b Hb2: g b = d
existsa : A * B,
(let '(a0, b) := a in x a0 /\ y b) /\
(let (x, y) := a in (f x, g y)) = (c, d)
A, B, C, D: Type f: A -> C g: B -> D x: A -> Prop y: B -> Prop c: C d: D a: A Ha1: x a Ha2: f a = c b: B Hb1: y b Hb2: g b = d
(x a /\ y b) /\ (f a, g b) = (c, d)
A, B, C, D: Type f: A -> C g: B -> D x: A -> Prop y: B -> Prop a: A Ha1: x a b: B Hb1: y b
(x a /\ y b) /\ (f a, g b) = (f a, g b)
intuition.
A, B, C, D: Type f: A -> C g: B -> D x: A -> Prop y: B -> Prop c: C d: D
(existsa : A * B,
(let '(a0, b) := a in x a0 /\ y b) /\
(let (x, y) := a in (f x, g y)) = (c, d)) ->
(existsa : A, x a /\ f a = c) /\
(existsa : B, y a /\ g a = d)
A, B, C, D: Type f: A -> C g: B -> D x: A -> Prop y: B -> Prop c: C d: D a: A b: B Hab1: x a /\ y b Hab2: (f a, g b) = (c, d)
(existsa : A, x a /\ f a = c) /\
(existsa : B, y a /\ g a = d)
A, B, C, D: Type f: A -> C g: B -> D x: A -> Prop y: B -> Prop c: C d: D a: A b: B Hab1: x a /\ y b Hab2: (f a, g b) = (c, d) H0: f a = c H1: g b = d
(existsa0 : A, x a0 /\ f a0 = f a) /\
(existsa : B, y a /\ g a = g b)
A, B, C, D: Type f: A -> C g: B -> D x: A -> Prop y: B -> Prop a: A b: B Hab1: x a /\ y b Hab2: (f a, g b) = (f a, g b)
(existsa0 : A, x a0 /\ f a0 = f a) /\
(existsa : B, y a /\ g a = g b)
intuitioneauto.
forall (ABC : Type) (x : A -> Prop) (y : B -> Prop)
(z : C -> Prop),
map associator (x ⊗ y ⊗ z) = x ⊗ (y ⊗ z)
A, B, C: Type x: A -> Prop y: B -> Prop z: C -> Prop
map associator (x ⊗ y ⊗ z) = x ⊗ (y ⊗ z)
A, B, C: Type x: A -> Prop y: B -> Prop z: C -> Prop a: A b: B c: C
A, B, C: Type x: A -> Prop y: B -> Prop z: C -> Prop a: A b: B c: C
(existsa0 : A * B * C,
(let
'(a, b) := a0 in
(let '(a1, b0) := a in x a1 /\ y b0) /\ z b) /\
(let (p0, z) := a0 inlet (x, y) := p0 in (x, (y, z))) = (a, (b, c))) =
(x a /\ y b /\ z c)
A, B, C: Type x: A -> Prop y: B -> Prop z: C -> Prop a: A b: B c: C
(existsa0 : A * B * C,
(let
'(a, b) := a0 in
(let '(a1, b0) := a in x a1 /\ y b0) /\ z b) /\
(let (p0, z) := a0 inlet (x, y) := p0 in (x, (y, z))) = (a, (b, c))) ->
x a /\ y b /\ z c
A, B, C: Type x: A -> Prop y: B -> Prop z: C -> Prop a: A b: B c: C
x a /\ y b /\ z c ->
existsa0 : A * B * C,
(let
'(a, b) := a0 in
(let '(a1, b0) := a in x a1 /\ y b0) /\ z b) /\
(let (p0, z) := a0 inlet (x, y) := p0 in (x, (y, z))) = (a, (b, c))
A, B, C: Type x: A -> Prop y: B -> Prop z: C -> Prop a: A b: B c: C
(existsa0 : A * B * C,
(let
'(a, b) := a0 in
(let '(a1, b0) := a in x a1 /\ y b0) /\ z b) /\
(let (p0, z) := a0 inlet (x, y) := p0 in (x, (y, z))) = (a, (b, c))) ->
x a /\ y b /\ z c
A, B, C: Type x: A -> Prop y: B -> Prop z: C -> Prop a: A b: B c: C a': A b': B c': C Ht1: (x a' /\ y b') /\ z c' Ht2: (a', (b', c')) = (a, (b, c))
x a /\ y b /\ z c
A, B, C: Type x: A -> Prop y: B -> Prop z: C -> Prop a: A b: B c: C Ht2: (a, (b, c)) = (a, (b, c)) Ht1: (x a /\ y b) /\ z c
x a /\ y b /\ z c
tauto.
A, B, C: Type x: A -> Prop y: B -> Prop z: C -> Prop a: A b: B c: C
x a /\ y b /\ z c ->
existsa0 : A * B * C,
(let
'(a, b) := a0 in
(let '(a1, b0) := a in x a1 /\ y b0) /\ z b) /\
(let (p0, z) := a0 inlet (x, y) := p0 in (x, (y, z))) = (a, (b, c))
A, B, C: Type x: A -> Prop y: B -> Prop z: C -> Prop a: A b: B c: C H: x a /\ y b /\ z c
existsa0 : A * B * C,
(let
'(a, b) := a0 in
(let '(a1, b0) := a in x a1 /\ y b0) /\ z b) /\
(let (p0, z) := a0 inlet (x, y) := p0 in (x, (y, z))) = (a, (b, c))
A, B, C: Type x: A -> Prop y: B -> Prop z: C -> Prop a: A b: B c: C H: x a /\ y b /\ z c
((x a /\ y b) /\ z c) /\ (a, (b, c)) = (a, (b, c))
tauto.
forall (A : Type) (x : A -> Prop),
map left_unitor (pure tt ⊗ x) = x
A: Type x: A -> Prop
map left_unitor (pure tt ⊗ x) = x
A: Type x: A -> Prop a: A
map left_unitor (pure tt ⊗ x) a = x a
A: Type x: A -> Prop a: A
(existsa0 : unit * A,
(let '(a, b) := a0 in tt = a /\ x b) /\
(let (_, y) := a0 in y) = a) = x a
A: Type x: A -> Prop a: A
(existsa0 : unit * A,
(let '(a, b) := a0 in tt = a /\ x b) /\
(let (_, y) := a0 in y) = a) -> x a
A: Type x: A -> Prop a: A
x a ->
existsa0 : unit * A,
(let '(a, b) := a0 in tt = a /\ x b) /\
(let (_, y) := a0 in y) = a
A: Type x: A -> Prop a: A
(existsa0 : unit * A,
(let '(a, b) := a0 in tt = a /\ x b) /\
(let (_, y) := a0 in y) = a) -> x a
A: Type x: A -> Prop a: A tt': unit a': A H1: tt = tt' /\ x a' H2: a' = a
x a
nowsubst.
A: Type x: A -> Prop a: A
x a ->
existsa0 : unit * A,
(let '(a, b) := a0 in tt = a /\ x b) /\
(let (_, y) := a0 in y) = a
A: Type x: A -> Prop a: A Xa: x a
existsa0 : unit * A,
(let '(a, b) := a0 in tt = a /\ x b) /\
(let (_, y) := a0 in y) = a
A: Type x: A -> Prop a: A Xa: x a
(tt = tt /\ x a) /\ a = a
tauto.
forall (A : Type) (x : A -> Prop),
map right_unitor (x ⊗ pure tt) = x
A: Type x: A -> Prop
map right_unitor (x ⊗ pure tt) = x
A: Type x: A -> Prop a: A
map right_unitor (x ⊗ pure tt) a = x a
A: Type x: A -> Prop a: A
(existsa0 : A * unit,
(let '(a, b) := a0 in x a /\ tt = b) /\
(let (x, _) := a0 in x) = a) = x a
A: Type x: A -> Prop a: A
(existsa0 : A * unit,
(let '(a, b) := a0 in x a /\ tt = b) /\
(let (x, _) := a0 in x) = a) -> x a
A: Type x: A -> Prop a: A
x a ->
existsa0 : A * unit,
(let '(a, b) := a0 in x a /\ tt = b) /\
(let (x, _) := a0 in x) = a
A: Type x: A -> Prop a: A
(existsa0 : A * unit,
(let '(a, b) := a0 in x a /\ tt = b) /\
(let (x, _) := a0 in x) = a) -> x a
A: Type x: A -> Prop a, a': A tt': unit H1: x a' /\ tt = tt' H2: a' = a
x a
nowsubst.
A: Type x: A -> Prop a: A
x a ->
existsa0 : A * unit,
(let '(a, b) := a0 in x a /\ tt = b) /\
(let (x, _) := a0 in x) = a
A: Type x: A -> Prop a: A Xa: x a
existsa0 : A * unit,
(let '(a, b) := a0 in x a /\ tt = b) /\
(let (x, _) := a0 in x) = a
A: Type x: A -> Prop a: A Xa: x a
(x a /\ tt = tt) /\ a = a
tauto.
forall (AB : Type) (a : A) (b : B),
pure a ⊗ pure b = pure (a, b)
A, B: Type a: A b: B
pure a ⊗ pure b = pure (a, b)
A, B: Type a: A b: B a': A b': B
(pure a ⊗ pure b) (a', b') = pure (a, b) (a', b')
A, B: Type a: A b: B a': A b': B
(a = a' /\ b = b') = ((a, b) = (a', b'))
A, B: Type a: A b: B a': A b': B
a = a' /\ b = b' -> (a, b) = (a', b')
A, B: Type a: A b: B a': A b': B
(a, b) = (a', b') -> a = a' /\ b = b'
A, B: Type a: A b: B a': A b': B
a = a' /\ b = b' -> (a, b) = (a', b')
A, B: Type a: A b: B a': A b': B H0: a = a' H1: b = b'
(a, b) = (a', b')
nowsubst.
A, B: Type a: A b: B a': A b': B
(a, b) = (a', b') -> a = a' /\ b = b'
intros X; inversion X; nowsubst.Qed.
forall (AB : Type) (sf : subset%tea (A -> B))
(sa : subset%tea A) (b : B),
(sf <⋆> sa) b =
(exists (f : A -> B) (a : A), sa a /\ sf f /\ f a = b)
forall (AB : Type) (sf : subset%tea (A -> B))
(sa : subset%tea A) (b : B),
(sf <⋆> sa) b =
(exists (f : A -> B) (a : A), sa a /\ sf f /\ f a = b)
A, B: Type sf: subset%tea (A -> B) sa: subset%tea A b: B
(sf <⋆> sa) b =
(exists (f : A -> B) (a : A), sa a /\ sf f /\ f a = b)
A, B: Type sf: subset%tea (A -> B) sa: subset%tea A b: B
map (fun '(f, a) => f a) (sf ⊗ sa) b =
(exists (f : A -> B) (a : A), sa a /\ sf f /\ f a = b)
A, B: Type sf: subset%tea (A -> B) sa: subset%tea A b: B
(existsa : (A -> B) * A,
(sf ⊗ sa) a /\ (let '(f, a0) := a in f a0) = b) =
(exists (f : A -> B) (a : A), sa a /\ sf f /\ f a = b)
A, B: Type sf: subset%tea (A -> B) sa: subset%tea A b: B
(existsa : (A -> B) * A,
(let '(a0, b) := a in sf a0 /\ sa b) /\
(let '(f, a0) := a in f a0) = b) =
(exists (f : A -> B) (a : A), sa a /\ sf f /\ f a = b)
A, B: Type sf: subset%tea (A -> B) sa: subset%tea A b: B
(existsa : (A -> B) * A,
(let '(a0, b) := a in sf a0 /\ sa b) /\
(let '(f, a0) := a in f a0) = b) ->
exists (f : A -> B) (a : A), sa a /\ sf f /\ f a = b
A, B: Type sf: subset%tea (A -> B) sa: subset%tea A b: B
(exists (f : A -> B) (a : A), sa a /\ sf f /\ f a = b) ->
existsa : (A -> B) * A,
(let '(a0, b) := a in sf a0 /\ sa b) /\
(let '(f, a0) := a in f a0) = b
A, B: Type sf: subset%tea (A -> B) sa: subset%tea A b: B
(existsa : (A -> B) * A,
(let '(a0, b) := a in sf a0 /\ sa b) /\
(let '(f, a0) := a in f a0) = b) ->
exists (f : A -> B) (a : A), sa a /\ sf f /\ f a = b
A, B: Type sf: subset%tea (A -> B) sa: subset%tea A b: B f: A -> B a: A hyp1: sf f hyp2: sa a hyp3: f a = b
exists (f : A -> B) (a : A), sa a /\ sf f /\ f a = b
A, B: Type sf: subset%tea (A -> B) sa: subset%tea A b: B f: A -> B a: A hyp1: sf f hyp2: sa a hyp3: f a = b
sa a /\ sf f /\ f a = b
auto.
A, B: Type sf: subset%tea (A -> B) sa: subset%tea A b: B
(exists (f : A -> B) (a : A), sa a /\ sf f /\ f a = b) ->
existsa : (A -> B) * A,
(let '(a0, b) := a in sf a0 /\ sa b) /\
(let '(f, a0) := a in f a0) = b
A, B: Type sf: subset%tea (A -> B) sa: subset%tea A b: B f: A -> B a: A hyp1: sa a hyp2: sf f hyp3: f a = b
existsa : (A -> B) * A,
(let '(a0, b) := a in sf a0 /\ sa b) /\
(let '(f, a0) := a in f a0) = b
A, B: Type sf: subset%tea (A -> B) sa: subset%tea A f: A -> B a: A hyp1: sa a hyp2: sf f
existsa0 : (A -> B) * A,
(let '(a, b) := a0 in sf a /\ sa b) /\
(let '(f, a) := a0 in f a) = f a
A, B: Type sf: subset%tea (A -> B) sa: subset%tea A f: A -> B a: A hyp1: sa a hyp2: sf f
(sf f /\ sa a) /\ f a = f a
tauto.Qed.(** ** Non-Idempotence of the Applicative *)(********************************************************************)
forall (AB : Type) (fg : A -> B),
(existsa : A, f a <> g a) -> f <> g
forall (AB : Type) (fg : A -> B),
(existsa : A, f a <> g a) -> f <> g
A, B: Type f, g: A -> B H: existsa : A, f a <> g a
f <> g
A, B: Type f, g: A -> B H: existsa : A, f a <> g a contra: f = g
False
A, B: Type f, g: A -> B a: A Hneq: f a <> g a contra: f = g
False
A, B: Type f, g: A -> B a: A Hneq: g a <> g a contra: f = g
False
contradiction.Qed.
forall (A : Type) (a : A) (s1s2 : subset%tea A),
s1 a -> ~ s2 a -> s1 <> s2
forall (A : Type) (a : A) (s1s2 : subset%tea A),
s1 a -> ~ s2 a -> s1 <> s2
A: Type a: A s1, s2: subset%tea A H: s1 a H0: ~ s2 a
s1 <> s2
A: Type a: A s1, s2: subset%tea A H: s1 a H0: ~ s2 a
existsa : A, s1 a <> s2 a
A: Type a: A s1, s2: subset%tea A H: s1 a H0: ~ s2 a
s1 a <> s2 a
A: Type a: A s1, s2: subset%tea A H: s1 a H0: ~ s2 a contra: s1 a = s2 a
False
A: Type a: A s1, s2: subset%tea A H: s2 a H0: ~ s2 a contra: s1 a = s2 a
False
contradiction.Qed.
~
(forall (A : Type) (s : subset%tea A),
s ⊗ s = map (funa : A => (a, a)) s)
~
(forall (A : Type) (s : subset%tea A),
s ⊗ s = map (funa : A => (a, a)) s)
contra: forall (A : Type) (s : A -> Prop),
s ⊗ s = map (funa : A => (a, a)) s