This PR ensures that even if a type is marked as `irreducible` the
compiler can see through it in
order to discover functions hidden behind type aliases.
This PR fixes a bad error message due to elaborating partial syntax with
Verso docstrings.
When elaborating partial syntax, the elaborator sometimes attempts to
add a docstring for a declaration that it didn't parse a name for. The
name defaults to anonymous, but inserting the docs for the anonymous
name throws a panic about being on the wrong async branch.
With this change, the reported error is the expected parser error
instead, which is much friendlier.
This PR adds infrastructure for the upcoming `grind` tactic mode, which
will be similar to the `conv` mode. The goal is to extend `grind` from a
terminal tactic into an interactive mode: `grind => …`.
It will serve as the foundation for `ungrind`, the process of converting
an expensive (and potentially fragile) `grind` proof into a robust
script. This mode will include tactics for expensive reasoning steps
such as cutsat model-based search, Gröbner basis computation,
E-matching, case splits, and more.
It will also provide robust, succinct references to facts and terms:
labels, structural matches, and anchors (e.g., `#abcd`).
This PR adds the necessary infrastructure for recording elaboration
dependencies that may not be apparent from the resulting environment
such as notations and other metaprograms. An adapted version of `shake`
from Mathlib is added to `script/` but may be moved to another location
or repo in the future.
This PR implements support for negative constraints in `grind order`.
Examples:
```lean
open Lean Grind
example [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsLinearPreorder α]
(a b c d : α) : a ≤ b → ¬ (c ≤ b) → ¬ (d ≤ c) → d < a → False := by
grind -linarith (splits := 0)
example [LE α] [Std.IsLinearPreorder α]
(a b c d : α) : a ≤ b → ¬ (c ≤ b) → ¬ (d ≤ c) → ¬ (a ≤ d) → False := by
grind -linarith (splits := 0)
example [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsLinearPreorder α] [CommRing α] [OrderedRing α]
(a b c d : α) : a - b ≤ 5 → ¬ (c ≤ b) → ¬ (d ≤ c + 2) → d ≤ a - 8 → False := by
grind -linarith (splits := 0)
```
This PR implements support for positive constraints in `grind order`.
The new module can already solve problems such as:
```lean
example [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α]
(a b c : α) : a ≤ b → b ≤ c → c < a → False := by
grind
example [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α]
(a b c d : α) : a ≤ b → b ≤ c → c < d → d ≤ a → False := by
grind
example [LE α] [Std.IsPreorder α]
(a b c : α) : a ≤ b → b ≤ c → a ≤ c := by
grind
example [LE α] [Std.IsPreorder α]
(a b c d : α) : a ≤ b → b ≤ c → c ≤ d → a ≤ d := by
grind
```
It also generalizes support for offset constraints in `grind` to rings.
The new module implements theory propagation and reduces the number of
case splits required to solve problems:
```lean
example [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α] [Ring α] [OrderedRing α]
(a b : α) : a ≤ 5 → b ≤ 8 → a > 6 ∨ b > 10 → False := by
grind -linarith (splits := 0)
example [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α] [CommRing α] [OrderedRing α]
(a b c : α) : a + b*c + 2*c ≤ 5 → a + c > 5 - c - c*b → False := by
grind -linarith (splits := 0)
example (a b : Int) (h : a + b > 5) : (if a + b ≤ 0 then b else a) = a := by
grind -linarith -cutsat (splits := 0)
```
We still need to implement support for negated constraints.
This PR implements the function for adding new edges to the graph used
by `grind order`. The graph maintains the transitive closure of all
asserted constraints.
This PR ensures that Lake only receives recognized CMake build types
from CMake. This fixes an issue with #10581 which broke the
`RelWithAssert` build.
This PR makes Lake no longer error if build outputs found in a trace
file (or in the artifact cache) are ill-formed.
This is caused a problem with the CI cache and is just generally too
strict.
This PR alters `libPrefixOnWindows` behavior to add the `lib` prefix to
the library's `libName` rather than just the file path. This means that
Lake's `-l` will now have the prefix on Windows. While this should not
matter to a MSYS2 build (which accepts both `lib`-prefixed and
unprefixed variants), it should ensure compatibility with MSVC (if that
is ever an issue).
This PR invalidates the CI cache for the Linux Lake build job by bumping
the version of the CI cache key.
The CI cache is broken due to a change in the output format in build
traces. This will be fixed in #10586, but this should prevent further
breakages of PRs in the meantime.
This PR adds a new package configuration option: `restoreAllArtifacts`.
When set to `true` and the Lake local artifact cache is enabled, Lake
will copy all cached artifacts into the build directory. This ensures
they are available for external consumers who expect build results to be
in the build directory.
This PR enables Reservoir packages to be required as dependencies at a
specific package version (i.e., the `version` specified in the package's
configuration file).
This file is essentially just for me and can cause problems with the
language server, so I have removed it from the committed code (and left
an ignored version on my own setup).
* Wrap proof subterms in `by exact` so dependencies can be demoted to
private `import`s
* Remove trivial instance re-definitions that may cause name collisions
on import changes
* Remove unused `open`s that may fail on import removals
This PR ensures that `SPred` proof mode tactics such as `mspec`,
`mintro`, etc. immediately replace the main goal when entering the proof
mode. This prevents `No goals to be solved` errors.
This PR ensures private declarations are accessible from the private
scope iff they are local or imported through an `import all` chain,
including for anonymous notation and structure instance notation.
This PR adds support for case label like syntax in `mvcgen invariants`
in order to refer to inaccessible names. Example:
```lean
def copy (l : List Nat) : Id (Array Nat) := do
let mut acc := #[]
for x in l do
acc := acc.push x
return acc
theorem copy_labelled_invariants (l : List Nat) : ⦃⌜True⌝⦄ copy l ⦃⇓ r => ⌜r = l.toArray⌝⦄ := by
mvcgen [copy] invariants
| inv1 acc => ⇓ ⟨xs, letMuts⟩ => ⌜acc = l.toArray⌝
with admit
```
This PR improves `mvcgen invariants?` to suggest concrete invariants
based on how invariants are used in VCs.
These suggestions are intentionally simplistic and boil down to "this
holds at the start of the loop and this must hold at the end of the
loop":
```lean
def mySum (l : List Nat) : Nat := Id.run do
let mut acc := 0
for x in l do
acc := acc + x
return acc
/--
info: Try this:
invariants
· ⇓⟨xs, letMuts⟩ => ⌜xs.prefix = [] ∧ letMuts = 0 ∨ xs.suffix = [] ∧ letMuts = l.sum⌝
-/
#guard_msgs (info) in
theorem mySum_suggest_invariant (l : List Nat) : mySum l = l.sum := by
generalize h : mySum l = r
apply Id.of_wp_run_eq h
mvcgen invariants?
all_goals admit
```
It still is the user's job to weaken this invariant such that it
interpolates over all loop iterations, but it *is* a good starting point
for iterating. It is also useful because the user does not need to
remember the exact syntax.
This PR simplifies the `grind order` module, and internalizes the order
constraints. It removes the `Offset` type class because it introduced
too much complexity. We now cover the same use cases with a simpler
approach:
- Any type that implements at least `Std.IsPreorder`
- Arbitrary ordered rings.
- `Nat` by the `Nat.ToInt` adapter.
This PR refactors the Lake log monads to take a `LogConfig` structure
when run (rather than multiple arguments). This breaking change should
help minimize future breakages due to changes in configurations options.
In addition, the CLI logging monad stack has been polished up and
`LogIO` now supports the `failLv` configuration option.
This PR adds support for remote artifact caches (e.g., Reservoir) to
Lake. As part of this support, a new suite of `lake cache` CLI commands
has been introduced to help manage Lake's cache. Also, the existing
local cache support has been overhauled for better interplay with the
new remote support.
**Cache CLI**
Artifacts are uploaded to a remote cache via `lake cache put`. This
command takes a JSON Lines input-to-outputs file which describes the
output artifacts for a build (indexed by its input hash). This file can
be produced by a run of `lake build` with the new `-o` option. Lake will
write the input-to-outputs mappings of thee root package artifacts
traversed by the build to the file specified via `-o`. This file can
then be passed to `lake cache put` to upload both it and the built
artifacts from the local cache to the remote cache.
The remote cache service can be customized using the following
environment variables:
* `LAKE_CACHE_KEY`: This is the authorization key for the remote cache.
Lake uploads artifacts via `curl` using the AWS Signature Version 4
protocol, so this should be the S3 `<key>:<secret>` pair expected by
`curl`.
* `LAKE_CACHE_ARTIFACT_ENDPOINT`: This is the base URL to upload (or
download) artifacts to a given remote cache. Artifacts will be stored at
`<endpoint>/<scope/<content-hash>.art`.
* `LAKE_CACHE_REVISION_ENDPOINT`: This is the base URL to upload (or
download) input-to-output mappings to a given remote cache. Mappings are
indexed by the Git revision of the package, and are stored at
`<endpoint>/<scope/<rev>.jsonl`.
The `<scope>` is provided through the `--scope` option to `lake cache
put`. This option is used to prevent one package from overwriting the
artifacts/mappings of another. Lake artifact hashes and Git revisions
hashes are not cryptographically secure, so it is not safe for a service
to store untrusted files across packages in a single flat store.
Once artifacts are available in a remote cache, the `lake cache get`
command can be used to retrieve them. By default, it will fetch
artifacts for the root package's dependencies from Reservoir using its
API. But, like `cache put`, it can be configured to use a custom
endpoint with the above environment variables and an explicit `--scope`.
When so configured, `cache get` will instead download artifacts for the
root package. Lake only downloads artifacts for a single package in this
case, because it cannot deduce the necessary package scopes without
Reservoir.
**Significant local cache changes**
* Lake now always has a cache directory. If Lake cannot find a good
candidate directory on the system for the cache, it will instead store
the cache at `.lake/cache` within the workspace.
* If the local cache is disabled, Lake will not save built artifacts to
the cache. However, Lake will, nonetheless, always attempt to lookup
build artifacts in the cache. If found, the cached artifact will be
copied to the the build location ("restored").
* Input-to-outputs mappings in the local cache are no longer stored in a
single file for a package, but rather in individual files per input (in
the `outputs` subdirectory of the cache).
* Outputs in a trace file, outputs file, or mappings file are now an
`ArtifactDescr`, which is currently composed of both the content hash
and the file extension.
* Trace files now contain a date-based `schemaVersion` to help make
version to version migration easier. Hashes in JSON and in artifacts
names now use a 16-digit hexadecimal encoding (instead of a variable
decimal encoding).
* `buildArtifactUnlessUpToDate` now returns an `Artifact` instead of a
`FilePath`.
**NOTE:** The Lake local cache is still disabled by default. This means
that built artifacts, by default, will not be placed in the cache
directory, and thus will not be available for `lake cache put` to
upload. Users must first explicitly enable the cache by either setting
the `LAKE_ARTIFACT_CACHE` environment variable to a truthy value or by
setting the `enableArtifactCache` package configuration option to
`true`.
This PR changes the way that scientific numerals are parsed in order to
give better error messages for (invalid) syntax like `32.succ`.
Example:
```lean4
#check 32.succ
```
Before, the error message is:
```
unexpected identifier; expected command
```
This is because `32.` parses as a complete float, and `#check 32.`
parses as a complete command, so `succ` is being read as the start of a
new command.
With this change, the error message will move from the `succ` token to
the `32` token (which isn't totally ideal from my perspective) but gives
a less misleading error message and corresponding suggestion:
```
unexpected identifier after decimal point; consider parenthesizing the number
```