This PR completes aligning `List`/`Array`/`Vector` lemmas about `flatten`. `Vector.flatten` was previously missing, and has been added (for rectangular sizes only). A small number of missing `Option` lemmas were also need to get the proofs to go through.
133 lines
4.3 KiB
Text
133 lines
4.3 KiB
Text
/-!
|
|
A few cases where guessing the lexicographic order fails, and
|
|
where we want to keep tabs on the output.
|
|
|
|
All functions take more than one changing argument, because the guesslex
|
|
code skips non-mutuals unary functions with only one plausible measure.
|
|
-/
|
|
|
|
def nonTerminating : Nat → Nat → Nat
|
|
| 0, _ => 0
|
|
| n, m => nonTerminating (.succ n) (.succ m)
|
|
|
|
-- Saying decreasing_by forces Lean to use structural recursion, which gives a different
|
|
-- error message
|
|
def nonTerminating2 : Nat → Nat → Nat
|
|
| 0, _ => 0
|
|
| n, m => nonTerminating2 (.succ n) (.succ m)
|
|
decreasing_by decreasing_tactic
|
|
|
|
def noArguments : Nat := noArguments
|
|
|
|
def noNonFixedArguments (n : Nat) : Nat := noNonFixedArguments n
|
|
|
|
def Array.sum' (xs : Array Nat) : Nat := xs.foldl (init := 0) Nat.add
|
|
|
|
namespace InterestingMatrix
|
|
def f : (n m l : Nat) → Nat
|
|
| n+1, m+1, l+1 => #[
|
|
f (n+1) (m+1) (l+1),
|
|
f (n+1) (m-1) (l),
|
|
f (n) (m+1) (l) ].sum'
|
|
| _, _, _ => 0
|
|
decreasing_by decreasing_tactic
|
|
end InterestingMatrix
|
|
|
|
namespace InterestingMatrixWithForbiddenArguments
|
|
def f : (n m : Nat) → (h : True) → Nat → Nat
|
|
| n+1, m+1, h, l+1 => #[
|
|
f (n+1) (m+1) h (l+1),
|
|
f (n+1) (m-1) h (l),
|
|
f (n) (m+1) h (l) ].sum'
|
|
| _, _, _, _ => 0
|
|
decreasing_by decreasing_tactic
|
|
end InterestingMatrixWithForbiddenArguments
|
|
|
|
namespace InterestingMatrixWithNames
|
|
-- Hopefully eventually lean will pick up names even with pattern match syntax
|
|
def f (n m l : Nat) : Nat := match n, m, l with
|
|
| n+1, m+1, l+1 => #[
|
|
f (n+1) (m+1) (l+1),
|
|
f (n+1) (m-1) (l),
|
|
f (n) (m+1) (l) ].sum'
|
|
| _, _, _ => 0
|
|
decreasing_by decreasing_tactic
|
|
end InterestingMatrixWithNames
|
|
|
|
namespace Mutual
|
|
mutual
|
|
def f (fixed n m l : Nat) : Nat := match n, m, l with
|
|
| n+1, m+1, l+1 => #[
|
|
f fixed (n+1) (m+1) (l+1),
|
|
f fixed (n+1) (m-1) (l),
|
|
g fixed (n) (m+1) trivial (l)].sum'
|
|
| _, _, _ => 0
|
|
|
|
def g (fixed n m : Nat) (H : True) (l : Nat) : Nat := match n, m, l with
|
|
| n+1, m+1, l+1 => #[
|
|
g fixed (m+1) (n+1) H (l+1),
|
|
g fixed (m+1) (n-1) H (l),
|
|
h fixed (m) (n+1) ].sum'
|
|
| _, _, _ => 0
|
|
|
|
def h (fixed : Nat) : (n m : Nat) -> Nat
|
|
| n+1, m+1 => #[
|
|
f fixed (n+1) (m+1) (n+1),
|
|
h fixed (n+1) (m-1),
|
|
h fixed (n) (m+1) ].sum'
|
|
| _, _ => 0
|
|
end
|
|
end Mutual
|
|
|
|
|
|
namespace DuplicatedCall
|
|
|
|
def dup (a : Nat) (b : Nat := a) := a + b
|
|
|
|
def f : (n m : Nat) → Nat
|
|
| 0, m => m
|
|
| n+1, m => dup (f (n+2) (m+1))
|
|
|
|
end DuplicatedCall
|
|
|
|
namespace TrickyCode
|
|
|
|
-- These tests run GuessLex on peculiar code that it once stumbled over, or might
|
|
-- stumble over in the future.
|
|
|
|
-- The GuessLex code at some point did not like eta-contracted motives in `casesOn`.
|
|
def FinPlus1 n := Fin (n + 1)
|
|
def badCasesOn (n m : Nat) : Fin (n + 1) :=
|
|
Nat.casesOn (motive := FinPlus1) n (⟨0,Nat.zero_lt_succ _⟩) (fun n => Fin.succ (badCasesOn n (.succ m)))
|
|
-- termination_by n
|
|
decreasing_by decreasing_tactic
|
|
|
|
|
|
-- This actually also fails with an explicit termination_by, and could be fixed
|
|
-- by eta-expanding the motive.
|
|
-- TODO: Fix by using eta-expanding variant of lambdaTelescope, e.g.
|
|
-- https://leanprover.zulipchat.com/#narrow/stream/217875-Is-there-code-for-X.3F/topic/Going.20under.20exactly.20one.20lambda/near/404278529
|
|
def badCasesOn2 (n m : Nat) : Fin (n + 1) :=
|
|
Nat.casesOn (motive := FinPlus1) n (⟨0,Nat.zero_lt_succ _⟩) (fun n => Fin.succ (badCasesOn2 n (.succ m)))
|
|
termination_by n
|
|
decreasing_by decreasing_tactic
|
|
|
|
-- The GuessLex code at does not like `casesOn` alternative with insufficient lambdas
|
|
-- TODO: Fix by using eta-expanding variant of lambdaTelescope, e.g.
|
|
-- https://leanprover.zulipchat.com/#narrow/stream/217875-Is-there-code-for-X.3F/topic/Going.20under.20exactly.20one.20lambda/near/404278529
|
|
def Fin_succ_comp (f : (n : Nat) → Fin (n + 1)) : (n : Nat) → Fin (n + 2) := fun n => Fin.succ (f n)
|
|
def badCasesOn3 (n m : Nat) : Fin (n + 1) :=
|
|
Nat.casesOn (motive := fun n => Fin (n + 1)) n (⟨0,Nat.zero_lt_succ _⟩)
|
|
(Fin_succ_comp (fun n => badCasesOn3 n (.succ m)))
|
|
-- termination_by n
|
|
decreasing_by decreasing_tactic
|
|
|
|
|
|
-- Same test, explicit termination_by
|
|
def badCasesOn4 (n m : Nat) : Fin (n + 1) :=
|
|
Nat.casesOn (motive := fun n => Fin (n + 1)) n (⟨0,Nat.zero_lt_succ _⟩)
|
|
(Fin_succ_comp (fun n => badCasesOn4 n (.succ m)))
|
|
termination_by n
|
|
decreasing_by decreasing_tactic
|
|
|
|
end TrickyCode
|