Source code on Githubopen import Prelude.Init; open SetAsType
open L.Mem
open import Prelude.General
open import Prelude.DecEq
open import Prelude.Decidable
open import Prelude.Setoid
open import Prelude.InferenceRules
open import Prelude.InfEnumerable
module Nominal.Fun (Atom : Type) ⦃ _ : DecEq Atom ⦄ where
open import Nominal.Swap Atom
open import Nominal.Support Atom
module _ {A : Type ℓ} {B : Type ℓ′} ⦃ _ : Swap A ⦄ ⦃ _ : Swap B ⦄ where
open ≈-Reasoning
instance
Swap-Fun : Swap (A → B)
Swap-Fun .swap a b f = swap a b ∘ f ∘ swap a b
Setoid-Fun : ⦃ ISetoid B ⦄ → ISetoid (A → B)
Setoid-Fun = λ where
.relℓ → ℓ ⊔ₗ relℓ {A = B}
._≈_ f g → ∀ x → f x ≈ g x
SetoidLaws-Fun :
⦃ _ : ISetoid B ⦄ → ⦃ SetoidLaws B ⦄
→ SetoidLaws (A → B)
SetoidLaws-Fun .isEquivalence = record
{ refl = λ {f} x → ≈-refl
; sym = λ f∼g x → ≈-sym (f∼g x)
; trans = λ f∼g g∼h x → ≈-trans (f∼g x) (g∼h x)
}
SwapLaws-Fun :
⦃ _ : ISetoid A ⦄ ⦃ _ : SetoidLaws A ⦄ ⦃ _ : CongSetoid A ⦄ ⦃ _ : SwapLaws A ⦄
⦃ _ : ISetoid B ⦄ ⦃ _ : SetoidLaws B ⦄ ⦃ _ : SwapLaws B ⦄
→ SwapLaws (A → B)
SwapLaws-Fun .cong-swap {f}{g}{a}{b} f≗g x =
cong-swap (f≗g _)
SwapLaws-Fun .swap-id {a}{f} x =
begin
⦅ a ↔ a ⦆ (f (⦅ a ↔ a ⦆ x))
≈⟨ swap-id ⟩
f (⦅ a ↔ a ⦆ x)
≈⟨ ≈-cong f swap-id ⟩
f x
∎
SwapLaws-Fun .swap-rev {a}{b}{f} x =
begin
(⦅ a ↔ b ⦆ f) x
≡⟨⟩
⦅ a ↔ b ⦆ (f $ ⦅ a ↔ b ⦆ x)
≈⟨ cong-swap $ ≈-cong f swap-rev ⟩
⦅ a ↔ b ⦆ (f $ ⦅ b ↔ a ⦆ x)
≈⟨ swap-rev ⟩
⦅ b ↔ a ⦆ (f $ ⦅ b ↔ a ⦆ x)
≡⟨⟩
(⦅ b ↔ a ⦆ f) x
∎
SwapLaws-Fun .swap-sym {a}{b}{f} x =
begin
(⦅ a ↔ b ⦆ ⦅ b ↔ a ⦆ f) x
≡⟨⟩
⦅ a ↔ b ⦆ ⦅ b ↔ a ⦆ (f $ ⦅ b ↔ a ⦆ ⦅ a ↔ b ⦆ x)
≈⟨ cong-swap $ cong-swap $ ≈-cong f swap-sym ⟩
⦅ a ↔ b ⦆ ⦅ b ↔ a ⦆ (f x)
≈⟨ swap-sym ⟩
f x
∎
SwapLaws-Fun .swap-swap {𝕒 = a}{b}{c}{d}{f} x =
begin
(⦅ a ↔ b ⦆ ⦅ c ↔ d ⦆ f) x
≡⟨⟩
⦅ a ↔ b ⦆ ⦅ c ↔ d ⦆ (f $ ⦅ c ↔ d ⦆ ⦅ a ↔ b ⦆ x)
≈⟨ swap-swap ⟩
⦅ ⦅ a ↔ b ⦆ c ↔ ⦅ a ↔ b ⦆ d ⦆ ⦅ a ↔ b ⦆
(f $ ⦅ c ↔ d ⦆ ⦅ a ↔ b ⦆ x)
≈⟨ cong-swap $ cong-swap $ ≈-cong f
$ begin
⦅ c ↔ d ⦆ ⦅ a ↔ b ⦆ x
≡˘⟨ cong (λ ◆ → ⦅ c ↔ ◆ ⦆ ⦅ a ↔ b ⦆ x) swap-sym′ ⟩
⦅ c ↔ ⦅ a ↔ b ⦆ ⦅ a ↔ b ⦆ d ⦆ ⦅ a ↔ b ⦆ x
≡˘⟨ cong (λ ◆ → ⦅ ◆ ↔ ⦅ a ↔ b ⦆ ⦅ a ↔ b ⦆ d ⦆ ⦅ a ↔ b ⦆ x) swap-sym′ ⟩
⦅ ⦅ a ↔ b ⦆ ⦅ a ↔ b ⦆ c ↔ ⦅ a ↔ b ⦆ ⦅ a ↔ b ⦆ d ⦆ ⦅ a ↔ b ⦆ x
≈˘⟨ swap-swap ⟩
⦅ a ↔ b ⦆ ⦅ ⦅ a ↔ b ⦆ c ↔ ⦅ a ↔ b ⦆ d ⦆ x
∎
⟩
⦅ ⦅ a ↔ b ⦆ c ↔ ⦅ a ↔ b ⦆ d ⦆ ⦅ a ↔ b ⦆
(f $ ⦅ a ↔ b ⦆ ⦅ ⦅ a ↔ b ⦆ c ↔ ⦅ a ↔ b ⦆ d ⦆ x)
≡⟨⟩
(⦅ ⦅ a ↔ b ⦆ c ↔ ⦅ a ↔ b ⦆ d ⦆ ⦅ a ↔ b ⦆ f) x
∎
module _
⦃ _ : ISetoid A ⦄ ⦃ _ : SetoidLaws A ⦄ ⦃ _ : SwapLaws A ⦄ ⦃ _ : CongSetoid A ⦄
⦃ _ : ISetoid B ⦄ ⦃ _ : SetoidLaws B ⦄ ⦃ _ : SwapLaws B ⦄
where
conj : ∀ {𝕒 𝕓 : Atom} (f : A → B) (x : A) →
(swap 𝕒 𝕓 f) x ≈ swap 𝕒 𝕓 (f $ swap 𝕒 𝕓 x)
conj {𝕒} {𝕓} f x =
begin
(swap 𝕒 𝕓 f) x
≡⟨⟩
(swap 𝕒 𝕓 ∘ f ∘ swap 𝕒 𝕓) x
≡⟨⟩
swap 𝕒 𝕓 (f $ swap 𝕒 𝕓 x)
≈˘⟨ cong-swap $ ≈-cong f swap-sym′ ⟩
swap 𝕒 𝕓 (f $ swap 𝕒 𝕓 $ swap 𝕒 𝕓 $ swap 𝕒 𝕓 x)
≡⟨⟩
(swap 𝕒 𝕓 ∘ f ∘ swap 𝕒 𝕓) (swap 𝕒 𝕓 $ swap 𝕒 𝕓 x)
≡⟨⟩
(swap 𝕒 𝕓 f) (swap 𝕒 𝕓 $ swap 𝕒 𝕓 x)
≈˘⟨ distr-f 𝕒 𝕓 ⟩
swap 𝕒 𝕓 (f $ swap 𝕒 𝕓 x)
∎ where distr-f = swap↔ f
private
postulate
𝕒 𝕓 : Atom
𝕒≢𝕓 : 𝕒 ≢ 𝕓
unquoteDecl Swap-Maybe = DERIVE Swap [ quote Maybe , Swap-Maybe ]
justAtom : Atom → Maybe Atom
justAtom n =
if n == 𝕒 then
just 𝕒
else
nothing
justAtom′ : Atom → Maybe Atom
justAtom′ = ⦅ 𝕒 ↔ 𝕓 ⦆ justAtom
_ : justAtom 𝕒 ≡ just 𝕒
_ rewrite ≟-refl 𝕒 = refl
_ : justAtom 𝕓 ≡ nothing
_ rewrite dec-no (𝕓 ≟ 𝕒) (≢-sym 𝕒≢𝕓) .proj₂ = refl
_ : justAtom′ 𝕒 ≡ nothing
_ rewrite dec-no (𝕒 ≟ 𝕓) 𝕒≢𝕓 .proj₂
| ≟-refl 𝕒
| dec-no (𝕓 ≟ 𝕒) (≢-sym 𝕒≢𝕓) .proj₂
= refl
_ : justAtom′ 𝕓 ≡ just 𝕓
_ rewrite ≟-refl 𝕓
| dec-no (𝕓 ≟ 𝕒) (≢-sym 𝕒≢𝕓) .proj₂
| ≟-refl 𝕒
| ≟-refl 𝕒
= refl
module _
⦃ _ : Enumerable∞ Atom ⦄
{A : Type ℓ} ⦃ _ : ISetoid A ⦄ ⦃ _ : SetoidLaws A ⦄
⦃ _ : Swap A ⦄ ⦃ _ : SwapLaws A ⦄
where
equivariant-equiv : ∀ {f : A → A} →
Equivariant f
══════════════
Equivariant′ f
equivariant-equiv {f = f} = ↝ , ↜
where
open ≈-Reasoning
↝ : Equivariant f
─────────────────
Equivariant′ f
↝ equiv-f = fin-f , refl
where
fin-f : FinSupp f
fin-f = [] , (λ x y _ _ a →
begin
⦅ y ↔ x ⦆ (f $ ⦅ y ↔ x ⦆ a)
≈˘⟨ cong-swap $ equiv-f _ _ ⟩
⦅ y ↔ x ⦆ ⦅ y ↔ x ⦆ f a
≈⟨ swap-sym′ ⟩
f a
∎) , λ _ _ ()
↜ : Equivariant′ f
─────────────────
Equivariant f
↜ (fin-f , refl) a b {x} =
begin
⦅ a ↔ b ⦆ f x
≈˘⟨ cong-swap $ fin-f .proj₂ .proj₁ _ _ (λ ()) (λ ()) _ ⟩
⦅ a ↔ b ⦆ ⦅ a ↔ b ⦆ f (⦅ a ↔ b ⦆ x)
≈⟨ swap-sym′ ⟩
f (⦅ a ↔ b ⦆ x)
∎
private
f′ : A → A
f′ = id
suppF′ = Atoms ∋ []
g′ : A → A
g′ x = x
f≗g : f′ ≗ g′
f≗g _ = refl
f≈g : f′ ≈ g′
f≈g _ = ≈-refl
∃fin-f : ∃FinSupp f′
∃fin-f = suppF′ , λ _ _ _ _ _ → swap-sym′
fin-f : FinSupp f′
fin-f = suppF′ , (λ _ _ _ _ _ → swap-sym′) , (λ _ _ ())
equiv-f : Equivariant f′
equiv-f _ _ = ≈-refl
equiv-f′ : Equivariant′ f′
equiv-f′ = fin-f , refl
instance
Setoid-Bool : ISetoid Bool
Setoid-Bool = λ where
.relℓ → 0ℓ
._≈_ → _≡_
SetoidLaws-Bool : SetoidLaws Bool
SetoidLaws-Bool .isEquivalence = PropEq.isEquivalence
postulate x y : Atom
f : Atom → Bool
f z = (z == x) ∨ (z == y)
suppF = List Atom ∋ x ∷ y ∷ []
finF : ∃FinSupp f
finF = -, go
where
∀x∉suppF : ∀ {z} → z ∉ suppF → f z ≡ false
∀x∉suppF {z} z∉ with z ≟ x
... | yes refl = ⊥-elim $ z∉ $ here refl
... | no _ with z ≟ y
... | yes refl = ⊥-elim $ z∉ $ there $′ here refl
... | no _ = refl
go : ∀ 𝕒 𝕓 → 𝕒 ∉ suppF → 𝕓 ∉ suppF → f ∘ swap 𝕓 𝕒 ≗ f
go 𝕒 𝕓 𝕒∉ 𝕓∉ z with z ≟ 𝕓
... | yes refl rewrite ∀x∉suppF 𝕒∉ | ∀x∉suppF 𝕓∉ = refl
... | no _ with z ≟ 𝕒
... | yes refl rewrite ∀x∉suppF 𝕒∉ | ∀x∉suppF 𝕓∉ = refl
... | no _ = refl
_ = finF .proj₁ ≡ suppF
∋ refl
g : Atom → Bool
g z = (z ≠ x) ∧ (z ≠ y)
suppG = List Atom ∋ x ∷ y ∷ []
finG : ∃FinSupp g
finG = -, go
where
∀x∉suppG : ∀ {z} → z ∉ suppG → g z ≡ true
∀x∉suppG {z} z∉ with z ≟ x
... | yes refl = ⊥-elim $ z∉ $ here refl
... | no _ with z ≟ y
... | yes refl = ⊥-elim $ z∉ $ there $′ here refl
... | no _ = refl
go : ∀ 𝕒 𝕓 → 𝕒 ∉ suppG → 𝕓 ∉ suppG → g ∘ swap 𝕓 𝕒 ≗ g
go 𝕒 𝕓 𝕒∉ 𝕓∉ z with z ≟ 𝕓
... | yes refl rewrite ∀x∉suppG 𝕒∉ | ∀x∉suppG 𝕓∉ = refl
... | no _ with z ≟ 𝕒
... | yes refl rewrite ∀x∉suppG 𝕒∉ | ∀x∉suppG 𝕓∉ = refl
... | no _ = refl