Last active
August 29, 2015 14:04
-
-
Save josh-hs-ko/39ccd95af603d628b56b to your computer and use it in GitHub Desktop.
Insertion and extraction in coherence with increment and decrement, and minimum extraction (proved correct, of course).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| open import Data.Sum | |
| module BinomialHeap (V : Set) | |
| (_≤_ : V → V → Set) (≤-refl : {x : V} → x ≤ x) (≤-trans : {x y z : V} → x ≤ y → y ≤ z → x ≤ z) | |
| (_≤?_ : (x y : V) → x ≤ y ⊎ y ≤ x) where | |
| open import Level using (Level; _⊔_) | |
| open import Function | |
| open import Data.Empty | |
| open import Data.Unit | |
| open import Data.Bool using (Bool; false; true) | |
| open import Data.Maybe renaming (map to mapMaybe) | |
| open import Data.Product renaming (map to _**_; <_,_> to split) | |
| open import Data.Nat using (ℕ; zero; suc) | |
| open import Relation.Nullary | |
| open import Relation.Binary.PropositionalEquality | |
| open import Relation.Binary.HeterogeneousEquality using (_≅_; ≅-to-≡; ≡-to-≅; ≡-subst-removable) | |
| renaming (refl to hrefl; sym to fsym; trans to htrans; cong to hcong) | |
| - : {l : Level} {A : Set l} {{_ : A}} → A | |
| - {{a}} = a | |
| -- See Conor McBride's "How to keep your neighbours in order" (ICFP'14) | |
| if_then_else_ : {A B C : Set} → A ⊎ B → ({{_ : A}} → C) → ({{_ : B}} → C) → C | |
| if inj₁ a then t else u = t | |
| if inj₂ b then t else u = u | |
| if-elim : {A B C : Set} (c : A ⊎ B) (ca : {{_ : A}} → C) (cb : {{_ : B}} → C) → | |
| (P : C → Set) → ({{_ : A}} → P ca) → ({{_ : B}} → P cb) → P (if c then ca else cb) | |
| if-elim (inj₁ a) ca cb P pa pb = pa | |
| if-elim (inj₂ b) ca cb P pa pb = pb | |
| pattern <_> b = _ , b | |
| pattern <_>' h = h , _ | |
| pattern <_>ʳ h = h , refl | |
| Exists : ∀ {a b} {A : Set a} → (A → Set b) → Set (a ⊔ b) | |
| Exists = Σ _ | |
| syntax Exists (λ x → P) = ∃[ x ] P | |
| -------- | |
| -- binary numbers | |
| data Bin : Set where -- specialisation of List Bool | |
| nul : Bin | |
| zero : Bin → Bin | |
| one : Bin → Bin | |
| incr : Bin → Bin | |
| incr nul = one nul | |
| incr (zero b) = one b | |
| incr (one b) = zero (incr b) | |
| -------- | |
| -- binomial trees | |
| _^_ : (ℕ → Set) → ℕ → Set | |
| X ^ zero = ⊤ | |
| X ^ (suc n) = X n × (X ^ n) | |
| data BTree : V → ℕ → Set where | |
| node : {x : V} {r : ℕ} (y : V) {{ord : x ≤ y}} (ts : BTree y ^ r) → BTree x r | |
| root : {x : V} {r : ℕ} → BTree x r → V | |
| root (node a ts) = a | |
| link : {x y : V} {r : ℕ} (t : BTree x r) (u : BTree y r) {{leq : root u ≤ root t}} → BTree y (suc r) | |
| link (node a ts) (node b us) = node b (node a ts , us) | |
| link-root : {x y : V} {r : ℕ} (t : BTree x r) (u : BTree y r) {{leq : root u ≤ root t}} | |
| {l : V} → l ≤ root u → l ≤ root (link t u) | |
| link-root (node a ts) (node b us) l≤b = l≤b | |
| attach' : {x y : V} {r : ℕ} → BTree x r → BTree y r → ∃[ z ] BTree z (suc r) | |
| attach' t u = if root t ≤? root u then < link u t > else < link t u > | |
| attach : {x y : V} {r : ℕ} (t : BTree x r) (u : BTree y r) → BTree (proj₁ (attach' t u)) (suc r) | |
| attach t u = proj₂ (attach' t u) | |
| bound-root : {x : V} {r : ℕ} (t : BTree x r) {y : V} → y ≤ x → y ≤ root t | |
| bound-root (node a {{x≤a}} ts) y≤x = ≤-trans y≤x x≤a | |
| attach-root : {x y : V} {r : ℕ} (t : BTree x r) (u : BTree y r) | |
| {l : V} → l ≤ root t → l ≤ root u → l ≤ root (attach t u) | |
| attach-root {x} {y} {r} t u {l} l≤t l≤u = | |
| if-elim {C = ∃[ z ] BTree z (suc r)} (root t ≤? root u) < link u t > < link t u > | |
| (λ v → l ≤ root (proj₂ v)) (link-root u t l≤t) (link-root t u l≤u) | |
| -------- | |
| -- binomial heaps | |
| -- ornamentation of Bin | |
| data BHeap : ℕ → Set where | |
| nul : {r : ℕ} → BHeap r | |
| zero : {r : ℕ} (h : BHeap (suc r)) → BHeap r | |
| one : {r : ℕ} {x : V} (t : BTree x r) (h : BHeap (suc r)) → BHeap r | |
| -- free | |
| toBin : {r : ℕ} → BHeap r → Bin | |
| toBin nul = nul | |
| toBin (zero h) = zero (toBin h) | |
| toBin (one x h) = one (toBin h) | |
| -- free | |
| data BHeap' : ℕ → Bin → Set where | |
| nul : {r : ℕ} → BHeap' r nul | |
| zero : {r : ℕ} {b : Bin} (h : BHeap' (suc r) b) → BHeap' r (zero b) | |
| one : {r : ℕ} {b : Bin} {x : V} (t : BTree x r) (h : BHeap' (suc r) b) → BHeap' r (one b) | |
| insT' : {x : V} {r : ℕ} {b : Bin} → BTree x r → BHeap' r b → BHeap' r (incr b) | |
| insT' t nul = one t nul | |
| insT' t (zero h) = one t h | |
| insT' t (one u h) = zero (insT' (attach t u) h) | |
| -- free | |
| toBHeap : {r : ℕ} {b : Bin} → BHeap' r b → BHeap r | |
| toBHeap nul = nul | |
| toBHeap (zero h) = zero (toBHeap h) | |
| toBHeap (one t h) = one t (toBHeap h) | |
| -- free | |
| fromBHeap : {r : ℕ} (h : BHeap r) → BHeap' r (toBin h) | |
| fromBHeap nul = nul | |
| fromBHeap (zero h) = zero (fromBHeap h) | |
| fromBHeap (one t h) = one t (fromBHeap h) | |
| -- free | |
| insT : {x : V} {r : ℕ} → BTree x r → BHeap r → BHeap r | |
| insT t h = toBHeap (insT' t (fromBHeap h)) | |
| -- free | |
| recomputation : {r : ℕ} {b : Bin} (h : BHeap' r b) → toBin (toBHeap h) ≡ b | |
| recomputation nul = refl | |
| recomputation (zero h) = cong zero (recomputation h) | |
| recomputation (one t h) = cong one (recomputation h) | |
| -- free | |
| incr-insT-coherence : {x : V} {r : ℕ} (t : BTree x r) (h : BHeap r) → toBin (insT t h) ≡ incr (toBin h) | |
| incr-insT-coherence t h = recomputation (insT' t (fromBHeap h)) | |
| -------- | |
| -- refinements and upgrades | |
| elim-≡ : ∀ {a b} {A : Set a} {x : A} (P : {y : A} → x ≡ y → Set b) → P refl → {y : A} (eq : x ≡ y) → P eq | |
| elim-≡ P p refl = p | |
| record Iso (A B : Set) : Set₁ where | |
| field | |
| to : A → B | |
| from : B → A | |
| from-to-inverse : (x : A) → from (to x) ≡ x | |
| to-from-inverse : (y : B) → to (from y) ≡ y | |
| record Refinement (X Y : Set) : Set₁ where | |
| field | |
| P : X → Set | |
| i : Iso Y (Σ X P) | |
| forget : Y → X | |
| forget = proj₁ ∘ Iso.to i | |
| canonRef : {X Y : Set} → (Y → X) → Refinement X Y | |
| canonRef {X} {Y} f = | |
| record { P = λ x → Σ[ y ∈ Y ] f y ≡ x | |
| ; i = record { to = split f (split id (λ _ → refl)) | |
| ; from = proj₁ ∘ proj₂ | |
| ; to-from-inverse = λ { (._ , y , refl) → refl } | |
| ; from-to-inverse = λ _ → refl } } | |
| prom-change : {X Y : Set} (r s : Refinement X Y) → ((y : Y) → Refinement.forget r y ≡ Refinement.forget s y) → | |
| ∀ x → Refinement.P r x → Refinement.P s x | |
| prom-change r s eq x p = | |
| subst (Refinement.P s) | |
| (trans (sym (eq (Iso.from (Refinement.i r) (x , p)))) (cong proj₁ (Iso.to-from-inverse (Refinement.i r) (x , p)))) | |
| (proj₂ (Iso.to (Refinement.i s) (Iso.from (Refinement.i r) (x , p)))) | |
| prom-inverse : {X Y : Set} (r s : Refinement X Y) | |
| (rseq : (y : Y) → Refinement.forget r y ≡ Refinement.forget s y) | |
| (sreq : (y : Y) → Refinement.forget s y ≡ Refinement.forget r y) → | |
| ∀ x (p : Refinement.P r x) → prom-change s r sreq x (prom-change r s rseq x p) ≡ p | |
| prom-inverse r s rseq sreq x p = | |
| let xp = (x , subst (Refinement.P s) | |
| (trans (sym (rseq (Iso.from (Refinement.i r) (x , p)))) | |
| (cong proj₁ (Iso.to-from-inverse (Refinement.i r) (x , p)))) | |
| (proj₂ (Iso.to (Refinement.i s) (Iso.from (Refinement.i r) (x , p))))) | |
| in ≅-to-≡ (htrans (≡-subst-removable (Refinement.P r) | |
| (trans (sym (sreq (Iso.from (Refinement.i s) xp))) | |
| (cong proj₁ (Iso.to-from-inverse (Refinement.i s) xp))) | |
| (proj₂ (Iso.to (Refinement.i r) (Iso.from (Refinement.i s) xp)))) | |
| (elim-≡ (λ {x'} eq' → | |
| proj₂ (Iso.to (Refinement.i r) (Iso.from (Refinement.i s) | |
| (x' , subst (Refinement.P s) eq' | |
| (proj₂ (Iso.to (Refinement.i s) (Iso.from (Refinement.i r) (x , p))))))) | |
| ≅ p) | |
| (htrans (hcong (proj₂ ∘ Iso.to (Refinement.i r)) | |
| (≡-to-≅ (Iso.from-to-inverse (Refinement.i s) (Iso.from (Refinement.i r) (x , p))))) | |
| (hcong proj₂ (≡-to-≅ (Iso.to-from-inverse (Refinement.i r) (x , p))))) | |
| (trans (sym (rseq (Iso.from (Refinement.i r) (x , p)))) | |
| (cong proj₁ (Iso.to-from-inverse (Refinement.i r) (x , p)))))) | |
| promIso : {X Y : Set} (r s : Refinement X Y) → ((y : Y) → Refinement.forget r y ≡ Refinement.forget s y) → | |
| ∀ x → Iso (Refinement.P r x) (Refinement.P s x) | |
| promIso r s eq x = | |
| record { to = prom-change r s eq x | |
| ; from = prom-change s r (sym ∘ eq) x | |
| ; to-from-inverse = prom-inverse s r (sym ∘ eq) eq x | |
| ; from-to-inverse = prom-inverse r s eq (sym ∘ eq) x } | |
| coherence : {X Y : Set} (r : Refinement X Y) → ∀ x → Iso (Refinement.P r x) (Σ[ y ∈ Y ] Refinement.forget r y ≡ x) | |
| coherence {X} {Y} r = promIso r (canonRef (Refinement.forget r)) (λ _ → refl) | |
| record Upgrade (X Y : Set) : Set₁ where | |
| field | |
| P : X → Set | |
| C : X → Y → Set | |
| u : ∀ x → P x → Y | |
| c : ∀ x → (p : P x) → C x (u x p) | |
| toUpgrade : ∀ {X Y} → Refinement X Y → Upgrade X Y | |
| toUpgrade r = record { P = Refinement.P r | |
| ; C = λ x y → Refinement.forget r y ≡ x | |
| ; u = λ x → proj₁ ∘ Iso.to (coherence r x) | |
| ; c = λ x → proj₂ ∘ Iso.to (coherence r x) } | |
| _⇀_ : {X Y Z W : Set} → Refinement X Y → Upgrade Z W → Upgrade (X → Z) (Y → W) | |
| r ⇀ s = record { P = λ f → ∀ x → (p : Refinement.P r x) → Upgrade.P s (f x) | |
| ; C = λ f g → ∀ x y → Upgrade.C (toUpgrade r) x y → Upgrade.C s (f x) (g y) | |
| ; u = λ f h → Upgrade.u s _ ∘ uncurry h ∘ Iso.to (Refinement.i r) | |
| ; c = λ { f h ._ y refl → let xp = (Iso.to (Refinement.i r) y) | |
| in Upgrade.c s (f (proj₁ xp)) (uncurry h xp) } } | |
| infixr 2 _⇀_ | |
| new : {X : Set} (I : Set) {Y : I → Set} → (∀ i → Upgrade X (Y i)) → Upgrade X ((i : I) → Y i) | |
| new I r = record { P = λ x → ∀ i → Upgrade.P (r i) x | |
| ; C = λ x y → ∀ i → Upgrade.C (r i) x (y i) | |
| ; u = λ x p i → Upgrade.u (r i) x (p i) | |
| ; c = λ x p i → Upgrade.c (r i) x (p i) } | |
| syntax new I (λ i → r) = ∀⁺[ i ∈ I ] r | |
| new' : {X : Set} (I : Set) {Y : I → Set} → (∀ i → Upgrade X (Y i)) → Upgrade X ({i : I} → Y i) | |
| new' I r = record { P = λ x → ∀ {i} → Upgrade.P (r i) x | |
| ; C = λ x y → ∀ {i} → Upgrade.C (r i) x (y {i}) | |
| ; u = λ x p {i} → Upgrade.u (r i) x (p {i}) | |
| ; c = λ x p {i} → Upgrade.c (r i) x (p {i}) } | |
| syntax new' I (λ i → r) = ∀⁺[[ i ∈ I ]] r | |
| fixed : (I : Set) {X : I → Set} {Y : I → Set} → (∀ i → Upgrade (X i) (Y i)) → Upgrade ((i : I) → X i) ((i : I) → Y i) | |
| fixed I u = record { P = λ f → ∀ i → Upgrade.P (u i) (f i) | |
| ; C = λ f g → ∀ i → Upgrade.C (u i) (f i) (g i) | |
| ; u = λ f h i → Upgrade.u (u i) (f i) (h i) | |
| ; c = λ f h i → Upgrade.c (u i) (f i) (h i) } | |
| syntax fixed I (λ i → u) = ∀[ i ∈ I ] u | |
| fixed' : (I : Set) {X : I → Set} {Y : I → Set} → (∀ i → Upgrade (X i) (Y i)) → Upgrade ({i : I} → X i) ({i : I} → Y i) | |
| fixed' I u = record { P = λ f → ∀ {i} → Upgrade.P (u i) (f {i}) | |
| ; C = λ f g → ∀ {i} → Upgrade.C (u i) (f {i}) (g {i}) | |
| ; u = λ f h {i} → Upgrade.u (u i) (f {i}) (h {i}) | |
| ; c = λ f h {i} → Upgrade.c (u i) (f {i}) (h {i}) } | |
| syntax fixed' I (λ i → u) = ∀[[ i ∈ I ]] u | |
| fixed'' : (I : Set) {X : I → Set} {Y : I → Set} → (∀ i → Upgrade (X i) (Y i)) → Upgrade ((i : I) → X i) ({i : I} → Y i) | |
| fixed'' I u = record { P = λ f → (i : I) → Upgrade.P (u i) (f i) | |
| ; C = λ f g → (i : I) → Upgrade.C (u i) (f i) (g {i}) | |
| ; u = λ f h {i} → Upgrade.u (u i) (f i) (h i) | |
| ; c = λ f h i → Upgrade.c (u i) (f i) (h i) } | |
| record FUpgrade (X Y : Set) : Set₁ where | |
| field | |
| P : X → Set | |
| forget : Y → X | |
| u : ∀ x → P x → Y | |
| c : ∀ x → (p : P x) → forget (u x p) ≡ x | |
| fromFUpgrade : {X Y : Set} → FUpgrade X Y → Upgrade X Y | |
| fromFUpgrade fupg = record | |
| { P = FUpgrade.P fupg | |
| ; C = λ x y → FUpgrade.forget fupg y ≡ x | |
| ; u = FUpgrade.u fupg | |
| ; c = FUpgrade.c fupg } | |
| toFUpgrade : {X Y : Set} → Refinement X Y → FUpgrade X Y | |
| toFUpgrade ref = record | |
| { P = Refinement.P ref | |
| ; forget = Refinement.forget ref | |
| ; u = curry (Iso.from (Refinement.i ref)) | |
| ; c = curry (cong proj₁ ∘ Iso.to-from-inverse (Refinement.i ref)) } | |
| _⁺×_ : (X : Set) {Y Z : Set} → FUpgrade Y Z → FUpgrade Y (X × Z) | |
| X ⁺× fupg = record { P = λ y → X × FUpgrade.P fupg y | |
| ; forget = FUpgrade.forget fupg ∘ proj₂ | |
| ; u = λ { y (x , p) → x , FUpgrade.u fupg y p } | |
| ; c = λ { y (x , p) → FUpgrade.c fupg y p } } | |
| -------- | |
| -- refinement from Bin to BHeap | |
| toBHeap-fromBHeap-inverse : {r : ℕ} (h : BHeap r) → toBHeap (fromBHeap h) ≡ h | |
| toBHeap-fromBHeap-inverse nul = refl | |
| toBHeap-fromBHeap-inverse (zero h) = cong zero (toBHeap-fromBHeap-inverse h) | |
| toBHeap-fromBHeap-inverse (one t h) = cong (one t) (toBHeap-fromBHeap-inverse h) | |
| fromBHeap-toBHeap-inverse : | |
| {r : ℕ} (b : Bin) (h' : BHeap' r b) → | |
| let h = toBHeap h' in (toBin h , fromBHeap h) ≡ (Σ Bin (BHeap' r) ∋ b , h') | |
| fromBHeap-toBHeap-inverse nul nul = refl | |
| fromBHeap-toBHeap-inverse (zero b) (zero h') = cong (zero ** zero) (fromBHeap-toBHeap-inverse b h') | |
| fromBHeap-toBHeap-inverse (one b) (one t h') = cong (one ** one t) (fromBHeap-toBHeap-inverse b h') | |
| Bin-BHeap : (r : ℕ) → Refinement Bin (BHeap r) | |
| Bin-BHeap r = record | |
| { P = BHeap' r | |
| ; i = record { to = split toBin fromBHeap | |
| ; from = toBHeap ∘ proj₂ | |
| ; from-to-inverse = toBHeap-fromBHeap-inverse | |
| ; to-from-inverse = uncurry fromBHeap-toBHeap-inverse } } | |
| -------- | |
| -- decrement and extraction | |
| decr : Bin → Maybe Bin | |
| decr nul = nothing | |
| decr (zero b) = mapMaybe one (decr b) | |
| decr (one b) = just (zero b) | |
| data Maybe' {A : Set} (B : A → Set) : Maybe A → Set where | |
| nothing : Maybe' B nothing | |
| just : {a : A} (b : B a) → Maybe' B (just a) | |
| toMaybe : {A : Set} {B : A → Set} {ma : Maybe A} → Maybe' B ma → Maybe (Σ A B) | |
| toMaybe nothing = nothing | |
| toMaybe (just b) = just < b > | |
| mapMaybe' : {A B : Set} {C : A → Set} {D : B → Set} {f : A → B} → ({a : A} → C a → D (f a)) → | |
| {ma : Maybe A} → Maybe' C ma → Maybe' D (mapMaybe f ma) | |
| mapMaybe' f' nothing = nothing | |
| mapMaybe' f' (just c) = just (f' c) | |
| maybeFU : {A B : Set} → FUpgrade A B → FUpgrade (Maybe A) (Maybe B) | |
| maybeFU {A} {B} fupg = record | |
| { P = Maybe' (FUpgrade.P fupg) | |
| ; forget = mapMaybe (FUpgrade.forget fupg) | |
| ; u = λ _ → mapMaybe proj₂ ∘ toMaybe ∘ mapMaybe' {f = id} (λ {a} → FUpgrade.u fupg a) | |
| ; c = λ { nothing nothing → refl | |
| ; (just a) (just p) → cong just (FUpgrade.c fupg a p) } } | |
| decr-extract-upg : Upgrade (Bin → Maybe Bin) ({r : ℕ} → BHeap r → Maybe ((∃[ x ] BTree x r) × BHeap r)) | |
| decr-extract-upg = ∀⁺[[ r ∈ ℕ ]] Bin-BHeap r ⇀ fromFUpgrade (maybeFU ((∃[ x ] BTree x r) ⁺× toFUpgrade (Bin-BHeap r))) | |
| extract' : {r : ℕ} (b : Bin) → BHeap' r b → Maybe' (λ b' → (∃[ x ] BTree x r) × BHeap' r b') (decr b) | |
| extract' ._ nul = nothing | |
| extract' ._ (zero h) = mapMaybe' (λ { ((x , node a (t , ts)) , h) → < node {x} a ts > , one t h }) (extract' _ h) | |
| extract' ._ (one t h) = just (< t > , zero h) | |
| extract : {r : ℕ} → BHeap r → Maybe ((∃[ x ] BTree x r) × BHeap r) | |
| extract = Upgrade.u decr-extract-upg decr extract' | |
| decr-extract-coherence : {r : ℕ} (h : BHeap r) → mapMaybe (toBin ∘ proj₂) (extract h) ≡ decr (toBin h) | |
| decr-extract-coherence h = Upgrade.c decr-extract-upg decr extract' _ h refl | |
| first : {r : ℕ} → BHeap r → Maybe (∃[ x ] ∃[ r' ] BTree x r') | |
| first nul = nothing | |
| first (zero h) = first h | |
| first (one t h) = just < < t > > | |
| extract-first : {r : ℕ} (h : BHeap r) → mapMaybe (root ∘ proj₂ ∘ proj₁) (extract h) ≡ mapMaybe (root ∘ proj₂ ∘ proj₂) (first h) | |
| extract-first nul = refl | |
| extract-first (zero h) with extract-first h | |
| extract-first (zero h) | eq with extract' (toBin h) (fromBHeap h) | |
| extract-first (zero h) | eq | _ with decr (toBin h) | |
| extract-first (zero h) | eq | nothing | nothing = eq | |
| extract-first (zero h) | eq | just ((x , node a (t , ts)) , h') | just b = eq | |
| extract-first (one t h) = refl | |
| -------- | |
| -- minimum extraction | |
| {- | |
| replace : {x y : V} {r : ℕ} (k : ℕ) → BTree x r → BTree y (k + r) → BTree y r × (∃[ z ] BTree z (k + r)) | |
| replace zero t u = u , < t > | |
| replace (suc k) t (node b (u , us)) = (id ** (attach' u ∘ proj₂)) (replace k t (node b us)) | |
| replace-lemma : {x y : V} {r : ℕ} (k : ℕ) (t : BTree x r) (u : BTree y (k + r)) → root (proj₁ (replace k t u)) ≡ root u | |
| replace-lemma zero t u = refl | |
| replace-lemma (suc k) t (node b (u , us)) = replace-lemma k t (node b us) | |
| -} | |
| -- ornamentation of BHeap | |
| data BHeap'' : ℕ → Maybe V → Set where | |
| nul : {r : ℕ} → BHeap'' r nothing | |
| zero : {r : ℕ} {ma : Maybe V} (h : BHeap'' (suc r) ma) → BHeap'' r ma | |
| oneᶠ : {r : ℕ} {x : V} (t : BTree x r) (h : BHeap'' (suc r) nothing) → BHeap'' r (just (root t)) | |
| oneᵗʰ : {r : ℕ} {x : V} (t : BTree x r) {a : V} (h : BHeap'' (suc r) (just a)) {{leq : root t ≤ a}} → BHeap'' r (just (root t)) | |
| oneᵗᵗ : {r : ℕ} {x : V} (t : BTree x r) {a : V} (h : BHeap'' (suc r) (just a)) {{leq : a ≤ root t}} → BHeap'' r (just a) | |
| -- free | |
| fromBHeap'' : {r : ℕ} {ma : Maybe V} → BHeap'' r ma → BHeap r | |
| fromBHeap'' nul = nul | |
| fromBHeap'' (zero h) = zero (fromBHeap'' h) | |
| fromBHeap'' (oneᶠ t h) = one t (fromBHeap'' h) | |
| fromBHeap'' (oneᵗʰ t h) = one t (fromBHeap'' h) | |
| fromBHeap'' (oneᵗᵗ t h) = one t (fromBHeap'' h) | |
| _∈ᵀ_ : V → {r : ℕ} → BHeap r → Set | |
| a ∈ᵀ nul = ⊥ | |
| a ∈ᵀ zero h = a ∈ᵀ h | |
| a ∈ᵀ one u h = a ≡ root u ⊎ a ∈ᵀ h | |
| empty-heap : {r : ℕ} (h : BHeap'' r nothing) → {a : V} → ¬ (a ∈ᵀ fromBHeap'' h) | |
| empty-heap nul () | |
| empty-heap (zero h) i = empty-heap h i | |
| root-element : {r : ℕ} {a : V} (h : BHeap'' r (just a)) → a ∈ᵀ fromBHeap'' h | |
| root-element (zero h) = root-element h | |
| root-element (oneᶠ t h) = inj₁ refl | |
| root-element (oneᵗʰ t h) = inj₁ refl | |
| root-element (oneᵗᵗ t h) = inj₂ (root-element h) | |
| _≤ᵀ_ : (a : V) {r : ℕ} (h : BHeap r) → Set | |
| a ≤ᵀ h = {b : V} → b ∈ᵀ h → a ≤ b | |
| lower-bound : {r : ℕ} {a : V} (h : BHeap'' r (just a)) → a ≤ᵀ fromBHeap'' h | |
| lower-bound (zero h) i = lower-bound h i | |
| lower-bound (oneᶠ t h) (inj₁ refl) = ≤-refl | |
| lower-bound (oneᶠ t h) (inj₂ i ) = ⊥-elim (empty-heap h i) | |
| lower-bound (oneᵗʰ t h) (inj₁ refl) = ≤-refl | |
| lower-bound (oneᵗʰ t h) (inj₂ i ) = ≤-trans - (lower-bound h i) | |
| lower-bound (oneᵗᵗ t h) (inj₁ refl) = - | |
| lower-bound (oneᵗᵗ t h) (inj₂ i ) = lower-bound h i | |
| _IsMinRootOf_ : (a : V) {r : ℕ} (h : BHeap r) → Set | |
| a IsMinRootOf h = a ∈ᵀ h × a ≤ᵀ h | |
| minimum-root : {r : ℕ} {a : V} (h : BHeap'' r (just a)) → a IsMinRootOf (fromBHeap'' h) | |
| minimum-root h = root-element h , lower-bound h | |
| toBHeap'' : {r : ℕ} → BHeap r → ∃[ ma ] BHeap'' r ma | |
| toBHeap'' nul = < nul > | |
| toBHeap'' (zero h) = (id ** zero) (toBHeap'' h) | |
| toBHeap'' (one t h) with toBHeap'' h | |
| toBHeap'' (one t h) | nothing , h' = < oneᶠ t h' > | |
| toBHeap'' (one t h) | just a , h' = if root t ≤? a then < oneᵗʰ t h' > else < oneᵗᵗ t h' > | |
| -- free, if toBHeap'' is defined in terms of the optimised predicate | |
| fromBHeap''-toBHeap''-inverse : {r : ℕ} (h : BHeap r) → fromBHeap'' (proj₂ (toBHeap'' h)) ≡ h | |
| fromBHeap''-toBHeap''-inverse nul = refl | |
| fromBHeap''-toBHeap''-inverse (zero h) = cong zero (fromBHeap''-toBHeap''-inverse h) | |
| fromBHeap''-toBHeap''-inverse (one t h) with fromBHeap''-toBHeap''-inverse h | |
| fromBHeap''-toBHeap''-inverse (one t h) | eq with toBHeap'' h | |
| fromBHeap''-toBHeap''-inverse (one t h) | eq | nothing , h' = cong (one t) eq | |
| fromBHeap''-toBHeap''-inverse {r} (one t h) | eq | just a , h' = | |
| if-elim {C = ∃[ ma ] BHeap'' r ma} (root t ≤? a) < oneᵗʰ t h' > < oneᵗᵗ t h' > | |
| (λ w → fromBHeap'' (proj₂ w) ≡ one t h) (cong (one t) eq) (cong (one t) eq) | |
| regular : {r : ℕ} {ma : Maybe V} → BHeap'' r ma → Bool | |
| regular nul = true | |
| regular (zero h) = regular h | |
| regular (oneᶠ t h) = true | |
| regular (oneᵗʰ t h) = true | |
| regular (oneᵗᵗ t h) = false | |
| {- | |
| postulate | |
| regularise-aux : {r : ℕ} {a : V} (h : BHeap'' (suc r) (just a)) → | |
| Σ (Σ (∃[ x ] BTree x r) (λ { < u > → root u ≡ a })) | |
| (λ { < < u > >' → {x : V} (t : BTree x r) {{leq : a ≤ root t}} → ∃[ b ] BHeap'' (suc r) (just b) × a ≤ b }) | |
| -} | |
| attach'' : {x y : V} {r : ℕ} (t : BTree x r) (u : BTree y r) {{leq : x ≤ root u}} → Σ[ t ∈ BTree _ (suc r) ] x ≤ root t | |
| attach'' t u = attach t u , attach-root t u (bound-root t ≤-refl) - | |
| -- takes a (relatively) long time to typecheck | |
| regularise-aux : {r : ℕ} {a : V} (h : BHeap'' (suc r) (just a)) → | |
| Σ (Σ (∃[ x ] BTree x r) (λ { < u > → root u ≡ a })) | |
| (λ { < < u > >' → {x : V} (t : BTree x r) {{leq : a ≤ root t}} → ∃[ b ] BHeap'' (suc r) (just b) × a ≤ b }) | |
| regularise-aux (zero h) with regularise-aux h | |
| regularise-aux (zero h) | < x , node a (u , us) >ʳ , f = < x , node a us >ʳ , | |
| λ t → let < t' >' = attach'' u t | |
| < < h' >' > = f t' | |
| in < zero h' , - > | |
| regularise-aux (oneᶠ {x = x} (node c (v , vs)) h) = < x , node c vs >ʳ , | |
| λ t → let < t' >' = attach'' v t | |
| in < oneᶠ t' h , - > | |
| regularise-aux (oneᵗʰ {x = x} (node c (v , vs)) {a} h) = < x , node c vs >ʳ , | |
| λ t → let < t' >' = attach'' v t | |
| in if root t' ≤? a then < oneᵗʰ t' h , - > | |
| else < oneᵗᵗ t' h , - > | |
| regularise-aux (oneᵗᵗ v h) with regularise-aux h | |
| regularise-aux (oneᵗᵗ v h) | < x , node a (u , us) >ʳ , f = < x , node a us >ʳ , | |
| λ t → let < t' >' = attach'' u t | |
| (b , < h' >') = f t' | |
| in if root v ≤? b then < oneᵗʰ v h' , - > | |
| else < oneᵗᵗ v h' , - > | |
| regularise : {r : ℕ} {ma : Maybe V} → BHeap'' r ma → Σ[ h ∈ BHeap'' r ma ] regular h ≡ true | |
| regularise nul = < nul >ʳ | |
| regularise (zero h) = (zero ** id) (regularise h) | |
| regularise (oneᶠ t h) = < oneᶠ t h >ʳ | |
| regularise (oneᵗʰ t h) = < oneᵗʰ t h >ʳ | |
| regularise (oneᵗᵗ t h) with regularise-aux h | |
| regularise (oneᵗᵗ t h) | < x , node a us >ʳ , f = let < < h' >' > = f t in < oneᵗʰ {x = x} (node a us) h' >ʳ | |
| regular-first : {r : ℕ} {ma : Maybe V} (h : BHeap'' r ma) → regular h ≡ true → | |
| mapMaybe (root ∘ proj₂ ∘ proj₂) (first (fromBHeap'' h)) ≡ ma | |
| regular-first nul eq = refl | |
| regular-first (zero h) eq = regular-first h eq | |
| regular-first (oneᶠ t h) eq = refl | |
| regular-first (oneᵗʰ t h) eq = refl | |
| regular-first (oneᵗᵗ t h) () | |
| extractMin : {r : ℕ} → BHeap r → Maybe ((∃[ x ] BTree x r) × BHeap r) | |
| extractMin = extract ∘ fromBHeap'' ∘ proj₁ ∘ regularise ∘ proj₂ ∘ toBHeap'' | |
| extractMin-nothing : {r : ℕ} (h : BHeap r) → mapMaybe (root ∘ proj₂ ∘ proj₁) (extractMin h) ≡ nothing → {a : V} → ¬ (a ∈ᵀ h) | |
| extractMin-nothing h eq with fromBHeap''-toBHeap''-inverse h | |
| extractMin-nothing h eq | eq' with toBHeap'' h | |
| extractMin-nothing h eq | eq' | ma , h'' with trans (sym (regular-first (proj₁ (regularise h'')) (proj₂ (regularise h'')))) | |
| (trans (sym (extract-first (fromBHeap'' (proj₁ (regularise h''))))) eq) | |
| extractMin-nothing ._ eq | refl | nothing , h'' | _ = empty-heap h'' | |
| extractMin-nothing h eq | eq' | just a , h'' | () | |
| extractMin-just : {r : ℕ} (h : BHeap r) {a : V} → mapMaybe (root ∘ proj₂ ∘ proj₁) (extractMin h) ≡ just a → a IsMinRootOf h | |
| extractMin-just h eq with fromBHeap''-toBHeap''-inverse h | |
| extractMin-just h eq | eq' with toBHeap'' h | |
| extractMin-just h eq | eq' | ma , h'' with trans (sym (regular-first (proj₁ (regularise h'')) (proj₂ (regularise h'')))) | |
| (trans (sym (extract-first (fromBHeap'' (proj₁ (regularise h''))))) eq) | |
| extractMin-just h eq | eq' | nothing , h'' | () | |
| extractMin-just ._ eq | refl | just a , h'' | refl = minimum-root h'' | |
| {- | |
| _∈ᵀ_ : {x : V} {r : ℕ} → BTree x r → {r' : ℕ} → BHeap r' → Set | |
| t ∈ᵀ nul = ⊥ | |
| t ∈ᵀ zero h = t ∈ᵀ h | |
| t ∈ᵀ one u h = (((Σ[ x ∈ V ] Σ[ r ∈ ℕ ] BTree x r) ∋ < < t > >) ≡ < < u > >) ⊎ t ∈ᵀ h | |
| _Below_ : {x : V} {r : ℕ} (t : BTree x r) {r' : ℕ} (h : BHeap r') → Set | |
| t Below h = {y : V} {r'' : ℕ} {u : BTree y r''} → u ∈ᵀ h → root t ≤ root u | |
| findMin : {r : ℕ} (h : BHeap r) → | |
| Maybe (Σ (Σ[ x ∈ V ] Σ[ r' ∈ ℕ ] BTree x r') λ { < < t > > → t ∈ᵀ h × t Below h }) | |
| findMin nul = nothing | |
| findMin (zero h) = findMin h | |
| findMin (one t h) = mapMaybe (λ { (< < u > > , i , leqs) → | |
| if root t ≤? root u | |
| then (λ {{leq}} → < < t > > , inj₁ refl , | |
| λ { {._} {._} {._} (inj₁ refl) → ≤-refl | |
| ; (inj₂ j) → ≤-trans leq (leqs j) }) | |
| else (λ {{leq}} → < < u > > , inj₂ i , | |
| λ { {._} {._} {._} (inj₁ refl) → leq; (inj₂ j) → leqs j}) }) | |
| (findMin h) | |
| -} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment