{-# 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