Commit graph

8975 commits

Author SHA1 Message Date
Kyle Miller
41d310ab39
fix: solveByElim would add symm hypotheses to local context and make impossible-to-elaborate terms (#3962)
Rather than adding symm hypotheses to the local context, it now adds
them to the list of hypotheses derived from the local context.

This is not ideal for performance reasons, but it at least closes #3922.

In the future, solveByElim could maintain its own cache of facts that it
updates whenever it does intro.
2024-04-22 04:13:22 +00:00
Arthur Adjedj
6ad28ca446
feat: add inductive.autoPromoteIndices option (#3590)
This PR partly addresses #3458, by adding an option `autoPromoteIndices`
to turn off the promotion of fixed indices to parameters. The actual fix
for the issue is in a separate PR #3591.

Because nested inductive datatypes parameters cannot contain local
variables, it is often desirable for a fixed index to not be promoted,
as to allow free variables in that place. See example in `3458_1.lean`
2024-04-22 03:42:22 +00:00
Leonardo de Moura
3dd398a8a4
perf: improve isDefEq for contraints of the form t.i =?= s.i (#3965)
We now use lazy delta reduction at `t` and `s`.
See new test for motivation.
2024-04-22 00:41:34 +00:00
Kim Morrison
ac0f699775
perf: improve heuristic at isDefEq (#3837)
This is intended to fail at present: it just adds a test case containing
a minimization of a Mathlib slowdown from #3807.

Prior to #3807, the declaration `exists_algHom_adjoin_of_splits'''` at
the end of the file would take around 16,000 heartbeats. Now it takes
around 210,000 heartbeats.

---------

Co-authored-by: Leonardo de Moura <leomoura@amazon.com>
2024-04-21 23:27:44 +00:00
Mario Carneiro
62cdb51ed5
feat: UTF-8 string validation (#3958)
Previously, there was a function `opaque fromUTF8Unchecked : ByteArray
-> String` which would convert a list of bytes into a string, but as the
name implies it does not validate that the string is UTF-8 before doing
so and as a result it produces unsound results in the compiler (because
the lean model of `String` indirectly asserts UTF-8 validity). This PR
replaces that function by
```lean
opaque validateUTF8 (a : @& ByteArray) : Bool

opaque fromUTF8 (a : @& ByteArray) (h : validateUTF8 a) : String
```
so that while the function is still "unchecked", we have a proof witness
that the string is valid. To recover the original, actually unchecked
version, use `lcProof` or other unsafe methods to produce the proof
witness.

Because this was the only `ByteArray -> String` conversion function, it
was used in several places in an unsound way (e.g. reading untrusted
input from IO and treating it as UTF-8). These have been replaced by
`fromUTF8?` or `fromUTF8!` as appropriate.
2024-04-20 18:36:37 +00:00
Kim Morrison
f23be4a964
feat: upstream false_or_by_contra tests (2nd attempt) (#3949) 2024-04-19 08:09:50 +00:00
Kim Morrison
d1a42aae2a
chore: remove @ from rw? suggestions, and enable hover on constants in #check (#3911)
* Replaces the unused `Lean.PrettyPrinter.ppConst` with
`MessageData.ofConst` (which similarly avoids an unnecessary `@`) and
that further generates a hover for the constant

* Uses this in `TryThis.addRewriteSuggestion`, so that `rw?` suggestions
don't have unnecessary `@`s.

* Add `MessageData.signature`, as a wrapper around
`PrettyPrinter.signature`, using the same machinery to generate hovers
for constants, improving the hover behaviour in #check so that we get
second order pop-up for constants in the signature. (Not sure how to
write tests for second order hovers, so there is no test for this.)
2024-04-19 01:27:02 +00:00
David Thrane Christiansen
b6d77be6a5
feat: show diffs when #guard_msgs fails (#3912)
Adds the ability to show a diff when `guard_msgs` fails, using the
histogram diff algorithm pioneered in jgit. This algorithm tends to
produce more user-friendly diffs, but it can be quadratic in the worst
case. Empirically, the quadratic case of this implementation doesn't
seem to be slow enough to matter for messages smaller than hundreds of
megabytes, but if it's ever a problem, we can mitigate it the same way
jgit does by falling back to Myers diff.

See lean/run/guard_msgs.lean in the tests directory for some examples of
its output.
2024-04-18 15:09:44 +00:00
Henrik Böving
11ff00439e
feat: make linter options more explicitly discoverable (#3938)
Closes #3937
2024-04-18 07:20:55 +00:00
Joachim Breitner
4f50544242
chore: Nat.repr microbenchmark (#3888) 2024-04-17 18:10:32 +00:00
Kyle Miller
627a0f308b
fix: add unused variables ignore function for #guard_msgs (#3931)
The `#guard_msgs` command already runs linters by virtue of using
`elabCommandTopLevel`, so linters should *not* be run on `#guard_msgs`
itself. While we could use a more general solution, of the linters the
unused variables linter is the noisiest one, and it's easy enough to
make it not report messages for `#guard_msgs`.
2024-04-17 15:30:17 +00:00
Kyle Miller
036b5381f0
fix: make tests be aware of new instance names (#3936)
#3089 caused the stage0 update to cause a number of tests to start
failing because they were using the old instance names.
2024-04-17 16:14:51 +02:00
Joachim Breitner
784972462a
feat: omega: more helpful error messages (#3847)
while trying to help a user who was facing an unhelpful
```
omega did not find a contradiction:
[0, 0, 0, 0, 1, -1] ∈ [1, ∞)
[0, 0, 0, 0, 0, 1] ∈ [0, ∞)
[0, 0, 0, 0, 1] ∈ [0, ∞)
[1, -1] ∈ [1, ∞)
[0, 0, 0, 1] ∈ [0, ∞)
[0, 1] ∈ [0, ∞)
[1] ∈ [0, ∞)
[0, 0, 0, 1, 1] ∈ [-1, ∞)
```
I couldn’t resist and wrote a pretty-printer for these problem that
shows the linear combination as such, and includes the recognized atoms.
This is especially useful since oftem `omega` failures stem from failure
to recognize atoms as equal. In this case, we now get:

```
omega-failure.lean:19:2-19:7: error: omega could not prove the goal:
a possible counterexample may satisfy the constraints
  d - e ≥ 1
  e ≥ 0
  d ≥ 0
  a - b ≥ 1
  c ≥ 0
  b ≥ 0
  a ≥ 0
  c + d ≥ -1
where
 a := ↑(sizeOf xs)
 b := ↑(sizeOf x)
 c := ↑(sizeOf x.fst)
 d := ↑(sizeOf x.snd)
 e := ↑(sizeOf xs)
```
and this might help the user make progress (e.g. by using `case x`
first, and investingating why `sizeOf xs` shows up twice)
2024-04-16 15:11:51 +00:00
Joachim Breitner
c0fbcc76c4
feat: FunInd: reserve name .mutual_induct (#3898) 2024-04-16 11:59:40 +00:00
Sebastian Ullrich
6712913bfe chore: update cross-bench setup 2024-04-15 10:59:07 +02:00
Kyle Miller
1c20b53419
feat: shorten auto-generated instance names (#3089)
Implements a new method to generate instance names for anonymous
instances that uses a heuristic that tends to produce shorter names. A
design goal is to make them relatively unique within projects and
definitely unique across projects, while also using accessible names so
that they can be referred to as needed, both in Lean code and in
discussions.

The new method also takes into account binders provided to the instance,
and it adds project-based suffixes. Despite this, a median new name is
73% its original auto-generated length. (Compare: [old generated
names](https://gist.github.com/kmill/b72bb43f5b01dafef41eb1d2e57a8237)
and [new generated
names](https://gist.github.com/kmill/393acc82e7a8d67fc7387829f4ed547e).)

Some notes:
* The naming is sensitive to what is explicitly provided as a binder vs
what is provided via a `variable`. It does not make use of `variable`s
since, when names are generated, it is not yet known which variables are
used in the body of the instance.
* If the instance name refers to declarations in the current "project"
(given by the root module), then it does not add a suffix. Otherwise, it
adds the project name as a suffix to protect against cross-project
collisions.
* `set_option trace.Elab.instance.mkInstanceName true` can be used to
see what name the auto-generator would give, even if the instance
already has an explicit name.

There were a number of instances that were referred to explicitly in
meta code, and these have been given explicit names.

Removes the unused `Lean.Elab.mkFreshInstanceName` along with the
Command state's `nextInstIdx`.

Fixes #2343
2024-04-13 18:08:50 +00:00
Kyle Miller
c4bfe25d18
feat: make rcases use the custom Nat eliminator (#3747)
As a special case, makes the `rcases` machinery use `Nat.casesAuxOn` so
that goal states see `0` and `n + 1` rather than `Nat.zero` and
`Nat.succ n`. This is a followup to enabling custom eliminators for
`cases` and `induction`.

This doesn't use custom eliminators in general since `rcases` uses
`Lean.MVarId.cases`, which is completely different from what `cases` and
`induction` use.
2024-04-13 16:55:48 +00:00
Kyle Miller
eef928b98d
feat: whitespace and message ordering configurations for #guard_msgs (#3883)
Adds options to control whitespace normalization and message ordering in
`#guard_msgs`.

Examples:
1. `#guard_msgs (whitespace := lax)` ignores differences in whitespace
completely.
2. `#guard_msgs (whitespace := exact)` requires an exact match for
whitespace (after trimming).
3. `#guard_msgs (ordering := sorted)` sorts the list of messages, to
make it insensitive to message order.
2024-04-13 08:53:43 +00:00
Mario Carneiro
fb82428f2d
feat: hover / go-to-def for attribute cmd (#3896)
`attribute [attr] foo` was missing a hover on `foo`.
2024-04-13 07:13:25 +00:00
Joachim Breitner
280525f1fc
fix: omega: ignore levels in canonicalizer (#3853)
fixes #3848
2024-04-10 08:46:07 +00:00
Joe Hendrix
a82f0d9413
fix: offset typeclass checking in simp rules (#3838)
This changes how Nat typeclass checks in offset terms from syntactic
equality to definitional equality with "instances" transparency.

This may have a negative performance penalty in `isOffset?`, but it
should be small in common cases since the relevant instances are small
terms.

This closes #3836
2024-04-07 13:43:59 +00:00
thorimur
182270f8bf
fix: typo in withSetOptionIn (#3806)
When using `withSetOptionIn` on syntax `set_option ... in <command>`,
recurse into command syntax (`stx[2]`) instead of the syntax `in`
(`stx[1]`).

---

Demonstration of `stx[1]` vs. `stx[2]`:
```lean
import Lean

def stx := (Lean.Unhygienic.run `(set_option trace.debug true in #print foo)).raw

#eval stx[1] -- Lean.Syntax.atom (Lean.SourceInfo.none) "in"
#eval stx[2] -- `#print` command syntax
```
2024-04-06 18:00:34 +00:00
Joe Hendrix
f31c395973
fix: replace unary Nat.succ simp rules with simprocs (#3808)
This removes simp attributes from `Nat.succ.injEq` and
`Nat.succ_sub_succ_eq_sub` to replace them with simprocs. This is
because any reductions involving `Nat.succ` has a high risk of leading
proof performance problems when dealing with even moderately large
numbers.

Here are a couple examples that will both report a maximum recursion
depth error currently. These examples are fixed by this PR.

```
example : (123456: Nat) = 12345667 := by
  simp

example (x : Nat) (p : x = 0) : 1000 - (x + 1000) = 0 := by
  simp
```
2024-04-04 23:15:26 +00:00
Mario Carneiro
e41cd310e9
fix: String.splitOn bug (#3832)
Fixes #3829. As reported on Zulip (both
[recently](https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/current.20definition.20of.20.60String.2EsplitOn.60.20is.20incorrect/near/430930535)
and [a year
ago](https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/should.20we.20redefine.20.60String.2EsplitOnAux.60.3F/near/365899332)),
`String.splitOn` has a bug when dealing with separators of more than one
character (which are luckily rare). The code change here is very small,
replacing a `i` with `i - j`, but it makes termination more complex so
that's where the rest of the line count goes.
2024-04-04 09:30:53 +00:00
Scott Morrison
f3121b0427
fix: omega works as a simp discharger (#3828)
Possibly the more principled fix is to not have `simp` invoke
dischargers under `withReducible`.

In the meantime, this ensures that `falseOrByContra` still succeeds with
`intro1` on a `Not` goal, which previously was breaking `omega` as a
simp discharger.

Closes #3805.
2024-04-03 03:00:00 +00:00
Marc Huisinga
ecf0459122
fix: don't use info nodes before cursor for completion (#3778)
This fixes an issue where the completion would use info nodes before the
cursor for computing completions.

Fixes https://github.com/leanprover/lean4/issues/3462.

ToDo:
- [x] Fix test failures for completions that previously worked by
accident (cc: @Kha)
- [x] stage0 update

---------

Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2024-04-02 08:49:24 +00:00
Joe Hendrix
eacb1790b3
feat: weight lazy discriminator tree results early matches (#3818)
The matches returned by the lazy discriminator tree are partially
constrained by a priority, but ties are broken by the order in which
keys are traversed and the order of declarations.

This PR changes the match key traversal to use an explicit stack rather
than recursion and implicitly changes the order in which results are
returned to favor left-matches first e.g., given the term `f a b` with
constants `f a b`, and a tree with patterns `f a x -> 1` `f x b -> 2`
that have the same priority, this will return `#[1, 2]` since the early
matches for the key `a` are returned before the match for `x` which has
a star.

This appears to address the [lower quality results mentioned on
zulip](https://leanprover.zulipchat.com/#narrow/stream/428973-nightly-testing/topic/Mathlib.20status.20updates/near/429955747).
2024-04-02 07:19:30 +00:00
Leonardo de Moura
c0027d3987
fix: simp only should break Char literals (#3824)
closes #3686
2024-04-02 03:11:40 +00:00
Leonardo de Moura
82ae779218
fix: missing test at addDocString (#3823)
closes #3497
2024-04-02 02:29:14 +00:00
Leonardo de Moura
f35fc18c88
fix: simp usedSimps (#3821)
When `discharge?` failed, the `usedSimps` was being restored, but the
cache wasn't. This bug was exposed by issue #3710.

This PR makes the following changes:
- We restore the `cache` at `discharge?`. We use `SMap` to ensure the
operation is efficient.
- We don't need the field `dischargeDepth` anymore at `Simp.Result`.
- `UsedSimps` should use `PHashMap` since it is not used linearly.

closes #3710

---------

Co-authored-by: Mario Carneiro <di.gama@gmail.com>
2024-04-02 00:50:06 +00:00
Leonardo de Moura
0684c95d35
fix: do not lift (<- ...) over pure if-then-else (#3820)
Now, only `(<- ...)`s occurring in the condition of a pure if-then-else
are lifted.
That is, `if (<- foo) then ... else ...` is ok, but `if ... then (<-
foo) else ...` is not. See #3713

closes #3713 

This PR also adjusts this repo. Note that some of the `(<- ...)` were
harmless since they were just accessing some
read-only state.
2024-04-01 21:33:59 +00:00
Leonardo de Moura
a440e63435
fix: loose bound variables at ACLt (#3819)
Closes #3705 

This PR also fixes a performance issue at `ACLt` also exposed by example
at #3705
2024-04-01 20:26:20 +00:00
Leonardo de Moura
4a317ae3f8
fix: .yesWithDeltaI behavior (#3816)
It should not increase the transparency level from `reducible` to
`instances`. See new test.
2024-04-01 02:36:35 +00:00
Leonardo de Moura
0ba21269e8
fix: matcher splitter is code (#3815)
It have to keep it as a private definition for now. We currently only
support duplicate theorems in different modules. Splitters are generated
on demand, and are also used to write code.
2024-04-01 02:14:14 +00:00
Leonardo de Moura
d8d64f1fc0
perf: isDefEq performance issue (#3807)
Fixes a performance problem found by @hargoniX while working on LeanSAT.
2024-03-30 02:15:48 +00:00
Kyle Miller
9cb114eb83
feat: add pp.mvars and pp.mvars.withType (#3798)
* Setting `pp.mvars` to false causes metavariables to pretty print as
`?_`.
* Setting `pp.mvars.withType` to true causes metavariables to pretty
print with type ascriptions.

Motivation: when making tests, it is inconvenient using `#guard_msgs`
when there are metavariables, since the unique numbering is subject to
change.

This feature does not use `⋯` omissions since a metavariable is already
in a sense an omitted term. If repeated metavariables do not appear in
an expression, there is a chance that a term pretty printed with
`pp.mvars` set to false can still elaborate to the correct term, unlike
for other omissions.

(In the future we could consider an option that pretty prints uniquely
numbered metavariables as `?m✝`, `?m✝¹`, `?m✝²`, etc. to be able to tell
them apart, at least in the same pretty printed expression. It would
take care to make sure that these names are stable across different
hovers.)

Closes #3781
2024-03-29 18:03:05 +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
Joachim Breitner
97e3257ffd
chore: un-qualify .induct lemmas in tests (#3804)
now that #3803 is fixed.
2024-03-29 11:34:09 +00:00
Leonardo de Moura
7a93a7b877
fix: reserved name resolution (#3803)
This PR includes the following fixes:

- Reserved name resolution inside namespaces
- Equation theorems for `match`er declarations are not private anymore
- Equation theorems for `match`er declarations are realizable
- `foo.match_<idx>.splitter` is now a reserved name
2024-03-29 02:56:48 +00:00
Leonardo de Moura
dee074dcde fix: simp regression introduced by equation theorems for non-recursive definitions 2024-03-28 17:58:33 -07:00
Mac Malone
55b7b07c54
feat: lake: alternative TOML config (#3298)
Adds an alternative TOML configuration format to Lake. 

* Uses TOML v1.0.0 and is fully specification compliant (tested via
[toml-test v1.4.0](https://github.com/toml-lang/toml-test/tree/v1.4.0)).
* Supports package configuration options, Lean libraries, Lean
executables, and dependencies.
* TOML configurations can be generated for new projects via `lake
new|init <pkg> <template>.toml`.
* Supported configurations can be converted to/from TOML via `lake
translate-config <lang>`.
2024-03-28 02:35:02 +00:00
Joe Hendrix
0963f3476c
chore: extend GetElem with getElem! and getElem? (#3694)
This makes changes to the `GetElem` class so that it does not lead to
unnecessary overhead in container like `RBMap`.

The changes are to:
1. Make `getElem?` and `getElem!` part of the `GetElem` class so they
can be overridden in instances.
2. Introduce a `LawfulGetElem` class that contains correctness theorems
for `getElem?` and `getElem!` using the original definitions.
3. Reorganize definitions (e.g, by moving `GetElem` out of
`Init.Prelude`) so that the `GetElem` changes are feasible.
4. Provide `LawfulGetElem` instances to complement all existing
`GetElem` instances in Lean core.

To reduce the size of the PR, this doesn't do the work of providing new
`GetElem` instances for `RBMap`, `HashMap` etc. That will be done in a
separate PR (#3688) that depends on this.

---------

Co-authored-by: Mac Malone <tydeu@hatpress.net>
2024-03-28 01:42:00 +00:00
Kyle Miller
4bacd70b3f
feat: add option tactic.customEliminators to be able to turn off custom eliminators for induction and cases (#3655)
This was suggested by Scott Morrison to be able to help projects adjust
to `Nat` having built-in custom eliminators.
2024-03-28 01:14:17 +00:00
Mario Carneiro
775dabd4ce
fix: toUInt64LE! and toUInt64BE! are swapped (#3660)
fixes #3657

These functions are mostly not used by lean itself, but it does affect
two occurrences of `ByteArray.toUInt64LE! <$> IO.getRandomBytes 8` which
I left as is instead of switching them to use `toUInt64BE!` to preserve
behavior; but they are random bytes anyway seeded by the OS so it's
unlikely any use of them depending on particular values was sound to
begin with.

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
2024-03-28 01:13:42 +00:00
Kyle Miller
520cd3f0d6
fix: make generalized field notation for abbreviation types handle optional parameters (#3746)
Closes #3745
2024-03-28 00:59:09 +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
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