Library UniMath.CategoryTheory.MarkovCategories.Couplings
Require Import UniMath.Foundations.All.
Require Import UniMath.MoreFoundations.All.
Require Import UniMath.CategoryTheory.Core.Prelude.
Require Import UniMath.CategoryTheory.coslicecat.
Require Import UniMath.CategoryTheory.Limits.Terminal.
Require Import UniMath.CategoryTheory.Categories.Quotient.
Require Import UniMath.CategoryTheory.Monoidal.Categories.
Require Import UniMath.CategoryTheory.Monoidal.Structure.Cartesian.
Require Import UniMath.CategoryTheory.Monoidal.Structure.Symmetric.
Require Import UniMath.CategoryTheory.MarkovCategories.MarkovCategory.
Require Import UniMath.CategoryTheory.MarkovCategories.Determinism.
Require Import UniMath.CategoryTheory.MarkovCategories.State.
Require Import UniMath.CategoryTheory.MarkovCategories.InformationFlowAxioms.
Require Import UniMath.CategoryTheory.MarkovCategories.AlmostSurely.
Require Import UniMath.CategoryTheory.MarkovCategories.Conditionals.
Import MonoidalNotations.
Local Open Scope cat.
Local Open Scope moncat.
Local Open Scope markov.
Definition coupling {C : markov_category} {x y : C} (p : I_{C} --> x) (q : I_{C} --> y) : UU
:= ∑ (γ : I_{C} --> x ⊗ y), (γ · proj1 = p) × (γ · proj2 = q).
Proposition make_coupling {C : markov_category} {x y : C} {p : I_{C} --> x} {q : I_{C} --> y}
(γ : I_{C} --> x ⊗ y) (dom : γ · proj1 = p) (cod : γ · proj2 = q) : coupling p q.
Proof.
exists γ.
split; assumption.
Defined.
Coercion coupling_to_state {C : markov_category} {x y : C}
{p : I_{C} --> x} {q : I_{C} --> y} (γ : coupling p q) : I_{C} --> x ⊗ y := pr1 γ.
Proposition coupling_ext {C : markov_category} {p q : state C} {β γ : coupling p q} :
(coupling_to_state β) = (coupling_to_state γ) -> β = γ.
Proof.
intros pf.
use subtypePath.
{
intro.
use isapropdirprod ; apply homset_property.
}
exact pf.
Qed.
Proposition coupling_dom {C : markov_category} {x y : C}
{p : I_{C} --> x} {q : I_{C} --> y} (γ : coupling p q) :
γ · proj1 = p.
Proof.
exact (pr12 γ).
Defined.
Proposition coupling_cod {C : markov_category} {x y : C}
{p : I_{C} --> x} {q : I_{C} --> y} (γ : coupling p q) :
γ · proj2 = q.
Proof.
exact (pr22 γ).
Defined.
Section CouplingCompositionLemmas.
Context {C : markov_category_with_conditionals}.
Definition coupling_composition {x y z : C}
(β : I_{C} --> x ⊗ y) (γ : I_{C} --> y ⊗ z)
: I_{C} --> x ⊗ z := β · proj2 · ⟨ β|2 , γ|1 ⟩.
Proposition coupling_composition_eq {x y z : C}
(β : I_{C} --> x ⊗ y) (γ : I_{C} --> y ⊗ z)
(e : β · proj2 = γ · proj1)
: coupling_composition β γ = β · proj2 · ⟨ β|2 , γ|1 ⟩.
Proof.
reflexivity.
Qed.
Proposition coupling_composition_eq_2 {x y z : C}
(β : I_{C} --> x ⊗ y) (γ : I_{C} --> y ⊗ z)
(e : β · proj2 = γ · proj1)
: coupling_composition β γ = β · (identity _ #⊗ γ|1).
Proof.
unfold coupling_composition.
rewrite pairing_split_r.
rewrite assoc.
apply maponpaths_2.
rewrite <- conditional_distribution_2_eq.
reflexivity.
Qed.
Proposition coupling_composition_eq_3 {x y z : C}
(β : I_{C} --> x ⊗ y) (γ : I_{C} --> y ⊗ z)
(e : β · proj2 = γ · proj1)
: coupling_composition β γ = γ · (β|2 #⊗ identity _).
Proof.
unfold coupling_composition.
rewrite pairing_split_l.
rewrite assoc.
apply maponpaths_2.
rewrite e.
rewrite <- conditional_distribution_1_eq.
reflexivity.
Qed.
Proposition coupling_composition_dom {x y z : C}
(β : I_{C} --> x ⊗ y) (γ : I_{C} --> y ⊗ z)
(e : β · proj2 = γ · proj1) :
coupling_composition β γ · proj1 = β · proj1.
Proof.
rewrite coupling_composition_eq_2 ; [ | assumption ].
rewrite assoc'.
rewrite proj1_tensor.
reflexivity.
Qed.
Proposition coupling_composition_cod {x y z : C}
(β : I_{C} --> x ⊗ y) (γ : I_{C} --> y ⊗ z)
(e : β · proj2 = γ · proj1) :
coupling_composition β γ · proj2 = γ · proj2.
Proof.
rewrite coupling_composition_eq_3 ; [ | assumption ].
rewrite assoc'.
rewrite proj2_tensor.
reflexivity.
Qed.
Definition identity_coupling {x : C} (p : I_{C} --> x) : I_{C} --> x ⊗ x := p · copy x.
Proposition identity_coupling_dom {x : C} (p : I_{C} --> x) : identity_coupling p · proj1 = p.
Proof.
unfold identity_coupling.
rewrite <- assoc.
rewrite copy_proj1.
rewrite id_right.
reflexivity.
Qed.
Proposition identity_coupling_cod {x : C} (p : I_{C} --> x) : identity_coupling p · proj2 = p.
Proof.
unfold identity_coupling.
rewrite <- assoc.
rewrite copy_proj2.
rewrite id_right.
reflexivity.
Qed.
Proposition coupling_id_left {x y : C} (p : I_{C} --> x) (β : I_{C} --> x ⊗ y)
(e : identity_coupling p · proj2 = β · proj1) :
coupling_composition (identity_coupling p) β = β.
Proof.
assert (e2 : p = β · proj1).
{ rewrite <- e. rewrite identity_coupling_cod. reflexivity. }
rewrite coupling_composition_eq_2 ; [ | assumption ].
unfold identity_coupling.
rewrite <- assoc.
rewrite e2.
rewrite conditional_distribution_1_eq.
reflexivity.
Qed.
Proposition coupling_id_right {x y : C} (p : I_{C} --> y) (β : I_{C} --> x ⊗ y)
(e : β · proj2 = identity_coupling p · proj1) :
coupling_composition β (identity_coupling p) = β.
Proof.
assert (e2 : p = β · proj2).
{ rewrite e. rewrite identity_coupling_dom. reflexivity. }
rewrite coupling_composition_eq_3 ; [ | assumption ].
unfold identity_coupling.
rewrite <- assoc.
rewrite e2.
rewrite conditional_distribution_2_eq.
reflexivity.
Qed.
Local Lemma conditional_distribution_1_to_2 {x y x' y' : C}
(β : I_{C} --> x ⊗ y)
(f : x --> x') (g : y --> y') :
β · proj1 · ⟨ f , β|1 · g ⟩ = β · proj2 · ⟨ β|2 · f, g ⟩.
Proof.
rewrite <- (id_left f).
rewrite <- pairing_tensor.
rewrite assoc.
rewrite <- conditional_distribution_1_eq.
rewrite id_left.
rewrite <- (id_left g).
rewrite <- pairing_tensor.
rewrite assoc.
rewrite <- conditional_distribution_2_eq.
rewrite id_left.
reflexivity.
Qed.
Proposition coupling_composition_assoc {x y z w : C}
(β : I_{C} --> x ⊗ y)
(γ : I_{C} --> y ⊗ z)
(δ : I_{C} --> z ⊗ w)
(e1 : β · proj2 = γ · proj1)
(e2 : γ · proj2 = δ · proj1)
: coupling_composition (coupling_composition β γ) δ
=
coupling_composition β (coupling_composition γ δ).
Proof.
assert (coupling_composition β γ · proj2 = δ · proj1) as e3.
{ rewrite coupling_composition_cod ; assumption. }
assert (β · proj2 = coupling_composition γ δ · proj1) as e4.
{ rewrite coupling_composition_dom ; assumption. }
etrans.
{
repeat (rewrite coupling_composition_eq_2 ; [ | assumption ]).
etrans.
{
do 2 apply maponpaths_2.
exact (conditional_distribution_1_eq β).
}
do 2 refine (assoc' _ _ _ @ _).
rewrite <- tensor_comp_id_l.
rewrite pairing_tensor_r.
rewrite conditional_distribution_1_to_2.
rewrite e1.
rewrite conditional_distribution_1_to_2.
rewrite e2.
rewrite <- (id_right (δ |1)).
rewrite conditional_distribution_1_to_2.
rewrite id_right.
rewrite <- pairing_tensor_l.
refine (assoc _ _ _ @ _).
apply maponpaths_2.
exact (!(conditional_distribution_2_eq δ)).
}
repeat (rewrite coupling_composition_eq_3 ; [ | assumption ]).
rewrite tensor_comp_id_r.
rewrite assoc'.
reflexivity.
Qed.
End CouplingCompositionLemmas.
Section CouplingDaggerLemmas.
Context {C : markov_category_with_conditionals}.
Definition coupling_dagger {x y : C}
(γ : I_{C} --> x ⊗ y) : I_{C} --> y ⊗ x := γ · sym_mon_braiding _ _ _.
Proposition coupling_dagger_dom {x y : C} (γ : I_{C} --> x ⊗ y) :
coupling_dagger γ · proj1 = γ · proj2.
Proof.
unfold coupling_dagger.
rewrite assoc', sym_mon_braiding_proj1.
reflexivity.
Qed.
Proposition coupling_dagger_cod {x y : C} (γ : I_{C} --> x ⊗ y) :
coupling_dagger γ · proj2 = γ · proj1.
Proof.
unfold coupling_dagger.
rewrite assoc', sym_mon_braiding_proj2.
reflexivity.
Qed.
Proposition coupling_dagger_involution {x y : C} (γ : I_{C} --> x ⊗ y) :
coupling_dagger (coupling_dagger γ) = γ.
Proof.
unfold coupling_dagger.
rewrite assoc'.
rewrite sym_mon_braiding_inv.
rewrite id_right.
reflexivity.
Qed.
Proposition dagger_identity_coupling {x : C} {p : I_{C} --> x} :
coupling_dagger (identity_coupling p) = identity_coupling p.
Proof.
unfold coupling_dagger, identity_coupling.
rewrite assoc', copy_comm.
reflexivity.
Qed.
Proposition dagger_coupling_composition {x y z : C}
(β : I_{C} --> x ⊗ y) (γ : I_{C} --> y ⊗ z)
(e : β · proj2 = γ · proj1) :
coupling_composition (coupling_dagger γ) (coupling_dagger β)
= coupling_dagger (coupling_composition β γ).
Proof.
assert(compat : coupling_dagger γ · proj2 = coupling_dagger β · proj1).
{ rewrite coupling_dagger_dom, coupling_dagger_cod, e.
reflexivity. }
assert(def_cond : (β · sym_mon_braiding C x y)|1 = β|2).
{ reflexivity. }
etrans.
{ rewrite coupling_composition_eq_2; [ | assumption ].
unfold coupling_dagger.
rewrite assoc'.
rewrite <- tensor_sym_mon_braiding.
rewrite def_cond.
rewrite assoc.
reflexivity.
}
symmetry.
etrans.
{ rewrite coupling_composition_eq_2; [ | assumption ].
unfold coupling_dagger.
reflexivity. }
apply maponpaths_2.
rewrite <- coupling_composition_eq_2; [ | assumption ].
rewrite <- coupling_composition_eq_3; [ | assumption ].
reflexivity.
Qed.
End CouplingDaggerLemmas.
Section BloomCouplingLemmas.
Context {C : markov_category_with_conditionals}.
Definition bloom_coupling {x y : C} (p : I_{C} --> x) (f : x --> y) : I_{C} --> x ⊗ y
:= p · ⟨identity _, f⟩.
Proposition bloom_coupling_dom {x y : C} (p : I_{C} --> x) (f : x --> y) :
bloom_coupling p f · proj1 = p.
Proof.
unfold bloom_coupling.
rewrite assoc', pairing_proj1, id_right.
reflexivity.
Qed.
Proposition bloom_coupling_cod {x y : C} (p : I_{C} --> x) (f : x --> y) :
bloom_coupling p f · proj2 = p · f.
Proof.
unfold bloom_coupling.
rewrite assoc', pairing_proj2.
reflexivity.
Qed.
Proposition bloom_coupling_id {x : C} (p : I_{C} --> x) :
bloom_coupling p (identity x) = identity_coupling p.
Proof.
unfold bloom_coupling, identity_coupling.
rewrite pairing_id.
reflexivity.
Qed.
Proposition bloom_coupling_conditional_1_ase {x y : C} (p : I_{C} --> x) (f : x --> y) :
(bloom_coupling p f)|1 =_{p} f.
Proof.
unfold equal_almost_surely.
assert(e : p · ⟨ identity x, (bloom_coupling p f) |1 ⟩
= bloom_coupling p f · proj1 · ⟨ identity x, (bloom_coupling p f) |1 ⟩).
{ rewrite bloom_coupling_dom. reflexivity. }
rewrite e. clear e.
rewrite <- conditional_distribution_1_eq.
reflexivity.
Qed.
Proposition bloom_coupling_conditional_2_ase {x y : C} (p : I_{C} --> x) (f : x --> y) :
(bloom_coupling p f)|2 =_{p · f} bayesian_inverse p f.
Proof.
unfold equal_almost_surely.
assert(e : p · f · ⟨ identity y, (bloom_coupling p f) |2 ⟩
= bloom_coupling p f · proj2 · ⟨ identity y, (bloom_coupling p f) |2 ⟩).
{ rewrite bloom_coupling_cod. reflexivity. }
rewrite e. clear e.
apply cancel_braiding.
rewrite !assoc', !pairing_sym_mon_braiding, !assoc.
rewrite <- conditional_distribution_2_eq.
rewrite bayesian_inverse_eq_l.
reflexivity.
Qed.
Proposition bloom_coupling_composition {x y z : C}
(p : I_{C} --> x) (f : x --> y) (g : y --> z)
: coupling_composition (bloom_coupling p f) (bloom_coupling (p · f) g)
= bloom_coupling p (f · g).
Proof.
assert(compat : bloom_coupling p f · proj2 = bloom_coupling (p · f) g · proj1).
{ rewrite bloom_coupling_dom, bloom_coupling_cod.
reflexivity. }
rewrite coupling_composition_eq_2; [ | assumption ].
unfold bloom_coupling.
rewrite assoc'.
rewrite pairing_tensor.
rewrite id_left.
assert(target : f · (p · f · ⟨ identity y, g ⟩) |1 =_{p} f · g).
{ use ase_comp.
- apply conditionals_imply_causality.
- apply bloom_coupling_conditional_1_ase. }
exact target.
Qed.
End BloomCouplingLemmas.
#[global] Opaque coupling_composition.
Section CouplingsCategory.
Context {C : markov_category_with_conditionals}.
Definition cat_couplings_identity (p : state C) : coupling p p.
Proof.
use make_coupling.
- exact (identity_coupling p).
- apply identity_coupling_dom.
- apply identity_coupling_cod.
Defined.
Lemma couplings_composable {p q r : state C}
(β : coupling p q) (γ : coupling q r) : β · proj2 = γ · proj1.
Proof.
rewrite coupling_dom, coupling_cod.
reflexivity.
Qed.
Definition cat_couplings_composition {p q r : state C}
(β : coupling p q) (γ : coupling q r) : coupling p r.
Proof.
use make_coupling.
- exact (coupling_composition β γ).
- abstract
(rewrite coupling_composition_dom ;
[ apply coupling_dom | apply couplings_composable ]).
- abstract
(rewrite coupling_composition_cod ;
[ apply coupling_cod | apply couplings_composable ]).
Defined.
Definition couplings_precategory_ob_mor
: precategory_ob_mor.
Proof.
use make_precategory_ob_mor.
- exact (state C).
- exact (λ p q, coupling p q).
Defined.
Definition couplings_precategory_data
: precategory_data.
Proof.
use make_precategory_data.
- exact couplings_precategory_ob_mor.
- exact cat_couplings_identity.
- intros p q r β γ. exact (cat_couplings_composition β γ).
Defined.
Proposition is_precategory_couplings
: is_precategory couplings_precategory_data.
Proof.
use make_is_precategory_one_assoc.
- intros p q β.
apply coupling_ext.
apply coupling_id_left.
rewrite identity_coupling_cod.
rewrite coupling_dom.
reflexivity.
- intros p q β.
apply coupling_ext.
apply coupling_id_right.
rewrite identity_coupling_dom.
rewrite coupling_cod.
reflexivity.
- intros p q r s β γ δ.
apply coupling_ext.
cbn.
rewrite coupling_composition_assoc.
+ reflexivity.
+ apply couplings_composable.
+ apply couplings_composable.
Qed.
Definition couplings_precategory
: precategory.
Proof.
use make_precategory.
- exact couplings_precategory_data.
- exact is_precategory_couplings.
Defined.
Proposition has_homsets_couplings
: has_homsets couplings_precategory.
Proof.
intros x y.
use isaset_total2.
- apply homset_property.
- intro f.
apply isasetaprop.
use isapropdirprod ; apply homset_property.
Qed.
Definition couplings
: category.
Proof.
use make_category.
- exact couplings_precategory.
- exact has_homsets_couplings.
Defined.
End CouplingsCategory.