diff options
| author | Andreas Grois <andi@grois.info> | 2024-08-30 23:53:38 +0200 | 
|---|---|---|
| committer | Andreas Grois <andi@grois.info> | 2024-08-30 23:53:38 +0200 | 
| commit | 30139d5f88eedeb16d0f41c6f7ee7cfc036fe2dc (patch) | |
| tree | 9f587d97304681e1230439dd354a0bb60c6d6fa4 | |
| parent | 495487fde5a0d8d93ec66e5322ec88bafb6810a9 (diff) | |
First working version of indexOfSomeImpPredTrue
| -rw-r--r-- | BinaryHeap/CompleteTree/AdditionalProofs/IndexOf.lean | 110 | 
1 files changed, 107 insertions, 3 deletions
diff --git a/BinaryHeap/CompleteTree/AdditionalProofs/IndexOf.lean b/BinaryHeap/CompleteTree/AdditionalProofs/IndexOf.lean index dfba566..428f441 100644 --- a/BinaryHeap/CompleteTree/AdditionalProofs/IndexOf.lean +++ b/BinaryHeap/CompleteTree/AdditionalProofs/IndexOf.lean @@ -19,7 +19,7 @@ private theorem Option.bind_some_eq_map {α β : Type u} (f : α → β) (a : Op    case none => rfl    case some => rfl -private theorem Option.is_some_map {α : Type u} {β : Type v} (f : α → β) (a : Option α) : (Option.map f a).isSome = a.isSome := by +private theorem Option.is_some_map {α : Type u} {β : Type v} {f : α → β} {a : Option α} : (Option.map f a).isSome ↔ a.isSome := by    cases a    case none => simp only [Option.map_none', Option.isSome_none]    case some => simp only [Option.map_some', Option.isSome_some] @@ -29,6 +29,17 @@ private theorem Option.orElse_is_some {α : Type u} (a b : Option α) : (HOrElse    case none => simp only [Option.none_orElse, Option.isSome_none, Bool.false_or]    case some _ => simp only [Option.some_orElse, Option.isSome_some, Bool.true_or] +private theorem Option.isSome_of_eq_some {α : Type u} {a : α} {o : Option α} : o = some a → o.isSome := by +  intro h₁ +  cases o +  case none => contradiction +  case some => rfl + +private theorem Option.map_get {α: Type u} {β : Type v} {o : Option α} {f : α → β} (h₁ : (Option.map f o).isSome) : (Option.map f o).get h₁ = (f $ o.get (Option.is_some_map.mp h₁)) := by +  cases o +  case none => contradiction +  case some => rfl +  private theorem indexOfNoneImpPredFalseAux {α : Type u} {n : Nat} (tree : CompleteTree α n) (pred : α → Bool) (currentIndex : Nat) : (CompleteTree.Internal.indexOfAux tree pred currentIndex).isNone → ∀(index : Fin n), ¬pred (tree.get index) := by    if h₁ : n > 0 then      intro h₂ @@ -99,11 +110,104 @@ private theorem indexOfSomeImpPredTrueAux2 {α : Type u} {p : Nat} {r : Complete          right          exact indexOfSomeImpPredTrueAux2 _ _ h₁ +private theorem indexOfAuxAddsCurrentIndex {α : Type u} {n : Nat} (tree : CompleteTree α n) (pred : α → Bool) (currentIndex : Nat) (h₁ : Option.isSome $ Internal.indexOfAux tree pred currentIndex) (h₂ : Option.isSome $ Internal.indexOfAux tree pred 0) : Fin.val ((Internal.indexOfAux tree pred currentIndex).get h₁) = (Fin.val ((Internal.indexOfAux tree pred 0).get h₂)) + currentIndex := by +  unfold Internal.indexOfAux +  split +  case h_1 => omega --Good that omega can solve this. I really wouldn't want to dig for that proof by hand. +  case h_2 o p v l r _ _ _ => +    split +    case isTrue => +      have : currentIndex < o + p + 1 + currentIndex := by simp_arith +      simp only [Nat.add_eq, Nat.succ_eq_add_one, Option.get_some, Fin.val_ofNat', this, +        Nat.mod_eq_of_lt, Nat.add_zero, Nat.zero_lt_succ, Nat.zero_add] +    case isFalse => +      simp only [Nat.add_eq, Nat.succ_eq_add_one, Option.pure_def, Option.bind_eq_bind, +        Option.bind_some_eq_map, Option.map_map, Nat.add_zero, Nat.reduceAdd] +      unfold HOrElse.hOrElse instHOrElseOfOrElse OrElse.orElse Option.instOrElse Option.orElse +      -- All the cool tactics fail here. So, I hate to do this, but: +      simp only +      unfold Option.get +      split +      rename_i d1 d2 index₁ h₃ hsplit₁ _ +      clear d1 d2 +      split +      rename_i d1 d2 index₂ h₃₂ hsplit₂ _ +      clear d1 d2 +      -- In Lean, you know you are in for a world of pain if you split <;> split. +      split at hsplit₁ <;> split at hsplit₂ +      case' h_1.h_2 => let off := 1 +      case' h_2.h_1 => let off := currentIndex + 1 +      case h_1.h_2 hx₂ _ _ hx₁ | h_2.h_1 hx₁ _ _ _ hx₂ => +        have hx₂ := Option.isSome_of_eq_some hx₂ +        have hx₂ : (Internal.indexOfAux l pred _).isSome := Option.is_some_map.mp hx₂ +        have hx₂ := indexOfSomeImpPredTrueAux2 _ off hx₂ +        have hx₁ := Option.map_eq_none.mp hx₁ +        have hx₁ := Option.not_isSome_iff_eq_none.mpr hx₁ +        contradiction +      all_goals +        simp only [Option.some.injEq] at hsplit₂ hsplit₁ +      case h_1.h_1 he₁ _ _ _ he₂ => +        have hsplit₂ := hsplit₂.symm +        have hsplit₁ := hsplit₁.symm +        subst hsplit₂ hsplit₁ +        have h₃ : (Internal.indexOfAux l pred (currentIndex + 1)).isSome := +          match Option.eq_some_iff_get_eq.mp he₁ with +          | Exists.intro he₁ _ => Option.is_some_map.mp he₁ +        have h₄ : (Internal.indexOfAux l pred 1).isSome := indexOfSomeImpPredTrueAux2 _ _ h₃ +        have h₅ : (Internal.indexOfAux l pred 0).isSome := indexOfSomeImpPredTrueAux2 _ _ h₃ +        have h₆ := indexOfAuxAddsCurrentIndex l pred 1 h₄ h₅ +        have h₇ := indexOfAuxAddsCurrentIndex l pred (currentIndex + 1) h₃ h₅ +        rw[Option.eq_some_iff_get_eq] at he₂ he₁ +        match he₁, he₂ with +        | Exists.intro he₁ h₈, Exists.intro he₂ h₉ => +          simp[Fin.ext_iff, Option.map_get] at h₈ h₉ +          rw[Nat.mod_eq_of_lt (by omega), h₇] at h₈ +          rw[Nat.mod_eq_of_lt (by omega), h₆] at h₉ +          rw[←h₈, ←h₉] +          simp_arith +      case h_2.h_2 => +        have h₃ : (Internal.indexOfAux r pred (currentIndex + o + 1)).isSome := +          match Option.eq_some_iff_get_eq.mp hsplit₁ with +          | Exists.intro he₁ _ => Option.is_some_map.mp he₁ +        have h₄ : (Internal.indexOfAux r pred (0 + o + 1)).isSome := indexOfSomeImpPredTrueAux2 _ _ h₃ +        have h₅ : (Internal.indexOfAux r pred 0).isSome := indexOfSomeImpPredTrueAux2 _ _ h₃ +        have h₆ := indexOfAuxAddsCurrentIndex r pred (0 + o + 1) h₄ h₅ +        have h₇ := indexOfAuxAddsCurrentIndex r pred (currentIndex + o + 1) h₃ h₅ +        rw[Option.eq_some_iff_get_eq] at hsplit₁ hsplit₂ +        match hsplit₁, hsplit₂ with +        | Exists.intro hsplit₁ h₈, Exists.intro hsplit₂ h₉ => +          simp[Fin.ext_iff, Option.map_get] at h₈ h₉ +          rw[Nat.mod_eq_of_lt (by omega), h₇] at h₈ +          rw[Nat.mod_eq_of_lt (by omega), h₆] at h₉ +          rw[←h₈, ←h₉] +          simp_arith +  private theorem indexOfSomeImpPredTrueAuxR {α : Type u} {p : Nat} (r : CompleteTree α p) (pred : α → Bool) {o : Nat} (index : Fin ((o+p)+1)) (h₁ : o + p + 1 > 0) (h₂ : (Internal.indexOfAux r pred 0).isSome) : ∀(a : Fin (p + (o + 1))), (Internal.indexOfAux r pred (o + 1) = some a ∧ Fin.ofNat' ↑a h₁ = index) → (Internal.indexOfAux r pred 0).get h₂ + o + 1 = index.val := by -  sorry +  simp only [Nat.add_zero, and_imp] +  intros index₂ h₃ h₄ +  have : index₂.val = index.val := by +    rw[Fin.ext_iff, Fin.val_ofNat'] at h₄ +    have : index₂.val % (o + p + 1) = index₂.val := Nat.mod_eq_of_lt $ (Nat.add_comm o p).substr $ (Nat.add_assoc o p 1).substr index₂.isLt +    exact this.subst (motive := λx↦x=index.val) h₄ +  rw[←this] +  have := indexOfAuxAddsCurrentIndex r pred (o+1) (indexOfSomeImpPredTrueAux2 0 _ h₂) h₂ +  simp_arith at this +  rw[←this] +  simp only [h₃, Option.get_some]  private theorem indexOfSomeImpPredTrueAuxL {α : Type u} {o : Nat} (l : CompleteTree α o) (pred : α → Bool) {p : Nat} (index : Fin ((o+p)+1)) (h₁ : o + p + 1 > 0) (h₂ : (Internal.indexOfAux l pred 0).isSome) : ∀(a : Fin ((o + 1))), (Internal.indexOfAux l pred 1 = some a ∧ Fin.ofNat' ↑a h₁ = index) → (Internal.indexOfAux l pred 0).get h₂ + 1 = index.val := by -  sorry +  simp only [Nat.add_zero, and_imp] +  intros index₂ h₃ h₄ +  have : index₂.val = index.val := by +    rw[Fin.ext_iff, Fin.val_ofNat'] at h₄ +    have : o + 1 ≤ o+p+1 := Nat.succ_le_succ $ Nat.le_add_right o p +    have : index₂.val % (o + p + 1) = index₂.val := Nat.mod_eq_of_lt $ Nat.lt_of_lt_of_le index₂.isLt this +    exact this.subst (motive := λx↦x=index.val) h₄ +  rw[←this] +  have := indexOfAuxAddsCurrentIndex l pred 1 (indexOfSomeImpPredTrueAux2 0 _ h₂) h₂ +  simp_arith at this +  rw[←this] +  simp only [h₃, Option.get_some]  theorem indexOfSomeImpPredTrue {α : Type u} {n : Nat} (tree : CompleteTree α n) (pred : α → Bool) : (h₁ : (tree.indexOf pred).isSome) → pred (tree.get ((tree.indexOf pred).get h₁)) := by    intro h₁  | 
