Zulip Chat Archive
Stream: mathlib4
Topic: What does `simpa using foo` do?
Arien Malec (Nov 21 2022 at 20:30):
I'm trying to unwind a misbehaving simpa using foo
tactic (red squiggly + "no goals to be solved" + "Goals accomplished :tada:"), and would like to see where the more primitive simplification is getting to...
Riccardo Brasca (Nov 21 2022 at 20:35):
If you get both "goal accomplished" and an error it can be a bug. Can you provide a #mwe?
Arien Malec (Nov 21 2022 at 20:47):
Doesn't feel like it -- I'm deep in the bowels of a port that's secondary to another port. Let me see if I can sorry
some stuff to make an #mwe
Arien Malec (Nov 21 2022 at 20:49):
I get the error on both simpa
s here:
import Mathlib.Data.Option.Basic
import Mathlib.Data.Subtype
import Mathlib.Logic.Equiv.Defs
variable (e : Option α ≃ Option β)
private def remove_none_aux (x : α) : β := sorry
private theorem remove_none_aux_some {x : α} (h : ∃ x', e (some x) = some x') :
some (remove_none_aux e x) = e (some x) := sorry
private theorem remove_none_aux_none {x : α} (h : e (some x) = none) :
some (remove_none_aux e x) = e none := sorry
private theorem remove_none_aux_inv (x : α) : remove_none_aux e.symm (remove_none_aux e x) = x :=
Option.some_injective _
(by
cases h1 : e.symm (some (remove_none_aux e x)) <;> cases h2 : e (some x)
· rw [remove_none_aux_none _ h1]
exact (e.eq_symm_apply.mpr h2).symm
· rw [remove_none_aux_some _ ⟨_, h2⟩] at h1
simpa using h1
· rw [remove_none_aux_none _ h2] at h1
simpa using h1
· rw [remove_none_aux_some _ ⟨_, h1⟩]
rw [remove_none_aux_some _ ⟨_, h2⟩]
simp
)
But figuring out how to trigger this with a minimum of dependencies is going to be tricky. Let me work on it...
Junyan Xu (Nov 21 2022 at 20:52):
simpa using h1
is like simp
followed by exact h1
, so it's possible that simp
already solves the goal and so exact h1
produce an error that there's "no goals to be solved".
Riccardo Brasca (Nov 21 2022 at 20:54):
What happen if you remove all the private
?
Arien Malec (Nov 21 2022 at 20:54):
simp
doesn't solve the goal, sadly
Riccardo Brasca (Nov 21 2022 at 20:54):
Also, a sorried
def is always dangerous.
Junyan Xu (Nov 21 2022 at 20:55):
What does simp at h1 ⊢
gives you?
Arien Malec (Nov 21 2022 at 20:55):
No effect on removing the private
declarations.
Riccardo Brasca (Nov 21 2022 at 20:56):
Can you remove the first sorry
?
Arien Malec (Nov 21 2022 at 20:56):
I just sorry
d to de-dependency the beast...
Arien Malec (Nov 21 2022 at 20:56):
Unfortunately the first sorry
depends on a file that's as yet unported....
Arien Malec (Nov 21 2022 at 20:57):
@Junyan Xu 's suggestion gives the :tada:
Mario Carneiro (Nov 21 2022 at 20:58):
make them opaque
instead of sorry
Mario Carneiro (Nov 21 2022 at 20:58):
or axiom
Arien Malec (Nov 21 2022 at 21:00):
OK, this repros.
import Mathlib.Data.Option.Basic
import Mathlib.Data.Subtype
import Mathlib.Logic.Equiv.Defs
variable (e : Option α ≃ Option β)
def remove_none_aux (x : α) : β :=
if h : (e (some x)).isSome then Option.get _ h
else
Option.get _ <|
show (e none).isSome by
rw [← Option.ne_none_iff_isSome]
intro hn
rw [Option.not_isSome_iff_eq_none, ← hn] at h
exact Option.some_ne_none _ (e.injective h)
theorem remove_none_aux_some {x : α} (h : ∃ x', e (some x) = some x') :
some (remove_none_aux e x) = e (some x) :=
by simp [remove_none_aux, Option.isSome_iff_exists.mpr h]
theorem remove_none_aux_none {x : α} (h : e (some x) = none) :
some (remove_none_aux e x) = e none := by
simp [remove_none_aux, Option.not_isSome_iff_eq_none.mpr h]
theorem remove_none_aux_inv (x : α) : remove_none_aux e.symm (remove_none_aux e x) = x :=
Option.some_injective _
(by
cases h1 : e.symm (some (remove_none_aux e x)) <;> cases h2 : e (some x)
· rw [remove_none_aux_none _ h1]
exact (e.eq_symm_apply.mpr h2).symm
· rw [remove_none_aux_some _ ⟨_, h2⟩] at h1
simpa using h1
· rw [remove_none_aux_none _ h2] at h1
simpa using h1
· rw [remove_none_aux_some _ ⟨_, h1⟩]
rw [remove_none_aux_some _ ⟨_, h2⟩]
simp
)
Ruben Van de Velde (Nov 21 2022 at 21:06):
When I've hit that, replacing simpa using foo
by simp at foo
was sufficient
Arien Malec (Nov 21 2022 at 21:08):
So interestingly, when I replace
simpa using h1
with
simp at h1
exact h1
I get the same behavior (red squiggly + :tada:)
Mario Carneiro (Nov 21 2022 at 21:08):
what it macro expands to is:
have' h := h1
simp at h1
exact h
and the exact
line fails. As Ruben says, the solution is to just use simp at h1
, the error message should be fixed to indicate this
Mario Carneiro (Nov 21 2022 at 21:09):
The red squiggly + :tada: situation isn't that unusual, the tactic state is generally empty at the end of a proof and that's when the :tada: shows up
Mario Carneiro (Nov 21 2022 at 21:10):
in particular, almost all tactics give an error if used when there are no goals, and that's when you get the :tada:
Arien Malec (Nov 21 2022 at 21:10):
It's just that h1
is the goal....
Mario Carneiro (Nov 21 2022 at 21:10):
?
Arien Malec (Nov 21 2022 at 21:10):
so exact h1
should work?
Mario Carneiro (Nov 21 2022 at 21:11):
no, h1
is not the goal
Mario Carneiro (Nov 21 2022 at 21:11):
h1
is some ... = none
after simplification which is why simp
can close the goal itself
Arien Malec (Nov 21 2022 at 21:12):
If I take the #mwe above, replace simpa using h1
with simp at h1
, h1
is the goal...
Mario Carneiro (Nov 21 2022 at 21:12):
I think you must be confused by the "expected type" printout
Mario Carneiro (Nov 21 2022 at 21:12):
the tactic state is empty (i.e. there are no goals and you get a :tada:)
Mario Carneiro (Nov 21 2022 at 21:12):
that's the first bit
Mario Carneiro (Nov 21 2022 at 21:12):
the expected type is the type of h1
Mario Carneiro (Nov 21 2022 at 21:12):
because your cursor is on h1
Arien Malec (Nov 21 2022 at 21:14):
You are exactly correct
Last updated: Dec 20 2023 at 11:08 UTC