Commit graph

121 commits

Author SHA1 Message Date
Kyle Miller
409cbe1da9
fix: make rw collect only new goals, occurs check (#10306)
This PR fixes a few bugs in the `rw` tactic: it could "steal" goals
because they appear in the type of the rewrite, it did not do an occurs
check, and new proof goals would not be synthetic opaque. This PR also
lets the `rfl` tactic assign synthetic opaque metavariables so that it
is equivalent to `exact rfl`.

Implementation note: filtering old vs new is not sufficient. This PR
partially addresses the bug where the rw tactic creates natural
metavariables for each of the goals; now new proof goals are synthetic
opaque.

Metaprogramming API: Instead of `Lean.MVarId.rewrite` prefer
`Lean.Elab.Tactic.elabRewrite` for elaborating rewrite theorems and
applying rewrites to expressions.

Closes #10172
2025-09-14 04:44:55 +00:00
Leonardo de Moura
2652cc18b8
chore: error messages consistency (#10143)
This PR standardizes error messages by quoting names with backticks. The
changes were automated, so some cases may still be missing.
2025-08-26 17:55:43 +00:00
jrr6
9b186297c7
feat: add conversion-mode clear tactic (#6732)
This PR adds support for the `clear` tactic in conversion mode.

Closes #5734
2025-07-31 16:39:57 +00:00
jrr6
62f14514da
refactor: update built-in tactic error messages (#9633)
This PR updates various error messages produced by or associated with
built-in tactics and adapts their formatting to current conventions.
2025-07-31 14:16:57 +00:00
Sebastian Ullrich
ff1d3138bf
refactor: module-ize Lean (#9330) 2025-07-25 12:02:51 +00:00
Paul Reichert
98e4b2882f
refactor: migrate to new ranges (#8841)
This PR migrates usages of `Std.Range` to the new polymorphic ranges.

This PR unfortunately increases the transitive imports for
frequently-used parts of `Init` because the ranges now rely on iterators
in order to provide their functionality for types other than `Nat`.
However, iteration over ranges in compiled code is as efficient as
before in the examples I checked. This is because of a special
`IteratorLoop` implementation provided in the PR for this purpose.

There were two issues that were uncovered during migration:

* In `IndPredBelow.lean`, migrating the last remaining range causes
`compilerTest1.lean` to break. I have minimized the issue and came to
the conclusion it's a compiler bug. Therefore, I have not replaced said
old range usage yet (see #9186).
* In `BRecOn.lean`, we are publicly importing the ranges. Making this
import private should theoretically work, but there seems to be a
problem with the module system, causing the build to panic later in
`Init.Data.Grind.Poly` (see #9185).
* In `FuzzyMatching.lean`, inlining fails with the new ranges, which
would have led to significant slowdown. Therefore, I have not migrated
this file either.
2025-07-07 12:41:53 +00:00
Paul Reichert
6e538c35dd
refactor: migrate all usages of old slice notation (#9000)
This PR replaces all usages of `[:]` slice notation in `src` with the
new `[...]` notation in production code, tests and comments. The
underlying implementation of the `Subarray` functions stays the same.

Notation cheat sheet:

* `*...*` is the doubly-unbounded range.
* `*...a` or `*...<a` contains all elements that are less than `a`.
* `*...=a` contains all elements that are less than or equal to `a`.
* `a...*` contains all elements that are greater than or equal to `a`.
* `a...b` or `a...<b` contains all elements that are greater than or
equal to `a` and less than `b`.
* `a...=b` contains all elements that are greater than or equal to `a`
and less than or equal to `b`.
* `a<...*` contains all elements that are greater than `a`.
* `a<...b` or `a<...<b` contains all elements that are greater than `a`
and less than `b`.
* `a<...=b` contains all elements that are greater than `a` and less
than or equal to `b`.

Benchmarks have shown that importing the iterator-backed parts of the
polymorphic slice library in `Init` impacts build performance. This PR
avoids this problem by separating those parts of the library that do not
rely on iterators from those those that do. Whereever the new slice
notation is used, only the iterator-independent files are imported.
2025-06-27 18:52:07 +00:00
Kyle Miller
71cf266cd7
feat: add Meta.letToHave and the let_to_have tactic (#8954)
This PR adds a procedure that efficiently transforms `let` expressions
into `have` expressions (`Meta.letToHave`). This is exposed as the
`let_to_have` tactic.

It uses the `withTrackingZetaDelta` technique: the expression is
typechecked, and any `let` variables that don't enter the zeta delta set
are nondependent. The procedure uses a number of heuristics to limit the
amount of typechecking performed. For example, it is ok to skip
subexpressions that do not contain fvars, mvars, or `let`s.
2025-06-24 01:33:53 +00:00
Kyle Miller
517899da7b
feat: extract_lets and lift_lets tactics (#6432)
This PR implements tactics called `extract_lets` and `lift_lets` that
manipulate `let`/`let_fun` expressions. The `extract_lets` tactic
creates new local declarations extracted from any `let` and `let_fun`
expressions in the main goal. For top-level lets in the target, it is
like the `intros` tactic, but in general it can extract lets from deeper
subexpressions as well. The `lift_lets` tactic moves `let` and `let_fun`
expressions as far out of an expression as possible, but it does not
extract any new local declarations. The option `extract_lets +lift`
combines these behaviors.

This is a re-implementation of `extract_lets` and `lift_lets` from
mathlib. The new `extract_lets` is like doing `lift_lets; extract_lets`,
but it does not lift unextractable lets like `lift_lets`. The
`lift_lets; extract_lets` behavior is now handled by `extract_lets
+lift`. The new `lift_lets` tactic is a frontend to `extract_lets +lift`
machinery, which rather than creating new local definitions instead
represents the accumulated local declarations as top-level lets.

There are also conv tactics for both of these. The `extract_lets` has a
limitation due to the conv architecture; it can extract lets for a given
conv goal, but the local declarations don't survive outside conv. They
get zeta reduced immediately upon leaving conv.
2025-04-21 08:57:01 +00:00
Kyle Miller
092ece5d49
feat: let conv tactics ext/intro/enter take _ (#7806)
This PR modifies the syntaxes of the `ext`, `intro` and `enter` conv
tactics to accept `_`. The introduced binder is an inaccessible name.
2025-04-04 00:01:29 +00:00
jrr6
c07948a168
feat: add simp? and dsimp? in conversion mode (#6593)
This PR adds support for the `simp?` and `dsimp?` tactics in conversion
mode.

Closes #6164
2025-01-10 01:42:17 +00:00
Kyle Miller
764386734c
fix: improvements to change tactic (#6022)
This PR makes the `change` tactic and conv tactic use the same
elaboration strategy. It works uniformly for both the target and local
hypotheses. Now `change` can assign metavariables, for example:
```lean
example (x y z : Nat) : x + y = z := by
  change ?a = _
  let w := ?a
  -- now `w : Nat := x + y`
```
2024-11-16 07:08:29 +00:00
Leonardo de Moura
1315266dd3 refactor: mark the Simp.Context constructor as private
motivation: this is the first step to fix the mismatch
between `isDefEq` and the discrimination tree indexing.
2024-11-13 14:12:55 +11:00
Kyle Miller
406da78fc6
fix: arg conv tactic misreported number of arguments on error (#5968) 2024-11-06 02:13:24 +00:00
Kyle Miller
f1707117f0
feat: conv arg now can access more arguments (#5894)
Specializes the congr lemma generated for the `arg` conv tactic to only
rewrite the chosen argument. This makes it much more likely that the
chosen argument is able to be accessed.

Lets `arg` access the domain and codomain of pi types via `arg 1` and
`arg 2` in more situations. Upstreams `pi_congr` for this from mathlib.

Adds a negative indexing option, where `arg -2` accesses the
second-to-last argument for example, making the behavior of `lhs`
available to `arg`. This works for `enter` as well.

Other improvement: when there is an error in the `enter [...]` tactic,
individual locations get underlined with the error. The tactic info now
also is like `rw`, so you can see the intermediate conv states.

Closes #5871
2024-11-01 02:12:14 +00:00
Kyle Miller
9eded87462
fix: remove withoutRecover from apply elaboration (#5862)
The assumptions behind disabling error recovery for the `apply` tactic
no longer seem to hold, since tactic combinators like `first` themselves
disable error recovery when it makes sense.

This addresses part of #3831

Breaking change: `elabTermForApply` no longer uses `withoutRecover`.
Tactics using `elabTermForApply` should evaluate whether it makes sense
to wrap it with `withoutRecover`, which is generally speaking when it's
used to elaborate identifiers.
2024-10-28 21:27:14 +00:00
Kyle Miller
62521f4f2d
fix: let congr conv tactic handle "over-applied" functions (#5861)
Adds ability to chain congruence lemmas when a function's arity is less
than the number of supplied arguments. This improves `congr` as well as
all conv tactics implemented using `congr`, like `arg` and `enter`.

(The non-conv `congr` tactic still needs to be fixed.)

Toward #2942.
2024-10-28 07:34:33 +00:00
Kyle Miller
fa711253d6
feat: improved error message for unfold (#5815)
When `unfold` is trying to unfold a local variable that's not a local
definition, throws an error.

For issue from
[Zulip](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Unqualified.20unfold.20no.20longer.20works/near/478387250)
2024-10-23 03:35:15 +00:00
Kim Morrison
5d155d8b02
chore: simplify signature of Array.mapIdx (#5749)
This PR simplifies the signature of `Array.mapIdx`, to take a function
`f : Nat \to \a \to \b` rather than a function `f : Fin as.size \to \a
\to \b`.

Lean doesn't actually use the extra generality anywhere (so in fact this
change *simplifies* all the call sites of `Array.mapIdx`, since we no
longer need to throw away the proof).

This change would make the function signature equivalent to
`List.mapIdx`, hence making it easier to write verification lemmas.

We keep the original behaviour as `Array.mapFinIdx`.
2024-10-21 05:48:42 +00:00
euprunin
405b5aa047
chore: fix spelling mistakes in src/Lean/Elab/ (#5435)
Co-authored-by: euprunin <euprunin@users.noreply.github.com>
2024-09-23 21:58:16 +00:00
Kyle Miller
c9239bfaa8
feat: let unfold do zeta-delta reduction of local definitions (#4834)
This is "upstreaming" mathlib's `unfold_let` tactic by incorporating its
functionality into `unfold`. Now `unfold` can, in addition to unfolding
global definitions, unfold local definitions. The PR also updates the
`conv` version of the tactic.

An improvement over `unfold_let` is that it beta reduces unfolded local
functions.

Two features not present in `unfold` are that (1) `unfold_let` with no
arguments does zeta delta reduction of *all* local definitions, and also
(2) `unfold_let` can interleave unfoldings (in contrast, `unfold a b c`
is exactly the same as `unfold a; unfold b; unfold c`).

Closes RFC #4090
2024-09-07 21:48:08 +00:00
Joachim Breitner
aa3c87b2c7
fix: conv => arg n to handle .subsingletonInst (#5149)
this fixes #4394, see there for an analysis.
2024-08-29 15:48:31 +00:00
Joachim Breitner
b181fd83ef
feat: in conv tactic, use try with_reducibe rfl (#3763)
The `conv` tactic tries to close “trivial” goals after itself. As of
now, it uses
`try rfl`, which means it can close goals that are only trivial after
reducing with
default transparency. This is suboptimal

* this can require a fair amount of unfolding, and possibly slow down
the proof
   a lot. And the user cannot even prevent it.
* it does not match what `rw` does, and a user might expect the two to
behave the
   same.

So this PR changes it to `with_reducible rfl`, matching `rw`’s behavior.

I considered `with_reducible eq_refl` to only solve trivial goals that
involve equality,
but not other relations (e.g. `Perm xs xs`), but a discussion on mathlib
pointed out
that it’s expected and desirable to solve more general reflexive goals:


https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Closing.20after.20.60rw.60.2C.20.60conv.60.3A.20.60eq_refl.60.20instead.20of.20.60rfl.60/near/429851605
2024-03-29 11:59:45 +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
Henrik Böving
23e49eb519 perf: add prelude to all Lean modules 2024-02-18 14:55:17 -08:00
Joachim Breitner
17c7cb0e1c
feat: conv => fun (#3240)
Given a target
```
| f a b
```
the new conv tactic
```
conv => fun
```
turns it into
```
| f a
```
and `arg 0` turns it into
```
| f
```

Fixes #3239
2024-02-18 12:02:25 +00:00
Leonardo de Moura
b4a290a203 refactor: simp Step and Simproc types
Before this commit, `Simproc`s were defined as `Expr -> SimpM (Option Step)`, where `Step` is inductively defined as follows:
```
inductive Step where
  | visit : Result → Step
  | done  : Result → Step
```
Here, `Result` is a structure containing the resulting expression and a proof demonstrating its equality to the input. Notably, the proof is optional; in its absence, `simp` assumes reflexivity.

A simproc can:
- Fail by returning `none`, indicating its inapplicability. In this case, the next suitable simproc is attempted, along with other simp extensions.
- Succeed and invoke further simplifications using the `.visit`
constructor. This action returns control to the beginning of the
simplification loop.
- Succeed and indicate that the result should not undergo further
simplifications. However, I find the current approach unsatisfactory, as it does not align with the methodology employed in `Transform.lean`, where we have the type:

```
inductive TransformStep where
  /-- Return expression without visiting any subexpressions. -/
  | done (e : Expr)
  /--
  Visit expression (which should be different from current expression) instead.
  The new expression `e` is passed to `pre` again.
  -/
  | visit (e : Expr)
  /--
  Continue transformation with the given expression (defaults to current expression).
  For `pre`, this means visiting the children of the expression.
  For `post`, this is equivalent to returning `done`. -/
  | continue (e? : Option Expr := none)
```
This type makes it clearer what is going on. The new `Simp.Step` type is similar but use `Result` instead of `Expr` because we need a proof.
2024-02-01 16:58:54 +11:00
Leonardo de Moura
5edd59806c feat: simp only should not use default simproc set 2024-01-09 12:57:15 +01:00
Marcus Rossel
89d7eb8b78
doc: fix typos/indentation (#3085) 2023-12-17 18:41:46 +00:00
Mario Carneiro
8b0699cd3b fix: disable memoize in pattern conv 2022-12-19 06:21:54 -08:00
Sebastian Ullrich
d5fb32a393 fix: hygiened goal tags in conv congr 2022-12-14 16:36:47 +01:00
Mario Carneiro
583e023314 chore: snake-case attributes (part 2) 2022-10-19 09:28:08 -07:00
Mario Carneiro
db110f5dfe fix: preserve tags in simp conv 2022-09-28 14:24:44 -07:00
Mario Carneiro
6f8e861158 fix: case names in congr conv 2022-09-28 14:24:44 -07:00
Mario Carneiro
b6a58d13e1 fix: LHS goals should be pre-whnf'd 2022-09-28 14:24:44 -07:00
Mario Carneiro
b8ed329a5d feat: add dsimp conv <- mathlib4
Co-authored-by: Moritz Doll <doll@uni-bremen.de>
2022-09-28 14:24:44 -07:00
Mario Carneiro
a09934c693 feat: more conv goal structuring tactics 2022-09-28 14:24:44 -07:00
Mario Carneiro
9b9998f5c8 feat: pattern (occs := ...) conv 2022-09-25 19:52:56 -07:00
Mario Carneiro
0961561d4e feat: track simp lemmas through the core tactics 2022-09-25 06:40:56 -07:00
Mario Carneiro
90353d7fd7 feat: multiple delta, delta conv, unfold 2022-09-21 18:04:31 -07:00
Gabriel Ebner
9113291e9e fix: preserve separators in evalSepByIndentConv 2022-09-18 16:43:23 -07:00
Gabriel Ebner
2b5c1e397a feat: use sepBy1Indent for conv blocks 2022-09-18 16:43:23 -07:00
Gabriel Ebner
7356840cbc feat: use sepBy1Indent for tactic blocks 2022-09-18 16:43:23 -07:00
Leonardo de Moura
f1c150228b fix: fixes #1558 2022-09-09 15:27:51 -07:00
Mario Carneiro
b3ba6d4bf7 fix: use resolveGlobalConstNoOverloadWithInfo more 2022-08-13 18:20:55 -07:00
Leonardo de Moura
deafc315c7 fix: make forall_congr more robust at conv intro
closes #1426
2022-08-05 12:38:49 -07:00
Leonardo de Moura
303e322255 feat: avoid [Decidable p] instance implicit parameters in congruence theorems when possible 2022-08-02 04:47:42 -07:00
Leonardo de Moura
b2f34bdedd feat: improve congr conv tactic
It has better support for proof irrelevant and `[Decidable p]` arguments
2022-08-02 04:26:34 -07:00
Leonardo de Moura
01ce4b9982 feat: use infer_instance to close remaining goals at conv block 2022-08-02 04:24:56 -07:00
Leonardo de Moura
c143631ab1 chore: missing instantiateMVars 2022-08-02 02:24:50 -07:00