{-# OPTIONS --without-K --safe #-}
open import Algebra
module Data.FingerTree.Cons
{r m}
(ℳ : Monoid r m)
where
open import Data.Product
open import Data.FingerTree.Measures ℳ
open import Data.FingerTree.Structures ℳ
open import Data.FingerTree.Reasoning ℳ
open σ ⦃ ... ⦄
{-# DISPLAY σ.μ _ x = μ x #-}
{-# DISPLAY μ-tree _ x = μ x #-}
{-# DISPLAY μ-deep _ x = μ x #-}
open Monoid ℳ renaming (Carrier to 𝓡)
infixr 5 _◂_
infixl 5 _▸_
_◂_ : ∀ {a} {Σ : Set a} ⦃ _ : σ Σ ⦄ → (x : Σ) → (xs : Tree Σ) → μ⟨ Tree Σ ⟩≈ (μ x ∙ μ xs)
a ◂ empty = single a ⇑[ ℳ ↯ ]
a ◂ single b = deep ⟪ D₁ a & empty & D₁ b ⇓⟫ ⇑[ ℳ ↯ ]
a ◂ deep (𝓂 ↤ D₁ b & m & rs ⇑[ 𝓂≈ ]) = deep (μ a ∙ 𝓂 ↤ D₂ a b & m & rs ⇑[ assoc _ _ _ ⍮ ∙≫ 𝓂≈ ]) ⇑
a ◂ deep (𝓂 ↤ D₂ b c & m & rs ⇑[ 𝓂≈ ]) = deep (μ a ∙ 𝓂 ↤ D₃ a b c & m & rs ⇑[ assoc _ _ _ ⍮ ∙≫ 𝓂≈ ]) ⇑
a ◂ deep (𝓂 ↤ D₃ b c d & m & rs ⇑[ 𝓂≈ ]) = deep (μ a ∙ 𝓂 ↤ D₄ a b c d & m & rs ⇑[ assoc _ _ _ ⍮ ∙≫ 𝓂≈ ]) ⇑
a ◂ deep (𝓂 ↤ D₄ b c d e & m & rs ⇑[ 𝓂≈ ]) with ⟪ N₃ c d e ⇓⟫ ◂ m
... | m′ ⇑[ m′≈ ] = deep (μ a ∙ 𝓂 ↤ D₂ a b & m′ & rs ⇑[ ∙≫ ≪∙ m′≈ ] ≈[ ℳ ↯ ] ≈[ ∙≫ 𝓂≈ ]′) ⇑
_▸_ : ∀ {a} {Σ : Set a} ⦃ _ : σ Σ ⦄ → (xs : Tree Σ) → (x : Σ) → μ⟨ Tree Σ ⟩≈ (μ xs ∙ μ x)
empty ▸ a = single a ⇑[ ℳ ↯ ]
single a ▸ b = deep ⟪ D₁ a & empty & D₁ b ⇓⟫ ⇑[ ℳ ↯ ]
deep (𝓂 ↤ ls & m & D₁ a ⇑[ 𝓂≈ ]) ▸ b = deep (𝓂 ∙ μ b ↤ ls & m & D₂ a b ⇑[ ℳ ↯ ⍮′ ≪∙ 𝓂≈ ]) ⇑
deep (𝓂 ↤ ls & m & D₂ a b ⇑[ 𝓂≈ ]) ▸ c = deep (𝓂 ∙ μ c ↤ ls & m & D₃ a b c ⇑[ ℳ ↯ ⍮′ ≪∙ 𝓂≈ ]) ⇑
deep (𝓂 ↤ ls & m & D₃ a b c ⇑[ 𝓂≈ ]) ▸ d = deep (𝓂 ∙ μ d ↤ ls & m & D₄ a b c d ⇑[ ℳ ↯ ⍮′ ≪∙ 𝓂≈ ]) ⇑
deep (𝓂 ↤ ls & m & D₄ a b c d ⇑[ 𝓂≈ ]) ▸ e with m ▸ ⟪ N₃ a b c ⇓⟫
... | m′ ⇑[ m′≈ ] = deep (𝓂 ∙ μ e ↤ ls & m′ & D₂ d e ⇑[ ∙≫ ≪∙ m′≈ ] ≈[ ℳ ↯ ] ≈[ ≪∙ 𝓂≈ ]′) ⇑
open import Data.List as List using (List; _∷_; [])
listToTree : ∀ {a} {Σ : Set a} ⦃ _ : σ Σ ⦄ → (xs : List Σ) → μ⟨ Tree Σ ⟩≈ (μ xs)
listToTree [] = empty ⇑
listToTree (x ∷ xs) = [ ℳ ↯ ]≈ do
ys ← listToTree xs [ μ x ∙> s ⟿ s ]
x ◂ ys