{-# OPTIONS --rewriting #-}
module Examples.Decalf.ProbabilisticChoice where
open import Algebra.Cost
costMonoid = ℕ-CostMonoid
open CostMonoid costMonoid using (ℂ)
open import Calf costMonoid
open import Calf.Data.Nat
import Data.Nat.Properties as Nat
open import Calf.Data.List
open import Calf.Data.Equality as Eq using (_≡_; refl; module ≡-Reasoning)
open import Calf.Data.IsBoundedG costMonoid
open import Calf.Data.IsBounded costMonoid
open import Function hiding (flip)
open import Data.Interval
postulate
flip : (X : tp⁻) → 𝕀 → cmp X → cmp X → cmp X
flip/0 : {e₀ e₁ : cmp X} →
flip X 0𝕀 e₀ e₁ ≡ e₀
flip/1 : {e₀ e₁ : cmp X} →
flip X 1𝕀 e₀ e₁ ≡ e₁
flip/same : (X : tp⁻) (e : cmp X) {p : 𝕀} →
flip X p e e ≡ e
flip/sym : (X : tp⁻) (p : 𝕀) (e₀ e₁ : cmp X) →
flip X p e₀ e₁ ≡ flip X (1- p) e₁ e₀
flip/assocʳ : (X : tp⁻) (e₀ e₁ e₂ : cmp X) {p q r : 𝕀} → p ≡ (p ∨ q) ∧ r →
flip X p (flip X q e₀ e₁) e₂ ≡ flip X (p ∨ q) e₀ (flip X r e₁ e₂)
flip/assocˡ : (X : tp⁻) (e₀ e₁ e₂ : cmp X) {p q r : 𝕀} → p ≡ (p ∧ q) ∨ r →
flip X p e₀ (flip X q e₁ e₂) ≡ flip X (p ∧ q) (flip X r e₀ e₁) e₂
flip/assocˡ X e₀ e₁ e₂ {p} {q} {r} h =
let open ≡-Reasoning in
begin
flip X p e₀ (flip X q e₁ e₂)
≡⟨ Eq.cong (λ p → flip X p e₀ (flip X q e₁ e₂)) h ⟩
flip X (p ∧ q ∨ r) e₀ (flip X q e₁ e₂)
≡˘⟨ flip/assocʳ X e₀ e₁ e₂ (Eq.cong (_∧ q) h) ⟩
flip X (p ∧ q) (flip X r e₀ e₁) e₂
∎
postulate
bind/flip : {f : val A → cmp X} {p : 𝕀} {e₀ e₁ : cmp (F A)} →
bind {A = A} X (flip (F A) p e₀ e₁) f ≡ flip X p (bind X e₀ f) (bind X e₁ f)
{-# REWRITE bind/flip #-}
flip/step : {e₀ e₁ : cmp X} {p : 𝕀} →
step X c (flip X p e₀ e₁) ≡ flip X p (step X c e₀) (step X c e₁)
module _ where
bernoulli : cmp cost
bernoulli = flip cost ½ (step⋆ 0) (step⋆ 1)
bernoulli/upper : bernoulli ≤⁻[ cost ] step⋆ 1
bernoulli/upper =
let open ≤⁻-Reasoning cost in
begin
flip cost ½ (step⋆ 0) (step⋆ 1)
≲⟨ ≤⁻-mono {cost} (λ e → flip cost ½ e (step⋆ 1)) (≤⁺-mono step⋆ (≤⇒≤⁺ (z≤n {1}))) ⟩
flip cost ½ (step⋆ 1) (step⋆ 1)
≡⟨ flip/same cost (step⋆ 1) {½} ⟩
step⋆ 1
∎
binomial : cmp $ Π nat λ _ → cost
binomial zero = ret triv
binomial (suc n) =
bind cost bernoulli λ _ →
binomial n
binomial/+ : (m n : val nat) →
(bind cost (binomial m) λ _ → binomial n) ≡ binomial (m + n)
binomial/+ zero n = refl
binomial/+ (suc m) n =
let open ≡-Reasoning in
begin
( bind cost bernoulli λ _ →
bind cost (binomial m) λ _ →
binomial n
)
≡⟨
( Eq.cong (bind cost bernoulli) $ funext λ _ →
binomial/+ m n
)
⟩
binomial (suc m + n)
∎
binomial/comm : (n : val nat) →
(bind cost bernoulli λ _ → binomial n) ≡ (bind cost (binomial n) λ _ → bernoulli)
binomial/comm zero = refl
binomial/comm (suc n) =
let open ≡-Reasoning in
begin
( bind cost bernoulli λ _ →
bind cost bernoulli λ _ →
binomial n
)
≡⟨
( Eq.cong (bind cost bernoulli) $ funext λ _ →
binomial/comm n
)
⟩
( bind cost bernoulli λ _ →
bind cost (binomial n) λ _ →
bernoulli
)
∎
binomial/upper : (n : val nat) → binomial n ≤⁻[ cost ] step⋆ n
binomial/upper zero = ≤⁻-refl
binomial/upper (suc n) =
let open ≤⁻-Reasoning cost in
begin
( bind cost bernoulli λ _ →
binomial n
)
≲⟨ ≤⁻-mono (λ e → bind cost e λ _ → binomial n) bernoulli/upper ⟩
( bind cost (step⋆ 1) λ _ →
binomial n
)
≡⟨⟩
step cost 1 (binomial n)
≲⟨ ≤⁻-mono (step cost 1) (binomial/upper n) ⟩
step⋆ (suc n)
∎
sublist : cmp $ Π (list A) λ _ → F (list A)
sublist {A} [] = ret []
sublist {A} (x ∷ xs) =
bind (F (list A)) (sublist {A} xs) λ xs' →
flip (F (list A)) ½ (ret xs') (step (F (list A)) 1 (ret (x ∷ xs')))
sublist/cost : cmp $ Π (list A) λ _ → cost
sublist/cost l = binomial (length l)
sublist/is-bounded : (l : val (list A)) → IsBoundedG (list A) (sublist {A} l) (sublist/cost {A} l)
sublist/is-bounded {A} [] = ≤⁻-refl
sublist/is-bounded {A} (x ∷ xs) =
let open ≤⁻-Reasoning cost in
begin
bind cost
( bind (F (list A)) (sublist {A} xs) λ xs' →
flip (F (list A)) ½ (ret xs') (step (F (list A)) 1 (ret (x ∷ xs')))
)
(λ _ → ret triv)
≡⟨⟩
( bind cost (sublist {A} xs) λ _ →
flip cost ½ (ret triv) (step cost 1 (ret triv))
)
≡⟨⟩
( bind cost (sublist {A} xs) λ _ →
bernoulli
)
≲⟨ ≤⁻-mono (λ e → bind cost e λ _ → bernoulli) (sublist/is-bounded {A} xs) ⟩
( bind cost (binomial (length xs)) λ _ →
bernoulli
)
≡˘⟨ binomial/comm (length xs) ⟩
binomial (length (x ∷ xs))
∎
sublist/is-bounded' : (l : val (list A)) → IsBounded (list A) (sublist {A} l) (length l)
sublist/is-bounded' {A} l = ≤⁻-trans (sublist/is-bounded {A} l) (binomial/upper (length l))