diff options
| author | Andreas Grois <andi@grois.info> | 2024-08-27 22:59:11 +0200 | 
|---|---|---|
| committer | Andreas Grois <andi@grois.info> | 2024-08-27 22:59:11 +0200 | 
| commit | b1821bdf7fb928be27a9919f4969883a2f6670ff (patch) | |
| tree | 0597222a585b1e34c733390068ed9f35ad55bec1 | |
| parent | 3bdc50ac878c1b6d066a342d2b4909b1b4e841d9 (diff) | |
Simplify CompleteTree.get, and remove (redundant) CompleteTree.get'
| -rw-r--r-- | BinaryHeap.lean | 6 | ||||
| -rw-r--r-- | BinaryHeap/CompleteTree/AdditionalOperations.lean | 27 | ||||
| -rw-r--r-- | BinaryHeap/CompleteTree/AdditionalProofs/Contains.lean | 213 | ||||
| -rw-r--r-- | BinaryHeap/CompleteTree/AdditionalProofs/Find.lean | 4 | ||||
| -rw-r--r-- | BinaryHeap/CompleteTree/AdditionalProofs/Get.lean | 174 | ||||
| -rw-r--r-- | BinaryHeap/CompleteTree/AdditionalProofs/HeapPop.lean | 2 | ||||
| -rw-r--r-- | BinaryHeap/CompleteTree/AdditionalProofs/HeapPush.lean | 4 | ||||
| -rw-r--r-- | BinaryHeap/CompleteTree/AdditionalProofs/HeapRemoveAt.lean | 18 | ||||
| -rw-r--r-- | BinaryHeap/CompleteTree/AdditionalProofs/HeapRemoveLast.lean | 98 | ||||
| -rw-r--r-- | BinaryHeap/CompleteTree/AdditionalProofs/HeapUpdateAt.lean | 31 | ||||
| -rw-r--r-- | BinaryHeap/CompleteTree/AdditionalProofs/HeapUpdateRoot.lean | 95 | 
11 files changed, 251 insertions, 421 deletions
diff --git a/BinaryHeap.lean b/BinaryHeap.lean index 61ebd42..4c7326f 100644 --- a/BinaryHeap.lean +++ b/BinaryHeap.lean @@ -53,12 +53,10 @@ def indexOf {α : Type u} {le : α → α → Bool} {n : Nat} : BinaryHeap α le    tree.indexOf pred  instance : GetElem (BinaryHeap α le n) (Nat) α (λ _ index ↦ index < n) where -  getElem := λ heap index h₁ ↦ match n, heap, index with -  | (_+1), {tree, ..}, index => tree.get' ⟨index, h₁⟩ +  getElem := λ heap index h₁ ↦ heap.tree.get ⟨index, h₁⟩  instance : GetElem (BinaryHeap α le n) (Fin n) α (λ _ _ ↦ True) where -  getElem := λ heap index _ ↦ match n, heap, index with -  | (_+1), {tree, ..}, index => tree.get' index +  getElem := λ heap index _ ↦ heap.tree.get index  /--Helper for the common case of using natural numbers for sorting.-/  theorem nat_ble_to_heap_le_total : total_le Nat.ble := diff --git a/BinaryHeap/CompleteTree/AdditionalOperations.lean b/BinaryHeap/CompleteTree/AdditionalOperations.lean index ee6b685..8038555 100644 --- a/BinaryHeap/CompleteTree/AdditionalOperations.lean +++ b/BinaryHeap/CompleteTree/AdditionalOperations.lean @@ -32,27 +32,16 @@ def indexOf {α : Type u} (heap : CompleteTree α o) (pred : α → Bool) : Opti  ----------------------------------------------------------------------------------------------  -- get -/--Returns the lement at the given index. Indices are depth first.-/ -def get' {α : Type u} {n : Nat} (index : Fin (n+1)) (heap : CompleteTree α (n+1)) : α := -  match h₁ : index, h₂ : n, heap with -  | 0, (_+_), .branch v _ _ _ _ _ => v -  | ⟨j+1,h₃⟩, (o+p), .branch _ l r _ _ _ => -    if h₄ : j < o then -      match o with -      | (oo+1) => get' ⟨j, h₄⟩ l -    else -      have h₅ : n - o = p := Nat.sub_eq_of_eq_add $ (Nat.add_comm o p).subst h₂ -      have : p ≠ 0 := -        have h₆ : o < n := Nat.lt_of_le_of_lt (Nat.ge_of_not_lt h₄) (Nat.lt_of_succ_lt_succ h₃) -        h₅.symm.substr $ Nat.sub_ne_zero_of_lt h₆ -      have h₆ : j - o < p := h₅.subst $ Nat.sub_lt_sub_right (Nat.ge_of_not_lt h₄) $ Nat.lt_of_succ_lt_succ h₃ -      have _termination : j - o < index.val := (Fin.val_inj.mpr h₁).substr (Nat.sub_lt_succ j o) -      match p with -      | (pp + 1) => get' ⟨j - o, h₆⟩ r - +/--Returns the element at the given index. Indices are depth first.-/  def get {α : Type u} {n : Nat} (index : Fin n) (heap : CompleteTree α n) : α :=    match n, index, heap with -  | (_+1), index, heap => heap.get' index +  | (_+_+1), 0, .branch v _ _ _ _ _ => v +  | (o+p+1), ⟨j+1,h₃⟩, .branch _ l r _ _ _ => +    if h₄ : j < o then +      get ⟨j, h₄⟩ l +    else +      have h₄ : j - o < p := Nat.sub_lt_left_of_lt_add (Nat.ge_of_not_lt h₄) $ Nat.lt_of_succ_lt_succ h₃ +      get ⟨j - o, h₄⟩ r  ----------------------------------------------------------------------------------------------  -- contains - implemented as decidable proposition diff --git a/BinaryHeap/CompleteTree/AdditionalProofs/Contains.lean b/BinaryHeap/CompleteTree/AdditionalProofs/Contains.lean index 6614210..7a0c893 100644 --- a/BinaryHeap/CompleteTree/AdditionalProofs/Contains.lean +++ b/BinaryHeap/CompleteTree/AdditionalProofs/Contains.lean @@ -3,93 +3,46 @@ import BinaryHeap.CompleteTree.AdditionalProofs.Get  namespace BinaryHeap.CompleteTree.AdditionalProofs -private theorem if_get_eq_contains {α : Type u} {o : Nat} (tree : CompleteTree α (o+1)) (element : α) (index : Fin (o+1)) : tree.get' index = element → tree.contains element := by -    unfold get' contains -    simp only [Nat.succ_eq_add_one, Fin.zero_eta, Nat.add_eq, ne_eq] -    split -    case h_1 p q v l r _ _ _ _ => -      intro h₁ -      split; omega -      rename α => vv -      rename_i hsum heq -      have h₂ := heqSameRoot (hsum) (Nat.succ_pos (p+q)) heq -      rw[root_unfold] at h₂ -      rw[root_unfold] at h₂ -      simp only [←h₂, h₁, true_or] -    case h_2 index p q v l r _ _ _ _ h₃ => -      intro h₄ -      split ; rename_i hx _; exact absurd hx (Nat.succ_ne_zero _) -      case h_2 pp qq vv ll rr _ _  _ h₅ heq => -      have : p = pp := heqSameLeftLen h₅ (Nat.succ_pos _) heq -      have : q = qq := heqSameRightLen h₅ (Nat.succ_pos _) heq -      subst pp qq -      simp only [Nat.add_eq, Nat.succ_eq_add_one, heq_eq_eq, branch.injEq] at heq -      have : v = vv := heq.left -      have : l = ll := heq.right.left -      have : r = rr := heq.right.right -      subst vv ll rr -      revert h₄ -      split -      all_goals -        split -        intro h₄ -        right +private theorem if_get_eq_contains {α : Type u} {n : Nat} (tree : CompleteTree α n) (element : α) (index : Fin n) : tree.get index = element → tree.contains element := by +    rw[get_unfold] +    rw[contains_as_root_left_right] +    intro h₁ +    split at h₁ +    case isTrue => +      left +      assumption +    case isFalse h => +      have _termination : index.val ≠ 0 := Fin.val_ne_iff.mpr h +      right +      simp only at h₁ +      split at h₁        case' isTrue => left        case' isFalse => right        all_goals -        revert h₄ +        revert h₁          apply if_get_eq_contains -        done +termination_by index.val -private theorem if_contains_get_eq_auxl {α : Type u} {o : Nat} (tree : CompleteTree α (o+1)) (element : α) : -  ∀(indexl : Fin (tree.leftLen (Nat.succ_pos o))), (tree.left _).get indexl = element → ∃(index : Fin (o+1)), tree.get index = element +private theorem if_contains_get_eq_auxl {α : Type u} {n : Nat} (tree : CompleteTree α n) (element : α) (h₁ : n > 0): +  ∀(indexl : Fin (tree.leftLen h₁)), (tree.left _).get indexl = element → ∃(index : Fin n), tree.get index = element  := by    intro indexl -  let index : Fin (o+1) := indexl.succ.castLT (by -    simp only [Nat.succ_eq_add_one, Fin.val_succ, Nat.succ_lt_succ_iff, gt_iff_lt] -    exact Nat.lt_of_lt_of_le indexl.isLt $ Nat.le_of_lt_succ $ leftLenLtN tree (Nat.succ_pos o) -  ) +  let index : Fin n := indexl.succ.castLT (Nat.lt_of_le_of_lt (Nat.succ_le_of_lt indexl.isLt) (leftLenLtN tree h₁))    intro prereq    exists index -  unfold get -  simp -  unfold get' -  generalize hindex : index = i -  split -  case h_1 => -    have : index.val = 0 := Fin.val_eq_of_eq hindex -    contradiction -  case h_2 j p q v l r ht1 ht2 ht3 _ _ => -    have h₂ : index.val = indexl.val + 1 := rfl -    have h₃ : index.val = j.succ := Fin.val_eq_of_eq hindex -    have h₄ : j = indexl.val := Nat.succ.inj $ h₃.subst (motive := λx↦ x = indexl.val + 1) h₂ -    have : p = (branch v l r ht1 ht2 ht3).leftLen (Nat.succ_pos _) := rfl -    have h₅ : j < p := by simp only [this, indexl.isLt, h₄] -    simp only [h₅, ↓reduceDIte, Nat.add_eq] -    unfold get at prereq -    split at prereq -    rename_i pp ii ll hel hei heq -    split -    rename_i ppp lll _ _ _ _ _ _ -    have : pp = ppp := by omega -    subst pp -    simp only [gt_iff_lt, Nat.succ_eq_add_one, Nat.add_eq, heq_eq_eq, Nat.zero_lt_succ] at * -    have : j = ii.val := by omega -    subst j -    simp -    rw[←hei] at prereq -    rw[left_unfold] at heq -    rw[heq] -    assumption +  have h₂ : index > ⟨0,h₁⟩ := Nat.zero_lt_of_ne_zero $ Fin.val_ne_iff.mpr $ Fin.succ_ne_zero _ +  have h₃ : index.val ≤ tree.leftLen h₁ := Nat.succ_le_of_lt indexl.isLt +  rw[get_left _ _ h₂ h₃] +  exact prereq -private theorem if_contains_get_eq_auxr {α : Type u} {o : Nat} (tree : CompleteTree α (o+1)) (element : α) : -  ∀(indexl : Fin (tree.rightLen (Nat.succ_pos o))), (tree.right _).get indexl = element → ∃(index : Fin (o+1)), tree.get index = element +private theorem if_contains_get_eq_auxr {α : Type u} {n : Nat} (tree : CompleteTree α n) (element : α) (h₁ : n > 0): +  ∀(indexr : Fin (tree.rightLen h₁)), (tree.right _).get indexr = element → ∃(index : Fin n), tree.get index = element  := by    intro indexr -  let index : Fin (o+1) := ⟨(tree.leftLen (Nat.succ_pos o) + indexr.val + 1), by -    have h₂ : tree.leftLen (Nat.succ_pos _) + tree.rightLen _ + 1 = tree.length := Eq.symm $ lengthEqLeftRightLenSucc tree _ +  let index : Fin n := ⟨(tree.leftLen h₁ + indexr.val + 1), by +    have h₂ : tree.leftLen h₁ + tree.rightLen _ + 1 = tree.length := Eq.symm $ lengthEqLeftRightLenSucc tree _      rw[length] at h₂ -    have h₃ : tree.leftLen (Nat.succ_pos o) + indexr.val + 1 < tree.leftLen (Nat.succ_pos o) + tree.rightLen (Nat.succ_pos o) + 1 := by +    have h₃ : tree.leftLen h₁ + indexr.val + 1 < tree.leftLen h₁ + tree.rightLen h₁ + 1 := by        apply Nat.succ_lt_succ        apply Nat.add_lt_add_left        exact indexr.isLt @@ -97,95 +50,39 @@ private theorem if_contains_get_eq_auxr {α : Type u} {o : Nat} (tree : Complete    ⟩    intro prereq    exists index -  unfold get -  simp -  unfold get' -  generalize hindex : index = i -  split -  case h_1 => -    have : index.val = 0 := Fin.val_eq_of_eq hindex -    contradiction -  case h_2 j p q v l r ht1 ht2 ht3 _ _ => -    have h₂ : index.val = (branch v l r ht1 ht2 ht3).leftLen (Nat.succ_pos _) + indexr.val + 1 := rfl -    have h₃ : index.val = j.succ := Fin.val_eq_of_eq hindex -    have h₄ : j = (branch v l r ht1 ht2 ht3).leftLen (Nat.succ_pos _) + indexr.val := by -      rw[h₃] at h₂ -      exact Nat.succ.inj h₂ -    have : p = (branch v l r ht1 ht2 ht3).leftLen (Nat.succ_pos _) := rfl -    have h₅ : ¬(j < p) := by simp_arith [this, h₄] -    simp only [h₅, ↓reduceDIte, Nat.add_eq] -    unfold get at prereq -    split at prereq -    rename_i pp ii rr hel hei heq -    split -    rename_i ppp rrr _ _ _ _ _ _ _ -    have : pp = ppp := by rw[rightLen_unfold] at hel; exact Nat.succ.inj hel.symm -    subst pp -    simp only [gt_iff_lt, ne_eq, Nat.succ_eq_add_one, Nat.add_eq, Nat.reduceEqDiff, heq_eq_eq, Nat.zero_lt_succ] at * -    have : j = ii.val + p := by omega -    subst this -    simp -    rw[right_unfold] at heq -    rw[heq] -    assumption +  have h₂ : tree.leftLen h₁ < tree.leftLen h₁ + indexr.val + 1 := Nat.lt_of_le_of_lt (Nat.le_add_right _ _) (Nat.lt_succ_self _) +  rw[get_right _ index h₂] +  have : index.val - tree.leftLen h₁ - 1 = indexr.val := +    have : index.val = tree.leftLen h₁ + indexr.val + 1 := rfl +    have : index.val = indexr.val + tree.leftLen h₁ + 1 := (Nat.add_comm indexr.val (tree.leftLen h₁)).substr this +    have : index.val - (tree.leftLen h₁ + 1) = indexr.val := Nat.sub_eq_of_eq_add this +    (Nat.sub_sub _ _ _).substr this +  simp only[this] +  assumption -private theorem if_contains_get_eq {α : Type u} {o : Nat} (tree : CompleteTree α (o+1)) (element : α) (h₁ : tree.contains element) : ∃(index : Fin (o+1)), tree.get' index = element := by -    revert h₁ -    unfold contains -    split ; rename_i hx _; exact absurd hx (Nat.succ_ne_zero o) -    rename_i n m v l r _ _ _ he heq -    intro h₁ +private theorem if_contains_get_eq {α : Type u} {n : Nat} (tree : CompleteTree α n) (element : α) (h₁ : tree.contains element) : ∃(index : Fin n), tree.get index = element := by +    unfold contains at h₁ +    match n, tree with +    | 0, .leaf => contradiction +    | (o+p+1), .branch v l r o_le_p max_height_diff subtree_complete =>      cases h₁ -    case h_2.inl h₂ => -      unfold get' +    case inl h₂ =>        exists 0 -      split -      case h_2 hx => have hx := Fin.val_eq_of_eq hx; simp at hx; -      case h_1 vv _ _ _ _ _ _ _ => -        have h₃ := heqSameRoot he (Nat.succ_pos _) heq -        simp only[root_unfold] at h₃ -        simp only[h₃, h₂] -    rename_i h -    cases h -    case h_2.inr.inl h₂ => exact -      match hn : n, hl: l with -      | 0, .leaf => by contradiction -      | (nn+1), l => by -        have nn_lt_o : nn < o := by have : o = nn + 1 + m := Nat.succ.inj he; omega --also for termination -        have h₃ := if_contains_get_eq l element h₂ -        have h₄ := if_contains_get_eq_auxl tree element -        simp only at h₄ -        simp[get_eq_get'] at h₃ ⊢ -        apply h₃.elim -        match o, tree with -        | (yy+_), .branch _ ll _ _ _ _ => -          simp_all[left_unfold, leftLen_unfold] -          have : yy = nn+1 := heqSameLeftLen (by omega) (Nat.succ_pos _) heq -          have : _ = m := heqSameRightLen (by omega) (Nat.succ_pos _) heq -          subst yy m -          simp_all -          exact h₄ -    case h_2.inr.inr h₂ => exact -      match hm : m, hr: r with -      | 0, .leaf => by contradiction -      | (mm+1), r => by -        have mm_lt_o : mm < o := by have : o = n + (mm + 1) := Nat.succ.inj he; omega --termination -        have h₃ := if_contains_get_eq r element h₂ -        have h₄ := if_contains_get_eq_auxr tree element -        simp[get_eq_get'] at h₃ ⊢ -        apply h₃.elim -        match o, tree with -        | (_+zz), .branch _ _ rr _ _ _ => -          simp_all[right_unfold, rightLen_unfold] -          have : _ = n := heqSameLeftLen (by omega) (Nat.succ_pos _) heq -          have : zz = mm+1 := heqSameRightLen (by omega) (Nat.succ_pos _) heq -          subst n zz -          simp_all -          exact h₄ -  termination_by o +    case inr h₂ => +      cases h₂ +      case inl h₂ => +        have h₄ := if_contains_get_eq l element h₂ +        have h₅ := if_contains_get_eq_auxl (.branch v l r o_le_p max_height_diff subtree_complete) element (Nat.succ_pos _) +        apply h₄.elim +        assumption +      case inr h₂ => +        have h₄ := if_contains_get_eq r element h₂ +        have h₅ := if_contains_get_eq_auxr (.branch v l r o_le_p max_height_diff subtree_complete) element (Nat.succ_pos _) +        apply h₄.elim +        assumption -theorem contains_iff_index_exists' {α : Type u} {o : Nat} (tree : CompleteTree α (o+1)) (element : α) : tree.contains element ↔ ∃ (index : Fin (o+1)), tree.get' index = element := by +theorem contains_iff_index_exists' {α : Type u} {n : Nat} (tree : CompleteTree α n) (element : α) : tree.contains element ↔ ∃ (index : Fin n), tree.get index = element := by    constructor    case mpr =>      simp only [forall_exists_index] diff --git a/BinaryHeap/CompleteTree/AdditionalProofs/Find.lean b/BinaryHeap/CompleteTree/AdditionalProofs/Find.lean index 902afc4..32bf722 100644 --- a/BinaryHeap/CompleteTree/AdditionalProofs/Find.lean +++ b/BinaryHeap/CompleteTree/AdditionalProofs/Find.lean @@ -44,14 +44,14 @@ private theorem indexOfNoneImpPredFalseAux {α : Type u} {n : Nat} (tree : Compl      else        have h₃₂ : index > ⟨0,h₁⟩ := Fin.pos_iff_ne_zero.mpr h₃        if h₄ : index ≤ o then -        rw[get_left (.branch v l r p_le_o max_height_difference subtree_complete) _ h₁ h₃₂ h₄] +        rw[get_left (.branch v l r p_le_o max_height_difference subtree_complete) _ h₃₂ h₄]          rw[left_unfold]          have := indexOfNoneImpPredFalseAux l pred (currentIndex + 1)          simp only [Option.isNone_iff_eq_none, Bool.not_eq_true] at this          exact this h₂₂.left _        else          have h₄₂ : index > o := Nat.gt_of_not_le h₄ -        rw[get_right (.branch v l r p_le_o max_height_difference subtree_complete) _ (Nat.succ_pos _) h₄₂] +        rw[get_right (.branch v l r p_le_o max_height_difference subtree_complete) _ h₄₂]          rw[right_unfold]          have := indexOfNoneImpPredFalseAux r pred (currentIndex + o + 1)          simp only [Option.isNone_iff_eq_none, Bool.not_eq_true] at this diff --git a/BinaryHeap/CompleteTree/AdditionalProofs/Get.lean b/BinaryHeap/CompleteTree/AdditionalProofs/Get.lean index f872836..1012ef5 100644 --- a/BinaryHeap/CompleteTree/AdditionalProofs/Get.lean +++ b/BinaryHeap/CompleteTree/AdditionalProofs/Get.lean @@ -3,64 +3,39 @@ import BinaryHeap.CompleteTree.Lemmas  namespace BinaryHeap.CompleteTree.AdditionalProofs -theorem get_eq_get' {α : Type u} {n : Nat} (tree : CompleteTree α (n+1)) (index : Fin (n+1)) : tree.get' index = tree.get index := rfl +theorem get_zero_eq_root {α : Type u} {n : Nat} (tree : CompleteTree α n) (h₁ : n > 0): tree.root h₁ = tree.get ⟨0,h₁⟩ := +  match h₂ : n, h₃ : (⟨0,h₁⟩ : Fin n), tree with +  | (_+_+1), 0, .branch v _ _ _ _ _ => rfl +  | nn+1, ⟨j+1,h₄⟩, _ => by +    subst h₂ +    simp only [heq_eq_eq, Fin.ext_iff] at h₃ -theorem get_zero_eq_root {α : Type u} {n : Nat} (tree : CompleteTree α n) (h₁ : n > 0): tree.root h₁ = tree.get ⟨0,h₁⟩ := by -  unfold get -  match n with -  | nn+1 => -    unfold get' -    split -    case h_2 hx => exact absurd (Fin.mk.inj hx) (Nat.zero_ne_add_one _) -    case h_1 => trivial - -theorem get_right {α : Type u} {n : Nat} (tree : CompleteTree α n) (index : Fin n) (h₁ : n > 0) (h₂ : index > tree.leftLen h₁) : -  have h₃ : ↑index - tree.leftLen h₁ - 1 < tree.rightLen h₁ := by -    revert h₂ -    unfold leftLen rightLen length -    split -    intro h₂ -    rename_i o p v l r _ _ _ _ -    have h₃ := index.isLt -    apply Nat.sub_lt_right_of_lt_add -    omega -    apply Nat.sub_lt_right_of_lt_add -    omega -    have : p+1+o = (o.add p).succ := by simp_arith -    rw[this] -    assumption -  tree.get index = (tree.right h₁).get ⟨index.val - (tree.leftLen h₁) - 1, h₃⟩ -:= -  match n, tree with -  | (o+p+1), .branch v l r _ _ _ => by -    simp[right_unfold, leftLen_unfold] -    rw[leftLen_unfold] at h₂ -    generalize hnew : get ⟨↑index - o - 1, _⟩ r = new -    unfold get get' -    split -    case h_1 => -      contradiction -    case h_2 j h₃ o2 p2 v2 l2 r2 _ _ _ d1 he₁ he₂ _ => -      clear d1 -      have : o = o2 := heqSameLeftLen (congrArg Nat.succ he₁) (Nat.succ_pos _) he₂ -      have : p = p2 := heqSameRightLen (congrArg Nat.succ he₁) (Nat.succ_pos _) he₂ -      subst o2 p2 -      simp at he₂ -      have : v = v2 := he₂.left -      have : l = l2 := he₂.right.left -      have : r = r2 := he₂.right.right -      subst r2 l2 v2 -      simp_all -      have : ¬j < o := by simp_arith[h₂] -      simp[this] -      cases p <;> simp -      case zero => -        omega -      case succ pp _ _ _ _ _ _ => -        have : j + 1 - o - 1 = j - o := by omega -        simp[this] at hnew -        rw[get_eq_get'] -        assumption +theorem get_right {α : Type u} {n : Nat} (tree : CompleteTree α n) (index : Fin n) (h₂ : index > tree.leftLen (Nat.zero_lt_of_lt index.isLt)) +  : have h₁ : n > 0 := Nat.zero_lt_of_lt index.isLt +    have h₃ : ↑index - tree.leftLen h₁ - 1 < tree.rightLen h₁ := by +      revert h₂ +      unfold leftLen rightLen length +      split +      intro h₂ +      rename_i o p v l r _ _ _ +      have h₃ := index.isLt +      apply Nat.sub_lt_right_of_lt_add +      omega +      apply Nat.sub_lt_right_of_lt_add +      omega +      have : p+1+o = (o.add p).succ := by simp_arith +      rw[this] +      assumption +    tree.get index = (tree.right h₁).get ⟨index.val - (tree.leftLen h₁) - 1, h₃⟩ +  := +  match n, index, tree with +  | (o+p+1), ⟨j+1,h₃⟩, .branch _ _ r _ _ _ => +    if h₄ : j < o then +      absurd h₄ $ Nat.not_lt_of_ge (Nat.le_of_lt_succ h₂) +    else by +      simp only[right_unfold, leftLen_unfold] +      have : j + 1 - o - 1 = j - o := by omega +      simp (config := {autoUnfold := true})[this, h₄]  theorem get_right' {α : Type u} {n m : Nat} {v : α} {l : CompleteTree α n} {r : CompleteTree α m} {m_le_n : m ≤ n} {max_height_diff : n < 2 * (m + 1)} {subtree_complete : (n + 1).isPowerOfTwo ∨ (m + 1).isPowerOfTwo} (index : Fin (n + m + 1)) (h₁ : index > n) :    have h₂ : ↑index - n - 1 < m := by @@ -74,36 +49,73 @@ theorem get_right' {α : Type u} {n m : Nat} {v : α} {l : CompleteTree α n} {r      assumption    (branch v l r m_le_n max_height_diff subtree_complete).get index = r.get ⟨index.val - n - 1, h₂⟩  := -  get_right (branch v l r m_le_n max_height_diff subtree_complete) index (Nat.succ_pos _) h₁ +  get_right (branch v l r m_le_n max_height_diff subtree_complete) index h₁ -theorem get_left {α : Type u} {n : Nat} (tree : CompleteTree α n) (index : Fin n) (h₁ : n > 0) (h₂ : index > ⟨0, h₁⟩) (h₃ : index ≤ tree.leftLen h₁) : +theorem get_left {α : Type u} {n : Nat} (tree : CompleteTree α n) (index : Fin n) (h₂ : index > ⟨0, (Nat.zero_lt_of_lt index.isLt)⟩) (h₃ : index ≤ tree.leftLen (Nat.zero_lt_of_lt index.isLt)) : +  have h₁ : n > 0 := Nat.zero_lt_of_lt index.isLt    have h₃ : ↑index - 1 < tree.leftLen h₁ := Nat.lt_of_lt_of_le (Nat.pred_lt_self h₂) h₃    tree.get index = (tree.left h₁).get ⟨index.val - 1, h₃⟩  := -  match n, tree with -  | (o+p+1), .branch v l r _ _ _ => by -    simp[left_unfold] -    generalize hnew : get ⟨↑index - 1, _⟩ l = new -    unfold get get' -    split -    case h_1 => contradiction -    case h_2 j h₃ o2 p2 v2 l2 r2 _ _ _ d1 he₁ he₂ => -      clear d1 -      have : o = o2 := heqSameLeftLen (congrArg Nat.succ he₁) (Nat.succ_pos _) he₂ -      have : p = p2 := heqSameRightLen (congrArg Nat.succ he₁) (Nat.succ_pos _) he₂ -      subst o2 p2 -      simp[leftLen_unfold] at h₃ -      have h₄ : j < o :=Nat.lt_of_succ_le h₃ -      simp[h₄] -      cases o ; contradiction -      case succ oo => -        simp at hnew he₂ ⊢ -        have := he₂.right.left -        subst l2 -        assumption +    match n, index, tree with +  | (o+p+1), ⟨j+1,h₅⟩, .branch _ l _ _ _ _ => +    if h₄ : j < o then by +      simp only[left_unfold, leftLen_unfold] +      have : j + 1 - o - 1 = j - o := by omega +      simp (config := {autoUnfold := true})[this, h₄] +    else +      absurd (Nat.lt_of_succ_le h₃) h₄  theorem get_left' {α : Type u} {n m : Nat} {v : α} {l : CompleteTree α n} {r : CompleteTree α m} {m_le_n : m ≤ n} {max_height_diff : n < 2 * (m + 1)} {subtree_complete : (n + 1).isPowerOfTwo ∨ (m + 1).isPowerOfTwo} (index : Fin (n + m + 1)) (h₁ : index > ⟨0, Nat.succ_pos _⟩) (h₂ : index ≤ n) :    have h₃ : ↑index - 1 < n := Nat.lt_of_lt_of_le (Nat.pred_lt_self h₁) h₂    (branch v l r m_le_n max_height_diff subtree_complete).get index = l.get ⟨index.val - 1, h₃⟩  := -  get_left (branch v l r m_le_n max_height_diff subtree_complete) index (Nat.succ_pos _) h₁ h₂ +  get_left (branch v l r m_le_n max_height_diff subtree_complete) index h₁ h₂ + +theorem get_unfold {α : Type u} {n : Nat} (tree : CompleteTree α n) (index : Fin n) +  : +  have h₁ : n > 0 := (Nat.zero_lt_of_lt index.isLt) +  tree.get index = +    if h₂ : index = ⟨0, h₁⟩ then +      tree.root h₁ +    else if h₃ : index ≤ tree.leftLen h₁ then +      have h₃ : ↑index - 1 < tree.leftLen h₁ := Nat.lt_of_lt_of_le (Nat.pred_lt_self $ Nat.zero_lt_of_ne_zero $ Fin.val_ne_iff.mpr h₂) h₃ +      (tree.left h₁).get ⟨index.val - 1, h₃⟩ +    else +      have h₃ : ↑index - tree.leftLen h₁ - 1 < tree.rightLen h₁ := by +        revert h₃ +        unfold leftLen rightLen length +        split +        intro h₂ +        rename_i o p v l r _ _ _ _ _ +        have h₃ := index.isLt +        apply Nat.sub_lt_right_of_lt_add +        omega +        apply Nat.sub_lt_right_of_lt_add +        omega +        have : p+1+o = (o.add p).succ := by simp_arith +        rw[this] +        assumption +      (tree.right h₁).get ⟨index.val - (tree.leftLen h₁) - 1, h₃⟩ +  := +  have h₁ : n > 0 := (Nat.zero_lt_of_lt index.isLt) +  if h₂ : index = ⟨0, h₁⟩ then by +    simp only [h₂] +    exact Eq.symm $ get_zero_eq_root _ _ +  else if h₃ : index ≤ tree.leftLen h₁ then by +    simp [h₂, h₃] +    exact get_left tree index (Nat.zero_lt_of_ne_zero $ Fin.val_ne_iff.mpr h₂) h₃ +  else by +    simp [h₂, h₃] +    exact get_right tree index (Nat.gt_of_not_le h₃) + +theorem get_unfold' {α : Type u} {n m : Nat} {v : α} {l : CompleteTree α n} {r : CompleteTree α m} {m_le_n : m ≤ n} {max_height_diff : n < 2 * (m + 1)} {subtree_complete : (n + 1).isPowerOfTwo ∨ (m + 1).isPowerOfTwo} (index : Fin (n + m + 1)) : +  (branch v l r m_le_n max_height_diff subtree_complete).get index = if h₂ : index = ⟨0, Nat.zero_lt_of_lt index.isLt⟩ then +      v +    else if h₃ : index ≤ n then +      have h₃ : ↑index - 1 < n := Nat.lt_of_lt_of_le (Nat.pred_lt_self $ Nat.zero_lt_of_ne_zero $ Fin.val_ne_iff.mpr h₂) h₃ +      l.get ⟨index.val - 1, h₃⟩ +    else +      have h₃ : ↑index - n - 1 < m := by omega +      r.get ⟨index.val - n - 1, h₃⟩ +  := +    get_unfold _ _ diff --git a/BinaryHeap/CompleteTree/AdditionalProofs/HeapPop.lean b/BinaryHeap/CompleteTree/AdditionalProofs/HeapPop.lean index 807bdcb..09b1450 100644 --- a/BinaryHeap/CompleteTree/AdditionalProofs/HeapPop.lean +++ b/BinaryHeap/CompleteTree/AdditionalProofs/HeapPop.lean @@ -37,8 +37,6 @@ theorem heapPopOnlyRemovesRoot {α : Type u} {n : Nat} (tree : CompleteTree α (      if h₂ : index = (Internal.heapRemoveLastWithIndex tree).snd.snd then        have h₃ := CompleteTree.AdditionalProofs.heapRemoveLastWithIndexReturnsItemAtIndex tree        rw[←h₂] at h₃ -      unfold get -      simp only        have := CompleteTree.AdditionalProofs.heapRemoveLastWithIndexHeapRemoveLastSameElement tree        rw[←this] at h₃        simp[h₃, heapUpdateRootContainsUpdatedElement] diff --git a/BinaryHeap/CompleteTree/AdditionalProofs/HeapPush.lean b/BinaryHeap/CompleteTree/AdditionalProofs/HeapPush.lean index ea2b5a7..62b0e2c 100644 --- a/BinaryHeap/CompleteTree/AdditionalProofs/HeapPush.lean +++ b/BinaryHeap/CompleteTree/AdditionalProofs/HeapPush.lean @@ -87,7 +87,7 @@ theorem heapPushRetainsHeapValues {α : Type u} {n: Nat} (le : α → α → Boo            split            case' isFalse => rw[←containsSeesThroughCast]            case' isTrue | isFalse => -            rw[get_left (.branch v l r p_le_o max_height_difference subtree_complete) index (Nat.succ_pos _) h₂₂ h₃] +            rw[get_left (.branch v l r p_le_o max_height_difference subtree_complete) index h₂₂ h₃]              rw[contains_as_root_left_right _ _ (Nat.succ_pos _)]              right; left              rw[left_unfold] @@ -102,7 +102,7 @@ theorem heapPushRetainsHeapValues {α : Type u} {n: Nat} (le : α → α → Boo            split            case' isFalse => rw[←containsSeesThroughCast]            case' isTrue | isFalse => -            rw[get_right (.branch v l r p_le_o max_height_difference subtree_complete) index (Nat.succ_pos _) (Nat.gt_of_not_le h₃)] +            rw[get_right (.branch v l r p_le_o max_height_difference subtree_complete) index (Nat.gt_of_not_le h₃)]              rw[contains_as_root_left_right _ _ (Nat.succ_pos _)]              right; right              rw[right_unfold] diff --git a/BinaryHeap/CompleteTree/AdditionalProofs/HeapRemoveAt.lean b/BinaryHeap/CompleteTree/AdditionalProofs/HeapRemoveAt.lean index a8a551f..dcff870 100644 --- a/BinaryHeap/CompleteTree/AdditionalProofs/HeapRemoveAt.lean +++ b/BinaryHeap/CompleteTree/AdditionalProofs/HeapRemoveAt.lean @@ -5,11 +5,11 @@ import BinaryHeap.CompleteTree.AdditionalProofs.HeapRemoveLast  namespace BinaryHeap.CompleteTree.AdditionalProofs -theorem heapRemoveAtReturnsElementAt {α : Type u} {n : Nat} (le : α → α → Bool) (heap : CompleteTree α (n+1)) (index : Fin (n+1)) : (heap.heapRemoveAt le index).snd = heap.get' index := by +theorem heapRemoveAtReturnsElementAt {α : Type u} {n : Nat} (le : α → α → Bool) (heap : CompleteTree α (n+1)) (index : Fin (n+1)) : (heap.heapRemoveAt le index).snd = heap.get index := by    unfold heapRemoveAt    if h₁ : index = 0 then      simp only [h₁, ↓reduceDIte] -    rw[get_eq_get', ←Fin.zero_eta, ←get_zero_eq_root] +    rw[←Fin.zero_eta, ←get_zero_eq_root]      exact heapPopReturnsRoot heap le    else      simp only [h₁, ↓reduceDIte, ge_iff_le] @@ -20,15 +20,15 @@ theorem heapRemoveAtReturnsElementAt {α : Type u} {n : Nat} (le : α → α →        if h₃ : (Internal.heapRemoveLastWithIndex heap).2.snd ≤ index then          simp only[h₂, h₃, ↓reduceDIte]          have h₄ := CompleteTree.AdditionalProofs.heapRemoveLastWithIndexRelationGt heap index $ Nat.lt_of_le_of_ne h₃ (Fin.val_ne_iff.mpr (Ne.symm h₂)) -        rewrite[get_eq_get', ←h₄] +        rewrite[←h₄]          exact Eq.symm $ heapUpdateAtReturnsElementAt le _ _ _        else          simp only[h₂, h₃, ↓reduceDIte]          have h₄ := CompleteTree.AdditionalProofs.heapRemoveLastWithIndexRelationLt heap index (Nat.gt_of_not_le h₃) -        rewrite[get_eq_get', ←h₄] +        rewrite[←h₄]          exact Eq.symm $ heapUpdateAtReturnsElementAt le _ _ _ -theorem heapRemoveAtOnlyRemovesAt {α : Type u} {n : Nat} (le : α → α → Bool) (heap : CompleteTree α (n+1)) (removeIndex : Fin (n+1)) (otherIndex : Fin (n+1)) (h₁ : removeIndex ≠ otherIndex) : (heap.heapRemoveAt le removeIndex).fst.contains (heap.get' otherIndex) := by +theorem heapRemoveAtOnlyRemovesAt {α : Type u} {n : Nat} (le : α → α → Bool) (heap : CompleteTree α (n+1)) (removeIndex : Fin (n+1)) (otherIndex : Fin (n+1)) (h₁ : removeIndex ≠ otherIndex) : (heap.heapRemoveAt le removeIndex).fst.contains (heap.get otherIndex) := by    unfold heapRemoveAt    if h₂ : removeIndex = 0 then      subst removeIndex @@ -45,13 +45,13 @@ theorem heapRemoveAtOnlyRemovesAt {α : Type u} {n : Nat} (le : α → α → Bo          simp only [gt_iff_lt] at h₅          split at h₅          case isTrue h₆ => -          rw[get_eq_get', ←h₅] +          rw[←h₅]            apply heapUpdateAtOnlyUpdatesAt            simp only [ne_eq, Fin.pred_inj, h₁, not_false_eq_true]          case isFalse h₆ =>            split at h₅            case isTrue h₇ => -            rw[get_eq_get', ←h₅] +            rw[←h₅]              apply heapUpdateAtOnlyUpdatesAt              simp only [ne_eq, Fin.ext_iff, Fin.coe_pred, Fin.coe_castLT]              generalize (Internal.heapRemoveLastWithIndex heap).snd.snd = j at * @@ -69,7 +69,7 @@ theorem heapRemoveAtOnlyRemovesAt {α : Type u} {n : Nat} (le : α → α → Bo          simp only [gt_iff_lt] at h₅          split at h₅          case isTrue h₆ => -          rw[get_eq_get', ←h₅] +          rw[←h₅]            apply heapUpdateAtOnlyUpdatesAt            simp[Fin.ext_iff]            generalize (Internal.heapRemoveLastWithIndex heap).snd.snd = j at * @@ -77,7 +77,7 @@ theorem heapRemoveAtOnlyRemovesAt {α : Type u} {n : Nat} (le : α → α → Bo          case isFalse h₆ =>            split at h₅            case isTrue h₇ => -            rw[get_eq_get', ←h₅] +            rw[←h₅]              apply heapUpdateAtOnlyUpdatesAt              rw[←Fin.val_ne_iff] at h₁ ⊢              exact h₁ diff --git a/BinaryHeap/CompleteTree/AdditionalProofs/HeapRemoveLast.lean b/BinaryHeap/CompleteTree/AdditionalProofs/HeapRemoveLast.lean index 694a0ee..cf0774f 100644 --- a/BinaryHeap/CompleteTree/AdditionalProofs/HeapRemoveLast.lean +++ b/BinaryHeap/CompleteTree/AdditionalProofs/HeapRemoveLast.lean @@ -7,84 +7,39 @@ import BinaryHeap.CompleteTree.NatLemmas  namespace BinaryHeap.CompleteTree.AdditionalProofs  /--Shows that the index and value returned by heapRemoveLastWithIndex are consistent.-/ -protected theorem heapRemoveLastWithIndexReturnsItemAtIndex {α : Type u} {o : Nat} (heap : CompleteTree α (o+1)) : heap.get' (Internal.heapRemoveLastWithIndex heap).snd.snd = (Internal.heapRemoveLastWithIndex heap).snd.fst := by +protected theorem heapRemoveLastWithIndexReturnsItemAtIndex {α : Type u} {o : Nat} (heap : CompleteTree α (o+1)) : heap.get (Internal.heapRemoveLastWithIndex heap).snd.snd = (Internal.heapRemoveLastWithIndex heap).snd.fst := by    unfold CompleteTree.Internal.heapRemoveLastWithIndex CompleteTree.Internal.heapRemoveLastAux    split    rename_i n m v l r m_le_n max_height_difference subtree_full    simp only [Nat.add_eq, Fin.zero_eta, Fin.isValue, decide_eq_true_eq, Fin.castLE_succ]    split    case isTrue n_m_zero => -    unfold get' -    split -    case h_1 nn mm vv ll rr mm_le_nn _ _ _ _ he₁ he₂ => -      have h₁ : n = 0 := And.left $ Nat.add_eq_zero.mp n_m_zero.symm -      have h₂ : m = 0 := And.right $ Nat.add_eq_zero.mp n_m_zero.symm -      have h₃ : nn = 0 := And.left (Nat.add_eq_zero.mp $ Eq.symm $ (Nat.zero_add 0).subst (motive := λx ↦ x = nn + mm) $ h₂.subst (motive := λx ↦ 0 + x = nn + mm) (h₁.subst (motive := λx ↦ x + m = nn + mm) he₁)) -      have h₄ : mm = 0 := And.right (Nat.add_eq_zero.mp $ Eq.symm $ (Nat.zero_add 0).subst (motive := λx ↦ x = nn + mm) $ h₂.subst (motive := λx ↦ 0 + x = nn + mm) (h₁.subst (motive := λx ↦ x + m = nn + mm) he₁)) -      subst n m nn mm -      exact And.left $ CompleteTree.branch.inj (eq_of_heq he₂.symm) -    case h_2 => -      omega -- to annoying to deal with Fin.ofNat... There's a hypothesis that says 0 = ⟨1,_⟩. +    have h₁ : n = 0 := And.left $ Nat.add_eq_zero.mp n_m_zero.symm +    have h₂ : m = 0 := And.right $ Nat.add_eq_zero.mp n_m_zero.symm +    subst n m +    rfl    case isFalse n_m_not_zero => -    unfold get'      split -    case h_1 nn mm vv ll rr mm_le_nn max_height_difference_2 subtree_full2 _ he₁ he₂ he₃ => -      --aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -      --okay, I know that he₁ is False. -      --but reducing this wall of text to something the computer understands - I am frightened. -      exfalso -      revert he₁ -      split -      case' isTrue => cases l; case leaf hx => exact absurd hx.left $ Nat.not_lt_zero m -      all_goals -        apply Fin.ne_of_val_ne -        simp only [Fin.isValue, Fin.val_succ, Fin.coe_castLE, Fin.coe_addNat, Nat.add_one_ne_zero, not_false_eq_true] -      --okay, this wasn't that bad -    case h_2 j j_lt_n_add_m nn mm vv ll rr mm_le_nn max_height_difference_2 subtree_full2 heap he₁ he₂ he₃ => -      --he₁ relates j to the other indices. This is the important thing here. -      --it should be reducible to j = (l or r).heap.heapRemoveLastWithIndex.snd.snd -      --or something like it. - -      --but first, let's get rid of mm and nn, and vv while at it. -      -- which are equal to m, n, v, but we need to deduce this from he₃... -      have : n = nn := heqSameLeftLen (congrArg (·+1) he₂) (Nat.succ_pos _) he₃ -      have : m = mm := heqSameRightLen (congrArg (·+1) he₂) (Nat.succ_pos _) he₃ -      subst nn mm -      simp only [heq_eq_eq, branch.injEq] at he₃ -      -- yeah, no more HEq fuglyness! -      have : v = vv := he₃.left -      have : l = ll := he₃.right.left -      have : r = rr := he₃.right.right -      subst vv ll rr -      split at he₁ -      <;> rename_i goLeft -      <;> simp only [goLeft, and_self, ↓reduceDIte, Fin.isValue] -      case' isTrue => -        cases l; -        case leaf => exact absurd goLeft.left $ Nat.not_lt_zero m -        rename_i o p _ _ _ _ _ _ _ -      case' isFalse => -        cases r; -        case leaf => simp (config := { ground := true }) only [and_true, Nat.not_lt, Nat.le_zero_eq] at goLeft; -                     exact absurd ((Nat.add_zero n).substr goLeft.symm) n_m_not_zero -      all_goals -        have he₁ := Fin.val_eq_of_eq he₁ -        simp only [Fin.isValue, Fin.val_succ, Fin.coe_castLE, Fin.coe_addNat, Nat.reduceEqDiff] at he₁ -        have : max_height_difference_2 = max_height_difference := rfl -        have : subtree_full2 = subtree_full := rfl -        subst max_height_difference_2 subtree_full2 -        rename_i del1 del2 -        clear del1 del2 -      case' isTrue => -        have : j < o + p + 1 := by omega --from he₁. It has j = (blah : Fin (o+p+1)).val -      case' isFalse => -        have : ¬j<n := by omega --from he₁. It has j = something + n. -      all_goals -        simp only [this, ↓reduceDIte, Nat.pred_succ, Fin.isValue] -        subst j -- overkill, but unlike rw it works -        simp only [Nat.pred_succ, Fin.isValue, Nat.add_sub_cancel, Fin.eta] +    case isTrue goLeft => +      match _term : n, l, m_le_n, max_height_difference, subtree_full with +      | (nn+1), l ,m_le_n, max_height_difference, subtree_full => +      dsimp only [Fin.isValue, Nat.succ_eq_add_one] +      rw[get_left, left_unfold] +      case h₂ => exact Nat.succ_pos _ +      case h₃ => exact (Internal.heapRemoveLastAux (β := λ n ↦ α × Fin n) l _ _ _).2.snd.isLt +      apply AdditionalProofs.heapRemoveLastWithIndexReturnsItemAtIndex +    case isFalse goRight => +      dsimp only [Nat.pred_eq_sub_one, Nat.succ_eq_add_one, Fin.isValue] +      cases r -- to work around cast +      case leaf => simp (config:={ground:=true}) at goRight; exact absurd goRight.symm n_m_not_zero +      case branch rv rl rr rm_le_n rmax_height_difference rsubtree_full => +        rw[get_right, right_unfold] +        case h₂ => simp_arith[leftLen_unfold] +        simp only [Fin.isValue, Fin.val_succ, Fin.coe_castLE, Fin.coe_addNat, leftLen_unfold] +        have : ∀(a : Nat), a + n + 1 - n - 1 = a := λa↦(Nat.add_sub_cancel _ _).subst $ (Nat.add_assoc a n 1).subst (motive := λx↦a+n+1-n-1 = x-(n+1)) $ (Nat.sub_sub (a+n+1) n 1).subst rfl +        simp only[this]          apply AdditionalProofs.heapRemoveLastWithIndexReturnsItemAtIndex -        done +  protected theorem heapRemoveLastWithIndexLeavesRoot {α : Type u} {n: Nat} (heap : CompleteTree α (n+1)) (h₁ : n > 0) : heap.root (Nat.succ_pos n) = (CompleteTree.Internal.heapRemoveLastWithIndex heap).fst.root h₁ :=    CompleteTree.heapRemoveLastAuxLeavesRoot heap _ _ _ h₁ @@ -267,7 +222,6 @@ if h₃ : p < o ∧ (p + 1).nextPowerOfTwo = p + 1 then          rewrite[←lens_see_through_cast _ leftLen _ (Nat.succ_pos _) _]          rewrite[leftLen_unfold]          assumption -        omega        simp only [Nat.add_eq, ne_eq, Fin.zero_eta, Nat.succ_eq_add_one, Nat.pred_eq_sub_one,          Fin.coe_pred, Fin.isValue, ← lens_see_through_cast _ leftLen _ (Nat.succ_pos _) _]        simp only[leftLen_unfold] @@ -502,10 +456,10 @@ protected theorem heapRemoveLastWithIndexEitherContainsOrReturnsElement {α : Ty    else by      right      have h₂ := CompleteTree.AdditionalProofs.heapRemoveLastWithIndexReturnsItemAtIndex heap -    unfold get      simp at h₁      subst index -    exact h₂.symm +    rw[h₂] +    rfl  /--    Shows that each element contained before removing the last that is not the last is still contained after removing the last. diff --git a/BinaryHeap/CompleteTree/AdditionalProofs/HeapUpdateAt.lean b/BinaryHeap/CompleteTree/AdditionalProofs/HeapUpdateAt.lean index be82a57..606b687 100644 --- a/BinaryHeap/CompleteTree/AdditionalProofs/HeapUpdateAt.lean +++ b/BinaryHeap/CompleteTree/AdditionalProofs/HeapUpdateAt.lean @@ -5,19 +5,18 @@ import BinaryHeap.CompleteTree.AdditionalProofs.Get  namespace BinaryHeap.CompleteTree.AdditionalProofs +theorem heapUpdatAtRootEqUpdateRoot {α : Type u} {le : α → α → Bool} : CompleteTree.heapUpdateAt le ⟨0, h₁⟩ = CompleteTree.heapUpdateRoot h₁ le := by +  funext +  unfold heapUpdateAt heapUpdateAtAux +  rfl +  theorem heapUpdateAtReturnsElementAt {α : Type u} {n : Nat} (le : α → α → Bool) (val : α) (heap : CompleteTree α n) (index : Fin n) : heap.get index = (heap.heapUpdateAt le index val).snd := by    cases index    rename_i i isLt    cases i    case mk.zero => -    unfold get get' -    split -    split -    case h_2 hx => -      have hx := Fin.val_eq_of_eq hx -      contradiction -    case h_1 v l r h₂ h₃ h₄ _ _=> -      exact Eq.symm $ heapUpdateRootReturnsRoot le val (.branch v l r h₂ h₃ h₄) (Nat.succ_pos _) +    rw[←get_zero_eq_root, heapUpdatAtRootEqUpdateRoot] +    exact Eq.symm $ heapUpdateRootReturnsRoot le val heap isLt    case mk.succ j =>      unfold heapUpdateAt heapUpdateAtAux      generalize hj : (⟨j + 1, isLt⟩ : Fin n) = index -- otherwise split fails... @@ -37,18 +36,12 @@ theorem heapUpdateAtReturnsElementAt {α : Type u} {n : Nat} (le : α → α →            exact h₂          apply heapUpdateAtReturnsElementAt        case isFalse h₂ => -        rw[get_right _ _] -        case h₁ => exact Nat.succ_pos _ +        rw[get_right]          case h₂ =>            simp only [Nat.not_le] at h₂            simp only [leftLen_unfold, gt_iff_lt, h₂]          apply heapUpdateAtReturnsElementAt -theorem heapUpdatAtRootEqUpdateRoot {α : Type u} {le : α → α → Bool} : CompleteTree.heapUpdateAt le ⟨0, h₁⟩ = CompleteTree.heapUpdateRoot h₁ le := by -  funext -  unfold heapUpdateAt heapUpdateAtAux -  rfl -  theorem heapUpdateAtContainsValue {α : Type u} {n : Nat} (le : α → α → Bool) (heap : CompleteTree α n) (value : α) (index : Fin n) : (heap.heapUpdateAt le index value).fst.contains value := by    unfold heapUpdateAt heapUpdateAtAux    generalize heapUpdateAt.proof_1 index = h₁ @@ -141,7 +134,7 @@ theorem heapUpdateAtOnlyUpdatesAt {α : Type u} {n : Nat} (le : α → α → Bo        case false.isTrue h₅ | true.isTrue h₅ =>          if h₆ : otherIndex ≤ o then            have : otherIndex ≤ (branch v l r olep mhd stc).leftLen (Nat.succ_pos _) := by simp only [leftLen_unfold, h₆] -          rw[get_left _ _ (Nat.succ_pos _) h₄₂ this] +          rw[get_left _ _ h₄₂ this]            left            --rw[left_unfold]            have : o < o + p + 1 := Nat.lt_of_le_of_lt (Nat.le_add_right o p) (Nat.lt_succ_self (o+p)) @@ -150,7 +143,7 @@ theorem heapUpdateAtOnlyUpdatesAt {α : Type u} {n : Nat} (le : α → α → Bo            exact (Nat.pred_ne_of_ne (Fin.pos_iff_ne_zero.mpr h₃) (Fin.pos_iff_ne_zero.mpr h₄)).mp $ Fin.val_ne_iff.mpr h₂          else            have : otherIndex > (branch v l r olep mhd stc).leftLen (Nat.succ_pos _) := by rw[leftLen_unfold]; exact Nat.gt_of_not_le h₆ -          rw[get_right _ _ (Nat.succ_pos _) this] +          rw[get_right _ _ this]            right            --rw[right_unfold]            --rw[right_unfold] @@ -164,7 +157,7 @@ theorem heapUpdateAtOnlyUpdatesAt {α : Type u} {n : Nat} (le : α → α → Bo        case false.isFalse h₅ | true.isFalse h₅ =>          if h₆ : otherIndex ≤ o then            have : otherIndex ≤ (branch v l r olep mhd stc).leftLen (Nat.succ_pos _) := by simp only [leftLen_unfold, h₆] -          rw[get_left _ _ (Nat.succ_pos _) h₄₂ this] +          rw[get_left _ _ h₄₂ this]            left            --rw[left_unfold]            --rw[left_unfold] @@ -175,7 +168,7 @@ theorem heapUpdateAtOnlyUpdatesAt {α : Type u} {n : Nat} (le : α → α → Bo            omega          else            have h₆ : otherIndex > (branch v l r olep mhd stc).leftLen (Nat.succ_pos _) := by rw[leftLen_unfold]; exact Nat.gt_of_not_le h₆ -          rw[get_right _ _ (Nat.succ_pos _) h₆] +          rw[get_right _ _ h₆]            right            --rw[right_unfold]            have : p < o + p + 1 := Nat.lt_of_le_of_lt (Nat.le_add_left p o) (Nat.lt_succ_self (o+p)) diff --git a/BinaryHeap/CompleteTree/AdditionalProofs/HeapUpdateRoot.lean b/BinaryHeap/CompleteTree/AdditionalProofs/HeapUpdateRoot.lean index cd765bb..1a44da1 100644 --- a/BinaryHeap/CompleteTree/AdditionalProofs/HeapUpdateRoot.lean +++ b/BinaryHeap/CompleteTree/AdditionalProofs/HeapUpdateRoot.lean @@ -18,10 +18,8 @@ abbrev heapUpdateRootReturnsRoot {α : Type u} {n : Nat} (le : α → α → Boo    -/  theorem heapUpdateRootOnlyUpdatesRoot {α : Type u} {n : Nat} (le : α → α → Bool) (tree : CompleteTree α n) (h₁ : n > 0) (index : Fin n) (h₂ : index ≠ ⟨0, h₁⟩) (value : α) : (tree.heapUpdateRoot h₁ le value).fst.contains $ tree.get index := by    generalize h₃ : (get index tree) = oldVal -  unfold get at h₃    unfold heapUpdateRoot    split -  simp at h₃    rename_i o p v l r p_le_o _ _ _    cases o    case zero => @@ -30,50 +28,46 @@ theorem heapUpdateRootOnlyUpdatesRoot {α : Type u} {n : Nat} (le : α → α       exact absurd (Fin.fin_one_eq_zero index) h₂    case succ oo _ _ _ =>      simp -    unfold get' at h₃ -    split at h₃ -    case h_1 => omega -    case h_2 j _ o2 p2 v2 l2 r2 _ _ _ _ he1 he2 => -      have : oo+1 = o2 := heqSameLeftLen (congrArg Nat.succ he1) (by simp_arith) he2 -      have : p = p2 := heqSameRightLen (congrArg Nat.succ he1) (by simp_arith) he2 -      subst o2 -      subst p2 -      simp at he2 -      have := he2.left -      have := he2.right.left -      have := he2.right.right -      subst v2 l2 r2 -      simp at h₃ -      cases p -      case zero => -        have : j < oo + 1 := by omega -        simp[this] at h₃ ⊢ -        cases le value (l.root _) <;> simp -        case false => -          cases j -          case zero => -            rw[heapUpdateRootReturnsRoot] -            rw[get_zero_eq_root] -            unfold get; simp only -            rw[h₃, contains_as_root_left_right _ _ (Nat.succ_pos _)] -            left -            rw[root_unfold] -          case succ jj h₄ => -            have h₅ : oo = 0 := by omega -            have h₆ : jj < oo := Nat.lt_of_succ_lt_succ this -            have h₆ : jj < 0 := h₅.subst h₆ -            exact absurd h₆ $ Nat.not_lt_zero jj -        case true h₄ _ _ _ _ _=> -          rw[contains_as_root_left_right _ _ h₄] -          right +    rw[get_unfold'] at h₃ +    simp only[h₂, reduceDIte] at h₃ +    cases p +    case zero => +      let j := index.val.pred +      simp at h₃ ⊢ +      have : index.val ≤ oo + 1 := Nat.le_of_lt_succ index.isLt +      simp only [this, reduceDIte] at h₃ +      cases le value (l.root _) <;> simp +      case false => +        cases hj : j +        case zero => +          rw[heapUpdateRootReturnsRoot] +          rw[get_zero_eq_root] +          rw[contains_as_root_left_right _ _ (Nat.succ_pos _)]            left -          rewrite[contains_iff_index_exists'] -          exists ⟨j,this⟩ -      case succ pp _ _ _ _ _ _ _ _ => +          rw[root_unfold] +          simp only[←hj] +          exact h₃ +        case succ jj => +          have h₅ : oo = 0 := by omega +          have h₆ : index.val = jj + 1 + 1 := hj.subst (motive := λx ↦ index.val = x + 1) $ Eq.symm $ Nat.succ_pred (Fin.val_ne_iff.mpr h₂) +          have h₇ : jj < 0 := h₅.subst $ Nat.le_of_succ_le_succ $ h₆.subst (motive := λx ↦ x ≤ oo + 1) this +          exact absurd h₇ $ Nat.not_lt_zero jj +      case true h₄ => +        rw[contains_as_root_left_right _ _ h₄] +        right +        left +        rewrite[contains_iff_index_exists'] +        exists ⟨j, (Nat.succ_pred (Fin.val_ne_iff.mpr h₂)).substr (p := λx ↦ x ≤ oo + 1) this⟩ +    case succ pp _ _ _ => +      have h₂ := Fin.val_ne_iff.mpr h₂ +      generalize hi :  index.val = i at h₂ ⊢ +      simp only[hi] at h₃ +      cases i; contradiction +      case succ j =>          simp          if h : j < oo + 1 then            -- index was in l -          simp only [h, ↓reduceDIte] at h₃ +          simp only [Nat.succ_le_of_lt h, ↓reduceDIte] at h₃            split            case isTrue =>              simp @@ -91,8 +85,6 @@ theorem heapUpdateRootOnlyUpdatesRoot {α : Type u} {n : Nat} (le : α → α                 cases j                case zero =>                  rw[get_zero_eq_root] -                unfold get -                simp only                  rw[h₃, contains_as_root_left_right _ _ (Nat.succ_pos _)]                  left                  rw[root_unfold] @@ -104,8 +96,8 @@ theorem heapUpdateRootOnlyUpdatesRoot {α : Type u} {n : Nat} (le : α → α                   rw[←h₃, left_unfold]                  have : oo + 1 < oo + 1 + pp + 1 + 1 := by simp_arith --termination                  apply heapUpdateRootOnlyUpdatesRoot -                apply Fin.ne_of_val_ne -                simp only [Nat.add_one_ne_zero, not_false_eq_true] +                apply Fin.val_ne_iff.mp +                exact Nat.succ_ne_zero _              case isFalse =>                -- r.root gets moved up                rw[contains_as_root_left_right _ _ (Nat.succ_pos _)] @@ -116,9 +108,9 @@ theorem heapUpdateRootOnlyUpdatesRoot {α : Type u} {n : Nat} (le : α → α                 exists ⟨j, h⟩          else            -- index was in r -          simp only [h, ↓reduceDIte] at h₃ -          rename_i h₄ _ _ _ _ -          have h₄ : j - (oo + 1) < pp + 1 := Nat.sub_lt_left_of_lt_add (Nat.le_of_not_gt h) (Nat.lt_of_succ_lt_succ h₄) +          have : j + 1 - (oo + 1) - 1 = j - oo - 1 := (Nat.sub_sub (j+1) 1 oo).substr $ (Nat.add_comm oo 1).substr rfl +          simp only [this, Not.intro $ h ∘ Nat.lt_of_succ_le ∘ (Nat.succ_eq_add_one j).substr, ↓reduceDIte] at h₃ +          have h₄ : j - (oo + 1) < pp + 1 := Nat.sub_lt_left_of_lt_add (Nat.le_of_not_gt h) (Nat.lt_of_succ_lt_succ $ hi.subst (motive := λx ↦ x < _) index.isLt)            split            case isTrue h₄ _ _ _ _ _ =>              simp @@ -141,14 +133,12 @@ theorem heapUpdateRootOnlyUpdatesRoot {α : Type u} {n : Nat} (le : α → α               case isFalse =>                --r.root gets moved up                simp only -              generalize h₅ : j - (oo + 1) = jr +              generalize h₅ : j - oo - 1 = jr                simp only [h₅] at h₃                have h₄ : jr < pp+1 := h₅.subst (motive := λx ↦ x < pp+1) h₄                cases jr                case zero =>                  rw[get_zero_eq_root] -                unfold get -                simp only                  rw[h₃, contains_as_root_left_right _ _ (Nat.succ_pos _)]                  left                  rw[root_unfold] @@ -161,7 +151,6 @@ theorem heapUpdateRootOnlyUpdatesRoot {α : Type u} {n : Nat} (le : α → α                   apply heapUpdateRootOnlyUpdatesRoot                  apply Fin.ne_of_val_ne                  simp only [Nat.add_one_ne_zero, not_false_eq_true] -termination_by n  theorem heapUpdateRootContainsUpdatedElement {α : Type u} {n : Nat} (tree : CompleteTree α n) (le : α → α → Bool) (value : α) (h₁ : n > 0): (tree.heapUpdateRoot h₁ le value).fst.contains value := by    unfold heapUpdateRoot  | 
