Commit graph

6892 commits

Author SHA1 Message Date
Kyle Miller
70924be89c
feat: hovering over omission term shows reason for omission (#3751)
This avoids printing the entire docstring for `⋯` when hovering over it,
which is rather long, and instead it gives a brief reason for omission
and what option to set to pretty print the omitted term.
2024-03-27 15:10:20 +00:00
Scott Morrison
02c5700c63
feat: change apply_rfl tactic so that it does not operate on = (#3784)
Previously:

If the `rfl` macro was going to fail, it would:
1. expand to `eq_refl`, which is implemented by
`Lean.Elab.Tactic.evalRefl`, and call `Lean.MVarId.refl` which would:
* either try kernel defeq (if in `.default` or `.all` transparency mode)
  * otherwise try `IsDefEq`
  * then fail.
2. Next expand to the `apply_rfl` tactic, which is implemented by
`Lean.Elab.Tactic.Rfl.evalApplyRfl`, and call `Lean.MVarId.applyRefl`
which would look for lemmas labelled `@[refl]`, and unfortunately in
Mathlib find `Eq.refl`, so try applying that (resulting in another
`IsDefEq`)
3. Because of an accidental duplication, if `Lean.Elab.Tactic.Rfl` was
imported, it would *again* expand to `apply_rfl`.

Now:
1. Same behaviour in `eq_refl`.
2. The `@[refl]` attribute will reject `Eq.refl`, and `MVarId.applyRefl`
will fail when applied to equality goals.
3. The duplication has been removed.
2024-03-27 12:04:22 +00:00
Scott Morrison
94d6286e5a
chore: reorganising to reduce imports (#3790)
[Before](https://github.com/leanprover/lean4/files/14772220/oi.pdf) and
[after](https://github.com/leanprover/lean4/files/14772226/oi2.pdf).

This gets `ByteArray`, `String.Extra`, `ToString.Macro` and `RCases` out
of the imports of `omega`. I'd hoped to get `Array.Subarray` too, but
it's tangled up in the list literal syntax. Further progress could come
from make `split` use available `Decidable` instances, so we could pull
out `Classical` (and possibly some of `PropLemmas`).
2024-03-27 11:15:01 +00:00
Joachim Breitner
c857d08be6
fix: remove derive_functional_induction (#3788)
this follows up on #3776 and the subsequent stage0 update, now relying
on the reserved name for the induction principles.
2024-03-27 10:08:13 +00:00
Henrik Böving
2405fd605e
feat: trace non-easy whnf invocations (#3774) 2024-03-27 08:35:22 +00:00
Scott Morrison
b4caee80a3
chore: rw? uses MVarId.refl not MVarId.applyRfl (#3783)
I think this was in error in my original Mathlib implementation. We're
not interested in relations other than `=`, so there is no point uses
`MVarId.applyRfl`, which just looks up `@[refl]` tagged lemmas and tries
those.

In a separate PR, I will change `MVarId.applyRfl` so it has a flag to
control whether on `=` it should just hand-off to `MVarId.refl`, or
fail. Failure is appropriate in the version we call from the `rfl`
macro, to avoid doing a double `IsDefEq` check on every `rfl`!
2024-03-27 03:02:30 +00:00
Joe Hendrix
b17c47d852
fix: lemma selection improvements to to rw? and lazy discriminator tree (#3769)
This makes several changes to rw? and lazy discrimination trees based on
test failures in rewrite search.

Changes include:
1. Reverting to Mathlib function for candidate lemma priority in rw?
2. Introducing additional filters for auto-generated named in lazy
discriminator tree.
3. Refactoring lazy discriminator values to clarify what is stored.
4. Including star keys in calculation of match closeness in
prioritization.
5. Using more fields in current core context when initializing lazy
discriminator tree and avoiding max heartbeat issues.

---------

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
2024-03-26 23:57:08 +00:00
Joachim Breitner
ab318dda2d
feat: use reserved name infrastructure for functional induction (#3776)
no need to enter `derive_functional_induction` anymore.

(Will remove the support for `derive_functional_induction` after the
next stage0 update, since we are already using it in Init.)
2024-03-26 22:25:10 +00:00
Joachim Breitner
301dd7ba16
feat: failing macros to show error from first registered rule (#3771)
fixes #3770

Also start `rfl` with a `fail` message that is hopefully more helpful
than what we get now (see updated test output). This would be a cheaper
way to address #3302 without changing the implementation of rfl (as
tried in #3714).
2024-03-26 22:24:45 +00:00
Joachim Breitner
466ef74ccc
feat: functional induction for structural recursion (#3738)
This extends `derive_functional_induction` to work with structural
recursion as well.

It produces the less general, more concrete induction rule where the
induction hypothesis is
specialized for every argument of the recursive call, not just the the
one that the function
is recursing on.

Care is taken so that the induction principle and it's motive take the
arguments in the same
order as the original function.

While I was it, also makes sure that the order of the cases in the
induction principle matches
the order of recursive calls in the function better.

---------

Co-authored-by: David Thrane Christiansen <david@davidchristiansen.dk>
Co-authored-by: Leonardo de Moura <leomoura@amazon.com>
2024-03-26 13:36:24 +00:00
Leonardo de Moura
22b5c957e9
chore: rename automatically generated "unfold" theorems (#3767)
Given a definition `foo`, they were previously called `foo._unfold`
until 4.7.0. We tried to rename them to `foo.def`, but it created too
many issues in the Mathlib repo. We decided to rename it again to
`foo.eq_def`. The new name is also consistent with the `eq_<idx>`
theorems generated for different "cases". That is, `foo.eq_def` is the
equality theorem for the whole definition, and `foo.eq_<idx>` is the
equality theorem for case `<idx>`.

cc @semorrison
2024-03-25 21:41:26 +00:00
Leonardo de Moura
a0dac9f546
feat: ignore explicit proofs in canonicalizer (#3766) 2024-03-25 20:52:42 +00:00
Joachim Breitner
e0c6c5d226
fix: functional induction: preseve order of cases better (#3762)
by passing an explicit array of metavariable around, instead of relying
on `getMVarsNoDelayed`, which may return them in unexpected order.
2024-03-25 11:59:29 +00:00
Jon Eugster
3dd811f9ad
chore: remove FileMap.lines and add FileMap.getLine (#3237)
`FileMap.lines` is an array that seems to be manually managed to have
the form `#[1, 2, ..., n-1, n-1]` with same length as
`FileMap.positions`. Remove this structure field in favour of
calculating the line number as `min(x+1, positions.size-1)` when needed.

Follow-up on #3221
2024-03-25 10:33:04 +00:00
Scott Morrison
1d245bcb82
chore: revert ToJson/FromJson Sum (#3759) (#3760)
Sorry, this was ill-considered, it doesn't round trip faithfully.
2024-03-25 09:09:44 +00:00
Scott Morrison
a943a79bd3
chore: ToJson/FromJson Sum (#3759) 2024-03-25 07:43:40 +00:00
Joachim Breitner
80d2455b64
fix: prune universe params in functional induction (#3754)
fixes #3752
2024-03-24 10:15:50 +00:00
Kyle Miller
655ec964f5
feat: flatten parent projections when pretty printing structure instance notation (#3749)
Given
```lean
structure A where
  x : Nat

structure B extends A where
  y : Nat
```
rather than pretty printing `{ x := 1, y := 2 : B }` as `{ toA := { x :=
1 }, y := 2 }`, it now pretty prints as `{ x := 1, y := 2 }`.

The option `pp.structureInstances.flatten` controls whether to flatten
structure instances like this.
2024-03-23 09:20:52 +00:00
Kyle Miller
925a6befd4
fix: do not pretty print theorems with generalized field notation (#3750)
For example, pretty print as `Nat.add_comm m n` rather than as
`m.add_comm n`.
2024-03-23 09:20:48 +00:00
Joe Hendrix
6c8976abbe
feat: upstream rw? tactic (#3719)
This updates the rw? tactic from Mathlib to use lazy discriminator trees
and upstreams it.

---------

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
2024-03-23 05:01:35 +00:00
Kyle Miller
d39b0415f0
feat: enable pp.fieldNotation.generalized globally (#3744)
Sets the default value to `pp.fieldNotation.generalized` to `true`.
Updates tests, and fixes some minor flaws in the implementation of the
generalized field notation pretty printer.

Now generalized field notation won't be used for any function that has a
`motive` argument. This is intended to prevent recursors from pretty
printing using it as (1) recursors are more like control flow structures
than actual functions and (2) generalized field notation tends to cause
elaboration problems for recursors.

Note: be sure functions that have an `@[app_unexpander]` use
`@[pp_nodot]` if applicable. For example, `List.toArray` needs
`@[pp_nodot]` to ensure the unexpander prints it using `#[...]`
notation.
2024-03-23 02:38:09 +00:00
Marc Huisinga
3f8f2b09af
chore: more generic import out of date diagnostic (#3739)
The concrete dependency that is stale isn't really actionable
information for users (ideally we'd like something like "amount of
dependencies that will be rebuilt when you restart file"). This also
makes the diagnostic an "information" diagnostic so that non-infoview
users can still see it.

Since we are moving away from using notifications for stale dependency
information, we don't need to provide an ID anymore, either.
2024-03-22 13:13:20 +00:00
Kyle Miller
1f4dea8582
feat: add pp.fieldNotation.generalized for generalized field notation, add @[pp_nodot] attribute (#3737)
Refactors app delaborator, merging in the projection delaborator, to
support pretty printing with generalized field notation.

Renames option `pp.structureProjections` to `pp.fieldNotation` and adds
sub-option `pp.fieldNotation.generalized` to enable/disable generalized
field notation. Adds `@[pp_nodot]` attribute to permanently disable
using field notation for a given declaration.

For now, the default value of `pp.fieldNotation.generalized` is false
since we need a stage0 update to add `@[pp_nodot]` to some core
definitions (such as `List.toArray`) before updating the tests.

[Zulip
discussion](https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/.60pp.2EgeneralizedFieldNotation.60/near/425856054)
2024-03-22 08:55:02 +00:00
Scott Morrison
d5a1dce0ae
chore: omega notices that 0 ≤ (x : Int) % (y : Int) (#3736) 2024-03-22 02:49:24 +00:00
Kyle Miller
980e73c368
feat: make in Infoview hovers show docstring (#3663)
The docstring for `⋯` gives information about why the omission term
might appear in an expression, and it helps with discoverability to give
documentation right in the hover.

This was mentioned by Patrick Massot [on
Zulip](https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Deep.20terms.20ellipses/near/426133597)
as being an issue.
2024-03-22 00:00:23 +00:00
David Thrane Christiansen
966fa800f8
chore: remove the coercion from String to Name (#3589)
This coercion caused difficult-to-diagnose bugs sometimes. Because there
are some situations where converting a string to a name should be done
by parsing the string, and others where it should not, an explicit
choice seems better here.

---------

Co-authored-by: Mac Malone <tydeu@hatpress.net>
2024-03-21 23:46:03 +00:00
Kyle Miller
ff7a0db099
feat: add pp_using_anonymous_constructor attribute (#3640)
Implements a Lean 3 pretty printer feature. Structures with the
`@[pp_using_anonymous_constructor]` attribute pretty using anonymous
constructor notation (`⟨x, y, z⟩`) rather than structure instance
notation (`{a := x, b := y, c := z}`).

[Zulip
discussion](https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/.60pp_using_anonymous_constructor.60/near/425705445)
2024-03-21 23:01:10 +00:00
Sebastian Ullrich
085d01942d
fix: restore default of stderrAsMessages (#3733)
Puts trace.compiler back in the info view. Apparently an unintended
change in #3014.
2024-03-21 17:43:29 +00:00
Marc Huisinga
31767aa835
fix: use sticky diags in getInteractiveDiagnostics (#3730)
I forgot to use the sticky diagnostics in `getInteractiveDiagnostics` in
#3247, leading to them not consistently showing up in the "Messages"
panel of the InfoView.
2024-03-21 14:34:22 +00:00
Marc Huisinga
902668dc38
fix: use correct positions for header errors (#3728)
This lead to incorrect diagnostic spans in the editor and resulted in
header errors that did not show up under "Messages" everywhere in the
file because the `fullRange?` property was missing.

Also changes the "Import out of date" warning diagnostic severity to
"Hint" so that it doesn't show up in the "Problems" view.
2024-03-21 14:19:45 +00:00
Mario Carneiro
49f66dc485
perf: rewrite UnusedVariables lint (#3186)
This is a rewrite of the `UnusedVariables` lint to inline and simplify
many of the dependent functions to try to improve the performance of
this lint, which quite often shows up in perf reports.

* The mvar assignment scanning is one of the most expensive parts of the
process, so we do two things to improve this:
  * Lazily perform the scan only if we need it
* Use an object-pointer hashmap to ensure that we don't have quadratic
behavior when there are many mvar assignments with slight differences.
* The dependency on `Lean.Server` is removed, meaning we don't need to
do the LSP conversion stuff anymore. The main logic of reference finding
is inlined.
* We take `fvarAliases` into account, and union together fvars which are
aliases of a base fvar. (It would be great if we had `UnionFind` here.)

More docs will be added once we confirm an actual perf improvement.

---------

Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2024-03-21 12:28:57 +00:00
Arthur Adjedj
bf8b66c6a5
fix: ignore unused alternatives in Ord derive handler (#3725)
Closes #3706

This derive handler's implementation is very similar to `BEq`'s, which
already ignores unused alternative so as to work correctly on indexed
inductive types. This PR simply implements the same solution as the one
present in
[`BEq.lean`](2c15cdda04/src/Lean/Elab/Deriving/BEq.lean (L94)).

After some tests, it doesn't seem like any other derive handler present
in Core suffers from the same issue (though some handlers don't work on
indexed inductives for other reasons).
2024-03-21 10:29:22 +00:00
Sebastian Ullrich
4d4e467392
feat: MonadAlwaysExcept for MonadCacheT (#3726) 2024-03-21 09:01:13 +00:00
Marc Huisinga
40b5282ec2
fix: use correct module name in references (#3722)
#3656 used the wrong name in `RefIdent`, which lead to "Find References"
being broken. I really need to set up some tests for this functionality
...
2024-03-20 20:28:01 +00:00
Scott Morrison
846300038f
fix: make attribute based rfl tactic builtin (#3708) 2024-03-18 11:39:59 +00:00
Marc Huisinga
3c82f9ae12
feat: diagnostics for stale dependencies (#3247)
Sends a diagnostic informing the user to run Restart File when a file
dependency is saved.

Based on #3014 because this feature was easier to implement with the new
architecture.

ToDo:
- [x] Adjust vscode-lean4 to display a notification when this diagnostic
appears in a non-annoying way
(https://github.com/leanprover/vscode-lean4/pull/393)
- [x] Use a file watcher to identify changes to files not tracked by VS
Code
- [x] Rebase onto master when #3014 is merged
2024-03-18 10:38:38 +00:00
Scott Morrison
66541b00a6
feat: upstream Std's rfl tactic (#3671)
This allows tagging lemmas with `@[refl]`, that will then by used by
`rfl`.

This is preparatory to upstreaming Mathlib's `convert` tactic.
2024-03-17 07:06:13 +00:00
Scott Morrison
f1f9b57df9
feat: upstream apply helper tactics from Mathlib (#3670)
These are used in Mathlib's `congr!` and `convert` tactics, which will
be upstreamed soon.

---------

Co-authored-by: Kyle Miller <kmill31415@gmail.com>
2024-03-17 06:47:56 +00:00
Scott Morrison
88b1751b54
chore: fix namespaces in recently upstreamed tactics (#3672) 2024-03-17 06:41:40 +00:00
Timo Carlin-Burns
8e96d7ba1d
refactor: clean up public API around Array.eraseIdx (#3676)
- Removes the public definitions `Array.eraseIdxAux` and
`Array.eraseIdxSzAux` which were implementation details.
- Motivation: `Array.eraseIdxAux` and `Array.eraseIdxSzAux` were clearly
not intended to remain public, but simply making them private would make
it inconvenient to unfold them when writing proofs in Std.
- Adds documentation comments to the public `Array.eraseIdx`-related
definitions which remain.
- Removes `Array.eraseIdx'` which was just `Array.feraseIdx` wrapped in
a subtype and adds `Array.size_feraseIdx` to prove the subtype property
as a standalone theorem.

Co-Authored-By: Daniel Windham <daniel@atlascomputing.org>
2024-03-17 06:25:10 +00:00
Joachim Breitner
0b01ceb3bb
fix: substVars in functional inductions removed valuable information (#3695)
using the `substVars` tactic on the goal can remove too much
information, as it does not take into account that the `motive` may
depend on the fixed parameters.

This is fixed by etracting `substVar` from `subst` which expects the
`x`, not the `h : x = rhs`, and then using this tactic on the local
declarations _after_ the `motive` exclusively.
2024-03-16 14:55:31 +00:00
Joachim Breitner
4c57da4b0f
feat: infer termination arguments like xs.size - i (#3666)
a common pattern for recursive functions is
```
def countUp (n i acc : Nat) : Nat :=
  if i < n then
    countUp n (i+1) (acc + i)
  else
    acc
```
where we increase a value `i` until it hits an upper bound. This is
particularly common with array processing functions:
```
$ git grep 'termination_by.*size.*-' src/|wc -l
26
```

GuessLex now recognizes this pattern. The general approach is:

For every recursive call, check if the context contains hypotheses of
the form `e₁ < e₂` (or similar comparisions), and then consider `e₂ -
e₁` as a termination argument.

Currently, this only fires when `e₁` and `e₂` only depend on the
functions parameters, but not local let-bindings or variables bound in
local pattern matches.

Duplicates are removed.

In the table showing the termination argument failures, long termination
arguments are now given a number and abbreviated as e.g. `#4` in the
table headers.

More examples in the test file, here as some highlights:
```
def distinct (xs : Array Nat) : Bool :=
  let rec loop (i j : Nat) : Bool :=
    if _ : i < xs.size then
      if _ : j < i then
        if xs[j] = xs[i] then
          false
        else
          loop i (j+1)
      else
        loop (i+1) 0
    else
      true
  loop 0 0
```
infers
```
termination_by (Array.size xs - i, i - j)
```
and the weird functions where `i` goes up or down
```
def weird (xs : Array Nat) (i : Nat) : Bool :=
  if _ : i < xs.size then
    if _ : 0 < i then
      if xs[i] = 42 then
        weird xs.pop (i - 1)
      else
        weird xs (i+1)
    else
      weird xs (i+1)
  else
    true
decreasing_by all_goals simp_wf; omega
```
infers
```
termination_by (Array.size xs - i, i)
```
but unfortunately needs `decreasing_by` pending the “big
decreasing_tactic refactor” that
I expect we’ll want to do at some point.
2024-03-16 12:27:35 +00:00
Joachim Breitner
f0ff01ae28
refactor: pass Measures around as Expr in GuessLex (#3665)
this refactor prepares GuessLex to be able to infer more complex
termination arguments.

As a side-effect it fixes an (obscure) bug where `sizeOf` would be
applied to a term of the wrong type and thus a wrong `SizeOf` instance
could be inferred.
2024-03-16 10:25:55 +00:00
Joe Hendrix
0ec8862103
chore: migrate find functionality into LazyDiscrTree (#3685)
This migrates some lookup functionality from library_search to a more
generic version in LazyDiscrTree.

It is a step towards `rw?` in core.
2024-03-16 01:01:53 +00:00
Marc Huisinga
e47d8ca5cd
fix: periodically refresh semantic tokens (#3691)
Based on #3619 that was reverted because of nondeterministic test
failures. This PR should resolve those.
2024-03-15 11:58:50 +00:00
Marc Huisinga
14654d802d
chore: revert periodically refresh semantic tokens (#3619) (#3689)
This reverts commit 4e3a8468c3 for PR
#3619. It looks like the CI in that commit didn't inform me that a test
was broken by the PR, so I managed to commit it despite the broken test.
2024-03-15 09:17:53 +00:00
Leonardo de Moura
173b956961
feat: reserved names (#3675)
- Add support for reserved declaration names. We use them for theorems
generated on demand.
- Equation theorems are not private declarations anymore.
- Generate equation theorems on demand when resolving symbols.
- Prevent users from creating declarations using reserved names. Users
can bypass it using meta-programming.

See next test for examples.
2024-03-15 00:33:22 +00:00
Joachim Breitner
022b2e4d96
refactor: termination arguments as Expr, not Syntax (#3658)
Before, the termination argument as inferred by `GuessLex` was passed
further
on as `Syntax`, to be elaborated later in `WF.Rel`.

This didn’t feel quite right anymore. In particular if we want to teach
`GuessLex` about guessing more complex termination arguments like
`xs.size -
i`, using `Expr` here is more natural.

So this introduces `TerminationArgument` based on an `Expr` to be used
here.

A side-effect of how the termination arguments are elaborated is that
the unused
variables linter will now look at `termination_by` variables, and that
parameters
past the colon are not even invisibly in scope, so `‹_›` will not find
them
See https://github.com/leanprover-community/mathlib4/pull/11370/files
for examples
of fixing these changes.
2024-03-14 23:51:53 +00:00
Marc Huisinga
4e3a8468c3
fix: periodically refresh semantic tokens (#3619)
This PR fixes an issue where the file worker would not provide the
client with semantic tokens until the file had been elaborated
completely. The file worker now also tells the client to refresh its
semantic tokens after running "Restart File". This PR is based on #3271.
2024-03-14 17:10:04 +00:00
Marc Huisinga
78a72741c6
fix: jump to correct definition when names overlap (#3656)
Fixes #1170.

This PR adds the module name to `RefIdent` in order to distinguish
conflicting names from different files. This also fixes related issues
in find-references or the call hierarchy feature.
It also adds some docstrings and stylistically refactors a bunch of
code.
2024-03-14 16:21:19 +00:00