{-# OPTIONS --without-K --safe #-}
open import Algebra
open import Relation.Unary
open import Relation.Binary hiding (Decidable)
module Data.FingerTree.Split
{r m}
(ℳ : Monoid r m)
{s}
{ℙ : Pred (Monoid.Carrier ℳ) s}
(ℙ-resp : ℙ Respects (Monoid._≈_ ℳ))
(ℙ? : Decidable ℙ)
where
open import Relation.Nullary using (¬_; yes; no; Dec)
open import Level using (_⊔_)
open import Data.Product
open import Function
open import Data.List as List using (List; _∷_; [])
open import Data.FingerTree.Measures ℳ
open import Data.FingerTree.Structures ℳ
open import Data.FingerTree.Reasoning ℳ
open import Data.FingerTree.View ℳ using (deepₗ; deepᵣ)
open import Data.FingerTree.Cons ℳ using (listToTree)
open import Relation.Nullary using (Dec; yes; no)
open import Relation.Nullary.Decidable using (True; toWitness; False; toWitnessFalse)
open σ ⦃ ... ⦄
{-# DISPLAY σ.μ _ = μ #-}
open Monoid ℳ renaming (Carrier to 𝓡)
open import Data.FingerTree.Relation.Binary.Reasoning.FasterInference.Setoid setoid
infixr 5 _∣_
record _∣_ (left focus : 𝓡) : Set s where
constructor ¬[_]ℙ[_]
field
¬ℙ : ¬ ℙ left
!ℙ : ℙ (left ∙ focus)
open _∣_
infixl 2 _≈◄⟅_⟆ _≈▻⟅_⟆ _≈⟅_∣_⟆ _◄_ _▻_
_◄_ : ∀ {l f₁ f₂} → l ∣ f₁ ∙ f₂ → ¬ ℙ (l ∙ f₁) → (l ∙ f₁) ∣ f₂
!ℙ (p ◄ ¬ℙf) = ℙ-resp (sym (assoc _ _ _)) (!ℙ p)
¬ℙ (p ◄ ¬ℙf) = ¬ℙf
_▻_ : ∀ {l f₁ f₂} → l ∣ f₁ ∙ f₂ → ℙ (l ∙ f₁) → l ∣ f₁
!ℙ (p ▻ ℙf) = ℙf
¬ℙ (p ▻ ℙf) = ¬ℙ p
_≈◄⟅_⟆ : ∀ {x y z} → x ∣ y → x ≈ z → z ∣ y
¬ℙ (x⟅y⟆ ≈◄⟅ x≈z ⟆) = ¬ℙ x⟅y⟆ ∘ ℙ-resp (sym x≈z)
!ℙ (x⟅y⟆ ≈◄⟅ x≈z ⟆) = ℙ-resp (≪∙ x≈z) (!ℙ x⟅y⟆)
_≈▻⟅_⟆ : ∀ {x y z} → x ∣ y → y ≈ z → x ∣ z
¬ℙ (x⟅y⟆ ≈▻⟅ y≈z ⟆) = ¬ℙ x⟅y⟆
!ℙ (x⟅y⟆ ≈▻⟅ y≈z ⟆) = ℙ-resp (∙≫ y≈z) (!ℙ x⟅y⟆)
_≈⟅_∣_⟆ : ∀ {x₁ y₁ x₂ y₂} → x₁ ∣ y₁ → x₁ ≈ x₂ → y₁ ≈ y₂ → x₂ ∣ y₂
¬ℙ (x⟅y⟆ ≈⟅ x≈ ∣ y≈ ⟆) = ¬ℙ x⟅y⟆ ∘ ℙ-resp (sym x≈)
!ℙ (x⟅y⟆ ≈⟅ x≈ ∣ y≈ ⟆) = ℙ-resp (∙-cong x≈ y≈) (!ℙ x⟅y⟆)
¬∄ℙ : ∀ {i} → ¬ (i ∣ ε)
¬∄ℙ i⟅ε⟆ = ¬ℙ i⟅ε⟆ (ℙ-resp (identityʳ _) (!ℙ i⟅ε⟆))
module SplitStructures where
record Split′ (i : 𝓡) {a b} (Σ : Set a) (A : Set b) ⦃ _ : σ Σ ⦄ ⦃ _ : σ A ⦄ : Set (a ⊔ b ⊔ s) where
constructor _∷⟨_⟩∷_[_]
field
left′ : Σ
focus′ : A
right′ : Σ
proof′ : i ∙ μ left′ ∣ μ focus′
instance
σ-Split′ : ∀ {a b} {Σ : Set a} {A : Set b} ⦃ _ : σ Σ ⦄ ⦃ _ : σ A ⦄ {i : 𝓡} → σ (Split′ i Σ A)
μ ⦃ σ-Split′ {i = i} ⦄ (l ∷⟨ x ⟩∷ r [ _ ]) = i ∙ (μ l ∙ (μ x ∙ μ r))
infixl 2 _i≈[_]
_i≈[_] : ∀ {a b} {Σ : Set a} {A : Set b} ⦃ _ : σ Σ ⦄ ⦃ _ : σ A ⦄ → ∀ {i xs} → μ⟨ Split′ i Σ A ⟩≈ (i ∙ xs) → ∀ {j} → i ≈ j → μ⟨ Split′ j Σ A ⟩≈ (j ∙ xs)
xs ∷⟨ x ⟩∷ ys [ p₁ ] ⇑[ p₂ ] i≈[ i≈ ] = xs ∷⟨ x ⟩∷ ys [ p₁ ≈◄⟅ ≪∙ i≈ ⟆ ] ⇑[ ≪∙ sym i≈ ⍮ p₂ ⍮ ≪∙ i≈ ]
{-# INLINE _i≈[_] #-}
open import Data.Empty using (⊥-elim)
infixl 2 _≈ℙ_[_]
record ⟪ℙ⟫ (x : 𝓡) : Set (s ⊔ r ⊔ m) where
constructor _≈ℙ_[_]
field
result : Dec (ℙ x)
stored : 𝓡
equiv : stored ≈ x
open ⟪ℙ⟫
⟪ℙ?⟫ : ∀ x → ⟪ℙ⟫ x
result (⟪ℙ?⟫ x) = ℙ? x
stored (⟪ℙ?⟫ x) = x
equiv (⟪ℙ?⟫ x) = refl
module _ {a} {Σ : Set a} ⦃ _ : σ Σ ⦄ where
splitList : (i : 𝓡) → (xs : List Σ) → i ∣ μ xs → μ⟨ Split′ i (List Σ) Σ ⟩≈ (i ∙ μ xs)
splitList i [] s = ⊥-elim (¬∄ℙ s)
splitList i (x ∷ xs) s with ⟪ℙ?⟫ (i ∙ μ x)
... | yes p ≈ℙ i∙x [ i∙x≈ ] = [] ∷⟨ x ⟩∷ xs [ s ▻ p ≈◄⟅ ℳ ↯ ⟆ ] ⇑[ ℳ ↯ ]
... | no ¬p ≈ℙ i∙x [ i∙x≈ ] with splitList i∙x xs (s ◄ ¬p ≈◄⟅ sym i∙x≈ ⟆) i≈[ i∙x≈ ]
... | ys ∷⟨ y ⟩∷ zs [ s′ ] ⇑[ ys≈ ] = (x ∷ ys) ∷⟨ y ⟩∷ zs [ s′ ≈◄⟅ ℳ ↯ ⟆ ] ⇑[ ℳ ↯ ] ≈[ ys≈ ]′ ≈[ ℳ ↯ ]
splitNode : ∀ i → (xs : Node Σ) → i ∣ μ xs → μ⟨ Split′ i (List Σ) Σ ⟩≈ (i ∙ μ xs)
splitNode i xs s = do
ys ← nodeToList xs [ _ ∙> sz ⟿ sz ]
splitList i ys (s ≈▻⟅ sym (_ ≈? _) ⟆)
splitDigit : ∀ i → (xs : Digit Σ) → i ∣ μ xs → μ⟨ Split′ i (List Σ) Σ ⟩≈ (i ∙ μ xs)
splitDigit i xs s = digitToList xs [ _ ∙> sz ⟿ sz ] >>= λ ys → splitList i ys (s ≈▻⟅ sym (_ ≈? _) ⟆)
splitTree-l : ∀ i → (ls : Digit Σ) → (m : Tree ⟪ Node Σ ⟫) → (rs : Digit Σ) → i ∣ μ ls → μ⟨ Split′ i (Tree Σ) Σ ⟩≈ (i ∙ (μ ls ∙ (μ m ∙ μ rs)))
splitTree-l i ls m rs s with splitDigit i ls s
splitTree-l i ls m rs s | lsₗ ∷⟨ mₗ ⟩∷ rsₗ [ p ] ⇑[ l≈ ] = [ ( ℳ ↯ ⍮′ ≪∙ l≈ ⍮ assoc _ _ _) ]≈ do
ls′ ← listToTree lsₗ [ i ∙> (sz <∙ _) ⟿ sz ]
rs′ ← deepₗ rsₗ m rs [ i ∙> (_ ∙> (_ ∙> sz)) ⟿ sz ]
ls′ ∷⟨ mₗ ⟩∷ rs′ [ p ≈◄⟅ ∙≫ sym (_ ≈? _) ⟆ ] ⇑
splitTree-r : ∀ i → (ls : Digit Σ) → (m : Tree ⟪ Node Σ ⟫) → (rs : Digit Σ) → ∀ i∙ls∙m → i∙ls∙m ≈ (i ∙ μ ls ∙ μ m) → (i ∙ μ ls ∙ μ m) ∣ μ rs → μ⟨ Split′ i (Tree Σ) Σ ⟩≈ (i ∙ (μ ls ∙ (μ m ∙ μ rs)))
splitTree-r i ls m rs i′ i′≈ s with splitDigit i′ rs (s ≈◄⟅ sym i′≈ ⟆)
splitTree-r i ls m rs i′ i′≈ s | lsᵣ ∷⟨ mᵣ ⟩∷ rsᵣ [ p ] ⇑[ r≈ ] = [ lemma ]≈ do
ls′ ← deepᵣ ls m lsᵣ [ i ∙> (sz <∙ _) ⟿ sz ]
rs′ ← listToTree rsᵣ [ i ∙> (_ ∙> (_ ∙> sz)) ⟿ sz ]
ls′ ∷⟨ mᵣ ⟩∷ rs′ [ p ≈◄⟅ ≪∙ i′≈ ⍮ ℳ ↯ ⍮′ ∙≫ sym (μ ls′ ≈? (μ ls ∙ (μ m ∙ μ lsᵣ))) ⟆ ] ⇑
where
lemma = begin
i ∙ (μ ls ∙ (μ m ∙ μ lsᵣ) ∙ (μ mᵣ ∙ μ rsᵣ))
≈⟨ ℳ ↯ ⟩
i ∙ μ ls ∙ μ m ∙ (μ lsᵣ ∙ (μ mᵣ ∙ μ rsᵣ))
≈⟨ ≪∙ sym i′≈ ⟩
i′ ∙ (μ lsᵣ ∙ (μ mᵣ ∙ μ rsᵣ))
≈⟨ r≈ ⟩
i′ ∙ μ rs
≈⟨ ≪∙ i′≈ ⟩
i ∙ μ ls ∙ μ m ∙ μ rs
≈⟨ ℳ ↯ ⟩
i ∙ (μ ls ∙ (μ m ∙ μ rs)) ∎
splitTree : ∀ {a} {Σ : Set a} ⦃ _ : σ Σ ⦄
→ ∀ i
→ (xs : Tree Σ)
→ i ∣ μ xs
→ μ⟨ Split′ i (Tree Σ) Σ ⟩≈ (i ∙ μ xs)
splitTree i empty s = ⊥-elim (¬∄ℙ s)
splitTree i (single x) s = empty ∷⟨ x ⟩∷ empty [ s ≈◄⟅ ℳ ↯ ⟆ ] ⇑[ ℳ ↯ ]
splitTree i (deep (𝓂 ↤ ls & m & rs ⇑[ 𝓂≈ ])) s with ⟪ℙ?⟫ (i ∙ μ ls)
... | yes p₁ ≈ℙ i∙ls [ i∙ls≈ ] = splitTree-l i ls m rs ¬[ ¬ℙ s ]ℙ[ p₁ ] ≈[ ∙≫ 𝓂≈ ]
... | no ¬p₁ ≈ℙ i∙ls [ i∙ls≈ ] with ⟪ℙ?⟫ (i∙ls ∙ μ m)
... | no ¬p₂ ≈ℙ i∙ls∙m [ i∙ls∙m≈ ] = splitTree-r i ls m rs i∙ls∙m (i∙ls∙m≈ ⍮ ≪∙ i∙ls≈) (s ≈▻⟅ sym 𝓂≈ ⟆ ◄ ¬p₁ ≈◄⟅ sym i∙ls≈ ⟆ ◄ ¬p₂ ≈◄⟅ ≪∙ i∙ls≈ ⟆) ≈[ ∙≫ 𝓂≈ ]
... | yes p₂ ≈ℙ i∙ls∙m [ i∙ls∙m≈ ] with splitTree i∙ls m (s ≈▻⟅ sym 𝓂≈ ⟆ ◄ ¬p₁ ≈◄⟅ sym i∙ls≈ ⟆ ▻ p₂)
... | lsₘ ∷⟨ μmₘ ↤ mₘ ⇑[ mₘ≈ ] ⟩∷ rsₘ [ sₘ ] ⇑[ m≈ ] with splitNode (i∙ls ∙ μ lsₘ) mₘ (sₘ ≈▻⟅ sym mₘ≈ ⟆)
... | lsₗ ∷⟨ mₗ ⟩∷ rsₗ [ sₗ ] ⇑[ l≈ ] = [ lemma ]≈ do
ll ← deepᵣ ls lsₘ lsₗ [ i ∙> (sz <∙ _) ⟿ sz ]
rr ← deepₗ rsₗ rsₘ rs [ i ∙> (_ ∙> (μ mₗ ∙> sz)) ⟿ sz ]
ll ∷⟨ mₗ ⟩∷ rr [ sₗ ≈◄⟅ ≪∙ ≪∙ i∙ls≈ ⍮ ℳ ↯ ⍮′ ∙≫ sym (_ ≈? _) ⟆ ] ⇑
where
lemma = begin
i ∙ (μ ls ∙ (μ lsₘ ∙ μ lsₗ) ∙ (μ mₗ ∙ (μ rsₗ ∙ (μ rsₘ ∙ μ rs))))
≈⟨ ℳ ↯ ⟩
i ∙ μ ls ∙ μ lsₘ ∙ (μ lsₗ ∙ (μ mₗ ∙ μ rsₗ)) ∙ (μ rsₘ ∙ μ rs)
≈⟨ ≪∙ ≪∙ ≪∙ sym i∙ls≈ ⍮ l≈ <∙ (μ rsₘ ∙ μ rs) ⟩
i∙ls ∙ μ lsₘ ∙ μ mₘ ∙ (μ rsₘ ∙ μ rs)
≈⟨ ≪∙ ∙≫ mₘ≈ ⟩
i∙ls ∙ μ lsₘ ∙ μmₘ ∙ (μ rsₘ ∙ μ rs)
≈⟨ ℳ ↯ ⟩
i∙ls ∙ (μ lsₘ ∙ (μmₘ ∙ μ rsₘ)) ∙ μ rs
≈⟨ m≈ <∙ μ rs ⟩
i∙ls ∙ μ m ∙ μ rs
≈⟨ ≪∙ ≪∙ i∙ls≈ ⟩
i ∙ μ ls ∙ μ m ∙ μ rs
≈⟨ ℳ ↯ ⟩
i ∙ (μ ls ∙ (μ m ∙ μ rs))
≈⟨ ∙≫ 𝓂≈ ⟩
i ∙ 𝓂 ∎
init-ℙ : ∀ {𝓂} → (¬ℙ⟨ε⟩ : False (ℙ? ε)) → (ℙ⟨xs⟩ : True (ℙ? 𝓂)) → ε ∣ 𝓂
¬ℙ (init-ℙ fl tr) = toWitnessFalse fl
!ℙ (init-ℙ fl tr) = ℙ-resp (sym (identityˡ _)) (toWitness tr)
record Split {a} (Σ : Set a) ⦃ _ : σ Σ ⦄ : Set (a ⊔ r ⊔ m ⊔ s) where
constructor _∷⟨_⟩∷_[_]
field
left : Tree Σ
focus : Σ
right : Tree Σ
is-split : μ left ∣ μ focus
open Split public
instance
σ-Split : ∀ {a} {Σ : Set a} ⦃ _ : σ Σ ⦄ → σ (Split Σ)
μ ⦃ σ-Split ⦄ (l ∷⟨ x ⟩∷ r [ _ ]) = μ l ∙ (μ x ∙ μ r)
open SplitStructures
split : ∀ {a} {Σ : Set a} ⦃ _ : σ Σ ⦄
→ {¬ℙ⟨ε⟩ : False (ℙ? ε)}
→ (xs : Tree Σ)
→ {ℙ⟨xs⟩ : True (ℙ? (μ xs))}
→ μ⟨ Split Σ ⟩≈ μ xs
split {¬ℙ⟨ε⟩ = ¬ℙ⟨ε⟩} xs {ℙ⟨xs⟩} with splitTree ε xs (init-ℙ ¬ℙ⟨ε⟩ ℙ⟨xs⟩) ≈[ identityˡ _ ]
... | xs′ ∷⟨ x ⟩∷ ys [ p ] ⇑[ p₂ ] = xs′ ∷⟨ x ⟩∷ ys [ p ≈◄⟅ identityˡ _ ⟆ ] ⇑[ sym (identityˡ _) ⍮ p₂ ]