{-# 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) β