I made a few choices so far that can probably be discussed:
- got rid of `modn` on `UInt`, nobody seems to use it apart from the
definition of `shift` which can use normal `mod`
- removed the previous defeq optimized definition of `USize.size` in
favor for a normal one. The motivation was to allow `OfNat` to work
which doesn't seem to be necessary anymore afaict.
- Minimized uses of `.val`, should we maybe mark it deprecated?
- Mostly got rid of `.val` in basically all theorems as the proper next
level of API would now be `.toBitVec`. We could probably re-prove them
but it would be more annoying given the change of definition.
- Did not yet redefine `log2` in terms of `BitVec` as this would require
a `log2` in `BitVec` as well, do we want this?
- I added a couple of theorems around the relation of `<` on `UInt` and
`Nat`. These were previously not needed because defeq was used all over
the place to save us. I did not yet generalize these to all types as I
wasn't sure if they are the appropriate lemma that we want to have.
Adds `pushGoal`/`pushGoals` and `popGoal` for manipulating the goal
state. These are an alternative to `replaceMainGoal` and `getMainGoal`,
and with them you don't need to worry about making sure nothing clears
assigned metavariables from the goal list between assigning the main
goal and using `replaceMainGoal`.
Modifies `closeMainGoalUsing`, which is like a `TacticM` version of
`liftMetaTactic`. Now the callback is run in a context where the main
goal is removed from the goal list, and the callback is free to modify
the goal list. Furthermore, the `checkUnassigned` argument has been
replaced with `checkNewUnassigned`, which checks whether the value
assigned to the goal has any *new* metavariables, relative to the start
of execution of the callback. This API is sufficient for the `exact`
tactic for example.
Modifies `withCollectingNewGoalsFrom` to take the `parentTag` argument
explicitly rather than indirectly via `getMainTag`. This is needed when
used under `closeMainGoalUsing`.
Modifies `elabTermWithHoles` to optionally take `parentTag?`. It
defaults to `getMainTag` if it is `none`.
Renames `Tactic.tryCatch` to `Tactic.tryCatchRestore`, and adds a
`Tactic.tryCatch` that doesn't do backtracking.
---------
Co-authored-by: Kim Morrison <kim@tqft.net>
`getNumHeadForalls` and `getNumHeadLambdas` were both duplicated
downstream with different names; I'll clean up those next.
Also adds `getAppNumArgs'`.
it seems to be unused, arguably even for kernel recursors their type
should be usable with `mkRecursorInfo`, and removing this will help
understand the impact of #5679.
Mathlib has a duplicate of this instance as `Quotient.decidableEq` (with
the same implementation) and refers to it by name a few times, so let's
just rename our version to the mathlib name so that the copy in mathlib
can be dropped.
This takes a few standalone bitvector problems, about inequalties, from
LNSym, and adds them as a benchmark to prevent further regressions with
bv_decide.
These problems are particularly interesting, because they've previously
had a bad interaction with bv_decides normalization pass, see
https://github.com/leanprover/lean4/issues/5664.
---------
Co-authored-by: Henrik Böving <hargonix@gmail.com>
Projects like mathlib like to define projection functions with extra
structure, for example one could imagine defining `Multiset.card :
Multiset α →+ Nat`, which bundles the fact that `Multiset.card (m1 + m2)
= Multiset.card m1 + Multiset.card m2` for all `m1 m2 : Multiset α`. A
problem though is that so far this has prevented dot notation from
working: you can't write `(m1 + m2).card = m1.card + m2.card`.
With this PR, now you can. The way it works is that "LValue resolution"
will apply CoeFun instances when trying to resolve which argument should
receive the object of dot notation.
A contrived-yet-representative example:
```lean
structure Equiv (α β : Sort _) where
toFun : α → β
invFun : β → α
infixl:25 " ≃ " => Equiv
instance: CoeFun (α ≃ β) fun _ => α → β where
coe := Equiv.toFun
structure Foo where
n : Nat
def Foo.n' : Foo ≃ Nat := ⟨Foo.n, Foo.mk⟩
variable (f : Foo)
#check f.n'
-- Foo.n'.toFun f : Nat
```
Design note 1: While LValue resolution attempts to make use of named
arguments when positional arguments cannot be used, when we apply CoeFun
instances we disallow making use of named arguments. The rationale is
that argument names for CoeFun instances tend to be random, which could
lead dot notation randomly succeeding or failing. It is better to be
uniform, and so it uniformly fails in this case.
Design note 2: There is a limitation in that this will *not* make use of
the values of any of the provided arguments when synthesizing the CoeFun
instances (see the tests for an example), since argument elaboration
takes place after LValue resolution. However, we make sure that
synthesis will fail rather than choose the wrong CoeFun instance.
Performance note: Such instances will be synthesized twice, once during
LValue resolution, and again when applying arguments.
This also adds in a small optimization to the parameter list computation
in LValue resolution so that it lazily reduces when a relevant parameter
hasn't been found yet, rather than using `forallTelescopeReducing`. It
also switches to using `forallMetaTelescope` to make sure the CoeFun
synthesis will fail if multiple instances could apply.
Getting this to pretty print will be deferred to future work.
Closes#1910
Gives more control over pretty printing metavariables.
- When `pp.mvars.levels` is false, then universe level metavariables
pretty print as `_` rather than `?u.22`
- When `pp.mvars.anonymous` is false, then anonymous metavariables
pretty print as `?_` rather than `?m.22`. Named metavariables still
pretty print with their names. When this is false, it also sets
`pp.mvars.levels` to false, since every level metavariable is anonymous.
- When `pp.mvars` is false, then all metavariables pretty print as `?_`
or `_`.
Modifies TryThis to use `pp.mvars.anonymous` rather than doing a
post-delaboration modification. This incidentally improves TryThis since
it now prints universe level metavariables as `_` rather than `?u.22`.
We trust that the users read the error messages or tactic docs to
discover the option.
AWS problems have shown that this can be too eager of an operation to
do.
Given that we have the luxury of interactivity let's go for an approach
where the users
can optionally enable it.
This PR ensures that deprecated declarations are displayed with a
strikethrough markup in the completion popup of VS Code and that the
docstring of a completion item denotes the meta-data of the deprecation.
These lemmas are peeled from `leanprover/lnsym`.
Moreover, note that these lemmas only hold when we do not have overflow
in their operands, and thus, we are able to treat the operands as if
they were 'regular' natural numbers.
---------
Co-authored-by: Tobias Grosser <github@grosser.es>
Co-authored-by: Kim Morrison <scott@tqft.net>
Divison proofs are more likely to depend on add/sub/mul proofs than the
other way around. This cleans up
https://github.com/leanprover/lean4/pull/5609, which added division
proofs that rely on negation to already be defined.
Closes#5682
- Removes the broken `-f` flag from the help message which doesn't
behave as expected as an alternative to `--features`.
- Adds the `-g` flag to the help message which is a working alternative
to the `--githash` flag.
Lake will now only automatically fetch Reservoir build caches for
package in the the `leanprover` and `leanprover-community`
organizations. We are not planning to expand the Reservoir build cache
to other packages until farther in the future.
Makes `#eval` use the `elabMutualDef` machinery to process all the `let
rec`s that might appear in the expression. This now works:
```lean
#eval
let rec fact (n : Nat) : Nat :=
match n with
| 0 => 1
| n' + 1 => n * fact n'
fact 5
```
Closes#2374
The `decide!` tactic is like `decide`, but when it tries reducing the
`Decidable` instance it uses kernel reduction rather than the
elaborator's reduction.
The kernel ignores transparency, so it can unfold all definitions (for
better or for worse). Furthermore, by using kernel reduction we can
cache the result as an auxiliary lemma — this is more efficient than
`decide`, which needs to reduce the instance twice: once in the
elaborator to check whether the tactic succeeds, and once again in the
kernel during final typechecking.
While RFC #5629 proposes a `decide!` that skips checking altogether
during elaboration, with this PR's `decide!` we can use `decide!` as
more-or-less a drop-in replacement for `decide`, since the tactic will
fail if kernel reduction fails.
This PR also includes two small fixes:
- `blameDecideReductionFailure` now uses `withIncRecDepth`.
- `Lean.Meta.zetaReduce` now instantiates metavariables while zeta
reducing.
Some profiling:
```lean
set_option maxRecDepth 2000
set_option trace.profiler true
set_option trace.profiler.threshold 0
theorem thm1 : 0 < 1 := by decide!
theorem thm1' : 0 < 1 := by decide
theorem thm2 : ∀ x < 400, x * x ≤ 160000 := by decide!
theorem thm2' : ∀ x < 400, x * x ≤ 160000 := by decide
/-
[Elab.command] [0.003655] theorem thm1 : 0 < 1 := by decide!
[Elab.command] [0.003164] theorem thm1' : 0 < 1 := by decide
[Elab.command] [0.133223] theorem thm2 : ∀ x < 400, x * x ≤ 160000 := by decide!
[Elab.command] [0.252310] theorem thm2' : ∀ x < 400, x * x ≤ 160000 := by decide
-/
```
---------
Co-authored-by: Joachim Breitner <mail@joachim-breitner.de>
Deprecates `inductive ... :=`, `structure ... :=`, and `class ... :=` in
favor of the `... where` variant. Currently this syntax produces a
warning, controlled by the `linter.deprecated` option.
Breaking change: modifies `Lean.Linter.logLintIf` to use
`Lean.Linter.getLinterValue` to determine if a linter value is set. This
means that the `linter.all` option now is taken into account when the
linter option is not set.
Part of #5236
This PR enables tactic completion in the whitespace of a tactic proof
and adds tactic docstrings to the completion menu.
Future work:
- A couple of broken tactic completions: This is due to tactic
completion now using @david-christiansen's `Tactic.Doc.allTacticDocs` to
obtain the tactic docstrings and should be fixed soon.
- Whitespace tactic completion in tactic combinators: This requires
changing the syntax of tactic combinators to produce a syntax node that
makes it clear that a tactic is expected at the given position.
Closes#1651.
When named arguments introduce eta arguments, the full application
contains fvars for these eta arguments, so `MVarErrorKind.implicitArg`
needs to keep a local context for its error messages. This is because
the local context of the mvar associated to the `MVarErrorKind` is not
sufficient, since when an eta argument come after an implicit argument,
the implicit argument's mvar doesn't contain the eta argument's fvar in
its local context.
Closes#5475
Now one can write `@x.f`, `@(x).f`, `@x.1`, `@(x).1`, and so on.
This fixes an issue where structure instance update notation (like `{x
with a := a'}`) could fail if the field `a` had a type with implicit,
optional, or auto parameters.
Closes#5406
Fixes#5565, by using tags instead of trying to string match on a
`MessageData`. This ends up reverting some unwanted test output changes
from #4781 too.
This changes `isMaxRecDepth` for good measure too.
This was a regression in Lean 4.11.0, so may be worth backporting to
4.12.x, if not also 4.11.x.
A Lake build of target within a a package will no longer build a
package's dependencies package-level extra targets dependencies. At the
technical level, a package's `extraDep` facet no longer transitively
builds its dependencies' `extraDep` facet.
Closes#5633.