{-# OPTIONS --cubical-compatible --safe #-}
open import Relation.Binary.Bundles using (Setoid)
module Data.List.Relation.Binary.Permutation.Setoid
{a ℓ} (S : Setoid a ℓ) where
open import Data.List.Base using (List; _∷_)
import Data.List.Relation.Binary.Permutation.Homogeneous as Homogeneous
import Data.List.Relation.Binary.Equality.Setoid as ≋
open import Function.Base using (_∘′_)
open import Level using (_⊔_)
open import Relation.Binary.Core using (Rel; _⇒_)
open import Relation.Binary.Definitions
using (Reflexive; Symmetric; Transitive; LeftTrans; RightTrans)
open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)
import Relation.Binary.Reasoning.Setoid as ≈-Reasoning
open import Relation.Binary.Reasoning.Syntax
open import Relation.Binary.Structures using (IsEquivalence)
open module ≈ = Setoid S using (_≈_) renaming (Carrier to A)
open ≋ S using (_≋_; _∷_; ≋-refl; ≋-sym; ≋-trans)
open Homogeneous public
using (refl; prep; swap; trans)
infix 3 _↭_
_↭_ : Rel (List A) (a ⊔ ℓ)
_↭_ = Homogeneous.Permutation _≈_
steps = Homogeneous.steps {R = _≈_}
↭-reflexive-≋ : _≋_ ⇒ _↭_
↭-reflexive-≋ = refl
↭-trans : Transitive _↭_
↭-trans = trans
↭-prep : ∀ x {xs ys} → xs ↭ ys → x ∷ xs ↭ x ∷ ys
↭-prep x xs↭ys = prep ≈.refl xs↭ys
↭-swap : ∀ x y {xs ys} → xs ↭ ys → x ∷ y ∷ xs ↭ y ∷ x ∷ ys
↭-swap x y xs↭ys = swap ≈.refl ≈.refl xs↭ys
↭-reflexive : _≡_ ⇒ _↭_
↭-reflexive refl = ↭-reflexive-≋ ≋-refl
↭-refl : Reflexive _↭_
↭-refl = ↭-reflexive refl
↭-sym : Symmetric _↭_
↭-sym = Homogeneous.sym ≈.sym
↭-transˡ-≋ : LeftTrans _≋_ _↭_
↭-transˡ-≋ xs≋ys (refl ys≋zs)
= refl (≋-trans xs≋ys ys≋zs)
↭-transˡ-≋ (x≈y ∷ xs≋ys) (prep y≈z ys↭zs)
= prep (≈.trans x≈y y≈z) (↭-transˡ-≋ xs≋ys ys↭zs)
↭-transˡ-≋ (x≈y ∷ w≈z ∷ xs≋ys) (swap eq₁ eq₂ ys↭zs)
= swap (≈.trans x≈y eq₁) (≈.trans w≈z eq₂) (↭-transˡ-≋ xs≋ys ys↭zs)
↭-transˡ-≋ xs≋ys (trans ys↭ws ws↭zs)
= trans (↭-transˡ-≋ xs≋ys ys↭ws) ws↭zs
↭-transʳ-≋ : RightTrans _↭_ _≋_
↭-transʳ-≋ (refl xs≋ys) ys≋zs
= refl (≋-trans xs≋ys ys≋zs)
↭-transʳ-≋ (prep x≈y xs↭ys) (y≈z ∷ ys≋zs)
= prep (≈.trans x≈y y≈z) (↭-transʳ-≋ xs↭ys ys≋zs)
↭-transʳ-≋ (swap eq₁ eq₂ xs↭ys) (x≈w ∷ y≈z ∷ ys≋zs)
= swap (≈.trans eq₁ y≈z) (≈.trans eq₂ x≈w) (↭-transʳ-≋ xs↭ys ys≋zs)
↭-transʳ-≋ (trans xs↭ws ws↭ys) ys≋zs
= trans xs↭ws (↭-transʳ-≋ ws↭ys ys≋zs)
↭-trans′ : Transitive _↭_
↭-trans′ (refl xs≋ys) ys↭zs = ↭-transˡ-≋ xs≋ys ys↭zs
↭-trans′ xs↭ys (refl ys≋zs) = ↭-transʳ-≋ xs↭ys ys≋zs
↭-trans′ xs↭ys ys↭zs = trans xs↭ys ys↭zs
↭-isEquivalence : IsEquivalence _↭_
↭-isEquivalence = record
{ refl = ↭-refl
; sym = ↭-sym
; trans = ↭-trans
}
↭-setoid : Setoid _ _
↭-setoid = record { isEquivalence = ↭-isEquivalence }
module PermutationReasoning where
private module Base = ≈-Reasoning ↭-setoid
open Base public
hiding (step-≈; step-≈˘; step-≈-⟩; step-≈-⟨)
renaming (≈-go to ↭-go)
open ↭-syntax _IsRelatedTo_ _IsRelatedTo_ ↭-go ↭-sym public
open ≋-syntax _IsRelatedTo_ _IsRelatedTo_ (↭-go ∘′ ↭-reflexive-≋) ≋-sym public
infixr 2 step-swap step-prep
step-prep : ∀ x xs {ys zs : List A} → (x ∷ ys) IsRelatedTo zs →
xs ↭ ys → (x ∷ xs) IsRelatedTo zs
step-prep x xs rel xs↭ys = ↭-go (↭-prep x xs↭ys) rel
step-swap : ∀ x y xs {ys zs : List A} → (y ∷ x ∷ ys) IsRelatedTo zs →
xs ↭ ys → (x ∷ y ∷ xs) IsRelatedTo zs
step-swap x y xs rel xs↭ys = ↭-go (↭-swap x y xs↭ys) rel
syntax step-prep x xs y↭z x↭y = x ∷ xs <⟨ x↭y ⟩ y↭z
syntax step-swap x y xs y↭z x↭y = x ∷ y ∷ xs <<⟨ x↭y ⟩ y↭z