{-# OPTIONS --safe #-}
open import Prelude
open import Signatures
open import FinitenessConditions
open import FreeMonad.PackagedTheory
module Hoare.Boolean {ℓ} (𝒯 : FullTheory ℓ) where
open import FreeMonad.Quotiented 𝒯
open import Truth
ℋ : Term (A × Bool) → Type _
ℋ p = map₂ (const true) <$> p ≡ p
module _
{A : Type a} (p : Term A) (ϕ : A → Bool)
(f g : A → Term C)
(k : (x : A) → T (ϕ x) → f x ≡ g x)
(G : ℋ (id ▵ ϕ <$> p))
where
ℋ▵ : (_, true) <$> p ≡ (id ▵ ϕ) <$> p
ℋ▵ = (λ x → x , true) <$> p ≡˘⟨ assoc p (return ∘ (id ▵ ϕ)) (return ∘ map₂ (const true)) ⟩
map₂ (const true) <$> ((id ▵ ϕ) <$> p) ≡⟨ G ⟩
(id ▵ ϕ) <$> p ∎
ℋb : (k′ : A → Bool → Term B) → p >>= (λ x → k′ x true) ≡ p >>= (λ x → k′ x (ϕ x))
ℋb k′ = sym (assoc p (return ∘ (_, true)) (uncurry k′)) ; cong (_>>= uncurry k′) ℋ▵ ; assoc p (return ∘ (id ▵ ϕ)) (uncurry k′)
ℋ-elim : p >>= f ≡ p >>= g
ℋ-elim =
ℋb
(λ x b → if b then f x else g x) ;
(x ⇐ p ;/ bool {P = λ r → r ≡ ϕ x → (if r then f x else g x) ≡ g x} (const refl) (λ r → k x (subst T r tt)) (ϕ x) refl)