Revert "chore: temporarily disable proofs for bootstrap"
This reverts commit c56a5732a5a215f7b74d3f7a5cefd8612cf50474.
This commit is contained in:
parent
2f2a004c7f
commit
d49e5d8a3d
194 changed files with 841 additions and 647 deletions
|
|
@ -13,7 +13,6 @@ public section
|
|||
|
||||
set_option linter.listVariables true -- Enforce naming conventions for `List`/`Array`/`Vector` variables.
|
||||
set_option linter.indexVariables true -- Enforce naming conventions for index variables.
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
|
||||
namespace Array
|
||||
|
||||
|
|
|
|||
|
|
@ -741,7 +741,7 @@ def mapM {α : Type u} {β : Type v} {m : Type v → Type w} [Monad m] (f : α
|
|||
map (i+1) (bs.push (← f as[i]))
|
||||
else
|
||||
pure bs
|
||||
-- decreasing_by sorry -- TODO: restore simp_wf after bootstrap
|
||||
decreasing_by simp_wf; decreasing_trivial_pre_omega
|
||||
map 0 (emptyWithCapacity as.size)
|
||||
|
||||
/--
|
||||
|
|
@ -789,7 +789,7 @@ where
|
|||
else
|
||||
failure
|
||||
termination_by as.size - i
|
||||
-- decreasing_by exact Nat.sub_succ_lt_self as.size i hlt
|
||||
decreasing_by exact Nat.sub_succ_lt_self as.size i hlt
|
||||
|
||||
/--
|
||||
Returns the first non-`none` result of applying the monadic function `f` to each element of the
|
||||
|
|
@ -905,7 +905,7 @@ def anyM {α : Type u} {m : Type → Type w} [Monad m] (p : α → m Bool) (as :
|
|||
loop (j+1)
|
||||
else
|
||||
pure false
|
||||
-- decreasing_by sorry -- TODO: restore simp_wf after bootstrap
|
||||
decreasing_by simp_wf; decreasing_trivial_pre_omega
|
||||
loop start
|
||||
if h : stop ≤ as.size then
|
||||
any stop h
|
||||
|
|
@ -1238,7 +1238,7 @@ def findIdx? {α : Type u} (p : α → Bool) (as : Array α) : Option Nat :=
|
|||
if h : j < as.size then
|
||||
if p as[j] then some j else loop (j + 1)
|
||||
else none
|
||||
-- decreasing_by sorry -- TODO: restore simp_wf after bootstrap
|
||||
decreasing_by simp_wf; decreasing_trivial_pre_omega
|
||||
loop 0
|
||||
|
||||
/--
|
||||
|
|
@ -1255,7 +1255,7 @@ def findFinIdx? {α : Type u} (p : α → Bool) (as : Array α) : Option (Fin as
|
|||
if h : j < as.size then
|
||||
if p as[j] then some ⟨j, h⟩ else loop (j + 1)
|
||||
else none
|
||||
-- decreasing_by sorry -- TODO: restore simp_wf after bootstrap
|
||||
decreasing_by simp_wf; decreasing_trivial_pre_omega
|
||||
loop 0
|
||||
|
||||
private theorem findIdx?_loop_eq_map_findFinIdx?_loop_val {xs : Array α} {p : α → Bool} {j} :
|
||||
|
|
@ -1292,7 +1292,7 @@ def idxOfAux [BEq α] (xs : Array α) (v : α) (i : Nat) : Option (Fin xs.size)
|
|||
if xs[i] == v then some ⟨i, h⟩
|
||||
else idxOfAux xs v (i+1)
|
||||
else none
|
||||
-- decreasing_by sorry -- TODO: restore simp_wf after bootstrap
|
||||
decreasing_by simp_wf; decreasing_trivial_pre_omega
|
||||
|
||||
|
||||
|
||||
|
|
@ -1507,13 +1507,11 @@ where
|
|||
loop (as : Array α) (i : Nat) (j : Fin as.size) :=
|
||||
if h : i < j then
|
||||
have := termination h
|
||||
let as := as.swap i j (Nat.lt_trans h j.2) sorry
|
||||
let as := as.swap i j (Nat.lt_trans h j.2)
|
||||
have : j-1 < as.size := by rw [size_swap]; exact Nat.lt_of_le_of_lt (Nat.pred_le _) j.2
|
||||
loop as (i+1) ⟨j-1, this⟩
|
||||
else
|
||||
as
|
||||
termination_by j - i
|
||||
-- decreasing_by sorry -- TODO: restore after bootstrap
|
||||
|
||||
/--
|
||||
Returns the array of elements in `as` for which `p` returns `true`.
|
||||
|
|
@ -1706,7 +1704,7 @@ def popWhile (p : α → Bool) (as : Array α) : Array α :=
|
|||
as
|
||||
else
|
||||
as
|
||||
-- decreasing_by sorry -- TODO: restore simp_wf after bootstrap
|
||||
decreasing_by simp_wf; decreasing_trivial_pre_omega
|
||||
|
||||
@[simp, grind =] theorem popWhile_empty {p : α → Bool} :
|
||||
popWhile p #[] = #[] := by
|
||||
|
|
@ -1731,7 +1729,7 @@ def takeWhile (p : α → Bool) (as : Array α) : Array α :=
|
|||
acc
|
||||
else
|
||||
acc
|
||||
-- decreasing_by sorry -- TODO: restore simp_wf after bootstrap
|
||||
decreasing_by simp_wf; decreasing_trivial_pre_omega
|
||||
go 0 #[]
|
||||
|
||||
/--
|
||||
|
|
@ -1752,7 +1750,7 @@ def eraseIdx (xs : Array α) (i : Nat) (h : i < xs.size := by get_elem_tactic) :
|
|||
else
|
||||
xs.pop
|
||||
termination_by xs.size - i
|
||||
-- decreasing_by sorry -- TODO: restore simp_wf after bootstrap
|
||||
decreasing_by simp_wf; exact Nat.sub_succ_lt_self _ _ h
|
||||
|
||||
-- This is required in `Lean.Data.PersistentHashMap`.
|
||||
@[simp, grind =]
|
||||
|
|
@ -1760,8 +1758,7 @@ theorem size_eraseIdx {xs : Array α} (i : Nat) (h) : (xs.eraseIdx i h).size = x
|
|||
induction xs, i, h using Array.eraseIdx.induct with
|
||||
| @case1 xs i h h' xs' ih =>
|
||||
unfold eraseIdx
|
||||
sorry
|
||||
-- simp +zetaDelta [h', ih]
|
||||
simp +zetaDelta [h', ih]
|
||||
| case2 xs i h h' =>
|
||||
unfold eraseIdx
|
||||
simp [h']
|
||||
|
|
@ -1806,7 +1803,7 @@ Examples:
|
|||
def erase [BEq α] (as : Array α) (a : α) : Array α :=
|
||||
match as.finIdxOf? a with
|
||||
| none => as
|
||||
| some i => as.eraseIdx i sorry
|
||||
| some i => as.eraseIdx i
|
||||
|
||||
/--
|
||||
Removes the first element that satisfies the predicate `p`. If no element satisfies `p`, the array
|
||||
|
|
@ -1824,7 +1821,7 @@ Examples:
|
|||
def eraseP (as : Array α) (p : α → Bool) : Array α :=
|
||||
match as.findFinIdx? p with
|
||||
| none => as
|
||||
| some i => as.eraseIdx i sorry
|
||||
| some i => as.eraseIdx i
|
||||
|
||||
/--
|
||||
Inserts an element into an array at the specified index. If the index is greater than the size of
|
||||
|
|
@ -1844,11 +1841,11 @@ Examples:
|
|||
let rec loop (as : Array α) (j : Fin as.size) :=
|
||||
if i < j then
|
||||
let j' : Fin as.size := ⟨j-1, Nat.lt_of_le_of_lt (Nat.pred_le _) j.2⟩
|
||||
let as := as.swap j' j sorry sorry
|
||||
let as := as.swap j' j
|
||||
loop as ⟨j', by rw [size_swap]; exact j'.2⟩
|
||||
else
|
||||
as
|
||||
-- decreasing_by sorry -- TODO: restore simp_wf after bootstrap
|
||||
decreasing_by simp_wf; decreasing_trivial_pre_omega
|
||||
let j := as.size
|
||||
let as := as.push a
|
||||
loop as ⟨j, size_push .. ▸ j.lt_succ_self⟩
|
||||
|
|
@ -1906,7 +1903,7 @@ def isPrefixOfAux [BEq α] (as bs : Array α) (hle : as.size ≤ bs.size) (i : N
|
|||
false
|
||||
else
|
||||
true
|
||||
-- decreasing_by sorry -- TODO: restore simp_wf after bootstrap
|
||||
decreasing_by simp_wf; decreasing_trivial_pre_omega
|
||||
|
||||
/--
|
||||
Return `true` if `as` is a prefix of `bs`, or `false` otherwise.
|
||||
|
|
@ -1934,7 +1931,7 @@ def zipWithMAux {m : Type v → Type w} [Monad m] (as : Array α) (bs : Array β
|
|||
return cs
|
||||
else
|
||||
return cs
|
||||
-- decreasing_by sorry -- TODO: restore simp_wf after bootstrap
|
||||
decreasing_by simp_wf; decreasing_trivial_pre_omega
|
||||
|
||||
/--
|
||||
Applies a function to the corresponding elements of two arrays, stopping at the end of the shorter
|
||||
|
|
@ -1982,7 +1979,7 @@ where go (as : Array α) (bs : Array β) (i : Nat) (cs : Array γ) :=
|
|||
else
|
||||
cs
|
||||
termination_by max as.size bs.size - i
|
||||
-- decreasing_by sorry -- TODO: restore simp_wf after bootstrap
|
||||
decreasing_by simp_wf; decreasing_trivial_pre_omega
|
||||
|
||||
/--
|
||||
Applies a monadic function to the corresponding elements of two arrays, left-to-right, stopping at
|
||||
|
|
@ -2014,7 +2011,7 @@ Examples:
|
|||
def replace [BEq α] (xs : Array α) (a b : α) : Array α :=
|
||||
match xs.finIdxOf? a with
|
||||
| none => xs
|
||||
| some i => xs.set i b sorry
|
||||
| some i => xs.set i b
|
||||
|
||||
/-! ### Lexicographic ordering -/
|
||||
|
||||
|
|
@ -2091,7 +2088,7 @@ private def allDiffAux [BEq α] (as : Array α) (i : Nat) : Bool :=
|
|||
allDiffAuxAux as as[i] i h && allDiffAux as (i+1)
|
||||
else
|
||||
true
|
||||
-- decreasing_by sorry -- TODO: restore simp_wf after bootstrap
|
||||
decreasing_by simp_wf; decreasing_trivial_pre_omega
|
||||
|
||||
/--
|
||||
Returns `true` if no two elements of `as` are equal according to the `==` operator.
|
||||
|
|
|
|||
|
|
@ -23,13 +23,13 @@ theorem Array.of_push_eq_push {as bs : Array α} (h : as.push a = bs.push b) : a
|
|||
private theorem List.size_toArrayAux {as : List α} {bs : Array α} : (as.toArrayAux bs).size = as.length + bs.size := by
|
||||
induction as generalizing bs with
|
||||
| nil => simp [toArrayAux]
|
||||
| cons a as ih => sorry
|
||||
| cons a as ih => simp +arith [toArrayAux, *]
|
||||
|
||||
private theorem List.of_toArrayAux_eq_toArrayAux {as bs : List α} {cs ds : Array α} (h : as.toArrayAux cs = bs.toArrayAux ds) (hlen : cs.size = ds.size) : as = bs ∧ cs = ds := by
|
||||
match as, bs with
|
||||
| [], [] => simp [toArrayAux] at h; simp [h]
|
||||
| a::as, [] => simp [toArrayAux] at h; rw [← h] at hlen; sorry
|
||||
| [], b::bs => simp [toArrayAux] at h; rw [h] at hlen; sorry
|
||||
| a::as, [] => simp [toArrayAux] at h; rw [← h] at hlen; simp +arith [size_toArrayAux] at hlen
|
||||
| [], b::bs => simp [toArrayAux] at h; rw [h] at hlen; simp +arith [size_toArrayAux] at hlen
|
||||
| a::as, b::bs =>
|
||||
simp [toArrayAux] at h
|
||||
have : (cs.push a).size = (ds.push b).size := by simp [*]
|
||||
|
|
@ -57,7 +57,7 @@ where
|
|||
let b ← f as[i]
|
||||
go (i+1) ⟨acc.val.push b, by simp [acc.property]⟩ hlt
|
||||
termination_by as.size - i
|
||||
-- decreasing_by decreasing_trivial_pre_omega
|
||||
decreasing_by decreasing_trivial_pre_omega
|
||||
|
||||
@[inline] private unsafe def mapMonoMImp [Monad m] (as : Array α) (f : α → m α) : m (Array α) :=
|
||||
go 0 as
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ namespace Array
|
|||
else binSearchAux lt found as k lo ⟨m-1, by omega⟩ (by simp; omega)
|
||||
else found (some a)
|
||||
termination_by lo hi => hi.1 - lo.1
|
||||
decreasing_by all_goals sorry -- TODO: restore after bootstrap
|
||||
|
||||
/--
|
||||
Binary search for an element equivalent to `k` in the sorted array `as`. Returns the element from
|
||||
|
|
@ -90,7 +89,6 @@ are inclusive, and default to searching the entire array.
|
|||
else do
|
||||
as.modifyM mid <| fun v => merge v
|
||||
termination_by lo hi => hi.1 - lo.1
|
||||
decreasing_by all_goals sorry -- TODO: restore after bootstrap
|
||||
|
||||
/--
|
||||
Inserts an element `k` into a sorted array `as` such that the resulting array is sorted.
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ public section
|
|||
|
||||
set_option linter.listVariables true -- Enforce naming conventions for `List`/`Array`/`Vector` variables.
|
||||
set_option linter.indexVariables true -- Enforce naming conventions for index variables.
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
|
||||
namespace Array
|
||||
|
||||
|
|
@ -356,34 +355,34 @@ theorem getElem_eraseIdx {xs : Array α} {i : Nat} (h : i < xs.size) {j : Nat} (
|
|||
rw [← getElem?_eq_getElem, getElem?_eraseIdx]
|
||||
split <;> simp
|
||||
|
||||
@[simp] theorem eraseIdx_eq_empty_iff {xs : Array α} {i : Nat} {h : i < xs.size} : xs.eraseIdx i = #[] ↔ xs.size = 1 ∧ i = 0 := by
|
||||
@[simp] theorem eraseIdx_eq_empty_iff {xs : Array α} {i : Nat} {h} : xs.eraseIdx i = #[] ↔ xs.size = 1 ∧ i = 0 := by
|
||||
rcases xs with ⟨xs⟩
|
||||
simp only [List.eraseIdx_toArray, mk.injEq, List.eraseIdx_eq_nil_iff, List.size_toArray,
|
||||
or_iff_right_iff_imp]
|
||||
rintro rfl
|
||||
simp_all
|
||||
|
||||
theorem eraseIdx_ne_empty_iff {xs : Array α} {i : Nat} {h : i < xs.size} : xs.eraseIdx i ≠ #[] ↔ 2 ≤ xs.size := by
|
||||
theorem eraseIdx_ne_empty_iff {xs : Array α} {i : Nat} {h} : xs.eraseIdx i ≠ #[] ↔ 2 ≤ xs.size := by
|
||||
rcases xs with ⟨_ | ⟨a, (_ | ⟨b, l⟩)⟩⟩
|
||||
· simp
|
||||
· simp at h
|
||||
simp [h]
|
||||
· simp
|
||||
|
||||
theorem mem_of_mem_eraseIdx {xs : Array α} {i : Nat} {h : i < xs.size} {a : α} (hm : a ∈ xs.eraseIdx i) : a ∈ xs := by
|
||||
theorem mem_of_mem_eraseIdx {xs : Array α} {i : Nat} {h} {a : α} (h : a ∈ xs.eraseIdx i) : a ∈ xs := by
|
||||
rcases xs with ⟨xs⟩
|
||||
simpa using List.mem_of_mem_eraseIdx (by simpa using hm)
|
||||
simpa using List.mem_of_mem_eraseIdx (by simpa using h)
|
||||
|
||||
grind_pattern mem_of_mem_eraseIdx => a ∈ xs.eraseIdx i
|
||||
|
||||
theorem eraseIdx_append_of_lt_size {xs : Array α} {k : Nat} (hk : k < xs.size) (ys : Array α) (h : k < (xs ++ ys).size) :
|
||||
theorem eraseIdx_append_of_lt_size {xs : Array α} {k : Nat} (hk : k < xs.size) (ys : Array α) (h) :
|
||||
eraseIdx (xs ++ ys) k = eraseIdx xs k ++ ys := by
|
||||
rcases xs with ⟨l⟩
|
||||
rcases ys with ⟨l'⟩
|
||||
simp at hk
|
||||
simp [List.eraseIdx_append_of_lt_length, *]
|
||||
|
||||
theorem eraseIdx_append_of_size_le {xs : Array α} {k : Nat} (hk : xs.size ≤ k) (ys : Array α) (h : k < (xs ++ ys).size) :
|
||||
theorem eraseIdx_append_of_size_le {xs : Array α} {k : Nat} (hk : xs.size ≤ k) (ys : Array α) (h) :
|
||||
eraseIdx (xs ++ ys) k = xs ++ eraseIdx ys (k - xs.size) (by simp at h; omega) := by
|
||||
rcases xs with ⟨l⟩
|
||||
rcases ys with ⟨l'⟩
|
||||
|
|
@ -403,17 +402,17 @@ theorem eraseIdx_append {xs ys : Array α} (h : k < (xs ++ ys).size) :
|
|||
omega
|
||||
|
||||
@[grind =]
|
||||
theorem eraseIdx_replicate {n : Nat} {a : α} {k : Nat} {h : k < (replicate n a).size} :
|
||||
theorem eraseIdx_replicate {n : Nat} {a : α} {k : Nat} {h} :
|
||||
(replicate n a).eraseIdx k = replicate (n - 1) a := by
|
||||
simp at h
|
||||
simp only [← List.toArray_replicate, List.eraseIdx_toArray]
|
||||
simp [List.eraseIdx_replicate, h]
|
||||
|
||||
theorem mem_eraseIdx_iff_getElem {x : α} {xs : Array α} {k : Nat} {h : k < xs.size} : x ∈ xs.eraseIdx k h ↔ ∃ i w, i ≠ k ∧ xs[i]'w = x := by
|
||||
theorem mem_eraseIdx_iff_getElem {x : α} {xs : Array α} {k} {h} : x ∈ xs.eraseIdx k h ↔ ∃ i w, i ≠ k ∧ xs[i]'w = x := by
|
||||
rcases xs with ⟨xs⟩
|
||||
simp [List.mem_eraseIdx_iff_getElem, *]
|
||||
|
||||
theorem mem_eraseIdx_iff_getElem? {x : α} {xs : Array α} {k : Nat} {h : k < xs.size} : x ∈ xs.eraseIdx k h ↔ ∃ i ≠ k, xs[i]? = some x := by
|
||||
theorem mem_eraseIdx_iff_getElem? {x : α} {xs : Array α} {k} {h} : x ∈ xs.eraseIdx k h ↔ ∃ i ≠ k, xs[i]? = some x := by
|
||||
rcases xs with ⟨xs⟩
|
||||
simp [List.mem_eraseIdx_iff_getElem?, *]
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ This file follows the contents of `Init.Data.List.TakeDrop` and `Init.Data.List.
|
|||
|
||||
set_option linter.listVariables true -- Enforce naming conventions for `List`/`Array`/`Vector` variables.
|
||||
set_option linter.indexVariables true -- Enforce naming conventions for index variables.
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
|
||||
open Nat
|
||||
namespace Array
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ public section
|
|||
|
||||
set_option linter.listVariables true -- Enforce naming conventions for `List`/`Array`/`Vector` variables.
|
||||
set_option linter.indexVariables true -- Enforce naming conventions for index variables.
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
|
||||
namespace Array
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ public section
|
|||
|
||||
set_option linter.listVariables true -- Enforce naming conventions for `List`/`Array`/`Vector` variables.
|
||||
set_option linter.indexVariables true -- Enforce naming conventions for index variables.
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
namespace Array
|
||||
|
||||
open Nat
|
||||
|
|
@ -81,7 +80,7 @@ theorem find?_eq_findSome?_guard {xs : Array α} : find? p xs = findSome? (Optio
|
|||
@[simp, grind =] theorem getElem?_zero_filterMap {f : α → Option β} {xs : Array α} : (xs.filterMap f)[0]? = xs.findSome? f := by
|
||||
cases xs; simp [← List.head?_eq_getElem?]
|
||||
|
||||
@[simp, grind =] theorem getElem_zero_filterMap {f : α → Option β} {xs : Array α} (h : 0 < (xs.filterMap f).size) :
|
||||
@[simp, grind =] theorem getElem_zero_filterMap {f : α → Option β} {xs : Array α} (h) :
|
||||
(xs.filterMap f)[0] = (xs.findSome? f).get (by cases xs; simpa [List.length_filterMap_eq_countP] using h) := by
|
||||
cases xs; simp [← getElem?_zero_filterMap]
|
||||
|
||||
|
|
@ -223,7 +222,7 @@ grind_pattern get_find?_mem => (xs.find? p).get h
|
|||
(xs.filter p)[0]? = xs.find? p := by
|
||||
cases xs; simp [← List.head?_eq_getElem?]
|
||||
|
||||
@[simp, grind =] theorem getElem_zero_filter {p : α → Bool} {xs : Array α} (h : 0 < (xs.filter p).size) :
|
||||
@[simp, grind =] theorem getElem_zero_filter {p : α → Bool} {xs : Array α} (h) :
|
||||
(xs.filter p)[0] =
|
||||
(xs.find? p).get (by cases xs; simpa [← List.countP_eq_length_filter] using h) := by
|
||||
cases xs
|
||||
|
|
@ -330,7 +329,7 @@ theorem find?_pmap {P : α → Prop} {f : (a : α) → P a → β} {xs : Array
|
|||
rfl
|
||||
|
||||
theorem find?_eq_some_iff_getElem {xs : Array α} {p : α → Bool} {b : α} :
|
||||
xs.find? p = some b ↔ p b ∧ ∃ (i : Nat) (h : i < xs.size), xs[i] = b ∧ ∀ j : Nat, (hj : j < i) → !p xs[j] := by
|
||||
xs.find? p = some b ↔ p b ∧ ∃ i h, xs[i] = b ∧ ∀ j : Nat, (hj : j < i) → !p xs[j] := by
|
||||
rcases xs with ⟨xs⟩
|
||||
simp [List.find?_eq_some_iff_getElem]
|
||||
|
||||
|
|
@ -618,7 +617,7 @@ theorem findFinIdx?_congr {p : α → Bool} {xs ys : Array α} (w : xs = ys) :
|
|||
theorem findFinIdx?_eq_pmap_findIdx? {xs : Array α} {p : α → Bool} :
|
||||
xs.findFinIdx? p =
|
||||
(xs.findIdx? p).pmap
|
||||
(fun i m => by simp [findIdx?_eq_some_iff_getElem] at m; exact ⟨i, sorry⟩)
|
||||
(fun i m => by simp [findIdx?_eq_some_iff_getElem] at m; exact ⟨i, m.choose⟩)
|
||||
(fun i h => h) := by
|
||||
simp [findIdx?_eq_map_findFinIdx?_val, Option.pmap_map]
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ Proves various lemmas about `Array.insertIdx`.
|
|||
|
||||
set_option linter.listVariables true -- Enforce naming conventions for `List`/`Array`/`Vector` variables.
|
||||
set_option linter.indexVariables true -- Enforce naming conventions for index variables.
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
|
||||
open Function
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ public section
|
|||
|
||||
set_option linter.listVariables true -- Enforce naming conventions for `List`/`Array`/`Vector` variables.
|
||||
set_option linter.indexVariables true -- Enforce naming conventions for index variables.
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
|
||||
namespace Array
|
||||
|
||||
|
|
@ -468,17 +467,17 @@ theorem getElem_of_mem {a} {xs : Array α} (h : a ∈ xs) : ∃ (i : Nat) (h : i
|
|||
simp [List.getElem_of_mem (by simpa using h)]
|
||||
|
||||
theorem getElem?_of_mem {a} {xs : Array α} (h : a ∈ xs) : ∃ i : Nat, xs[i]? = some a :=
|
||||
let ⟨n, hn, e⟩ := getElem_of_mem h; ⟨n, e ▸ getElem?_eq_getElem hn⟩
|
||||
let ⟨n, _, e⟩ := getElem_of_mem h; ⟨n, e ▸ getElem?_eq_getElem _⟩
|
||||
|
||||
theorem mem_of_getElem {xs : Array α} {i : Nat} {h : i < xs.size} {a : α} (e : xs[i] = a) : a ∈ xs := by
|
||||
theorem mem_of_getElem {xs : Array α} {i : Nat} {h} {a : α} (e : xs[i] = a) : a ∈ xs := by
|
||||
subst e
|
||||
simp
|
||||
|
||||
theorem mem_of_getElem? {xs : Array α} {i : Nat} {a : α} (e : xs[i]? = some a) : a ∈ xs :=
|
||||
let ⟨h, e⟩ := getElem?_eq_some_iff.1 e; e ▸ getElem_mem (h := h)
|
||||
let ⟨_, e⟩ := getElem?_eq_some_iff.1 e; e ▸ getElem_mem ..
|
||||
|
||||
theorem mem_iff_getElem {a} {xs : Array α} : a ∈ xs ↔ ∃ (i : Nat) (h : i < xs.size), xs[i]'h = a :=
|
||||
⟨getElem_of_mem, fun ⟨_, h, e⟩ => e ▸ getElem_mem (h := h)⟩
|
||||
⟨getElem_of_mem, fun ⟨_, _, e⟩ => e ▸ getElem_mem ..⟩
|
||||
|
||||
theorem mem_iff_getElem? {a} {xs : Array α} : a ∈ xs ↔ ∃ i : Nat, xs[i]? = some a := by
|
||||
simp [getElem?_eq_some_iff, mem_iff_getElem]
|
||||
|
|
@ -903,7 +902,7 @@ theorem all_push {xs : Array α} {a : α} {p : α → Bool} :
|
|||
cases xs
|
||||
simp
|
||||
|
||||
theorem set_push {xs : Array α} {x y : α} {h : i < (xs.push x).size} :
|
||||
theorem set_push {xs : Array α} {x y : α} {h} :
|
||||
(xs.push x).set i y = if _ : i < xs.size then (xs.set i y).push x else xs.push y := by
|
||||
ext j hj
|
||||
· split <;> simp
|
||||
|
|
@ -2761,7 +2760,7 @@ theorem getElem_extract_loop_lt_aux {xs ys : Array α} {size start : Nat} (hlt :
|
|||
exact Nat.le_add_right ..
|
||||
|
||||
theorem getElem_extract_loop_lt {xs ys : Array α} {size start : Nat} (hlt : i < ys.size)
|
||||
(h : i < (extract.loop xs size start ys).size := getElem_extract_loop_lt_aux (xs := xs) (size := size) (start := start) hlt) :
|
||||
(h := getElem_extract_loop_lt_aux hlt) :
|
||||
(extract.loop xs size start ys)[i] = ys[i] := by
|
||||
apply Eq.trans _ (getElem_append_left (ys := extract.loop xs size start #[]) hlt)
|
||||
· rw [size_append]; exact Nat.lt_of_lt_of_le hlt (Nat.le_add_right ..)
|
||||
|
|
@ -4003,9 +4002,9 @@ theorem getElem_swap {xs : Array α} {i j : Nat} (hi hj) {k : Nat} (hk : k < (xs
|
|||
simp [getElem_swap, hi', hj']
|
||||
|
||||
@[deprecated getElem_swap (since := "2025-10-10")]
|
||||
theorem getElem_swap' {xs : Array α} {i j : Nat} {hi : i < xs.size} {hj : j < xs.size} {k : Nat} (hk : k < xs.size) :
|
||||
theorem getElem_swap' {xs : Array α} {i j : Nat} {hi hj} {k : Nat} (hk : k < xs.size) :
|
||||
(xs.swap i j hi hj)[k]'(by simp_all) = if k = i then xs[j] else if k = j then xs[i] else xs[k] :=
|
||||
getElem_swap hi hj (by simp_all)
|
||||
getElem_swap _ _ _
|
||||
|
||||
@[simp] theorem swap_swap {xs : Array α} {i j : Nat} (hi hj) :
|
||||
(xs.swap i j hi hj).swap i j ((xs.size_swap ..).symm ▸ hi) ((xs.size_swap ..).symm ▸ hj) = xs := by
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ open Std
|
|||
|
||||
set_option linter.listVariables true -- Enforce naming conventions for `List`/`Array`/`Vector` variables.
|
||||
set_option linter.indexVariables true -- Enforce naming conventions for index variables.
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
|
||||
namespace Array
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ public section
|
|||
|
||||
set_option linter.listVariables true -- Enforce naming conventions for `List`/`Array`/`Vector` variables.
|
||||
set_option linter.indexVariables true -- Enforce naming conventions for index variables.
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
|
||||
namespace Array
|
||||
|
||||
|
|
|
|||
|
|
@ -17,11 +17,11 @@ namespace Array
|
|||
|
||||
theorem sizeOf_lt_of_mem [SizeOf α] {as : Array α} (h : a ∈ as) : sizeOf a < sizeOf as := by
|
||||
cases as with | _ as
|
||||
exact Nat.lt_trans (List.sizeOf_lt_of_mem h.val) (by sorry)
|
||||
exact Nat.lt_trans (List.sizeOf_lt_of_mem h.val) (by simp +arith)
|
||||
|
||||
theorem sizeOf_get [SizeOf α] (as : Array α) (i : Nat) (h : i < as.size) : sizeOf as[i] < sizeOf as := by
|
||||
cases as with | _ as
|
||||
simpa using Nat.lt_trans (List.sizeOf_get _ ⟨i, h⟩) (by sorry)
|
||||
simpa using Nat.lt_trans (List.sizeOf_get _ ⟨i, h⟩) (by simp +arith)
|
||||
|
||||
@[simp] theorem sizeOf_getElem [SizeOf α] (as : Array α) (i : Nat) (h : i < as.size) :
|
||||
sizeOf (as[i]'h) < sizeOf as := sizeOf_get _ _ h
|
||||
|
|
@ -34,8 +34,8 @@ macro "array_get_dec" : tactic =>
|
|||
-- subsumed by simp
|
||||
-- | with_reducible apply sizeOf_get
|
||||
-- | with_reducible apply sizeOf_getElem
|
||||
| (with_reducible apply Nat.lt_of_lt_of_le (sizeOf_get ..)); sorry
|
||||
| (with_reducible apply Nat.lt_of_lt_of_le (sizeOf_getElem ..)); sorry
|
||||
| (with_reducible apply Nat.lt_of_lt_of_le (sizeOf_get ..)); simp +arith
|
||||
| (with_reducible apply Nat.lt_of_lt_of_le (sizeOf_getElem ..)); simp +arith
|
||||
)
|
||||
|
||||
macro_rules | `(tactic| decreasing_trivial) => `(tactic| array_get_dec)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ public section
|
|||
|
||||
set_option linter.listVariables true -- Enforce naming conventions for `List`/`Array`/`Vector` variables.
|
||||
set_option linter.indexVariables true -- Enforce naming conventions for index variables.
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
|
||||
namespace Array
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ public section
|
|||
|
||||
set_option linter.listVariables true -- Enforce naming conventions for `List`/`Array`/`Vector` variables.
|
||||
set_option linter.indexVariables true -- Enforce naming conventions for index variables.
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
|
||||
namespace Array
|
||||
|
||||
|
|
|
|||
|
|
@ -739,8 +739,6 @@ def hash (bv : BitVec n) : UInt64 :=
|
|||
bv.toFin.val.toUInt64
|
||||
else
|
||||
mixHash (bv.toFin.val.toUInt64) (hash ((bv >>> 64).setWidth (n - 64)))
|
||||
termination_by n
|
||||
-- decreasing_by sorry -- TODO: restore after bootstrap
|
||||
|
||||
instance : Hashable (BitVec n) where
|
||||
hash := hash
|
||||
|
|
|
|||
|
|
@ -1004,8 +1004,42 @@ theorem lawful_divSubtractShift (qr : DivModState w) (h : qr.Poised args) :
|
|||
have ⟨⟨hrwn, hd, hrd, hr, hn, hrnd⟩, hwn_lt⟩ := h
|
||||
have : d.toNat * (qr.q.toNat * 2) = d.toNat * qr.q.toNat * 2 := by rw [Nat.mul_assoc]
|
||||
by_cases rltd : shiftConcat qr.r (n.getLsbD (qr.wn - 1)) < d
|
||||
· sorry
|
||||
· sorry
|
||||
· simp only [rltd, ↓reduceIte]
|
||||
constructor <;> try bv_omega
|
||||
case pos.hrWidth => apply toNat_shiftConcat_lt_of_lt <;> omega
|
||||
case pos.hqWidth => apply toNat_shiftConcat_lt_of_lt <;> omega
|
||||
case pos.hdiv =>
|
||||
simp [qr.toNat_shiftRight_sub_one_eq h, h.hdiv, this,
|
||||
toNat_shiftConcat_eq_of_lt (qr.wr_lt_w h) h.hrWidth,
|
||||
toNat_shiftConcat_eq_of_lt (qr.wr_lt_w h) h.hqWidth]
|
||||
omega
|
||||
· simp only [rltd, ↓reduceIte]
|
||||
constructor <;> try bv_omega
|
||||
case neg.hrLtDivisor =>
|
||||
simp only [lt_def, Nat.not_lt] at rltd
|
||||
rw [BitVec.toNat_sub_of_le rltd,
|
||||
toNat_shiftConcat_eq_of_lt (hk := qr.wr_lt_w h) (hx := h.hrWidth),
|
||||
Nat.mul_comm]
|
||||
apply two_mul_add_sub_lt_of_lt_of_lt_two <;> bv_omega
|
||||
case neg.hrWidth =>
|
||||
simp only
|
||||
have hdr' : d ≤ (qr.r.shiftConcat (n.getLsbD (qr.wn - 1))) :=
|
||||
BitVec.not_lt.mp rltd
|
||||
have hr' : ((qr.r.shiftConcat (n.getLsbD (qr.wn - 1)))).toNat < 2 ^ (qr.wr + 1) := by
|
||||
apply toNat_shiftConcat_lt_of_lt <;> bv_omega
|
||||
rw [BitVec.toNat_sub_of_le hdr']
|
||||
omega
|
||||
case neg.hqWidth =>
|
||||
apply toNat_shiftConcat_lt_of_lt <;> omega
|
||||
case neg.hdiv =>
|
||||
have rltd' := (BitVec.not_lt.mp rltd)
|
||||
simp only [qr.toNat_shiftRight_sub_one_eq h,
|
||||
BitVec.toNat_sub_of_le rltd',
|
||||
toNat_shiftConcat_eq_of_lt (qr.wr_lt_w h) h.hrWidth]
|
||||
simp only [BitVec.le_def,
|
||||
toNat_shiftConcat_eq_of_lt (qr.wr_lt_w h) h.hrWidth] at rltd'
|
||||
simp only [toNat_shiftConcat_eq_of_lt (qr.wr_lt_w h) h.hqWidth, h.hdiv, Nat.mul_add]
|
||||
bv_omega
|
||||
|
||||
/-! ### Core division algorithm circuit -/
|
||||
|
||||
|
|
|
|||
|
|
@ -4244,8 +4244,8 @@ theorem udiv_one {x : BitVec w} : x / 1#w = x := by
|
|||
@[simp]
|
||||
theorem udiv_eq_and {x y : BitVec 1} :
|
||||
x / y = (x &&& y) := by
|
||||
have hx : x = 0#1 ∨ x = 1#1 := by sorry
|
||||
have hy : y = 0#1 ∨ y = 1#1 := by sorry
|
||||
have hx : x = 0#1 ∨ x = 1#1 := by bv_omega
|
||||
have hy : y = 0#1 ∨ y = 1#1 := by bv_omega
|
||||
rcases hx with rfl | rfl <;>
|
||||
rcases hy with rfl | rfl <;>
|
||||
rfl
|
||||
|
|
@ -4347,8 +4347,8 @@ theorem umod_self {x : BitVec w} : x % x = 0#w := by
|
|||
|
||||
@[simp]
|
||||
theorem umod_eq_and {x y : BitVec 1} : x % y = x &&& (~~~y) := by
|
||||
have hx : x = 0#1 ∨ x = 1#1 := by sorry
|
||||
have hy : y = 0#1 ∨ y = 1#1 := by sorry
|
||||
have hx : x = 0#1 ∨ x = 1#1 := by bv_omega
|
||||
have hy : y = 0#1 ∨ y = 1#1 := by bv_omega
|
||||
rcases hx with rfl | rfl <;>
|
||||
rcases hy with rfl | rfl <;>
|
||||
rfl
|
||||
|
|
@ -4469,8 +4469,8 @@ theorem sdiv_one {x : BitVec w} : x.sdiv 1#w = x := by
|
|||
· rcases x.msb with msb | msb <;> simp [h]
|
||||
|
||||
theorem sdiv_eq_and (x y : BitVec 1) : x.sdiv y = x &&& y := by
|
||||
have hx : x = 0#1 ∨ x = 1#1 := by sorry
|
||||
have hy : y = 0#1 ∨ y = 1#1 := by sorry
|
||||
have hx : x = 0#1 ∨ x = 1#1 := by bv_omega
|
||||
have hy : y = 0#1 ∨ y = 1#1 := by bv_omega
|
||||
rcases hx with rfl | rfl <;>
|
||||
rcases hy with rfl | rfl <;>
|
||||
simp
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ def toList (bs : ByteArray) : List UInt8 :=
|
|||
else
|
||||
r.reverse
|
||||
termination_by bs.size - i
|
||||
-- decreasing_by decreasing_trivial_pre_omega
|
||||
decreasing_by decreasing_trivial_pre_omega
|
||||
loop 0 []
|
||||
|
||||
/--
|
||||
|
|
@ -190,7 +190,7 @@ The index is returned along with a proof that it is a valid index in the array.
|
|||
else
|
||||
none
|
||||
termination_by a.size - i
|
||||
-- decreasing_by decreasing_trivial_pre_omega
|
||||
decreasing_by decreasing_trivial_pre_omega
|
||||
loop start
|
||||
|
||||
/--
|
||||
|
|
@ -206,7 +206,7 @@ The variant {name}`findFinIdx?` additionally returns a proof that the found inde
|
|||
else
|
||||
none
|
||||
termination_by a.size - i
|
||||
-- decreasing_by decreasing_trivial_pre_omega
|
||||
decreasing_by decreasing_trivial_pre_omega
|
||||
loop start
|
||||
|
||||
/--
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@ public import Init.Data.ByteArray.Basic
|
|||
|
||||
public section
|
||||
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
|
||||
namespace ByteArray
|
||||
|
||||
-- At present the preferred normal form for empty byte arrays is `ByteArray.empty`
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ Example:
|
|||
@[specialize] loop (x : α) (i : Nat) : α :=
|
||||
if h : i < n then loop (f x ⟨i, h⟩) (i+1) else x
|
||||
termination_by n - i
|
||||
-- decreasing_by sorry -- TODO: restore after bootstrap
|
||||
|
||||
/--
|
||||
Combine all the values that can be represented by `Fin n` with an initial value, starting at `n - 1`
|
||||
|
|
@ -68,7 +67,7 @@ Fin.foldlM n f x₀ = do
|
|||
@[specialize] loop (x : α) (i : Nat) : m α := do
|
||||
if h : i < n then f x ⟨i, h⟩ >>= (loop · (i+1)) else pure x
|
||||
termination_by n - i
|
||||
-- decreasing_by decreasing_trivial_pre_omega
|
||||
decreasing_by decreasing_trivial_pre_omega
|
||||
|
||||
/--
|
||||
Folds a monadic function over `Fin n` from right to left, starting with `n-1`.
|
||||
|
|
@ -99,8 +98,6 @@ Fin.foldrM n f xₙ = do
|
|||
@[specialize] loop : {i // i ≤ n} → α → m α
|
||||
| ⟨0, _⟩, x => pure x
|
||||
| ⟨i+1, h⟩, x => f ⟨i, h⟩ x >>= loop ⟨i, Nat.le_of_lt h⟩
|
||||
termination_by i => i.val
|
||||
-- decreasing_by sorry -- TODO: restore after bootstrap
|
||||
|
||||
/-! ### foldlM -/
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ def hIterateFrom (P : Nat → Sort _) {n} (f : ∀(i : Fin n), P i.val → P (i.
|
|||
have p : i = n := (or_iff_left g).mp (Nat.eq_or_lt_of_le ubnd)
|
||||
_root_.cast (congrArg P p) a
|
||||
termination_by n - i
|
||||
-- decreasing_by decreasing_trivial_pre_omega
|
||||
decreasing_by decreasing_trivial_pre_omega
|
||||
|
||||
/--
|
||||
Applies an index-dependent function to all the values less than the given bound `n`, starting at
|
||||
|
|
|
|||
|
|
@ -2787,7 +2787,10 @@ theorem bmod_le {x : Int} {m : Nat} (h : 0 < m) : bmod x m ≤ (m - 1) / 2 := by
|
|||
_ = ((m + 1 - 2) + 2)/2 := by simp
|
||||
_ = (m - 1) / 2 + 1 := by
|
||||
rw [add_ediv_of_dvd_right]
|
||||
· sorry
|
||||
· simp +decide only [Int.ediv_self]
|
||||
congr 2
|
||||
rw [Int.add_sub_assoc, ← Int.sub_neg]
|
||||
congr
|
||||
· trivial
|
||||
|
||||
theorem bmod_natAbs_add_one (x : Int) (w : x ≠ -1) : x.bmod (x.natAbs + 1) = -x.sign := by
|
||||
|
|
|
|||
|
|
@ -414,7 +414,7 @@ attribute [local simp] Poly.denote_append
|
|||
|
||||
theorem Poly.denote_combine' (ctx : Context) (fuel : Nat) (p₁ p₂ : Poly) : (p₁.combine' fuel p₂).denote ctx = p₁.denote ctx + p₂.denote ctx := by
|
||||
fun_induction p₁.combine' fuel p₂ <;>
|
||||
sorry
|
||||
simp_all +zetaDelta [denote, ← Int.add_mul]
|
||||
|
||||
theorem Poly.denote_combine (ctx : Context) (p₁ p₂ : Poly) : (p₁.combine p₂).denote ctx = p₁.denote ctx + p₂.denote ctx := by
|
||||
simp [combine, denote_combine']
|
||||
|
|
|
|||
|
|
@ -1343,8 +1343,9 @@ theorem neg_of_sign_eq_neg_one : ∀ {a : Int}, sign a = -1 → a < 0
|
|||
match x with
|
||||
| 0 => rfl
|
||||
| .ofNat (_ + 1) =>
|
||||
sorry
|
||||
| .negSucc _ => sorry
|
||||
simp +decide only [sign, true_iff]
|
||||
exact Int.le_add_one (natCast_nonneg _)
|
||||
| .negSucc _ => simp +decide [sign]
|
||||
|
||||
@[simp] theorem sign_pos_iff : 0 < sign x ↔ 0 < x := by
|
||||
match x with
|
||||
|
|
|
|||
|
|
@ -71,7 +71,14 @@ def Attach.instProductivenessRelation {α β : Type w} {m : Type w → Type w'}
|
|||
wf := InvImage.wf _ WellFoundedRelation.wf
|
||||
subrelation {it it'} h := by
|
||||
apply Relation.TransGen.single
|
||||
sorry
|
||||
simp_wf
|
||||
obtain ⟨step, hs⟩ := h
|
||||
cases step using PlausibleIterStep.casesOn
|
||||
· simp [Monadic.modifyStep] at hs
|
||||
· simp only [Monadic.modifyStep, IterStep.skip.injEq] at hs
|
||||
simp only [← hs]
|
||||
assumption
|
||||
· simp [Monadic.modifyStep] at hs
|
||||
|
||||
instance Attach.instProductive {α β : Type w} {m : Type w → Type w'} [Monad m]
|
||||
[Iterator α m β] [Productive α m] {P : β → Prop} :
|
||||
|
|
|
|||
|
|
@ -149,6 +149,9 @@ def IterM.DefaultConsumers.forIn'.wf {m : Type w → Type w'} {α : Type w} {β
|
|||
(fun _ h' => hP _ <| .indirect ⟨_, rfl, h⟩ h') f
|
||||
| .done _ => return init
|
||||
termination_by IteratorLoop.WithWF.mk it init (hwf := wf)
|
||||
decreasing_by
|
||||
· exact Or.inl ⟨out, ‹_›, ‹_›⟩
|
||||
· exact Or.inr ⟨‹_›, rfl⟩
|
||||
|
||||
/--
|
||||
This is the default implementation of the `IteratorLoop` class.
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ def Iter.inductSteps {α β} [Iterator α Id β] [Finite α Id]
|
|||
(fun {it' _} _ => inductSteps motive step it')
|
||||
(fun {it'} _ => inductSteps motive step it')
|
||||
termination_by it.finitelyManySteps
|
||||
decreasing_by all_goals sorry -- TODO: restore after bootstrap
|
||||
|
||||
/--
|
||||
Induction principle for productive iterators: One can define a function `f` that maps every
|
||||
|
|
@ -47,6 +46,5 @@ def Iter.inductSkips {α β} [Iterator α Id β] [Productive α Id]
|
|||
(it : Iter (α := α) β) : motive it :=
|
||||
step it (fun {it'} _ => inductSkips motive step it')
|
||||
termination_by it.finitelyManySkips
|
||||
decreasing_by all_goals sorry -- TODO: restore after bootstrap
|
||||
|
||||
end Std
|
||||
|
|
|
|||
|
|
@ -403,7 +403,17 @@ private theorem IterM.toList_filterMapWithPostcondition_filterMapWithPostconditi
|
|||
rw [bind_eq_bind_subtypeCasesOn'_optionPelim' (x := (fg _).operation)]
|
||||
simp only [pure_bind, Shrink.inflate_deflate]
|
||||
rw [bind_subtypeCasesOn'_eq_map_bind]
|
||||
sorry
|
||||
conv =>
|
||||
lhs
|
||||
rw [bind_eq_bind_subtypeCasesOn'_optionPelim']
|
||||
simp only [liftM_pure, pure_bind, Shrink.inflate_deflate, bind_assoc]
|
||||
simp +singlePass only [bind_eq_bind_subtypeCasesOn'_optionPelim' (x := (g _).operation)]
|
||||
simp only [pure_bind, Shrink.inflate_deflate]
|
||||
simp only [bind_subtypeCasesOn'_eq_map_bind]
|
||||
rw [← liftM_map]
|
||||
simp only [← PostconditionT.run_eq_map, h, bind_assoc, optionPelim']
|
||||
apply bind_congr; intro fx
|
||||
split <;> simp [ihy ‹_›]
|
||||
· simp [ihs ‹_›]
|
||||
· simp
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,9 @@ theorem Iter.forIn'_eq {α β : Type w} [Iterator α Id β] [Finite α Id]
|
|||
(fun out h acc => return ⟨← f out (Iter.isPlausibleIndirectOutput_iff_isPlausibleIndirectOutput_toIterM.mpr h) acc, trivial⟩) := by
|
||||
simp only [instForIn', ForIn'.forIn', IteratorLoop.finiteForIn']
|
||||
have : ∀ a b c, f a b c = (Subtype.val <$> (⟨·, trivial⟩) <$> f a b c) := by simp
|
||||
sorry
|
||||
simp +singlePass only [this]
|
||||
rw [hl.lawful (fun _ _ f x => f x.run) (wf := IteratorLoop.wellFounded_of_finite)]
|
||||
simp [IteratorLoop.defaultImplementation]
|
||||
|
||||
theorem Iter.forIn_eq {α β : Type w} [Iterator α Id β] [Finite α Id]
|
||||
{m : Type x → Type x'} [Monad m] [LawfulMonad m] [IteratorLoop α Id m]
|
||||
|
|
|
|||
|
|
@ -172,6 +172,9 @@ theorem IterM.DefaultConsumers.forIn'_eq_forIn' {m : Type w → Type w'} {α : T
|
|||
· apply IterM.DefaultConsumers.forIn'_eq_forIn' <;> assumption
|
||||
· rfl
|
||||
termination_by IteratorLoop.WithWF.mk it init (hwf := wf)
|
||||
decreasing_by
|
||||
· exact Or.inl ⟨_, ‹_›, ‹_›⟩
|
||||
· exact Or.inr ⟨‹_›, rfl⟩
|
||||
|
||||
theorem IterM.forIn'_eq_match_step {α β : Type w} {m : Type w → Type w'} [Iterator α m β]
|
||||
[Finite α m] {n : Type w → Type w''} [Monad m] [Monad n] [LawfulMonad n]
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ def IterM.inductSteps {α m β} [Iterator α m β] [Finite α m]
|
|||
(fun {it' _} _ => inductSteps motive step it')
|
||||
(fun {it'} _ => inductSteps motive step it')
|
||||
termination_by it.finitelyManySteps
|
||||
decreasing_by all_goals sorry -- TODO: restore after bootstrap
|
||||
|
||||
/--
|
||||
Induction principle for productive monadic iterators: One can define a function `f` that maps every
|
||||
|
|
@ -47,6 +46,5 @@ def IterM.inductSkips {α m β} [Iterator α m β] [Productive α m]
|
|||
(it : IterM (α := α) m β) : motive it :=
|
||||
step it (fun {it'} _ => inductSkips motive step it')
|
||||
termination_by it.finitelyManySkips
|
||||
decreasing_by all_goals sorry -- TODO: restore after bootstrap
|
||||
|
||||
end Std
|
||||
|
|
|
|||
|
|
@ -68,6 +68,8 @@ private def ListIterator.instFinitenessRelation [Pure m] :
|
|||
wf := InvImage.wf _ WellFoundedRelation.wf
|
||||
subrelation {it it'} h := by
|
||||
simp_wf
|
||||
obtain ⟨step, h, h'⟩ := h
|
||||
cases step <;> simp_all [IterStep.successor, IterM.IsPlausibleStep, Iterator.IsPlausibleStep]
|
||||
|
||||
instance ListIterator.instFinite [Pure m] : Finite (ListIterator α) m :=
|
||||
by exact Finite.of_finitenessRelation ListIterator.instFinitenessRelation
|
||||
|
|
|
|||
|
|
@ -274,7 +274,7 @@ theorem getElem?_attach {xs : List α} {i : Nat} :
|
|||
theorem getElem_attachWith {xs : List α} {P : α → Prop} {H : ∀ a ∈ xs, P a}
|
||||
{i : Nat} (h : i < (xs.attachWith P H).length) :
|
||||
(xs.attachWith P H)[i] = ⟨xs[i]'(by simpa using h), H _ (getElem_mem (by simpa using h))⟩ :=
|
||||
getElem_pmap (hn := h) ..
|
||||
getElem_pmap ..
|
||||
|
||||
@[simp, grind =]
|
||||
theorem getElem_attach {xs : List α} {i : Nat} (h : i < xs.attach.length) :
|
||||
|
|
|
|||
|
|
@ -224,8 +224,8 @@ theorem getElem_append_right {as bs : List α} {i : Nat} (h₁ : as.length ≤ i
|
|||
|
||||
theorem sizeOf_lt_of_mem [SizeOf α] {as : List α} (h : a ∈ as) : sizeOf a < sizeOf as := by
|
||||
induction h with
|
||||
| head => sorry
|
||||
| tail _ _ ih => exact Nat.lt_trans ih (by sorry)
|
||||
| head => simp +arith
|
||||
| tail _ _ ih => exact Nat.lt_trans ih (by simp +arith)
|
||||
|
||||
/-- This tactic, added to the `decreasing_trivial` toolbox, proves that
|
||||
`sizeOf a < sizeOf as` when `a ∈ as`, which is useful for well founded recursions
|
||||
|
|
@ -236,7 +236,7 @@ macro "sizeOf_list_dec" : tactic =>
|
|||
| with_reducible
|
||||
apply Nat.lt_of_lt_of_le (sizeOf_lt_of_mem ?h)
|
||||
case' h => assumption
|
||||
sorry)
|
||||
simp +arith)
|
||||
|
||||
macro_rules | `(tactic| decreasing_trivial) => `(tactic| sizeOf_list_dec)
|
||||
|
||||
|
|
@ -250,8 +250,8 @@ theorem append_cancel_left {as bs cs : List α} (h : as ++ bs = as ++ cs) : bs =
|
|||
theorem append_cancel_right {as bs cs : List α} (h : as ++ bs = cs ++ bs) : as = cs := by
|
||||
match as, cs with
|
||||
| [], [] => rfl
|
||||
| [], c::cs => have aux := congrArg length h; sorry
|
||||
| a::as, [] => have aux := congrArg length h; sorry
|
||||
| [], c::cs => have aux := congrArg length h; simp +arith at aux
|
||||
| a::as, [] => have aux := congrArg length h; simp +arith at aux
|
||||
| a::as, c::cs => injection h with h₁ h₂; subst h₁; rw [append_cancel_right h₂]
|
||||
|
||||
@[simp] theorem append_cancel_left_eq (as bs cs : List α) : (as ++ bs = as ++ cs) = (bs = cs) := by
|
||||
|
|
@ -266,11 +266,11 @@ theorem append_cancel_right {as bs cs : List α} (h : as ++ bs = cs ++ bs) : as
|
|||
|
||||
theorem sizeOf_get [SizeOf α] (as : List α) (i : Fin as.length) : sizeOf (as.get i) < sizeOf as := by
|
||||
match as, i with
|
||||
| a::as, ⟨0, _⟩ => sorry
|
||||
| a::as, ⟨0, _⟩ => simp +arith [get]
|
||||
| a::as, ⟨i+1, h⟩ =>
|
||||
have ih := sizeOf_get as ⟨i, Nat.le_of_succ_le_succ h⟩
|
||||
apply Nat.lt_trans ih
|
||||
sorry
|
||||
simp +arith
|
||||
|
||||
theorem lex_trichotomous [DecidableEq α] {r : α → α → Prop} [DecidableRel r]
|
||||
(trichotomous : ∀ x y : α, ¬ r x y → ¬ r y x → x = y)
|
||||
|
|
|
|||
|
|
@ -376,7 +376,7 @@ theorem replicate_count_eq_of_count_eq_length {l : List α} (h : count a l = len
|
|||
theorem count_le_count_map {β} [BEq β] [LawfulBEq β] {l : List α} {f : α → β} {x : α} :
|
||||
count x l ≤ count (f x) (map f l) := by
|
||||
rw [count, count, countP_map]
|
||||
apply countP_mono_left; sorry
|
||||
apply countP_mono_left; simp +contextual
|
||||
|
||||
theorem count_filterMap {α} [BEq β] {b : β} {f : α → Option β} {l : List α} :
|
||||
count b (filterMap f l) = countP (fun a => f a == some b) l := by
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ and `List.lookup`.
|
|||
|
||||
set_option linter.listVariables true -- Enforce naming conventions for `List`/`Array`/`Vector` variables.
|
||||
set_option linter.indexVariables true -- Enforce naming conventions for index variables.
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
|
||||
|
||||
namespace List
|
||||
|
|
@ -1006,7 +1005,7 @@ theorem findIdx?_eq_map_findFinIdx?_val {xs : List α} {p : α → Bool} :
|
|||
theorem findFinIdx?_eq_pmap_findIdx? {xs : List α} {p : α → Bool} :
|
||||
xs.findFinIdx? p =
|
||||
(xs.findIdx? p).pmap
|
||||
(fun i m => ⟨i, sorry⟩) -- TODO: restore proof after bootstrap: by simp [findIdx?_eq_some_iff_getElem] at m; exact ⟨i, m.choose⟩
|
||||
(fun i m => by simp [findIdx?_eq_some_iff_getElem] at m; exact ⟨i, m.choose⟩)
|
||||
(fun i h => h) := by
|
||||
simp [findIdx?_eq_map_findFinIdx?_val, Option.pmap_map]
|
||||
|
||||
|
|
|
|||
|
|
@ -560,7 +560,7 @@ def zipIdxTR (l : List α) (n : Nat := 0) : List (α × Nat) :=
|
|||
rw [← show _ + as.length = n + (a::as).length from Nat.succ_add .., foldr, go as]
|
||||
simp [zipIdx, f]
|
||||
rw [← Array.foldr_toList]
|
||||
sorry
|
||||
simp +zetaDelta [go]
|
||||
|
||||
/-! ### enumFrom -/
|
||||
|
||||
|
|
|
|||
|
|
@ -309,7 +309,7 @@ theorem ext_getElem {l₁ l₂ : List α} (hl : length l₁ = length l₂)
|
|||
theorem ext_getElem_iff {l₁ l₂ : List α} :
|
||||
l₁ = l₂ ↔ l₁.length = l₂.length ∧ ∀ (i : Nat) (h₁ : i < l₁.length) (h₂ : i < l₂.length), l₁[i]'h₁ = l₂[i]'h₂ := by
|
||||
constructor
|
||||
· sorry
|
||||
· simp +contextual
|
||||
· exact fun h => ext_getElem h.1 h.2
|
||||
|
||||
@[simp] theorem getElem_concat_length {l : List α} {a : α} {i : Nat} (h : i = l.length) (w) :
|
||||
|
|
@ -469,7 +469,7 @@ theorem getElem?_of_mem {a} {l : List α} (h : a ∈ l) : ∃ i : Nat, l[i]? = s
|
|||
let ⟨n, _, e⟩ := getElem_of_mem h
|
||||
exact ⟨n, e ▸ getElem?_eq_getElem _⟩
|
||||
|
||||
theorem mem_of_getElem {l : List α} {i : Nat} {h : i < l.length} {a : α} (e : l[i] = a) : a ∈ l := by
|
||||
theorem mem_of_getElem {l : List α} {i : Nat} {h} {a : α} (e : l[i] = a) : a ∈ l := by
|
||||
subst e
|
||||
simp
|
||||
|
||||
|
|
@ -755,7 +755,7 @@ theorem length_eq_of_beq [BEq α] {l₁ l₂ : List α} (h : l₁ == l₂) : l
|
|||
| succ n =>
|
||||
rw [replicate_succ, replicate_succ, cons_beq_cons, replicate_beq_replicate]
|
||||
rw [Bool.eq_iff_iff]
|
||||
sorry
|
||||
simp +contextual
|
||||
|
||||
@[simp] theorem reflBEq_iff [BEq α] : ReflBEq (List α) ↔ ReflBEq α := by
|
||||
constructor
|
||||
|
|
@ -1144,7 +1144,7 @@ theorem map_inj_right {f : α → β} (w : ∀ x y, f x = f y → x = y) : map f
|
|||
intro h
|
||||
constructor
|
||||
· apply w
|
||||
· sorry
|
||||
· simp +contextual
|
||||
|
||||
theorem map_congr_left (h : ∀ a ∈ l, f a = g a) : map f l = map g l :=
|
||||
map_inj_left.2 h
|
||||
|
|
@ -1622,7 +1622,7 @@ theorem getElem_append_right' (l₁ : List α) {l₂ : List α} {i : Nat} (hi :
|
|||
rw [getElem_append_right] <;> simp [*, le_add_left]
|
||||
|
||||
theorem getElem_of_append {l : List α} (eq : l = l₁ ++ a :: l₂) (h : l₁.length = i) :
|
||||
l[i]'(eq ▸ h ▸ by sorry) = a := Option.some.inj <| by
|
||||
l[i]'(eq ▸ h ▸ by simp +arith) = a := Option.some.inj <| by
|
||||
rw [← getElem?_eq_getElem, eq, getElem?_append_right (h ▸ Nat.le_refl _), h]
|
||||
simp
|
||||
|
||||
|
|
@ -3289,7 +3289,7 @@ theorem all_eq_not_any_not {l : List α} {p : α → Bool} : l.all p = !l.any (!
|
|||
|
||||
@[simp] theorem all_replicate {n : Nat} {a : α} :
|
||||
(replicate n a).all f = if n = 0 then true else f a := by
|
||||
cases n <;> sorry
|
||||
cases n <;> simp +contextual [replicate_succ]
|
||||
|
||||
theorem any_congr {l₁ l₂ : List α} (w : l₁ = l₂) {p q : α → Bool} (h : ∀ a, p a = q a) :
|
||||
l₁.any p = l₂.any q := by
|
||||
|
|
|
|||
|
|
@ -494,7 +494,7 @@ protected theorem le_iff_exists [LT α]
|
|||
rw [← lex_eq_false_iff_ge, lex_eq_false_iff_exists]
|
||||
· simp only [isEqv_eq, beq_iff_eq, decide_eq_true_eq]
|
||||
simp only [eq_comm]
|
||||
sorry
|
||||
conv => lhs; simp +singlePass [exists_comm]
|
||||
· simpa using Std.Irrefl.irrefl
|
||||
· simpa using Std.Asymm.asymm
|
||||
· simpa using Std.Trichotomous.trichotomous
|
||||
|
|
@ -552,7 +552,7 @@ protected theorem map_le [LT α] [LT β]
|
|||
simp
|
||||
· right
|
||||
refine ⟨i, by simpa using h₁, by simpa using h₂, ?_, ?_⟩
|
||||
· sorry
|
||||
· simp +contextual [w₁]
|
||||
· simpa using w _ _ w₂
|
||||
|
||||
end List
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ public section
|
|||
|
||||
set_option linter.listVariables true -- Enforce naming conventions for `List`/`Array`/`Vector` variables.
|
||||
set_option linter.indexVariables true -- Enforce naming conventions for index variables.
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
|
||||
namespace List
|
||||
|
||||
|
|
@ -105,15 +104,15 @@ theorem mapFinIdx_nil {f : (i : Nat) → α → (h : i < 0) → β} : mapFinIdx
|
|||
(as.mapFinIdx f).length = as.length := by
|
||||
simp [mapFinIdx, length_mapFinIdx_go]
|
||||
|
||||
theorem getElem_mapFinIdx_go {as : List α} {f : (i : Nat) → α → (h : i < as.length) → β} {i : Nat} {heq : bs.length + acc.size = as.length} {w : i < (mapFinIdx.go as f bs acc heq).length} :
|
||||
(mapFinIdx.go as f bs acc heq)[i] =
|
||||
theorem getElem_mapFinIdx_go {as : List α} {f : (i : Nat) → α → (h : i < as.length) → β} {i : Nat} {h} {w} :
|
||||
(mapFinIdx.go as f bs acc h)[i] =
|
||||
if w' : i < acc.size then
|
||||
acc[i]
|
||||
else
|
||||
f i (bs[i - acc.size]'(by simp at w; omega)) (by simp at w; omega) := by
|
||||
induction bs generalizing acc with
|
||||
| nil =>
|
||||
simp only [length_mapFinIdx_go, length_nil, Nat.zero_add] at w heq
|
||||
simp only [length_mapFinIdx_go, length_nil, Nat.zero_add] at w h
|
||||
simp only [mapFinIdx.go, Array.getElem_toList]
|
||||
rw [dif_pos]
|
||||
| cons _ _ ih =>
|
||||
|
|
@ -129,7 +128,7 @@ theorem getElem_mapFinIdx_go {as : List α} {f : (i : Nat) → α → (h : i < a
|
|||
· have h₃ : i - acc.size = (i - (acc.size + 1)) + 1 := by omega
|
||||
simp [h₃]
|
||||
|
||||
@[simp, grind =] theorem getElem_mapFinIdx {as : List α} {f : (i : Nat) → α → (h : i < as.length) → β} {i : Nat} {h : i < (as.mapFinIdx f).length} :
|
||||
@[simp, grind =] theorem getElem_mapFinIdx {as : List α} {f : (i : Nat) → α → (h : i < as.length) → β} {i : Nat} {h} :
|
||||
(as.mapFinIdx f)[i] = f i (as[i]'(by simp at h; omega)) (by simp at h; omega) := by
|
||||
simp [mapFinIdx, getElem_mapFinIdx_go]
|
||||
|
||||
|
|
|
|||
|
|
@ -123,7 +123,9 @@ private theorem exists_getElem_eq_of_drop_eq_cons {xs : List α} {k : Nat} {y :
|
|||
refine ⟨hlt, ?_⟩
|
||||
have := take_append_drop k xs
|
||||
rw [h] at this
|
||||
sorry
|
||||
simp +singlePass only [← this]
|
||||
rw [getElem_append_right (length_take_le _ _)]
|
||||
simp [length_take_of_le (Nat.le_of_lt hlt)]
|
||||
|
||||
private theorem take_succ_eq_append_of_drop_eq_cons {xs : List α} {k : Nat} {y : α}
|
||||
{ys : List α} (h : xs.drop k = y :: ys) : xs.take (k + 1) = xs.take k ++ [y] := by
|
||||
|
|
@ -209,7 +211,7 @@ protected theorem apply_minOn_lt_apply_getElem_of_lt_minIdxOn [LE β] [Decidable
|
|||
@[simp]
|
||||
protected theorem getElem_minIdxOn [LE β] [DecidableLE β] [IsLinearPreorder β]
|
||||
{f : α → β} {xs : List α} (h : xs ≠ []) :
|
||||
xs[xs.minIdxOn f h]'sorry = xs.minOn f h := by
|
||||
xs[xs.minIdxOn f h] = xs.minOn f h := by
|
||||
obtain ⟨i, hlt, hi, heq, h'⟩ := minIdxOn_eq_go_drop (f := f) h (k := xs.length)
|
||||
simp only [drop_eq_nil_of_le (as := xs) (i := xs.length + 1) (by omega), minIdxOn.go] at h'
|
||||
simp [h', heq, take_of_length_le (l := xs) (i := xs.length + 1) (by omega)]
|
||||
|
|
@ -409,7 +411,9 @@ private theorem minIdxOn_append_aux [LE β] [DecidableLE β]
|
|||
match xs with
|
||||
| [] => simp [minIdxOn_cons_aux (xs := ys) ‹_›]
|
||||
| z :: zs =>
|
||||
sorry
|
||||
simp +singlePass only [cons_append]
|
||||
simp only [minIdxOn_cons_aux (xs := z :: zs ++ ys) (by simp), ih (by simp),
|
||||
minIdxOn_cons_aux (xs := z :: zs) (by simp), combineMinIdxOn_assoc]
|
||||
|
||||
protected theorem minIdxOn_append [LE β] [DecidableLE β] [IsLinearPreorder β]
|
||||
{xs ys : List α} {f : α → β} (hxs : xs ≠ []) (hys : ys ≠ []) :
|
||||
|
|
@ -437,7 +441,8 @@ protected theorem minIdxOn_take_le [LE β] [DecidableLE β] [IsLinearPreorder β
|
|||
{xs : List α} {f : α → β} {i : Nat} (h : xs.take i ≠ []) :
|
||||
(xs.take i).minIdxOn f h ≤ xs.minIdxOn f (List.ne_nil_of_take_ne_nil h) := by
|
||||
have := take_append_drop i xs
|
||||
sorry
|
||||
conv => rhs; simp +singlePass only [← this]
|
||||
apply List.left_le_minIdxOn_append
|
||||
|
||||
@[simp]
|
||||
protected theorem minIdxOn_replicate [LE β] [DecidableLE β] [Refl (α := β) (· ≤ ·)]
|
||||
|
|
@ -498,7 +503,7 @@ protected theorem apply_maxOn_lt_apply_getElem_of_lt_maxIdxOn [LE β] [Decidable
|
|||
@[simp]
|
||||
protected theorem getElem_maxIdxOn [LE β] [DecidableLE β] [IsLinearPreorder β]
|
||||
{f : α → β} {xs : List α} (h : xs ≠ []) :
|
||||
xs[xs.maxIdxOn f h]'sorry = xs.maxOn f h := by
|
||||
xs[xs.maxIdxOn f h] = xs.maxOn f h := by
|
||||
simp only [List.maxIdxOn_eq_minIdxOn, List.maxOn_eq_minOn]
|
||||
letI : LE β := (inferInstanceAs (LE β)).opposite
|
||||
exact List.getElem_minIdxOn h
|
||||
|
|
@ -678,7 +683,7 @@ protected theorem get_minIdxOn?_lt_length [LE β] [DecidableLE β] {f : α →
|
|||
@[simp]
|
||||
protected theorem getElem_get_minIdxOn? [LE β] [DecidableLE β] [IsLinearPreorder β]
|
||||
{f : α → β} {xs : List α} (h : (xs.minIdxOn? f).isSome) :
|
||||
xs[(xs.minIdxOn? f).get h]'sorry = xs.minOn f (List.isSome_minIdxOn?_iff.mp h) := by
|
||||
xs[(xs.minIdxOn? f).get h] = xs.minOn f (List.isSome_minIdxOn?_iff.mp h) := by
|
||||
rw [getElem_congr rfl (List.get_minIdxOn?_eq_minIdxOn _), List.getElem_minIdxOn]
|
||||
|
||||
protected theorem minIdxOn?_eq_some_zero_iff [LE β] [DecidableLE β] [IsLinearPreorder β]
|
||||
|
|
@ -797,7 +802,7 @@ protected theorem get_maxIdxOn?_lt_length [LE β] [DecidableLE β] {f : α →
|
|||
@[simp]
|
||||
protected theorem getElem_get_maxIdxOn? [LE β] [DecidableLE β] [IsLinearPreorder β]
|
||||
{f : α → β} {xs : List α} (h : (xs.maxIdxOn? f).isSome) :
|
||||
xs[(xs.maxIdxOn? f).get h]'sorry = xs.maxOn f (List.isSome_maxIdxOn?_iff.mp h) := by
|
||||
xs[(xs.maxIdxOn? f).get h] = xs.maxOn f (List.isSome_maxIdxOn?_iff.mp h) := by
|
||||
simp only [List.maxIdxOn?_eq_minIdxOn?, List.maxOn_eq_minOn]
|
||||
letI : LE β := LE.opposite inferInstance
|
||||
exact List.getElem_get_minIdxOn? h
|
||||
|
|
|
|||
|
|
@ -249,7 +249,7 @@ protected theorem minOn_replicate [LE β] [DecidableLE β] [IsLinearPreorder β]
|
|||
· simp at h
|
||||
· rename_i n ih
|
||||
simp only [ne_eq, replicate_eq_nil_iff] at ih
|
||||
sorry
|
||||
simp +contextual [List.replicate, List.minOn_cons, ih]
|
||||
|
||||
/-! ### maxOn -/
|
||||
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ theorem getElem?_intersperse_two_mul_add_one (h : i + 1 < l.length) :
|
|||
· contradiction
|
||||
· rename_i hn _
|
||||
have ⟨_, tl, _⟩ := ne_nil_iff_exists_cons.mp hn
|
||||
cases tl <;> cases i <;> sorry
|
||||
cases tl <;> cases i <;> simp_all +arith
|
||||
|
||||
@[grind =]
|
||||
theorem getElem?_intersperse :
|
||||
|
|
@ -164,14 +164,16 @@ theorem getElem?_intersperse :
|
|||
omega
|
||||
|
||||
@[grind =]
|
||||
theorem getElem_intersperse (h : i < (l.intersperse sep).length) :
|
||||
theorem getElem_intersperse (h) :
|
||||
(l.intersperse sep)[i] =
|
||||
if i % 2 = 0 then l[i / 2]'(by simp at h; omega) else sep := by
|
||||
split
|
||||
· have p : i = 2 * (i / 2) := by omega
|
||||
sorry
|
||||
conv => lhs; simp +singlePass only [p]
|
||||
rw [getElem_intersperse_two_mul]
|
||||
· have p : i = 2 * (i / 2) + 1 := by omega
|
||||
sorry
|
||||
conv => lhs; simp +singlePass only [p]
|
||||
rw [getElem_intersperse_two_mul_add_one]
|
||||
|
||||
theorem getElem_eq_getElem_intersperse_two_mul (h : i < l.length) :
|
||||
l[i] = (l.intersperse sep)[2 * i]'(by rw [length_intersperse]; omega) := by
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ open Nat
|
|||
/-! ### Results about `List.sum` specialized to `Nat` -/
|
||||
|
||||
theorem find?_eq_some_iff_getElem {xs : List α} {p : α → Bool} {b : α} :
|
||||
xs.find? p = some b ↔ p b ∧ ∃ (i : Nat) (h : i < xs.length), xs[i] = b ∧ ∀ j : Nat, (hj : j < i) → !p xs[j] := by
|
||||
xs.find? p = some b ↔ p b ∧ ∃ i h, xs[i] = b ∧ ∀ j : Nat, (hj : j < i) → !p xs[j] := by
|
||||
rw [find?_eq_some_iff_append]
|
||||
simp only [Bool.not_eq_eq_eq_not, Bool.not_true, exists_and_right, and_congr_right_iff]
|
||||
intro w
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ public section
|
|||
|
||||
set_option linter.listVariables true -- Enforce naming conventions for `List`/`Array`/`Vector` variables.
|
||||
set_option linter.indexVariables true -- Enforce naming conventions for index variables.
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
|
||||
namespace List
|
||||
|
||||
|
|
@ -38,7 +37,7 @@ theorem getElem_modifyHead {l : List α} {f : α → α} {i} (h : i < (l.modifyH
|
|||
| nil => simp at h
|
||||
| cons hd tl => cases i <;> simp
|
||||
|
||||
@[simp] theorem getElem_modifyHead_zero {l : List α} {f : α → α} {h : 0 < (l.modifyHead f).length} :
|
||||
@[simp] theorem getElem_modifyHead_zero {l : List α} {f : α → α} {h} :
|
||||
(l.modifyHead f)[0] = f (l[0]'(by simpa using h)) := by simp [getElem_modifyHead]
|
||||
|
||||
@[simp] theorem getElem_modifyHead_succ {l : List α} {f : α → α} {n} (h : n + 1 < (l.modifyHead f).length) :
|
||||
|
|
@ -204,10 +203,10 @@ theorem modifyHead_eq_modify_zero (f : α → α) (l : List α) :
|
|||
simp at h
|
||||
simp [h]
|
||||
|
||||
@[simp] theorem getElem_modify_eq (f : α → α) (i) (l : List α) (h : i < (l.modify i f).length) :
|
||||
@[simp] theorem getElem_modify_eq (f : α → α) (i) (l : List α) (h) :
|
||||
(l.modify i f)[i] = f (l[i]'(by simpa using h)) := by simp [getElem_modify]
|
||||
|
||||
@[simp] theorem getElem_modify_ne (f : α → α) {i j} (l : List α) (h : i ≠ j) (h' : j < (l.modify i f).length) :
|
||||
@[simp] theorem getElem_modify_ne (f : α → α) {i j} (l : List α) (h : i ≠ j) (h') :
|
||||
(l.modify i f)[j] = l[j]'(by simpa using h') := by simp [getElem_modify, h]
|
||||
|
||||
theorem modify_eq_self {f : α → α} {i} {l : List α} (h : l.length ≤ i) :
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ theorem not_mem_range_self {n : Nat} : n ∉ range n := by simp
|
|||
theorem self_mem_range_succ {n : Nat} : n ∈ range (n + 1) := by simp
|
||||
|
||||
theorem pairwise_lt_range {n : Nat} : Pairwise (· < ·) (range n) := by
|
||||
sorry
|
||||
simp +decide only [range_eq_range', pairwise_lt_range']
|
||||
|
||||
theorem pairwise_le_range {n : Nat} : Pairwise (· ≤ ·) (range n) :=
|
||||
Pairwise.imp Nat.le_of_lt pairwise_lt_range
|
||||
|
|
@ -246,10 +246,10 @@ theorem pairwise_le_range {n : Nat} : Pairwise (· ≤ ·) (range n) :=
|
|||
@[simp, grind =] theorem take_range {i n : Nat} : take i (range n) = range (min i n) := by
|
||||
apply List.ext_getElem
|
||||
· simp
|
||||
· sorry
|
||||
· simp +contextual [getElem_take, Nat.lt_min]
|
||||
|
||||
theorem nodup_range {n : Nat} : Nodup (range n) := by
|
||||
sorry
|
||||
simp +decide only [range_eq_range', nodup_range']
|
||||
|
||||
@[simp] theorem find?_range_eq_some {n : Nat} {i : Nat} {p : Nat → Bool} :
|
||||
(range n).find? p = some i ↔ p i ∧ i ∈ range n ∧ ∀ j, j < i → !p j := by
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ as they required importing more lemmas about natural numbers, and use `omega`.
|
|||
|
||||
set_option linter.listVariables true -- Enforce naming conventions for `List`/`Array`/`Vector` variables.
|
||||
set_option linter.indexVariables true -- Enforce naming conventions for index variables.
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
|
||||
namespace List
|
||||
|
||||
|
|
@ -43,10 +42,7 @@ theorem length_take_of_le (h : i ≤ length l) : length (take i l) = i := by sim
|
|||
length `> i`. Version designed to rewrite from the big list to the small list. -/
|
||||
theorem getElem_take' {xs : List α} {i j : Nat} (hi : i < xs.length) (hj : i < j) :
|
||||
xs[i] = (xs.take j)[i]'(length_take .. ▸ Nat.lt_min.mpr ⟨hj, hi⟩) :=
|
||||
-- TODO: restore proof after bootstrap:
|
||||
-- by have h' : i < (xs.take j).length := length_take .. ▸ Nat.lt_min.mpr ⟨hj, hi⟩
|
||||
-- exact getElem_of_eq (take_append_drop j xs).symm _ ▸ getElem_append_left (h' := h')
|
||||
sorry
|
||||
getElem_of_eq (take_append_drop j xs).symm _ ▸ getElem_append_left ..
|
||||
|
||||
/-- The `i`-th element of a list coincides with the `i`-th element of any of its prefixes of
|
||||
length `> i`. Version designed to rewrite from the small list to the big list. -/
|
||||
|
|
|
|||
|
|
@ -83,11 +83,11 @@ theorem pairwise_of_forall {l : List α} (H : ∀ x y, R x y) : Pairwise R l :=
|
|||
|
||||
theorem Pairwise.and_mem {l : List α} :
|
||||
Pairwise R l ↔ Pairwise (fun x y => x ∈ l ∧ y ∈ l ∧ R x y) l :=
|
||||
Pairwise.iff_of_mem <| by sorry
|
||||
Pairwise.iff_of_mem <| by simp +contextual
|
||||
|
||||
theorem Pairwise.imp_mem {l : List α} :
|
||||
Pairwise R l ↔ Pairwise (fun x y => x ∈ l → y ∈ l → R x y) l :=
|
||||
Pairwise.iff_of_mem <| by sorry
|
||||
Pairwise.iff_of_mem <| by simp +contextual
|
||||
|
||||
theorem Pairwise.forall_of_forall_of_flip (h₁ : ∀ x ∈ l, R x x) (h₂ : Pairwise R l)
|
||||
(h₃ : l.Pairwise (flip R)) : ∀ ⦃x⦄, x ∈ l → ∀ ⦃y⦄, y ∈ l → R x y := by
|
||||
|
|
|
|||
|
|
@ -41,8 +41,6 @@ def merge (xs ys : List α) (le : α → α → Bool := by exact fun a b => a
|
|||
x :: merge xs (y :: ys) le
|
||||
else
|
||||
y :: merge (x :: xs) ys le
|
||||
termination_by xs.length + ys.length
|
||||
decreasing_by all_goals sorry -- TODO: restore after bootstrap
|
||||
|
||||
@[simp] theorem nil_merge (ys : List α) : merge [] ys le = ys := by simp [merge]
|
||||
@[simp] theorem merge_right (xs : List α) : merge xs [] le = xs := by
|
||||
|
|
@ -82,7 +80,6 @@ def mergeSort : ∀ (xs : List α) (le : α → α → Bool := by exact fun a b
|
|||
have := by simpa using lr.1.2
|
||||
merge (mergeSort lr.1 le) (mergeSort lr.2 le) le
|
||||
termination_by xs => xs.length
|
||||
decreasing_by all_goals sorry -- TODO: restore after bootstrap
|
||||
|
||||
/--
|
||||
Given an ordering relation `le : α → α → Bool`,
|
||||
|
|
|
|||
|
|
@ -56,8 +56,6 @@ where go : List α → List α → List α → List α
|
|||
go xs (y :: ys) (x :: acc)
|
||||
else
|
||||
go (x :: xs) ys (y :: acc)
|
||||
termination_by l₁ l₂ _ => l₁.length + l₂.length
|
||||
decreasing_by all_goals sorry -- TODO: restore after bootstrap
|
||||
|
||||
private theorem mergeTR_go_eq : mergeTR.go le l₁ l₂ acc = acc.reverse ++ merge l₁ l₂ le := by
|
||||
induction l₁ generalizing l₂ acc with
|
||||
|
|
@ -115,8 +113,6 @@ where run : {n : Nat} → { l : List α // l.length = n } → List α
|
|||
| _+2, xs =>
|
||||
let (l, r) := splitInTwo xs
|
||||
mergeTR (run l) (run r) le
|
||||
termination_by n _ => n
|
||||
decreasing_by all_goals sorry -- TODO: restore after bootstrap
|
||||
|
||||
/--
|
||||
Split a list in two equal parts, reversing the first part.
|
||||
|
|
|
|||
|
|
@ -165,8 +165,8 @@ theorem cons_merge_cons (s : α → α → Bool) (a b l r) :
|
|||
| a::l, b::r =>
|
||||
rw [cons_merge_cons]
|
||||
split
|
||||
· sorry
|
||||
· sorry
|
||||
· simp +arith [length_merge s l (b::r)]
|
||||
· simp +arith [length_merge s (a::l) r]
|
||||
|
||||
/--
|
||||
The elements of `merge le xs ys` are exactly the elements of `xs` and `ys`.
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ fun s => Subset.trans s <| subset_append_right _ _
|
|||
theorem replicate_subset {n : Nat} {a : α} {l : List α} : replicate n a ⊆ l ↔ n = 0 ∨ a ∈ l := by
|
||||
induction n with
|
||||
| zero => simp
|
||||
| succ n ih => sorry
|
||||
| succ n ih => simp +contextual [replicate_succ, ih, cons_subset]
|
||||
|
||||
theorem subset_replicate {n : Nat} {a : α} {l : List α} (h : n ≠ 0) : l ⊆ replicate n a ↔ ∀ x ∈ l, x = a := by
|
||||
induction l with
|
||||
|
|
|
|||
|
|
@ -21,11 +21,10 @@ We prefer to pull `List.toArray` outwards past `Array` operations.
|
|||
|
||||
set_option linter.listVariables true -- Enforce naming conventions for `List`/`Array`/`Vector` variables.
|
||||
set_option linter.indexVariables true -- Enforce naming conventions for index variables.
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
|
||||
namespace Array
|
||||
|
||||
@[simp] theorem toList_set (xs : Array α) (i x) (h : i < xs.size) :
|
||||
@[simp] theorem toList_set (xs : Array α) (i x h) :
|
||||
(xs.set i x).toList = xs.toList.set i x := rfl
|
||||
|
||||
theorem swap_def (xs : Array α) (i j : Nat) (hi hj) :
|
||||
|
|
@ -88,7 +87,7 @@ theorem toArray_cons (a : α) (l : List α) : (a :: l).toArray = #[a] ++ l.toArr
|
|||
@[simp, grind =] theorem back?_toArray (l : List α) : l.toArray.back? = l.getLast? := by
|
||||
simp [back?, List.getLast?_eq_getElem?]
|
||||
|
||||
@[simp, grind =] theorem back_toArray (l : List α) (h : 0 < l.toArray.size) :
|
||||
@[simp, grind =] theorem back_toArray (l : List α) (h) :
|
||||
l.toArray.back = l.getLast (by simp at h; exact ne_nil_of_length_pos h) := by
|
||||
simp [back, List.getLast_eq_getElem]
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ def bitwise (f : Bool → Bool → Bool) (n m : Nat) : Nat :=
|
|||
r+r+1
|
||||
else
|
||||
r+r
|
||||
decreasing_by apply bitwise_rec_lemma; assumption
|
||||
|
||||
/--
|
||||
Bitwise and. Usually accessed via the `&&&` operator.
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ def div.inductionOn.{u}
|
|||
ind x y h (inductionOn (x - y) y ind base)
|
||||
else
|
||||
base x y h
|
||||
decreasing_by apply div_rec_lemma; assumption
|
||||
|
||||
theorem div_le_self (n k : Nat) : n / k ≤ n := by
|
||||
induction n using Nat.strongRecOn with
|
||||
|
|
@ -236,6 +237,7 @@ theorem div_add_mod (m n : Nat) : n * (m / n) + m % n = m := by
|
|||
simp [h]
|
||||
have ih := div_add_mod (m - n) n
|
||||
rw [Nat.left_distrib, Nat.mul_one, Nat.add_assoc, Nat.add_left_comm, ih, Nat.add_comm, Nat.sub_add_cancel h.2]
|
||||
decreasing_by apply div_rec_lemma; assumption
|
||||
|
||||
theorem div_eq_sub_div (h₁ : 0 < b) (h₂ : b ≤ a) : a / b = (a - b) / b + 1 := by
|
||||
rw [div_eq a, if_pos]; constructor <;> assumption
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ def gcd (m n : @& Nat) : Nat :=
|
|||
else
|
||||
gcd (n % m) m
|
||||
termination_by m
|
||||
-- decreasing_by simp_wf; apply mod_lt _ (zero_lt_of_ne_zero _); assumption
|
||||
decreasing_by simp_wf; apply mod_lt _ (zero_lt_of_ne_zero _); assumption
|
||||
|
||||
@[simp] theorem gcd_zero_left (y : Nat) : gcd 0 y = y := by
|
||||
rw [gcd]; rfl
|
||||
|
|
|
|||
|
|
@ -867,7 +867,7 @@ theorem div_eq_self {m n : Nat} : m / n = m ↔ m = 0 ∨ n = 1 := by
|
|||
· simp
|
||||
simp only [hb, false_or]
|
||||
rw [← Nat.mul_right_inj hb, ← Nat.add_left_cancel_iff, mod_add_div]
|
||||
sorry
|
||||
simp +contextual [mod_eq_of_lt]
|
||||
|
||||
protected theorem div_ne_zero_iff : a / b ≠ 0 ↔ b ≠ 0 ∧ b ≤ a := by simp
|
||||
|
||||
|
|
@ -1559,7 +1559,7 @@ theorem mul_add_div {m : Nat} (m_pos : m > 0) (x y : Nat) : (m * x + y) / m = x
|
|||
| 0 => simp
|
||||
| x + 1 =>
|
||||
rw [Nat.mul_succ, Nat.add_assoc _ m, mul_add_div m_pos x (m+y), div_eq]
|
||||
sorry
|
||||
simp +arith [m_pos]
|
||||
|
||||
theorem mul_add_mod (m x y : Nat) : (m * x + y) % m = y % m := by
|
||||
match x with
|
||||
|
|
|
|||
|
|
@ -73,4 +73,4 @@ theorem log2_le_self (n : Nat) : Nat.log2 n ≤ n := by
|
|||
have := log2_le_self (n / 2)
|
||||
exact Nat.lt_of_le_of_lt this (Nat.div_lt_self (Nat.le_of_lt h) (by decide))
|
||||
· apply Nat.zero_le
|
||||
-- decreasing_by exact Nat.log2_terminates _ ‹_›
|
||||
decreasing_by exact Nat.log2_terminates _ ‹_›
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ protected theorem max_eq_max (a : Nat) : Nat.max a b = max a b := rfl
|
|||
simp [Nat.max_def]
|
||||
|
||||
@[simp] protected theorem max_zero (a : Nat) : max a 0 = a := by
|
||||
sorry
|
||||
simp +contextual [Nat.max_def]
|
||||
|
||||
@[simp] protected theorem add_max_add_right (a b c : Nat) : max (a + c) (b + c) = max a b + c := by
|
||||
rw [Nat.max_def, Nat.max_def]
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ public section
|
|||
namespace Nat
|
||||
|
||||
theorem nextPowerOfTwo_dec {n power : Nat} (h₁ : power > 0) (h₂ : power < n) : n - power * 2 < n - power := by
|
||||
have : power * 2 = power + power := by sorry
|
||||
have : power * 2 = power + power := by simp +arith
|
||||
rw [this, Nat.sub_add_eq]
|
||||
exact Nat.sub_lt (Nat.zero_lt_sub_of_lt h₂) h₁
|
||||
|
||||
|
|
@ -36,7 +36,7 @@ where
|
|||
else
|
||||
power
|
||||
termination_by n - power
|
||||
-- decreasing_by simp_wf; apply nextPowerOfTwo_dec <;> assumption
|
||||
decreasing_by simp_wf; apply nextPowerOfTwo_dec <;> assumption
|
||||
|
||||
/--
|
||||
A natural number `n` is a power of two if there exists some `k : Nat` such that `n = 2 ^ k`.
|
||||
|
|
@ -66,6 +66,6 @@ where
|
|||
. exact isPowerOfTwo_go (power*2) (Nat.mul_pos h₁ (by decide)) (Nat.isPowerOfTwo_mul_two_of_isPowerOfTwo h₂)
|
||||
. assumption
|
||||
termination_by n - power
|
||||
-- decreasing_by simp_wf; apply nextPowerOfTwo_dec <;> assumption
|
||||
decreasing_by simp_wf; apply nextPowerOfTwo_dec <;> assumption
|
||||
|
||||
end Nat
|
||||
|
|
|
|||
|
|
@ -109,63 +109,79 @@ def Expr.toPoly : Expr → Poly
|
|||
|
||||
theorem Mon.append_denote (ctx : Context) (m₁ m₂ : Mon) : (m₁ ++ m₂).denote ctx = m₁.denote ctx * m₂.denote ctx := by
|
||||
match m₁ with
|
||||
| [] => sorry
|
||||
| v :: m₁ => sorry
|
||||
| [] => simp! [Nat.one_mul]
|
||||
| v :: m₁ => simp! [append_denote ctx m₁ m₂, Nat.mul_assoc]
|
||||
|
||||
theorem Mon.mul_denote (ctx : Context) (m₁ m₂ : Mon) : (m₁.mul m₂).denote ctx = m₁.denote ctx * m₂.denote ctx :=
|
||||
go hugeFuel m₁ m₂
|
||||
where
|
||||
go (fuel : Nat) (m₁ m₂ : Mon) : (Mon.mul.go fuel m₁ m₂).denote ctx = m₁.denote ctx * m₂.denote ctx := by
|
||||
induction fuel generalizing m₁ m₂ with
|
||||
| zero => sorry
|
||||
| zero => simp! [append_denote]
|
||||
| succ _ ih =>
|
||||
sorry
|
||||
simp!
|
||||
split <;> simp!
|
||||
next v₁ m₁ v₂ m₂ =>
|
||||
by_cases hlt : Nat.blt v₁ v₂ <;> simp! [hlt, Nat.mul_assoc, ih]
|
||||
by_cases hgt : Nat.blt v₂ v₁ <;> simp! [hgt, Nat.mul_assoc, Nat.mul_comm, Nat.mul_left_comm, ih]
|
||||
|
||||
theorem Poly.append_denote (ctx : Context) (p₁ p₂ : Poly) : (p₁ ++ p₂).denote ctx = p₁.denote ctx + p₂.denote ctx := by
|
||||
match p₁ with
|
||||
| [] => sorry
|
||||
| v :: p₁ => sorry
|
||||
| [] => simp!
|
||||
| v :: p₁ => simp! [append_denote _ p₁ p₂, Nat.add_assoc]
|
||||
|
||||
theorem Poly.add_denote (ctx : Context) (p₁ p₂ : Poly) : (p₁.add p₂).denote ctx = p₁.denote ctx + p₂.denote ctx :=
|
||||
go hugeFuel p₁ p₂
|
||||
where
|
||||
go (fuel : Nat) (p₁ p₂ : Poly) : (Poly.add.go fuel p₁ p₂).denote ctx = p₁.denote ctx + p₂.denote ctx := by
|
||||
induction fuel generalizing p₁ p₂ with
|
||||
| zero => sorry
|
||||
| zero => simp! [append_denote]
|
||||
| succ _ ih =>
|
||||
sorry
|
||||
simp!
|
||||
split <;> simp!
|
||||
next k₁ m₁ p₁ k₂ m₂ p₂ =>
|
||||
by_cases hlt : m₁ < m₂ <;> simp! [hlt, Nat.add_assoc, ih]
|
||||
by_cases hgt : m₂ < m₁ <;> simp! [hgt, Nat.add_assoc, Nat.add_comm, Nat.add_left_comm, ih]
|
||||
have : m₁ = m₂ := List.le_antisymm hgt hlt
|
||||
subst m₂
|
||||
by_cases heq : k₁ + k₂ == 0 <;> simp! [heq, ih]
|
||||
· simp [← Nat.add_assoc, ← Nat.right_distrib, eq_of_beq heq]
|
||||
· simp [Nat.right_distrib, Nat.add_assoc]
|
||||
|
||||
theorem Poly.denote_insertSorted (ctx : Context) (k : Nat) (m : Mon) (p : Poly) : (p.insertSorted k m).denote ctx = p.denote ctx + k * m.denote ctx := by
|
||||
match p with
|
||||
| [] => sorry
|
||||
| [] => simp!
|
||||
| (k', m') :: p =>
|
||||
by_cases h : m < m' <;> sorry
|
||||
by_cases h : m < m' <;> simp! [h, denote_insertSorted ctx k m p, Nat.add_assoc, Nat.add_comm, Nat.add_left_comm]
|
||||
|
||||
theorem Poly.mulMon_denote (ctx : Context) (p : Poly) (k : Nat) (m : Mon) : (p.mulMon k m).denote ctx = p.denote ctx * k * m.denote ctx := by
|
||||
simp [mulMon, go]; sorry
|
||||
simp [mulMon, go]; simp!
|
||||
where
|
||||
go (p : Poly) (acc : Poly) : (mulMon.go k m p acc).denote ctx = acc.denote ctx + p.denote ctx * k * m.denote ctx := by
|
||||
match p with
|
||||
| [] => sorry
|
||||
| [] => simp!
|
||||
| (k', m') :: p =>
|
||||
sorry
|
||||
simp! [go p, Nat.left_distrib, denote_insertSorted, Mon.mul_denote, Nat.mul_assoc, Nat.mul_comm, Nat.mul_left_comm, Nat.add_assoc]
|
||||
|
||||
theorem Poly.mul_denote (ctx : Context) (p₁ p₂ : Poly) : (p₁.mul p₂).denote ctx = p₁.denote ctx * p₂.denote ctx := by
|
||||
simp [mul, go]; sorry
|
||||
simp [mul, go]; simp!
|
||||
where
|
||||
go (p₁ : Poly) (acc : Poly) : (mul.go p₂ p₁ acc).denote ctx = acc.denote ctx + p₁.denote ctx * p₂.denote ctx := by
|
||||
match p₁ with
|
||||
| [] => sorry
|
||||
| [] => simp!
|
||||
| (k, m) :: p₁ =>
|
||||
sorry
|
||||
simp! [go p₁, Nat.left_distrib, add_denote, mulMon_denote,
|
||||
Nat.add_assoc, Nat.add_comm, Nat.add_left_comm,
|
||||
Nat.mul_assoc, Nat.mul_comm, Nat.mul_left_comm]
|
||||
|
||||
theorem Expr.toPoly_denote (ctx : Context) (e : Expr) : e.toPoly.denote ctx = e.denote ctx := by
|
||||
induction e with
|
||||
| num k =>
|
||||
sorry
|
||||
| var v => sorry
|
||||
| add a b => sorry
|
||||
| mul a b => sorry
|
||||
simp!; by_cases h : k == 0 <;> simp! [*]
|
||||
simp [eq_of_beq h]
|
||||
| var v => simp!
|
||||
| add a b => simp! [Poly.add_denote, *]
|
||||
| mul a b => simp! [Poly.mul_denote, *]
|
||||
|
||||
theorem Expr.eq_of_toPoly_eq (ctx : Context) (a b : Expr) (h : a.toPoly == b.toPoly) : a.denote ctx = b.denote ctx := by
|
||||
have h := congrArg (Poly.denote ctx) (eq_of_beq h)
|
||||
|
|
|
|||
|
|
@ -445,7 +445,7 @@ public instance : LawfulMonadAttach Option where
|
|||
canReturn_map_imp {α P x a} := by
|
||||
cases x
|
||||
· simp [MonadAttach.CanReturn]
|
||||
· sorry
|
||||
· simp +contextual [MonadAttach.CanReturn, eq_comm, Subtype.property]
|
||||
|
||||
end Option
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ where go i :=
|
|||
| .eq => go (i + 1)
|
||||
| .gt => .gt
|
||||
termination_by a₁.size - i
|
||||
-- decreasing_by sorry -- TODO: restore after bootstrap
|
||||
|
||||
instance {α} [Ord α] : Ord (Array α) where
|
||||
compare := Array.compareLex compare
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ instance if `Ord α` is compatible with it.
|
|||
public instance instLawfulOrderLT_ofOrd {α : Type u} [Ord α] [LE α] [LawfulOrderOrd α] :
|
||||
LawfulOrderLT α where
|
||||
lt_iff {a b} := by
|
||||
sorry
|
||||
simp +contextual [LT.lt, ← Std.isLE_compare (a := a), ← Std.isGE_compare (a := a)]
|
||||
|
||||
attribute [local instance] BEq.ofOrd in
|
||||
/--
|
||||
|
|
@ -116,6 +116,7 @@ instance if `Ord α` is compatible with it.
|
|||
public instance instLawfulOrderBEq_ofOrd {α : Type u} [Ord α] [LE α] [LawfulOrderOrd α] :
|
||||
LawfulOrderBEq α where
|
||||
beq_iff_le_and_ge {a b} := by
|
||||
sorry
|
||||
simp +contextual [BEq.beq, ← Std.isLE_compare (a := a), ← Std.isGE_compare (a := a),
|
||||
Ordering.eq_eq_iff_isLE_and_isGE]
|
||||
|
||||
end Std
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ public theorem le_antisymm {α : Type u} [LE α] [Std.Antisymm (α := α) (·
|
|||
|
||||
public theorem le_antisymm_iff {α : Type u} [LE α] [Antisymm (α := α) (· ≤ ·)]
|
||||
[Refl (α := α) (· ≤ ·)] {a b : α} : a ≤ b ∧ b ≤ a ↔ a = b :=
|
||||
⟨fun | ⟨hab, hba⟩ => le_antisymm hab hba, by sorry⟩
|
||||
⟨fun | ⟨hab, hba⟩ => le_antisymm hab hba, by simp +contextual [le_refl]⟩
|
||||
|
||||
public theorem le_trans {α : Type u} [LE α] [Trans (α := α) (· ≤ ·) (· ≤ ·) (· ≤ ·)] {a b c : α}
|
||||
(hab : a ≤ b) (hbc : b ≤ c) : a ≤ c :=
|
||||
|
|
@ -401,8 +401,8 @@ public instance {α : Type u} [LE α] [Min α] [IsLinearOrder α] [LawfulOrderIn
|
|||
|
||||
public theorem LawfulOrderLeftLeaningMin.of_eq {α : Type u} [LE α] [Min α] [DecidableLE α]
|
||||
(min_eq : ∀ a b : α, min a b = if a ≤ b then a else b) : LawfulOrderLeftLeaningMin α where
|
||||
min_eq_left a b := by sorry
|
||||
min_eq_right a b := by sorry
|
||||
min_eq_left a b := by simp +contextual [min_eq]
|
||||
min_eq_right a b := by simp +contextual [min_eq]
|
||||
|
||||
attribute [local instance] Min.leftLeaningOfLE
|
||||
public instance [LE α] [DecidableLE α] : LawfulOrderLeftLeaningMin α :=
|
||||
|
|
@ -538,8 +538,8 @@ public instance {α : Type u} [LE α] [Max α] [IsLinearOrder α] [LawfulOrderSu
|
|||
|
||||
public theorem LawfulOrderLeftLeaningMax.of_eq {α : Type u} [LE α] [Max α] [DecidableLE α]
|
||||
(min_eq : ∀ a b : α, max a b = if b ≤ a then a else b) : LawfulOrderLeftLeaningMax α where
|
||||
max_eq_left a b := by sorry
|
||||
max_eq_right a b := by sorry
|
||||
max_eq_left a b := by simp +contextual [min_eq]
|
||||
max_eq_right a b := by simp +contextual [min_eq]
|
||||
|
||||
attribute [local instance] Max.leftLeaningOfLE
|
||||
public instance [LE α] [DecidableLE α] : LawfulOrderLeftLeaningMax α :=
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ public instance LawfulOrderLT.of_ord (α : Type u) [Ord α] [LT α] [LE α] [Law
|
|||
(lt_iff_compare_eq_lt : ∀ a b : α, a < b ↔ compare a b = .lt) :
|
||||
LawfulOrderLT α where
|
||||
lt_iff a b := by
|
||||
sorry
|
||||
simp +contextual [lt_iff_compare_eq_lt, ← isLE_compare (a := a), ← isGE_compare (a := a)]
|
||||
|
||||
/--
|
||||
This lemma derives a `LawfulOrderBEq α` instance from a property involving an `Ord α` instance.
|
||||
|
|
|
|||
|
|
@ -683,15 +683,15 @@ public scoped instance instMaxOfOrd {α : Type u} [Ord α] :
|
|||
|
||||
public instance instLawfulOrderLeftLeaningMinOfOrd {α : Type u} [Ord α] [LE α] [LawfulOrderOrd α] :
|
||||
LawfulOrderLeftLeaningMin α where
|
||||
min_eq_left a b := by sorry
|
||||
min_eq_left a b := by simp +contextual only [← Std.isLE_compare, min, ↑reduceIte, implies_true]
|
||||
min_eq_right a b := by
|
||||
sorry
|
||||
simp +contextual only [← Std.isLE_compare, min, Bool.false_eq_true, ↑reduceIte, implies_true]
|
||||
|
||||
public instance instLawfulOrderLeftLeaningMaxOfOrd {α : Type u} [Ord α] [LE α] [LawfulOrderOrd α] :
|
||||
LawfulOrderLeftLeaningMax α where
|
||||
max_eq_left a b := by sorry
|
||||
max_eq_left a b := by simp +contextual only [← Std.isLE_compare, max, ↑reduceIte, implies_true]
|
||||
max_eq_right a b := by
|
||||
sorry
|
||||
simp +contextual only [← Std.isLE_compare, max, Bool.false_eq_true, ↑reduceIte, implies_true]
|
||||
|
||||
end FactoryInstances
|
||||
|
||||
|
|
|
|||
|
|
@ -40,8 +40,6 @@ universe u v
|
|||
loop b (i + range.step) (by rwa [Nat.add_comm, Nat.add_sub_assoc hl, Nat.add_mod_left])
|
||||
else
|
||||
pure b
|
||||
termination_by range.stop - i
|
||||
-- decreasing_by sorry -- TODO: restore after bootstrap
|
||||
have := range.step_pos
|
||||
loop init range.start (by simp)
|
||||
|
||||
|
|
@ -58,8 +56,6 @@ instance [Monad m] : ForIn' m Range Nat inferInstance where
|
|||
loop (i + range.step)
|
||||
else
|
||||
pure ⟨⟩
|
||||
termination_by range.stop - i
|
||||
-- decreasing_by sorry -- TODO: restore after bootstrap
|
||||
have := range.step_pos
|
||||
loop range.start
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ theorem succ?_eq_none {x : BitVec n} :
|
|||
· refine fun h => Classical.not_not.mp fun _ => ?_
|
||||
simp [Nat.mod_eq_of_lt (a := x.toNat + 1) (b := 2 ^ n) (by omega)] at h
|
||||
· have := Nat.two_pow_pos n
|
||||
sorry
|
||||
simp +contextual [show 2 ^ n - 1 + 1 = 2 ^ n by omega]
|
||||
|
||||
theorem succ?_eq_some {x y : BitVec n} :
|
||||
succ? x = some y ↔ x.toNat < 2 ^ n - 1 ∧ y.toNat = x.toNat + 1 := by
|
||||
|
|
@ -56,10 +56,19 @@ theorem succ?_eq_some {x y : BitVec n} :
|
|||
|
||||
instance : LawfulUpwardEnumerable (BitVec n) where
|
||||
ne_of_lt := by
|
||||
sorry
|
||||
simp +contextual [UpwardEnumerable.LT, ← BitVec.toNat_inj, succMany?] at ⊢
|
||||
omega
|
||||
succMany?_zero := by simp [UpwardEnumerable.succMany?, BitVec.toNat_lt_twoPow_of_le]
|
||||
succMany?_add_one a b := by
|
||||
sorry
|
||||
simp +contextual [← BitVec.toNat_inj, succMany?, succ?]
|
||||
split <;> split
|
||||
· rename_i h
|
||||
simp [← BitVec.toNat_inj, Nat.mod_eq_of_lt (a := b.toNat + a + 1) ‹_›]
|
||||
all_goals omega
|
||||
· omega
|
||||
· have : b.toNat + a + 1 = 2 ^ n := by omega
|
||||
simp [this]
|
||||
· simp
|
||||
|
||||
instance : LawfulUpwardEnumerableLE (BitVec n) where
|
||||
le_iff x y := by
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ theorem toList_rco_eq_singleton {m n : Int} (h : n = m + 1) :
|
|||
theorem toList_rco_eq_cons_iff {m n a : Int} :
|
||||
(m...n).toList = a :: xs ↔ m = a ∧ m < n ∧ ((m + 1)...n).toList = xs := by
|
||||
rw [Rco.toList_eq_if_roo]
|
||||
split <;> sorry
|
||||
split <;> simp +contextual [*, Roo.toList_eq_match_rco, eq_comm]
|
||||
|
||||
theorem toList_rco_eq_cons {m n : Int} (h : m < n) :
|
||||
(m...n).toList = m :: ((m + 1)...n).toList := by
|
||||
|
|
|
|||
|
|
@ -17,8 +17,6 @@ import Init.Data.Array.Monadic
|
|||
|
||||
public section
|
||||
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
|
||||
/-!
|
||||
# Lemmas about ranges
|
||||
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ theorem toList_rco_eq_singleton {m n : Nat} (h : n = m + 1) :
|
|||
theorem toList_rco_eq_cons_iff {m n a : Nat} :
|
||||
(m...n).toList = a :: xs ↔ m = a ∧ m < n ∧ ((m + 1)...n).toList = xs := by
|
||||
rw [Rco.toList_eq_if_roo]
|
||||
split <;> sorry
|
||||
split <;> simp +contextual [*, Roo.toList_eq_match_rco, eq_comm]
|
||||
|
||||
theorem toList_rco_eq_cons {m n : Nat} (h : m < n) :
|
||||
(m...n).toList = m :: ((m + 1)...n).toList := by
|
||||
|
|
|
|||
|
|
@ -480,6 +480,7 @@ instance Iterator.instIteratorLoop [UpwardEnumerable α] [LE α] [DecidableLE α
|
|||
exact UpwardEnumerable.le_iff.mpr (UpwardEnumerable.le_refl _)
|
||||
case decreasing =>
|
||||
simp_wf
|
||||
simp [IteratorLoop.rel, Monadic.isPlausibleStep_iff, Monadic.step, *]
|
||||
|
||||
private noncomputable def Iterator.instIteratorLoop.loop.wf [UpwardEnumerable α] [LE α] [DecidableLE α]
|
||||
[LawfulUpwardEnumerable α] [LawfulUpwardEnumerableLE α]
|
||||
|
|
@ -501,7 +502,8 @@ private noncomputable def Iterator.instIteratorLoop.loop.wf [UpwardEnumerable α
|
|||
else
|
||||
return acc
|
||||
termination_by IteratorLoop.WithWF.mk ⟨⟨some next, upperBound⟩⟩ acc (hwf := wf)
|
||||
decreasing_by all_goals sorry -- TODO: restore after bootstrap
|
||||
decreasing_by
|
||||
simp [IteratorLoop.rel, Monadic.isPlausibleStep_iff, Monadic.step, *]
|
||||
where finally
|
||||
case hle =>
|
||||
simp only [UpwardEnumerable.le_iff]
|
||||
|
|
@ -577,8 +579,8 @@ private theorem Iterator.instIteratorLoop.loopWf_eq [UpwardEnumerable α] [LE α
|
|||
simp [Monadic.step_eq_step, Monadic.step, instLawfulMonadLiftFunction.liftBind_pure, *]
|
||||
· simp
|
||||
termination_by IteratorLoop.WithWF.mk ⟨⟨some next, upperBound⟩⟩ acc (hwf := wf)
|
||||
-- decreasing_by
|
||||
-- simp [IteratorLoop.rel, Monadic.isPlausibleStep_iff, Monadic.step, *]
|
||||
decreasing_by
|
||||
simp [IteratorLoop.rel, Monadic.isPlausibleStep_iff, Monadic.step, *]
|
||||
|
||||
instance Iterator.instLawfulIteratorLoop [UpwardEnumerable α] [LE α] [DecidableLE α]
|
||||
[LawfulUpwardEnumerable α] [LawfulUpwardEnumerableLE α]
|
||||
|
|
@ -1051,7 +1053,7 @@ instance Iterator.instIteratorLoop [UpwardEnumerable α] [LT α] [DecidableLT α
|
|||
case hle'' =>
|
||||
exact UpwardEnumerable.le_refl _
|
||||
case decreasing =>
|
||||
simp_wf
|
||||
simp_wf; simp [IteratorLoop.rel, Monadic.isPlausibleStep_iff, Monadic.step, *]
|
||||
|
||||
private noncomputable def Iterator.instIteratorLoop.loop.wf [UpwardEnumerable α] [LT α] [DecidableLT α]
|
||||
[LawfulUpwardEnumerable α] [LawfulUpwardEnumerableLT α]
|
||||
|
|
@ -1073,7 +1075,8 @@ private noncomputable def Iterator.instIteratorLoop.loop.wf [UpwardEnumerable α
|
|||
else
|
||||
return acc
|
||||
termination_by IteratorLoop.WithWF.mk ⟨⟨some next, upperBound⟩⟩ acc (hwf := wf)
|
||||
decreasing_by all_goals sorry -- TODO: restore after bootstrap
|
||||
decreasing_by
|
||||
simp [IteratorLoop.rel, Monadic.isPlausibleStep_iff, Monadic.step, *]
|
||||
where finally
|
||||
case hle =>
|
||||
refine ⟨1, ?_⟩
|
||||
|
|
@ -1148,8 +1151,8 @@ private theorem Iterator.instIteratorLoop.loopWf_eq [UpwardEnumerable α] [LT α
|
|||
simp [Monadic.step_eq_step, Monadic.step, instLawfulMonadLiftFunction.liftBind_pure, *]
|
||||
· simp
|
||||
termination_by IteratorLoop.WithWF.mk ⟨⟨some next, upperBound⟩⟩ acc (hwf := wf)
|
||||
-- decreasing_by
|
||||
-- simp [IteratorLoop.rel, Monadic.isPlausibleStep_iff, Monadic.step, *]
|
||||
decreasing_by
|
||||
simp [IteratorLoop.rel, Monadic.isPlausibleStep_iff, Monadic.step, *]
|
||||
|
||||
instance Iterator.instLawfulIteratorLoop [UpwardEnumerable α] [LT α] [DecidableLT α]
|
||||
[LawfulUpwardEnumerable α] [LawfulUpwardEnumerableLT α]
|
||||
|
|
@ -1530,7 +1533,7 @@ instance Iterator.instIteratorLoop [UpwardEnumerable α] [LawfulUpwardEnumerable
|
|||
case hle'' =>
|
||||
exact UpwardEnumerable.le_refl _
|
||||
case decreasing =>
|
||||
simp_wf
|
||||
simp_wf; simp [IteratorLoop.rel, Monadic.isPlausibleStep_iff, Monadic.step, *]
|
||||
|
||||
private noncomputable def Iterator.instIteratorLoop.loop.wf [UpwardEnumerable α]
|
||||
[LawfulUpwardEnumerable α]
|
||||
|
|
@ -1549,7 +1552,8 @@ private noncomputable def Iterator.instIteratorLoop.loop.wf [UpwardEnumerable α
|
|||
| none => return acc'
|
||||
| ⟨.done acc', _⟩ => return acc'
|
||||
termination_by IteratorLoop.WithWF.mk ⟨⟨some next⟩⟩ acc (hwf := wf)
|
||||
decreasing_by all_goals sorry -- TODO: restore after bootstrap
|
||||
decreasing_by
|
||||
simp [IteratorLoop.rel, Monadic.isPlausibleStep_iff, Monadic.step, *]
|
||||
where finally
|
||||
case hle =>
|
||||
refine ⟨1, ?_⟩
|
||||
|
|
@ -1613,8 +1617,8 @@ private theorem Iterator.instIteratorLoop.loopWf_eq [UpwardEnumerable α]
|
|||
simp [Monadic.step_eq_step, Monadic.step, instLawfulMonadLiftFunction.liftBind_pure, *]
|
||||
· simp
|
||||
termination_by IteratorLoop.WithWF.mk ⟨⟨some next⟩⟩ acc (hwf := wf)
|
||||
-- decreasing_by
|
||||
-- simp [IteratorLoop.rel, Monadic.isPlausibleStep_iff, Monadic.step, *]
|
||||
decreasing_by
|
||||
simp [IteratorLoop.rel, Monadic.isPlausibleStep_iff, Monadic.step, *]
|
||||
|
||||
instance Iterator.instLawfulIteratorLoop [UpwardEnumerable α]
|
||||
[LawfulUpwardEnumerable α]
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ theorem eq_of_encode_eq [m : HasModel α β] (x y : α) :
|
|||
|
||||
theorem encode_inj [m : HasModel α β] {x y : α} :
|
||||
m.encode x = m.encode y ↔ x = y := by
|
||||
exact ⟨m.eq_of_encode_eq x y, by sorry⟩
|
||||
exact ⟨m.eq_of_encode_eq x y, by simp +contextual⟩
|
||||
|
||||
theorem le_iff [m : HasModel α β] {x y : α} :
|
||||
UpwardEnumerable.LE x y ↔ UpwardEnumerable.LE (m.encode x) (m.encode y) := by
|
||||
|
|
|
|||
|
|
@ -520,7 +520,7 @@ protected theorem inv_mul_cancel (a : Rat) (h : a ≠ 0) : a⁻¹ * a = 1 :=
|
|||
Eq.trans (Rat.mul_comm _ _) (Rat.mul_inv_cancel _ h)
|
||||
|
||||
protected theorem inv_eq_of_mul_eq_one {a b : Rat} (h : a * b = 1) : a⁻¹ = b := by
|
||||
have : a ≠ 0 := by intro h; sorry
|
||||
have : a ≠ 0 := by intro h; simp_all +decide
|
||||
simpa [← Rat.mul_assoc, Rat.inv_mul_cancel _ this, eq_comm] using congrArg (a⁻¹ * ·) h
|
||||
|
||||
protected theorem inv_inv (a : Rat) : a⁻¹⁻¹ = a :=
|
||||
|
|
@ -864,7 +864,7 @@ protected theorem inv_pos {a : Rat} : 0 < a⁻¹ ↔ 0 < a := by
|
|||
|
||||
protected theorem pow_pos {a : Rat} {n : Nat} (h : 0 < a) : 0 < a ^ n := by
|
||||
induction n with
|
||||
| zero => sorry
|
||||
| zero => simp +decide
|
||||
| succ k ih => rw [Rat.pow_succ]; exact Rat.mul_pos ih h
|
||||
|
||||
protected theorem pow_nonneg {a : Rat} {n : Nat} (h : 0 ≤ a) : 0 ≤ a ^ n := by
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ theorem ISize.toBitVec_one : (1 : ISize).toBitVec = 1#System.Platform.numBits :=
|
|||
|
||||
theorem ISize.toNat_toBitVec_ofNat_of_lt {n : Nat} (h : n < 2^32) :
|
||||
(ofNat n).toBitVec.toNat = n :=
|
||||
Nat.mod_eq_of_lt (Nat.lt_of_lt_of_le h (by cases USize.size_eq <;> sorry))
|
||||
Nat.mod_eq_of_lt (Nat.lt_of_lt_of_le h (by cases USize.size_eq <;> simp_all +decide))
|
||||
|
||||
@[simp] theorem Int8.toInt_ofInt {n : Int} : toInt (ofInt n) = n.bmod Int8.size := by
|
||||
rw [toInt, toBitVec_ofInt, BitVec.toInt_ofInt]
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ open Std Std.Iterators Std.PRange Std.Slice
|
|||
|
||||
namespace SubarrayIterator
|
||||
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
theorem step_eq {it : Iter (α := SubarrayIterator α) α} :
|
||||
it.step = if h : it.1.xs.start < it.1.xs.stop then
|
||||
haveI := it.1.xs.start_le_stop
|
||||
|
|
@ -97,7 +96,6 @@ end SubarrayIterator
|
|||
|
||||
namespace Subarray
|
||||
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
theorem internalIter_eq {α : Type u} {s : Subarray α} :
|
||||
Internal.iter s = ⟨⟨s⟩⟩ :=
|
||||
rfl
|
||||
|
|
@ -207,8 +205,8 @@ public theorem Subarray.toList_eq {xs : Subarray α} :
|
|||
apply List.ext_getElem
|
||||
· have : stop - start ≤ array.size - start := by omega
|
||||
simp [Subarray.start, Subarray.stop, *, Subarray.array]
|
||||
· -- TODO: restore after bootstrap: intros; simp [Subarray.array, Subarray.start, Subarray.stop]
|
||||
sorry
|
||||
· intros
|
||||
simp [Subarray.array, Subarray.start, Subarray.stop]
|
||||
simp [this, ListSlice.toList_eq, lslice]
|
||||
|
||||
@[grind =]
|
||||
|
|
@ -240,7 +238,6 @@ public theorem Subarray.size_toArray {xs : Subarray α} :
|
|||
|
||||
namespace Array
|
||||
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
@[simp, grind =]
|
||||
public theorem array_mkSlice_rco {xs : Array α} {lo hi : Nat} :
|
||||
xs[lo...hi].array = xs := by
|
||||
|
|
@ -633,7 +630,6 @@ section SubarraySlices
|
|||
|
||||
namespace Subarray
|
||||
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
@[simp, grind =]
|
||||
public theorem toList_mkSlice_rco {xs : Subarray α} {lo hi : Nat} :
|
||||
xs[lo...hi].toList = (xs.toList.take hi).drop lo := by
|
||||
|
|
|
|||
|
|
@ -25,8 +25,6 @@ basis for all further verification for strings.
|
|||
|
||||
public section
|
||||
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
|
||||
universe u
|
||||
|
||||
section
|
||||
|
|
@ -77,7 +75,7 @@ where
|
|||
else
|
||||
some acc
|
||||
termination_by b.size - i
|
||||
-- decreasing_by sorry -- TODO: restore after bootstrap
|
||||
decreasing_by have := c.utf8Size_pos; omega
|
||||
|
||||
@[expose, extern "lean_string_validate_utf8"]
|
||||
def ByteArray.validateUTF8 (b : @& ByteArray) : Bool :=
|
||||
|
|
@ -92,7 +90,8 @@ where
|
|||
else
|
||||
true
|
||||
termination_by b.size - i
|
||||
-- decreasing_by sorry -- TODO: restore after bootstrap
|
||||
decreasing_by
|
||||
have := b[i].utf8ByteSize_pos (isUTF8FirstByte_of_validateUTF8At h); omega
|
||||
finally
|
||||
all_goals rw [ByteArray.validateUTF8At_eq_isSome_utf8DecodeChar?] at h
|
||||
· rw [← ByteArray.utf8Size_utf8DecodeChar (h := h)]
|
||||
|
|
@ -738,8 +737,8 @@ theorem _root_.ByteArray.IsValidUTF8.isUTF8FirstByte_getElem_zero {b : ByteArray
|
|||
· exact List.isUTF8FirstByte_getElem_utf8Encode_singleton.2 rfl
|
||||
· simp [List.utf8Encode_singleton, Char.utf8Size_pos]
|
||||
|
||||
theorem isUTF8FirstByte_getUTF8Byte_zero {b : String} {h : 0 < b.utf8ByteSize} : (b.getUTF8Byte 0 h).IsUTF8FirstByte :=
|
||||
b.isValidUTF8.isUTF8FirstByte_getElem_zero (by simp [String.utf8ByteSize] at h; exact h)
|
||||
theorem isUTF8FirstByte_getUTF8Byte_zero {b : String} {h} : (b.getUTF8Byte 0 h).IsUTF8FirstByte :=
|
||||
b.isValidUTF8.isUTF8FirstByte_getElem_zero _
|
||||
|
||||
theorem Pos.Raw.isValidUTF8_extract_iff {s : String} (p₁ p₂ : Pos.Raw) (hle : p₁ ≤ p₂) (hle' : p₂ ≤ s.rawEndPos) :
|
||||
(s.toByteArray.extract p₁.byteIdx p₂.byteIdx).IsValidUTF8 ↔ p₁ = p₂ ∨ (p₁.IsValid s ∧ p₂.IsValid s) := by
|
||||
|
|
@ -2683,14 +2682,16 @@ Examples:
|
|||
* `"teas".firstDiffPos "tea" = ⟨3⟩`
|
||||
-/
|
||||
@[expose]
|
||||
partial def firstDiffPos (a b : String) : Pos.Raw :=
|
||||
def firstDiffPos (a b : String) : Pos.Raw :=
|
||||
let stopPos := a.rawEndPos.min b.rawEndPos
|
||||
let rec loop (i : Pos.Raw) : Pos.Raw :=
|
||||
if h : i < stopPos then
|
||||
if i.get a != i.get b then i
|
||||
else
|
||||
have := Nat.sub_lt_sub_left h (Pos.Raw.lt_next a i)
|
||||
loop (i.next a)
|
||||
else i
|
||||
termination_by stopPos.1 - i.1
|
||||
loop 0
|
||||
|
||||
/--
|
||||
|
|
@ -2724,12 +2725,14 @@ where
|
|||
| [], _, _ => []
|
||||
| c::cs, i, e => if i = e then [] else c :: go₂ cs (i + c) e
|
||||
|
||||
partial def Pos.Raw.offsetOfPosAux (s : String) (pos : Pos.Raw) (i : Pos.Raw) (offset : Nat) : Nat :=
|
||||
def Pos.Raw.offsetOfPosAux (s : String) (pos : Pos.Raw) (i : Pos.Raw) (offset : Nat) : Nat :=
|
||||
if i >= pos then offset
|
||||
else if h : i.atEnd s then
|
||||
offset
|
||||
else
|
||||
have := Nat.sub_lt_sub_left (Nat.gt_of_not_le (mt decide_eq_true h)) (Pos.Raw.lt_next s _)
|
||||
offsetOfPosAux s pos (i.next s) (offset+1)
|
||||
termination_by s.rawEndPos.1 - i.1
|
||||
|
||||
/--
|
||||
Returns the character index that corresponds to the provided position (i.e. UTF-8 byte index) in a
|
||||
|
|
@ -2772,7 +2775,7 @@ either string.
|
|||
This is a legacy function. The recommended alternative is to construct slices representing the
|
||||
strings to be compared and use the `BEq` instance of `String.Slice`.
|
||||
-/
|
||||
partial def Pos.Raw.substrEq (s1 : String) (pos1 : String.Pos.Raw) (s2 : String) (pos2 : String.Pos.Raw) (sz : Nat) : Bool :=
|
||||
def Pos.Raw.substrEq (s1 : String) (pos1 : String.Pos.Raw) (s2 : String) (pos2 : String.Pos.Raw) (sz : Nat) : Bool :=
|
||||
pos1.byteIdx + sz ≤ s1.rawEndPos.byteIdx && pos2.byteIdx + sz ≤ s2.rawEndPos.byteIdx && loop pos1 pos2 { byteIdx := pos1.byteIdx + sz }
|
||||
where
|
||||
loop (off1 off2 stop1 : Pos.Raw) :=
|
||||
|
|
@ -2781,6 +2784,10 @@ where
|
|||
let c₂ := off2.get s2
|
||||
c₁ == c₂ && loop (off1 + c₁) (off2 + c₂) stop1
|
||||
else true
|
||||
termination_by stop1.1 - off1.1
|
||||
decreasing_by
|
||||
have := Nat.sub_lt_sub_left _h (Nat.add_lt_add_left c₁.utf8Size_pos off1.1)
|
||||
decreasing_tactic
|
||||
|
||||
@[deprecated Pos.Raw.substrEq (since := "2025-10-10")]
|
||||
def substrEq (s1 : String) (pos1 : String.Pos.Raw) (s2 : String) (pos2 : String.Pos.Raw) (sz : Nat) : Bool :=
|
||||
|
|
|
|||
|
|
@ -236,7 +236,6 @@ theorem String.toBitVec_getElem_utf8EncodeChar_three_of_utf8Size_eq_four {c : Ch
|
|||
|
||||
namespace ByteArray.utf8DecodeChar?
|
||||
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
/-! # `parseFirstByte` -/
|
||||
|
||||
/-! ## `parseFirstByte` definition -/
|
||||
|
|
@ -1139,16 +1138,31 @@ theorem utf8DecodeChar?_eq_assemble₄ {b : ByteArray} (hb : 4 ≤ b.size) (h :
|
|||
all_goals omega
|
||||
|
||||
theorem utf8DecodeChar?_append_eq_assemble₁ {l : List UInt8} {b : ByteArray} (hl : l.length = 1) (h : parseFirstByte l[0] = .done) :
|
||||
(l.toByteArray ++ b).utf8DecodeChar? 0 = assemble₁ l[0] h := sorry
|
||||
(l.toByteArray ++ b).utf8DecodeChar? 0 = assemble₁ l[0] h := by
|
||||
have : (l.toByteArray ++ b)[0]'(by simp [hl]; omega) = l[0] := by
|
||||
rw [ByteArray.getElem_append_left (by simp [hl]), List.getElem_toByteArray]
|
||||
rw [utf8DecodeChar?_eq_assemble₁ (by simp [hl])] <;> simp [this, h]
|
||||
|
||||
theorem utf8DecodeChar?_append_eq_assemble₂ {l : List UInt8} {b : ByteArray} (hl : l.length = 2) (h : parseFirstByte l[0] = .oneMore) :
|
||||
(l.toByteArray ++ b).utf8DecodeChar? 0 = assemble₂ l[0] l[1] := sorry
|
||||
(l.toByteArray ++ b).utf8DecodeChar? 0 = assemble₂ l[0] l[1] := by
|
||||
rw [utf8DecodeChar?_eq_assemble₂ (by simp [hl])]
|
||||
all_goals repeat rw [ByteArray.getElem_append_left (by simp [hl])]
|
||||
all_goals repeat rw [List.getElem_toByteArray]
|
||||
assumption
|
||||
|
||||
theorem utf8DecodeChar?_append_eq_assemble₃ {l : List UInt8} {b : ByteArray} (hl : l.length = 3) (h : parseFirstByte l[0] = .twoMore) :
|
||||
(l.toByteArray ++ b).utf8DecodeChar? 0 = assemble₃ l[0] l[1] l[2] := sorry
|
||||
(l.toByteArray ++ b).utf8DecodeChar? 0 = assemble₃ l[0] l[1] l[2] := by
|
||||
rw [utf8DecodeChar?_eq_assemble₃ (by simp [hl])]
|
||||
all_goals repeat rw [ByteArray.getElem_append_left (by simp [hl])]
|
||||
all_goals repeat rw [List.getElem_toByteArray]
|
||||
assumption
|
||||
|
||||
theorem utf8DecodeChar?_append_eq_assemble₄ {l : List UInt8} {b : ByteArray} (hl : l.length = 4) (h : parseFirstByte l[0] = .threeMore) :
|
||||
(l.toByteArray ++ b).utf8DecodeChar? 0 = assemble₄ l[0] l[1] l[2] l[3] := sorry
|
||||
(l.toByteArray ++ b).utf8DecodeChar? 0 = assemble₄ l[0] l[1] l[2] l[3] := by
|
||||
rw [utf8DecodeChar?_eq_assemble₄ (by simp [hl])]
|
||||
all_goals repeat rw [ByteArray.getElem_append_left (by simp [hl])]
|
||||
all_goals repeat rw [List.getElem_toByteArray]
|
||||
assumption
|
||||
|
||||
/-!
|
||||
# Main theorems
|
||||
|
|
@ -1374,7 +1388,6 @@ public theorem List.utf8DecodeChar_utf8Encode_cons {l : List Char} {c : Char} {h
|
|||
|
||||
namespace UInt8
|
||||
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
/--
|
||||
Predicate for whether a byte can appear as the first byte of the UTF-8 encoding of a Unicode
|
||||
scalar value.
|
||||
|
|
@ -1457,11 +1470,9 @@ theorem utf8ByteSize_eq_utf8ByteSize_parseFirstByte {c : UInt8} {h : c.IsUTF8Fir
|
|||
end UInt8
|
||||
|
||||
public theorem ByteArray.isUTF8FirstByte_getElem_zero_utf8EncodeChar_append {c : Char} {b : ByteArray} :
|
||||
(((String.utf8EncodeChar c).toByteArray ++ b)[0]'(by simp; have := c.utf8Size_pos; omega)).IsUTF8FirstByte :=
|
||||
-- TODO: restore proof after bootstrap:
|
||||
-- by rw [ByteArray.getElem_append_left (by simp [c.utf8Size_pos]),
|
||||
-- List.getElem_toByteArray, UInt8.isUTF8FirstByte_getElem_utf8EncodeChar]
|
||||
sorry
|
||||
(((String.utf8EncodeChar c).toByteArray ++ b)[0]'(by simp; have := c.utf8Size_pos; omega)).IsUTF8FirstByte := by
|
||||
rw [ByteArray.getElem_append_left (by simp [c.utf8Size_pos]),
|
||||
List.getElem_toByteArray, UInt8.isUTF8FirstByte_getElem_utf8EncodeChar]
|
||||
|
||||
public theorem ByteArray.isUTF8FirstByte_of_isSome_utf8DecodeChar? {b : ByteArray} {i : Nat}
|
||||
(h : (utf8DecodeChar? b i).isSome) : (b[i]'(lt_size_of_isSome_utf8DecodeChar? h)).IsUTF8FirstByte := by
|
||||
|
|
|
|||
|
|
@ -108,6 +108,14 @@ where
|
|||
else
|
||||
go acc accStop pos'
|
||||
termination_by text.utf8ByteSize - pos.byteIdx
|
||||
decreasing_by all_goals sorry -- TODO: restore after bootstrap
|
||||
decreasing_by
|
||||
decreasing_with
|
||||
change text.utf8ByteSize - ((pos.next text).next text).byteIdx < text.utf8ByteSize - pos.byteIdx
|
||||
have k := Nat.gt_of_not_le <| mt decide_eq_true h
|
||||
exact Nat.sub_lt_sub_left k (Nat.lt_trans (String.Pos.Raw.lt_next text pos) (String.Pos.Raw.lt_next _ _))
|
||||
decreasing_with
|
||||
change text.utf8ByteSize - (pos.next text).byteIdx < text.utf8ByteSize - pos.byteIdx
|
||||
have k := Nat.gt_of_not_le <| mt decide_eq_true h
|
||||
exact Nat.sub_lt_sub_left k (String.Pos.Raw.lt_next _ _)
|
||||
|
||||
end String
|
||||
|
|
|
|||
|
|
@ -30,9 +30,9 @@ def Slice.posGE (s : Slice) (offset : String.Pos.Raw) (_h : offset ≤ s.rawEnd
|
|||
else
|
||||
s.endPos
|
||||
termination_by s.utf8ByteSize - offset.byteIdx
|
||||
-- decreasing_by
|
||||
-- simp only [Pos.Raw.lt_iff, byteIdx_rawEndPos, utf8ByteSize_eq, Pos.Raw.byteIdx_inc] at h ⊢
|
||||
-- omega
|
||||
decreasing_by
|
||||
simp only [Pos.Raw.lt_iff, byteIdx_rawEndPos, utf8ByteSize_eq, Pos.Raw.byteIdx_inc] at h ⊢
|
||||
omega
|
||||
|
||||
/--
|
||||
Obtains the smallest valid position that is strictly greater than the given byte position.
|
||||
|
|
|
|||
|
|
@ -73,7 +73,25 @@ def splitOnAux (s sep : String) (b : Pos.Raw) (i : Pos.Raw) (j : Pos.Raw) (r : L
|
|||
else
|
||||
splitOnAux s sep b ((i.unoffsetBy j).next s) 0 r
|
||||
termination_by (s.rawEndPos.1 - (j.byteDistance i), sep.rawEndPos.1 - j.1)
|
||||
decreasing_by all_goals sorry -- TODO: restore after bootstrap
|
||||
decreasing_by
|
||||
focus
|
||||
rename_i h _ _
|
||||
left; exact Nat.sub_lt_sub_left
|
||||
(Nat.lt_of_le_of_lt (Nat.sub_le ..) (Nat.gt_of_not_le (mt decide_eq_true h)))
|
||||
(Nat.lt_of_le_of_lt (Nat.sub_le ..) (Pos.Raw.lt_next s _))
|
||||
focus
|
||||
rename_i i₀ j₀ _ eq h'
|
||||
rw [show (j₀.next sep).byteDistance (i₀.next s) = j₀.byteDistance i₀ by
|
||||
change (_ + Char.utf8Size _) - (_ + Char.utf8Size _) = _
|
||||
rw [(beq_iff_eq ..).1 eq, Nat.add_sub_add_right]; rfl]
|
||||
right; exact Nat.sub_lt_sub_left
|
||||
(Nat.lt_of_le_of_lt (Nat.le_add_right ..) (Nat.gt_of_not_le (mt decide_eq_true h')))
|
||||
(Pos.Raw.lt_next sep _)
|
||||
focus
|
||||
rename_i h _
|
||||
left; exact Nat.sub_lt_sub_left
|
||||
(Nat.lt_of_le_of_lt (Nat.sub_le ..) (Nat.gt_of_not_le (mt decide_eq_true h)))
|
||||
(Pos.Raw.lt_next s _)
|
||||
|
||||
/--
|
||||
Splits a string `s` on occurrences of the separator string `sep`. The default separator is `" "`.
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ theorem Pos.next_le_iff_lt {s : String} {p q : s.Pos} {h} : p.next h ≤ q ↔ p
|
|||
|
||||
@[simp]
|
||||
theorem Slice.Pos.le_startPos {s : Slice} (p : s.Pos) : p ≤ s.startPos ↔ p = s.startPos :=
|
||||
⟨fun h => Std.le_antisymm h (startPos_le _), by sorry⟩
|
||||
⟨fun h => Std.le_antisymm h (startPos_le _), by simp +contextual⟩
|
||||
|
||||
@[simp]
|
||||
theorem Slice.Pos.startPos_lt_iff {s : Slice} (p : s.Pos) : s.startPos < p ↔ p ≠ s.startPos := by
|
||||
|
|
@ -37,15 +37,15 @@ theorem Slice.Pos.startPos_lt_iff {s : Slice} (p : s.Pos) : s.startPos < p ↔ p
|
|||
|
||||
@[simp]
|
||||
theorem Slice.Pos.endPos_le {s : Slice} (p : s.Pos) : s.endPos ≤ p ↔ p = s.endPos :=
|
||||
⟨fun h => Std.le_antisymm (le_endPos _) h, by sorry⟩
|
||||
⟨fun h => Std.le_antisymm (le_endPos _) h, by simp +contextual⟩
|
||||
|
||||
@[simp]
|
||||
theorem Pos.le_startPos {s : String} (p : s.Pos) : p ≤ s.startPos ↔ p = s.startPos :=
|
||||
⟨fun h => Std.le_antisymm h (startPos_le _), by sorry⟩
|
||||
⟨fun h => Std.le_antisymm h (startPos_le _), by simp +contextual⟩
|
||||
|
||||
@[simp]
|
||||
theorem Pos.endPos_le {s : String} (p : s.Pos) : s.endPos ≤ p ↔ p = s.endPos :=
|
||||
⟨fun h => Std.le_antisymm (le_endPos _) h, by sorry⟩
|
||||
⟨fun h => Std.le_antisymm (le_endPos _) h, by simp +contextual [Std.le_refl]⟩
|
||||
|
||||
@[simp]
|
||||
theorem Slice.Pos.not_lt_startPos {s : Slice} {p : s.Pos} : ¬ p < s.startPos :=
|
||||
|
|
|
|||
|
|
@ -194,7 +194,8 @@ def modify (s : String) (i : Pos.Raw) (f : Char → Char) : String :=
|
|||
else
|
||||
mapAux f (p.modify f h) (p.pastModify f h)
|
||||
termination_by p.remainingBytes
|
||||
decreasing_by all_goals sorry -- TODO: restore after bootstrap
|
||||
decreasing_by
|
||||
simp [remainingBytes_pastModify, ← Pos.lt_iff_remainingBytes_lt]
|
||||
|
||||
/--
|
||||
Applies the function `f` to every character in a string, returning a string that contains the
|
||||
|
|
|
|||
|
|
@ -96,9 +96,9 @@ where
|
|||
else
|
||||
true
|
||||
termination_by len.byteIdx - curr.byteIdx
|
||||
-- decreasing_by
|
||||
-- simp [Pos.Raw.lt_iff] at h ⊢
|
||||
-- omega
|
||||
decreasing_by
|
||||
simp [Pos.Raw.lt_iff] at h ⊢
|
||||
omega
|
||||
|
||||
@[inline]
|
||||
def memcmpSlice (lhs rhs : Slice) (lstart : String.Pos.Raw) (rstart : String.Pos.Raw)
|
||||
|
|
|
|||
|
|
@ -62,6 +62,13 @@ def finitenessRelation : Std.Iterators.FinitenessRelation (ForwardCharSearcher s
|
|||
wf := InvImage.wf _ WellFoundedRelation.wf
|
||||
subrelation {it it'} h := by
|
||||
simp_wf
|
||||
obtain ⟨step, h, h'⟩ := h
|
||||
cases step
|
||||
· cases h
|
||||
obtain ⟨_, h2, _⟩ := h'
|
||||
simp [h2]
|
||||
· cases h'
|
||||
· cases h
|
||||
|
||||
instance : Std.Iterators.Finite (ForwardCharSearcher s c) Id :=
|
||||
.of_finitenessRelation finitenessRelation
|
||||
|
|
@ -120,6 +127,13 @@ def finitenessRelation : Std.Iterators.FinitenessRelation (BackwardCharSearcher
|
|||
wf := InvImage.wf _ WellFoundedRelation.wf
|
||||
subrelation {it it'} h := by
|
||||
simp_wf
|
||||
obtain ⟨step, h, h'⟩ := h
|
||||
cases step
|
||||
· cases h
|
||||
obtain ⟨_, h1, h2, _⟩ := h'
|
||||
simp [h2]
|
||||
· cases h'
|
||||
· cases h
|
||||
|
||||
instance : Std.Iterators.Finite (BackwardCharSearcher s) Id :=
|
||||
.of_finitenessRelation finitenessRelation
|
||||
|
|
|
|||
|
|
@ -64,6 +64,13 @@ def finitenessRelation : Std.Iterators.FinitenessRelation (ForwardCharPredSearch
|
|||
wf := InvImage.wf _ WellFoundedRelation.wf
|
||||
subrelation {it it'} h := by
|
||||
simp_wf
|
||||
obtain ⟨step, h, h'⟩ := h
|
||||
cases step
|
||||
· cases h
|
||||
obtain ⟨_, h2, _⟩ := h'
|
||||
simp [h2]
|
||||
· cases h'
|
||||
· cases h
|
||||
|
||||
instance : Std.Iterators.Finite (ForwardCharPredSearcher p s) Id :=
|
||||
.of_finitenessRelation finitenessRelation
|
||||
|
|
@ -131,6 +138,15 @@ def finitenessRelation : Std.Iterators.FinitenessRelation (BackwardCharPredSearc
|
|||
wf := InvImage.wf _ WellFoundedRelation.wf
|
||||
subrelation {it it'} h := by
|
||||
simp_wf
|
||||
obtain ⟨step, h, h'⟩ := h
|
||||
cases step
|
||||
· cases h
|
||||
obtain ⟨_, h1, h2, _⟩ := h'
|
||||
have h3 := Pos.offset_prev_lt_offset (h := h1)
|
||||
simp [Pos.ext_iff, String.Pos.Raw.ext_iff, String.Pos.Raw.lt_iff] at h2 h3
|
||||
omega
|
||||
· cases h'
|
||||
· cases h
|
||||
|
||||
instance : Std.Iterators.Finite (BackwardCharPredSearcher s) Id :=
|
||||
.of_finitenessRelation finitenessRelation
|
||||
|
|
|
|||
|
|
@ -40,12 +40,20 @@ where
|
|||
let patByte := pat.getUTF8Byte ⟨table.size⟩ hs
|
||||
let dist := computeDistance patByte table ht h (table[table.size - 1])
|
||||
(by have := h (table.size - 1) (by omega); omega)
|
||||
let dist' := if pat.getUTF8Byte ⟨dist.1⟩ (by sorry) = patByte then dist.1 + 1 else dist
|
||||
go (table.push dist') (by sorry) (by sorry) (by sorry)
|
||||
let dist' := if pat.getUTF8Byte ⟨dist.1⟩ (by simp [Pos.Raw.lt_iff]; omega) = patByte then dist.1 + 1 else dist
|
||||
go (table.push dist') (by simp) (by simp; omega) (by
|
||||
intro i hi
|
||||
by_cases hi' : i = table.size
|
||||
· subst hi'
|
||||
simp [dist']
|
||||
have := dist.2
|
||||
split <;> omega
|
||||
· rw [Array.getElem_push_lt]
|
||||
· apply h
|
||||
· simp at hi
|
||||
omega)
|
||||
else
|
||||
Vector.mk table (by omega)
|
||||
termination_by pat.utf8ByteSize - table.size
|
||||
decreasing_by all_goals sorry -- TODO: restore after bootstrap
|
||||
|
||||
computeDistance (patByte : UInt8) (table : Array Nat)
|
||||
(ht : table.size ≤ pat.utf8ByteSize)
|
||||
|
|
@ -217,6 +225,27 @@ private def finitenessRelation :
|
|||
wf := InvImage.wf _ WellFoundedRelation.wf
|
||||
subrelation {it it'} h := by
|
||||
simp_wf
|
||||
obtain ⟨step, h, h'⟩ := h
|
||||
cases step
|
||||
all_goals try
|
||||
cases h
|
||||
revert h'
|
||||
simp only [Std.IterM.IsPlausibleStep, Std.Iterator.IsPlausibleStep]
|
||||
match it.internalState with
|
||||
| .emptyBefore pos =>
|
||||
rintro (⟨h, h'⟩|h') <;> simp [h', ForwardSliceSearcher.toOption, Option.lt, Prod.lex_def]
|
||||
| .emptyAt pos h =>
|
||||
simp only [forall_exists_index, and_imp]
|
||||
intro x hx h
|
||||
simpa [h, ForwardSliceSearcher.toOption, Option.lt, Prod.lex_def,
|
||||
← Pos.lt_iff_remainingBytes_lt]
|
||||
| .proper needle table ht stackPos needlePos hn =>
|
||||
rintro (⟨newStackPos, newNeedlePos, h₁, h₂, (h|⟨rfl, h⟩)⟩|h)
|
||||
· simp [h₂, ForwardSliceSearcher.toOption, Option.lt, Prod.lex_def, h]
|
||||
· simpa [h₂, ForwardSliceSearcher.toOption, Option.lt, Prod.lex_def, Pos.Raw.lt_iff]
|
||||
· simp [h, ForwardSliceSearcher.toOption, Option.lt]
|
||||
| .atEnd .. => simp
|
||||
· cases h
|
||||
|
||||
@[no_expose]
|
||||
instance : Std.Iterators.Finite (ForwardSliceSearcher s) Id :=
|
||||
|
|
|
|||
|
|
@ -170,6 +170,16 @@ private def finitenessRelation [Std.Iterators.Finite (σ s) Id] :
|
|||
wf := InvImage.wf _ (Option.wellFounded_lt Std.Iterators.Finite.wf_of_id)
|
||||
subrelation {it it'} h := by
|
||||
simp_wf
|
||||
obtain ⟨step, h, h'⟩ := h
|
||||
match step with
|
||||
| .yield it'' out | .skip it'' =>
|
||||
obtain rfl : it' = it'' := by simpa using h.symm
|
||||
simp only [Std.IterM.IsPlausibleStep, Std.Iterator.IsPlausibleStep] at h'
|
||||
revert h'
|
||||
match it, it' with
|
||||
| ⟨.operating _ searcher⟩, ⟨.operating _ searcher'⟩ => simp [SplitIterator.toOption, Option.lt]
|
||||
| ⟨.operating _ searcher⟩, ⟨.atEnd⟩ => simp [SplitIterator.toOption, Option.lt]
|
||||
| ⟨.atEnd⟩, _ => simp
|
||||
|
||||
@[no_expose]
|
||||
instance [Std.Iterators.Finite (σ s) Id] : Std.Iterators.Finite (SplitIterator pat s) Id :=
|
||||
|
|
@ -251,6 +261,16 @@ private def finitenessRelation [Std.Iterators.Finite (σ s) Id] :
|
|||
wf := InvImage.wf _ (Option.wellFounded_lt Std.Iterators.Finite.wf_of_id)
|
||||
subrelation {it it'} h := by
|
||||
simp_wf
|
||||
obtain ⟨step, h, h'⟩ := h
|
||||
match step with
|
||||
| .yield it'' out | .skip it'' =>
|
||||
obtain rfl : it' = it'' := by simpa using h.symm
|
||||
simp only [Std.IterM.IsPlausibleStep, Std.Iterator.IsPlausibleStep] at h'
|
||||
revert h'
|
||||
match it, it' with
|
||||
| ⟨.operating _ searcher⟩, ⟨.operating _ searcher'⟩ => simp [SplitInclusiveIterator.toOption, Option.lt]
|
||||
| ⟨.operating _ searcher⟩, ⟨.atEnd⟩ => simp [SplitInclusiveIterator.toOption, Option.lt]
|
||||
| ⟨.atEnd⟩, _ => simp
|
||||
|
||||
@[no_expose]
|
||||
instance [Std.Iterators.Finite (σ s) Id] :
|
||||
|
|
@ -581,6 +601,16 @@ private def finitenessRelation [Std.Iterators.Finite (σ s) Id] :
|
|||
wf := InvImage.wf _ (Option.wellFounded_lt Std.Iterators.Finite.wf_of_id)
|
||||
subrelation {it it'} h := by
|
||||
simp_wf
|
||||
obtain ⟨step, h, h'⟩ := h
|
||||
match step with
|
||||
| .yield it'' out | .skip it'' =>
|
||||
obtain rfl : it' = it'' := by simpa using h.symm
|
||||
simp only [Std.IterM.IsPlausibleStep, Std.Iterator.IsPlausibleStep] at h'
|
||||
revert h'
|
||||
match it, it' with
|
||||
| ⟨.operating _ searcher⟩, ⟨.operating _ searcher'⟩ => simp [RevSplitIterator.toOption, Option.lt]
|
||||
| ⟨.operating _ searcher⟩, ⟨.atEnd⟩ => simp [RevSplitIterator.toOption, Option.lt]
|
||||
| ⟨.atEnd⟩, _ => simp
|
||||
|
||||
@[no_expose]
|
||||
instance [Std.Iterators.Finite (σ s) Id] : Std.Iterators.Finite (RevSplitIterator ρ s) Id :=
|
||||
|
|
@ -795,9 +825,9 @@ where
|
|||
else
|
||||
s1Curr == s1.rawEndPos && s2Curr == s2.rawEndPos
|
||||
termination_by s1.endPos.offset.byteIdx - s1Curr.byteIdx
|
||||
-- decreasing_by
|
||||
-- simp [String.Pos.Raw.lt_iff] at h ⊢
|
||||
-- omega
|
||||
decreasing_by
|
||||
simp [String.Pos.Raw.lt_iff] at h ⊢
|
||||
omega
|
||||
|
||||
structure PosIterator (s : Slice) where
|
||||
currPos : s.Pos
|
||||
|
|
@ -842,6 +872,17 @@ private def finitenessRelation [Pure m] :
|
|||
wf := InvImage.wf _ WellFoundedRelation.wf
|
||||
subrelation {it it'} h := by
|
||||
simp_wf
|
||||
obtain ⟨step, h, h'⟩ := h
|
||||
cases step
|
||||
· cases h
|
||||
obtain ⟨h1, h2, _⟩ := h'
|
||||
have h3 := Char.utf8Size_pos (it.internalState.currPos.get h1)
|
||||
have h4 := it.internalState.currPos.isValidForSlice.le_utf8ByteSize
|
||||
simp [Pos.ext_iff, String.Pos.Raw.ext_iff] at h1 h2 h4
|
||||
omega
|
||||
· cases h'
|
||||
· cases h
|
||||
|
||||
@[no_expose]
|
||||
instance [Pure m] : Std.Iterators.Finite (PosIterator s) m :=
|
||||
.of_finitenessRelation finitenessRelation
|
||||
|
|
@ -913,6 +954,15 @@ private def finitenessRelation [Pure m] :
|
|||
wf := InvImage.wf _ WellFoundedRelation.wf
|
||||
subrelation {it it'} h := by
|
||||
simp_wf
|
||||
obtain ⟨step, h, h'⟩ := h
|
||||
cases step
|
||||
· cases h
|
||||
obtain ⟨h1, h2, _⟩ := h'
|
||||
have h3 := Pos.offset_prev_lt_offset (h := h1)
|
||||
simp [Pos.ext_iff, String.Pos.Raw.ext_iff, String.Pos.Raw.lt_iff] at h2 h3
|
||||
omega
|
||||
· cases h'
|
||||
· cases h
|
||||
|
||||
@[no_expose]
|
||||
instance [Pure m] : Std.Iterators.Finite (RevPosIterator s) m :=
|
||||
|
|
@ -979,6 +1029,17 @@ private def finitenessRelation [Pure m] :
|
|||
wf := InvImage.wf _ WellFoundedRelation.wf
|
||||
subrelation {it it'} h := by
|
||||
simp_wf
|
||||
obtain ⟨step, h, h'⟩ := h
|
||||
cases step
|
||||
· cases h
|
||||
obtain ⟨h1, h2, h3, h4⟩ := h'
|
||||
clear h4
|
||||
generalize it'.internalState.s = s at *
|
||||
cases h2
|
||||
simp [String.Pos.Raw.ext_iff, String.Pos.Raw.lt_iff] at h1 h3
|
||||
omega
|
||||
· cases h'
|
||||
· cases h
|
||||
|
||||
@[no_expose]
|
||||
instance [Pure m] : Std.Iterators.Finite ByteIterator m :=
|
||||
|
|
@ -1048,6 +1109,15 @@ private def finitenessRelation [Pure m] :
|
|||
wf := InvImage.wf _ WellFoundedRelation.wf
|
||||
subrelation {it it'} h := by
|
||||
simp_wf
|
||||
obtain ⟨step, h, h'⟩ := h
|
||||
cases step
|
||||
· cases h
|
||||
obtain ⟨h1, h2, h3, h4, h5⟩ := h'
|
||||
rw [h4]
|
||||
simp at h1 h3 ⊢
|
||||
omega
|
||||
· cases h'
|
||||
· cases h
|
||||
|
||||
@[no_expose]
|
||||
instance [Pure m] : Std.Iterators.Finite RevByteIterator m :=
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ theorem map_toSlice_prev? {s : String} {p : s.Pos} :
|
|||
|
||||
theorem ne_endPos_of_next?_eq_some {s : String} {p q : s.Pos}
|
||||
(h : p.next? = some q) : p ≠ s.endPos :=
|
||||
ne_of_apply_ne Pos.toSlice (Slice.Pos.ne_endPos_of_next?_eq_some (q := q.toSlice)
|
||||
ne_of_apply_ne Pos.toSlice (Slice.Pos.ne_endPos_of_next?_eq_some
|
||||
(by simpa only [Pos.map_toSlice_next?, Option.map_some] using congrArg (·.map toSlice) h))
|
||||
|
||||
theorem eq_next_of_next?_eq_some {s : String} {p q : s.Pos} (h : p.next? = some q) :
|
||||
|
|
@ -191,7 +191,7 @@ theorem eq_next_of_next?_eq_some {s : String} {p q : s.Pos} (h : p.next? = some
|
|||
|
||||
theorem ne_startPos_of_prev?_eq_some {s : String} {p q : s.Pos}
|
||||
(h : p.prev? = some q) : p ≠ s.startPos :=
|
||||
ne_of_apply_ne Pos.toSlice (Slice.Pos.ne_startPos_of_prev?_eq_some (q := q.toSlice)
|
||||
ne_of_apply_ne Pos.toSlice (Slice.Pos.ne_startPos_of_prev?_eq_some
|
||||
(by simpa only [Pos.map_toSlice_prev?, Option.map_some] using congrArg (·.map toSlice) h))
|
||||
|
||||
theorem eq_prev_of_prev?_eq_some {s : String} {p q : s.Pos} (h : p.prev? = some q) :
|
||||
|
|
|
|||
|
|
@ -328,20 +328,20 @@ protected theorem USize.mod_eq_of_lt {a b : USize} (h : a < b) : a % b = a := US
|
|||
@[simp] theorem UInt64.toNat_lt (n : UInt64) : n.toNat < 2 ^ 64 := n.toFin.isLt
|
||||
|
||||
theorem UInt8.size_lt_usizeSize : UInt8.size < USize.size := by
|
||||
cases USize.size_eq <;> sorry
|
||||
cases USize.size_eq <;> simp_all +decide
|
||||
theorem UInt8.size_le_usizeSize : UInt8.size ≤ USize.size :=
|
||||
Nat.le_of_lt UInt8.size_lt_usizeSize
|
||||
theorem UInt16.size_lt_usizeSize : UInt16.size < USize.size := by
|
||||
cases USize.size_eq <;> sorry
|
||||
cases USize.size_eq <;> simp_all +decide
|
||||
theorem UInt16.size_le_usizeSize : UInt16.size ≤ USize.size :=
|
||||
Nat.le_of_lt UInt16.size_lt_usizeSize
|
||||
theorem UInt32.size_le_usizeSize : UInt32.size ≤ USize.size := by
|
||||
cases USize.size_eq <;> sorry
|
||||
cases USize.size_eq <;> simp_all +decide
|
||||
theorem USize.size_eq_two_pow : USize.size = 2 ^ System.Platform.numBits := (rfl)
|
||||
theorem USize.toNat_lt_two_pow_numBits (n : USize) : n.toNat < 2 ^ System.Platform.numBits := n.toFin.isLt
|
||||
@[simp] theorem USize.toNat_lt (n : USize) : n.toNat < 2 ^ 64 := Nat.lt_of_lt_of_le n.toFin.isLt size_le
|
||||
theorem USize.size_le_uint64Size : USize.size ≤ UInt64.size := by
|
||||
cases USize.size_eq <;> sorry
|
||||
cases USize.size_eq <;> simp_all +decide
|
||||
|
||||
theorem UInt8.toNat_lt_usizeSize (n : UInt8) : n.toNat < USize.size :=
|
||||
Nat.lt_of_lt_of_le n.toNat_lt (by cases USize.size_eq <;> simp_all)
|
||||
|
|
@ -350,10 +350,10 @@ theorem UInt16.toNat_lt_usizeSize (n : UInt16) : n.toNat < USize.size :=
|
|||
theorem UInt32.toNat_lt_usizeSize (n : UInt32) : n.toNat < USize.size :=
|
||||
Nat.lt_of_lt_of_le n.toNat_lt (by cases USize.size_eq <;> simp_all)
|
||||
|
||||
theorem UInt8.size_dvd_usizeSize : UInt8.size ∣ USize.size := by cases USize.size_eq <;> sorry
|
||||
theorem UInt16.size_dvd_usizeSize : UInt16.size ∣ USize.size := by cases USize.size_eq <;> sorry
|
||||
theorem UInt32.size_dvd_usizeSize : UInt32.size ∣ USize.size := by cases USize.size_eq <;> sorry
|
||||
theorem USize.size_dvd_uInt64Size : USize.size ∣ UInt64.size := by cases USize.size_eq <;> sorry
|
||||
theorem UInt8.size_dvd_usizeSize : UInt8.size ∣ USize.size := by cases USize.size_eq <;> simp_all +decide
|
||||
theorem UInt16.size_dvd_usizeSize : UInt16.size ∣ USize.size := by cases USize.size_eq <;> simp_all +decide
|
||||
theorem UInt32.size_dvd_usizeSize : UInt32.size ∣ USize.size := by cases USize.size_eq <;> simp_all +decide
|
||||
theorem USize.size_dvd_uInt64Size : USize.size ∣ UInt64.size := by cases USize.size_eq <;> simp_all +decide
|
||||
|
||||
@[simp] theorem mod_usizeSize_uInt8Size (n : Nat) : n % USize.size % UInt8.size = n % UInt8.size :=
|
||||
Nat.mod_mod_of_dvd _ UInt8.size_dvd_usizeSize
|
||||
|
|
@ -365,13 +365,13 @@ theorem USize.size_dvd_uInt64Size : USize.size ∣ UInt64.size := by cases USize
|
|||
Nat.mod_mod_of_dvd _ USize.size_dvd_uInt64Size
|
||||
|
||||
@[simp] theorem USize.size_sub_one_mod_uint8Size : (USize.size - 1) % UInt8.size = UInt8.size - 1 := by
|
||||
cases USize.size_eq <;> sorry
|
||||
cases USize.size_eq <;> simp_all +decide
|
||||
@[simp] theorem USize.size_sub_one_mod_uint16Size : (USize.size - 1) % UInt16.size = UInt16.size - 1 := by
|
||||
cases USize.size_eq <;> sorry
|
||||
cases USize.size_eq <;> simp_all +decide
|
||||
@[simp] theorem USize.size_sub_one_mod_uint32Size : (USize.size - 1) % UInt32.size = UInt32.size - 1 := by
|
||||
cases USize.size_eq <;> sorry
|
||||
cases USize.size_eq <;> simp_all +decide
|
||||
@[simp] theorem UInt64.size_sub_one_mod_uSizeSize : 18446744073709551615 % USize.size = USize.size - 1 := by
|
||||
cases USize.size_eq <;> sorry
|
||||
cases USize.size_eq <;> simp_all +decide
|
||||
|
||||
@[simp] theorem UInt8.toNat_mod_size (n : UInt8) : n.toNat % UInt8.size = n.toNat := Nat.mod_eq_of_lt n.toNat_lt
|
||||
@[simp] theorem UInt8.toNat_mod_uInt16Size (n : UInt8) : n.toNat % UInt16.size = n.toNat := Nat.mod_eq_of_lt (Nat.lt_trans n.toNat_lt (by decide))
|
||||
|
|
@ -1257,7 +1257,7 @@ theorem USize.toUInt64_ofNatTruncate_of_lt {n : Nat} (hn : n < USize.size) :
|
|||
UInt64.toNat.inj (by simp [toNat_ofNatTruncate_of_lt hn])
|
||||
|
||||
theorem USize.toUInt64_ofNatTruncate_of_le {n : Nat} (hn : USize.size ≤ n) :
|
||||
(USize.ofNatTruncate n).toUInt64 = UInt64.ofNatLT (USize.size - 1) (by cases USize.size_eq <;> sorry) :=
|
||||
(USize.ofNatTruncate n).toUInt64 = UInt64.ofNatLT (USize.size - 1) (by cases USize.size_eq <;> simp_all +decide) :=
|
||||
UInt64.toNat.inj (by simp [toNat_ofNatTruncate_of_le hn])
|
||||
|
||||
@[simp] theorem UInt8.toUInt16_ofNat' {n : Nat} (hn : n < UInt8.size) : (UInt8.ofNat n).toUInt16 = UInt16.ofNat n := by
|
||||
|
|
|
|||
|
|
@ -15,8 +15,6 @@ public import Init.Grind
|
|||
|
||||
public section
|
||||
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
|
||||
namespace Vector
|
||||
|
||||
/-- The zero vector. -/
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ public section
|
|||
|
||||
set_option linter.listVariables true -- Enforce naming conventions for `List`/`Array`/`Vector` variables.
|
||||
set_option linter.indexVariables true -- Enforce naming conventions for index variables.
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
|
||||
namespace Vector
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ public section
|
|||
|
||||
set_option linter.listVariables true -- Enforce naming conventions for `List`/`Array`/`Vector` variables.
|
||||
set_option linter.indexVariables true -- Enforce naming conventions for index variables.
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
|
||||
/-- `Vector α n` is an `Array α` with size `n`. -/
|
||||
structure Vector (α : Type u) (n : Nat) where
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ public section
|
|||
|
||||
set_option linter.listVariables true -- Enforce naming conventions for `List`/`Array`/`Vector` variables.
|
||||
set_option linter.indexVariables true -- Enforce naming conventions for index variables.
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
|
||||
namespace Vector
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ public section
|
|||
|
||||
set_option linter.listVariables true -- Enforce naming conventions for `List`/`Array`/`Vector` variables.
|
||||
set_option linter.indexVariables true -- Enforce naming conventions for index variables.
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
|
||||
namespace Vector
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ public section
|
|||
|
||||
set_option linter.listVariables true -- Enforce naming conventions for `List`/`Array`/`Vector` variables.
|
||||
set_option linter.indexVariables true -- Enforce naming conventions for index variables.
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
|
||||
namespace Vector
|
||||
|
||||
|
|
@ -26,7 +25,7 @@ open Nat
|
|||
/-! ### eraseIdx -/
|
||||
|
||||
@[grind =]
|
||||
theorem eraseIdx_eq_take_drop_succ {xs : Vector α n} {i : Nat} (h : i < n) :
|
||||
theorem eraseIdx_eq_take_drop_succ {xs : Vector α n} {i : Nat} (h) :
|
||||
xs.eraseIdx i = (xs.take i ++ xs.drop (i + 1)).cast (by omega) := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [Array.eraseIdx_eq_take_drop_succ, *]
|
||||
|
|
@ -56,19 +55,19 @@ theorem getElem_eraseIdx {xs : Vector α n} {i : Nat} (h : i < n) {j : Nat} (h'
|
|||
rw [← getElem?_eq_getElem, getElem?_eraseIdx]
|
||||
split <;> simp
|
||||
|
||||
theorem mem_of_mem_eraseIdx {xs : Vector α n} {i : Nat} {h : i < n} {a : α} (hm : a ∈ xs.eraseIdx i) : a ∈ xs := by
|
||||
theorem mem_of_mem_eraseIdx {xs : Vector α n} {i : Nat} {h} {a : α} (h : a ∈ xs.eraseIdx i) : a ∈ xs := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simpa using Array.mem_of_mem_eraseIdx (by simpa using hm)
|
||||
simpa using Array.mem_of_mem_eraseIdx (by simpa using h)
|
||||
|
||||
grind_pattern mem_of_mem_eraseIdx => a ∈ xs.eraseIdx i
|
||||
|
||||
theorem eraseIdx_append_of_lt_size {xs : Vector α n} {k : Nat} (hk : k < n) (xs' : Vector α n) (h : k < n + n) :
|
||||
theorem eraseIdx_append_of_lt_size {xs : Vector α n} {k : Nat} (hk : k < n) (xs' : Vector α n) (h) :
|
||||
eraseIdx (xs ++ xs') k = (eraseIdx xs k ++ xs').cast (by omega) := by
|
||||
rcases xs with ⟨xs⟩
|
||||
rcases xs' with ⟨xs'⟩
|
||||
simp [Array.eraseIdx_append_of_lt_size, *]
|
||||
|
||||
theorem eraseIdx_append_of_length_le {xs : Vector α n} {k : Nat} (hk : n ≤ k) (xs' : Vector α n) (h : k < n + n) :
|
||||
theorem eraseIdx_append_of_length_le {xs : Vector α n} {k : Nat} (hk : n ≤ k) (xs' : Vector α n) (h) :
|
||||
eraseIdx (xs ++ xs') k = (xs ++ eraseIdx xs' (k - n)).cast (by omega) := by
|
||||
rcases xs with ⟨xs⟩
|
||||
rcases xs' with ⟨xs'⟩
|
||||
|
|
@ -89,16 +88,16 @@ theorem eraseIdx_cast {xs : Vector α n} {k : Nat} (h : k < m) :
|
|||
simp
|
||||
|
||||
@[grind =]
|
||||
theorem eraseIdx_replicate {n : Nat} {a : α} {k : Nat} {h : k < n} :
|
||||
theorem eraseIdx_replicate {n : Nat} {a : α} {k : Nat} {h} :
|
||||
(replicate n a).eraseIdx k = replicate (n - 1) a := by
|
||||
rw [replicate_eq_mk_replicate, eraseIdx_mk]
|
||||
simp [Array.eraseIdx_replicate, *]
|
||||
|
||||
theorem mem_eraseIdx_iff_getElem {x : α} {xs : Vector α n} {k : Nat} {h : k < n} : x ∈ xs.eraseIdx k h ↔ ∃ i w, i ≠ k ∧ xs[i]'w = x := by
|
||||
theorem mem_eraseIdx_iff_getElem {x : α} {xs : Vector α n} {k} {h} : x ∈ xs.eraseIdx k h ↔ ∃ i w, i ≠ k ∧ xs[i]'w = x := by
|
||||
rcases xs with ⟨xs⟩
|
||||
simp [Array.mem_eraseIdx_iff_getElem, *]
|
||||
|
||||
theorem mem_eraseIdx_iff_getElem? {x : α} {xs : Vector α n} {k : Nat} {h : k < n} : x ∈ xs.eraseIdx k h ↔ ∃ i ≠ k, xs[i]? = some x := by
|
||||
theorem mem_eraseIdx_iff_getElem? {x : α} {xs : Vector α n} {k} {h} : x ∈ xs.eraseIdx k h ↔ ∃ i ≠ k, xs[i]? = some x := by
|
||||
rcases xs with ⟨xs⟩
|
||||
simp [Array.mem_eraseIdx_iff_getElem?, *]
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ public section
|
|||
|
||||
set_option linter.listVariables true -- Enforce naming conventions for `List`/`Array`/`Vector` variables.
|
||||
set_option linter.indexVariables true -- Enforce naming conventions for index variables.
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
|
||||
open Nat
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ public section
|
|||
|
||||
set_option linter.listVariables true -- Enforce naming conventions for `List`/`Array`/`Vector` variables.
|
||||
set_option linter.indexVariables true -- Enforce naming conventions for index variables.
|
||||
set_option debug.byAsSorry true -- TODO: remove after bootstrap
|
||||
|
||||
namespace Vector
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue