Commit graph

7647 commits

Author SHA1 Message Date
Leonardo de Moura
a2aadee28f feat: simproc declaration vs simproc attribute
Allow `simproc`s to be declared without setting the `[simproc]`
attribute. A `simproc` declaration is function + pattern.

Motivation: allow them to be provided as arguments to `simp` **and** `simp only`.

TODO: track their use in `simp`.
TODO: builtin simprocs
2024-01-09 12:57:15 +01:00
Leonardo de Moura
923216f9a9 feat: add simprocs
TODO:
- `builtin_simproc` attribute
- more tests
2024-01-09 12:57:15 +01:00
Leonardo de Moura
22c8154811 feat: add pre simp lemmas for if-then-else terms
See new test for example that takes exponential time without new simp
theorems.
TODO: replace auxiliary theorems with simprocs as soon as we implement them.
2024-01-09 12:57:15 +01:00
Leonardo de Moura
05e9983e25 feat: better support for match-application in the simplifier
The new test exposes a performance problem found in software
verification applications.
2024-01-09 12:57:15 +01:00
Leonardo de Moura
b37fdea5bf feat: add reduceStep, and try pre simp steps again if term was reduced 2024-01-09 12:57:15 +01:00
Arthur Adjedj
b7c3ff6e6d
fix: manage all declarations in a given derive (#3058)
Closes #3057
2024-01-09 07:42:06 +00:00
Joachim Breitner
684f32fabe
feat: let get_elem_tactic_trivial handle [a]'h.2 (#3132)
The pattern
```
    for h : i in [:xs.size] do
      let x := xs[i]'h.2
```
is occassionally useful to iterate over an array with the index in
hand. This PR extends the `get_elem_tactic_trivial` so that one can
simply write
```
    for h : i in [:xs.size] do
      let x := xs[i]
```

fixes #3032.
2024-01-08 16:23:09 +00:00
Scott Morrison
504b6dc93f
feat: do not instantiate metavariables in kabstract/rw for disallowed occurrences (#2539)
Fixes #2538.
2024-01-03 00:01:40 +00:00
Kyle Miller
cc1dcf8043
feat: delaborate have inside do blocks (#3116) 2024-01-02 09:36:39 +00:00
Joachim Breitner
1145976ff9
test: test “motive is not type correct” (#3122) 2023-12-28 15:28:17 +00:00
Mario Carneiro
d1a15dea03
fix: hover info for cases h : ... (#3084)
This makes hover info, go to definition, etc work for the `h` in `cases
h : e`. The implementation is similar to that used for the `generalize h
: e = x` tactic.
2023-12-21 22:39:23 +00:00
Scott Morrison
bcc49d1c5f
chore: update tests for #2966 to use test_extern (#3092)
#2966 was the `@[extern]` bug that prompted development of the
`test_extern` command, but then we merged the fix to #2966 without
updating the tests to use `test_extern`.
2023-12-21 22:22:47 +00:00
Sebastian Ullrich
bddb2152e5
chore: default compiler.enableNew to false until development restarts (#3034) 2023-12-21 07:48:25 +00:00
Wojciech Nawrocki
8d04ac171d
feat: bundle of widget improvements (#2964)
Implements RFC #2963.

Leftover tasks:
- [x] Provide companion PR to vscode-lean4 (leanprover/vscode-lean4#376)
- [x] Companion PR to std4 (leanprover/std4#467)
- [x] Companion PR to ProofWidgets4
(leanprover-community/ProofWidgets4#36)
- [X] Companion commit to mathlib4
(0f4660f655)
- [ ] ~~Update the manual chapter~~ (will do in a follow-up)
2023-12-21 06:24:33 +00:00
Kyle Miller
ae6fe098cb
feat: Rust-style raw string literals (#2929)
For example, `r"\n"` and `r#"The word "this" is in quotes."#`.

Implements #1422
2023-12-20 16:53:08 +00:00
Kyle Miller
67bfa19ce0
feat: add quot_precheck for expression tree elaborators (binop%, etc.) (#3078)
There were no `quot_precheck` instances registered for the expression
tree elaborators, which prevented them from being usable in a `notation`
expansion without turning off the quotation prechecker.

Users can evaluate whether `set_option quotPrecheck false` is still
necessary for their `notation` definitions.
2023-12-18 16:52:49 +00:00
Kyle Miller
a2226a43ac
feat: encode let_fun using a letFun function (#2973)
Switches from encoding `let_fun` using an annotated `(fun x : t => b) v`
expression to a function application `letFun v (fun x : t => b)`.

---------

Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2023-12-18 09:01:42 +00:00
Scott Morrison
8475ec7e36
fix: reference implementation ByteArray.copySlice (#2967)
Fixes reference implementation of `ByteArray.copySlice`, as reported
https://github.com/leanprover/lean4/issues/2966.

Adds tests.

---------

Co-authored-by: Joachim Breitner <mail@joachim-breitner.de>
2023-12-16 20:26:16 +00:00
Scott Morrison
d4dca3baac
feat: test_extern command (#2970)
This adds a `test_extern` command.

Usage:
```
import Lean.Util.TestExtern

test_extern Nat.add 17 37
```

This:
* Checks that the head symbol has an `@[extern]` attribute.
* Writes down `t == t'`, where `t` is the term provided, and `t'` is the
reference implementation (specifically, `t` with the head symbol
unfolded).
* Tries to reduce this to `true`, and complains if this fails.

Note that the type of the term must have a `BEq` instance for this to
work: there's a self-explanatory error message if it isn't available.
2023-12-12 23:33:05 +00:00
Jannis Limperg
e2f957109f
fix: omit fvars from simp_all? theorem list (#2969)
Removes local hypotheses from the simp theorem list generated by
`simp_all?`.

Fixes: #2953

---

Supersedes PR #1862
2023-12-12 00:45:07 +00:00
Scott Morrison
20dd63aabf
chore: fix superfluous lemmas in simp.trace (#2923)
Fixes an issue reported on Zulip; see the test case.

* Modifies the `MonadBacktrack` instance for `SimpM` to also backtrack
the `UsedSimps` field.
* When calling the discharger, `saveState`, and then `restoreState` if
something goes wrong.

I'm not certain that it makes sense to restore the `MetaM` state if
discharging fails. I can easily change this to more conservatively just
backtrack the `UsedSimps` after failed discharging.
2023-12-11 23:51:31 +00:00
Joachim Breitner
5cd90f5826
feat: drop support for termination_by' (#3033)
until around 7fe6881 the way to define well-founded recursions was to
specify a `WellFoundedRelation` on the argument explicitly. This was
rather low-level, for example one had to predict the packing of multiple
arguments into `PProd`s, the packing of mutual functions into `PSum`s,
and the cliques that were calculated.

Then the current `termination_by` syntax was introduced, where you
specify the termination argument at a higher level (one clause per
functions, unpacked arguments), and the `WellFoundedRelation` is found
using type class resolution.

The old syntax was kept around as `termination_by'`. This is not used
anywhere in the lean, std, mathlib or the theorem-proving-in-lean
repositories,
and three occurrences I found in the wild can do without

In particular, it should be possible to express anything that the old
syntax
supported also with the new one, possibly requiring a helper type with a
suitable instance, or the following generic wrapper that now lives in
std
```
def wrap {α : Sort u} {r : α → α → Prop} (h : WellFounded r) (x : α) : {x : α // Acc r x}
```

Since the old syntax is unused, has an unhelpful name and relies on
internals, this removes the support. Now is a good time before the
refactoring that's planned in #2921.

The test suite was updated without particular surprises.

The parametric `terminationHint` parser is gone, which means we can
match on syntax more easily now, in `expandDecreasingBy?`.
2023-12-11 17:33:17 +00:00
Mario Carneiro
178ab8ef2e
fix: Option.getD eagerly evaluates dflt (#3043)
Reported [on
Zulip](https://leanprover.zulipchat.com/#narrow/stream/348111-std4/topic/Panics.20in.20Std.2EHashMap.2Efind!/near/406872395).
The `dflt` argument of `Option.getD` is not evaluated lazily, as the
documentation says, because even after `macro_inline` the expression
```lean
match opt, dflt with
| some x, _ => x
| none, e => e
```
still has the semantics of evaluating `dflt` when `opt` is `some x`.
2023-12-11 10:07:30 +00:00
Joachim Breitner
1b2bbe717d
chore: remove obsolete comment in test (#3044) 2023-12-09 13:20:58 +00:00
Joachim Breitner
f2a92f3331
fix: GuessLex: deduplicate recursive calls (#3004)
The elaborator is prone to duplicate terms, including recursive calls,
even if the user only wrote a single one. This duplication is wasteful
if we run the tactics on duplicated calls, and confusing in the output
of GuessLex. So prune the list of recursive calls, and remove those
where another call exists that has the same goal and context that is no
more specific.
2023-12-07 09:08:46 +00:00
Kyle Miller
bcbcf50442
feat: string gaps for continuing string literals across multiple lines (#2821)
Implements "gaps" in string literals. These are escape sequences of the
form `"\" newline whitespace+` that have the interpretation of an empty
string. For example,
```
  "this is \
     a string"
```
is equivalent to `"this is a string"`. These are modeled after string
continuations in
[Rust](https://doc.rust-lang.org/beta/reference/tokens.html#string-literals).

Implements RFC #2838
2023-12-07 08:17:00 +00:00
Joachim Breitner
ec8811a75a
fix: WF.Fix: deduplicate subsumed goals before running tactic (#3024)
before code like

    def dup (a : Nat) (b : Nat := a) := a + b

    def rec : Nat → Nat
     | 0 => 1
     | n+1 => dup (dup (dup (rec n)))
    decreasing_by decreasing_tactic

would run the `decreasing_tactic` 8 tims, because the recursive call
`rec n` gets duplicate due to the default paramter. Similar effects can
be observed due to dependent types or tactics like `cases`.

This is wasteful, and is confusing to the user when they use
`decreasing_by` interactively. Therfore, we now go through the proof
obligations (MVars) and if solving one would imply solving another one,
we assign the mvars to each other accordingly.

This PR is a sibling of #3004.
2023-12-07 08:04:27 +00:00
bc²
d4f10bc07e
feat: detail error message about invalid mutual blocks (#2949)
To prevent user confusion as in this [Zulip
message](https://leanprover.zulipchat.com/#narrow/stream/113489-new-members/topic/Matching.20on.20prop/near/341456011)
2023-12-05 10:50:10 +00:00
Joachim Breitner
d6c81f8594
feat: GuessLex: print inferred termination argument (#3012)
With

    set_option showInferredTerminationBy true

this prints a message like

    Inferred termination argument:
    termination_by
      ackermann n m => (sizeOf n, sizeOf m)

it tries hard to use names that

 * match the names that the user used, if present
 * have no daggers (so that it can be copied)
 * do not shadow each other
 * do not shadow anything from the environment (just to be nice)

it does so by appending sufficient `'` to the name.

Some of the emitted `sizeOf` calls are unnecessary, but they are needed
sometimes with dependent parameters. A follow-up PR will not emit them
for non-dependent arguments, so that in most cases the output is pretty.

Somewhen down the road we also want a code action, maybe triggered by
`termination_by?`. This should come after #2921, as that simplifies that
feature (no need to merge termination arguments from different cliques
for example.)
2023-12-05 09:41:52 +00:00
Joachim Breitner
17825bf81d
feat: GuessLex: if no measure is found, explain why (#2960)
by showing the matrix of calls and measures, and what we know about that
call (=, <, ≤, ?), e.g.

guessLexFailures.lean:27:0-33:31: error: Could not find a decreasing
measure.
    The arguments relate at each recursive call as follows:
(<, ≤, =: relation proved, ? all proofs failed, _: no proof attempted)
               x1 x2 x3
    1) 29:6-25  =  =  =
    2) 30:6-23  =  ?  <
    3) 31:6-23  <  _  _
    Please use `termination_by` to specify a decreasing measure

It’s a bit more verbose for mutual functions.

It will use the user-specified argument names for functions written
```
foo (n : Nat) := …
```
but not with pattern matching like
```
foo : Nat → … 
  | n => …
```
This can be refined later and separately (and maybe right away in
`expandMatchAltsWhereDecls`).
2023-12-05 08:32:15 +00:00
Joachim Breitner
6d23450642
refactor: rewrite TerminationHint elaborators (#2958)
In order to familiarize myself with this code, and so that the next
person has an easier time, I

* added docstrings explaining what I found out these things to
* rewrote the syntax expansion functions using syntax pattern matches,
  to the extend possible
2023-12-02 10:08:07 +00:00
Joachim Breitner
465f0feb2d
test: expand tests/lean/issue2981.lean a bit (#3007) 2023-12-01 17:52:34 +00:00
Arthur Adjedj
66cb44c53c
fix: missing whnf in mkBelowBinder and mkMotiveBinder (#2991)
Closes #2990
2023-12-01 14:46:09 +00:00
Joachim Breitner
8be3897a8b
chore: improve tests/lean/copy-produced (#3006)
* do not take an argument, no longer needed
* make it whitespace-in-filenames safe
* copy verbosely when there are changes, for better user feedback
2023-12-01 14:34:52 +00:00
Joachim Breitner
e4f2c39ab2
test: termination checking and duplicated terms (#2993)
These tests came out of #2981 and #2982; let’s have them in master even
if the changes there will not happen right away.
2023-11-29 15:40:57 +00:00
Joachim Breitner
ffbea840bf
feat: WF.GuessLex: If there is only one plausible measure, use it (#2954)
If here is only one plausible measure, there is no point having the
`GuessLex` code see if it
is terminating, running all the tactics, only for the `MkFix` code then
run the tactics again.

So if there is only one plausible measure (non-mutual recursion with
only one varying
parameter), just use that measure.

Side benefit: If the function isn’t terminating, more detailed error
messages are shown
(failing proof goals), located at the recursive calls.
2023-11-27 22:41:40 +00:00
Joachim Breitner
cbba783bcf
feat: Guess lexicographic order for well-founded recursion (#2874)
This improves Lean’s capabilities to guess the termination measure for
well-founded
recursion, by also trying lexicographic orders.  For example:

    def ackermann (n m : Nat) := match n, m with
      | 0, m => m + 1
      | .succ n, 0 => ackermann n 1
      | .succ n, .succ m => ackermann n (ackermann (n + 1) m)

now just works.

The module docstring of `Lean.Elab.PreDefinition.WF.GuessLex` tells the
technical story.
Fixes #2837
2023-11-27 16:30:20 +00:00
Mario Carneiro
9769ad6572
fix: missing withContext in simp trace (#2053)
As [reported on
Zulip](https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/simp.3F.20.5B*.5D/near/322724789).

---------

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
2023-11-27 12:02:38 +00:00
Marc Huisinga
7ff7cf9b5a
feat: per-package server options (#2858)
This PR adds per-package server options to resolve #2455. It is based on
the previous work in #2456, but takes a different approach: options are
loaded for the specific file in the file worker when `print-paths` is
called, instead of loading them in the watchdog with a separate Lake
command. This change addresses review comments made in #2456.

In doing so, it introduces two new Lake config fields: 
- `leanOptions`: `-D` flag options that are passed to both the language
server and `lean` when building.
- `moreServerOptions`: `-D` flag options that are passed to the language
server.

Since `print-paths` must also accept a file path to compute the options
for that file, this PR is changing the API for `print-paths`. As there
have been numerous complaints about the name `print-paths`, I also
decided to change it to `setup-file` in this PR, since it would break
compatibility with the old Lake API anyways.

This PR deprecates the Lakefile field `moreServerArgs` in favor of
`moreGlobalServerArgs`, as suggested in the review for #2456.

Fixes #2455

---------

Co-authored-by: digama0 <mcarneir@andrew.cmu.edu>
2023-11-26 13:42:38 +00:00
Kyle Miller
5639302989
feat: pp.beta to apply beta reduction when pretty printing (#2864)
This was a Lean 3 pretty printer option. While this pretty printer
option tends to lead to confusing situations when set, it has been
frequently requested. [It is
possible](https://github.com/leanprover-community/mathlib4/pull/7910) to
implement this pretty printer option as a user, but it comes with some
artifacts -- for instance, expressions in hovers are not beta reduced.
Adding this as a core pp option is cleanest.

(We should consider having hooks into the tactic evaluator to allow
users to transform the tactic state between tactics. This would enable
beta reducing the entire local context for real, which would be useful
for teaching.)

Closes #715
2023-11-24 12:26:31 +00:00
Joachim Breitner
260eaebf4e
fix: PackMutual: Eta-Expand as needed (#2902)
The `packMutual` code ought to reliably replace all recursive calls to
the functions in `preDefs`, even when they are under- or over-applied.
Therefore eta-expand if need rsp. keep extra arguments around.

Needs a tweak to `Meta.transform` to avoid mistaking the `f` in
`f x1 x2` as a zero-arity application.

Includes a test case.

This fixes #2628 and #2883.
2023-11-22 14:25:56 +00:00
Joachim Breitner
dede354e77
fix: Float RecApp out of applications (#2818)
This didn't work before
```
def f (n : Nat) : Nat :=
  match n with
  | 0 => 0
  | n + 1 => (f) n
```
because the `RecApp` metadata marker gets in the way. More practically
relevant, such code is to be produced when using `rw` or `simp` in
recursive theorems (see included test case).

We can fix this by preprocessing the definitions and floating the
`.mdata` marker out of applications.

For structural recursion, there already exists a `preprocess` function;
this now also floats out `.mdata` markers.

For well-founded recursion, this introduces an analogous `preprocess`
function.

Fixes #2810.

One test case output changes: With the `.mdata` out of the way, we get a
different error message. Seems fine.

Alternative approaches are:

* Leaving the `.mdata` marker where it is, and looking around it.
  Tried in #2813, but not nice (many many places where `withApp` etc.
  need to be adjusted).
* Moving the `.mdata` _inside_ the application, so that `withApp` still
  works. Tried in #2814. Also not nice, the invariant that the `.mdata`
  is around the `.const` is tedious to maintain.
2023-11-22 14:25:09 +00:00
Joachim Breitner
54dd588fc2
fix: Use whnf for mutual recursion with types hiding (#2926)
the code stumbled over recursive functions whose type doesn’t have
enough manifest foralls, like:

```
def FunType := Nat → Nat

mutual
def foo : FunType
  | .zero => 0
  | .succ n => bar n
def bar : FunType
  | .zero => 0
  | .succ n => foo n
end
termination_by foo n => n; bar n => n
```

This can be fixed by using `whnf` in appropriate places, to expose the
`.forall` constructor.

Fixes #2925, comes with test case.
2023-11-22 11:31:36 +00:00
Mario Carneiro
b97b0ad2aa
feat: rename request handler (#2462)
This implements a request handler for the `textDocument/rename` LSP
request, enabling renames via F2. It handles both local renames (e.g.
`let x := 1; x` to `let y := 1; y`) as well as global renames
(definitions).

Unfortunately it does not work for "orphan" files outside a project, as
it uses ilean data for the current file and this does not seem to be
saved for orphan files. As a result, the test file does not work,
although one can manually test the implementation against a project such
as mathlib. (This issue already exists for the "references" request,
e.g. ctrl click on the first `x` in `let x := 1; x` takes you to the
second one only if you are not in an orphan file.)

* Fixes leanprover-community/mathlib4#7124
2023-11-21 13:10:52 +01:00
Joachim Breitner
9800e066bc
fix: PackMutual: Deal with extra arguments (#2892)
previously, it would ignore a recursive call that has extra arguments,
which can happen when the recursive functions return something of
function type. Therefore just leave them extra arguments in place.

Fixes #2883.
2023-11-20 17:07:50 +01:00
Kyle Miller
4d39a0b0e3
fix: DecidableEq deriving handler could not handle fields whose types start with an implicit argument (#2918)
Fixes #2914
2023-11-20 20:51:47 +11:00
Mario Carneiro
8881517018 fix: report goals in induction with parse error 2023-11-20 09:15:27 +01:00
Leni Aniva
ab36ed477e
feat: allow trailing comma in tuples, lists, and tactics (#2643) 2023-11-17 13:31:41 +01:00
tydeu
171837216a feat: IO.FS.Handle.lock/tryLock/unlock 2023-11-15 19:31:08 -05:00
Sebastian Ullrich
8cfcf7ce61 fix: look through binop% variants in elabCDotFunctionAlias? 2023-11-12 16:57:51 +11:00