module Examples.Bool where
open import Prelude.Function
open import Prelude.InverseImage
open import Refinement
open import Description
open import Ornament
open import Data.Unit using (⊤; tt)
open import Data.Empty using (⊥)
open import Data.Product using (Σ; _,_)
open import Data.List using (List; []; _∷_)
open import Relation.Binary.PropositionalEquality using (_≡_; refl; cong)
data BoolTag : Set where
`false : BoolTag
`true : BoolTag
BoolD : Desc ⊤
BoolD = wrap λ _ → σ[ _ ∈ BoolTag ] ṿ []
MaybeOD : Set → OrnDesc ⊤ ! BoolD
MaybeOD A = wrap λ _ → σ BoolTag λ { `false → ṿ tt
; `true → Δ[ _ ∈ A ] ṿ tt }
Maybe : Set → Set
Maybe A = μ ⌊ MaybeOD A ⌋ tt
pattern nothing = con (`false , _)
pattern just a = con (`true , a , _)
mapMaybe : {A B : Set} → (A → B) → Maybe A → Maybe B
mapMaybe f nothing = nothing
mapMaybe f (just a) = just (f a)
EitherOD : Set → Set → OrnDesc ⊤ ! BoolD
EitherOD A B = wrap λ _ → σ BoolTag λ { `false → Δ[ _ ∈ A ] ṿ tt
; `true → Δ[ _ ∈ B ] ṿ tt }
Maybe'OD : {A : Set} (B : A → Set) → OrnDesc (Maybe A) ! ⌊ MaybeOD (Σ A B) ⌋
Maybe'OD B = wrap λ { {._} (ok nothing ) → ∇ `false (ṿ tt)
; {._} (ok (just a)) → ∇ `true (Δ[ b ∈ B a ] ∇ (a , b) (ṿ tt)) }
Maybe' : {A : Set} → (A → Set) → Maybe A → Set
Maybe' B = μ ⌊ Maybe'OD B ⌋
maybeU : {A B : Set} → Upgrade A B → Upgrade (Maybe A) (Maybe B)
maybeU {A} {B} upg = record
{ P = Maybe' (Upgrade.P upg)
; C = λ { nothing nothing → ⊤
; nothing (just b) → ⊥
; (just a) nothing → ⊥
; (just a) (just b) → Upgrade.C upg a b }
; u = λ { nothing mp → nothing
; (just a) (con (p , _)) → just (Upgrade.u upg a p) }
; c = λ { nothing mp → tt
; (just a) (con (p , _)) → Upgrade.c upg a p } }
maybeFU : {A B : Set} → FUpgrade A B → FUpgrade (Maybe A) (Maybe B)
maybeFU {A} {B} fupg = record
{ P = Maybe' (FUpgrade.P fupg)
; forget = mapMaybe (FUpgrade.forget fupg)
; u = λ { nothing mp → nothing
; (just a) (con (p , _)) → just (FUpgrade.u fupg a p) }
; c = λ { nothing mp → refl
; (just a) (con (p , _)) → cong just (FUpgrade.c fupg a p) } }