Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Identifiers in auto-tactics don't respect lexical scope #4624

Open
3 tasks done
david-christiansen opened this issue Jul 2, 2024 · 4 comments
Open
3 tasks done

Identifiers in auto-tactics don't respect lexical scope #4624

david-christiansen opened this issue Jul 2, 2024 · 4 comments
Labels
bug Something isn't working P-medium We may work on this issue if we find the time

Comments

@david-christiansen
Copy link
Contributor

Prerequisites

Please put an X between the brackets as you perform the following steps:

Description

PR #3328 began allowing identifiers in auto-tactics, a much-desired feature. But these identifiers don't respect lexical scope/hygiene.

Steps to Reproduce

  1. Create a file with the definition from the test case in feat: support idents in auto tactics #3328:
    def f3 (x y : Nat) (h : x = y := by exact Eq.refl x) : Nat :=
    x + x
    
  2. Run the test with a local name other than x:
    #check fun someNameOtherThanX => f3 someNameOtherThanX someNameOtherThanX
    

Expected behavior: I would expect the test to pass, because x is bound by the function's parameter named x. Lean's tactic language usually respects lexical scope.

Actual behavior: Elaboration fails with the message unknown identifier 'x'

Versions

This is present in the 4.9 release, as well as 4.11.0-nightly-2024-07-01 on live.lean-lang.org.

Impact

Add 👍 to issues you consider important. If others are impacted by this issue, please ask them to add 👍 to it.

@david-christiansen david-christiansen added the bug Something isn't working label Jul 2, 2024
@digama0
Copy link
Collaborator

digama0 commented Jul 2, 2024

This seems unlikely to work, especially if you consider that you can also call f3 (1 + 1) 2, at which point it's not clear what name x is supposed to be. The "correct" behavior in this particular case would be to treat x in the auto tactic not as a name but rather a reference to the previous expression and subject to substitution like regular expressions, but I don't think tactics allow that. Perhaps you can hack it in by adding let x := 1 + 1 into the local context in which to run the tactic, but that can have other side effects and it's not obviously the right behavior.

@david-christiansen
Copy link
Contributor Author

It's definitely tricky, and I agree that there isn't an obviously right semantics. But we do need to explain to people how to use this at some point.

What is the specification for the current behavior? Is it that names in the script are resolved in the global context immediately prior to the definition, or is it that they're resolved unhygienically at the use site? The former seems like something we can document our way out of, but the test here seems to indicate the latter, which strikes me as unpredictable.

@nomeata
Copy link
Contributor

nomeata commented Jul 3, 2024

Putting the assignment x := 1+1 into the local context before elaborating the tactic seems to be most correct behavior to me, if it can be made to work. The other semantics discussed here seem rather weird.

@leanprover-bot leanprover-bot added the P-medium We may work on this issue if we find the time label Aug 2, 2024
@mhuisi
Copy link
Contributor

mhuisi commented Sep 13, 2024

Another issue related to this feature is that these identifiers now show up in the .ilean files at the call-sites of those functions. E.g. IO.waitAny has a parameter (h : tasks.length > 0 := by exact Nat.zero_lt_succ _) and Nat.zero_lt_succ now shows up in the .ilean files of all call-sites of IO.waitAny, effectively breaking language server support for that function (e.g.: when hovering over the identifier, it displays an incorrect span, go to definition doesn't immediately take you to IO.waitAny but requires you to choose between Nat.zero_lt_succ and IO.waitAny, "find references" shows the references of both identifiers, etc.).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working P-medium We may work on this issue if we find the time
Projects
None yet
Development

No branches or pull requests

5 participants