Commit graph

2009 commits

Author SHA1 Message Date
Henrik Böving
5fd8c1b94d
feat: new String.Slice API (#10514)
This PR defines the new `String.Slice` API.

Many of the core design principles of the API are taken over from Rust's
[string
library](https://doc.rust-lang.org/stable/std/string/struct.String.html).
2025-09-25 12:18:52 +00:00
Mario Carneiro
9f41f3324a
fix: make Substring.beq reflexive (#10552)
This PR ensures that `Substring.beq` is reflexive, and in particular
satisfies the equivalence `ss1 == ss2 <-> ss1.toString = ss2.toString`.

Closes #10511.

Note: I also fixed a strange line in the `String.extract` documentation
which looks like it may have been a copypasta, and added another example
to show how invalid UTF8 positions work, but the doc also makes a point
of saying that it is unspecified so maybe it would be better not to have
the example? 🤷
2025-09-25 05:08:41 +00:00
Markus Himmel
d6cd738ab4
feat: redefine String, part two (#10457)
This PR introduces safe alternatives to `String.Pos` and `Substring`
that can only represent valid positions/slices.

Specifically, the PR

- introduces the predicate `String.Pos.IsValid`;
- proves several nontrivial equivalent conditions for
`String.Pos.IsValid`;
- introduces `String.ValidPos`, which is a `String.Pos` with an
`IsValid` proof;
- introduces `String.Slice`, which is like `Substring` but made from
`String.ValidPos` instead of `Pos`;
- introduces `String.Pos.IsValidForSlice`, which is like
`String.Pos.IsValid` but for slices;
- introduces `String.Slice.Pos`, which is like `String.ValidPos` but for
slices;
- introduces various functions for converting between the two types of
positions.

The API added in this PR is not complete. It will be expanded in future
PRs with addional operations and verification.
2025-09-24 13:36:55 +00:00
Markus Himmel
b6198434f2
fix: String regressions (#10523)
This PR fixes some regressions introduced by #10304.
2025-09-24 12:01:50 +00:00
Kim Morrison
3ddda9ae4d
chore: adjust List.countP grind annotations (#10532) 2025-09-24 07:07:11 +00:00
Kim Morrison
ac0b82933f
chore: add variant of Rat.ofScientific_def for grind (#10534) 2025-09-24 06:37:46 +00:00
Kim Morrison
781e3c6add
chore: remove unhelpful grind annotations (#10435)
This PR removes some `grind` annotations for `Array.attach` and related
functions. These lemmas introduce lambda on the right hand side which
`grind` can't do much with. I've added a test file that verifies that
the theorems with removed annotations can actually be proved already by
grind. Removing the annotations will help with excessive instantiation.
2025-09-24 03:02:46 +00:00
Kim Morrison
e2f87ed215
chore: lemma for unfolding eraseIdxIfInBounds (#10520) 2025-09-23 13:08:41 +00:00
Tom Levy
e42892cfb6
doc: fix comment about String.fromUTF8 replacing invalid chars (#10240)
Hi, the doc of `String.fromUTF8` previously said invalid characters are
replaced with 'A'. But the parameter `h : validateUTF8 a` guarantees
there are no invalid characters, so that explanation doesn't make sense
to me. This PR deletes that explanation (and fixes some unrelated
typos).

I also have a patch that uses `h` to prove each of the characters is
valid, eliminating the need for a default character
([pr/chore-String-fromUTF8-prove-valid](27f1ff36b2)),
would you be interested in merging that?

<details>
<summary>Notes on invalid characters from unchecked C++</summary>
I don't know if this function may be called from unchecked C++ with
invalid characters. If it may, I'm not sure what would happen with my
patched function... I'm not familiar with Lean's safety model, but it
seems like a bad idea to have a Lean function that takes a proof of a
proposition but is expected to operate in a certain way even if the
proposition is false. I think the safe approach is to have two functions
-- one that takes a proof and is only called from Lean, and another that
doesn't take a proof and replaces invalid chars (for use from C++, not
sure whether it's useful from Lean); I'd prefer to go even further and
report an error instead of silently replacing invalid characters (I'm
not sure if there is any easy way to report errors/panic in Lean code
called from C++).
</details>
2025-09-23 10:19:20 +00:00
Sebastian Ullrich
cc5c070328
fix: inline/specialize may only refer to publicly imported decls for now (#10494)
This PR resolves a potential bad interaction between the compiler and
the module system where references to declarations not imported are
brought into scope by inlining or specializing. We now proactively check
that declarations to be inlined/specialized only reference public
imports. The intention is to later resolve this limitation by moving out
compilation into a separate build step with its own import/incremental
system.
2025-09-23 09:58:14 +00:00
Kim Morrison
2b23afdfab
chore: remove >6 month old deprecations (#10446) 2025-09-22 12:47:11 +00:00
Kim Morrison
979c2b4af0
chore: add grind annotations for List.not_mem_nil (#10493) 2025-09-22 12:18:03 +00:00
Kim Morrison
b3cd5999e7
chore: normalize empty ByteArrays to .empty (#10501) 2025-09-22 12:06:29 +00:00
Sebastian Ullrich
7822ee4500
fix: check that compiler does not infer inconsistent types between modules (#10418)
This PR fixes a potential miscompilation when using non-exposed type
definitions using the module system by turning it into a static error. A
future revision may lift the restriction by making the compiler metadata
independent of the current module.
2025-09-19 12:36:47 +00:00
Leonardo de Moura
9fb5ab8450
feat: helper definitions for injective function support in grind (#10445)
This PR adds helper definitions in preparation for the upcoming
injective function support in `grind`.
2025-09-18 19:42:15 +00:00
Leonardo de Moura
a62c0bce77
chore: missing grind modifier (#10441) 2025-09-18 14:44:57 +00:00
Markus Himmel
197bc6cb66
feat: redefine String, part one (#10304)
This PR redefines `String` to be the type of byte arrays `b` for which
`b.IsValidUtf8`.

This moves the data model of strings much closer to the actual data
representation at runtime.

In the near future, we will

- provide variants of `String.Pos` and `Substring` that only allow for
valid positions
- redefine all `String` functions to be much closer to their C++
implementations

In the near-to-medium future we will then provide comprehensive
verification of `String` based on these refactors.
2025-09-18 11:36:52 +00:00
Luisa Cicolini
02ca710872
feat: add BitVec.ctz to bv_decide (#9298)
This PR adds support the Count Trailing Zeros operation `BitVec.ctz` to
the bitvector library and to `bv_decide`, relying on the existing `clz`
circuit. We also build some theory around `BitVec.ctz` (analogous to the
theory existing for `BitVec.clz`) and introduce lemmas
`BitVec.[ctz_eq_reverse_clz, clz_eq_reverse_ctz, ctz_lt_iff_ne_zero,
getLsbD_false_of_lt_ctz, getLsbD_true_ctz_of_ne_zero,
two_pow_ctz_le_toNat_of_ne_zero, reverse_reverse_eq,
reverse_eq_zero_iff]`.

`ctz` operation is common in numerous compiler intrinsics (see
[here](https://clang.llvm.org/docs/LanguageExtensions.html#intrinsics-support-within-constant-expressions))
and architectures (see
[here](https://en.wikipedia.org/wiki/Find_first_set)).

---------

Co-authored-by: Siddharth <siddu.druid@gmail.com>
2025-09-18 08:38:07 +00:00
Leonardo de Moura
6ca699b1ff
feat: enable new E-matching pattern inference procedure in grind (#10432)
This PR enables the new E-matching pattern inference heuristic for
`grind`, implemented in PR #10422.
**Important**: Users can still use the old pattern inference heuristic
by setting:

```lean
set_option backward.grind.inferPattern true
```

In PR #10422, we introduced the new modifier `@[grind!]` for enabling
the minimal indexable subexpression condition. This option can now also
be set in `grind` parameters. Example:

```lean
opaque f : Nat → Nat
opaque fInv : Nat → Nat 
axiom fInv_f : fInv (f x) = x

/-- trace: [grind.ematch.pattern] fInv_f: [f #0] -/
#guard_msgs in 
set_option trace.grind.ematch.pattern true in
example {x y} : f x = f y → x = y := by
  /-
  The modifier `!` instructs `grind` to use the minimal indexable subexpression 
  (i.e., `f x` in this case).   
  -/
  grind [!fInv_f] 
```
2025-09-18 04:13:54 +00:00
Leonardo de Moura
a80169165e
chore: missing grind modifiers and local grind theorems config (#10428)
This PR makes explicit missing `grind` modifiers, and ensures `grind`
uses "minIndexable" for local theorems.
2025-09-17 16:15:16 +00:00
Joachim Breitner
7b75db7c6e
refactor: use deriving LawfulBEq in Init (#10411)
This PR starts using `deriving LawfulBEq` in `Init`, removing some hairy
hand-rolled proofs.
2025-09-16 16:26:32 +00:00
Joachim Breitner
9deff2751f
refactor: use reduceBEq in Init (#10398)
This PR uses the `reduceBEq` simproc in Init, but mostly only for
testing, because afer #10351 this code will be derived.
2025-09-16 10:35:46 +00:00
Kim Morrison
4d8d502754
chore: remove bad grind annotation on List.eq_nil_of_map_eq_nil (#10356) 2025-09-15 04:33:16 +00:00
Kyle Miller
409cbe1da9
fix: make rw collect only new goals, occurs check (#10306)
This PR fixes a few bugs in the `rw` tactic: it could "steal" goals
because they appear in the type of the rewrite, it did not do an occurs
check, and new proof goals would not be synthetic opaque. This PR also
lets the `rfl` tactic assign synthetic opaque metavariables so that it
is equivalent to `exact rfl`.

Implementation note: filtering old vs new is not sufficient. This PR
partially addresses the bug where the rw tactic creates natural
metavariables for each of the goals; now new proof goals are synthetic
opaque.

Metaprogramming API: Instead of `Lean.MVarId.rewrite` prefer
`Lean.Elab.Tactic.elabRewrite` for elaborating rewrite theorems and
applying rewrites to expressions.

Closes #10172
2025-09-14 04:44:55 +00:00
Paul Reichert
caa0eacea8
feat: ranges in UInt* (#10303)
This PR adds range support to`BitVec` and the `UInt*` types. This means
that it is now possible to write, for example, `for i in (1 : UInt8)...5
do`, in order to loop over the values 1, 2, 3 and 4 of type `UInt8`.
2025-09-12 07:52:45 +00:00
Paul Reichert
ae682ed225
feat: more iterator/range lemmas about toList and toArray (#10244)
This PR adds more lemmas about the `toList` and `toArray` functions on
ranges and iterators. It also renames `Array.mem_toArray` into
`List.mem_toArray`.
2025-09-12 07:14:28 +00:00
Kim Morrison
72cc6c85eb
chore: correct order of implicit arguments for Injective/Surjective API (#10354) 2025-09-11 23:30:19 +00:00
Kim Morrison
5c06c79c15
chore: fix remainining discrepancies for change in grind pattern heuristics (#10347)
This PR is followup to the change in grind pattern heuristics from
#10342, typically resolving the discrepancy by writing out an explicit
`grind_pattern` for the intended pattern. The new behaviour is more
aggressive, because it selects smaller patterns.
2025-09-11 12:48:52 +00:00
Kim Morrison
01ed345643
chore: more review of @[grind] annotations (#10340)
This PR completes the review of `@[grind]` annotations without a sigil
(e.g. `=` or `←`), replacing most of them with more specific annotations
or patterns.

---------

Co-authored-by: Leonardo de Moura <leomoura@amazon.com>
2025-09-11 06:09:52 +00:00
Kim Morrison
c3667e2861
feat: upstream Function.Injective/Surjective (#10341)
This PR moves the definitions and basic facts about `Function.Injective`
and `Function.Surjective` up from Mathlib. We can do a better job of
arguing via injectivity in `grind` if these are available.
2025-09-11 04:04:46 +00:00
Leonardo de Moura
33266b23cd
chore: use [grind =] (#10337) 2025-09-11 03:21:37 +00:00
Kim Morrison
b7520e7232
chore: cleanup grind annotations in List (#10338)
This PR updates `@[grind]` annotations which should be `@[grind =]`, for
robustness (and, presumably, in some fraction of cases the existing
heuristic for `@[grind]` is already too liberal).
2025-09-11 02:36:18 +00:00
Kim Morrison
a0ecff4610
chore: remove over-eager grind lemma eq_empty_of_append_eq_empty (#10162)
This PR removes `grind →` annotations that fire too often, unhelpfully.
It would be nice for `grind` to instantiate these lemmas, but only if
they already see `xs ++ ys` and `#[]` in the same equivalence class, not
just as soon as it sees `xs ++ ys`.

In the meantime, let's see what is using these.
2025-09-10 02:35:54 +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
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
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
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
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
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
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
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
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
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