This PR improves the functional cases principles, by making a more educated guess which function parameters should be targets and which should remain parameters (or be dropped). This simplifies the principles, and increases the chance that `fun_cases` can unfold the function call. Fixes #8296 (at least for the common cases, I hope.)
42 lines
1.4 KiB
Text
42 lines
1.4 KiB
Text
/--
|
||
info: Option.map.fun_cases.{u_1} {α : Type u_1} (motive : Option α → Prop) (case1 : ∀ (x : α), motive (some x))
|
||
(case2 : motive none) (x✝ : Option α) : motive x✝
|
||
-/
|
||
#guard_msgs(pass trace, all) in
|
||
#check Option.map.fun_cases
|
||
|
||
example (x : Option Nat) (f : Nat → Nat) : (x.map f).isSome = x.isSome := by
|
||
cases x using Option.map.fun_cases
|
||
case case1 x => simp
|
||
case case2 => simp
|
||
|
||
/--
|
||
info: List.map.fun_cases.{u} {α : Type u} (motive : List α → Prop) (case1 : motive [])
|
||
(case2 : ∀ (a : α) (as : List α), motive (a :: as)) (x✝ : List α) : motive x✝
|
||
-/
|
||
#guard_msgs in
|
||
#check List.map.fun_cases
|
||
|
||
/--
|
||
info: List.find?.fun_cases.{u} {α : Type u} (p : α → Bool) (motive : List α → Prop) (case1 : motive [])
|
||
(case2 : ∀ (a : α) (as : List α), p a = true → motive (a :: as))
|
||
(case3 : ∀ (a : α) (as : List α), p a = false → motive (a :: as)) (x✝ : List α) : motive x✝
|
||
-/
|
||
#guard_msgs in
|
||
#check List.find?.fun_cases
|
||
|
||
|
||
-- This tests shows that its not so easy to post-hoc recognize that `x` could be a parameter, but
|
||
-- `y` should be a target of the `fun_cases` principle (or the other way around)
|
||
def areTheseTargetsUnchanged (x y : Nat) : Bool :=
|
||
if _ : x = y then
|
||
true
|
||
else
|
||
false
|
||
|
||
/--
|
||
info: areTheseTargetsUnchanged.fun_cases (x y : Nat) (motive : Prop) (case1 : x = y → motive) (case2 : ¬x = y → motive) :
|
||
motive
|
||
-/
|
||
#guard_msgs in
|
||
#check areTheseTargetsUnchanged.fun_cases
|