Commit graph

4542 commits

Author SHA1 Message Date
Paul Reichert
6e538c35dd
refactor: migrate all usages of old slice notation (#9000)
This PR replaces all usages of `[:]` slice notation in `src` with the
new `[...]` notation in production code, tests and comments. The
underlying implementation of the `Subarray` functions stays the same.

Notation cheat sheet:

* `*...*` is the doubly-unbounded range.
* `*...a` or `*...<a` contains all elements that are less than `a`.
* `*...=a` contains all elements that are less than or equal to `a`.
* `a...*` contains all elements that are greater than or equal to `a`.
* `a...b` or `a...<b` contains all elements that are greater than or
equal to `a` and less than `b`.
* `a...=b` contains all elements that are greater than or equal to `a`
and less than or equal to `b`.
* `a<...*` contains all elements that are greater than `a`.
* `a<...b` or `a<...<b` contains all elements that are greater than `a`
and less than `b`.
* `a<...=b` contains all elements that are greater than `a` and less
than or equal to `b`.

Benchmarks have shown that importing the iterator-backed parts of the
polymorphic slice library in `Init` impacts build performance. This PR
avoids this problem by separating those parts of the library that do not
rely on iterators from those those that do. Whereever the new slice
notation is used, only the iterator-independent files are imported.
2025-06-27 18:52:07 +00:00
Leonardo de Moura
422eb68f6f
feat: assert ToInt bounds in grind cutsat (#9050)
This PR ensures the `ToInt` bounds are asserted for every `toInt a`
application internalized in `grind cutsat`.
2025-06-27 18:42:35 +00:00
Henrik Böving
7a1113ada3
feat: extend identifiers to french (#9035)
This PR extends the list of acceptable characters to all the french ones
as well as some others,
by adding characters from the Latin-1-Supplement add Latin-Extended-A
unicode block.
2025-06-27 12:50:09 +00:00
Paul Reichert
1a6eae16ec
feat: introduce uLift iterator combinator, make Subarray.iter universe-polymorphic (#9027)
This PR provides an iterator combinator that lifts the emitted values
into a higher universe level via `ULift`. This combinator is then used
to make the subarray iterators universe-polymorphic. Previously, they
were only available for `Subarray α` if `α : Type`.
2025-06-27 07:34:08 +00:00
Kim Morrison
8d40cf5157
chore: missing Option lemma (#9028) 2025-06-27 07:28:59 +00:00
Kyle Miller
7abc9106d7
feat: optimized simp routine for let telescopes (#8968)
This PR adds the following features to `simp`:
- A routine for simplifying `have` telescopes in a way that avoids
quadratic complexity arising from locally nameless expression
representations, like what #6220 did for `letFun` telescopes.
Furthermore, simp converts `letFun`s into `have`s (nondependent lets),
and we remove the #6220 routine since we are moving away from `letFun`
encodings of nondependent lets.
- A `+letToHave` configuration option (enabled by default) that converts
lets into haves when possible, when `-zeta` is set. Previously Lean
would need to do a full typecheck of the bodies of `let`s, but the
`letToHave` procedure can skip checking some subexpressions, and it
modifies the `let`s in an entire expression at once rather than one at a
time.
- A `+zetaHave` configuration option, to turn off zeta reduction of
`have`s specifically. The motivation is that dependent `let`s can only
be dsimped by let, so zeta reducing just the dependent lets is a
reasonable way to make progress. The `+zetaHave` option is also added to
the meta configuration.
- When `simp` is zeta reducing, it now uses an algorithm that avoids
complexity quadratic in the depth of the let telescope.
- Additionally, the zeta reduction routines in `simp`, `whnf`, and
`isDefEq` now all are consistent with how they apply the `zeta`,
`zetaHave`, and `zetaUnused` configurations.

The `letToFun` option is addressing a TODO in `getSimpLetCase` ("handle
a block of nested let decls in a single pass if this becomes a
performance problem").

Performance should be compared to before #8804, which temporarily
disabled the #6220 optimizations for `letFun` telescopes.

Good kernel performance depends on carefully handling the `have`
encoding. Due to the way the kernel instantiates bvars (it does *not*
beta reduce when instantiating), we cannot use congruence theorems of
the form `(have x := v; f x) = (have x ;= v'; f' x)`, since the bodies
of the `have`s will not be syntactically equal, which triggers zeta
reduction in the kernel in `is_def_eq`. Instead, we work with `f v = f'
v'`, where `f` and `f'` are lambda expressions. There is still zeta
reduction, but only when converting between these two forms at the
outset of the generated proof.
2025-06-27 02:13:20 +00:00
jrr6
05948f19e4
fix: improve precision of synthesis failure spans in interpolated strings (#9004)
This PR ensures that type-class synthesis failure errors in interpolated
strings are displayed at the interpolant at which they occurred.
2025-06-27 01:47:32 +00:00
Leonardo de Moura
6b520ede08
feat: generic toInt for cutsat (#9022)
This PR completes the generic `toInt` infrastructure for embedding terms
implementing the `ToInt` type classes into `Int`.
2025-06-27 00:28:51 +00:00
Luisa Cicolini
b1a306cf69
feat: add BitVec.toFin_(sdiv, smod, srem) and BitVec.toNat_srem (#8950)
This PR adds `BitVec.toFin_(sdiv, smod, srem)` and `BitVec.toNat_srem`.
The strategy for the `rhs` of the `toFin_*` lemmas is to consider what
the corresponding `toNat_*` theorems do and push the `toFin` closerto
the operands. For the `rhs` of `BitVec.toNat_srem` I used the same
strategy as `BitVec.toNat_smod`.
2025-06-26 20:01:01 +00:00
Sebastian Graf
f87d05ad4e
feat: Hoare logic for monadic programs and verification condition generation (#8995)
This PR introduces a Hoare logic for monadic programs in
`Std.Do.Triple`, and assorted tactics:

*  `mspec` for applying Hoare triple specifications
* `mvcgen` to turn a Hoare triple proof obligation `⦃P⦄ prog ⦃Q⦄` into
pure verification conditoins (i.e., without any traces of Hoare triples
or weakest preconditions reminiscent of `prog`). The resulting
verification conditions in the stateful logic of `Std.Do.SPred` can be
discharged manually with the tactics coming with its custom proof mode
or with automation such as `simp` and `grind`.

This is pre-release of a planned feature and not yet intended for
production use. We are grateful for feedback of early adopters, though.

Co-authored-by: Sebastian Graf <sg@lean-fro.org>
2025-06-26 15:49:56 +00:00
Paul Reichert
83e226204d
feat: introduce slices (#8947)
This PR introduces polymorphic slices in their most basic form. They
come with a notation similar to the new range notation. `Subarray` is
now also a slice and can produce an iterator now. It is intended to
migrate more operations of `Subarray` to the `Slice` wrapper type to
make them available for slices of other types, too.

The PR also moves the `filterMap` combinators into `Init` because they
are used internally to implement iterators on array slices.
2025-06-26 15:29:03 +00:00
Sebastian Graf
0d7fe9a196
feat: Upstream MPL.SPred.* from mpl (#8928)
This PR adds a logic of stateful predicates SPred to Std.Do in order to
support reasoning about monadic programs. It comes with a dedicated
proof mode the tactics of which are accessible by importing
Std.Tactic.Do.

Co-authored-by: Sebastian Graf <sg@lean-fro.org>
2025-06-26 11:15:11 +00:00
Paul Reichert
70b4b2b36c
feat: polymorphic ranges (#8784)
This PR introduces ranges that are polymorphic, in contrast to the
existing `Std.Range` which only supports natural numbers.

Breakdown of core changes:

* `Lean.Parser.Basic`: Modified the number parser (`Lean.Parser.Basic`)
so that it will only consider a *single* dot to be part of a decimal
number. `1..` will no longer be parsed as `1.` followed by `.`, but as
`1` followed by `..`.
* The test `ellipsisProjIssue` ensures that `#check Nat.add ...succ`
produces a syntax error. After introducing the new range notation (see
below), it returns a different (less nice) error message. I updated the
test to reflect the new error message. (The error message will become
nicer as soon as a delaborator for the ranges is implemented. This is
out of scope for this PR.)

Breakdown of standard library changes:

Modified modules: `Init.Data.Range.Polymorphic` (added),
`Init.Data.Iterators`, `Std.Data.Iterators`

* Introduced the type `Std.PRange` that is parameterized over the type
in which the range operates and the shapes of the lower and upper bound.
* Introduced a new notation for ranges. Examples for this notation are:
`1...*`, `1...=3`, `1...<3`, `1<...=2`, `*...=3`.
* Defined lots of typeclasses for different capabilities of ranges,
depending on their shape and underlying type.
* Introduced `Iter(M).size`.
* Introduced the `Iter(M).stepSize n` combinator, which iterates over an
iterator with the given step size `n`. It will drop `n - 1` values
between every value it emits.
* Replaced `LawfulPureIterator` with a new and better typeclass
`LawfulDeterministicIterator`.
* Simplified some lemma statements in the iterator library such as
`IterM.toList_eq_match`, which unnecessarily matched over a `Subtype`,
hindering rewrites due to type dependencies.

Reasons for the concrete choice of notation:

* `lean4-cli` uses `...`-based notation for the `Cmd` notation and it
clashes with `...a` range notation.
* test `2461` fails when using two-dot-based notation because of the
existing `{ a.. }` notation.
2025-06-26 08:18:11 +00:00
Paul Reichert
3695059504
feat: introduce MonadLiftT Id m (#8977)
This PR adds a generic `MonadLiftT Id m` instance. We do not implement a
`MonadLift Id m` instance because it would slow down instance resolution
and because it would create more non-canonical instances. This change
makes it possible to iterate over a pure iterator, such as `[1, 2,
3].iter`, in arbitrary monads.
2025-06-26 07:33:07 +00:00
Leonardo de Moura
b76bf44654
feat: infrastructure for cutsat generic ToInt (#9008)
This PR implements the basic infrastructure for the generic `ToInt`
support in `cutsat`.
2025-06-26 07:01:19 +00:00
Kim Morrison
561c18819c
chore: typo (#9007) 2025-06-26 03:50:29 +00:00
David Thrane Christiansen
5ec3cc5df7
doc: review Repr and Format docstrings (#8998)
This PR makes the docstrings related to `Format` and `Repr` have
consistent formatting and style, and adds missing docstrings.
2025-06-26 03:20:23 +00:00
Kim Morrison
62e9d73f8b
chore: revert BitVec/Lemmas grind proofs; too many bootstrapping difficulties (#9006) 2025-06-26 03:04:01 +00:00
Kim Morrison
1e135f2187
fix: refactor ToInt.OfNat (#9005)
This PR changes the definition of `Lean.Grind.ToInt.OfNat`, introducing
a `wrap` on the right-hand-side.
2025-06-26 02:27:15 +00:00
Luisa Cicolini
25b1b46572
feat: add BitVec.msb_(smod, srem) (#8974)
This PR adds `BitVec.msb_(smod, srem)`. 

co-authored with @tobiasgrosser and @bollu

---------

Co-authored-by: Tobias Grosser <github@grosser.es>
Co-authored-by: Siddharth <siddu.druid@gmail.com>
2025-06-25 13:49:33 +00:00
Kim Morrison
0ddd9341d6
feat: refactor of Lean.Grind.ToInt and remaining instances (#8996)
This PR provides the remaining instances for the `Lean.Grind.ToInt`
typeclasses.
2025-06-25 13:32:38 +00:00
Joachim Breitner
9641a9ac6c
feat: PULift (#8992)
This PR adds `PULift`, a more general form of `ULift` and `PLift` that
subsumes both.

Needed in #8973
2025-06-25 09:04:52 +00:00
Kim Morrison
94f48c3cec
feat: add ToInt typeclasses for grind (#8991)
This PR adds some missing `ToInt.X` typeclass instances for `grind`.

There are still several more to add (in particular, for `ToInt.Pow`),
but I am going to perform an intermediate refactor first.
2025-06-25 05:38:15 +00:00
Kim Morrison
58c69909a1
feat: doc-strings for grind algebra classes (#8990)
This PR adds missing doc-strings for grind's internal algebra
typeclasses, for inclusion in the reference manual.
2025-06-25 04:46:44 +00:00
Kim Morrison
708c5f1d9a
chore: cleanup of grind in BitVec/Lemmas (#8989) 2025-06-25 03:00:31 +00:00
Kim Morrison
3e8d28ae6b
feat: use grind in BitVec/Lemmas (#8967)
This PR both adds initial `@[grind]` annotations for `BitVec`, and uses
`grind` to remove many proofs from `BitVec/Lemmas`.

---------

Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2025-06-24 10:54:43 +00:00
Henrik Böving
a223e92f85
chore: remove use of deprecated API (#8970) 2025-06-24 08:22:50 +00:00
Luisa Cicolini
46a7c9108f
feat: add BitVec.(getElem, getLsbD, getMsbD)_(smod, sdiv, srem) (#8941)
This PR adds `BitVec.(getElem, getLsbD, getMsbD)_(smod, sdiv, srem)`
theorems to complete the API for `sdiv`, `srem`, `smod`. Even though the
rhs is not particularly succint (it's hard to find a meaning for what it
means to have "the n-th bit of the result of a signed division/modulo
operation"), these lemmas prevent the need to `unfold` of operations.

---------

Co-authored-by: Kim Morrison <477956+kim-em@users.noreply.github.com>
2025-06-24 07:09:00 +00:00
Kyle Miller
a427a8264a
chore: cleanup after stage0 update (#8966)
This PR cleans up the bootstrapping code added in #8957.
2025-06-24 05:34:57 +00:00
Kim Morrison
cc493e688b
feat: embed a NatModule in its IntModule completion (#8963)
This PR embeds a NatModule into its IntModule completion, which is
injective when we have AddLeftCancel, and monotone when the modules are
ordered. Also adds some (failing) grind test cases that can be verified
once `grind` uses this embedding.
2025-06-24 05:30:43 +00:00
Kim Morrison
5a9d7ae925
feat: revise grind annotations for bitwise operations (#8965)
This PR revises @[grind] annotations on Nat bitwise operations.
2025-06-24 05:16:21 +00:00
Kim Morrison
e0c2263073
chore: add @[expose] in Grind/Ring/Poly.lean (#8964)
This PR adds `@[expose]` attributes to proof terms constructed by
`grind` that need to be evaluated in the kernel.
2025-06-24 05:14:12 +00:00
Kim Morrison
449bc31832
chore: adds (failing) grind algebra tests (#8961) 2025-06-24 03:51:39 +00:00
Kim Morrison
6970d77ae4
feat: the grothendieck envelope of an ordered semiring is an ordered ring (#8959)
This PR add instances showing that the Grothendieck (i.e. additive)
envelope of a semiring is an ordered ring if the original semiring is
ordered (and satisfies ExistsAddOfLE), and in this case the embedding is
monotone.
2025-06-24 03:23:18 +00:00
Kyle Miller
b28dc8c5fb
feat: add configuration for let/have tactics (#8957)
This PR adds configuration options to the `let`/`have` tactic syntaxes.
For example, `let (eq := h) x := v` adds `h : x = v` to the local
context. The configuration options are the same as those for the
`let`/`have` term syntaxes.
2025-06-24 02:49:02 +00:00
Kyle Miller
71cf266cd7
feat: add Meta.letToHave and the let_to_have tactic (#8954)
This PR adds a procedure that efficiently transforms `let` expressions
into `have` expressions (`Meta.letToHave`). This is exposed as the
`let_to_have` tactic.

It uses the `withTrackingZetaDelta` technique: the expression is
typechecked, and any `let` variables that don't enter the zeta delta set
are nondependent. The procedure uses a number of heuristics to limit the
amount of typechecking performed. For example, it is ok to skip
subexpressions that do not contain fvars, mvars, or `let`s.
2025-06-24 01:33:53 +00:00
Leonardo de Moura
ba07e46368
refactor: simplify semiring normalization helper theorems (#8946)
This PR simplifies the semiring normalization theorem that will be used
by `grind`.
2025-06-23 23:20:20 +00:00
Leonardo de Moura
9a202a420b
feat: semiring normalization theorems (#8943)
This PR adds helper theorems for normalizing semirings that do not
implement `AddRightCancel`.
2025-06-23 13:07:46 +00:00
Wojciech Rozowski
489d7b6d72
feat: add antitonicity lemmas for (co)inductive predicates (#8940)
This PR introduces antitonicity lemmas that support the elaboration of
mixed inductive-coinductive predicates defined using the
`least_fixpoint` / `greatest_fixpoint` constructs.

For instance, the following definition elaborates correctly because all
occurrences of the inductively defined predicate `tock `within the
coinductive definition of `tick` appear in negative positions. The dual
situation applies to the definition of `tock`:
```
  mutual
    def tick : Prop :=
      tock → tick
    greatest_fixpoint

    def tock : Prop :=
      tick → tock
    least_fixpoint
  end
```
2025-06-23 11:02:08 +00:00
Joachim Breitner
29298c9f30
feat: linter.loopingSimpArgs (#8865)
This PR allows `simp` to recognize and warn about simp lemmas that are
likely looping in the current simp set. It does so automatically
whenever simplification fails with the dreaded “max recursion depth”
error fails, but it can be made to do it always with `set_option
linter.loopingSimpArgs true`. This check is not on by default because it
is somewhat costly, and can warn about simp calls that still happen to
work.

This closes #5111. In the end, this implemented much simpler logic than
described there (and tried in the abandoned #8688; see that PR
description for more background information), but it didn’t work as well
as I thought. The current logic is:

“Simplify the RHS of the simp theorem, complain if that fails”.

It is a reasonable policy for a Lean project to say that all simp
invocation should be so that this linter does not complain. Often it is
just a matter of explicitly disabling some simp theorems from the
default simp set, to make it clear and robust that in this call, we do
not want them to trigger. But given that often such simp call happen to
work, it’s too pedantic to impose it on everyone.
2025-06-23 07:36:21 +00:00
Kim Morrison
8f4b2909de
chore: cleanup of grind's order typeclasses (#8913)
This PR cleans up `grind`'s internal order typeclasses, removing
unnecessary duplication.
2025-06-22 23:36:48 +00:00
Kyle Miller
f4f664e1ed
fix: update Parser.Term.letIdDeclNoBinders to use new letIdDecl format (#8929)
This PR is a followup to #8914, fixing an oversight where
`letIdDeclBinders` is was not updated with the new format. This relies
on some bootstrapping code to stay in place, but we do bootstrap cleanup
that is currently possible.
2025-06-22 19:28:46 +00:00
Mac Malone
ded8a0cb57
feat: IO.FS.Stream.readToEnd (#8886)
This PR adds `IO.FS.Stream.readToEnd` which parallels
`IO.FS.Handle.readToEnd` along with its upstream definitions (i.e.,
`readBinToEndInto` and `readBinToEnd`). It also removes an unnecessary
`partial` from `IO.FS.Handle.readBinToEnd`.

This function is useful for reading, for example, all of standard input.
2025-06-22 15:39:10 +00:00
Mac Malone
52bdc9bcbd
feat: IO.FS.Stream.lines & IO.FS.Handle.lines (#8887)
This PR generalizes `IO.FS.lines` with `IO.FS.Handle.lines` and adds the
parallel `IO.FS.Stream.lines` for streams.

The stream version is useful for reading, for example, the lines of
standard input.
2025-06-22 14:57:17 +00:00
Sebastian Graf
1e78207d3a
chore: Revert "feat: Upstream MPL.SPred.* from mpl" (#8927)
Reverts leanprover/lean4#8745 until I take a closer look on its breakage
in Mathlib on Monday
2025-06-22 09:02:54 +00:00
Kyle Miller
239534cbb7
chore: for #8914 after stage0 update (#8925)
This PR does a first pass at cleaning things up for #8914 after a stage0
update.
2025-06-22 06:52:11 +00:00
Kyle Miller
219f8214d3
feat: make let and have term syntaxes be consistent (#8914)
This PR modifies `let` and `have` term syntaxes to be consistent with
each other. Adds configuration options; for example, `have` is
equivalent to `let +nondep`, for *nondependent* lets. Other options
include `+usedOnly` (for `let_tmp`), `+zeta` (for `letI`/`haveI`), and
`+postponeValue` (for `let_delayed)`. There is also `let (eq := h) x :=
v; b` for introducing `h : x = v` when elaborating `b`. The `eq` option
works for pattern matching as well, for example `let (eq := h) (x, y) :=
p; b`.

Future PRs will add these options to tactic syntax, once a stage0 update
has been done.
2025-06-22 04:22:47 +00:00
Leonardo de Moura
7531d16112
feat: (commutative) semiring support in grind (#8921)
This PR implements support for (commutative) semirings in `grind`. It
uses the Grothendieck completion to construct a (commutative) ring
`Lean.Grind.Ring.OfSemiring.Q α` from a (commutative) semiring `α`. This
construction is mostly useful for semirings that implement
`AddRightCancel α`. Otherwise, the function `toQ` is not injective.
Examples:
```lean
example (x y : Nat) : x^2*y = 1 → x*y^2 = y → y*x = 1 := by
  grind 

example [CommSemiring α] [AddRightCancel α] (x y : α) : x^2*y = 1 → x*y^2 = y → y*x = 1 := by
  grind

example (a b : Nat) : 3 * a * b = a * b * 3 := by grind

example (k z : Nat) : k * (z * 2 * (z * 2 + 1)) = z * (k * (2 * (z * 2 + 1))) := by grind

example [CommSemiring α] [AddRightCancel α] [IsCharP α 0] (x y : α) 
    : x^2*y = 1 → x*y^2 = y → x + y = 1 → False := by
  grind
```
2025-06-21 23:00:16 +00:00
Joachim Breitner
61518e4357
chore: remove more unused simp args (#8920)
This PR uses the linter from #8901 to clean up more simp arguments,
completing #8905.
2025-06-21 18:34:17 +00:00
Kim Morrison
5198a3fbb7
feat: refactor grind's typeclasses for ordered algebra (#8855)
This PR refactors `Lean.Grind.NatModule/IntModule/Ring.IsOrdered`.

We ensure the the diamond from `Ring` to `NatModule` via either
`Semiring` or `IntModule` is defeq, which was not previously the case.

---------

Co-authored-by: Leonardo de Moura <leomoura@amazon.com>
2025-06-21 04:49:13 +00:00