Commit graph

9508 commits

Author SHA1 Message Date
Kyle Miller
a4d521cf96
fix: make all_goals admit goals on failure (#5934)
New behavior: when in recovery mode, if any tactic fails in `all_goals`
then the metacontext is restored and all goals are admitted.

Without this, it can leave partially-solved metavariables and incomplete
goal lists.
2024-11-04 21:12:59 +00:00
Henrik Böving
93dd6f2b36
feat: add Int16/Int32/Int64 (#5885)
This adds all fixed width integers with the exception of `ssize_t` so
the code is quick to review as everything just behaves the same.
2024-11-04 13:18:05 +00:00
Henrik Böving
c61ced3f15
feat: introduce synthetic atoms in bv_decide (#5942)
This introduces a notion of synthetic atoms into `bv_decide`'s
reflection framework. An atom can be declared synthetic if its behavior
is fully specified by additional lemmas that are added in the process of
creating it. This is for example useful in the code that handles `if` as
the entire `if` block is abstracted as an atom and then two lemmas to
describe either branch are added. Previously this had the effect of
creating error messages about potentially unsound counterexamples, now
the synthetic atoms get filtered from the counter example generation.
2024-11-04 10:14:51 +00:00
Kyle Miller
1659f3bfe2
fix: .. in patterns should not make use of optparams or autoparams (#5933)
In patterns, ellipsis should always fill in each remaining argument as
an implicit argument, even if it is an optparam or autoparam. This
prevents examples such as the one in #4555 from failing:
```lean
match e with
| .internal .. => sorry
| .error .. => sorry
```
The `internal` constructor has an optparam (`| internal (id :
InternalExceptionId) (extra : KVMap := {})`).

We may consider having ellipsis suppress optparams and autoparams in
general. We avoid doing so for now since it's possible to opt-out of
them individually (for example with `.internal (extra := _) ..`) but
it's not possible to opt-in, and it is plausible that `..` with
optparams is useful in contexts such as the `refine` tactic. With
patterns however, it is hard to imagine a use case that offsets the
inconvenience of optparams being eagerly supplied.

Closes #4555
2024-11-03 18:40:21 +00:00
Kyle Miller
b75cc35db2
feat: update omega/solve_by_elim to use new tactic syntax, use new tactic syntax (#5932)
Following up #5928, updates the syntax for `omega` and `solve_by_elim`
and restores the syntax quotations in their implementations.

Following up #5898, uses the new tactic syntax in the library, replacing
all uses of `(config := ...)`.
2024-11-03 16:23:37 +00:00
Alex
16e5e09ffd
feat: better error message for invalid induction alternative name (#5888)
Closes #5887
2024-11-01 21:33:15 +00:00
Kyle Miller
5549e0509f
feat: on "type mismatch" errors, expose differences in functions and pi types (#5922)
Example: Normally subtype notation pretty prints as `{ x // x > 0 }`,
but now the difference in domains is exposed:
```lean
example (h : {x : Int // x > 0}) : {x : Nat // x > 0} := h
/-
error: type mismatch
  h
has type
  { x : Int // x > 0 } : Type
but is expected to have type
  { x : Nat // x > 0 } : Type
-/
```
2024-11-01 18:42:14 +00:00
Kyle Miller
c7f5fd9a83
feat: make "type mismatch" error add numeric type ascriptions (#5919)
Example:
```lean
example : 0 = (0 : Nat) := by
  exact Eq.refl (0 : Int)
/-
error: type mismatch
  Eq.refl 0
has type
  (0 : Int) = 0 : Prop
but is expected to have type
  (0 : Nat) = 0 : Prop
-/
```
2024-11-01 16:44:52 +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
Kim Morrison
e4a2c3d8f0
feat: interim implementation of HashMap.modify/alter (#5880)
These implementations could be made more efficient by promoting them to
primitive operations, but I propose installing these in the meantime to
encourage users to avoid non-linearity problems.
2024-11-01 01:21:21 +00:00
Kyle Miller
465ed8af46
feat: resolve generalized field notation using all parents (#5770)
* Now `getPathToBaseStructure?` can navigate to all parent structures,
not just through subobjects.
* Adds a "resolution order" for methods. This is the order that
generalized field notation visits parent structures when trying to
resolve names. The algorithm to compute a resolution order is the
commonly used C3 (used for instance by Python). By default we use a
relaxed version of the algorithm that tolerates inconsistencies. Using
`set_option structure.strictResolutionOrder true` makes inconsistent
parent orderings into warnings.
* This makes generalized field notation be able to resolve names for all
parent structures, not just those that are embedded as subobjects.
Closes #3467. (And addresses side note in #1881.)
* Modifies `getAllParentStructures` to return *all* parents. This
improves dot completion in the editor.
2024-10-31 21:04:50 +00:00
Joachim Breitner
008537abbd
fix: FunInd: unfold aux definitions more carefully (#5904)
fixes #5903
2024-10-31 18:04:36 +00:00
Henrik Böving
844e7ae7eb
chore: remove native code for UInt8.modn (#5901)
Closes #5818
2024-10-31 12:42:24 +00:00
Kim Morrison
a826de8a3d
chore: remove duplicated ForIn instances (#5892)
I'd previously added an instance from `ForIn'` to `ForIn`, but this then
caused some non-defeq duplication. It seems fine to just remove the
concrete `ForIn` instances in cases where the `ForIn'` instance exists
too. We can even remove a number of type-specific lemmas in favour of
the general ones.
2024-10-31 07:40:09 +00:00
Kyle Miller
0fcee100e7
feat: enable recursive structure command (#5783)
Now that the elaborator supports primitive projections for recursive
inductive types (#5822), enable defining recursive inductive types with
the `structure` command, which was set up in #5842.

Example:
```lean
structure Tree where
  n : Nat
  children : Fin n → Tree

def Tree.size : Tree → Nat
  | {n, children} => Id.run do
    let mut s := 0
    for h : i in [0 : n] do
      s := s + (children ⟨i, h.2⟩).size
    pure s
```

Note for kernel re-implementors: recursive structures are exercising the
kernel feature where primitive projections are valid for one-constructor
inductive types in general, so long as the structure isn't a `Prop` and
doesn't have any non-`Prop` fields, not just ones that are non-indexed
and non-recursive.

Closes #2512
2024-10-31 05:23:12 +00:00
Kyle Miller
03c6e99ef7
fix: bring elaborator in line with kernel for primitive projections (#5822)
The kernel supports primitive projections for all inductive types with
one construtor. The elaborator was assuming primitive projections only
work for "structure-likes", non-recursive inductive types with no
indices.

Enables numeric projection notation for general one-constructor
inductives.

Extracted from #5783.
2024-10-31 03:16:52 +00:00
Kyle Miller
d4b1be094d
feat: adds optConfig syntax for tactic configuration (#5883)
This PR adds a new syntax for tactic and command configurations. It also
updates the elaborator construction command to be able to process this
new syntax.

We do not update core tactics yet. Once tactics switch over to it,
rather than (for example) writing `simp (config := { contextual := true,
maxSteps := 22})`, one can write `simp +contextual (maxSteps := 22)`.
The new syntax is reverse compatible in the sense that `(config := ...)`
still sets the entire configuration.

Note to metaprogrammers: Use `optConfig` instead of `(config)?`. The
elaborator generated by `declare_config_elab` accepts both old and new
configurations. The elaborator has also been written to be tolerant to
null nodes, so adapting to `optConfig` should be as easy as changing
just the syntax for your tactics and deleting `mkOptionalNode`.

Breaking change: The new system is mostly reverse compatible, however
the type of the generated elaborator now lands in `TacticM` to make use
of the current recovery state. Commands that wish to elaborate
configurations should now use `declare_command_config_elab` instead of
`declare_config_elab` to get an elaborator landing in `CommandElabM`.
2024-10-30 23:31:34 +00:00
Kyle Miller
c3cbc92a0c
feat: upstream and update #where command (#5065)
This command comes from Lean 3, which I had previously ported and
contributed to Batteries (née Std). In this new version, `#where`
produces actual command Syntax for all features of a top-level scope
(rather than splicing together strings), and it also now reports
included variables.

---------

Co-authored-by: Kim Morrison <kim@tqft.net>
2024-10-30 18:00:08 +00:00
Joachim Breitner
0d12618539
fix: declareSimpLikeTactic macro to use mkSynthetic (#5838)
this fixes #5597
2024-10-30 14:27:56 +00:00
Kyle Miller
cdbe29b46d
feat: accurate binder names in signatures (like in output of #check) (#5827)
An important part of the interface of a function is the parameter names,
for making used of named arguments. This PR makes the parameter names
print in a reliable way. The parameters of the type now appear as
hygienic names if they cannot be used as named arguments.

Modifies the heuristic for how parameters are chosen to appear before or
after the colon. The rule is now that parameters start appearing after
the colon at the first non-dependent non-instance-implicit parameter
that has a name unusable as a named argument. This is a refinement of
#2846.

Fixes the issue where consecutive hygienic names pretty print without a
space separating them, so we now have `(x✝ y✝ : Nat)` rather than `(x✝y✝
: Nat)`.

Breaking change: `Lean.PrettyPrinter.Formatter.pushToken` now takes an
additional boolean `ident` argument, which should be `true` for
identifiers. Used to insert discretionary space between consecutive
identifiers.

Closes #5810
2024-10-29 16:43:11 +00:00
Joachim Breitner
6514385bb9
feat: attribute [simp ←] (#5870)
This adds the ability to add the converse direction of a rewrite rule
not just in simp arguments `simp [← thm]`, but also as a global
attribute

```lean
attribute [simp ←] thm
```

This fixes #5828.

This can be undone with `attribute [-simp]`, although note that
`[-simp]` wins and cannot be undone at the moment (#5868).

Like `simp [← thm]` (see #4290), this will do an implicit `attribute
[-simp] thm` if the other direction is already defined.
2024-10-29 11:07:08 +00:00
Kyle Miller
1437033e69
fix: prevent addPPExplicitToExposeDiff from assigning metavariables (#5276)
Type mismatch errors have a nice feature where expressions are annotated
with `pp.explicit` to expose differences via `isDefEq` checking.
However, this procedure has side effects since `isDefEq` may assign
metavariables. This PR wraps the procedure with `withoutModifyingState`
to prevent assignments from escaping.

Assignments can lead to confusing behavior. For example, in the
following a higher-order unification fails, but the difference-finding
procedure unifies metavariables in a naive way, producing a baffling
error message:
```lean
theorem test {f g : Nat → Nat} (n : Nat) (hfg : ∀a, f (g a) = a) :
    f (g n) = n := hfg n

example {g2 : ℕ → ℕ} (n2 : ℕ) : (λx => x * 2) (g2 n2) = n2 := by
  with_reducible refine test n2 ?_
  /-
  type mismatch
    test n2 ?m.648
  has type
    (fun x ↦ x * 2) (g2 n2) = n2 : Prop
  but is expected to have type
    (fun x ↦ x * 2) (g2 n2) = n2 : Prop
  -/
```
With the change, it now says `has type ?m.153 (?m.154 n2) = n2`.

Note: this uses `withoutModifyingState` instead of `withNewMCtxDepth`
because we want to know something about where `isDefEq` failed — we are
trying to simulate a very basic version of `isDefEq` for function
applications, and we want the state at the point of failure to know
which argument is "at fault".
2024-10-28 22:51:41 +00:00
Kyle Miller
b308f2bb55
fix: let simp arguments elaborate with error recovery (#5863)
Modifies `simp` to elaborate all simp arguments without disabling error
recovery. Like in #4177, simp arguments with elaboration errors are not
added to the simp set. Error recovery is still disabled when `simp` is
used in combinators such as `first`.

This enables better term info and features like tab completion when
there are elaboration errors.

Also included is a fix to the `all_goals` and `<;>` tactic combinators.
Recall that `try`/`catch` for the Tactic monad restores the state on
failure. This meant that all messages were being cleared on tactic
failure. The fix is to use `Tactic.tryCatch` instead, which doesn't
restore state.

Part of addressing #3831

Closes #4888
2024-10-28 21:39:03 +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
19bebfc22f
feat: improved calc error messages (#5719)
Makes the error messages report on RHSs and LHSs that do not match the
expected values when the relations are defeq. If the relations are not
defeq, the error message now no longer mentions the value of the whole
`calc` expression.

Adds a field to `mkCoe` with an optional callback to use to generate
error messages.

Note: it is tempting to try to make use of expected types when
elaborating the `calc` expression, but this runs into issue #2073.

Closes #4318
2024-10-28 20:38:45 +00:00
Henrik Böving
c57d054b87
feat: support all the SMTLIB BitVec divison/remainder operations in bv_decide (#5869) 2024-10-28 16:37:06 +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
9847923f9b
feat: record all structure parents in StructureInfo (#5853)
Followup to #5841. Makes the `structure` command populate the new
`parentInfo` field with all the structures in the `extends` clause.

This will require a stage0 update to fully take effect.

Breaking change: now it's a warning if a structure extends a parent
multiple times.

Breaking change: now `getParentStructures` is `getStructureSubobjects`.
Adds `getStructureParentInfo` for getting all the immediate parents.
Note that the set of subobjects is neither a subset nor a superset of
the immediate parents.

Closes #1881
2024-10-28 01:23:48 +00:00
Kyle Miller
709ea6cdf8
feat: make it possible to use dot notation in m! strings (#5857)
This default instance makes it possible to write things like `m!"the
constant is {.ofConstName n}"`.

Breaking change: This weakly causes terms to have a type of
`MessageData` if their type is otherwise unknown. For example:
* `m!"... {x} ..."` can cause `x` to have type `MessageData`, causing
the `let` definition of `x` to fail to elaborate. Fix: give `x` an
explicit type.
* Arithmetic expressions in `m!` strings may need a type ascription. For
example, if the type of `i` is unknown at the time the arithmetic
expression is elaborated, then `m!"... {i + 1} ..."` can fail saying
that it cannot find an `HAdd Nat Nat MessageData` instance. Two fixes:
either ensure that the type of `i` is known, or add a type ascription to
guide the `MessageData` coercion, like `m!"... {(i + 1 : Nat)} ..."`.
2024-10-27 22:55:29 +00:00
Henrik Böving
8c7f7484f9
feat: if support and more in bv_decide (#5855)
Using the same strategy as #5852 this provides `bv_decide` support for
`Bool` and `BitVec` ifs
this in turn instantly enables support for:
- `sdiv`
- `smod`
- `abs`

and thus closes our last discrepancies to QF_BV!
2024-10-27 08:40:38 +00:00
Kyle Miller
c50f04ace0
feat: add delaborators for <|>, <*>, >>, <*, and *> (#5854)
Closes #5668
2024-10-26 23:49:16 +00:00
Henrik Böving
8b5443eb22
feat: support BitVec.ofBool in bv_decide (#5852)
This is the first step towards fixing the issue of not having mutual
recursion between the `Bool` and `BitVec` fragment of `QF_BV` in
`bv_decide`. This PR adds support for `BitVec.ofBool` by doing the
following:
1. Introduce a new mechanism into the reification engine that allows us
to add additional lemmas to the top level on the fly as we are
traversing the expression tree.
2. If we encounter an expression `BitVec.ofBool boolExpr` we reify
`boolExpr` and then abstract `BitVec.ofBool boolExpr` as some atom `a`
3. We add two lemmas `boolExpr = true -> a = 1#1` and `boolExpr = false
-> a = 0#1`. This mirrors the full behavior of `BitVec.ofBool` and thus
makes our atom `a` correctly interpreted again.

In order to do the reification in step 2 mutual recursion in the
reification engine is required. For this reason I started pulling out
logic from the, now rather large, mutual block into other files and
document the invariants that they assume explicitly.
2024-10-26 19:08:07 +00:00
Joachim Breitner
38490a4ac7
refactor: Predefinition.Structural code cleanup (#5850)
useful bits from the shelved #5849
2024-10-26 10:21:47 +00:00
Kyle Miller
13036655e9
fix: reduce types when constructing default values in structure instance notation (#5844)
A step of expanding structure instances is to determine all the default
values, and part of this is reducing projections that appear in the
default values so that they get replaced with the user-provided values.
Binder types in foralls, lambdas, and lets have to be reduced too.

Closes #2186
2024-10-26 00:45:21 +00:00
Kyle Miller
abe6d5bca7
fix: declaration ranges changed after stage0 update (#5845)
Recently declaration ranges have changed slightly to include attribute
lists. Fixes a test that broke.
2024-10-25 21:38:06 +00:00
Kyle Miller
a310488b7f
chore: refactor structure command, fixes (#5842)
Refactors the `structure` command to support recursive structures. These
are disabled for now, pending additional elaborator support in #5822.
This refactor is also a step toward `structure` appearing in `mutual`
blocks.

Error reporting is now more precise, and this fixes an issue where
general errors could appear on the last field. Adds "don't know how to
synthesize placeholder" errors for default values.

Closes #2512
2024-10-25 19:46:17 +00:00
Joachim Breitner
57a95c8b5f
test: test case for #5836 (#5843) 2024-10-25 19:34:09 +00:00
Kim Morrison
4c0d12b3f1
chore: cleanup some deprecations in tests (#5834) 2024-10-25 11:11:22 +00:00
Kim Morrison
07ea626560
feat: Array.forIn', and relate to List (#5833)
Adds support for `for h : x in my_array do`, and relates this to the
existing `List` version.
2024-10-25 07:24:39 +00:00
Henrik Böving
193b6f2bec
feat: define Int8 (#5790) 2024-10-25 06:06:40 +00:00
Yann Herklotz
19ce2040a2
fix: wildcard generalize only generalizes visible theorems (#4846)
`generalize ... at *` sometimes will try to modify the recursive
hypothesis corresponding to the current theorem being defined, which may
not be the expected behaviour. It should only try to `generalize`
hypotheses that it can actually modify and are visible, not
implementation details. Otherwise this means that there are
discrepancies between `generalize ... at *` and `generalize ... at H`,
even though `H` is the only hypothesis in the context.

This commit uses `getLocalHyps` instead of `getFVarIds` to get the
current valid `FVarIds` in the context. This uses
`isImplementationDetail` to filter out `FVarIds` that are implementation
details in the context and are not visible to the user and should not be
manipulated by `generalize`.

Closes #4845
2024-10-25 05:09:28 +00:00
Arthur Adjedj
7150a0d538
fix: reduce let-bodies correctly in StructInst (#3152)
Closes #3146

Reduction doesn't trigger correctly on the bodies of `let`-expressions
in `StructInst`, leading some meta-variables to linger in the terms of
some fields. Because of this, default fields may try multiple times (and
fail) to be generated, leading to an unexpected error.

The solution implemented here is to modify the values of the introduced
variables in the local context so as to reduce them correctly.
2024-10-24 23:33:33 +00:00
Kyle Miller
e07272a53a
chore: review delaborators, make sure they respond to pp.explicit (#5830)
Rule: if an expression contains an implicit argument that the
delaborator would omit, only use the delaborator if `pp.explicit` is
false.
2024-10-24 22:56:47 +00:00
Sebastian Ullrich
9157c1f279
test: big_omega benchmark (#5817)
Extracted from #5614
2024-10-24 07:26:29 +00:00
Henrik Böving
8822b0fca7
feat: bv_decide BitVec.sdiv (#5823) 2024-10-23 21:10:27 +00:00
Kyle Miller
249530f3c1
feat: partial inhabitation uses local Inhabited instances created from parameters (#5821)
Rather than having a special pass where `mkInhabitantFor` uses the
`assumption` tactic, it creates `Inhabited` instances for each parameter
and just searches for an `Inhabited`/`Nonempty` instance for the return
type.

This makes examples like the following work:
```lean
partial def f (x : X) : Bool × X := ...
```

Removes the strategy where it looks for `Inhabited`/`Nonempty` instances
for every suffix of the signature.

This is a follow-up to #5780. Motivated [by
Zulip](https://leanprover.zulipchat.com/#narrow/channel/113489-new-members/topic/Why.20return.20type.20of.20partial.20function.20MUST.20.60inhabited.60.3F/near/477905312).
2024-10-23 18:15:31 +00:00
Aaron Tomb
45b1b367ca
test: add a benchmark that is slow to elaborate (#5656)
Add an example Lean file that includes an unusually large definition
that takes a long time to elaborate.

It may be that it's difficult to process it more efficiently, but
perhaps someone will discover a way to improve it if it's in the
benchmark suite. Improved performance on this benchmark will likely make
some program analysis and verification tasks within Lean more feasible.

---------

Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2024-10-23 08:20:15 +00:00
Kyle Miller
66dbad911e
fix: improve error message for partial inhabitation and add delta deriving (#5780)
Example new output:
```text
failed to compile 'partial' definition 'checkMyList', could not prove that the type
  ListNode → Bool × ListNode
is nonempty.

This process uses multiple strategies:
- It looks for a parameter that matches the return type.
- It tries synthesizing 'Inhabited' and 'Nonempty' instances for the return type.
- It tries unfolding the return type.

If the return type is defined using the 'structure' or 'inductive' command, you can try
adding a 'deriving Nonempty' clause to it.
```
The inhabitation prover now also unfolds definitions when trying to
prove inhabitation. For example,
```lean
def T (α : Type) := α × α

partial def f (n : Nat) : T Nat := f n
```

Motivated [by
Zulip](https://leanprover.zulipchat.com/#narrow/channel/113489-new-members/topic/Why.20return.20type.20of.20partial.20function.20MUST.20.60inhabited.60.3F/near/477905312)
2024-10-23 06:32:11 +00:00
Kyle Miller
83129b7e3a
fix: inductive elaboration should keep track of universe level parameters created in binders (#5814)
Refactors `inductive` elaborator to keep track of universe level
parameters created during elaboration of `variable`s and binders. This
fixes an issue in Mathlib where its `Type*` elaborator can result in
unexpected universe levels.

For example, in
```lean4
variable {F : Type*}
inductive I1 (A B : Type*) (x : F) : Type
```
before this change the signature would be
```
I1.{u_1, u_2} {F : Type u_1} (A : Type u_1) (B : Type u_2) (x : F) : Type
```
but now it is
```
I1.{u_1, u_2, u_3} {F : Type u_1} (A : Type u_2) (B : Type u_3) (x : F) : Type
```
Fixes this for the `axiom` elaborator too.

Adds more accurate universe level validation for mutual inductives.

Breaking change: removes `Lean.Elab.Command.expandDeclId`. Use
`Lean.Elab.Term.expandDeclId` from within `runCommandElabM`.
2024-10-23 04:07:40 +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