Commit graph

4586 commits

Author SHA1 Message Date
Leonardo de Moura
33f7865bbb
fix: cached results at synthInstance? (#4530)
Synthesized type class instances may introduce new metavariables, and we
should actually cache `AbstractMVarsResult`.

closes #2283
2024-06-23 17:54:35 +00:00
Bhavik Mehta
43a9c73556
chore: fix typo and incorrect name in doc (#4404)
Fixes typo "reflexivitiy" to "reflexivity", and changes exact Eq.rfl to
exact rfl, since Eq.rfl does not exist.

(I got something confused wrt the bot message on #4367 and accidentally
closed that one, so making this one instead, which I think satisfies the
requirements it wanted.)

---------

Co-authored-by: Joachim Breitner <mail@joachim-breitner.de>
2024-06-23 09:06:50 +00:00
Joachim Breitner
378b02921d
refactor: port recOn construction to Lean (#4516)
this is the simplest of the constructions to be ported from C++ to Lean,
so I’ll PR this one first.

This begins to put each construction into its own file, as it was the
case with C++.

For validation I developed this in a separate repository at
https://github.com/nomeata/lean-constructions/tree/fad715e
and checked that all `.recOn` declarations found in Lean and Mathlib are
identical (per `==`) to the ones produced by the C code.
2024-06-23 07:36:27 +00:00
David Thrane Christiansen
84e46162b5
feat: more infrastructure for tactic documentation (#4490)
This is the groundwork for a tactic index in generated documentation, as
there was in Lean 3. There are a few challenges to getting this to work
well in Lean 4:
* There's no natural notion of *tactic identity* - a tactic may be
specified by multiple syntax rules (e.g. the pattern-matching version of
`intro` is specified apart from the default version, but both are the
same from a user perspective)
* There's no natural notion of *tactic name* - here, we take the
pragmatic choice of using the first keyword atom in the tactic's syntax
specification, but this may need to be overridable someday.
* Tactics are extensible, but we don't want to allow arbitrary imports
to clobber existing tactic docstrings, which could become unpredictable
in practice.

For tactic identity, this PR introduces the notion of a *tactic
alternative*, which is a `syntax` specification that is really "the same
as" an existing tactic, but needs to be separate for technical reasons.
This provides a notion of tactic identity, which we can use as the basis
of a tactic index in generated documentation. Alternative forms of
tactics are specified using a new `@[tactic_alt IDENT]` attribute,
applied to the new tactic syntax. It is an error to declare a tactic
syntax rule to be an alternative of another one that is itself an
alternative. Documentation hovers now take alternatives into account,
and display the docs for the canonical name.

*Tactic tags*, created with the `register_tactic_tag` command, specify
tags that may be applied to tactics. This is intended to be used by
doc-gen and Verso. Tags may be applied using the `@[tactic_tag TAG1 TAG2
...]` attribute on a canonical tactic parser, which may be used in any
module to facilitate downstream projects introducing tags that apply to
pre-existing tactics. Tags may not be removed, but it's fine to
redundantly add them. The collection of tags, and the tactics to which
they're applied, can be seen using the `#print tactic tags` command.

*Extension documentation* provides a structured way to document
extensions to tactics. The resulting documentation is gathered into a
bulleted list at the bottom of the tactic's docstring. Extensions are
added using the `tactic_extension TAC` command. This can be used when
adding new interpretations of a tactic via `macro_rules`, when extending
some table or search index used by the tactic, or in any other way. It
is a command to facilitate its flexible use with various extension
mechanisms.
2024-06-21 12:49:30 +00:00
Kim Morrison
301a89aba4
feat: lemmas about List.map (#4521) 2024-06-21 06:40:30 +00:00
Leonardo de Moura
45c5d009d6
fix: dsimp missing theorems for literals (#4467) 2024-06-20 00:35:53 +00:00
Leonardo de Moura
458835360f
fix: [implemented_by] at functions defined by well-founded recursion (#4508)
closes #2899
2024-06-20 00:06:38 +00:00
Leonardo de Moura
3e05b0641b chore: fix test 2024-06-20 01:05:52 +02:00
Leonardo de Moura
49f058cb76
feat: open _root_.<namespace> (#4505)
closes #3045
2024-06-19 21:59:46 +00:00
JovanGerb
c7c50a8bec
chore: fix linter errors (#4502)
The linters in Batteries can be used to spot mistakes in Lean. See the
message on
[Zulip](https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Go-to-def.20on.20typeclass.20fields.20and.20type-dependent.20notation/near/442613564).
These are the different linters with errors:

- unusedArguments:
There are many unused instance arguments, especially a redundant `[Monad
m]` is very common
- checkUnivs:
There was a problem with universes in a definition in
`Init.Control.StateCps`. I fixed it by adding a `variable` statement for
the implicit arguments in the file.
- defLemma:
many proofs are written as `def` instead of `theorem`, most notably
`rfl`. Because `rfl` is used as a match pattern, it must be a def. Is
this desirable?
The keyword `abbrev` is sometimes used for an alias of a theorem, which
also results in a def. I would want to replace it with the `alias`
keyword to fix this, but it isn't available.
- dupNamespace:
I fixed some of these, but left `Tactic.Tactic` and `Parser.Parser` as
they are as these seem intended.
- unusedHaveSuffices:
  I cleaned up a few proofs with unused `have` or `suffices`
- explicitVarsOfIff:
  I didn't fix any of these, because that would be a breaking change.
- simpNF:
I didn't fix any of these, because I think that requires knowing the
intended simplification order.
2024-06-19 18:24:08 +00:00
Leonardo de Moura
357b52928f
fix: global definition shadowing a local one when using dot-notation (#4497)
closes #3079
2024-06-19 05:52:45 +00:00
Leonardo de Moura
167771923e
test: for isDefEq issue (#4492)
The issue has already been fixed in previous PRs.

closes #2461
2024-06-18 17:54:55 +00:00
Sebastian Ullrich
eb67654ae6
feat: incremental next and tactic if (#4459) 2024-06-18 12:36:59 +00:00
Kim Morrison
face4cef75
feat: complete API for List.replicate (#4487)
This is not the most exciting place to start, but I started here to:
* pick a function with little development in Batteries and Mathlib, so I
wouldn't have conflicts
* that is easy!
* to see how much effort it is to get fairly complete coverage
* and to set up some infrastructure to be used later, i.e.
`tests/lean/run/list_simp.lean`
2024-06-18 08:30:09 +00:00
Leonardo de Moura
fca87da2d4
fix: simp support for OfNat instances that are functions (#4481)
closes #4462
2024-06-17 22:01:25 +00:00
Leonardo de Moura
3c4d6ba864 feat: new #reduce elaborator
closes #4465
2024-06-17 23:27:34 +02:00
Joachim Breitner
59a09fb4e7
feat: use priorities to ensure simp applies eqational lemmas in order (#4434)
This assigns priorities to the equational lemmas so that more specific
ones
are tried first before a possible catch-all with possible
side-conditions.

We assign very low priorities to match the simplifiers behavior when
unfolding
a definition, which happens in `simpLoop`’ `visitPreContinue` after
applying
rewrite rules.

Definitions with more than 100 equational theorems will use priority 1
for all
but the last (a heuristic, not perfect).

fixes #4173, to some extent.
2024-06-17 18:22:28 +00:00
Markus Schmaus
1cf71e54cf
feat: add missing theorems for + 1 and - 1 normal form (#4242)
`Nat.succ_eq_add_one` and `Nat.pred_eq_sub_one` are now simp lemmas. For
theorems about `Nat.succ` or `Nat.pred` without corresponding theorem
for `+ 1` or `- 1`, this adds the corresponding theorem.
2024-06-17 05:35:32 +00:00
Kim Morrison
03d01f4024
chore: reorganisation of List API (#4469)
This PR neither adds nor removes material, but improves the organization
of `Init/Data/List/*`.

These files are essentially completely re-ordered, to ensure that
material is developed in a consistent order between `List.Basic`,
`List.Impl`, `List.BasicAux`, and `List.Lemmas`.

Everything is organised in subsections, and I've added some module docs.
2024-06-17 04:21:53 +00:00
David Thrane Christiansen
456ed44550
feat: add a linter for local vars that clash with their constructors (#4301)
This came up when watching new Lean users in a class situation. A number
of them were confused when they omitted a namespace on a constructor
name, and Lean treated the variable as a pattern that matches anything.

For example, this program is accepted but may not do what the user
thinks:
```
inductive Tree (α : Type) where
  | leaf
  | branch (left : Tree α) (val : α) (right : Tree α)

def depth : Tree α → Nat
  | leaf => 0
```
Adding a `branch` case to `depth` results in a confusing message.

With this linter, Lean marks `leaf` with:
```
Local variable 'leaf' resembles constructor 'Tree.leaf' - write '.leaf' (with a dot) or 'Tree.leaf' to use the constructor.
note: this linter can be disabled with `set_option linter.constructorNameAsVariable false`
```

Additionally, the error message that occurs when invalid names are
applied in patterns now suggests similar names. This means that:
```
def length (list : List α) : Nat :=
  match list with
  | nil => 0
  | cons x xs => length xs + 1
```
now results in the following warning on `nil`:
```
warning: Local variable 'nil' resembles constructor 'List.nil' - write '.nil' (with a dot) or 'List.nil' to use the constructor.
note: this linter can be disabled with `set_option linter.constructorNameAsVariable false`
```

and error on `cons`:
```
invalid pattern, constructor or constant marked with '[match_pattern]' expected

Suggestion: 'List.cons' is similar
```

The list of suggested constructors is generated before the type of the
pattern is known, so it's less accurate, but it truncates the list to
ten elements to avoid being overwhelming. This mostly comes up with
`mk`.
2024-06-14 13:03:09 +00:00
Kim Morrison
2cf478cbbe
chore: prefer · == a over a == · (#3056)
We recently discovered inconsistencies in Mathlib and Std over the
ordering of the arguments for `==`.

The most common usage puts the "more variable" term on the LHS, and the
"more constant" term on the RHS, however there are plenty of exceptions,
and they cause unnecessary pain when switching (particularly, sometimes
requiring otherwise unneeded `LawfulBEq` hypotheses).

This convention is consistent with the (obvious) preference for `x == 0`
over `0 == x` when one term is a literal.

We recently updated Std to use this convention
https://github.com/leanprover/std4/pull/430

This PR changes the two major places in Lean that use the opposite
convention, and adds a suggestion to the docstring for `BEq` about the
preferred convention.
2024-06-14 04:08:45 +00:00
hwatheod
bedcbfcfee
chore: fix typo in trace.split.failure error message (#4431)
should be "failure" not "failures"

Co-authored-by: q r <qr@abc.local>
2024-06-12 05:57:29 +00:00
Leonardo de Moura
ce6ebd1044
feat: dsimprocs for ite and dite (#4430) 2024-06-11 23:36:18 +00:00
Leonardo de Moura
ab73ac9d15
fix: missing simproc for BitVec equality (#4428) 2024-06-11 22:05:28 +00:00
Leonardo de Moura
3bd39ed8b6
perf: a isDefEq friendly Fin.sub (#4421)
The performance issue at #4413 is due to our `Fin.sub` definition.
```
def sub : Fin n → Fin n → Fin n
  | ⟨a, h⟩, ⟨b, _⟩ => ⟨(a + (n - b)) % n, mlt h⟩
```
Thus, the following runs out of stack space
```
example (a : UInt64) : a - 1 = a :=
  rfl
```
at the `isDefEq` test
```
(a.val.val + 18446744073709551615) % 18446744073709551616 =?= a.val.val
```

From the user's perspective, this timeout is unexpected since they are
using small numerals, and none of the other `Fin` basic operations (such
as `Fin.add` and `Fin.mul`) suffer from this problem.

This PR implements an inelegant solution for the performance issue. It
redefines `Fin.sub` as
```
def sub : Fin n → Fin n → Fin n
  | ⟨a, h⟩, ⟨b, _⟩ => ⟨((n - b) + a) % n, mlt h⟩
```
This approach is unattractive because it relies on the fact that
`Nat.add` is defined using recursion on the second argument.

The impact on this repo was small, but we want to evaluate the impact on
Mathlib.

closes #4413
2024-06-11 17:18:11 +00:00
Leonardo de Moura
ec775df6cc
fix: rw should not include existing goal metavariables in the resulting subgoals (#4385)
closes #4381
2024-06-11 02:50:58 +00:00
Leonardo de Moura
c8e668a9ad
fix: occurs check at metavariable types (#4420)
closes #4405
2024-06-11 00:16:19 +00:00
Leonardo de Moura
a1c8a941f0
fix: universe parameter order discrepancy between theorem and def (#4408)
Before this commit, the `theorem` and `def` declarations had different
universe parameter orders.
For example, the following `theorem`:
```
theorem f (a : α) (f : α → β) : f a = f a := by
  rfl
```
was elaborated as
```
theorem f.{u_2, u_1} : ∀ {α : Sort u_1} {β : Sort u_2} (a : α) (f : α → β), f a = f a :=
  fun {α} {β} a f => Eq.refl (f a)
```
However, if we declare `f` as a `def`, the expected order is produced.
```
def f.{u_1, u_2} : ∀ {α : Sort u_1} {β : Sort u_2} (a : α) (f : α → β), f a = f a :=
  fun {α} {β} a f => Eq.refl (f a)
```

This commit fixes this discrepancy.

@semorrison @jcommelin: This might be a disruptive change to Mathlib,
but it is better to fix the issue asap. I am surprised nobody has
complained about this issue before. I discovered it while trying to
reduce discrepancies between `theorem` and `def` elaboration.
2024-06-10 23:37:52 +00:00
Leonardo de Moura
b02c1c56ab
fix: improve split discriminant generalization strategy (#4401)
This commit also
- improves `split` error messages.
- adds `trace.split.failure` option.
- uses new convention for trace messages.

closes #4390
2024-06-07 21:35:09 +00:00
Leonardo de Moura
0a0f1d7cc7
fix: variable must execute pending tactics and elaboration problems (#4370)
closes #2226
closes #3214
2024-06-06 13:06:18 +00:00
Leonardo de Moura
ff0d338dd2
feat: improve error messages for numerals (#4368)
closes #4365
2024-06-06 00:28:42 +00:00
Joachim Breitner
e33c32fb00
feat: ppOrigin to use MessageData.ofConst (#4362)
so that the pretty-printed origin is clickable, and avoid the
unnecessary `@`.

Particularly nice is this fix:
```diff
 /--
-info: [Meta.Tactic.simp.discharge] @bar discharge 
+info: [Meta.Tactic.simp.discharge] bar discharge 
       autoParam T _auto✝
-  [Meta.Tactic.simp.rewrite] { }:1000, T ==> True
-[Meta.Tactic.simp.rewrite] @bar:1000, U ==> True
+  [Meta.Tactic.simp.rewrite] T.mk:1000, T ==> True
+[Meta.Tactic.simp.rewrite] bar:1000, U ==> True
 -/
```
2024-06-05 11:00:34 +00:00
Joachim Breitner
5cd9f805b7
fix: without recover bad simp arg should fail (#4359)
this is an amendment to #4177, after @kmill pointed out an issue:

Users might expect that within a tactic combinator like `first`, `simp
[h]` fails if `h` does not exist. Therefore the behavior introduced in
PR #4177, which is really most useful in mormal interactive use of
`skip`, is restricted to when `recover := true`.
2024-06-05 08:05:38 +00:00
Joachim Breitner
f0a11b8864
fix: FunInd: support structural recursion on reflexive types (#4327)
types like
```
inductive Many (α : Type u) where
  | none : Many α
  | more : α → (Unit → Many α) → Many α
```
have a `.brecOn` only supports motives producing `Type u`, but not `Sort
u`, but our induction principles produce `Prop`. So the previous
implementation of functional induction would fail for functions that
structurally recurse over such types.

We recognize this case now and, rather hazardously, replace `.brecOn`
with `.binductionOn` (and thus `.below ` with `.ibelow` and `PProd` with
`And`). This assumes that these definitions are highly analogous.

This also improves the error message when realizing a reserved name
fails with an exception, by prepending
```
Failed to realize constant {id}:
```
to the error message.

Fixes #4320
2024-06-05 07:54:48 +00:00
Joachim Breitner
5a25612434
fix: GuessLex: delaborate unused parameters as _ (#4329)
fixes #4230
2024-06-05 07:54:29 +00:00
Austin Letson
644c1d4e36
doc: add docstrings and examples for String functions (#4332)
Add docstrings, usage examples, and doctests for `String.get'`,
`String.next'`, `String.posOf`, `String.revPosOf`.
2024-06-05 05:16:56 +00:00
Leonardo de Moura
46db59d1d9
fix: split (for if-expressions) should work on non-propositional goals (#4349)
Remark: when splitting an `if-then-else` term, the subgoals now have
tags `isTrue` and `isFalse` instead of `inl` and `inr`.
closes #4313

---------

Co-authored-by: Mario Carneiro <di.gama@gmail.com>
2024-06-05 04:43:46 +00:00
Leonardo de Moura
982c338b45
fix: missing dsimp simplification when applying auto-congr theorems (#4352)
closes #4339
2024-06-05 01:01:33 +00:00
Leonardo de Moura
5924c5aea9
fix: simp must not use the forward version of an user-specified backward theorem (#4345)
closes #4290
2024-06-04 22:49:31 +00:00
Leonardo de Moura
28cf1cf5cf
fix: mutual inductives with instance parameters (#4342)
closes #4310
2024-06-04 17:35:41 +00:00
Kyle Miller
a54fa7cae6
fix: partial calc tactic would fail due to mdata or uninstantiated mvars (#4335)
Reported by Heather Macbeth.

Closes #4334

---------

Co-authored-by: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com>
2024-06-04 01:23:20 +00:00
Joachim Breitner
f65e3ae985
feat: simp to still work even if one simp arg does not work (#4177)
this fixes a usability paper cut that just annoyed me. When editing a
larger simp proof, I usually want to see the goal state after the simp,
and this is what I see while the `simp` command is complete. But then,
when I start typing, and necessarily type incomplete lemma names, that
error makes `simp` do nothing again and I see the original goal state.
In fact, if a prefix of the simp theorem name I am typing is a valid
identifier, it jumps even more around.

With this PR, using `logException`, I still get the red squiggly lines
for the unknown identifer, but `simp` just ignores that argument and
still shows me the final goal. Much nicer.

I also demoted the message for `[-foo]` when `foo` isn’t `simp` to a
warning and gave it the correct `ref`.

See it in action here: (in the middle, when you suddenly see the
terminal,
I am switching lean versions.)


https://github.com/leanprover/lean4/assets/148037/8cb3c563-1354-4c2d-bcee-26dfa1005ae0
2024-06-03 14:21:31 +00:00
Leonardo de Moura
b53a74d6fd
fix: miscompilation in constant folding (#4311)
closes #4306
2024-05-31 04:24:45 +00:00
Leonardo de Moura
8eee5ff27f
fix: do not include internal match equational theorems at simp trace (#4274)
closes #4251
2024-05-25 17:16:19 +00:00
Kim Morrison
b0c1112471
chore: better omega error message if no facts found (#4264) 2024-05-24 05:15:15 +00:00
Leonardo de Moura
2bc41d8f3a
fix: case tactic in macros (#4252)
We must erase macro scopes for tags in `case` as we do in `cases .. with
..` and `induction .. with ..`.
2024-05-23 00:01:24 +00:00
Sebastian Ullrich
f97a7d4234
feat: incremental elaboration of definition headers, bodies, and tactics (#3940)
Extends Lean's incremental reporting and reuse between commands into
various steps inside declarations:
* headers and bodies of each (mutual) definition/theorem
* `theorem ... := by` for each contained tactic step, including
recursively inside supported combinators currently consisting of
  * `·` (cdot), `case`, `next`
  * `induction`, `cases`
  * macros such as `next` unfolding to the above

![Recording 2024-05-10 at 11 07
32](https://github.com/leanprover/lean4/assets/109126/c9d67b6f-c131-4bc3-a0de-7d63eaf1bfc9)

*Incremental reuse* means not recomputing any such steps if they are not
affected by a document change. *Incremental reporting* includes the
parts seen in the recording above: the progress bar and messages. Other
language server features such as hover etc. are *not yet* supported
incrementally, i.e. they are shown only when the declaration has been
fully processed as before.

---------

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
2024-05-22 13:23:30 +00:00
Leonardo de Moura
ff37e5d512
feat: add grind core module (#4249) 2024-05-22 03:50:36 +00:00
Leonardo de Moura
d6709eb157 feat: add [grind_cases] attribute 2024-05-21 21:46:23 +02:00
Leonardo de Moura
e6be8b90f5
feat: add grind.injection (#4243) 2024-05-21 17:57:02 +00:00