\begin{code}
{-# OPTIONS --safe --experimental-lossy-unification #-}
open import Prelude renaming (tt to β¨β©)
open import Signatures
open import FinitenessConditions
open import FreeMonad.PackagedTheory
open import FreeMonad.FindVars using (FindVars)
open import Finite using (β°)
module Hoare.HElim (π― : FullTheory βzero)
(findVar : FindVars (FullTheory.π― π―))
(fin-arities : β Oα΅’ β β° (Signature.Arity (FullTheory.π½ π―) Oα΅’)) where
open import Truth using (ProofOf ; _|β|_ ; |β|-idΛ‘; True; Ξ©)
open import Hoare.Definition π―
open import FreeMonad.HElim π― findVar fin-arities
open import FreeMonad.Quotiented π―
module _ {p : Level} where
module _ {A B : Type}
(Ο : A β Ξ© p)
(f g : A β Term B)
(k : (x : A) β ProofOf (Ο x) β f x β‘ g x)
(t : Term A) where
\end{code}
%<*h-elim>
\begin{code}
H-elim : (β
β x β t β
return (Ο x) β) β (t >>= f) β‘ (t >>= g)
\end{code}
%</h-elim>
\begin{code}
H-elim h = π’-elim Ο f g k t $
Ο? Ο <$> t β‘β¨β©
(do x β t; return (x , Ο x)) β‘β¨ x β t ΝΎ/ cong (return β (_,_ x)) (const Truth.iff Ξ» f β f _) β©
(do x β t; return (x , True |β| Ο x)) β‘β¨ on-pair h β©
(do x β t; return (x , True)) β‘β¨β©
ΟT Ο <$> t β
\end{code}