Zulip Chat Archive
Stream: new members
Topic: Why does "cases" fail and what to do then? (mismatch motive)
Malvin Gattinger (Mar 04 2024 at 17:27):
I am confused about when "cases" works and what I should use when it does not. My vague understanding is that it only works when the goal is a Prop
, but I am wondering whether there is a fundamental reason behind this restriction.
import Mathlib.Tactic.Tauto
def splitCases : α → β → (∀ γ ∈ [α, β], γ) := by
intro a b γ γ_def
simp at γ_def
-- The goal here does not yet mention Prop.
cases γ_def -- this actually restricts α,β,γ to be Prop !!
· tauto
· tauto
noncomputable -- I guess this is because we do not have DecidableEq Type?
def splitNoCases {α β : Type} : List α → List β → (∀ γ ∈ [α, β], List γ) := by
intro a b γ γ_def
simp at γ_def
-- cases γ_def -- does not work because the goal is List γ.
if h : γ = α then
subst h; exact a
else
if h : γ = β then
subst h; exact b
else
exfalso; tauto
def splitNoCases' {α β : Nat} : Fin α → Fin β → (∀ γ ∈ [α, β], Fin γ) := by
intro a b γ γ_def
simp at γ_def
-- cases γ_def -- does not work: type mismatch when assigning motive
if h : γ = α then
subst h; exact a
else
if h : γ = β then
subst h; exact b
else
exfalso; tauto
What are shorter and more elegant ways to do this if-then-else chaining? I also tried to use "cases (decide ...)" but it seems tedious with disjunctions. How do I do it if instead of [α, β] I have some arbitrary indexing type? Many thanks in advance for any help!
Kevin Buzzard (Mar 04 2024 at 19:56):
If the goal isn't a Prop
then arguably you shouldn't be in tactic mode at all! High-powered tactics like simp
will produce horrible terms which will be very hard to work with. They're fine in proofs because proofs are erased.
Kyle Miller (Mar 04 2024 at 20:50):
Cases uses the casesOn
associated to an inductive type, which is specialized to Prop
. In this case, I think you're using List.Mem.casesOn
, and you can use #check
to verify.
Kyle Miller (Mar 04 2024 at 21:12):
Here's how I would probably write the last function:
def splitNoCases' {α β : Nat} (a : Fin α) (b : Fin β) (γ : Nat) (γ_def : γ ∈ [α, β]) : Fin γ :=
if h : γ = α then
Fin.cast h.symm a
else if h' : γ = β then
Fin.cast h'.symm b
else
by exfalso; simp at γ_def; tauto
Malvin Gattinger (Mar 05 2024 at 09:34):
Thanks! This also made me learn about ▸
which seems to be a general version of things like Fin.cast
.
Kyle Miller (Mar 05 2024 at 18:34):
It's general, and it's how Fin.cast
itself can be implemented, but be aware that it's better to use Fin.cast
, and to define functions such as Fin.cast
, since you can write better simp lemmas for such functions than ▸
.
Last updated: May 02 2025 at 03:31 UTC