{-# OPTIONS --safe --experimental-lossy-unification #-}
open import Prelude
open import FinitenessConditions
open import Signatures
module Effects.NonDetState
(S : Type)
(choice : SplitQuotientedChoiceΟ S)
(set : isSet S)
where
import Effects.NonDet as βπ»
import Effects.State S choice set as π
open import FreeMonad.Combinations.Tensor βπ».βπ»-theory π.π-theory
open import FreeMonad.Quotiented combinedTheory
import FreeMonad.Syntax as Synt
open Synt (βπ».βπ» β π.π) using (Opβ¦_β§)
open Signature (βπ».βπ» β π.π)
open βπ».NonDet.Op
put : S β Term β€
put s = [ injβ (π.Synt.put s) ]
get : Term (S)
get = [ injβ π.Synt.get ]
fail : Term A
fail = [ Synt.op (inl `fail , absurd) ]
infixl 5 _<|>_
_<|>_ : Term A β Term A β Term A
xs <|> ys = opβ (inl `<|> , bool ys xs)
until : β β Term Bool β Term β€ β Term β€
until zero c t = fail
until (suc n) c t = c >>= bool (t >> until n c t) (return tt)
guard : Bool β Term β€
guard = bool fail (return tt)
open import Data.Nat.Order using () renaming (_<α΅_ to _<_)
open import Data.Nat.Properties using (_+_)
<|>-alg : (p q : Term A) (k : A β Term B) β ((p <|> q) >>= k) β‘ ((p >>= k) <|> (q >>= k))
<|>-alg p q k = algebraic (inl `<|>) k (bool q p)
<|>-idem : (x : Term A) β x <|> x β‘ x
<|>-idem = elimProp/ (Ξ» _ β squash/ _ _ )
Ξ» x β cong ([_] β Synt.op β _,_ (inl `<|>)) (funExt (bool refl refl)) ΝΎ eq/ _ _ (eqβ (inl (inl βπ».Synt.idem)) tt (const x))
<|>-assoc : (x y z : Term A) β (x <|> y) <|> z β‘ x <|> (y <|> z)
<|>-assoc = elimProp3/ (Ξ» _ _ _ β squash/ _ _ )
Ξ» x y z β
let h = eq/ _ _ (eqβ (inl (inl βπ».Synt.assoc)) tt Ξ» { zero β z ; (suc zero) β y ; _ β x })
in cong ([_] β Synt.op β _,_ (inl `<|>)) (funExt (bool refl (cong (Synt.op β _,_ (inl `<|>)) (funExt (bool refl refl)))))
ΝΎ sym h
ΝΎ cong ([_] β Synt.op β _,_ (inl `<|>)) (funExt (bool (cong (Synt.op β _,_ (inl `<|>)) (funExt (bool refl refl))) refl))
<|>-comm : (x y : Term A) β x <|> y β‘ y <|> x
<|>-comm = elimProp2/ (Ξ» _ _ β squash/ _ _ )
Ξ» x y β
let h = eq/ _ _ (eqβ (inl (inl βπ».Synt.comm)) tt Ξ» { zero β y ; _ β x })
in cong ([_] β Synt.op β _,_ (inl `<|>)) (funExt (bool refl refl))
ΝΎ h
ΝΎ cong ([_] β Synt.op β _,_ (inl `<|>)) (funExt (bool refl refl))
side : Term Bool
side = Opββ¦ inl `<|> β§
open import Hoare.Definition combinedTheory
open import Hoare.Lemmas combinedTheory
open import Hoare.Calculus combinedTheory
comm-<|>-op : β Oβ (k : Arity (inr Oβ) Γ Arity (inl `<|>) β Term A) β (do s β Opββ¦ inr Oβ β§; n β side; k (s , n)) β‘ (do n β side; s β Opββ¦ inr Oβ β§; k (s , n))
comm-<|>-op Oβ =
SplitQuotientedChoiceAt.elim~canonical
(quotientedChoiceProd (π.finiteOps Oβ) quotientedChoiceBool)
_
(Ξ» _ β squash/ _ _)
Ξ» k β sym (s β Opββ¦ inr Oβ β§ ΝΎ/ syntactic-bind (Ξ» n β k (s , n)) Opβ¦ inl `<|> β§)
ΝΎ sym (syntactic-bind (Ξ» s β Synt.op (inl `<|> , Ξ» n β k (s , n))) (Opβ¦ inr Oβ β§))
ΝΎ sym ( eq/ _ _ (commutesβ² `<|> Oβ (flip (curry k))) )
ΝΎ syntactic-bind (Ξ» n β Synt.op (inr Oβ , Ξ» s β k (s , n))) Opβ¦ inl `<|> β§
ΝΎ (n β side ΝΎ/ (syntactic-bind (Ξ» s β k (s , n)) Opβ¦ inr Oβ β§))
fail-exit : (k : A β Term B) β (fail >>= k) β‘ fail
fail-exit k =
fail >>= k β‘β¨ algebraic (inl `fail) k absurd β©
opβ (inl `fail , k β absurd) β‘β¨ cong {x = k β absurd} {y = [_] β absurd} (opβ β _,_ (inl `fail)) (funExt (Ξ» ())) β©
opβ (inl `fail , [_] β absurd) β‘β¨ opβ-com-[] absurd β©
[ Synt.op (inl `fail , absurd) ] β‘β¨β©
fail β
<|>-comm-dupe : (k : Bool β Bool β Term A) β (do sβ β side; sβ β side; k sβ sβ) β‘ (do sβ β side; sβ β side; k sβ sβ)
<|>-comm-dupe k =
(k true true <|> k true false) <|> (k false true <|> k false false) β‘β¨ <|>-assoc (k true true) (k true false) (k false true <|> k false false) ΝΎ cong (k true true <|>_) (sym (<|>-assoc (k true false) (k false true) (k false false))) β©
k true true <|> ((k true false <|> k false true) <|> k false false) β‘β¨ cong (Ξ» e β k true true <|> (e <|> k false false)) (<|>-comm (k true false) (k false true)) β©
k true true <|> ((k false true <|> k true false) <|> k false false) β‘Λβ¨ <|>-assoc (k true true) (k false true) (k true false <|> k false false) ΝΎ cong (k true true <|>_) (sym (<|>-assoc (k false true) (k true false) (k false false))) β©
(k true true <|> k false true) <|> (k true false <|> k false false) β
sefβ²-<|> : (k : A β Bool βΒ Term B) (p : Term A) β
(do x β p ; s β side ; k x s) β‘ (do s β side ; x β p ; k x s)
sefβ²-<|> k =
elimβ-prop
_
(Ξ» _ β squash/ _ _)
Ξ» { (Synt.var x) β refl
; (Synt.op (Oα΅’ , xs) Pβ¨xsβ©) β algebraic Oα΅’ _ _ ΝΎ (i β Opββ¦ Oα΅’ β§ ΝΎ/ Pβ¨xsβ© i) ΝΎ lemma Oα΅’ xs k Pβ¨xsβ© ΝΎ s β side ΝΎ/ (sym (algebraic Oα΅’ (Ξ» x β k x s) xs))
}
where
lemma : β Oα΅’ (xs : Arity Oα΅’ β Term A) (k : A β Bool β Term B)
β (β i β (xs i >>= Ξ» x β side >>= k x) β‘ side >>= (Ξ» s β xs i >>= Ξ» x β k x s))
β (do i β Opββ¦ Oα΅’ β§; s β side; x β xs i; k x s) β‘ (do s β side ; i β Opββ¦ Oα΅’ β§; x β xs i; k x s)
lemma (inl `<|>) xs k x = <|>-comm-dupe (Ξ» sβ sβ β xs sβ >>= Ξ» x β k x sβ)
lemma (inr Oβ) xs k x = comm-<|>-op Oβ (Ξ» { (i , s) β xs i >>= flip k s })
lemma (inl `fail) xs k x =
(do f β Opββ¦ inl `fail β§
s β side
x β xs f
k x s) β‘β¨ fail-exit (Ξ» f β side >>= Ξ» s β xs f >>= flip k s) β©
fail β‘Λβ¨ <|>-idem fail β©
(do s β side
fail) β‘Λβ¨ s β side ΝΎ/ fail-exit (xs >=> flip k s) β©
(do s β side
f β Opββ¦ inl `fail β§
x β xs f
k x s) β
sef-<|> : (p : Term A) (q r : A β Term B) β (p >>= (Ξ» x β q x <|> r x)) β‘ ((p >>= q) <|> (p >>= r))
sef-<|> p q r = sefβ²-<|> (Ξ» x s β bool (r x) (q x) s) p
module _ where
open import Truth.MonoLevel βzero
open import Truth using (|β|-id)
guard-hoare : β p β β
β guard p β
return (|T| p) β
guard-hoare false .proof k = refl
guard-hoare true .proof k = cong (k tt) (|β|-id _)
fail-absurd : (Ο : A β Term Ξ©) β
β
β x β fail β
Ο x β
fail-absurd Ο .proof k = refl
open import Truth
<|>-conj : {A : Type a}
β (Ο : Term (Ξ© a)) β
(Ο : A β Term (Ξ© a))
β (p q : Term A) β
β
Ο β x β p β
Ο x β β
β
Ο β x β q β
Ο x β β
β
Ο β x β p <|> q β
Ο x β
<|>-conj Ο Ο p q lhs rhs .proof k =
(do a β Ο
x β (p <|> q)
b β Ο x
k x (a |β| b)) β‘β¨ a β Ο ΝΎ/ <|>-alg p q _ β©
(do a β Ο;
(do x β p
b β Ο x
k x (a |β| b))
<|>
(do x β q
b β Ο x
k x (a |β| b)))
β‘β¨ sef-<|> Ο _ _ β©
(do a β Ο
x β p
b β Ο x
k x (a |β| b))
<|>
(do a β Ο
x β q
b β Ο x
k x (a |β| b))
β‘β¨ congβ _<|>_ (lhs .proof k) (rhs .proof k) β©
(do a β Ο
x β p
b β Ο x
k x True)
<|>
(do a β Ο
x β q
b β Ο x
k x True)
β‘Λβ¨ sef-<|> Ο _ _ β©
(do a β Ο;
(do x β p
b β Ο x
k x True)
<|>
(do x β q
b β Ο x
k x True))
β‘Λβ¨ a β Ο ΝΎ/ <|>-alg p q _ β©
(do a β Ο
x β (p <|> q)
b β Ο x
k x True) β