Zulip Chat Archive
Stream: general
Topic: esimp?
Reid Barton (Jul 13 2018 at 20:31):
Using Scott's category theory library, I sometimes encounter subexpressions like compose f (identity X)
, but with the caveat that one or both of the implicit "object" arguments of compose
is not syntactically equal to X
. This appears to stymie simp
from reducing the subexpression to f
. Is there a way to make simp
smarter here?
I know about erw
, which in my experience solves this problem when I want to use rw
, but I haven't found a good solution for simp
.
Reid Barton (Jul 13 2018 at 20:32):
It's kind of annoying, since I guess simp
could just generalize the wildcards in the pattern when trying to match the identity lemma...
Reid Barton (Jul 13 2018 at 20:41):
that is, rather than match against
@categories.category.compose.{?u_0 ?u_1} ?x_0 ?x_1 ?x_2 ?x_3 ?x_3 ?x_4 (@categories.category.identity.{?u_0 ?u_1} ?x_0 ?x_1 ?x_3)
look for
@categories.category.compose.{?u_0 ?u_1} ?x_0 ?x_1 ?x_2 ?x_3' ?x_3'' ?x_4 -- make these distinct (@categories.category.identity.{?u_0 ?u_1} ?x_0 ?x_1 ?x_3)
on the assumption that, if we found this, we can conclude that definitionally ?x_3 = ?x_3' = ?x_3''
, and no need to check syntactic equality
Mario Carneiro (Jul 13 2018 at 20:42):
In my experience this doesn't stop simp...
def nat2 := nat example (x : ℕ) : x + @has_zero.zero nat2 nat.has_zero = x := by simp
Mario Carneiro (Jul 13 2018 at 20:43):
I don't think it tries to match arguments that are dependencies at all
Reid Barton (Jul 13 2018 at 20:44):
Hmm, strange. I have several uses of dsimp, simp
where I'm pretty sure the dsimp
is just simplifying one of these object arguments. Let me look more closely at a simple one...
Reid Barton (Jul 13 2018 at 20:57):
Here is a small reproducer that depends on lean-category-theory
(or -pr
):
import categories.category open categories variables {C : Type} [small_category C] def M : C → C := id set_option trace.simplify.rewrite true set_option pp.all true variables {a b : C} {f : M a ⟶ M b} example : (f ≫ 𝟙 b : a ⟶ b) = f := begin simp end /- simplify tactic failed to simplify state: C : Type, _inst_1 : categories.small_category.{0} C, a b : C, f : @categories.category.Hom.{0 0} C _inst_1 (@M C _inst_1 a) (@M C _inst_1 b) ⊢ @eq.{1} (@categories.category.Hom.{0 0} C _inst_1 a b) (@categories.category.compose.{0 0} C _inst_1 a (@M C _inst_1 b) b f (@categories.category.identity.{0 0} C _inst_1 b)) f -/ example : (f ≫ 𝟙 b : a ⟶ b) = f := begin dsimp [M], simp end -- ok
Reid Barton (Jul 13 2018 at 20:59):
With the dsimp [M]
, the only change in the goal is that (@M C _inst_1 b)
is replaced by b
Mario Carneiro (Jul 13 2018 at 21:00):
is there any change if you dsimp
the type of f
instead of the goal?
Reid Barton (Jul 13 2018 at 21:01):
How would I do that?
Mario Carneiro (Jul 13 2018 at 21:01):
dsimp [M] at f
Reid Barton (Jul 13 2018 at 21:02):
Subsequent simp
is still stuck
Mario Carneiro (Jul 13 2018 at 21:02):
does rw
work?
Reid Barton (Jul 13 2018 at 21:03):
rw
doesn't work, but erw
does
Reid Barton (Jul 13 2018 at 21:03):
(Which I learned about from its usage in Scott's library.)
Mario Carneiro (Jul 13 2018 at 21:04):
erw
will work because it's basically just dsimp [M], rw
Reid Barton (Jul 13 2018 at 21:12):
Maybe your example works because of this canonize_instances
stuff?
Reid Barton (Jul 13 2018 at 21:14):
Or maybe not
Reid Barton (Jul 14 2018 at 14:44):
A related example that I don't understand.
set_option pp.all true variable (z : has_zero nat) example (x : nat) : x + @has_zero.zero nat z = x := by simp /- type mismatch at application (λ (a a_1 : nat) (e_1 : @eq.{1} nat a a_1) (a_2 a_3 : nat) (e_2 : @eq.{1} nat a_2 a_3), @congr.{1 1} nat Prop (@eq.{1} nat a) (@eq.{1} nat a_1) a_2 a_3 (@congr_arg.{1 1} nat (nat → Prop) a a_1 (@eq.{1} nat) e_1) e_2) (@has_add.add.{0} nat nat.has_add x (@has_zero.zero.{0} nat z)) x (@add_zero.{0} nat nat.add_monoid x) term @add_zero.{0} nat nat.add_monoid x has type @eq.{1} nat (@has_add.add.{0} nat (@add_semigroup.to_has_add.{0} nat (@add_monoid.to_add_semigroup.{0} nat nat.add_monoid)) x (@has_zero.zero.{0} nat (@add_monoid.to_has_zero.{0} nat nat.add_monoid))) x but is expected to have type @eq.{1} nat (@has_add.add.{0} nat nat.has_add x (@has_zero.zero.{0} nat z)) x -/
Reid Barton (Jul 14 2018 at 14:47):
Note that the simp
tactic actually succeeded, and used add_zero
. So somehow simp
didn't care that the has_zero
dictionary was the wrong one. But looking at trace.type_context.is_def_eq_detail
output and the type_context.cpp
code, I don't see how this is possible.
Chris Hughes (Aug 07 2018 at 13:38):
This problem came up for me today, helping someone who had a proof that was approved by the tactics
but not by the kernel, where there was a nat.pow
versus monoid.pow
issue somewhere.
Last updated: Dec 20 2023 at 11:08 UTC