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 simpas 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 sorryd 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 h1is 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