{-# OPTIONS --cubical-compatible --safe #-}
open import Relation.Binary.Bundles using (Setoid)
module Data.List.Relation.Binary.Permutation.Declarative
{s ℓ} (S : Setoid s ℓ) where
open import Data.List.Base using (List; []; _∷_; [_]; _++_)
open import Data.List.Properties using (++-identityʳ)
open import Function.Base using (id; _∘_)
open import Level using (_⊔_)
import Relation.Binary.PropositionalEquality as ≡ using (sym)
open import Data.List.Relation.Binary.Equality.Setoid S as ≋
using (_≋_; []; _∷_; ≋-refl; ≋-reflexive)
open Setoid S
renaming (Carrier to A; refl to ≈-refl; sym to ≈-sym; trans to ≈-trans)
private
variable
a b c d : A
as bs cs ds : List A
infix 4 _↭_
data _↭_ : List A → List A → Set (s ⊔ ℓ) where
[] : [] ↭ []
_∷_ : a ≈ b → as ↭ bs → a ∷ as ↭ b ∷ bs
trans : as ↭ bs → bs ↭ cs → as ↭ cs
_++ᵒ_ : ∀ as bs → as ++ bs ↭ bs ++ as
_≡∷_ : ∀ c → as ↭ bs → c ∷ as ↭ c ∷ bs
_≡∷_ c = ≈-refl ∷_
↭-reflexive : as ≋ bs → as ↭ bs
↭-reflexive [] = []
↭-reflexive (a≈b ∷ as↭bs) = a≈b ∷ ↭-reflexive as↭bs
↭-refl : ∀ as → as ↭ as
↭-refl _ = ↭-reflexive ≋-refl
↭-sym : as ↭ bs → bs ↭ as
↭-sym [] = []
↭-sym (a≈b ∷ as↭bs) = ≈-sym a≈b ∷ ↭-sym as↭bs
↭-sym (trans as↭cs cs↭bs) = trans (↭-sym cs↭bs) (↭-sym as↭cs)
↭-sym (as ++ᵒ bs) = bs ++ᵒ as
↭-trans : as ↭ bs → bs ↭ cs → as ↭ cs
↭-trans [] = id
↭-trans (trans as↭bs bs↭cs) = ↭-trans as↭bs ∘ ↭-trans bs↭cs
↭-trans as↭bs = trans as↭bs
↭-swap-++ : (as bs : List A) → as ++ bs ↭ bs ++ as
↭-swap-++ [] bs = ↭-reflexive (≋-reflexive (≡.sym (++-identityʳ bs)))
↭-swap-++ as@(_ ∷ _) [] = ↭-reflexive (≋-reflexive (++-identityʳ as))
↭-swap-++ as@(_ ∷ _) bs@(_ ∷ _) = as ++ᵒ bs
↭-congʳ : as ↭ bs → cs ++ as ↭ cs ++ bs
↭-congʳ {as = as} {bs = bs} {cs = cs} as↭bs = lemma cs
where
lemma : ∀ cs → cs ++ as ↭ cs ++ bs
lemma [] = as↭bs
lemma (c ∷ cs) = c ≡∷ lemma cs
↭-congˡ : as ↭ bs → as ++ cs ↭ bs ++ cs
↭-congˡ {as = as} {bs = bs} {cs = cs} as↭bs =
↭-trans (↭-swap-++ as cs) (↭-trans (↭-congʳ as↭bs) (↭-swap-++ cs bs))
↭-cong : as ↭ bs → cs ↭ ds → as ++ cs ↭ bs ++ ds
↭-cong as↭bs cs↭ds = ↭-trans (↭-congˡ as↭bs) (↭-congʳ cs↭ds)
infix 5 _↭-⋎_
_↭-⋎_ : as ↭ b ∷ cs → a ∷ cs ↭ bs → a ∷ as ↭ b ∷ bs
_↭-⋎_ {b = b} {a = a} as↭b∷cs a∷cs↭bs =
trans (a ≡∷ as↭b∷cs) (↭-trans (↭-congˡ ([ a ] ++ᵒ [ b ])) (b ≡∷ a∷cs↭bs))
⋎-syntax : ∀ cs → as ↭ b ∷ cs → a ∷ cs ↭ bs → a ∷ as ↭ b ∷ bs
⋎-syntax cs = _↭-⋎_ {cs = cs}
syntax ⋎-syntax cs as↭b∷cs a∷cs↭bs = as↭b∷cs ↭-⋎[ cs ] a∷cs↭bs