aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BinaryHeap/Aux.lean35
1 files changed, 26 insertions, 9 deletions
diff --git a/BinaryHeap/Aux.lean b/BinaryHeap/Aux.lean
index b57130a..16d7e94 100644
--- a/BinaryHeap/Aux.lean
+++ b/BinaryHeap/Aux.lean
@@ -21,11 +21,13 @@ instance : ForIn m (BinaryHeap α le n) α where
/-- Builds a Binary Heap from a list. -/
def ofList {α : Type u} {le : α → α → Bool} (h₁ : TotalAndTransitiveLe le) (l : List α) : BinaryHeap α le l.length :=
- let rec worker : (l : List α) → {n : Nat} → (BinaryHeap α le n) → (BinaryHeap α le (n + l.length)) := λ (l : List α) {n : Nat} (heap : BinaryHeap α le n) ↦
+ let rec worker : (l : List α) → {n : Nat} → (BinaryHeap α le n) → (BinaryHeap α le (l.length + n)) := λ (l : List α) {n : Nat} (heap : BinaryHeap α le n) ↦
match l with
- | [] => heap
- | a :: as => (Nat.add_comm_right n as.length 1).subst rfl ▸ worker as (heap.push a)
- Nat.zero_add l.length ▸ worker l $ BinaryHeap.new h₁
+ | [] => Nat.zero_add _ ▸ heap
+ | a :: as =>
+ have : (a :: as).length + n = as.length + n + 1 := by simp +arith
+ this ▸ worker as (heap.push a)
+ worker l $ BinaryHeap.new h₁
/-- Converts the tree to a sorted list. -/
def toList (heap : BinaryHeap α le n) : List α :=
@@ -76,11 +78,26 @@ def fold (f : α → β → α) (init : α) (heap : BinaryHeap β le n) : α :=
def map {α : Type u} {le₀ : α → α → Bool } {β : Type u₁} {le : β → β → Bool} (h₁ : TotalAndTransitiveLe le) (f : α → β) : (h : BinaryHeap α le₀ n) → BinaryHeap β le n
| { tree, .. } =>
-- no need to do this in-order.
- let rec worker : (o p : Nat) → (CompleteTree α o) → (BinaryHeap β le p) → (BinaryHeap β le (p + o)) := λ o p t h ↦
+ let rec worker : (o p : Nat) → (CompleteTree α o) → (BinaryHeap β le p) → (BinaryHeap β le (o+p)) := λ o p t h ↦
match o, t with
- | 0, .leaf => h
+ | 0, .leaf => (Nat.add_comm _ _)▸h
| (q+r+1), .branch v left right _ _ _ =>
let left_result := worker q p left h
- let right_result := worker r (p+q) right left_result
- (Nat.add_assoc _ _ _▸right_result).push (f v)
- (Nat.zero_add _)▸worker n 0 tree $ BinaryHeap.new h₁
+ let right_result := worker r (q+p) right left_result
+ have : r + (q + p) + 1 = q+r+1+p := by simp +arith
+ this▸(right_result).push (f v)
+ worker n 0 tree $ BinaryHeap.new h₁
+
+private theorem toList.worker.len_const (l : List α) {n : Nat} (h : BinaryHeap α le n) : (BinaryHeap.toList.worker l h).length = l.length + n :=
+ match n with
+ | 0 => List.length_reverse.subst rfl
+ | (m+1) => (toList.worker.len_const (h.pop.fst :: l) (h.pop.snd))
+ |> List.length_cons.subst (motive := λx ↦ _ = x + _)
+ |> (Nat.add_assoc l.length 1 m).subst
+ |> (Nat.add_comm 1 m).subst (motive := λx ↦ _ = _ + (x))
+
+theorem toList_len_eq (h : BinaryHeap α le n) : h.toList.length = n :=
+ match n with
+ | 0 => rfl
+ | (m+1) => toList.worker.len_const [h.pop.fst] h.pop.snd
+ |> (Nat.add_comm 1 m).subst