open import Data.Product using (Σ; _,_; proj₁; proj₂; _×_) renaming (map to _**_)
open import Relation.Nullary using (¬_; Dec; yes; no)
module Examples.LeftistHeap
(Val : Set) (_≤_ : Val → Val → Set)
(≤-refl : ∀ {x} → x ≤ x)
(≤-trans : ∀ {x y z} → x ≤ y → y ≤ z → x ≤ z)
(_≤?_ : (x y : Val) → Dec (x ≤ y))
(≰-invert : ∀ {x y} → ¬ (x ≤ y) → y ≤ x)
(_⊓_ : Val → Val → Val)
(⊓-universal-⇒ : ∀ z x y → z ≤ (x ⊓ y) → z ≤ x × z ≤ y)
(⊓-universal-⇐ : ∀ {z x y} → z ≤ x → z ≤ y → z ≤ (x ⊓ y)) where
open import Prelude
open import Refinement
open import Description
open import Ornament
open import Ornament.ParallelComposition
open import Ornament.RefinementSemantics
open import Ornament.ParallelComposition.PredicateSwap
open import Examples.Nat
open import Examples.Nat.TotalOrdering renaming (_≤_ to _≤'_; ≤-refl to ≤'-refl; _≤?_ to _≤'?_; ≰-invert to ≰'-invert)
open import Examples.List
open import Function using (id; _∘_)
open import Data.Unit using (⊤; tt)
open import Data.Bool using (Bool; false; true)
open import Relation.Binary.PropositionalEquality using (_≡_; refl; subst; cong; sym; trans)
TreeD : Desc ⊤
TreeD = wrap λ _ → σ Bool λ { false → ∎
; true → ṿ tt * ṿ tt }
LTreeO : OrnDesc Nat ! TreeD
LTreeO = wrap λ { (con (false , _)) → ∇ false ∎
; (con (true , r)) → ∇ true (Δ[ r' ∶ Nat ] Δ[ _ ∶ r ≤' r' ] ṿ (ok r') * ṿ (ok r)) }
ITreeO : Set → OrnDesc ⊤ ! TreeD
ITreeO A = wrap λ _ → σ Bool λ { false → ∎
; true → Δ[ _ ∶ A ] ṿ (ok tt) * ṿ (ok tt) }
ITree : Set → Set
ITree A = μ ⌊ ITreeO A ⌋ tt
preorder : ∀ {A} → ITree A → List A
preorder (con (false , _)) = []
preorder (con (true , x , t , u)) = x ∷ preorder t ++ preorder u
HeapO : OrnDesc Val ! TreeD
HeapO = wrap λ b → σ Bool λ { false → ∎
; true → Δ[ x ∶ Val ] Δ[ _ ∶ b ≤ x ] ṿ (ok x) * ṿ (ok x) }
ITreeD-HeapD : Orn ! ⌊ ITreeO Val ⌋ ⌊ HeapO ⌋
ITreeD-HeapD =
wrap λ b → σ Bool λ { false → ∎
; true → σ[ x ∶ Val ] Δ[ _ ∶ b ≤ x ] ṿ refl * ṿ refl }
Heap : Val → Set
Heap = μ ⌊ HeapO ⌋
relax : ∀ {b b'} → b' ≤ b → ∀ {t} → [ ok b ] t ⊩ ⌈ HeapO ⌉ → [ ok b' ] t ⊩ ⌈ HeapO ⌉
relax b'≤b {con (false , _)} p = con tt
relax b'≤b {con (true , _)} (con (x , b≤x , t , u)) = con (x , ≤-trans b'≤b b≤x , t , u)
LHeapD : Desc (! ⋈ !)
LHeapD = ⌊ ⌈ HeapO ⌉ ⊗ ⌈ LTreeO ⌉ ⌋
LHeap : Val → Nat → Set
LHeap b r = μ LHeapD (ok b , ok r)
toList : ∀ {b r} → LHeap b r → List Val
toList = preorder ∘ forget ITreeD-HeapD ∘ forget (diffOrn-l ⌈ HeapO ⌉ ⌈ LTreeO ⌉)
lhrelax : ∀ {b b'} → b' ≤ b → ∀ {r} → LHeap b r → LHeap b' r
lhrelax {b} {b'} b'≤b {r} =
Iso.from (Refinement.ℜ re (ok (ok b' , ok r))) ∘
(id ** (relax b'≤b ** id)) ∘
Iso.to (Refinement.ℜ re (ok (ok b , ok r)))
where re : Refinement (μ TreeD) (μ LHeapD)
re = toRefinement (Swap-⊗ ⌈ HeapO ⌉ ⌈ LTreeO ⌉ idSwap idSwap)
makeT : (x : Val) → ∀ {r} (t : LHeap x r) → ∀ {r'} (t' : LHeap x r') → Σ Nat (LHeap x)
makeT x {r} t {r'} t' with r ≤'? r'
makeT x {r} t {r'} t' | yes r≤r' = suc r , con (x , ≤-refl , r' , r≤r' , t' , t)
makeT x {r} t {r'} t' | no r≰r' = suc r' , con (x , ≤-refl , r , ≰'-invert r≰r' , t , t')
mutual
merge : ∀ {b r} → LHeap b r → ∀ {b' r'} → LHeap b' r' → Σ Nat (LHeap (b ⊓ b'))
merge {b} {con (false , _)} h {b'} h' = _ , lhrelax (proj₂ (⊓-universal-⇒ (b ⊓ b') b b' ≤-refl)) h'
merge {b} {con (true , r)} h {b'} h' = merge' h h'
merge' : ∀ {b r} → LHeap b (suc r) → ∀ {b' r'} → LHeap b' r' → Σ Nat (LHeap (b ⊓ b'))
merge' {b} {r} h {b'} {con (false , _)} h' =
_ , lhrelax (proj₁ (⊓-universal-⇒ (b ⊓ b') b b' ≤-refl)) (subst (LHeap b) (sym (rhs-zero (suc r))) h)
merge' {b} {r} (con (x , b≤x , l , r≤l , t , u)) {b'} {con (true , r')} (con (x' , b'≤x' , l' , r'≤l' , t' , u')) =
merge'-with x b≤x l r≤l t u x' b'≤x' l' r'≤l' t' u' (x ≤? x')
merge'-with :
∀ {b r} → (x : Val) (b≤x : b ≤ x) (l : Nat) (r≤l : r ≤' l) (t : LHeap x l) (u : LHeap x r) →
∀ {b' r'} → (x' : Val) (b'≤x' : b' ≤ x') (l' : Nat) (r'≤l' : r' ≤' l') (t' : LHeap x' l') (u' : LHeap x' r') →
Dec (x ≤ x') → Σ Nat (LHeap (b ⊓ b'))
merge'-with {b} {r} x b≤x l r≤l t u {b'} {r'} x' b'≤x' l' r'≤l' t' u' (yes x≤x') =
_ , lhrelax (≤-trans (proj₁ (⊓-universal-⇒ (b ⊓ b') b b' ≤-refl)) b≤x)
(proj₂ (makeT x t (lhrelax (⊓-universal-⇐ ≤-refl ≤-refl)
(proj₂ (merge u {r' = suc r'} (con (x' , x≤x' , l' , r'≤l' , t' , u')))))))
merge'-with {b} {r} x b≤x l r≤l t u {b'} {r'} x' b'≤x' l' r'≤l' t' u' (no x≰x') =
_ , lhrelax (≤-trans (proj₂ (⊓-universal-⇒ (b ⊓ b') b b' ≤-refl)) b'≤x')
(proj₂ (makeT x' t' (lhrelax (⊓-universal-⇐ ≤-refl ≤-refl)
(proj₂ (merge' {r = r} (con (x , ≰-invert x≰x' , l , r≤l , t , u)) u')))))
insert : (y : Val) → ∀ {b r} → LHeap b r → Σ Nat (LHeap (b ⊓ y))
insert y h = merge h {r' = suc zero} (con (y , ≤-refl , zero , ≤'-refl , con tt , con tt))
WLTreeO : OrnDesc Nat ! TreeD
WLTreeO = wrap λ { (con (false , _)) → ∇ false ∎
; (con (true , n)) → ∇ true (Δ[ l ∶ Nat ] Δ[ r ∶ Nat ] Δ[ _ ∶ r ≤' l ] Δ[ _ ∶ n ≡ l + r ] ṿ (ok l) * ṿ (ok r)) }
WLHeapD : Desc (! ⋈ !)
WLHeapD = ⌊ ⌈ HeapO ⌉ ⊗ ⌈ WLTreeO ⌉ ⌋
WLHeap : Val → Nat → Set
WLHeap b n = μ WLHeapD (ok b , ok n)
wlhrelax : ∀ {b b'} → b' ≤ b → ∀ {n} → WLHeap b n → WLHeap b' n
wlhrelax {b} {b'} b'≤b {r} h =
Iso.from (Refinement.ℜ re (ok (ok b' , ok r)))
((id ** (relax b'≤b ** id))
(Iso.to (Refinement.ℜ re (ok (ok b , ok r))) h))
where re : Refinement (μ TreeD) (μ WLHeapD)
re = toRefinement (Swap-⊗ ⌈ HeapO ⌉ ⌈ WLTreeO ⌉ idSwap idSwap)
{-# NO_TERMINATION_CHECK #-}
mutual
wmerge : ∀ {b n} → WLHeap b n → ∀ {b' n'} → WLHeap b' n' → WLHeap (b ⊓ b') (n + n')
wmerge {b} {con (false , _)} h {b'} h' = wlhrelax (proj₂ (⊓-universal-⇒ (b ⊓ b') b b' ≤-refl)) h'
wmerge {b} {con (true , n)} h h' = wmerge' h h'
wmerge' : ∀ {b n} → WLHeap b (suc n) → ∀ {b' n'} → WLHeap b' n' → WLHeap (b ⊓ b') (suc n + n')
wmerge' {b} {n} h {b'} {con (false , _)} h' =
wlhrelax (proj₁ (⊓-universal-⇒ (b ⊓ b') b b' ≤-refl)) (subst (WLHeap b) (sym (rhs-zero (suc n))) h)
wmerge' {b} {n} (con (x , b≤x , l , r , r≤l , n≡l+r , t , u))
{b'} {con (true , n')} (con (x' , b'≤x' , l' , r' , r'≤l' , n'≡l'+r' , t' , u')) =
wmerge'-with x b≤x l r r≤l n≡l+r t u x' b'≤x' l' r' r'≤l' n'≡l'+r' t' u' (x ≤? x')
wmerge'-with :
∀ {b n} (x : Val) (b≤x : b ≤ x) (l r : Nat) (r≤l : r ≤' l) (n≡l+r : n ≡ l + r) (t : WLHeap x l) (u : WLHeap x r) →
∀ {b' n'} (x' : Val) (b'≤x' : b' ≤ x') (l' r' : Nat) (r'≤l' : r' ≤' l') (n'≡l'+r' : n' ≡ l' + r') (t' : WLHeap x' l') (u' : WLHeap x' r') →
Dec (x ≤ x') → WLHeap (b ⊓ b') (suc n + suc n')
wmerge'-with {b} {n} x b≤x l r r≤l n≡l+r t u {b'} {n'} x' b'≤x' l' r' r'≤l' n'≡l'+r' t' u' (yes x≤x') =
wlhrelax (≤-trans (proj₁ (⊓-universal-⇒ (b ⊓ b') b b' ≤-refl)) b≤x)
(subst (WLHeap x) (cong suc (trans (sym (assoc l r (suc n'))) (cong (λ m → m + suc n') (sym n≡l+r))))
(wmakeT x t (wlhrelax (⊓-universal-⇐ {x} ≤-refl ≤-refl)
(wmerge u {n' = suc n'} (con (x' , x≤x' , l' , r' , r'≤l' , n'≡l'+r' , t' , u'))))))
wmerge'-with {b} {n} x b≤x l r r≤l n≡l+r t u {b'} {n'} x' b'≤x' l' r' r'≤l' n'≡l'+r' t' u' (no x≰x') =
wlhrelax (≤-trans (proj₂ (⊓-universal-⇒ (b ⊓ b') b b' ≤-refl)) b'≤x')
(subst (WLHeap x') (cong suc (trans (assoc (suc n) l' r')
(trans (sym (rhs-suc n (l' + r'))) (cong (_+_ n) (cong suc (sym n'≡l'+r'))))))
(wmakeT x' (wlhrelax (⊓-universal-⇐ {x'} ≤-refl ≤-refl)
(wmerge' {n = n} (con (x , ≰-invert x≰x' , l , r , r≤l , n≡l+r , t , u)) t')) u'))
wmakeT : (x : Val) → ∀ {n} (t : WLHeap x n) → ∀ {n'} (t' : WLHeap x n') → WLHeap x (suc (n + n'))
wmakeT x {n} t {n'} t' with n ≤'? n'
wmakeT x {n} t {n'} t' | yes n≤n' = con (x , ≤-refl , n' , n , n≤n' , comm n n' , t' , t)
wmakeT x {n} t {n'} t' | no n≰n' = con (x , ≤-refl , n , n' , ≰'-invert n≰n' , refl , t , t')