Commit graph

4777 commits

Author SHA1 Message Date
Leonardo de Moura
dd87739fc2
feat: grind normalizers for natCast and intCast (#10313)
This PR adds missing `grind` normalization rules for `natCast` and
`intCast` Examples:
```
open Lean.Grind
variable (R : Type) (a b : R)

section CommSemiring
variable [CommSemiring R]

example (m n : Nat) : (m + n) • a = m • a + n • a := by grind
example (m n : Nat) : (m * n) • a = m • (n • a) := by grind

end CommSemiring

section CommRing
variable [CommRing R]

example (m n : Nat) : (m + n) • a = m • a + n • a := by grind
example (m n : Nat) : (m * n) • a = m • (n • a) := by grind
example (m n : Int) : (m * n) • (a * b) = (m • a) * (n • b) := by grind

end CommRing
```
2025-09-09 01:32:09 +00:00
Kim Morrison
f9b2e550bb
feat: grind annotations for basic monad transformers (#10227)
This PR adds `@[grind]` annotations (nearly all `@[grind =]` annotations
parallel to existing `@[simp]`s) for `ReaderT`, `StateT`, `ExceptT`.
2025-09-08 23:51:55 +00:00
Cameron Zwarich
e86ab1b1db
fix: make IO.RealWorld opaque (#9631)
This PR makes `IO.RealWorld` opaque. It also adds a new compiler -only
`lcRealWorld` constant to represent this type within the compiler. By
default, an opaque type definition is treated like `lcAny`, whereas we
want a more efficient representation. At the moment, this isn't a big
difference, but in the future we would like to completely erase
`IO.RealWorld` at runtime.
2025-09-08 18:12:19 +00:00
Joachim Breitner
79051fb5c0
feat: simpler off-diagonal noConfusion construction using ctorIdx (#10300)
This PR offers an alternative `noConfusion` construction for the
off-diagonal use (i.e. for different constructors), based on comparing
the `.ctorIdx`. This should lead to faster type checking, as the kernel
only has to reduce `.ctorIdx` twice, instead of the complicate
`noConfusionType` construction.
2025-09-08 14:34:26 +00:00
Leonardo de Moura
058f6008c0
fix: bug at Poly.combine_mul_k (#10296)
This PR fixes a bug in an auxiliary function used to construct proof
terms in `grind cutsat`.
2025-09-08 02:17:11 +00:00
Markus Himmel
9402c307fe
chore: reorganize Init imports around strings (#10289)
This PR reorganizes the import hierarchy so that
`Init.Data.String.Basic` can import `Init.Data.UInt.Bitwise` and
`Init.Data.Array.Lemmas`.
2025-09-07 17:09:14 +00:00
Markus Himmel
aa0a31ae7d
chore: prepare for untangling strings (#10288)
This PR prepares for a future reorganization of the import hierarchy so
that `Init.Data.String.Basic` can import `Init.Data.UInt.Bitwise` and
`Init.Data.Array.Lemmas`.
2025-09-07 12:58:23 +00:00
Markus Himmel
19bd0254c3
chore: move String.utf8EncodeChar to the prelude (#10264)
This PR moves `String.utf8EncodeChar` to the prelude to prepare for the
imminent redefinition of `String`.

The definition in the prelude uses modulo and division operations on
natural numbers. In `String.Extra`, a `csimp` lemma is provided, showing
that the new definition is equal to the previous one (which is now
called `utf8EncodeCharFast`) which uses bitwise operations on `UInt8`.
2025-09-07 12:42:53 +00:00
Leonardo de Moura
652868c308
feat: NatModule equation normalization theorem (#10280)
This PR adds the auxiliary theorem `Lean.Grind.Linarith.eq_normN` for
normalizing `NatModule` equations when the instance `AddRightCancel` is
not available.
2025-09-06 23:32:26 +00:00
Leonardo de Moura
52a9fe3b67
feat: missing NatModule instances (#10277)
This PR adds the missing instances `IsPartialOrder`, `IsLinearPreorder`
and `IsLinearOrder` for `OfNatModule.Q α`.
2025-09-06 18:58:02 +00:00
Leonardo de Moura
8735447d44
feat: infrastructure for NatModule in grind linarith (#10267)
This PR implements the infrastructure for supporting `NatModule` in
`grind linarith` and uses it to handle disequalities. Another PR will
add support for equalities and inequalities. Example:
```lean
open Lean Grind
variable (M : Type) [NatModule M] [AddRightCancel M]

example (x y : M) : 2 • x + 3 • y + x = 3 • (x + y) := by
  grind
```
2025-09-06 01:16:03 +00:00
Paul Reichert
184f716da1
refactor: improve names in the range API (#10059)
This PR improves the names of definitions and lemmas in the polymorphic
range API. It also introduces a recommended spelling. For example, a
left-closed, right-open range is spelled `Rco` in analogy with Mathlib's
`Ico` intervals.
2025-09-05 13:10:05 +00:00
Marc Huisinga
7ba0ae1f72
feat: improve auto-completion performance (#10249)
This PR speeds up auto-completion by a factor of ~3.5x through various
performance improvements in the language server. On one machine, with
`import Mathlib`, completing `i` used to take 3200ms and now instead
yields a result in 920ms.

Specifically, the following improvements are made:
- The watchdog process no longer de-serializes and re-serializes most
messages from the file worker before passing them on to the user - a
fast partial de-serialization procedure is now used to determine whether
the message needs to be de-serialized in full or not.
- `escapePart` is optimized to perform better on ASCII strings that do
not need escaping.
- `Json.compress` is optimized to allocate fewer objects.
- A faster JSON compression specifically for completion responses is
implemented that skips allocating `Json` altogether.
- The JSON compression has been moved to the task where we convert a
request response to `Json` so that converting to a string won't block
the output task of the FileWorker and so the `Json` value is not marked
as multi-threaded when we compress is, which drastically increases the
cost of reference-counting.
- The JSON representation of the `data?` field of each completion item
is optimized.
- Both the completion kind and the set of completion tags for each
imported completion item is now cached.
- The filtering of duplicate completion items is optimized.

Other adjustments:
- `LT UInt8` and `LE UInt8` are moved to Prelude so that they can be
used in `Init.Meta` for the name part escaping fast path.
- `Array.usize` is exposed since it was marked as `@[simp]`.
2025-09-05 08:55:49 +00:00
Leonardo de Moura
6cefbc4bb0
chore: fix typo (#10251) 2025-09-04 16:05:00 +00:00
Paul Reichert
9b6a4a7588
fix: solve two problems with LinearOrderPackage factories (#10250)
This PR fixes a bug in the `LinearOrderPackage.ofOrd` factory. If there
is a `LawfulEqOrd` instance available, it should automatically use it
instead of requiring the user to provide the `eq_of_compare` argument to
the factory. The PR also solves a hygiene-related problem making the
factories fail when `Std` is not open.
2025-09-04 15:27:09 +00:00
Kim Morrison
85f168bbd0
chore: add test cases for grind on Fin lemmas (#10241)
This PR adds some test cases for `grind` working with `Fin`. There are
many still failing tests in `tests/lean/grind/grind_fin.lean` which I'm
intending to triage and work on.
2025-09-04 04:28:29 +00:00
Rob23oba
80df86dfdd
feat: add more MonoBind instances for monad transformers (#10230)
This PR adds `MonoBind` for more monad transformers. This allows using
`partial_fixpoint` for more complicated monads based on `Option` and
`EIO`. Example:
```lean-4
abbrev M := ReaderT String (StateT String.Pos Option)

def parseAll (x : M α) : M (List α) := do
  if (← read).atEnd (← get) then
    return []
  let val ← x
  let list ← parseAll x
  return val :: list
partial_fixpoint
```
2025-09-03 17:15:41 +00:00
Paul Reichert
fef390df08
perf: improve iterator/range benchmarks, use shortcut instances for Int ranges (#10197)
This PR is the result of analyzing the elaborator performance regression
introduced by #10005. It makes the `workspaceSymboldNewRanges` and
`iterators` benchmarks less noisy. It also replaces some range-related
instances for `Nat` with shortcuts to the general-purpose instances.
This is a trade-off between the ergonomics and the synthesis cost of
having general-purpose instances.
2025-09-03 15:47:52 +00:00
Leonardo de Moura
a4f6f391fe
feat: equality propagation from AC module to grind core (#10223)
This PR implements equality propagation from the new AC module into the
`grind` core. Examples:

```lean
example {α β : Sort u} (f : α → β) (op : α → α → α) [Std.Associative op] [Std.Commutative op] 
    (a b c d : α) : op a (op b b) = op d c → f (op (op b a) (op b c)) = f (op c (op d c)) := by
  grind only

example (a b c : Nat) : min a (max b (max c 0)) = min (max c b) a := by
  grind -cutsat only

example {α β : Sort u} (bar : α → β) (op : α → α → α) [Std.Associative op] [Std.IdempotentOp op]
    (a b c d e f x y w : α) :
    op d (op x c) = op a b →
    op e (op f (op y w)) = op (op d a) (op b c) →
    bar (op d (op x c)) = bar (op e (op f (op y w))) := by
  grind only
```
2025-09-02 23:02:25 +00:00
Leonardo de Moura
dac61c406f
feat: extra critical pairs for associative + idempotent operators in grind ac (#10221)
This PR adds the extra critical pairs to ensure the `grind ac` procedure
is complete when the operator is associative and idempotent, but not
commutative. Example:
```lean
example {α : Sort u} (op : α → α → α) [Std.Associative op] [Std.IdempotentOp op] (a b c d e f x y w : α)
    : op d (op x c) = op a b →
      op e (op f (op y w)) = op a (op b c) →
      op d (op x c) = op e (op f (op y w)) := by
  grind only

example {α : Sort u} (op : α → α → α) [Std.Associative op] [Std.IdempotentOp op] (a b c d e f x y w : α)
    : op a (op d x) = op b c →
      op e (op f (op y w)) = op a (op b c) →
      op a (op d x) = op e (op f (op y w)) := by
  grind only
```
2025-09-02 15:52:56 +00:00
Aaron Liu
f748d1c4ef
doc: fix typo in docstring for fieldIdxKind (#8814)
This PR fixes a typo in the docstring for `Lean.fieldIdxKind`, which was
missing a backtick.
2025-09-02 12:30:07 +00:00
Leonardo de Moura
d826474b14
feat: extra critical pairs for AC + idempotent operators in grind ac (#10208)
This PR adds the extra critical pairs to ensure the `grind ac` procedure
is complete when the operator is AC and idempotent. Example:
```lean
example {α : Sort u} (op : α → α → α) [Std.Associative op] [Std.Commutative op] [Std.IdempotentOp op] 
      (a b c d : α) : op a (op b b) = op d c → op (op b a) (op b c) = op c (op d c)  := by
  grind only
```
2025-09-02 04:24:22 +00:00
Kim Morrison
8d9d23b5bb
feat: (approximate) inverses of dyadic rationals (#10194)
This PR adds the inverse of a dyadic rational, at a given precision, and
characterising lemmas. Also cleans up various parts of the `Int.DivMod`
and `Rat` APIs, and proves some characterising lemmas about
`Rat.toDyadic`.

---------

Co-authored-by: Rob23oba <152706811+Rob23oba@users.noreply.github.com>
2025-09-02 03:43:53 +00:00
Leonardo de Moura
c83237baf7
chore: cleanup superposeAC? (#10207)
This PR ensures `superposeAC?` and `superpose?` have similar signatures.
2025-09-02 01:55:20 +00:00
Leonardo de Moura
11f618ac49
feat: critical pairs (non commutative case) for grind ac (#10206)
This PR adds superposition for associative (but non-commutative)
operators in `grind ac`. Examples:
```lean
example {α} (op : α → α → α) [Std.Associative op] (a b c d : α)
   : op a b = c →
     op b a = d →
     op (op c a) (op b c) = op (op a d) (op d b) := by
  grind

example {α} (a b c d : List α)
   : a ++ b = c →
     b ++ a = d →
     c ++ a ++ b ++ c = a ++ d ++ d ++ b := by
  grind only
```
2025-09-02 00:58:49 +00:00
Joachim Breitner
b0506ee835
chore: remove bootstrap tricks from #9951 (#10203)
This PR removes bootstrap tricks from #9951.
2025-09-01 13:30:42 +00:00
Leonardo de Moura
c4e5f57512
feat: proof terms for grind ac (#10189)
This PR implements the proof terms for the new `grind ac` module.
Examples:
```lean
example {α : Sort u} (op : α → α → α) [Std.Associative op] (a b c d : α)
    : op a (op b b) = op c d → op c (op d c) = op (op a b) (op b c) := by
  grind only

example {α : Sort u} (op : α → α → α) [Std.Associative op] [Std.Commutative op] (a b c d : α)
    : op a (op b b) = op d c → op (op b a) (op b c) = op c (op d c)  := by
  grind only

example {α : Sort u} (op : α → α → α) [Std.Associative op] [Std.Commutative op]
    (one : α) [Std.LawfulIdentity op one] (a b c d : α)
    : op a (op (op b one) b) = op d c → op (op b a) (op (op b one) c) = op (op c one) (op d c)  := by
  grind only
```

The `grind ac` module is not complete yet, we still need to implement
critical pair computation and fix the support for idempotent operators.
2025-08-31 04:10:10 +00:00
Leonardo de Moura
8e7e55f2d5
doc: grind attribute modifiers (#10185)
This PR documents all `grind` attribute modifiers (e.g., `=`, `usr`,
`ext`, etc).
2025-08-30 16:12:50 +00:00
Kim Morrison
8789e5621b
feat: missing Nat.fold(Rev)_add lemmas (#10182)
This PR adds lemmas about `Nat.fold` and `Nat.foldRev` on sums, to match
the existing theorems about `dfold` and `dfoldRev`.
2025-08-30 08:54:12 +00:00
Leonardo de Moura
50ddf85b07
feat: check grind ac invariants (#10176)
This PR adds code for checking invariants in the `grind ac` module, and
fixes the bugs exposed by them.
2025-08-29 22:36:39 +00:00
Kim Morrison
4c44fdb95f
chore: remove grind annotations of List/Array/Vector.zip_map_left/right (#10163)
This PR removes some (hopefully) unnecessary `grind` annotations that
cause instantiation explosions.
2025-08-28 10:38:50 +00:00
Kim Morrison
a62dabeb56
feat: nodup_keys theorems for maps (#10159)
This PR adds `nodup_keys` lemmas as corollaries of existing
`distinct_keys` to all `Map` variants.
2025-08-28 06:00:28 +00:00
Leonardo de Moura
38608a672e
feat: simplify equations in grind AC module (#10165)
This PR adds support for equality simplification helper functions to the
`grind` AC module.
2025-08-28 03:54:09 +00:00
Leonardo de Moura
86425f655a
feat: helper AC.Seq functions (#10164)
This PR adds helper functions for the `AC.Seq` type.
2025-08-28 02:16:52 +00:00
Sebastian Ullrich
9757a7be53
perf: do not export opaque bodies (#10119)
In particular, do not export `partial` bodies
2025-08-27 20:59:59 +00:00
Leonardo de Moura
2dda33ddb2
chore: remove workaround (#10156) 2025-08-27 15:18:17 +00:00
Joachim Breitner
b5555052bd
feat: T.ctor.elim single-constructor cases function (#9952)
This PR adds “non-branching case statements”: For each inductive
constructor `T.con` this adds a function `T.con.with` that is similar
`T.casesOn`, but has only one arm (the one for `con`), and an additional
`t.toCtorIdx = 12` assumption.

For example:
```lean
inductive Vec (α : Type) : Nat → Type where
  | nil : Vec α 0
  | cons {n} : α → Vec α n → Vec α (n + 1)

/--
info: @[reducible] protected def Vec.cons.elim.{u} : {α : Type} →
  {motive : (a : Nat) → Vec α a → Sort u} →
    {a : Nat} →
      (t : Vec α a) →
        t.ctorIdx = 1 → ({n : Nat} → (a : α) → (a_1 : Vec α n) → motive (n + 1) (Vec.cons a a_1)) → motive a t
-/
#guard_msgs in
#print sig Vec.cons.elim
```

This is a building block for non-quadratic implementations of `BEq` and
`DecidableEq` etc.

Builds on top of #9951.

The compiled code for a these functions could presumably, without
branching on the inductive value, directly access the fields. Achieving
this optimization (and achieving it without a quadratic compilation
cost) is not in scope for this PR.
2025-08-27 09:40:31 +00:00
thorimur
5bb7818355
feat: allow position reporting in #guard_msgs (#10125)
This PR allows `#guard_msgs` to report the relative positions of logged
messages with the config option `(positions := true)`.

Closes #8265
2025-08-27 06:47:34 +00:00
Leonardo de Moura
aaec0f584c
feat: ac normalization in grind (#10146)
This PR implements the basic infrastructure for the new procedure
handling AC operators in grind. It already supports normalizing
disequalities. Future PRs will add support for simplification using
equalities, and computing critical pairs. Examples:
```lean
example {α : Sort u} (op : α → α → α) [Std.Associative op] (a b c : α)
    : op a (op b c) = op (op a b) c := by
  grind only

example {α : Sort u} (op : α → α → α) (u : α) [Std.Associative op] [Std.LawfulIdentity op u] (a b c : α)
    : op a (op b c) = op (op a b) (op c u) := by
  grind only

example {α : Type u} (op : α → α → α) (u : α) [Std.Associative op] [Std.Commutative op] 
    [Std.IdempotentOp op] [Std.LawfulIdentity op u] (a b c : α)
    : op (op a a) (op b c) = op (op (op b a) (op (op u b) b)) c := by
  grind only

example {α} (as bs cs : List α) : as ++ (bs ++ cs) = ((as ++ []) ++ bs) ++ (cs ++ []) := by
  grind only

example (a b c : Nat) : max a (max b c) = max (max b 0) (max a c) ∧ min a b = min b a := by
  grind only [cases Or]
```
2025-08-27 03:28:30 +00:00
Marc Huisinga
2324c0939d
chore: add private getUtf8Byte' to Init.Meta (#10140)
This PR adds a private `Lean.Name.getUtf8Byte'` to `Init.Meta` for a
future PR that optimizes `Lean.Name.escapePart`.
`Lean.Name.getUtf8Byte'` should be replaced with `String.getUtf8Byte`
once the string refactor is through.
2025-08-26 16:54:02 +00:00
Luisa Cicolini
3e11f27ff4
feat: add fast circuit for unsigned multiplication overflow detection fastUmulOverflow_eq and surrounding definitions (#7858)
This PR implements the fast circuit for overflow detection in unsigned
multiplication used by Bitwuzla and proposed in:
https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=987767

The theorem is based on three definitions: 
* `uppcRec`: the unsigned parallel prefix circuit for the bits until a
certain `i`
* `aandRec`: the conjunction between the parallel prefix circuit at of
the first operand until a certain `i` and the `i`-th bit in the second
operand
* `resRec`: the preliminary overflow flag computed with these two
definitions
To establish the correspondence between these definitiions and their
meaning in `Nat`, we rely on `clz` and `clzAuxRec` definitions.
Therefore, this PR contains the `clz`- and `clzAuxRec`-related
infrastructure that was necessary to get the proofs through.

An additional change this PR contains is the moving of `### Count
leading zeros` section in `BitVec.Lemmas` downwards. In fact, some of
the proofs I wrote required introducing `Bitvec.toNat_lt_iff` and
`BitVec.le_toNat_iff` which I believe should live in the `Inequalities`
section. Therefore, to put these in the appropriate section, I decided
to move the whole `clz` section downwards (while it's small and
relatively self contained. Specifically, the theorems I moved are:
`clzAuxRec_zero`, `clzAuxRec_succ`, `clzAuxRec_eq_clzAuxRec_of_le`,
`clzAuxRec_eq_clzAuxRec_of_getLsbD_false`.
 
The fast circuit is not yet the default one in the bitblaster, as it's
performance is not yet competitive due to some missing rewrites that
bitwuzla supports but are not in Lean yet.
 
co-authored-by: @bollu

---------

Co-authored-by: Tobias Grosser <tobias@grosser.es>
2025-08-26 13:21:23 +00:00
Kim Morrison
a78a34bbd7
chore: replace Lean.Grind internal preorder classes with the classes from Std (#10129)
This PR replaces the interim order typeclasses used by `Grind` with the
new publicly available classes in `Std`.
2025-08-26 13:18:22 +00:00
Kim Morrison
9e47edd0df
feat: lemmas about rounding dyadics (#10138)
This PR adds lemmas about the `Dyadic.roundUp` and `Dyadic.roundDown`
operations.
2025-08-26 12:31:40 +00:00
Kim Morrison
0f1174d097
chore: use SMul rather than HMul in grind algebra typeclasses (#10095)
This PR modifies the `grind` algebra typeclasses to use `SMul x y`
instead of `HMul x y y`.
2025-08-26 12:23:37 +00:00
Kim Morrison
ad3e975178
feat: dyadic rationals (#9993)
This PR defines the dyadic rationals, showing they are an ordered ring
embedding into the rationals. We will use this for future interval
arithmetic tactics.

Many thanks to @Rob23oba, who did most of the implementation work here.

---------

Co-authored-by: Rob23oba <robin.arnez@web.de>
2025-08-26 03:49:39 +00:00
Kim Morrison
a6a02fe6b9
chore: reduce Int imports on the critical path (#10123)
This PR shortens the rebuild critical path at
https://speed.lean-lang.org/lean4-out/cbf3814a565f7188f830f365453fb0bdd66d6175/
2025-08-25 23:07:02 +00:00
Kim Morrison
a06e6e7f4d
chore: make UInt.Lemmas a private import of String.Extra (#10115)
This PR makes the `Init.Data.UInt.Lemmas` import into
`Init.Data.String.Extra` private; previously this import was on the
rebuild critical path.
2025-08-25 16:46:22 +00:00
Joachim Breitner
1718ca21cd
feat: deprecate .toCtorIdx for .ctorIdx (#10113)
This PR deprecates `.toCtorIdx` for the more naturally named `.ctorIdx`
(and updates the standard library).
2025-08-25 14:32:05 +00:00
Joachim Breitner
afcf52e623
feat: .ctorIdx for all inductives (#9951)
This PR generates `.ctorIdx` functions for all inductive types, not just
enumeration types. This can be a building block for other constructions
(`BEq`, `noConfusion`) that are size-efficient even for large
inductives.

It also renames it from `.toCtorIdx` to `.ctorIdx`, which is the more
idiomatic naming.
The old name exists as an alias, with a deprecation attribute to be
added after the next
stage0 update.

These functions can arguably compiled down to a rather efficient tag
lookup, rather than a `case` statement. This is future work (but
hopefully near future).

For a fair number of basic types the compiler is not able to compile a
function using `casesOn` until further definitions have been defined.
This therefore (ab)uses the `genInjectivity` flag and
`gen_injective_theorems%` command to also control the generation of this
construct.

For (slightly) more efficient kernel reduction one could use `.rec`
rather than `.casesOn`. I did not do that yet, also because it
complicates compilation.
2025-08-25 10:47:06 +00:00
Sebastian Ullrich
3c40ea2733
chore: revert automatically exposing derived instances (#10101)
Heed surrounding `@[expose]` instead
2025-08-25 08:55:10 +00:00