Zulip Chat Archive
Stream: general
Topic: namespace affects behaviour of `apply_list_expr`
Heather Macbeth (Oct 05 2022 at 22:43):
In the following example, opening the namespace nat
affects the ability of docs#tactic.apply_list_expr to function. Can anyone suggest a fix?
import tactic.core
import data.int.basic
open tactic
@[user_attribute]
meta def foo : user_attribute :=
{ name := `foo,
descr := "" }
attribute [foo] pow_lt_pow_of_lt_left
meta def minitac : tactic unit := do
foo_rules ← resolve_attribute_expr_list `foo,
trace foo_rules.length,
apply_list_expr {md := reducible} foo_rules
example {x y : ℤ} (n : ℕ) :
x ^ n < y ^ n :=
begin
minitac, -- desired behaviour
end
open nat
example {x y : ℤ} (n : ℕ) :
x ^ n < y ^ n :=
begin
minitac, -- "no matching rule"
end
Heather Macbeth (Oct 05 2022 at 22:43):
I'm assuming the problem is in docs#tactic.apply_list_expr rather than docs#tactic.resolve_attribute_expr_list, because of the output of the trace
.
Alex J. Best (Oct 05 2022 at 23:02):
Actually I think the problem is the calls to docs#tactic.resolve_name in docs#tactic.resolve_attribute_expr_list, you get a name clash between docs#pow_lt_pow_of_lt_left and docs#nat.pow_lt_pow_of_lt_left.
The following version has the desired behaviour:
import tactic.core
import data.int.basic
open tactic
.
@[user_attribute]
meta def foo : user_attribute :=
{ name := `foo,
descr := "" }
attribute [foo] pow_lt_pow_of_lt_left
meta def resolve_attribute_expr_list' (attr_name : name) : tactic (list (tactic expr)) := do
l ← attribute.get_instances attr_name,
list.map i_to_expr_for_apply <$> list.reverse <$> l.mmap (λ n, do c ← (mk_const n), return (pexpr.of_expr c))
meta def tactic.interactive.minitac : tactic unit := do
foo_rules ← resolve_attribute_expr_list' `foo,
trace foo_rules.length,
apply_list_expr {md := reducible} foo_rules
example {x y : ℤ} (n : ℕ) :
x ^ n < y ^ n :=
begin
minitac, -- desired behaviour
end
open nat
example {x y : ℤ} (n : ℕ) :
x ^ n < y ^ n :=
begin
minitac,
end
Heather Macbeth (Oct 05 2022 at 23:06):
Huh! So should
list.map i_to_expr_for_apply <$> list.reverse <$> l.mmap resolve_name
be replaced by
list.map i_to_expr_for_apply <$> list.reverse <$> l.mmap (λ n, do c ← (mk_const n), return (pexpr.of_expr c))
in tactic#resolve_attribute_expr_list ?
Alex J. Best (Oct 05 2022 at 23:07):
Looks like resolve_attribute_expr_list is only used in one place, which is apply_rules, which seems more general, so I wouldn't say so without looking a lot deeper
Alex J. Best (Oct 05 2022 at 23:08):
meta def resolve_attribute_expr_list' (attr_name : name) : tactic (list (tactic expr)) := do
l ← attribute.get_instances attr_name,
l.reverse.mmap (λ n, return (mk_const n))
is probably a shorter way
Heather Macbeth (Oct 05 2022 at 23:08):
Indeed, I am using it for an apply_rules
-like function.
Heather Macbeth (Oct 05 2022 at 23:09):
Well, if I make the change in a branch and it doesn't break anything in mathlib, is that enough evidence to PR it?
Alex J. Best (Oct 05 2022 at 23:13):
Could be, but I also don't really see an issue with having similar but slightly different tactic internals around if they have slightly different purposes. Of course if you can reproduce the original issue with apply rules then thats a bug that should be fixed
We should also ask @Rob Lewis if he has a particular reason to write it this way, the comments in the source of apply rules make it seem like the setup was carefully chosen, though out of context it does seem a bit odd (e.g. returning a list of tactic exprs)
Alex J. Best (Oct 05 2022 at 23:14):
Actually the bug does seem to be there for apply rules, or at least the error message is unhelpful
open nat
example {x y : ℤ} (n : ℕ) :
x ^ n < y ^ n :=
begin
apply_rules [pow_lt_pow_of_lt_left],
end
Heather Macbeth (Oct 05 2022 at 23:15):
Indeed, it's exactly the same behaviour for apply_rules.
import tactic.core
import data.int.basic
open tactic
@[user_attribute]
meta def foo : user_attribute :=
{ name := `foo,
descr := "" }
attribute [foo] pow_lt_pow_of_lt_left
example {x y : ℤ} (n : ℕ) :
x ^ n < y ^ n :=
begin
apply_rules with foo, -- desired behaviour
end
open nat
example {x y : ℤ} (n : ℕ) :
x ^ n < y ^ n :=
begin
apply_rules with foo, -- "no matching rule"
end
Alex J. Best (Oct 05 2022 at 23:15):
So that should be fixed, but I'm not sure the fix is the same as in your case, where you know precisely which declaration you want to apply, as its the one given to you by the attribute, so there is never a need to resolve the name
Heather Macbeth (Oct 05 2022 at 23:16):
Maybe, at least, this should be the behaviour for apply_rules when it is used with an attribute (as here).
Alex J. Best (Oct 05 2022 at 23:16):
For apply rules what should probably happen is it tells the user, hey you gave me an ambiguous name, please specify this more, rather than "no matching rule"
Alex J. Best (Oct 05 2022 at 23:18):
Oh I see, yeah thats more similar to your tactic, so maybe there should be different internals
Heather Macbeth (Oct 05 2022 at 23:18):
Do you mean, different internals for apply_rules
with an attribute vs with a user-specified lemma?
Alex J. Best (Oct 05 2022 at 23:21):
Yeah I think that you make the most sense, after all one has the possibility of ambiguity, that we want to ask the user to fix, but the other should just work
Heather Macbeth (Oct 05 2022 at 23:21):
Thanks! It's slightly above my pay grade, unfortunately. I'll open an issue.
Heather Macbeth (Oct 05 2022 at 23:22):
And also ping @Scott Morrison who I think is doing the mathlib4 port.
Alex J. Best (Oct 05 2022 at 23:22):
Actually looking at it more it seems your original suggestion is fine, resolve_attribute_expr_list
is only used for the ones supplied via attribute anyway, so making the change there should be ok
Heather Macbeth (Oct 05 2022 at 23:23):
Oh, ok! Then I think I can do that myself.
Alex J. Best (Oct 05 2022 at 23:24):
Sorry for the confusion! Took me a minute to wrap my head around the way it is set up
Heather Macbeth (Oct 05 2022 at 23:24):
(Or you can if you prefer, it's your line of code)
Alex J. Best (Oct 05 2022 at 23:26):
Please go ahead (I'm about to log off for the night anyways)! I think the
list.map i_to_expr_for_apply <$> list.reverse <$> l.mmap (λ n, do c ← (mk_const n), return (pexpr.of_expr c))
version is maybe better after looking at this more
Heather Macbeth (Oct 05 2022 at 23:30):
Eric Wieser (Oct 05 2022 at 23:48):
Why does apply_rules take a list of names and not pexprs?
Eric Wieser (Oct 05 2022 at 23:49):
Then the name resolution would just be automatic like it is for rw
Notification Bot (Feb 06 2023 at 10:56):
Chris Hughes has marked this topic as resolved.
Notification Bot (Feb 06 2023 at 13:47):
Chris Hughes has marked this topic as unresolved.
Last updated: Dec 20 2023 at 11:08 UTC