This PR adds support for the following import variants to the
experimental module system:
* `private import`: Makes the imported constants available only in
non-exported contexts such as proofs. In particular, the import will not
be loaded, or required to exist at all, when the current module is
imported into other modules.
* `import all`: Makes non-exported information such as proofs of the
imported module available in non-exported contexts in the current
module. Main purpose is to allow for reasoning about imported
definitions when they would otherwise be opaque. TODO: adjust name
resolution so that imported `private` decls are accessible through
syntax.
They can be combined into `private import all`, which will likely be the
most common usage of `import all`.
This PR lets `induction` accept eliminator where the motive application
in the conclusion has complex arguments; these are abstracted over using
`kabstract` if possible. This feature will go well with unfolding
induction principles (#8088).
This PR adds simprocs to simplify appends of non-overlapping Bitvector
adds. We add a simproc instead of just a `simp` lemma to ensure that we
correctly rewrite bitvector appends. Since bitvector appends lead to
computation at the bitvector width level, it seems to be more stable to
write a simproc.
As I write this, I realize that I can maybe write the `simp` lemma using
`no_index` to recover the same behaviour, so I'll try that too.
This PR fixes a bug when constructing the proof term for a
Nullstellensatz certificate produced by the new commutative ring
procedure in `grind`. The kernel was rejecting the proof term.
This PR adds some currently failing tests for `grind +ring`, resulting
in either kernel type mismatches (bugs) or a kernel deep recursion
(perhaps just a too-large problem).
This PR is a follow up to #8055 and implements a `Selector` for async
UDP in order to allow IO multiplexing using UDP sockets.
The technical approach taken for this PR is basically a copy of #8078
but adjusted for UDP. The libuv API gives the same guarantee that was
used in that PR.
This PR changes `Lean.Grind.CommRing` to inline the `NatCast` instance
(i.e. to be provided by the user) rather than constructing one from the
existing data. Without this change we can't construct instances in
Mathlib that `grind` can use.
This PR adds the “unfolding” variant of the functional induction and
functional cases principles, under the name `foo.induct_unfolding` resp.
`foo.fun_cases_unfolding`. These theorems combine induction over the
structure of a recursive function with the unfolding of that function,
and should be more reliable, easier to use and more efficient than just
case-splitting and then rewriting with equational theorems.
For example instead of
```
ackermann.induct
(motive : Nat → Nat → Prop)
(case1 : ∀ (m : Nat), motive 0 m)
(case2 : ∀ (n : Nat), motive n 1 → motive (Nat.succ n) 0)
(case3 : ∀ (n m : Nat), motive (n + 1) m → motive n (ackermann (n + 1) m) → motive (Nat.succ n) (Nat.succ m))
(x x : Nat) : motive x x
```
one gets
```
ackermann.fun_cases_unfolding
(motive : Nat → Nat → Nat → Prop)
(case1 : ∀ (m : Nat), motive 0 m (m + 1))
(case2 : ∀ (n : Nat), motive n.succ 0 (ackermann n 1))
(case3 : ∀ (n m : Nat), motive n.succ m.succ (ackermann n (ackermann (n + 1) m)))
(x✝ x✝¹ : Nat) : motive x✝ x✝¹ (ackermann x✝ x✝¹)
```
This PR is a follow up to #8055 and implements a Selector for
`Std.Channel` in order to allow
multiplexing using channels.
There is one subtlety to the implementation: Suppose we are in a
situation where we run `select` in a loop on two channels. One of the
channels is always quiet while the other has data available occasionally
(however not always as this would trigger the `tryFn` fast path and hide
the issue). In this situation the select receivers that are enqueued on
the silent channel would usually just remain there indefinitely as
nothing ever happens, causing a memleak. To avoid this we want to make a
channel select clean up after itself, even if it fails.
In an imperative programming language we could implement the receive
queue as a doubly linked list and simply make each receive select
maintain a pointer to its element in the queue and then remove itself in
`O(1)` upon failure. As that is not possible in Lean trivially we
decided to go for another approach for now: simply filter the queue for
selects that have failed in `unregisterFn`. While this approach is
`O(n)` we expect the amount of receivers enqueued on a channel to not be
terribly large and thus this to be a reasonably fast operation compared
to the remaining overhead. If it ever ends up becoming an issue, we
could switch to an approach that uses a `TreeMap` with numbered
receivers instead at a certain wait queue size and go to `O(log(n))`.
This PR fixes a mistake in documented time complexity of List.merge.
The running time would only be `O(min |l| |r|)` in the very specific
best case where all the elements in the shorter list are less than all
the elements in the longer list. The worst-case (and average-case) time
complexity is `O(|l| + |r|)`.
Also update the variables in the time complexity to match the names of
the parameters.
This PR adds optimized division functions for `Int` and `Nat` when the
arguments are known to be divisible (such as when normalizing
rationals). These are backed by the gmp functions `mpz_divexact` and
`mpz_divexact_ui`. See also leanprover-community/batteries#1202.
This PR fixes a bug where the old compiler's lcnf conversion expr cache
was not including all of the relevant information in the key, leading to
terms inadvertently being erased. The `root` variable is used to
determine whether lambda arguments to applications should get let
bindings or not, which in turn affects later decisions about type
erasure (erase_irrelevant assumes that any non-atomic argument is
irrelevant).
This PR fixes the `grind +splitImp` and the arrow propagator. Given `p :
Prop`, the propagator was incorrectly assuming `A` was always a
proposition in an arrow `A -> p`. This PR also adds a missing
normalization rule to `grind`.
This PR changes the predicate for `Option.guard` to be `p : α → Bool`
instead of `p : α → Prop`. This brings it in line with other comparable
functions like `Option.filter`.
This PR adds an initial set of `@[grind]` annotations for
`List`/`Array`/`Vector`, enough to set up some regression tests using
`grind` in proofs about `List`. More annotations to follow.
This PR makes `realizeConst` to not set a `declPrefix`. This allows the
realization of both `foo.eq_def` and `bar.eq_def`, where `foo` and `bar`
are mutually recursive, all attached to the same function's environment.
This PR generalises `List.eraseDups` to allow for an arbitrary
comparison relation. Further, it proves `eraseDups_append : (as ++
bs).eraseDups = as.eraseDups ++ (bs.removeAll as).eraseDups`.
This PR adds `List.findRev?` and `List.findSomeRev?`, for parity with
the existing Array API, and simp lemmas converting these into existing
operations.
This PR adds extensional hash maps and hash sets under the names
`Std.ExtDHashMap`, `Std.ExtHashMap` and `Std.ExtHashSet`. Extensional
hash maps work like regular hash maps, except that they have
extensionality lemmas which make them easier to use in proofs. This
however makes it also impossible to regularly iterate over its entries.
This PR improves equality propagation (also known as theory combination)
and polynomial simplification for rings that do not implement the
`NoZeroNatDivisors` class. With these fixes, `grind` can now solve:
```lean
example [CommRing α] (a b c : α) (f : α → Nat)
: a + b + c = 3 →
a^2 + b^2 + c^2 = 5 →
a^3 + b^3 + c^3 = 7 →
f (a^4 + b^4) + f (9 - c^4) ≠ 1 := by
grind +ring
```
This example uses the commutative ring procedure, the linear integer
arithmetic solver, and congruence closure.
For rings that implement `NoZeroNatDivisors`, a polynomial is now also
divided by the greatest common divisor (gcd) of its coefficients when it
is inserted into the basis.
This PR ensures that `set_option grind.debug true` works properly when
using `grind +ring`. It also adds the helper functions `mkPropEq` and
`mkExpectedPropHint`.
This PR fixes the monomial order used by the commutative ring procedure
in `grind`. The following new test now terminates quickly.
```lean
example [CommRing α] (a b c : α)
: a + b + c = 3 →
a^2 + b^2 + c^2 = 5 →
a^3 + b^3 + c^3 = 7 →
a^4 + b^4 + c^4 = 9 := by
grind +ring
```
This PR implements equality propagation in the new commutative ring
procedure in `grind`. The idea is to propagate implied equalities back
to the `grind` core module that does congruence closure. In the
following example, the equalities: `x^2*y = 1` and `x*y^2 - y = 0` imply
that `y*x` is equal to `y*x*y`, which implies by congruence that `f
(y*x) = f (y*x*y)`.
```lean
example [CommRing α] (x y : α) (f : α → Nat) : x^2*y = 1 → x*y^2 - y = 0 → f (y*x) = f (y*x*y) := by
grind +ring
```
This PR updates the If-Normalization example, to separately give an
implementation and subsequently prove the spec (using fun_induction),
instead of previously building a term in the subtype directly. At the
same time, adds a (failing) `grind` test case illustrating a problem
with unused match witnesses.
This PR implements the main loop of the new commutative ring procedure
in `grind`. In the main loop, for each polynomial `p` in the todo queue,
the procedure:
- Simplifies it using the current basis.
- Computes critical pairs with polynomials already in the basis and adds
them to the queue.
After the queue is empty, the disequalities are re-simplified using the
new basis. `grind` can now solve examples such as:
```lean
example [CommRing α] (x y : α) : x*y*x = 1 → x*y*y = y → y = 1 := by
grind +ring
example [CommRing α] (x y : α) : x^2*y = 1 → x*y^2 = y → y*x = 1 := by
grind +ring
example (x y : BitVec 16) : x^2*y = 1 → x*y^2 = y → y*x = 1 := by
grind +ring
```
This PR correctly handles escaping functions in the LCNF
elimDeadBranches pass, by setting all params to top instead of
potentially leaving them at their default bottom value.
This PR implements the generation of compact proof terms for
Nullstellensatz certificates in the new commutative ring procedure in
`grind`. Some examples:
```lean
example [CommRing α] (x y : α) : x = 1 → y = 2 → 2*x + y = 4 := by
grind +ring
example [CommRing α] [IsCharP α 7] (x y : α) : 3*x = 1 → 3*y = 2 → x + y = 1 := by
grind +ring
example [CommRing α] [NoZeroNatDivisors α] (x y : α) : 3*x = 1 → 3*y = 2 → x + y = 1 := by
grind +ring
example (x y z : BitVec 8) : z = y → (x + 1)*(x - 1)*y + y = z*x^2 + 1 → False := by
grind +ring
```
This PR adds the helper type class `NoZeroNatDivisors` for the
commutative ring procedure in `grind`. Core only implements it for
`Int`. It can be instantiated in Mathlib for any type `A` that
implements `NoZeroSMulDivisors Nat A`.
See `findSimp?` and `PolyDerivation` for details on how this instance
impacts the commutative ring procedure.
This PR fixes a parallelism regression where linters that e.g. check for
errors in the command would no longer find such messages.
---------
Co-authored-by: damiano <adomani@gmail.com>
`[wf_preprocess]` expects a dsimp theorem, which in `Init` temporarily
have a simplistic syntactic representation until a more robust solution
is implemented.
This PR reverts #8056 because the implementation there has a bug that is
best fixed with a different approach, and which we should preferably
only merge next release cycle.
This PR fixes the generation of functional induction principles for
functions with nested nested well-founded recursion and late fixed
parameters. This is a follow-up for #7166. Fixes#8093.
This PR is a follow up to #8055 and implements a `Selector` for async
TCP in order to allow IO multiplexing using TCP sockets.
As we must not commit to actually fetching data from the socket buffer
this cannot be implemented by just racing on `recv?`. Instead we perform
a call to `uv_read_start` and pass an `alloc_cb` that allocates no
memory at all. According to the docs of
[`uv_alloc_cb`](https://docs.libuv.org/en/v1.x/handle.html#c.uv_alloc_cb)
this is guaranteed to give us a `UV_ENOBUFS` in the relevant callback.
Thus we can first run this "zero read" and then go into one of three
cases:
1. We get cancelled before the zero read completes, in this case just
cancel the zero read and give up.
2. The zero read completes and we loose the race for completing the
`select`, in this case just don't do anything anymore
3. The zero read completes and we win the race for completing the
`select`, in this case we perform the actual read on the socket. As we
know that data is available already (since the read callback of the zero
read is only triggered if data actually is available) we know that the
subsequent actual read should complete right away.
In this way we avoid any data loss if we loose the race.
This PR contains the theorem proving that signed division x.toInt /
y.toInt only overflows when `x = intMin w` and `y = allOnes w` (for `0 <
w`).
To show that this is the *only* case in which overflow happens, we refer
to overflow for negation
(`BitVec.sdivOverflow_eq_negOverflow_of_neg_one`): in fact,
`x.toInt/(allOnes w).toInt = - x.toInt`, i.e., the overflow conditions
are the same as `negOverflow` for `x`, and then reason about the signs
of the operands with the respective theorems.
These BitVec theorems themselves rely on numerous `Int.ediv_*` theorems,
that carefully set the bounds of signed division for integers.
co-authored by @bollu, @tobiasgrosser
This PR makes sure that the functional induction priciples for mutually
recursive structural functions with extra parameters are split deeply,
as expected.
This PR introduces the modules `Std.Data.DTreeMap.Raw`,
`Std.Data.TreeMap.Raw` and `Std.Data.TreeSet.Raw` and imports them into
`Std.Data`. All modules related to the raw tree maps are imported into
these new modules so that they are now a transitive dependency of `Std`.
This PR ensures that for modules opted into the experimental module
system, we do not import module docstrings or declaration ranges.
Excluding declaration docstrings as well would require some more work to
make `[inherit_doc]` leave a mere reference to the other declaration
instead of copying its docstring eagerly.
This PR adds an implementation of an async IO multiplexing framework as
well as an implementation of it for the `Timer` API in order to
demonstrate it.
The main motivation is to have fair and data loss free multiplexing of
event sources.
To illustrate two situations where just naively racing two tasks that
read from an event source might be the wrong thing:
1. Suppose we are waiting on two channel reads that are continuously
being filled up. As the first channel will always be ready when we start
its receive function it will instantly resolve the race before the
second one can even try. Thus the path where we receive data from the
second channel gets starved. For this reason we want to try in random
order (for fairness) if the event sources already have data available
for us.
2. Suppose we are waiting on two socket reads and both happen to finish
at the same time. As we are now only going to select one of them to
execute further, we are going to loose data on the second one (unless
there is a user written buffering mechanism involved) as we are going to
disregard the buffer it received and do a new receive next time. For
this reason it is important to wait for an event source to be available
without committing to actually fetching some data until we know that
this particular event source is going to win the select race.
The implementation is inspired by the Oslo framework written by
@haesbaert as well as Go's
[`select`](https://go.dev/src/runtime/select.go) implementation. Given a
list of event sources to select one from it is going to:
1. Randomly shuffle them
2. Attempt to fetch data from them (in their new random order) without
blocking (for fairness). If any of them succeeds return right away.
3. If none has data available right away set all of them up to resolve a
promise. They will then race to win the right to resolve that promise.
Only the data source that wins the race is allowed to then actually
fetch data, ensuring that no other event source actually fetches data
and then fails to deliver it to the consumer.
Follow up PRs are going to add implementations of `Selector` for
`Std.Channel` as well as TCP and UDP sockets.
---------
Co-authored-by: Markus Himmel <markus@lean-fro.org>
This PR makes two improvements to the local context when there are
autobound implicits in `variable`s. First, the local context no longer
has two copies of every variable (the local context is rebuilt if the
types of autobound implicits have metavariables). Second, these
metavariables get names using the same algorithm used by binders that
appear in declarations (with `mkForallFVars'` instead of
`mkForallFVars`).
This removes the last use of `Term.addAutoBoundImplicits'`, which
inherently has this variable duplication issue.
This PR implements `EqCnstr.mkNullCertExt`. Given an implied polynomial
equation `p = 0`, it generates the certificate:
```
q₁ * h₁ + … + qₙ * hₙ
```
for `d * p = 0`, where each `qᵢ`s are polynomials and each `hᵢ` is an
equational hypothesis of the form `lhsᵢ = rhsᵢ`. `d` is a numeral.
This PR replaces `Array.Perm` and `Vector.Perm` with one-field
structures. This avoids dot notation for `List` to work like e.g.
`h.cons 3` where `h` is an `Array.Perm`.
This PR fixes a bug where the trace nodes in the InfoView would close
while the file was still being elaborated.
Closes#8053.
The cause of this bug was that we didn't memorize interactive
diagnostics correctly, so the server would generate new RPC pointers in
every single `getInteractiveDiagnostics` RPC request, which lead to the
client resetting the UI.
This PR moves the Lake DSL syntax into a dedicated module with minimal
imports.
This allows modules outside of Lake/Lean to import Lake.DSL.Syntax
without crashing, because it reduces the transitive closure of these
modules' imports. This is needed for the reference manual to be able to
document the DSL syntax.
Additionally, the imports of `Lake.Build.Fetch` are decreased, which
reduces its import closure sufficiently to include docs for `FetchM` in
the reference manual.
This PR fixes a small oversight in the wakeup mechanism of blocked
bounded channel senders that occurs when calling `tryRecv`.
Marked as `changelog-no` as this isn't released yet.
This PR makes `IntCast` a field of `Lean.Grind.CommRing`, along with
additional axioms relating it to negation of `OfNat`. This allows use to
use existing instances which are not definitionally equal to the
previously given construction.
---------
Co-authored-by: Leonardo de Moura <leomoura@amazon.com>
This PR fixes a linearity issue in `bv_decide`'s bitblaster, caused by
the fact that the higher order combinators `AIG.RefVec.zip` and
`AIG.RefVec.fold` were not being properly specialised.
Example benchmark `QF_BV/sage/app1/bench_1967.smt2`:
- before: https://share.firefox.dev/4cE86It
- after: https://share.firefox.dev/42L9chd
This PR implements tactics called `extract_lets` and `lift_lets` that
manipulate `let`/`let_fun` expressions. The `extract_lets` tactic
creates new local declarations extracted from any `let` and `let_fun`
expressions in the main goal. For top-level lets in the target, it is
like the `intros` tactic, but in general it can extract lets from deeper
subexpressions as well. The `lift_lets` tactic moves `let` and `let_fun`
expressions as far out of an expression as possible, but it does not
extract any new local declarations. The option `extract_lets +lift`
combines these behaviors.
This is a re-implementation of `extract_lets` and `lift_lets` from
mathlib. The new `extract_lets` is like doing `lift_lets; extract_lets`,
but it does not lift unextractable lets like `lift_lets`. The
`lift_lets; extract_lets` behavior is now handled by `extract_lets
+lift`. The new `lift_lets` tactic is a frontend to `extract_lets +lift`
machinery, which rather than creating new local definitions instead
represents the accumulated local declarations as top-level lets.
There are also conv tactics for both of these. The `extract_lets` has a
limitation due to the conv architecture; it can extract lets for a given
conv goal, but the local declarations don't survive outside conv. They
get zeta reduced immediately upon leaving conv.
This PR fixes the IR expand_reset_reuse pass to correctly handle
duplicate projections from the same base/index. This does not occur (at
least easily) with the old compiler, but it occurs when bootstrapping
Lean with the new compiler.
This PR makes the following modifications to the new comm ring procedure
in `grind`
1. Adds data-structures for representing equations (and their
justifications), basis, and queue of equations to be processed.
2. Adds `RingM` helper monad.
3. Adds equation simplification main loop
Makes the elaborator constant map truly independent of the kernel's in
preparation for the module system where declarations in the elab env may
in fact differ from the kernel env.
This PR adds support to `grind` for detecting unsatisfiable commutative
ring equations when the ring characteristic is known. Examples:
```lean
example (x : Int) : (x + 1)*(x - 1) = x^2 → False := by
grind +ring
example (x y : Int) : (x + 1)*(x - 1)*y + y = y*x^2 + 1 → False := by
grind +ring
example (x : UInt8) : (x + 1)*(x - 1) = x^2 → False := by
grind +ring
example (x y : BitVec 8) : (x + 1)*(x - 1)*y + y = y*x^2 + 1 → False := by
grind +ring
```
This PR implements basic support for `CommRing` in `grind`. Terms are
already being reified and normalized. We still need to process the
equations, but `grind` can already prove simple examples such as:
```lean
open Lean.Grind in
example [CommRing α] (x : α) : (x + 1)*(x - 1) = x^2 - 1 := by
grind +ring
open Lean.Grind in
example [CommRing α] [IsCharP α 256] (x : α) : (x + 16)*(x - 16) = x^2 := by
grind +ring
example (x : Int) : (x + 1)*(x - 1) = x^2 - 1 := by
grind +ring
example (x : UInt8) : (x + 16)*(x - 16) = x^2 := by
grind +ring
example (x : Int) : (x + 1)^2 - 1 = x^2 + 2*x := by
grind +ring
example (x : BitVec 8) : (x + 16)*(x - 16) = x^2 := by
grind +ring
example (x : BitVec 8) : (x + 1)^2 - 1 = x^2 + 2*x := by
grind +ring
```
This PR fixes bugs in #7809 and #7909 that were not caught partially
because the `badImport` test had been disabled.
**Bugs Fixed:**
* Building by path no longer drops top-level logs.
* "bad import" errors are once again printed.
* Transitively imported precompiled modules are once again loaded during
elaboration.
This PR fixes a bug where pretty printing is done in a context with
cleared local instances. These were cleared since the local context is
updated during a name sanitization step, but preserving local instances
is valid since the modification to the local context only affects user
names.
This showed up when writing the mathlib delaborator for `max` and `min`
(https://github.com/leanprover-community/mathlib4/pull/23558#discussion_r2050787403)
This PR makes the IR elim_dead_branches pass correctly handle extern
functions by considering them as having a top return value. This fix is
required to bootstrap the Init/ directory with the new compiler.
This PR ensures that `mkAppM` can be used to construct terms that are
only type-correct at at default transparency, even if we are in
`withReducible` (e.g. in simp), so that simp does not stumble over
simplifying `let` expression with simplifiable type.reliable.
Here is a reproducer of the issue this solves:
```
example (a b : Nat) (h : a = b):
(let _ : id Bool := true; a) = (let _ : Bool := true; b) := by
simp -zeta -zetaDelta [h]
```
This fixes#7826.
This PR fixes several issues in the `CommRing` multivariate polynomial
library:
1. Replaces the previous array type with the universe polymorphic
`RArray`.
2. Properly eliminates cancelled monomials.
3. Sorts monomials in decreasing order.
4. Marks the parameter `p` of the `IsCharP` class as an output
parameter.
5. Adds `LawfulBEq` instances for the types `Power`, `Mon`, and `Poly`.
This PR fixes the IR elim_dead_branches pass to correctly handle join
points with no params, which currently get considered unreachable. I was
not able to find an easy repro of this with the old compiler, but it
occurs when bootstrapping Lean with the new compiler.
This PR adds the option `debug.terminalTacticsAsSorry`. When enabled,
terminal tactics such as `grind` and `omega` are replaced with `sorry`.
Useful for debugging and fixing bootstrapping issues.
This PR fixes caseOn expressions with an implemented_by to work
correctly with hash consing, even when the elaborator produces terms
that reconstruct the discriminant rather than just reusing a variable.
This PR restricts lifting outside of cases expressions on values of a
Decidable type, since we can't correctly represent the dependency on the
erased proposition in the later stages of the compiler.
This PR changes specialization in the new code generator to consider
callee params to be ground variables, which improves the specialization
of polymorphic functions.
This PR changes eager lambda lifting heuristics in the new compiler to
match the old compiler, which ensures that inlining/specializing monadic
code does not accidentally create mutual tail recursion that the code
generator can't handle.
This PR changes the inlining heuristics of the new code generator to
match the old one, which ensures that monadic folds get sufficiently
inlined for their tail recursion to be exposed to the code generator.
This PR fixes a bug in #7967 that broke external library linking.
This is slipped through because the FFI example no longer uses
`extern_lib`. As such, a separate `extern_lib` test has been added.
This PR removes all type annotations (optional paramters, auto
parameters, out params, semi-out params, not just optional parameters as
before) from the type of functional induction principles.
This PR disables CSE of local function declarations in the base phase of
the new compiler. This was introducing sharing between lambdas to bind
calls w/ `do` notation, which caused them to later no longer be inlined.
This PR upstreams many of the results from `Mathlib/Data/Int/Init.lean`.
Notably, we upstream the `simp` tag on `Int.natCast_pow`. While this is
desirable as a `simp` lemma, it is non-confluent with other good `simp`
lemmas like `Int.emod_bmod_congr`, and this will need to be addressed in
the future.
This PR moves `ReflBEq` to `Init.Core` and changes `LawfulBEq` to extend
`ReflBEq`.
**BREAKING CHANGES:**
- The `refl` field of `ReflBEq` has been renamed to `rfl` to match
`LawfulBEq`
- `LawfulBEq` extends `ReflBEq`, so in particular `LawfulBEq.rfl` is no
longer valid
These tests are currently flaky in `merge-ci` and nightly releases, so
they are being temporarily disabled. Whatever the issue is will be
debugged in a separate PR.
This PR adds an `inheritEnv` field to `IO.Process.SpawnArgs`. If
`false`, the spawned process does not inherit its parent's environment.
For example, Lake will make use of this to ensure that build processes
do not use environment variables that Lake is not properly tracking with
its traces.
This PR adds a `bootstrap` option to Lake which is used to identify the
core Lean package. This enables Lake to use the current stage's include
directory rather than the Lean toolchains when compiling Lean with Lean
in core.
**Breaking change:** The Lean library directory is no longer part of
`getLeanLinkSharedFlags`. FFI users should provide this option
separately when linking to Lean (e.g.. via `s!"-L{(←
getLeanLibDir).toString}"`). See the FFI example for a demonstration.
This PR adds Lake support for building modules given their source file
path. This is made use of in both the CLI and the sever.
As a target specifier, `lake build Foo/Bar.lean` will now look for a
module in the workspace whose source file is `Foo/Bar.lean` and build
it. Facets are support via `lake build Foo/Bar.lean:o`. As such, `:` is
an illegal character in such file names (which is reasonable considering
its use in search paths like `PATH` on Linux).
In the server, `lake setup-file Foo/Bar.lean` will now try to lookup a
module for the source and and build its dependencies, ignoring the
imports specified. This allows Lake to return more specific
configuration for the module requested (e.g., library-specific dynlibs
and plugins). If the path cannot be found in the workspace, Lake will
fallback to its previous behavior.
Finally, like `setup-file`, `lake lean Foo/Bar.lean` will try to lookup
a module for the source path and use its more specific configuration if
possible.
Closes#2756.
This PR modifies the syntax of `induction`, `cases`, and other tactics
that use `Lean.Parser.Tactic.inductionAlts`. If a case omits `=> ...`
then it is assumed to be `=> ?_`. Example:
```lean
example (p : Nat × Nat) : p.1 = p.1 := by
cases p with | _ p1 p2
/-
case mk
p1 p2 : Nat
⊢ (p1, p2).fst = (p1, p2).fst
-/
```
This works with multiple cases as well. Example:
```lean
example (n : Nat) : n + 1 = 1 + n := by
induction n with | zero | succ n ih
/-
case zero
⊢ 0 + 1 = 1 + 0
case succ
n : Nat
ih : n + 1 = 1 + n
⊢ n + 1 + 1 = 1 + (n + 1)
-/
```
The `induction n with | zero | succ n ih` is short for `induction n with
| zero | succ n ih => ?_`, which is short for `induction n with | zero
=> ?_ | succ n ih => ?_`. Note that a consequence of parsing is that
only the last alternative can omit `=>`. Any `=>`-free alternatives
before an alternative with `=>` will be a part of that alternative.
Rationale:
- In the future we may require `tacticSeq` to be indented. For
one-constructor types, this lets the rest of the tactic sequence not
need indentation.
- This is a semi-structured alternative to the `cases'`/`induction'`
tactics in mathlib.
This PR changes Lake build traces to track their mixed inputs. The
tracked inputs are saved as part of the `.trace` file, which can
significantly assist in debugging trace issues. In addition, this PR
tweaks some existing Lake traces. Most significant, module olean traces
no longer incorporate their module's source trace.
This PR ensure that `bv_decide` can handle the simp normal form of a
shift.
Consider:
```lean
theorem test1 (b s : BitVec 5) (hb : b = 0) (hs : s ≠ 0)
: b <<< s = 0 := by
bv_decide
```
This works out, however:
```lean
theorem test2 (b s : BitVec 5) (hb : b = 0) (hs : s ≠ 0)
: b <<< s = 0 := by
simp
bv_decide
```
this fails because the `simp` normal form adds `toNat` to the right hand
argument of the `<<<` and `bv_decide` cannot deal with shifts by
non-constant `Nat`.
Discovered by @spdskatr
This PR adds lemmas about `Int.bmod` to achieve parity between
`Int.bmod` and `Int.emod`/`Int.fmod`/`Int.tmod`. Furthermore, it adds
missing lemmas for `emod`/`fmod`/`tmod` and performs cleanup on names
and statements for all four operations, also with a view towards
increasing consistency with the corresponding `Nat.mod` lemmas.
This PR fixes a bug in bv_decide where if it was presented with a match
on an enum with as many arms as constructors but the last arm being a
default match it would (wrongly) give up on the match.
This PR fixes a potential race between `IO.getTaskState` and the task in
question finishing, resulting in undefined behavior.
All task state must be accessed under the respective lock.
This PR ensures that after `main` is finished we still wait on dedicated
tasks instead of exiting forcefully. If users wish to violently kill
their dedicated tasks at the end of main instead they can run
`IO.Process.exit` at the end of `main` instead.
This PR adds some docstrings to clarify the functions of
`Lean.mkFreshId`, `Lean.Core.mkFreshUserName`,
`Lean.Elab.Term.mkFreshBinderName`, and
`Lean.Meta.mkFreshBinderNameForTactic`.
This PR modifies `all_goals` so that in recovery mode it commits changes
to the state only for those goals for which the tactic succeeds (while
preserving the new message log state). Before, we were trusting that
failing tactics left things in a reasonable state, but now we roll back
and admit the goal. The changes also fixes a bug where we were rolling
back only the metacontext state and not the tactic state, leading to an
inconsistent state (a goal list with metavariables not in the
metacontext). Closes#7883
Alternatively we could stop on the first error, however it is helpful to
see what the tactic did to each goal while interactively writing a
tactic script. There is some non-monotonicity here though since tactics
can solve for metavariables that appear in successive goals, and
conceivably a later goal succeeds only if a previous one does. Given
that the non-monotonicity is limited to recovery mode (which is for
example the RHS and not the LHS of the `<;>` combinator), we think this
is acceptable.
Another justification for the change to roll back the state on each
failure is that we need to admit goals in the failing cases. When a
tactic throws an error, we cannot assume the goal list is meaningful.
Rolling back lets us admit just the goal the tactic started with,
without needing to try to work out which new metavariables should be
admitted in the error state, allowing the tactic to continue trying the
tactic on the next goal.
This PR generalizes some typeclass hypotheses in the `List.Perm` API
(away from `DecidableEq`), and reproduces `List.Perm.mem_iff` for
`Array`, and fixes a mistake in the statement of `Array.Perm.extract`.
This PR adds the attribute `[grind ext]`. It is used to select which
`[ext]` theorems should be used by `grind`. The option `grind +extAll`
instructs `grind` to use all `[ext]` theorems available in the
environment.
After update stage0, we need to add the builtin `[grind ext]`
annotations to key theorems such as `funext`.
This PR adds lemmas about `List/Array/Vector.countP/count` interacting
with `replace`. (Specializing to `_self` and `_ne` lemmas doesn't seem
useful, as there will still be an `if` on the RHS.)
This PR extends `Std.Channel` to provide a full sync and async API, as
well as unbounded, zero sized and bounded channels.
A few notes on the implementation:
- the bounded channel is inspired by [Go channels on
steroids](https://docs.google.com/document/d/1yIAYmbvL3JxOKOjuCyon7JhW4cSv1wy5hC0ApeGMV9s/pub)
though currently doesn't do any of the lock-free optimizations
- @mhuisi convinced me that having a non-closable channel may be a good
idea as this alleviates the need for error handling which is very
annoying when working with `Task`. This does complicate the API a little
bit and I'm not quite sure whether this is a choice we want users to
give. An alternative to this would be to just write `send!` that panics
on sending to a closed channel (receiving from a closed channel is not
an error), this is for example the behavior that golang goes with.
This PR fixes two issues that were preventing `grind` to solve
`getElem?_eq_some_iff`.
1. Missing propagation rule for `Exists p = False`
2. Missing conditions at `isCongrToPrevSplit` a filter for discarding
unnecessary case-splits.
This PR introduces a fast path based on comparing the (cached) hash
value to the `DecidableEq` instance of the core expression data type in
`bv_decide`'s bitblaster.
As we use a good hash function ™️ this should allow us to short
circuit to "not equal" quicker (if appropriate) than currently as we
will often not have to traverse all the way down to the actual conflict.
This in turn should speed up traversing of bucket chains during hash
collisions.
This PR adds a function hook `PersistentEnvExtension.saveEntriesFn` that
can be used to store server-only metadata such as position information
and docstrings that should not affect (re)builds.
This PR adds some missing `List/Array/Vector lemmas` about
`isSome_idxOf?`, `isSome_finIdxOf?`, `isSome_findFinIdx?,
`isSome_findIdx?` and the corresponding `isNone` versions.
This PR fixes an issue introduced bug #6125 where an `inductive` or
`structure` with an autoimplicit parameter with a type that has a
metavariable would lead to a panic. Closes#7788.
This was due to switching from `Term.addAutoBoundImplicits'` to
`Term.addAutoBoundImplicits` and not properly handling metavariables in
the parameters list. To fix this, now the inductive type headers record
the abstracted type and the number of parameters, rather than record the
parameters, the type, the local context, and the local instances. A
benefit to this over `Term.addAutoBoundImplicits'` is that the type's
parameters do not appear twice in the local context.
This PR fixes two bugs in `grind`.
1. Model-based theory combination was creating type incorrect terms.
2. `Nat.cast` vs `NatCast.natCast` issue during normalization.
This PR fixes an issue where `let n : Nat := sorry` in the Infoview
pretty prints as ``n : ℕ := sorry `«Foo:17:17»``. This was caused by
top-level expressions being pretty printed with the same rules as
Infoview hovers. Closes#6715. Refactors `Lean.Widget.ppExprTagged`; now
it takes a delaborator, and downstream users should configure their own
pretty printer option overrides if necessary if they used the `explicit`
argument (see `Lean.Widget.makePopup.ppExprForPopup` for an example).
Breaking change: `ppExprTagged` does not set `pp.proofs` on the root
expression.
This PR cleans up the `Option` development, upstreaming some results
from mathlib in the process.
Notable changes:
- the name `<op>_eq_some_iff` is preferred over `<op>_eq_some`
- the `simp` normal form for `<$>` is `Option.map`, for `>>=` is
`Option.bind` and for `<|>` is `Option.orElse` (for the former two, this
was already true before this PR). All further lemmas about these
operations are now stated only in terms of
`Option.map`/`Option.bind`/`Option.orElse`. Previously, in some cases
both versions were available, with a prime used to disambiguate (the
primed version was usually the "non-ascii-art" version). Now, there are
no lemmas about the ascii-art versions besides the ones turning them
into the non-ascii-art operations, and there is only one version of
every lemma, about the non-ascii-art operation, and named without a
prime.
This PR fixes an oversight in `withFnRefWhenTagAppFns` that causes an
infinite loop when the expression is a constant. This affected pretty
printing of zero-field structures when `pp.tagAppFns` was true (used by
docgen and verso). Closes#7898.
This PR adds `instance [Pure f] : Inhabited (OptionT f α)`, so that
`Inhabited (OptionT Id Empty)` synthesizes.
Co-authored-by: Sebastian Graf <sg@lean-fro.org>
This PR shuffles some results about integers around to make sure that
all material that currently exists about `Int.bmod` is located in
`DivMod/Lemmas.lean` and not downstream of that.
This PR fixes a regression where elaboration of a previous document
version is not cancelled on changes to the document.
Done by removing the default from `SnapshotTask.cancelTk?` and
consistently passing the current thread's token for synchronous
elaboration steps.
This PR adds a mixin typeclass for `Lean.Grind.CommRing` recording the
characteristic of the ring, and constructs instances for `Int`, `IntX`,
`UIntX`, and `BitVec`.
This PR adds `BitVec.pow` and `Pow (BitVec w) Nat`. The implementation
is the naive one, and should later be replaced by an `@[extern]`. This
is tracked at https://github.com/leanprover/lean4/issues/7887.
This PR adds `Int.toNat_sub''` a variant of `Int.toNat_sub` taking
inequality hypotheses, rather than expecting the arguments to be casts
of natural numbers. This is parallel to the existing `toNat_add` and
`toNat_mul`.
This PR adds `UIntX.pow` and `Pow UIntX Nat` instances, and similarly
for signed fixed-width integers. These are currently only the naive
implementation, and will need to be subsequently replaced via
`@[extern]` with fast implementations (tracked at #7887).
This PR fixes a number of bugs related to the handling of the source
search path in the language server, where deleting files could cause
several features to stop functioning and both untitled files and files
that don't exist on disc could have conflicting module names.
In detail, it makes the following adjustments:
- The URI <-> module name conversion was adjusted to produce no name
collisions.
- File URIs in the search path yield a module name relative to the
search path, as before.
- File URIs not in the search path, non-file URIs and non-`.lean` files
yield a `«external:<full uri>»` module name.
- To avoid the issue of the URI -> module name conversion failing when a
file is deleted from disc, we now cache the result of this conversion in
the watchdog and the file worker when the file is first opened.
- All of the URI <-> module name conversions now consistently go through
`Server.documentUriFromModule?` and `moduleFromDocumentUri` to ensure
that we don't have minor deviations for this conversion all over the
place.
- The threading of the source search path through the file worker (from
`lake setup-file`) is removed. It turns out that `lake serve` already
sets the correct source search path in the environment, so we can just
always use the search path from the environment.
- Since we can now answer more requests that need the .ileans in
untitled files, a lot of the tests that test 'Go to definition' needed
to be adjusted so that they use the information from the watchdog, not
the file worker. As we load references asynchronously, this PR adds an
internal `$/lean/waitForILeans` request that tests can use to wait for
all .ilean files to be loaded and for the ilean references from the file
worker for the current document version to be finalized.
- As part of this PR, we noticed that the .ileans aren't available in
the NixOS setup, so @Kha adjusted the Nix CI to fix this.
### Breaking changes
- `Server.documentUriFromModule` has been renamed to
`Server.documentUriFromModule?` and doesn't take a `SearchPath` argument
anymore, as the `SearchPath` is now computed from the `LEAN_SRC_PATH`
environment variable. It has also been moved from `Lean.Server.GoTo` to
`Lean.Server.Utils`.
- `Server.moduleFromDocumentUri` does not take a `SearchPath` argument
anymore and won't return an `Option` anymore. It has also been moved
from `Lean.Server.GoTo` to `Lean.Server.Utils`.
- The `System.SearchPath.searchModuleNameOfUri` function has been
removed. It is recommended to use `Server.moduleFromDocumentUri`
instead.
- The `initSrcSearchPath` function has been renamed to
`getSrcSearchPath` and has been moved from `Lean.Util.Paths` to
`Lean.Util.Path`. It also doesn't need to take a `pkgSearchPath`
argument anymore.
---------
Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
This PR eliminates another source of facts of the form `-1 *
NatCast.natCast x <= 0` for each `x : Nat` in the local context. These
facts are now stored internally in the cutsat state.
cc @kim-em
This PR adjusts the `TryThis` widget to also work in widget messages
rather than only as a panel widget. It also adds additional
documentation explaining why this change was needed.
This PR generalizes the typeclass assumptions on monadic `Option`
functions.
`Option.mapA` is now an alias for `Option.mapM`, which now works for
applicative functors. The changed definition is exactly equivalent for
monads which use the default implementation of `map`, and those who
change it will hopefully choose a definition for `map` that is more
efficient and not less efficient. `Option.mapA` is not deprecated in
order to keep the API aligned with `List` (`List.mapA` and `List.mapM`
cannot be unified because the monadic version is much more efficient
than the applicative version).
This PR fixes a regression introduced in #7445 where the new
`Array.emptyWithCapacity` was accidentally not tagged with the correct
function to actually allocate the capacity.
This PR partially reverts #7818, because the function called
`Option.zipWith` in that PR does not actually correspond to
`List.zipWith`. We choose `Option.merge` as the name instead.
This PR changes definitions and theorems not to use the membership
instance on `Option` unless the theorem is specifically about the
membership instance.
The reasoning for this change is that the lemma `a ∈ o ↔ o = some a` is
a `simp` lemma, and we generally want theorem statements to use `simp`
normal forms.
One notable exception is the `ForIn'` instance, which must use
`Membership` because unlike `GetElem`, `ForIn'` requires the validity
predicate to be expressed via `Membership`.
This PR restores the use of builtins (e.g., initializer, elaborators,
and macros) for DSL features and the use of the Lake plugin in the
server.
The motivation is to avoid elaboration breakages in Lake when core types
need changing (e.g., `Environment`).
This reverts #7399 and partially reverts #7608. The use of the plugin is
more narrow -- it is now just used for elaboration of Lake configuration
files in the server. This should hopefully avoid the reappearance of
#7388.
This PR allows the LRAT parser to accept any proof that derives the
empty clause at somepoint, not necessarily in the last line. Some tools
like lrat-trim occasionally include deletions after the derivation of
the empty clause but the proof is sound as long as it soundly derives
the empty clause somewhere.
This PR improves the normalization of `Bool` terms in `grind`. Recall
that `grind` currently does not case split on Boolean terms to reduce
the size of the search space.
# glibc: use for linking (so Lean programs don't embed newer symbol versions), but not for running (because libc.so, librt.so, and ld.so must be compatible)!
$CP$GLIBC/lib/libc_nonshared.a stage1/lib/glibc
# libpthread_nonshared.a must be linked in order to be able to use `pthread_atfork(3)`. LibUV uses this function.
@@ -3,6 +3,8 @@ Copyright (c) 2020 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Leonardo de Moura
-/
module
prelude
importInit.Data.Format.Basic
importInit.Data.ToString.Macro
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.