module ListConform where
open import Data.List hiding (any ; length ; lookup ; zip) renaming (map to mapl)
open import Data.Bool hiding (_≤_ ; _<_)
open import Data.Char.Properties
open import Data.String.Base hiding (_<_)
open import Data.String hiding (_<_)
open import Data.Sum hiding (swap ; map₂ ; map₁)
open import Data.Product
open import Data.Empty
open import Data.Fin renaming (suc to fsuc) hiding (_≤_ ; _<_)
open import Data.Fin.Properties renaming (suc-injective to fsuc-injective)
open import Data.Nat hiding (_⊔_ ; _≤_ ; _<_)
open import Data.Maybe hiding (zip ; _>>=_)
open import Data.Maybe.Properties
open import Data.Maybe.Categorical
open import Data.List.Relation.Unary.Any renaming (map to mapAny)
open import Agda.Primitive
open import Relation.Nullary
open import Relation.Nullary.Negation
open import Relation.Nullary.Decidable
open import Relation.Unary hiding (_∈_ ; _∉_ ; _⇒_) renaming (Decidable to Decidableₚ)
open import Relation.Binary renaming (Decidable to Decidableᵣ)
open import Relation.Binary.PropositionalEquality hiding ([_])
open import ListSugar renaming (_,_ to _↪_)
open import Function hiding (_↪_)
open import Category.Monad
module AnyUnique where
data Any! {a b} {A : Set a} (P : Pred A b) : Pred (List A) (a ⊔ b)
where
here! : ∀ {x xs} → P x → ¬ Any P xs → Any! P (x ∷ xs)
there! : ∀ {x xs} → ¬ P x → Any! P xs → Any! P (x ∷ xs)
data _≤_ : Rel ℕ lzero where
z≤n : ∀ {n} → zero ≤ n
s≤s : ∀ {m n} → m ≤ n → suc m ≤ suc n
_<_ : Rel ℕ _
m < n = suc m ≤ n
3< : Any! (_< 3) (⟦ 5 ↪ 2 ↪ 3 ⟧)
3< = there! (λ {(s≤s (s≤s (s≤s ())))}) (here! (s≤s (s≤s (s≤s z≤n)))
λ {(here (s≤s (s≤s (s≤s ())))) ; (there ())})
s≡5 : Any! ((_≡ 5) ∘ length) (⟦ "one" ↪ "two" ↪ "three" ⟧)
s≡5 = there! (λ ()) (there! (λ ()) (here! refl λ ()))
private
variable
a b : Level
A : Set a
P : Pred A b
x : A
l : List A
A!→A : Any! P l → Any P l
A!→A (here! x₁ _ ) = here x₁
A!→A (there! _ any₁) = there (A!→A any₁)
P→A→¬A! : P x → Any P l → ¬ Any! P (x ∷ l)
P→A→¬A! _ apl (here! _ ¬apl) = ¬apl apl
P→A→¬A! px _ (there! ¬px _) = ¬px px
¬P→¬A!→¬A! : ¬ P x → ¬ Any! P l → ¬ Any! P (x ∷ l)
¬P→¬A!→¬A! ¬px _ (here! px _) = ¬px px
¬P→¬A!→¬A! _ ¬a!pl (there! _ a!pl) = ¬a!pl a!pl
¬A!→P→¬A : Any! P (x ∷ l) → P x → ¬ Any P l
¬A!→P→¬A (here! _ ¬apl) _ = ¬apl
¬A!→P→¬A (there! ¬px _) px _ = ¬px px
¬P→¬A→¬A : ¬ P x → ¬ Any P l → ¬ Any P (x ∷ l)
¬P→¬A→¬A ¬px _ (here px) = ¬px px
¬P→¬A→¬A _ ¬apl (there apxl) = ¬apl apxl
¬A[] : ¬ Any P []
¬A[] ()
infixr 1 ¬P→¬A→¬A
syntax ¬P→¬A→¬A ¬px ¬apl = ¬px ↦ ¬apl
syntax P→A→¬A! yRx w₂ = yRx ¬! w₂
decAny! : Decidableₚ P → Decidableₚ (Any! P)
decAny! _ [] = no (λ ())
decAny! decP (x ∷ _) with decP x
decAny! decP (_ ∷ l) | yes _ with (any decP) l
decAny! _ _ | yes px | yes apl = no (P→A→¬A! px apl)
decAny! _ _ | yes px | no ¬apl = yes (here! px ¬apl)
decAny! decP (_ ∷ l) | no ¬px with decAny! decP l
decAny! _ _ | no ¬px | yes a!pl = yes (there! ¬px a!pl)
decAny! _ _ | no ¬px | no ¬a!pl = no (¬P→¬A!→¬A! ¬px ¬a!pl)
open AnyUnique
module Membership {a b c} {A : Set a} {B : Set b} (_R_ : REL A B c) where
_∈_ : REL A (List B) _
x ∈ xs = Any (x R_) xs
_∈!_ : REL A (List B) _
x ∈! xs = Any! (x R_) xs
_∉_ : REL A (List B) _
x ∉ xs = ¬ (x ∈ xs)
_∉!_ : REL A (List B) _
x ∉! xs = ¬ (x ∈! xs)
dec∈ : Decidableᵣ _R_ → Decidableᵣ _∈_
dec∈ = any ∘_
dec∉ : Decidableᵣ _R_ → Decidableᵣ _∉_
dec∉ dec x = ¬? ∘ (dec∈ dec x)
dec∈! : Decidableᵣ _R_ → Decidableᵣ _∈!_
dec∈! = decAny! ∘_
dec∉! : Decidableᵣ _R_ → Decidableᵣ _∉!_
dec∉! dec x = ¬? ∘ (dec∈! dec x)
module Examples where
4<5 : 4 < 5
4<5 = s≤s (s≤s (s≤s (s≤s (s≤s z≤n))))
2<3 : 2 < 3
2<3 = s≤s (s≤s (s≤s z≤n))
2<5 : 2 < 5
2<5 = s≤s (s≤s (s≤s z≤n))
open Membership _<_ hiding (_∉_ ; _∈!_)
renaming (_∈_ to _∈<_ ; _∉!_ to _∉!<_)
list₁ : List ℕ
list₁ = ⟦ 3 ↪ 5 ↪ 2 ⟧
4∈list₁ : 4 ∈< list₁
4∈list₁ = there (here 4<5)
2∉!list₁ : 2 ∉!< list₁
2∉!list₁ (here! _ ¬2∈<[5,2]) = ¬2∈<[5,2] (here 2<5)
2∉!list₁ (there! ¬2<3 _) = ¬2<3 2<3
open import Data.List.Membership.Setoid Data.Char.Properties.≡-setoid
_∈l_ : _ → _ → _
c ∈l s = c ∈ toList s
_∉l_ : _ → _ → _
c ∉l s = c ∉ toList s
z∉Alice : 'z' ∉l "Alice"
z∉Alice = (λ ()) ↦ (λ ()) ↦ (λ ()) ↦ (λ ()) ↦ (λ ()) ↦ ¬A[]
z∉Bob : 'z' ∉l "Bob"
z∉Bob = (λ ()) ↦ (λ ()) ↦ (λ ()) ↦ ¬A[]
z∉Judith : 'z' ∉l "Judith"
z∉Judith = (λ ()) ↦ (λ ()) ↦ (λ ()) ↦ (λ ()) ↦ (λ ()) ↦ (λ ()) ↦ ¬A[]
J∉Alice : 'J' ∉l "Alice"
J∉Alice = (λ ()) ↦ (λ ()) ↦ (λ ()) ↦ (λ ()) ↦ (λ ()) ↦ ¬A[]
J∉Bob : 'J' ∉l "Bob"
J∉Bob = (λ ()) ↦ (λ ()) ↦ (λ ()) ↦ ¬A[]
J∈Judith : 'J' ∈l "Judith"
J∈Judith = here refl
open Membership _∈l_ hiding (_∈_ ; _∉!_)
renaming (_∉_ to _∉s_ ; _∈!_ to _∈!s_)
list₂ : List String
list₂ = ⟦ "Alice" ↪ "Bob" ↪ "Judith" ⟧
z∉list₂ : 'z' ∉s list₂
z∉list₂ (here z∈Alice) = z∉Alice z∈Alice
z∉list₂ (there (here z∈Bob)) = z∉Bob z∈Bob
z∉list₂ (there (there (here z∈Judith))) = z∉Judith z∈Judith
z∉list₂ (there (there (there ())))
z∉list₂' : 'z' ∉s list₂
z∉list₂' = z∉Alice ↦ z∉Bob ↦ z∉Judith ↦ ¬A[]
J∈!list₂ : 'J' ∈!s list₂
J∈!list₂ = there! J∉Alice (there! J∉Bob (here! J∈Judith λ ()))
module GlobalUnicity {a b c} {A : Set a} {B : Set b} (_R_ : REL A B c) where
open Membership _R_
_∈∈!_ : REL _ _ _
x ∈∈! l = x ∈ l → x ∈! l
Dec∈∈! : Decidableᵣ _R_ → Decidableᵣ _∈∈!_
Dec∈∈! decR x l with dec∈! decR x l
Dec∈∈! _ _ _ | yes p = yes (λ _ → p)
Dec∈∈! decR x l | no _ with dec∈ decR x l
Dec∈∈! _ _ _ | no ¬x∈!l | yes x∈l = no (λ x∈∈!l → ¬x∈!l (x∈∈!l x∈l))
Dec∈∈! _ _ _ | no _ | no ¬x∈l = yes (λ x∈l → ⊥-elim (¬x∈l x∈l))
GlobalUnicity : Pred _ _
GlobalUnicity l = ∀ {x} → x ∈∈! l
record GUList : Set (a ⊔ b ⊔ c) where
constructor gulist
field
content : List B
unique : GlobalUnicity content
gu[a] : ∀ {a} → GlobalUnicity [ a ]
gu[a] (here px) = here! px λ ()
private
variable
x : B
l : List B
guTl : GlobalUnicity (x ∷ l) → GlobalUnicity l
guTl guxl y∈l with guxl (there y∈l)
guTl _ y∈l | here! _ y∉l = contradiction y∈l y∉l
guTl _ y∈l | there! _ y∈!l = y∈!l
_witnesses_ : _
_witnesses_ = flip _R_
_[witnesses]_ : _
_[witnesses]_ = flip _∈_
infix 10 _witnesses_
infix 10 _[witnesses]_
≡index : _ → Set _
≡index l = ∀ {y} (w₁ w₂ : l [witnesses] y) → index w₁ ≡ index w₂
⇒ : GlobalUnicity l → ≡index l
⇒ _ (here _) (here _) = refl
⇒ gul (here yRx) (there w₂) = ⊥-elim ((yRx ¬! w₂) (gul (here yRx)))
⇒ gul (there w₁) (here yRx) = ⊥-elim ((yRx ¬! w₁) (gul (here yRx)))
⇒ gul (there w₁) (there w₂) = cong fsuc (⇒ (guTl gul) w₁ w₂)
helper : ∀ {y} → ≡index (x ∷ l) → x witnesses y → ¬ l [witnesses] y
helper ≡ind px x∈xs = case ≡ind (here px) (there x∈xs) of λ ()
⇐ : ≡index l → GlobalUnicity l
⇐ ≡ind (here px) = here! px (helper ≡ind px)
⇐ ≡ind (there x∈l) = there! (_⟨ helper ≡ind ⟩ x∈l)
(⇐ (λ w₁ w₂ → fsuc-injective (≡ind (there w₁) (there w₂))) x∈l)
_∷ᵤ_ : (∀ {y} → x witnesses y → ¬ l [witnesses] y)
→ GlobalUnicity l → GlobalUnicity (x ∷ l)
_∷ᵤ_ p _ (here yRx) = here! yRx (p yRx)
_∷ᵤ_ p gul (there y∈l) = there! (_⟨ p ⟩ y∈l) (gul y∈l)
infixr 10 _∷ᵤ_
gu[] : GlobalUnicity []
gu[] ()
gu[a]₀ : ∀ {a} → GlobalUnicity [ a ]
gu[a]₀ = (λ {_ ()}) ∷ᵤ gu[]
module GlobalUnicityExample where
open AnyUnique
open GlobalUnicity {A = ℕ} _≡_
l : List _
l = ⟦ 3 ↪ 5 ↪ 2 ⟧
¬⟦5,2⟧w3 : ∀ {y} → 3 witnesses y → ¬ ⟦ 5 ↪ 2 ⟧ [witnesses] y
¬⟦5,2⟧w3 refl = (λ ()) ↦ (λ ()) ↦ ¬A[]
¬⟦2⟧w5 : ∀ {y} → 5 witnesses y → ¬ ⟦ 2 ⟧ [witnesses] y
¬⟦2⟧w5 refl = (λ ()) ↦ ¬A[]
¬⟦⟧w2 : ∀ {y} → 2 witnesses y → ¬ [] [witnesses] y
¬⟦⟧w2 _ ()
gul : GlobalUnicity l
gul = ¬⟦5,2⟧w3 ∷ᵤ ¬⟦2⟧w5 ∷ᵤ ¬⟦⟧w2 ∷ᵤ gu[]
module GloballyUniqueEquivalence {a b} {A : Set a} {_≈_ : Rel A b}
(isEq : IsEquivalence _≈_) where
open GlobalUnicity _≈_
open Membership _≈_ renaming (_∈_ to _∈≈_)
open import Data.List.Membership.Setoid (record { Carrier = A ; _≈_ = _≡_ ; isEquivalence = isEquivalence })
open Relation.Binary.PropositionalEquality.≡-Reasoning
open IsEquivalence renaming (refl to ≈refl ; trans to ≈trans ; sym to ≈sym)
∈→∈≈ : ∀ {x l} → x ∈ l → x ∈≈ l
∈→∈≈ (here refl) = here (≈refl isEq)
∈→∈≈ (there x∈l) = there (∈→∈≈ x∈l)
i≡ic : ∀ {x l} (p : x ∈ l) → index p ≡ index (∈→∈≈ p)
i≡ic (here refl) = refl
i≡ic (there p) = cong fsuc (i≡ic p)
trans∈≈ : ∀ {x y l} → x ≈ y → x ∈≈ l → y ∈≈ l
trans∈≈ x≈y (here px) = here (≈trans isEq (≈sym isEq x≈y) px)
trans∈≈ x≈y (there x∈≈l) = there (trans∈≈ x≈y x∈≈l)
it≡i : ∀ {x y l} (p : x ≈ y) (q : x ∈≈ l)
→ index (trans∈≈ p q) ≡ index q
it≡i p (here px) = refl
it≡i p (there q) = cong fsuc (it≡i p q)
≡i→≡ : ∀ {x y l} {x∈l : x ∈ l} {y∈l : y ∈ l}
→ index x∈l ≡ index y∈l → x ≡ y
≡i→≡ {x∈l = here refl} {here refl} refl = refl
≡i→≡ {x∈l = here px} {there y∈l} ()
≡i→≡ {x∈l = there x∈l} {here px} ()
≡i→≡ {x∈l = there x∈l} {there y∈l} u = ≡i→≡ (fsuc-injective u)
gueq : ∀ {x y l} → x ∈ l → y ∈ l → GlobalUnicity l → x ≈ y → x ≡ y
gueq x∈l y∈l gul x≈y = ≡i→≡ (begin
index x∈l ≡⟨ i≡ic x∈l ⟩
index (∈→∈≈ x∈l)
≡⟨ ⇒ gul (∈→∈≈ x∈l) (trans∈≈ (≈sym isEq x≈y) (∈→∈≈ y∈l)) ⟩
index (trans∈≈ (≈sym isEq x≈y) (∈→∈≈ y∈l))
≡⟨ it≡i (≈sym isEq x≈y) (∈→∈≈ y∈l) ⟩
index (∈→∈≈ y∈l) ≡˘⟨ i≡ic y∈l ⟩
index y∈l ∎)
module GloballyUniqueTotalOrder {a b c} {A : Set a} {_≈_ : Rel A b}
{_≼_ : Rel A c} (isTot : IsTotalOrder _≈_ _≼_) where
open GlobalUnicity _≼_
open IsEquivalence
open IsTotalOrder
≼refl : ∀ {v} → v ≼ v
≼refl = IsPreorder.reflexive (IsPartialOrder.isPreorder (isPartialOrder isTot)) (IsEquivalence.refl (IsPreorder.isEquivalence (IsPartialOrder.isPreorder (isPartialOrder isTot))))
prop : ∀ {l} → GlobalUnicity l → ¬ Data.List.length l > 1
prop {[]} _ ()
prop {_ ∷ []} _ (s≤s ())
prop {x ∷ y ∷ _} _ with total isTot x y
prop {_ ∷ _ ∷ _} gul | inj₁ x≼y =
contradiction (gul (here ≼refl)) (P→A→¬A! ≼refl (here x≼y))
prop {_ ∷ _ ∷ _} gul | inj₂ y≼x =
contradiction (gul (there (here ≼refl))) (P→A→¬A! y≼x (here ≼refl))
prop₂ : ∀ {l} → ¬ Data.List.length l > 1 → GlobalUnicity l
prop₂ {[]} _ = gu[]
prop₂ {_ ∷ []} _ = gu[a]
prop₂ {_ ∷ _ ∷ _} p = case (p (s≤s (s≤s z≤n))) of λ ()
module FunctionRelation
{a b} {A : Set a} {B : Set b} (f : B → A) where
_≡f_ : REL A B a
_≡f_ x = (x ≡_) ∘ f
dec≡f : Decidableᵣ {A = A} _≡_ → Decidableᵣ _≡f_
dec≡f dec x = (dec x) ∘ f
module Commands {a b c} {A : Set a} {B : Set b} {C : Set c}
(f : B → A) (dec : Decidableᵣ {A = A} _≡_) (g : B → C) where
open FunctionRelation f
open Membership _≡f_
open GlobalUnicity _≡f_
newGUL : GUList
newGUL = gulist [] gu[]
trim : (gul : GUList) → ¬ (GUList.content gul) ≡ [] → GUList
trim (gulist [] unique) p = ⊥-elim (p refl)
trim (gulist (_ ∷ content) unique) _ = gulist content (guTl unique)
decGU : Decidableₚ GlobalUnicity
decGU [] = yes gu[]
decGU (x ∷ l) with dec∈ (dec≡f dec) (f x) l
decGU _ | yes fx∈l =
no (λ guxl → P→A→¬A! refl fx∈l (guxl (here refl)))
decGU (x ∷ l) | no _ with decGU l
decGU _ | no ¬fx∈l | yes gul =
yes ((λ {refl fx∈l → ¬fx∈l fx∈l}) ∷ᵤ gul)
decGU _ | no _ | no ¬p = no (contraposition guTl ¬p)
newFrom : List B → Maybe GUList
newFrom l with decGU l
newFrom l | yes p = just (gulist l p)
newFrom _ | no _ = nothing
open GUList
put : ∀ b l → List B
put = _∷_
put∈ : ∀ {x b l} → x ∈ l → x ∈ put b l
put∈ = there
putGUL : ∀ {b l} → f b ∉ l → GlobalUnicity l → GlobalUnicity (put b l)
putGUL p _ (here refl) = here! refl p
putGUL p = (λ {refl q → p q}) ∷ᵤ_
put_into_when_ : ∀ b → (l : GUList) → f b ∉ (content l) → GUList
put b into (gulist l gul) when p = gulist (put b l) (putGUL p gul)
put_inside_ : B → GUList → Maybe GUList
put b inside l with dec∉ (dec≡f dec) (f b) (content l)
put b inside l | yes p = just (put b into l when p)
put _ inside _ | no _ = nothing
put_inside'_ : B → GUList → Maybe GUList
put_inside'_ b = newFrom ∘ put b ∘ content
assign_inside_when_ : ∀ b l (fb∈l : f b ∈ l) → List B
assign b inside (_ ∷ l) when here _ = b ∷ l
assign b inside (x ∷ l) when there fb∈l =
x ∷ (assign b inside l when fb∈l)
∈assign : ∀ {a b l p} → a ∈ (assign b inside l when p) → a ∈ l
∈assign {p = here p} (here q) = here (trans q p)
∈assign {p = here _} (there q) = there q
∈assign {p = there _} (here q) = here q
∈assign {p = there _} (there q) = there (∈assign q)
assign∈ : ∀ {a b l p} → a ∈ l → a ∈ (assign b inside l when p)
assign∈ {p = here p} (here q) = here (trans q (sym p))
assign∈ {p = here _} (there q) = there q
assign∈ {p = there _} (here q) = here q
assign∈ {p = there _} (there q) = there (assign∈ q)
assign∈! : ∀ {a b l p} → a ∈! l → a ∈! (assign b inside l when p)
assign∈! {p = here p} (here! x y) = here! (trans x (sym p)) y
assign∈! {p = here p} (there! x y) = there! (x ∘ (flip trans) p) y
assign∈! {p = there _} (here! x y) = here! x (contraposition ∈assign y)
assign∈! {p = there _} (there! x y) = there! x (assign∈! y)
∈!assign : ∀ {a b l p} → a ∈! (assign b inside l when p) → a ∈! l
∈!assign {p = here p} (here! x y) = here! (trans x p) y
∈!assign {p = here p} (there! x y) = there! (x ∘ (flip trans) (sym p)) y
∈!assign {p = there _} (here! x y) = here! x (contraposition assign∈ y)
∈!assign {p = there _} (there! x y) = there! x (∈!assign y)
assignGUL : ∀ {b l p} → GlobalUnicity l
→ GlobalUnicity (assign b inside l when p)
assignGUL gul = assign∈! ∘ gul ∘ ∈assign
assign_inside_if_ : ∀ b l (fb∈l : f b ∈ content l) → GUList
assign b inside gulist l gul if p = gulist
(assign b inside l when p)
(assignGUL gul)
assign_inside_ : ∀ b (gul : GUList) → Maybe GUList
assign b inside l with dec∈ (dec≡f dec) (f b) (content l)
assign b inside l | yes p = just (assign b inside l if p)
assign _ inside _ | no _ = nothing
remove_from_when_ : ∀ a l (p : a ∈ l) → List B
remove a from (b ∷ l) when here px = l
remove a from (b ∷ l) when there a∈l = b ∷ remove a from l when a∈l
∉remove : ∀ {x a l p} → x ∉ l → x ∉ (remove a from l when p)
∉remove {p = here _} = contraposition there
∉remove {p = there _} x∉l (here px) = x∉l (here px)
∉remove {p = there p} x∉l (there x∈rm) =
∉remove {p = p} (contraposition there x∉l) x∈rm
removeGUL : ∀ {a l p} → GlobalUnicity l
→ GlobalUnicity (remove a from l when p)
removeGUL {p = here _} = guTl
removeGUL {p = there _} gul =
(λ x≡fb → ∉remove λ x∈xs →
P→A→¬A! x≡fb x∈xs (gul (here x≡fb)))
∷ᵤ removeGUL (guTl gul)
remove_from_ : ∀ a (gul : GUList) → Maybe GUList
remove a from gulist l _ with dec∈ (dec≡f dec) a l
remove a from gulist l gul | yes p =
just (gulist (remove a from l when p) (removeGUL gul))
remove _ from _ | no _ = nothing
assignOrPut_inside_ : ∀ b (gul : GUList) → GUList
assignOrPut b inside gulist l _ with dec∈ (dec≡f dec) (f b) l
assignOrPut b inside gulist l gul | yes p =
gulist (assign b inside l when p) (assignGUL gul)
assignOrPut b inside gulist l gul | no ¬p =
gulist (put b l) (putGUL ¬p gul)
open RawMonad {f = a ⊔ b} monad
collapse : ∀ {u} {X : Set u} → (X → GUList → Maybe GUList)
→ List X → GUList → Maybe GUList
collapse g l gul = foldl (λ mgu → (mgu >>=_) ∘ g) (return gul) l
putAll : List B → GUList → Maybe GUList
putAll = collapse put_inside_
removeAll : List A → GUList → Maybe GUList
removeAll = collapse remove_from_
assignAll : List B → GUList → Maybe GUList
assignAll = collapse assign_inside_
assignOrPutAll : List B → GUList → Maybe GUList
assignOrPutAll = collapse λ x → just ∘ (assignOrPut x inside_)
get_from_when_ : ∀ a l → a ∈ l → C
get _ from (b ∷ _) when here _ = g b
get a from (_ ∷ l) when there p = get a from l when p
get_from_if_ : ∀ a l → a ∈ (content l) → C
get a from l if p = get a from (content l) when p
get_from_ : ∀ a l → Maybe C
get a from l with dec∈ (dec≡f dec) a l
get a from l | yes p = just (get a from l when p)
get _ from _ | no ¬p = nothing
get : ∀ a gul → Maybe C
get a = get a from_ ∘ content
_∈ₗ_ : REL A GUList _
_∈ₗ_ x = x ∈_ ∘ content
dec∈ₗ : Decidableᵣ _∈ₗ_
dec∈ₗ x (gulist _ _) = dec∈ (dec≡f dec) x _
contains : GUList → A → Bool
contains gul x = does (dec∈ₗ x gul)
private
elements : ∀ {x} {X : Set x} → (B → X) → GUList → List X
elements f = (mapl f) ∘ content
elementsF : GUList → List A
elementsF = elements f
elementsG : GUList → List C
elementsG = elements g
elementsId : GUList → List B
elementsId = elements id
module Example1 where
open Commands id Data.String._≟_ id
open FunctionRelation {A = String} id
open GlobalUnicity _≡f_
open RawMonad {f = lzero} monad
ex₁ : Maybe GUList
ex₁ = return newGUL
>>= putAll (⟦ "Judith" ↪ "Bob" ↪ "Alice" ⟧)
ex₂ : Maybe GUList
ex₂ = ex₁ >>= putAll (⟦ "Judith" ↪ "Hector" ⟧)
module Example2 where
open Commands {B = ℕ × ℕ} (proj₁) (Data.Nat._≟_) (proj₂)
open FunctionRelation {B = ℕ × ℕ} proj₁
open GlobalUnicity _≡f_
open RawMonad {f = lzero} monad
ex₁ : Maybe GUList
ex₁ = return newGUL
>>= putAll (⟦ (3 , 4) ↪ (4 , 5) ↪ (5 , 5) ⟧)
>>= assignOrPutAll (⟦ (4 , 7) ↪ (3 , 12) ↪ (3 , 10) ↪ (5 , 1) ⟧)
ex₂ : Maybe GUList
ex₂ = ex₁ >>= assignAll (⟦ (3 , 12) ↪ (4 , 10) ↪ (5 , 1) ⟧)
ex₃ : Maybe GUList
ex₃ = ex₂ >>= putAll (⟦ (12 , 4) ↪ (20 , 5) ↪ (3 , 12) ⟧)
ex₄ : Maybe GUList
ex₄ = ex₂ >>= assignAll (⟦ (3 , 6) ↪ (7 , 8) ↪ (5 , 1) ⟧)
val₁ : Maybe ℕ
val₁ = ex₄ >>= get 3
val₂ : Maybe ℕ
val₂ = ex₂ >>= get 3
val₃ : Maybe ℕ
val₃ = ex₂ >>= get 6
el₁ : Maybe (List ℕ)
el₁ = ex₂ >>= just ∘ elementsG
module ListInclusion {a ℓ} {A : Set a} {_≈_ : Rel A ℓ}
(dec≈ : Decidableᵣ _≈_) (eq≈ : IsEquivalence _≈_) where
open Membership _≈_
_⊑_ : Rel (List A) _
_⊑_ = _⊆_ on flip _∈_
_≋_ : Rel (List A) _
_≋_ = _⊑_ -[ _×_ ]- flip _⊑_
open IsEquivalence renaming (trans to trans≈ ; refl to refl≈)
conserv∈≈ : ∀ {x y l} → x ∈ l → y ≈ x → y ∈ l
conserv∈≈ (here px) = here ∘ flip (trans≈ eq≈) px
conserv∈≈ (there p) = there ∘ conserv∈≈ p
dec⊑ : Decidableᵣ _⊑_
dec⊑ [] l₂ = yes λ()
dec⊑ (x ∷ l₁) l₂ with dec∈ dec≈ x l₂ | dec⊑ l₁ l₂
dec⊑ _ _ | yes p | (yes p₁) =
yes (λ {(here px) → conserv∈≈ p px ; (there x₂) → p₁ x₂})
dec⊑ _ _ | yes _ | (no ¬p ) = no (λ x₁ → ¬p (λ x₃ → x₁ (there x₃)))
dec⊑ _ _ | no ¬p | _ = no (λ x₁ → ¬p (x₁ (here (refl≈ eq≈))))
dec≋ : Decidableᵣ _≋_
dec≋ l₁ l₂ with dec⊑ l₁ l₂ | dec⊑ l₂ l₁
dec≋ _ _ | yes p | (yes p₁) = yes (p , p₁)
dec≋ _ _ | yes p | (no ¬p ) = no (¬p ∘ proj₂)
dec≋ _ _ | no ¬p | _ = no (¬p ∘ proj₁)
isEq≋ : IsEquivalence _≋_
isEq≋ = record {
refl = id , id ;
sym = swap ;
trans = zip (\f g → g ∘ f) \f g → f ∘ g }
module GUCompare {a b c} {A : Set a} {B : Set b} {C : Set c}
(f : B → A) (_≟a_ : Decidableᵣ {A = A} _≡_) (g : B → C)
(injfg : ∀ {x y} → (f x , g x) ≡ (f y , g y) → x ≡ y)
(_≟b_ : Decidableᵣ {A = B} _≡_) where
open Commands f _≟a_ g
open ListInclusion _≟b_ isEquivalence
open FunctionRelation f
open Membership _≡f_ renaming (_∈_ to _∈f_ ; dec∈ to dec∈f)
open Membership {A = B} _≡_
renaming (_∈_ to _∈≡_ ; dec∈ to dec∈≡)
open GlobalUnicity _≡f_
open GUList
dec∈fa : Decidableᵣ _
dec∈fa = (dec∈f ∘ dec≡f) _≟a_
_≋₁_ : Rel GUList _
_≋₁_ = _≋_ on content
eq≋₁ : IsEquivalence _≋₁_
eq≋₁ with isEq≋
eq≋₁ | record { refl = refl≋ ; sym = sym≋ ; trans = trans≋ }
= record { refl = refl≋ ; sym = sym≋ ; trans = trans≋ }
dec≋₁ : Decidableᵣ _≋₁_
dec≋₁ (gulist l₁ _) (gulist l₂ _) = dec≋ l₁ l₂
_≋₂_ : Rel GUList _
gu₁ ≋₂ gu₂ = ∀ {x} → get x gu₁ ≡ get x gu₂
eq≋₂ : IsEquivalence _≋₂_
eq≋₂ = record
{ refl = refl ;
sym = λ x → sym x ;
trans = λ x x₁ → trans x x₁ }
gu≡ : ∀ {b₀ b₁ l} → GlobalUnicity (b₀ ∷ l) → f b₁ ≡ f b₀
→ GlobalUnicity (b₁ ∷ l)
gu≡ gulb₀ eq (here refl) =
here! refl (contradiction (gulb₀ (here eq)) ∘ (P→A→¬A! eq))
gu≡ gulb₀ eq (there q) =
there! (λ p → ¬A!→P→¬A
(gulb₀ (there q)) (trans p eq) q) (guTl gulb₀ q)
∈≡→∈f : ∀ {b b₁ l} → f b ≡ f b₁ → b ∈≡ l → (f b₁) ∈f l
∈≡→∈f px = mapAny λ {refl → sym px}
∈≡→∈f' : ∀ {b l} → b ∈≡ l → (f b) ∈f l
∈≡→∈f' = ∈≡→∈f refl
get≡g : ∀ {b l p} → GlobalUnicity l → b ∈≡ l
→ get f b from l when p ≡ g b
get≡g {p = here refl} _ (here refl) = refl
get≡g {p = here px} gul (there b∈≡l) =
contradiction (gul (here refl))
(P→A→¬A! refl (∈≡→∈f px b∈≡l))
get≡g {p = there p} gul (here refl) =
contradiction (gul (here refl))
(P→A→¬A! refl p)
get≡g {p = there p} gul (there b∈≡l) = get≡g (guTl gul) b∈≡l
g≡get : ∀ {b l p} → get f b from l when p ≡ g b → b ∈≡ l
g≡get {p = here px} = here ∘ injfg ∘ (cong₂ _,_ px) ∘ sym
g≡get {p = there p} = there ∘ g≡get
get≡get : ∀ {b l l₁} → GlobalUnicity l
→ get f b from l ≡ get f b from l₁ → b ∈≡ l → b ∈≡ l₁
get≡get {b} {l} _ _ with dec∈fa (f b) l
get≡get {b} {l₁ = l₁} _ _ | yes _ with dec∈fa (f b) l₁
get≡get gul eq | yes _ | yes _ =
g≡get ∘ ((trans ∘ sym ∘ just-injective) eq) ∘ get≡g gul
get≡get _ _ | no ¬p = ⊥-elim ∘ ¬p ∘ ∈≡→∈f'
≋₂→≋₁ : ∀ {gu₁ gu₂} → gu₁ ≋₂ gu₂ → gu₁ ≋₁ gu₂
≋₂→≋₁ {gu₁} {gu₂} gu₁≋₂gu₂ =
let gu₂≋₂gu₁ = (IsEquivalence.sym eq≋₂) {gu₁} {gu₂} gu₁≋₂gu₂ in
(get≡get (unique gu₁) gu₁≋₂gu₂) ,
get≡get (unique gu₂) gu₂≋₂gu₁
retrieve : ∀ {x l} → GlobalUnicity l → (p : x ∈f l)
→ ∃ λ y → y ∈≡ l × x ≡ f y × get x from l when p ≡ g y
retrieve _ (here refl) = _ , here refl , refl , refl
retrieve gul (there x∈fl) = map₂ (map₁ there) (retrieve (guTl gul) x∈fl)
≋₁→≋₂ : ∀ {gu₁ gu₂} → gu₁ ≋₁ gu₂ → gu₁ ≋₂ gu₂
≋₁→≋₂ {gulist l₁ _} {gulist l₂ _} _ {x} with dec∈fa x l₁ | dec∈fa x l₂
≋₁→≋₂ {gulist _ gul₁} {gulist _ gul₂} (l₁⊑l₂ , _) | yes p | yes _ =
case retrieve gul₁ p of
λ {(_ , q , refl , ≡get) →
((cong just) ∘ (trans ≡get) ∘ sym ∘ (get≡g gul₂) ∘ l₁⊑l₂) q}
≋₁→≋₂ {gulist _ gul₁} (l₁⊑l₂ , _) | yes p | no ¬p =
⊥-elim (case retrieve gul₁ p of
λ {(_ , q , refl , _) → (¬p ∘ ∈≡→∈f' ∘ l₁⊑l₂) q})
≋₁→≋₂ {_} {gulist _ gul₂} (_ , l₂⊑l₁) | no ¬p | yes p =
⊥-elim (case retrieve gul₂ p of
λ {(_ , q , refl , _) → (¬p ∘ ∈≡→∈f' ∘ l₂⊑l₁) q})
≋₁→≋₂ _ | no _ | no _ = refl
dec≋₂ : Decidableᵣ _≋₂_
dec≋₂ gu₁ gu₂ with dec≋₁ gu₁ gu₂
dec≋₂ gu₁ gu₂ | yes p = yes (≋₁→≋₂ {gu₁} {gu₂} p)
dec≋₂ gu₁ gu₂ | no ¬p = no (¬p ∘ ≋₂→≋₁ {gu₁} {gu₂})