{-# OPTIONS --rewriting #-}
module Examples.Amortized.SplayTree.Base where
open import Algebra.Cost
costMonoid = ℕ-CostMonoid
open CostMonoid costMonoid renaming (_+_ to _⊕_)
open import Calf costMonoid
open import Calf.Data.List hiding (find)
open import Calf.Data.Nat
open import Calf.Data.Bool as Bool using (bool; true; false)
open import Calf.Data.Product
open import Data.Nat as Nat using (ℕ; _<_; _≤?_; _<?_; zero)
open import Data.Nat.Properties as Nat using (module ≤-Reasoning; _≟_)
open import Relation.Binary
open import Relation.Binary.PropositionalEquality as Eq using (_≡_; refl; module ≡-Reasoning)
open import Data.Nat.Logarithm
record BST : Set where
field
T : tp⁺
fromList : cmp (Π (list nat) (λ _ → F (T)))
size : cmp (Π T (λ _ → F (nat)))
find : cmp (Π T (λ _ → Π nat (λ _ → F (bool ×⁺ T))))
insert/val : (x : val nat) → (sorted-xs : val (list nat)) → val (list nat)
insert/val x [] = x ∷ []
insert/val x (y ∷ ys) with Nat.<-cmp x y
... | tri< _ _ _ = x ∷ (y ∷ ys)
... | tri≈ _ _ _ = x ∷ (y ∷ ys)
... | tri> _ _ _ = y ∷ (insert/val x ys)
sort/val : val (list nat) → val (list nat)
sort/val [] = []
sort/val (x ∷ xs) = insert/val x (sort/val xs)
listFind : (l : val (list nat)) (k : val nat) → cmp (F (bool))
listFind [] k = ret (false)
listFind (x ∷ xs) k with Nat.<-cmp x k
... | tri< _ _ _ = bind (F _) (listFind xs k) ret
... | tri≈ _ _ _ = ret (true)
... | tri> _ _ _ = bind (F _) (listFind xs k) ret
deduplicate/cmp : cmp (Π (list nat) λ _ → F (list nat))
deduplicate/cmp l = ret (deduplicate {R = _≡_} Nat._≟_ l)
ListTree : BST
ListTree .BST.T = list nat
ListTree .BST.fromList l =
step (F _) (length (sort/val (deduplicate {R = _≡_} Nat._≟_ l)) * ⌊log₂ (length (sort/val (deduplicate {R = _≡_} Nat._≟_ l))) ⌋)
(ret (sort/val (deduplicate {R = _≡_} Nat._≟_ l)))
ListTree .BST.size l = ret (length l)
ListTree .BST.find l k =
step (F _) ((3 * ⌊log₂ (length l)⌋) + 1) (
bind (F _) (listFind l k) (λ b → ret (b , l)))
list/find/lemma : ∀ (l : val (list nat)) (k : val nat) → ∃[ b ] (listFind l k ≡ ret b)
list/find/lemma [] k = false , refl
list/find/lemma (x ∷ xs) k with Nat.<-cmp x k
... | tri< _ _ _ = list/find/lemma xs k
... | tri≈ _ _ _ = true , refl
... | tri> _ _ _ = list/find/lemma xs k
list/find/bind/lemma : (l : val (list nat)) → (k : val nat) →
bind (F (list nat)) (listFind l k) (λ _ → ret l) ≡ ret l
list/find/bind/lemma l k with (list/find/lemma l k)
... | b , eq =
let open ≡-Reasoning in
begin
bind (F (list nat)) (listFind l k) (λ _ → ret l)
≡⟨ Eq.cong (λ e → bind (F _) e (λ _ → ret l)) eq ⟩
bind {A = bool} (F (list nat)) (ret b) (λ _ → ret l)
≡⟨⟩
ret l
∎