mirror of
https://github.com/leanprover/lean4.git
synced 2026-04-05 03:34:08 +00:00
Compare commits
1 Commits
release_ch
...
grind_getK
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e5e2cf558a |
3
.github/workflows/build-template.yml
vendored
3
.github/workflows/build-template.yml
vendored
@@ -82,7 +82,7 @@ jobs:
|
||||
- name: CI Merge Checkout
|
||||
run: |
|
||||
git fetch --depth=1 origin ${{ github.sha }}
|
||||
git checkout FETCH_HEAD flake.nix flake.lock script/prepare-*
|
||||
git checkout FETCH_HEAD flake.nix flake.lock
|
||||
if: github.event_name == 'pull_request'
|
||||
# (needs to be after "Checkout" so files don't get overridden)
|
||||
- name: Setup emsdk
|
||||
@@ -99,6 +99,7 @@ jobs:
|
||||
if: matrix.cmultilib
|
||||
- name: Cache
|
||||
id: restore-cache
|
||||
if: matrix.name != 'Linux Lake'
|
||||
uses: actions/cache/restore@v4
|
||||
with:
|
||||
# NOTE: must be in sync with `save` below
|
||||
|
||||
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@@ -170,8 +170,8 @@ jobs:
|
||||
{
|
||||
"name": "Linux Lake",
|
||||
"os": large ? "nscloud-ubuntu-22.04-amd64-4x8" : "ubuntu-latest",
|
||||
"check-level": 0,
|
||||
// just a secondary build job for now until false positives can be excluded
|
||||
// just a secondary PR build job for now
|
||||
"check-level": isPr ? 0 : 3,
|
||||
"secondary": true,
|
||||
"CMAKE_OPTIONS": "-DUSE_LAKE=ON",
|
||||
// TODO: why does this fail?
|
||||
|
||||
@@ -12,8 +12,6 @@ foreach(var ${vars})
|
||||
get_property(currentHelpString CACHE "${var}" PROPERTY HELPSTRING)
|
||||
if("${var}" MATCHES "STAGE0_(.*)")
|
||||
list(APPEND STAGE0_ARGS "-D${CMAKE_MATCH_1}=${${var}}")
|
||||
elseif("${var}" MATCHES "STAGE1_(.*)")
|
||||
list(APPEND STAGE1_ARGS "-D${CMAKE_MATCH_1}=${${var}}")
|
||||
elseif("${currentHelpString}" MATCHES "No help, variable specified on the command line." OR "${currentHelpString}" STREQUAL "")
|
||||
list(APPEND CL_ARGS "-D${var}=${${var}}")
|
||||
if("${var}" MATCHES "USE_GMP|CHECK_OLEAN_VERSION")
|
||||
@@ -79,29 +77,26 @@ if (USE_MIMALLOC)
|
||||
list(APPEND EXTRA_DEPENDS mimalloc)
|
||||
endif()
|
||||
|
||||
if (NOT STAGE1_PREV_STAGE)
|
||||
ExternalProject_add(stage0
|
||||
SOURCE_DIR "${LEAN_SOURCE_DIR}/stage0"
|
||||
SOURCE_SUBDIR src
|
||||
BINARY_DIR stage0
|
||||
# do not rebuild stage0 when git hash changes; it's not from this commit anyway
|
||||
# (however, CI will override this as we need to embed the githash into the stage 1 library built
|
||||
# by stage 0)
|
||||
CMAKE_ARGS -DSTAGE=0 -DUSE_GITHASH=OFF ${PLATFORM_ARGS} ${STAGE0_ARGS}
|
||||
BUILD_ALWAYS ON # cmake doesn't auto-detect changes without a download method
|
||||
INSTALL_COMMAND "" # skip install
|
||||
DEPENDS ${EXTRA_DEPENDS}
|
||||
)
|
||||
list(APPEND EXTRA_DEPENDS stage0)
|
||||
endif()
|
||||
ExternalProject_add(stage0
|
||||
SOURCE_DIR "${LEAN_SOURCE_DIR}/stage0"
|
||||
SOURCE_SUBDIR src
|
||||
BINARY_DIR stage0
|
||||
# do not rebuild stage0 when git hash changes; it's not from this commit anyway
|
||||
# (however, CI will override this as we need to embed the githash into the stage 1 library built
|
||||
# by stage 0)
|
||||
CMAKE_ARGS -DSTAGE=0 -DUSE_GITHASH=OFF ${PLATFORM_ARGS} ${STAGE0_ARGS}
|
||||
BUILD_ALWAYS ON # cmake doesn't auto-detect changes without a download method
|
||||
INSTALL_COMMAND "" # skip install
|
||||
DEPENDS ${EXTRA_DEPENDS}
|
||||
)
|
||||
ExternalProject_add(stage1
|
||||
SOURCE_DIR "${LEAN_SOURCE_DIR}"
|
||||
SOURCE_SUBDIR src
|
||||
BINARY_DIR stage1
|
||||
CMAKE_ARGS -DSTAGE=1 -DPREV_STAGE=${CMAKE_BINARY_DIR}/stage0 -DPREV_STAGE_CMAKE_EXECUTABLE_SUFFIX=${STAGE0_CMAKE_EXECUTABLE_SUFFIX} ${CL_ARGS} ${STAGE1_ARGS}
|
||||
CMAKE_ARGS -DSTAGE=1 -DPREV_STAGE=${CMAKE_BINARY_DIR}/stage0 -DPREV_STAGE_CMAKE_EXECUTABLE_SUFFIX=${STAGE0_CMAKE_EXECUTABLE_SUFFIX} ${CL_ARGS}
|
||||
BUILD_ALWAYS ON
|
||||
INSTALL_COMMAND ""
|
||||
DEPENDS ${EXTRA_DEPENDS}
|
||||
DEPENDS stage0
|
||||
STEP_TARGETS configure
|
||||
)
|
||||
ExternalProject_add(stage2
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
},
|
||||
{
|
||||
"name": "reldebug",
|
||||
"displayName": "Release with assertions enabled",
|
||||
"displayName": "Release with debug info build config",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "RelWithAssert"
|
||||
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
|
||||
},
|
||||
"generator": "Unix Makefiles",
|
||||
"binaryDir": "${sourceDir}/build/reldebug"
|
||||
|
||||
@@ -144,10 +144,6 @@ We'll use `v4.7.0-rc1` as the intended release version in this example.
|
||||
- Run `script/release_steps.py v4.7.0-rc1 <repo>` (e.g. replacing `<repo>` with `batteries`), which will walk you through the following steps:
|
||||
- Create a new branch off `master`/`main` (as specified in the `branch` field), called `bump_to_v4.7.0-rc1`.
|
||||
- Merge `origin/bump/v4.7.0` if relevant (i.e. `bump-branch: true` appears in `release_repos.yml`).
|
||||
- Otherwise, you *may* need to merge `origin/nightly-testing`.
|
||||
- Note that for `verso` and `reference-manual` development happens on `nightly-testing`, so
|
||||
we will merge that branch into `bump_to_v4.7.0-rc1`, but it is essential in the GitHub interface that we do a rebase merge,
|
||||
in order to preserve the history.
|
||||
- Update the contents of `lean-toolchain` to `leanprover/lean4:v4.7.0-rc1`.
|
||||
- In the `lakefile.toml` or `lakefile.lean`, if there are dependencies on `nightly-testing`, `bump/v4.7.0`, or specific version tags, update them to the new tag.
|
||||
If they depend on `main` or `master`, don't change this; you've just updated the dependency, so `lake update` will take care of modifying the manifest.
|
||||
@@ -155,7 +151,7 @@ We'll use `v4.7.0-rc1` as the intended release version in this example.
|
||||
- Run `lake build && if lake check-test; then lake test; fi` to check things are working.
|
||||
- Commit the changes as `chore: bump toolchain to v4.7.0-rc1` and push.
|
||||
- Create a PR with title "chore: bump toolchain to v4.7.0-rc1".
|
||||
- Merge the PR once CI completes. (Recall: for `verso` and `reference-manual` you will need to do a rebase merge.)
|
||||
- Merge the PR once CI completes.
|
||||
- Re-running `script/release_checklist.py` will then create the tag `v4.7.0-rc1` from `master`/`main` and push it (unless `toolchain-tag: false` in the `release_repos.yml` file)
|
||||
- We do this for the same list of repositories as for stable releases, see above for notes about special cases.
|
||||
As above, there are dependencies between these, and so the process above is iterative.
|
||||
|
||||
102
flake.lock
generated
102
flake.lock
generated
@@ -1,50 +1,112 @@
|
||||
{
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1745636243,
|
||||
"narHash": "sha256-kbNvlQZf8wwok3d2X1kM/TlXH/MZ+03ZNv+IPPBx+DM=",
|
||||
"rev": "f771eb401a46846c1aebd20552521b233dd7e18b",
|
||||
"type": "tarball",
|
||||
"url": "https://releases.nixos.org/nixos/unstable/nixos-25.05pre789333.f771eb401a46/nixexprs.tar.xz"
|
||||
"lastModified": 1710146030,
|
||||
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
"url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz"
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1710889954,
|
||||
"narHash": "sha256-Pr6F5Pmd7JnNEMHHmspZ0qVqIBVxyZ13ik1pJtm2QXk=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "7872526e9c5332274ea5932a0c3270d6e4724f3b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-cadical": {
|
||||
"locked": {
|
||||
"lastModified": 1740791350,
|
||||
"narHash": "sha256-igS2Z4tVw5W/x3lCZeeadt0vcU9fxtetZ/RyrqsCRQ0=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "199169a2135e6b864a888e89a2ace345703c025d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "199169a2135e6b864a888e89a2ace345703c025d",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-old": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1582018169,
|
||||
"narHash": "sha256-qv1iK1IchpZKSeWL3NEs4U5Jl5QVyNHDdiMJvLOI4Yc=",
|
||||
"type": "tarball",
|
||||
"url": "https://releases.nixos.org/nixos/19.03/nixos-19.03.173691.34c7eb7545d/nixexprs.tar.xz"
|
||||
"lastModified": 1581379743,
|
||||
"narHash": "sha256-i1XCn9rKuLjvCdu2UeXKzGLF6IuQePQKFt4hEKRU5oc=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "34c7eb7545d155cc5b6f499b23a7cb1c96ab4d59",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
"url": "https://channels.nixos.org/nixos-19.03/nixexprs.tar.xz"
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-19.03",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-older": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1550657948,
|
||||
"narHash": "sha256-BE0XqzNfzvhhtTXv37LyySyq4moL7z1i1hMvwbFNL/I=",
|
||||
"type": "tarball",
|
||||
"url": "https://releases.nixos.org/nixos/18.03/nixos-18.03.133402.cb0e20d6db9/nixexprs.tar.xz"
|
||||
"lastModified": 1523316493,
|
||||
"narHash": "sha256-5qJS+i5ECICPAKA6FhPLIWkhPKDnOZsZbh2PHYF1Kbs=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "0b307aa73804bbd7a7172899e59ae0b8c347a62d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
"url": "https://channels.nixos.org/nixos-18.03/nixexprs.tar.xz"
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "0b307aa73804bbd7a7172899e59ae0b8c347a62d",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs-cadical": "nixpkgs-cadical",
|
||||
"nixpkgs-old": "nixpkgs-old",
|
||||
"nixpkgs-older": "nixpkgs-older"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
|
||||
33
flake.nix
33
flake.nix
@@ -1,22 +1,29 @@
|
||||
{
|
||||
description = "Lean development flake. Not intended for end users.";
|
||||
|
||||
# We use channels so we're not affected by GitHub's rate limits
|
||||
inputs.nixpkgs.url = "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz";
|
||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
# old nixpkgs used for portable release with older glibc (2.27)
|
||||
inputs.nixpkgs-old.url = "https://channels.nixos.org/nixos-19.03/nixexprs.tar.xz";
|
||||
inputs.nixpkgs-old.url = "github:NixOS/nixpkgs/nixos-19.03";
|
||||
inputs.nixpkgs-old.flake = false;
|
||||
# old nixpkgs used for portable release with older glibc (2.26)
|
||||
inputs.nixpkgs-older.url = "https://channels.nixos.org/nixos-18.03/nixexprs.tar.xz";
|
||||
inputs.nixpkgs-older.url = "github:NixOS/nixpkgs/0b307aa73804bbd7a7172899e59ae0b8c347a62d";
|
||||
inputs.nixpkgs-older.flake = false;
|
||||
# for cadical 2.1.2; sync with CMakeLists.txt by taking commit from https://www.nixhub.io/packages/cadical
|
||||
inputs.nixpkgs-cadical.url = "github:NixOS/nixpkgs/199169a2135e6b864a888e89a2ace345703c025d";
|
||||
inputs.flake-utils.url = "github:numtide/flake-utils";
|
||||
|
||||
outputs = inputs: builtins.foldl' inputs.nixpkgs.lib.attrsets.recursiveUpdate {} (builtins.map (system:
|
||||
outputs = inputs: inputs.flake-utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
pkgs = import inputs.nixpkgs { inherit system; };
|
||||
# An old nixpkgs for creating releases with an old glibc
|
||||
pkgsDist-old = import inputs.nixpkgs-older { inherit system; };
|
||||
# An old nixpkgs for creating releases with an old glibc
|
||||
pkgsDist-old-aarch = import inputs.nixpkgs-old { localSystem.config = "aarch64-unknown-linux-gnu"; };
|
||||
pkgsCadical = import inputs.nixpkgs-cadical { inherit system; };
|
||||
cadical = if pkgs.stdenv.isLinux then
|
||||
# use statically-linked cadical on Linux to avoid glibc versioning troubles
|
||||
pkgsCadical.pkgsStatic.cadical.overrideAttrs { doCheck = false; }
|
||||
else pkgsCadical.cadical;
|
||||
|
||||
lean-packages = pkgs.callPackage (./nix/packages.nix) { src = ./.; };
|
||||
|
||||
@@ -24,7 +31,7 @@
|
||||
stdenv = pkgs.overrideCC pkgs.stdenv lean-packages.llvmPackages.clang;
|
||||
} ({
|
||||
buildInputs = with pkgs; [
|
||||
cmake gmp libuv ccache pkg-config
|
||||
cmake gmp libuv ccache cadical pkg-config
|
||||
lean-packages.llvmPackages.llvm # llvm-symbolizer for asan/lsan
|
||||
gdb
|
||||
tree # for CI
|
||||
@@ -60,17 +67,15 @@
|
||||
GDB = pkgsDist.gdb;
|
||||
});
|
||||
in {
|
||||
packages.${system} = {
|
||||
packages = {
|
||||
# to be removed when Nix CI is not needed anymore
|
||||
inherit (lean-packages) cacheRoots test update-stage0-commit ciShell;
|
||||
deprecated = lean-packages;
|
||||
};
|
||||
|
||||
devShells.${system} = {
|
||||
# The default development shell for working on lean itself
|
||||
default = devShellWithDist pkgs;
|
||||
oldGlibc = devShellWithDist pkgsDist-old;
|
||||
oldGlibcAArch = devShellWithDist pkgsDist-old-aarch;
|
||||
};
|
||||
}) ["x86_64-linux" "aarch64-linux"]);
|
||||
# The default development shell for working on lean itself
|
||||
devShells.default = devShellWithDist pkgs;
|
||||
devShells.oldGlibc = devShellWithDist pkgsDist-old;
|
||||
devShells.oldGlibcAArch = devShellWithDist pkgsDist-old-aarch;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import Lean.Data.Lsp
|
||||
import Lean.Elab.Import
|
||||
open Lean
|
||||
open Lean.Lsp
|
||||
open Lean.JsonRpc
|
||||
@@ -8,7 +7,9 @@ open Lean.JsonRpc
|
||||
Tests language server memory use by repeatedly re-elaborate a given file.
|
||||
|
||||
NOTE: only works on Linux for now.
|
||||
ot to touch the imports for usual files.
|
||||
|
||||
HACK: The line that is to be prepended with a space is hard-coded below to be sufficiently far down
|
||||
not to touch the imports for usual files.
|
||||
-/
|
||||
|
||||
def main (args : List String) : IO Unit := do
|
||||
@@ -32,8 +33,6 @@ def main (args : List String) : IO Unit := do
|
||||
Ipc.writeRequest ⟨0, "initialize", { capabilities : InitializeParams }⟩
|
||||
|
||||
let text ← IO.FS.readFile file
|
||||
let (_, headerEndPos, _) ← Elab.parseImports text
|
||||
let headerEndPos := FileMap.ofString text |>.leanPosToLspPos headerEndPos
|
||||
let mut requestNo : Nat := 1
|
||||
let mut versionNo : Nat := 1
|
||||
Ipc.writeNotification ⟨"textDocument/didOpen", {
|
||||
@@ -41,14 +40,15 @@ def main (args : List String) : IO Unit := do
|
||||
for i in [0:iters.toNat!] do
|
||||
if i > 0 then
|
||||
versionNo := versionNo + 1
|
||||
let pos := { line := 19, character := 0 }
|
||||
let params : DidChangeTextDocumentParams := {
|
||||
textDocument := {
|
||||
uri := uri
|
||||
version? := versionNo
|
||||
}
|
||||
contentChanges := #[TextDocumentContentChangeEvent.rangeChange {
|
||||
start := headerEndPos
|
||||
«end» := headerEndPos
|
||||
start := pos
|
||||
«end» := pos
|
||||
} " "]
|
||||
}
|
||||
let params := toJson params
|
||||
|
||||
@@ -47,10 +47,10 @@ def run_command(command, check=True, capture_output=True):
|
||||
|
||||
|
||||
def clone_repo(repo, temp_dir):
|
||||
"""Clone the repository to a temporary directory."""
|
||||
print(f"Cloning {repo}...")
|
||||
# Remove shallow clone for better merge detection
|
||||
clone_result = run_command(f"gh repo clone {repo} {temp_dir}", check=False)
|
||||
"""Clone the repository to a temporary directory using shallow clone."""
|
||||
print(f"Shallow cloning {repo}...")
|
||||
# Keep the shallow clone for efficiency
|
||||
clone_result = run_command(f"gh repo clone {repo} {temp_dir} -- --depth=1", check=False)
|
||||
if clone_result.returncode != 0:
|
||||
print(f"Failed to clone repository {repo}.")
|
||||
print(f"Error: {clone_result.stderr}")
|
||||
@@ -95,16 +95,26 @@ def check_and_merge(repo, branch, tag, temp_dir):
|
||||
if checkout_result.returncode != 0:
|
||||
return False
|
||||
|
||||
# Try merging the tag directly
|
||||
print(f"Merging {tag} into {branch}...")
|
||||
merge_result = run_command(f"git merge {tag} --no-edit", check=False)
|
||||
# Try merging the tag in a dry-run to check if it can be merged cleanly
|
||||
print(f"Checking if {tag} can be merged cleanly into {branch}...")
|
||||
merge_check = run_command(f"git merge --no-commit --no-ff {tag}", check=False)
|
||||
|
||||
if merge_result.returncode != 0:
|
||||
if merge_check.returncode != 0:
|
||||
print(f"Cannot merge {tag} cleanly into {branch}.")
|
||||
print("Merge conflicts would occur. Aborting merge.")
|
||||
run_command("git merge --abort")
|
||||
return False
|
||||
|
||||
# Abort the test merge
|
||||
run_command("git reset --hard HEAD")
|
||||
|
||||
# Now perform the actual merge and push to remote
|
||||
print(f"Merging {tag} into {branch}...")
|
||||
merge_result = run_command(f"git merge {tag} --no-edit")
|
||||
if merge_result.returncode != 0:
|
||||
print(f"Failed to merge {tag} into {branch}.")
|
||||
return False
|
||||
|
||||
print(f"Pushing changes to remote...")
|
||||
push_result = run_command(f"git push origin {branch}")
|
||||
if push_result.returncode != 0:
|
||||
|
||||
@@ -255,7 +255,6 @@ def main():
|
||||
branch_name = f"releases/v{version_major}.{version_minor}.0"
|
||||
if not branch_exists(lean_repo_url, branch_name, github_token):
|
||||
print(f" ❌ Branch {branch_name} does not exist")
|
||||
print(f" 🟡 After creating the branch, we'll need to check CMake version settings.")
|
||||
lean4_success = False
|
||||
else:
|
||||
print(f" ✅ Branch {branch_name} exists")
|
||||
@@ -361,24 +360,10 @@ def main():
|
||||
if check_stable and not is_release_candidate(toolchain):
|
||||
if not is_merged_into_stable(url, toolchain, "stable", github_token, verbose):
|
||||
org_repo = extract_org_repo_from_url(url)
|
||||
if args.dry_run:
|
||||
print(f" ❌ Tag {toolchain} is not merged into stable")
|
||||
print(f" Run `script/merge_remote.py {org_repo} stable {toolchain}` to merge it")
|
||||
repo_status[name] = False
|
||||
continue
|
||||
else:
|
||||
print(f" … Tag {toolchain} is not merged into stable. Running `script/merge_remote.py {org_repo} stable {toolchain}`...")
|
||||
|
||||
# Run the script to merge the tag
|
||||
subprocess.run(["script/merge_remote.py", org_repo, "stable", toolchain])
|
||||
|
||||
# Check again if the tag is merged now
|
||||
if not is_merged_into_stable(url, toolchain, "stable", github_token, verbose):
|
||||
print(f" ❌ Manual intervention required.")
|
||||
repo_status[name] = False
|
||||
continue
|
||||
|
||||
# This will print in all successful cases - whether tag was merged initially or was merged successfully
|
||||
print(f" ❌ Tag {toolchain} is not merged into stable")
|
||||
print(f" Run `script/merge_remote.py {org_repo} stable {toolchain}` to merge it")
|
||||
repo_status[name] = False
|
||||
continue
|
||||
print(f" ✅ Tag {toolchain} is merged into stable")
|
||||
|
||||
if check_bump:
|
||||
|
||||
@@ -21,19 +21,12 @@ repositories:
|
||||
branch: master
|
||||
dependencies: []
|
||||
|
||||
- name: lean4-cli
|
||||
url: https://github.com/leanprover/lean4-cli
|
||||
toolchain-tag: true
|
||||
stable-branch: false
|
||||
branch: main
|
||||
dependencies: []
|
||||
|
||||
- name: doc-gen4
|
||||
url: https://github.com/leanprover/doc-gen4
|
||||
toolchain-tag: true
|
||||
stable-branch: false
|
||||
branch: main
|
||||
dependencies: [lean4-cli]
|
||||
dependencies: []
|
||||
|
||||
- name: verso
|
||||
url: https://github.com/leanprover/verso
|
||||
@@ -49,13 +42,20 @@ repositories:
|
||||
branch: main
|
||||
dependencies: [verso]
|
||||
|
||||
- name: lean4-cli
|
||||
url: https://github.com/leanprover/lean4-cli
|
||||
toolchain-tag: true
|
||||
stable-branch: false
|
||||
branch: main
|
||||
dependencies: []
|
||||
|
||||
- name: ProofWidgets4
|
||||
url: https://github.com/leanprover-community/ProofWidgets4
|
||||
toolchain-tag: false
|
||||
stable-branch: false
|
||||
branch: main
|
||||
dependencies:
|
||||
- batteries
|
||||
- Batteries
|
||||
|
||||
- name: aesop
|
||||
url: https://github.com/leanprover-community/aesop
|
||||
@@ -63,7 +63,7 @@ repositories:
|
||||
stable-branch: true
|
||||
branch: master
|
||||
dependencies:
|
||||
- batteries
|
||||
- Batteries
|
||||
|
||||
- name: import-graph
|
||||
url: https://github.com/leanprover-community/import-graph
|
||||
@@ -71,8 +71,8 @@ repositories:
|
||||
stable-branch: false
|
||||
branch: main
|
||||
dependencies:
|
||||
- lean4-cli
|
||||
- batteries
|
||||
- Cli
|
||||
- Batteries
|
||||
|
||||
- name: plausible
|
||||
url: https://github.com/leanprover-community/plausible
|
||||
@@ -88,11 +88,10 @@ repositories:
|
||||
branch: master
|
||||
bump-branch: true
|
||||
dependencies:
|
||||
- aesop
|
||||
- Aesop
|
||||
- ProofWidgets4
|
||||
- lean4checker
|
||||
- batteries
|
||||
- lean4-cli
|
||||
- Batteries
|
||||
- doc-gen4
|
||||
- import-graph
|
||||
- plausible
|
||||
@@ -103,4 +102,4 @@ repositories:
|
||||
stable-branch: true
|
||||
branch: master
|
||||
dependencies:
|
||||
- mathlib4
|
||||
- Mathlib
|
||||
|
||||
@@ -68,7 +68,7 @@ def generate_script(repo, version, config):
|
||||
]
|
||||
|
||||
# Special cases for specific repositories
|
||||
if repo_name == "repl":
|
||||
if repo_name == "REPL":
|
||||
script_lines.extend([
|
||||
"lake update",
|
||||
"cd test/Mathlib",
|
||||
@@ -79,7 +79,7 @@ def generate_script(repo, version, config):
|
||||
"./test.sh"
|
||||
])
|
||||
elif dependencies:
|
||||
script_lines.append('perl -pi -e \'s/"v4\\.[0-9]+(\\.[0-9]+)?(-rc[0-9]+)?"/"' + version + '"/g\' lakefile.*')
|
||||
script_lines.append('echo "Please update the dependencies in lakefile.{lean,toml}"')
|
||||
script_lines.append("lake update")
|
||||
|
||||
script_lines.append("")
|
||||
@@ -89,20 +89,13 @@ def generate_script(repo, version, config):
|
||||
""
|
||||
])
|
||||
|
||||
if re.search(r'rc\d+$', version) and repo_name in ["batteries", "mathlib4"]:
|
||||
if re.search(r'rc\d+$', version) and repo_name in ["Batteries", "Mathlib"]:
|
||||
script_lines.extend([
|
||||
"echo 'This repo has nightly-testing infrastructure'",
|
||||
f"git merge origin/bump/{version.split('-rc')[0]}",
|
||||
"echo 'Please resolve any conflicts.'",
|
||||
""
|
||||
])
|
||||
if re.search(r'rc\d+$', version) and repo_name in ["verso", "reference-manual"]:
|
||||
script_lines.extend([
|
||||
"echo 'This repo does development on nightly-testing: remember to rebase merge the PR.'",
|
||||
f"git merge origin/nightly-testing",
|
||||
"echo 'Please resolve any conflicts.'",
|
||||
""
|
||||
])
|
||||
if repo_name != "Mathlib":
|
||||
script_lines.extend([
|
||||
"lake build && if lake check-test; then lake test; fi",
|
||||
@@ -111,7 +104,7 @@ def generate_script(repo, version, config):
|
||||
|
||||
script_lines.extend([
|
||||
'gh pr create --title "chore: bump toolchain to ' + version + '" --body ""',
|
||||
"echo 'Please review the PR and merge or rebase it.'",
|
||||
"echo 'Please review the PR and merge it.'",
|
||||
""
|
||||
])
|
||||
|
||||
|
||||
@@ -191,11 +191,10 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules")
|
||||
|
||||
# Initialize CXXFLAGS.
|
||||
set(CMAKE_CXX_FLAGS "${LEAN_EXTRA_CXX_FLAGS} -DLEAN_BUILD_TYPE=\"${CMAKE_BUILD_TYPE}\" -DLEAN_EXPORTING")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-DLEAN_DEBUG")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-DLEAN_DEBUG -DLEAN_TRACE")
|
||||
set(CMAKE_CXX_FLAGS_MINSIZEREL "-DNDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-DNDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHASSERT "-DLEAN_DEBUG")
|
||||
|
||||
# SPLIT_STACK
|
||||
if (SPLIT_STACK)
|
||||
@@ -222,7 +221,6 @@ elseif (MSVC)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "/Od /Zi ${CMAKE_CXX_FLAGS_DEBUG}")
|
||||
set(CMAKE_CXX_FLAGS_MINSIZEREL "/Os /Zc:inline ${CMAKE_CXX_FLAGS_MINSIZEREL}")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "/O2 /Oi /Oy /Zc:inline ${CMAKE_CXX_FLAGS_RELEASE}")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHASSERT "/O2 /Oi /Oy /Zc:inline ${CMAKE_CXX_FLAGS_RELWITHASSERT}")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/O2 /Oi /Zi ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
|
||||
set(LEAN_EXTRA_LINKER_FLAGS "/LTCG:INCREMENTAL ${LEAN_EXTRA_LINKER_FLAGS}")
|
||||
set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} ${LEAN_EXTRA_LINKER_FLAGS}")
|
||||
@@ -242,13 +240,11 @@ if (NOT MSVC)
|
||||
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os ${CMAKE_CXX_FLAGS_MINSIZEREL}")
|
||||
endif ()
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O3 ${CMAKE_CXX_FLAGS_RELEASE}")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHASSERT "-O3 ${CMAKE_CXX_FLAGS_RELWITHASSERT}")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g3 -fno-omit-frame-pointer ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
|
||||
elseif (MULTI_THREAD)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "/MTd ${CMAKE_CXX_FLAGS_DEBUG}")
|
||||
set(CMAKE_CXX_FLAGS_MINSIZEREL "/MT ${CMAKE_CXX_FLAGS_MINSIZEREL}")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "/MT ${CMAKE_CXX_FLAGS_RELEASE}")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHASSERT "/MT ${CMAKE_CXX_FLAGS_RELWITHASSERT}")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/MT ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
|
||||
endif ()
|
||||
|
||||
@@ -847,4 +843,6 @@ endif()
|
||||
|
||||
if(USE_LAKE AND STAGE EQUAL 1)
|
||||
configure_file(${LEAN_SOURCE_DIR}/lakefile.toml.in ${LEAN_SOURCE_DIR}/lakefile.toml)
|
||||
configure_file(${LEAN_SOURCE_DIR}/lakefile.toml.in ${LEAN_SOURCE_DIR}/../tests/lakefile.toml)
|
||||
configure_file(${LEAN_SOURCE_DIR}/lakefile.toml.in ${LEAN_SOURCE_DIR}/../lakefile.toml)
|
||||
endif()
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2014 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Prelude
|
||||
import Init.Notation
|
||||
|
||||
@@ -4,8 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Joachim Breitner
|
||||
-/
|
||||
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Prelude
|
||||
import Init.Tactics
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2021 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Gabriel Ebner
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.NotationExtra
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2024 Lean FRO, LLC. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura, Mario Carneiro
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Classical
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2020 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura, Mario Carneiro
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.PropLemmas
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2020 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura, Mario Carneiro
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Prelude
|
||||
set_option linter.missingDocs true -- keep it documented
|
||||
@@ -309,6 +307,9 @@ instance boolToSort : CoeSort Bool Prop where
|
||||
instance decPropToBool (p : Prop) [Decidable p] : CoeDep Prop p Bool where
|
||||
coe := decide p
|
||||
|
||||
instance optionCoe {α : Type u} : Coe α (Option α) where
|
||||
coe := some
|
||||
|
||||
instance subtypeCoe {α : Sort u} {p : α → Prop} : CoeOut (Subtype p) α where
|
||||
coe v := v.val
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2016 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Control.Basic
|
||||
import Init.Control.State
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2020 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Author: Leonardo de Moura, Sebastian Ullrich
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Core
|
||||
import Init.BinderNameHint
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2019 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Control.State
|
||||
import Init.Control.Except
|
||||
|
||||
@@ -5,8 +5,6 @@ Authors: Jared Roesch, Sebastian Ullrich
|
||||
|
||||
The Except monad transformer.
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Control.Basic
|
||||
import Init.Control.Id
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2021 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Control.Lawful.Basic
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@ Authors: Sebastian Ullrich
|
||||
|
||||
The identity Monad.
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Core
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2021 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Sebastian Ullrich, Leonardo de Moura, Mario Carneiro
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Control.Lawful.Basic
|
||||
import Init.Control.Lawful.Instances
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2021 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Sebastian Ullrich, Leonardo de Moura, Mario Carneiro
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.SimpLemmas
|
||||
import Init.Meta
|
||||
@@ -144,7 +142,6 @@ class LawfulMonad (m : Type u → Type v) [Monad m] : Prop extends LawfulApplica
|
||||
|
||||
export LawfulMonad (bind_pure_comp bind_map pure_bind bind_assoc)
|
||||
attribute [simp] pure_bind bind_assoc bind_pure_comp
|
||||
attribute [grind] pure_bind
|
||||
|
||||
@[simp] theorem bind_pure [Monad m] [LawfulMonad m] (x : m α) : x >>= pure = x := by
|
||||
show x >>= (fun a => pure (id a)) = x
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2021 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Sebastian Ullrich, Leonardo de Moura, Mario Carneiro
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Control.Lawful.Basic
|
||||
import Init.Control.Except
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Kim Morrison
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Control.Lawful.Basic
|
||||
import Init.RCases
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2017 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura, Sebastian Ullrich
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Option.Basic
|
||||
import Init.Control.Basic
|
||||
@@ -100,7 +98,7 @@ Handles failures by treating them as exceptions of type `Unit`.
|
||||
-/
|
||||
@[always_inline, inline] protected def tryCatch (x : OptionT m α) (handle : Unit → OptionT m α) : OptionT m α := OptionT.mk do
|
||||
let some a ← x | handle ()
|
||||
pure <| some a
|
||||
pure a
|
||||
|
||||
instance : MonadExceptOf Unit (OptionT m) where
|
||||
throw := fun _ => OptionT.fail
|
||||
|
||||
@@ -5,8 +5,6 @@ Authors: Sebastian Ullrich
|
||||
|
||||
The Reader monad transformer for passing immutable State.
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Control.Basic
|
||||
import Init.Control.Id
|
||||
|
||||
@@ -5,8 +5,6 @@ Authors: Leonardo de Moura, Sebastian Ullrich
|
||||
|
||||
The State monad transformer.
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Control.Basic
|
||||
import Init.Control.Id
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2021 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Control.Lawful.Basic
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@ Authors: Leonardo de Moura, Sebastian Ullrich
|
||||
|
||||
The State monad transformer using IO references.
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.System.ST
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@ Authors: Leonardo de Moura
|
||||
|
||||
Notation for operators defined at Prelude.lean
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Tactics
|
||||
import Init.Meta
|
||||
|
||||
@@ -5,8 +5,6 @@ Authors: Leonardo de Moura
|
||||
|
||||
notation, basic datatypes and type classes
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Prelude
|
||||
import Init.SizeOf
|
||||
@@ -23,8 +21,6 @@ which applies to all applications of the function).
|
||||
|
||||
theorem id_def {α : Sort u} (a : α) : id a = a := rfl
|
||||
|
||||
attribute [grind] id
|
||||
|
||||
/--
|
||||
`flip f a b` is `f b a`. It is useful for "point-free" programming,
|
||||
since it can sometimes be used to avoid introducing variables.
|
||||
@@ -940,34 +936,6 @@ term.
|
||||
theorem eqRec_heq {α : Sort u} {φ : α → Sort v} {a a' : α} : (h : a = a') → (p : φ a) → HEq (Eq.recOn (motive := fun x _ => φ x) h p) p
|
||||
| rfl, p => HEq.refl p
|
||||
|
||||
/--
|
||||
Heterogenous equality with an `Eq.rec` application on the left is equivalent to a heterogenous
|
||||
equality on the original term.
|
||||
-/
|
||||
theorem eqRec_heq_iff {α : Sort u} {a : α} {motive : (b : α) → a = b → Sort v}
|
||||
{b : α} {refl : motive a (Eq.refl a)} {h : a = b} {c : motive b h} :
|
||||
HEq (@Eq.rec α a motive refl b h) c ↔ HEq refl c :=
|
||||
h.rec (fun _ => ⟨id, id⟩) c
|
||||
|
||||
/--
|
||||
Heterogenous equality with an `Eq.rec` application on the right is equivalent to a heterogenous
|
||||
equality on the original term.
|
||||
-/
|
||||
theorem heq_eqRec_iff {α : Sort u} {a : α} {motive : (b : α) → a = b → Sort v}
|
||||
{b : α} {refl : motive a (Eq.refl a)} {h : a = b} {c : motive b h} :
|
||||
HEq c (@Eq.rec α a motive refl b h) ↔ HEq c refl :=
|
||||
h.rec (fun _ => ⟨id, id⟩) c
|
||||
|
||||
/--
|
||||
Moves an cast using `Eq.rec` from the function to the argument.
|
||||
Note: because the motive isn't reliably detected by unification,
|
||||
it needs to be provided as an explicit parameter.
|
||||
-/
|
||||
theorem apply_eqRec {α : Sort u} {a : α} (motive : (b : α) → a = b → Sort v)
|
||||
{b : α} {h : a = b} {c : motive a (Eq.refl a) → β} {d : motive b h} :
|
||||
@Eq.rec α a (fun b h => motive b h → β) c b h d = c (h.symm ▸ d) := by
|
||||
cases h; rfl
|
||||
|
||||
/--
|
||||
If casting a term with `Eq.rec` to another type makes it equal to some other term, then the two
|
||||
terms are heterogeneously equal.
|
||||
@@ -1013,7 +981,7 @@ theorem HEq.comm {a : α} {b : β} : HEq a b ↔ HEq b a := Iff.intro HEq.symm H
|
||||
theorem heq_comm {a : α} {b : β} : HEq a b ↔ HEq b a := HEq.comm
|
||||
|
||||
@[symm] theorem Iff.symm (h : a ↔ b) : b ↔ a := Iff.intro h.mpr h.mp
|
||||
theorem Iff.comm : (a ↔ b) ↔ (b ↔ a) := Iff.intro Iff.symm Iff.symm
|
||||
theorem Iff.comm: (a ↔ b) ↔ (b ↔ a) := Iff.intro Iff.symm Iff.symm
|
||||
theorem iff_comm : (a ↔ b) ↔ (b ↔ a) := Iff.comm
|
||||
|
||||
@[symm] theorem And.symm : a ∧ b → b ∧ a := fun ⟨ha, hb⟩ => ⟨hb, ha⟩
|
||||
@@ -1178,12 +1146,12 @@ theorem dif_eq_if (c : Prop) {h : Decidable c} {α : Sort u} (t : α) (e : α) :
|
||||
| isTrue _ => rfl
|
||||
| isFalse _ => rfl
|
||||
|
||||
instance {c t e : Prop} [dC : Decidable c] [dT : Decidable t] [dE : Decidable e] : Decidable (if c then t else e) :=
|
||||
instance {c t e : Prop} [dC : Decidable c] [dT : Decidable t] [dE : Decidable e] : Decidable (if c then t else e) :=
|
||||
match dC with
|
||||
| isTrue _ => dT
|
||||
| isFalse _ => dE
|
||||
|
||||
instance {c : Prop} {t : c → Prop} {e : ¬c → Prop} [dC : Decidable c] [dT : ∀ h, Decidable (t h)] [dE : ∀ h, Decidable (e h)] : Decidable (if h : c then t h else e h) :=
|
||||
instance {c : Prop} {t : c → Prop} {e : ¬c → Prop} [dC : Decidable c] [dT : ∀ h, Decidable (t h)] [dE : ∀ h, Decidable (e h)] : Decidable (if h : c then t h else e h) :=
|
||||
match dC with
|
||||
| isTrue hc => dT hc
|
||||
| isFalse hc => dE hc
|
||||
@@ -1899,7 +1867,9 @@ protected abbrev hrecOn
|
||||
(f : (a : α) → motive (Quot.mk r a))
|
||||
(c : (a b : α) → (p : r a b) → HEq (f a) (f b))
|
||||
: motive q :=
|
||||
Quot.recOn q f fun a b p => eq_of_heq (eqRec_heq_iff.mpr (c a b p))
|
||||
Quot.recOn q f fun a b p => eq_of_heq <|
|
||||
have p₁ : HEq (Eq.ndrec (f a) (sound p)) (f a) := eqRec_heq (sound p) (f a)
|
||||
HEq.trans p₁ (c a b p)
|
||||
|
||||
end
|
||||
end Quot
|
||||
@@ -2262,27 +2232,6 @@ theorem funext {α : Sort u} {β : α → Sort v} {f g : (x : α) → β x}
|
||||
show extfunApp (Quot.mk eqv f) = extfunApp (Quot.mk eqv g)
|
||||
exact congrArg extfunApp (Quot.sound h)
|
||||
|
||||
/--
|
||||
Like `Quot.liftOn q f h` but allows `f a` to "know" that `q = Quot.mk r a`.
|
||||
-/
|
||||
protected abbrev Quot.pliftOn {α : Sort u} {r : α → α → Prop}
|
||||
(q : Quot r)
|
||||
(f : (a : α) → q = Quot.mk r a → β)
|
||||
(h : ∀ (a b : α) (h h'), r a b → f a h = f b h') : β :=
|
||||
q.rec (motive := fun q' => q = q' → β) f
|
||||
(fun a b p => funext fun h' =>
|
||||
(apply_eqRec (motive := fun b _ => q = b)).trans
|
||||
(@h a b (h'.trans (sound p).symm) h' p)) rfl
|
||||
|
||||
/--
|
||||
Like `Quotient.liftOn q f h` but allows `f a` to "know" that `q = Quotient.mk s a`.
|
||||
-/
|
||||
protected abbrev Quotient.pliftOn {α : Sort u} {s : Setoid α}
|
||||
(q : Quotient s)
|
||||
(f : (a : α) → q = Quotient.mk s a → β)
|
||||
(h : ∀ (a b : α) (h h'), a ≈ b → f a h = f b h') : β :=
|
||||
Quot.pliftOn q f h
|
||||
|
||||
instance Pi.instSubsingleton {α : Sort u} {β : α → Sort v} [∀ a, Subsingleton (β a)] :
|
||||
Subsingleton (∀ a, β a) where
|
||||
allEq f g := funext fun a => Subsingleton.elim (f a) (g a)
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2016 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Basic
|
||||
import Init.Data.Nat
|
||||
|
||||
@@ -4,8 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Dany Fabian
|
||||
-/
|
||||
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Classical
|
||||
import Init.ByCases
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2017 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Gabriel Ebner
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Array.Basic
|
||||
import Init.Data.Array.QSort
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2021 Floris van Doorn. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Joachim Breitner, Mario Carneiro
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Array.Mem
|
||||
import Init.Data.Array.Lemmas
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2018 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.WFTactics
|
||||
import Init.Data.Nat.Basic
|
||||
@@ -40,11 +38,11 @@ namespace Array
|
||||
|
||||
/-! ### Preliminary theorems -/
|
||||
|
||||
@[simp, grind] theorem size_set {xs : Array α} {i : Nat} {v : α} (h : i < xs.size) :
|
||||
@[simp] theorem size_set {xs : Array α} {i : Nat} {v : α} (h : i < xs.size) :
|
||||
(set xs i v h).size = xs.size :=
|
||||
List.length_set ..
|
||||
|
||||
@[simp, grind] theorem size_push {xs : Array α} (v : α) : (push xs v).size = xs.size + 1 :=
|
||||
@[simp] theorem size_push {xs : Array α} (v : α) : (push xs v).size = xs.size + 1 :=
|
||||
List.length_concat ..
|
||||
|
||||
theorem ext {xs ys : Array α}
|
||||
@@ -110,7 +108,7 @@ theorem mem_def {a : α} {as : Array α} : a ∈ as ↔ a ∈ as.toList :=
|
||||
@[simp] theorem mem_toArray {a : α} {l : List α} : a ∈ l.toArray ↔ a ∈ l := by
|
||||
simp [mem_def]
|
||||
|
||||
@[simp, grind] theorem getElem_mem {xs : Array α} {i : Nat} (h : i < xs.size) : xs[i] ∈ xs := by
|
||||
@[simp] theorem getElem_mem {xs : Array α} {i : Nat} (h : i < xs.size) : xs[i] ∈ xs := by
|
||||
rw [Array.mem_def, ← getElem_toList]
|
||||
apply List.getElem_mem
|
||||
|
||||
@@ -194,7 +192,7 @@ Examples:
|
||||
def pop (xs : Array α) : Array α where
|
||||
toList := xs.toList.dropLast
|
||||
|
||||
@[simp, grind] theorem size_pop {xs : Array α} : xs.pop.size = xs.size - 1 := by
|
||||
@[simp] theorem size_pop {xs : Array α} : xs.pop.size = xs.size - 1 := by
|
||||
match xs with
|
||||
| ⟨[]⟩ => rfl
|
||||
| ⟨a::as⟩ => simp [pop, Nat.succ_sub_succ_eq_sub, size]
|
||||
@@ -836,7 +834,7 @@ some 10
|
||||
def findSomeM? {α : Type u} {β : Type v} {m : Type v → Type w} [Monad m] (f : α → m (Option β)) (as : Array α) : m (Option β) := do
|
||||
for a in as do
|
||||
match (← f a) with
|
||||
| some b => return some b
|
||||
| some b => return b
|
||||
| _ => pure ⟨⟩
|
||||
return none
|
||||
|
||||
@@ -867,7 +865,7 @@ some 1
|
||||
def findM? {α : Type} [Monad m] (p : α → m Bool) (as : Array α) : m (Option α) := do
|
||||
for a in as do
|
||||
if (← p a) then
|
||||
return some a
|
||||
return a
|
||||
return none
|
||||
|
||||
/--
|
||||
@@ -1175,7 +1173,7 @@ def find? {α : Type u} (p : α → Bool) (as : Array α) : Option α :=
|
||||
Id.run do
|
||||
for a in as do
|
||||
if p a then
|
||||
return some a
|
||||
return a
|
||||
return none
|
||||
|
||||
/--
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2022 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Array.Basic
|
||||
import Init.Data.Nat.Linear
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2019 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Array.Basic
|
||||
import Init.Data.Int.DivMod.Lemmas
|
||||
|
||||
@@ -4,8 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Mario Carneiro
|
||||
-/
|
||||
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.List.TakeDrop
|
||||
|
||||
@@ -112,19 +110,19 @@ abbrev pop_toList := @Array.toList_pop
|
||||
|
||||
@[simp] theorem toList_empty : (#[] : Array α).toList = [] := rfl
|
||||
|
||||
@[simp, grind] theorem append_empty {xs : Array α} : xs ++ #[] = xs := by
|
||||
@[simp] theorem append_empty {xs : Array α} : xs ++ #[] = xs := by
|
||||
apply ext'; simp only [toList_append, toList_empty, List.append_nil]
|
||||
|
||||
@[deprecated append_empty (since := "2025-01-13")]
|
||||
abbrev append_nil := @append_empty
|
||||
|
||||
@[simp, grind] theorem empty_append {xs : Array α} : #[] ++ xs = xs := by
|
||||
@[simp] theorem empty_append {xs : Array α} : #[] ++ xs = xs := by
|
||||
apply ext'; simp only [toList_append, toList_empty, List.nil_append]
|
||||
|
||||
@[deprecated empty_append (since := "2025-01-13")]
|
||||
abbrev nil_append := @empty_append
|
||||
|
||||
@[simp, grind _=_] theorem append_assoc {xs ys zs : Array α} : xs ++ ys ++ zs = xs ++ (ys ++ zs) := by
|
||||
@[simp] theorem append_assoc {xs ys zs : Array α} : xs ++ ys ++ zs = xs ++ (ys ++ zs) := by
|
||||
apply ext'; simp only [toList_append, List.append_assoc]
|
||||
|
||||
@[simp] theorem appendList_eq_append {xs : Array α} {l : List α} : xs.appendList l = xs ++ l := rfl
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Kim Morrison
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Array.Lemmas
|
||||
import Init.Data.List.Nat.Count
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2022 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Array.Basic
|
||||
import Init.Data.BEq
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Kim Morrison
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Array.Lemmas
|
||||
import Init.Data.List.Nat.Erase
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Kim Morrison
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Array.Lemmas
|
||||
import Init.Data.List.Nat.TakeDrop
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2024 François G. Dorais. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: François G. Dorais
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.List.FinRange
|
||||
import Init.Data.Array.OfFn
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2024 Lean FRO, LLC. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Kim Morrison
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.List.Nat.Find
|
||||
import Init.Data.Array.Lemmas
|
||||
@@ -23,11 +21,10 @@ open Nat
|
||||
|
||||
/-! ### findSome? -/
|
||||
|
||||
@[simp, grind] theorem findSome?_empty : (#[] : Array α).findSome? f = none := rfl
|
||||
@[simp, grind] theorem findSome?_push {xs : Array α} : (xs.push a).findSome? f = (xs.findSome? f).or (f a) := by
|
||||
@[simp] theorem findSome?_empty : (#[] : Array α).findSome? f = none := rfl
|
||||
@[simp] theorem findSome?_push {xs : Array α} : (xs.push a).findSome? f = (xs.findSome? f).or (f a) := by
|
||||
cases xs; simp [List.findSome?_append]
|
||||
|
||||
@[grind]
|
||||
theorem findSome?_singleton {a : α} {f : α → Option β} : #[a].findSome? f = f a := by
|
||||
simp
|
||||
|
||||
@@ -38,7 +35,7 @@ theorem findSome?_singleton {a : α} {f : α → Option β} : #[a].findSome? f =
|
||||
cases xs; simp_all
|
||||
|
||||
theorem exists_of_findSome?_eq_some {f : α → Option β} {xs : Array α} (w : xs.findSome? f = some b) :
|
||||
∃ a, a ∈ xs ∧ f a = some b := by
|
||||
∃ a, a ∈ xs ∧ f a = b := by
|
||||
cases xs; simp_all [List.exists_of_findSome?_eq_some]
|
||||
|
||||
@[simp] theorem findSome?_eq_none_iff : findSome? p xs = none ↔ ∀ x ∈ xs, p x = none := by
|
||||
|
||||
@@ -4,8 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura
|
||||
-/
|
||||
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Array.Basic
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Kim Morrison
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Array.Lemmas
|
||||
import Init.Data.List.Nat.InsertIdx
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2018 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Array.Basic
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,8 +3,6 @@ Copyright (c) 2024 Lean FRO. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Author: Kim Morrison
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Array.Lex.Basic
|
||||
import Init.Data.Array.Lex.Lemmas
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2024 Lean FRO. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Author: Kim Morrison
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Array.Basic
|
||||
import Init.Data.Nat.Lemmas
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2024 Lean FRO. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Author: Kim Morrison
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Array.Lemmas
|
||||
import Init.Data.List.Lex
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2022 Mario Carneiro. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Mario Carneiro, Kim Morrison
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Array.Lemmas
|
||||
import Init.Data.Array.Attach
|
||||
@@ -66,7 +64,7 @@ theorem mapFinIdx_spec {xs : Array α} {f : (i : Nat) → α → (h : i < xs.siz
|
||||
|
||||
@[simp] theorem getElem?_mapFinIdx {xs : Array α} {f : (i : Nat) → α → (h : i < xs.size) → β} {i : Nat} :
|
||||
(xs.mapFinIdx f)[i]? =
|
||||
xs[i]?.pbind fun b h => some <| f i b (getElem?_eq_some_iff.1 h).1 := by
|
||||
xs[i]?.pbind fun b h => f i b (getElem?_eq_some_iff.1 h).1 := by
|
||||
simp only [getElem?_def, size_mapFinIdx, getElem_mapFinIdx]
|
||||
split <;> simp_all
|
||||
|
||||
@@ -155,7 +153,7 @@ theorem mk_mem_zipIdx_iff_le_and_getElem?_sub {k i : Nat} {x : α} {xs : Array
|
||||
/-- Variant of `mk_mem_zipIdx_iff_le_and_getElem?_sub` specialized at `k = 0`,
|
||||
to avoid the inequality and the subtraction. -/
|
||||
theorem mk_mem_zipIdx_iff_getElem? {x : α} {i : Nat} {xs : Array α} :
|
||||
(x, i) ∈ xs.zipIdx ↔ xs[i]? = some x := by
|
||||
(x, i) ∈ xs.zipIdx ↔ xs[i]? = x := by
|
||||
rw [mk_mem_zipIdx_iff_le_and_getElem?_sub]
|
||||
simp
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2022 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura, Joachim Breitner
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Array.Basic
|
||||
import Init.Data.Nat.Linear
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2024 Lean FRO, LLC. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Kim Morrison
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Array.Lemmas
|
||||
import Init.Data.Array.Attach
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Kim Morrison
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Array.Lemmas
|
||||
import Init.Data.List.OfFn
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2024 Lean FRO. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Kim Morrison
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.List.Nat.Perm
|
||||
import Init.Data.Array.Lemmas
|
||||
@@ -22,91 +20,56 @@ open List
|
||||
This is a wrapper around `List.Perm`, and for now has much less API.
|
||||
For more complicated verification, use `perm_iff_toList_perm` and the `List` API.
|
||||
-/
|
||||
structure Perm (as bs : Array α) : Prop where
|
||||
of_toList_perm ::
|
||||
toList : as.toList ~ bs.toList
|
||||
def Perm (as bs : Array α) : Prop :=
|
||||
as.toList ~ bs.toList
|
||||
|
||||
@[inherit_doc] scoped infixl:50 " ~ " => Perm
|
||||
|
||||
theorem perm_iff_toList_perm {as bs : Array α} : as ~ bs ↔ as.toList ~ bs.toList :=
|
||||
⟨Perm.toList, Perm.of_toList_perm⟩
|
||||
theorem perm_iff_toList_perm {as bs : Array α} : as ~ bs ↔ as.toList ~ bs.toList := Iff.rfl
|
||||
|
||||
end Array
|
||||
|
||||
namespace List
|
||||
|
||||
open Array
|
||||
|
||||
theorem perm_iff_toArray_perm {as bs : List α} : as ~ bs ↔ as.toArray ~ bs.toArray := by
|
||||
@[simp] theorem perm_toArray (as bs : List α) : as.toArray ~ bs.toArray ↔ as ~ bs := by
|
||||
simp [perm_iff_toList_perm]
|
||||
|
||||
theorem Perm.of_toArray_perm {as bs : List α} : as.toArray ~ bs.toArray → as ~ bs :=
|
||||
perm_iff_toArray_perm.mpr
|
||||
|
||||
theorem Perm.toArray {as bs : List α} : as ~ bs → as.toArray ~ bs.toArray :=
|
||||
perm_iff_toArray_perm.mp
|
||||
|
||||
end List
|
||||
|
||||
namespace Array
|
||||
|
||||
open List
|
||||
|
||||
@[simp, refl] protected theorem Perm.refl (xs : Array α) : xs ~ xs := by
|
||||
cases xs
|
||||
simp [perm_iff_toList_perm]
|
||||
simp
|
||||
|
||||
protected theorem Perm.rfl {xs : Array α} : xs ~ xs := .refl _
|
||||
|
||||
theorem Perm.of_eq {xs ys : Array α} (h : xs = ys) : xs ~ ys := h ▸ .rfl
|
||||
|
||||
@[symm]
|
||||
protected theorem Perm.symm {xs ys : Array α} (h : xs ~ ys) : ys ~ xs := by
|
||||
cases xs; cases ys
|
||||
simp only [perm_iff_toList_perm] at h
|
||||
simpa [perm_iff_toList_perm] using h.symm
|
||||
simp only [perm_toArray] at h
|
||||
simpa using h.symm
|
||||
|
||||
protected theorem Perm.trans {xs ys zs : Array α} (h₁ : xs ~ ys) (h₂ : ys ~ zs) : xs ~ zs := by
|
||||
cases xs; cases ys; cases zs
|
||||
simp only [perm_iff_toList_perm] at h₁ h₂
|
||||
simpa [perm_iff_toList_perm] using h₁.trans h₂
|
||||
simp only [perm_toArray] at h₁ h₂
|
||||
simpa using h₁.trans h₂
|
||||
|
||||
instance : Trans (Perm (α := α)) (Perm (α := α)) (Perm (α := α)) where
|
||||
trans h₁ h₂ := Perm.trans h₁ h₂
|
||||
|
||||
theorem perm_comm {xs ys : Array α} : xs ~ ys ↔ ys ~ xs := ⟨Perm.symm, Perm.symm⟩
|
||||
|
||||
theorem Perm.size_eq {xs ys : Array α} (p : xs ~ ys) : xs.size = ys.size := by
|
||||
theorem Perm.length_eq {xs ys : Array α} (p : xs ~ ys) : xs.size = ys.size := by
|
||||
cases xs; cases ys
|
||||
simp only [perm_iff_toList_perm] at p
|
||||
simp only [perm_toArray] at p
|
||||
simpa using p.length_eq
|
||||
|
||||
@[deprecated Perm.size_eq (since := "2025-04-17")]
|
||||
abbrev Perm.length_eq := @Perm.size_eq
|
||||
|
||||
theorem Perm.mem_iff {a : α} {xs ys : Array α} (p : xs ~ ys) : a ∈ xs ↔ a ∈ ys := by
|
||||
rcases xs with ⟨xs⟩
|
||||
rcases ys with ⟨ys⟩
|
||||
simp only [perm_iff_toList_perm] at p
|
||||
simp at p
|
||||
simpa using p.mem_iff
|
||||
|
||||
theorem Perm.append {xs ys as bs : Array α} (p₁ : xs ~ ys) (p₂ : as ~ bs) :
|
||||
xs ++ as ~ ys ++ bs := by
|
||||
cases xs; cases ys; cases as; cases bs
|
||||
simp only [append_toArray, perm_iff_toList_perm] at p₁ p₂ ⊢
|
||||
exact p₁.append p₂
|
||||
|
||||
theorem Perm.push (x : α) {xs ys : Array α} (p : xs ~ ys) :
|
||||
xs.push x ~ ys.push x := by
|
||||
rw [push_eq_append_singleton]
|
||||
exact p.append .rfl
|
||||
|
||||
theorem Perm.push_comm (x y : α) {xs ys : Array α} (p : xs ~ ys) :
|
||||
theorem Perm.push (x y : α) {xs ys : Array α} (p : xs ~ ys) :
|
||||
(xs.push x).push y ~ (ys.push y).push x := by
|
||||
cases xs; cases ys
|
||||
simp only [perm_iff_toList_perm] at p
|
||||
simp only [push_toArray, List.append_assoc, singleton_append, perm_iff_toList_perm]
|
||||
exact p.append (Perm.swap ..)
|
||||
simp only [perm_toArray] at p
|
||||
simp only [push_toArray, List.append_assoc, singleton_append, perm_toArray]
|
||||
exact p.append (Perm.swap' _ _ Perm.nil)
|
||||
|
||||
theorem swap_perm {xs : Array α} {i j : Nat} (h₁ : i < xs.size) (h₂ : j < xs.size) :
|
||||
xs.swap i j ~ xs := by
|
||||
@@ -118,10 +81,10 @@ namespace Perm
|
||||
set_option linter.indexVariables false in
|
||||
theorem extract {xs ys : Array α} (h : xs ~ ys) {lo hi : Nat}
|
||||
(wlo : ∀ i, i < lo → xs[i]? = ys[i]?) (whi : ∀ i, hi ≤ i → xs[i]? = ys[i]?) :
|
||||
xs.extract lo hi ~ ys.extract lo hi := by
|
||||
(xs.extract lo hi) ~ (ys.extract lo hi) := by
|
||||
rcases xs with ⟨xs⟩
|
||||
rcases ys with ⟨ys⟩
|
||||
simp_all only [perm_iff_toList_perm, List.getElem?_toArray, List.extract_toArray,
|
||||
simp_all only [perm_toArray, List.getElem?_toArray, List.extract_toArray,
|
||||
List.extract_eq_drop_take]
|
||||
apply List.Perm.take_of_getElem? (w := fun i h => by simpa using whi (lo + i) (by omega))
|
||||
apply List.Perm.drop_of_getElem? (w := wlo)
|
||||
|
||||
@@ -1,9 +1,68 @@
|
||||
/-
|
||||
Copyright (c) 2024 Lean FRO. All rights reserved.
|
||||
Copyright (c) 2019 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Kim Morrison
|
||||
Authors: Leonardo de Moura
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Array.QSort.Basic
|
||||
import Init.Data.Vector.Basic
|
||||
import Init.Data.Ord
|
||||
|
||||
set_option linter.listVariables true -- Enforce naming conventions for `List`/`Array`/`Vector` variables.
|
||||
-- We do not enable `linter.indexVariables` because it is helpful to name index variables `lo`, `mid`, `hi`, etc.
|
||||
|
||||
namespace Array
|
||||
|
||||
private def qpartition {n} (as : Vector α n) (lt : α → α → Bool) (lo hi : Nat)
|
||||
(hlo : lo < n := by omega) (hhi : hi < n := by omega) : {n : Nat // lo ≤ n} × Vector α n :=
|
||||
let mid := (lo + hi) / 2
|
||||
let as := if lt as[mid] as[lo] then as.swap lo mid else as
|
||||
let as := if lt as[hi] as[lo] then as.swap lo hi else as
|
||||
let as := if lt as[mid] as[hi] then as.swap mid hi else as
|
||||
let pivot := as[hi]
|
||||
let rec loop (as : Vector α n) (i j : Nat)
|
||||
(ilo : lo ≤ i := by omega) (jh : j < n := by omega) (w : i ≤ j := by omega) :=
|
||||
if h : j < hi then
|
||||
if lt as[j] pivot then
|
||||
loop (as.swap i j) (i+1) (j+1)
|
||||
else
|
||||
loop as i (j+1)
|
||||
else
|
||||
(⟨i, ilo⟩, as.swap i hi)
|
||||
loop as lo lo
|
||||
|
||||
/--
|
||||
Sorts an array using the Quicksort algorithm.
|
||||
|
||||
The optional parameter `lt` specifies an ordering predicate. It defaults to `LT.lt`, which must be
|
||||
decidable to be used for sorting. Use `Array.qsortOrd` to sort the array according to the `Ord α`
|
||||
instance.
|
||||
|
||||
The optional parameters `low` and `high` delimit the region of the array that is sorted. Both are
|
||||
inclusive, and default to sorting the entire array.
|
||||
-/
|
||||
@[inline] def qsort (as : Array α) (lt : α → α → Bool := by exact (· < ·))
|
||||
(low := 0) (high := as.size - 1) : Array α :=
|
||||
let rec @[specialize] sort {n} (as : Vector α n) (lo hi : Nat)
|
||||
(hlo : lo < n := by omega) (hhi : hi < n := by omega) :=
|
||||
if h₁ : lo < hi then
|
||||
let ⟨⟨mid, hmid⟩, as⟩ := qpartition as lt lo hi
|
||||
if h₂ : mid ≥ hi then
|
||||
as
|
||||
else
|
||||
sort (sort as lo mid) (mid+1) hi
|
||||
else as
|
||||
if h : as.size = 0 then
|
||||
as
|
||||
else
|
||||
let low := min low (as.size - 1)
|
||||
let high := min high (as.size - 1)
|
||||
sort ⟨as, rfl⟩ low high |>.toArray
|
||||
|
||||
set_option linter.unusedVariables.funArgs false in
|
||||
/--
|
||||
Sorts an array using the Quicksort algorithm, using `Ord.compare` to compare elements.
|
||||
-/
|
||||
def qsortOrd [ord : Ord α] (xs : Array α) : Array α :=
|
||||
xs.qsort fun x y => compare x y |>.isLT
|
||||
|
||||
end Array
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
/-
|
||||
Copyright (c) 2019 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Vector.Basic
|
||||
import Init.Data.Ord
|
||||
|
||||
set_option linter.listVariables true -- Enforce naming conventions for `List`/`Array`/`Vector` variables.
|
||||
-- We do not enable `linter.indexVariables` because it is helpful to name index variables `lo`, `mid`, `hi`, etc.
|
||||
|
||||
|
||||
namespace Array
|
||||
|
||||
/--
|
||||
Internal implementation of `Array.qsort`.
|
||||
|
||||
`qpartition as lt lo hi hlo hhi` returns a pair `(⟨m, h₁, h₂⟩, as')` where
|
||||
`as'` is a permutation of `as` and `m` is a number such that:
|
||||
- `lo ≤ m`
|
||||
- `m < n`
|
||||
- `∀ i, lo ≤ i → i < m → lt as[i] as[m]`
|
||||
- `∀ j, m < j → j < hi → !lt as[j] as[m]`
|
||||
|
||||
It does so by first swapping the elements at indices `lo`, `mid := (lo + hi) / 2`, and `hi`
|
||||
if necessary so that the middle (pivot) element is at index `hi`.
|
||||
We then iterate from `j = lo` to `j = hi`, with a pointer `i` starting at `lo`, and
|
||||
swapping each element which is less than the pivot to position `i`, and then incrementing `i`.
|
||||
-/
|
||||
def qpartition {n} (as : Vector α n) (lt : α → α → Bool) (lo hi : Nat)
|
||||
(hlo : lo < n := by omega) (hhi : hi < n := by omega) : {m : Nat // lo ≤ m ∧ m < n} × Vector α n :=
|
||||
let mid := (lo + hi) / 2
|
||||
let as := if lt as[mid] as[lo] then as.swap lo mid else as
|
||||
let as := if lt as[hi] as[lo] then as.swap lo hi else as
|
||||
let as := if lt as[mid] as[hi] then as.swap mid hi else as
|
||||
let pivot := as[hi]
|
||||
let rec loop (as : Vector α n) (i j : Nat)
|
||||
(ilo : lo ≤ i := by omega) (jh : j < n := by omega) (w : i ≤ j := by omega) :=
|
||||
if h : j < hi then
|
||||
if lt as[j] pivot then
|
||||
loop (as.swap i j) (i+1) (j+1)
|
||||
else
|
||||
loop as i (j+1)
|
||||
else
|
||||
(⟨i, ilo, by omega⟩, as.swap i hi)
|
||||
loop as lo lo
|
||||
|
||||
/--
|
||||
In-place quicksort.
|
||||
|
||||
`qsort as lt low high` sorts the subarray `as[low:high+1]` in-place using `lt` to compare elements.
|
||||
-/
|
||||
@[inline] def qsort (as : Array α) (lt : α → α → Bool := by exact (· < ·))
|
||||
(low := 0) (high := as.size - 1) : Array α :=
|
||||
let rec @[specialize] sort {n} (as : Vector α n) (lo hi : Nat)
|
||||
(hlo : lo < n := by omega) (hhi : hi < n := by omega) :=
|
||||
if h₁ : lo < hi then
|
||||
let ⟨⟨mid, hmid⟩, as⟩ := qpartition as lt lo hi
|
||||
if h₂ : mid ≥ hi then
|
||||
as
|
||||
else
|
||||
sort (sort as lo mid) (mid+1) hi
|
||||
else as
|
||||
if h : as.size = 0 then
|
||||
as
|
||||
else
|
||||
let low := min low (as.size - 1)
|
||||
let high := min high (as.size - 1)
|
||||
sort as.toVector low high |>.toArray
|
||||
|
||||
set_option linter.unusedVariables.funArgs false in
|
||||
/--
|
||||
Sort an array using `compare` to compare elements.
|
||||
-/
|
||||
def qsortOrd [ord : Ord α] (xs : Array α) : Array α :=
|
||||
xs.qsort fun x y => compare x y |>.isLT
|
||||
|
||||
end Array
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Kim Morrison
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Array.Lemmas
|
||||
import Init.Data.Array.OfFn
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2020 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura, Mario Carneiro
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Tactics
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2020 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Array.Basic
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: David Thrane Christiansen
|
||||
-/
|
||||
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Array.Basic
|
||||
import Init.Data.Array.Subarray
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2024 Lean FRO, LLC. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Markus Himmel
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Array.Lemmas
|
||||
import Init.Data.List.Nat.TakeDrop
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Kim Morrison
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Array.TakeDrop
|
||||
import Init.Data.List.Zip
|
||||
@@ -325,7 +323,7 @@ theorem map_zipWithAll {δ : Type _} {f : α → β} {g : Option γ → Option
|
||||
simp [List.map_zipWithAll]
|
||||
|
||||
@[simp] theorem zipWithAll_replicate {a : α} {b : β} {n : Nat} :
|
||||
zipWithAll f (replicate n a) (replicate n b) = replicate n (f (some a) (some b)) := by
|
||||
zipWithAll f (replicate n a) (replicate n b) = replicate n (f a b) := by
|
||||
simp [← List.toArray_replicate]
|
||||
|
||||
@[deprecated zipWithAll_replicate (since := "2025-03-18")]
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2022 Mario Carneiro. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Mario Carneiro, Markus Himmel
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Bool
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2016 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Nat.Basic
|
||||
import Init.Data.Fin.Basic
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2024 Lean FRO, LLC. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Kim Morrison
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.BitVec.Basic
|
||||
import Init.Data.BitVec.Bitblast
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2024 Lean FRO, LLC. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Joe Hendrix, Wojciech Nawrocki, Leonardo de Moura, Mario Carneiro, Alex Keizer, Harun Khan, Abdalrhman M Mohamed, Siddharth Bhat
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Fin.Basic
|
||||
import Init.Data.Nat.Bitwise.Lemmas
|
||||
@@ -769,15 +767,6 @@ SMT-Lib name: `bvnego`.
|
||||
def negOverflow {w : Nat} (x : BitVec w) : Bool :=
|
||||
x.toInt == - 2 ^ (w - 1)
|
||||
|
||||
/--
|
||||
Checks whether the signed division of `x` by `y` results in overflow.
|
||||
For BitVecs `x` and `y` with nonzero width, this only happens if `x = intMin` and `y = allOnes w`.
|
||||
|
||||
SMT-LIB name: `bvsdivo`.
|
||||
-/
|
||||
def sdivOverflow {w : Nat} (x y : BitVec w) : Bool :=
|
||||
(2 ^ (w - 1) ≤ x.toInt / y.toInt) || (x.toInt / y.toInt < - 2 ^ (w - 1))
|
||||
|
||||
/- ### reverse -/
|
||||
|
||||
/-- Reverses the bits in a bitvector. -/
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2024 Lean FRO, LLC. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Joe Hendrix, Wojciech Nawrocki, Leonardo de Moura, Mario Carneiro, Alex Keizer, Harun Khan, Abdalrhman M Mohamed
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Fin.Basic
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2024 Lean FRO, LLC. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Harun Khan, Abdalrhman M Mohamed, Joe Hendrix, Siddharth Bhat
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.BitVec.Folds
|
||||
import Init.Data.Nat.Mod
|
||||
@@ -1358,41 +1356,9 @@ theorem negOverflow_eq {w : Nat} (x : BitVec w) :
|
||||
rcases w with _|w
|
||||
· simp [toInt_of_zero_length, Int.min_eq_right]
|
||||
· suffices - 2 ^ w = (intMin (w + 1)).toInt by simp [beq_eq_decide_eq, ← toInt_inj, this]
|
||||
simp only [toInt_intMin, Nat.add_one_sub_one, Int.natCast_emod, Int.neg_inj]
|
||||
simp only [toInt_intMin, Nat.add_one_sub_one, Int.ofNat_emod, Int.neg_inj]
|
||||
rw_mod_cast [Nat.mod_eq_of_lt (by simp [Nat.pow_lt_pow_succ])]
|
||||
|
||||
/--
|
||||
Prove that signed division `x.toInt / y.toInt` only overflows when `x = intMin w` and `y = allOnes w` (for `0 < w`).
|
||||
-/
|
||||
theorem sdivOverflow_eq {w : Nat} (x y : BitVec w) :
|
||||
(sdivOverflow x y) = (decide (0 < w) && (x = intMin w) && (y = allOnes w)) := by
|
||||
rcases w with _|w
|
||||
· simp [sdivOverflow, of_length_zero]
|
||||
· have yle := le_two_mul_toInt (x := y)
|
||||
have ylt := two_mul_toInt_lt (x := y)
|
||||
-- if y = allOnes (w + 1), thus y.toInt = -1,
|
||||
-- the division overflows iff x = intMin (w + 1), as for negation
|
||||
by_cases hy : y = allOnes (w + 1)
|
||||
· simp [sdivOverflow_eq_negOverflow_of_eq_allOnes, negOverflow_eq, ← hy, beq_eq_decide_eq]
|
||||
· simp only [sdivOverflow, hy, bool_to_prop]
|
||||
have := BitVec.neg_two_pow_le_toInt_ediv (x := x) (y := y)
|
||||
simp only [Nat.add_one_sub_one] at this
|
||||
by_cases hx : 0 ≤ x.toInt
|
||||
· by_cases hy' : 0 ≤ y.toInt
|
||||
· have := BitVec.toInt_ediv_toInt_lt_of_nonneg_of_nonneg
|
||||
(x := x) (y := y) (by omega) (by omega)
|
||||
simp only [Nat.add_one_sub_one] at this; simp; omega
|
||||
· have := BitVec.toInt_ediv_toInt_nonpos_of_nonneg_of_nonpos
|
||||
(x := x) (y := y) (by omega) (by omega)
|
||||
simp; omega
|
||||
· by_cases hy' : 0 ≤ y.toInt
|
||||
· have := BitVec.toInt_ediv_toInt_nonpos_of_nonpos_of_nonneg
|
||||
(x := x) (y := y) (by omega) (by omega)
|
||||
simp; omega
|
||||
· have := BitVec.toInt_ediv_toInt_lt_of_nonpos_of_lt_neg_one
|
||||
(x := x) (y := y) (by omega) (by rw [← toInt_inj, toInt_allOnes] at hy; omega)
|
||||
simp only [Nat.add_one_sub_one] at this; simp; omega
|
||||
|
||||
theorem umulOverflow_eq {w : Nat} (x y : BitVec w) :
|
||||
umulOverflow x y =
|
||||
(0 < w && BitVec.twoPow (w * 2) w ≤ x.zeroExtend (w * 2) * y.zeroExtend (w * 2)) := by
|
||||
@@ -1574,7 +1540,7 @@ theorem sdiv_ne_intMin_of_ne_intMin {x y : BitVec w} (h : x ≠ intMin w) :
|
||||
|
||||
theorem toInt_eq_neg_toNat_neg_of_msb_true {x : BitVec w} (h : x.msb = true) :
|
||||
x.toInt = -((-x).toNat) := by
|
||||
simp only [toInt_eq_msb_cond, h, ↓reduceIte, toNat_neg, Int.natCast_emod]
|
||||
simp only [toInt_eq_msb_cond, h, ↓reduceIte, toNat_neg, Int.ofNat_emod]
|
||||
norm_cast
|
||||
rw [Nat.mod_eq_of_lt]
|
||||
· omega
|
||||
@@ -1669,7 +1635,7 @@ theorem toInt_sdiv_of_ne_or_ne (a b : BitVec w) (h : a ≠ intMin w ∨ b ≠ -1
|
||||
(a.sdiv b).toInt = -((-a).toNat / b.toNat) := by
|
||||
simp only [sdiv_eq, ha, hb, udiv_eq]
|
||||
rw [toInt_eq_neg_toNat_neg_of_nonpos]
|
||||
· rw [neg_neg, toNat_udiv, toNat_neg, Int.natCast_emod, Int.neg_inj]
|
||||
· rw [neg_neg, toNat_udiv, toNat_neg, Int.ofNat_emod, Int.neg_inj]
|
||||
norm_cast
|
||||
· rw [neg_eq_zero_iff]
|
||||
by_cases h' : -a / b = 0#w
|
||||
@@ -1812,23 +1778,9 @@ theorem extractLsb'_mul {w len} {x y : BitVec w} (hlen : len ≤ w) :
|
||||
(x * y).extractLsb' 0 len = (x.extractLsb' 0 len) * (y.extractLsb' 0 len) := by
|
||||
simp [← setWidth_eq_extractLsb' hlen, setWidth_mul _ _ hlen]
|
||||
|
||||
/-- Adding bitvectors that are zero in complementary positions equals concatenation.
|
||||
We add a `no_index` annotation to `HAppend.hAppend` such that the width `v + w`
|
||||
does not act as a key in the discrimination tree.
|
||||
This is important to allow matching, when the type of the result of append
|
||||
`x : BitVec 3` and `y : BitVec 4` has been reduced to `x ++ y : BitVec 7`.
|
||||
-/
|
||||
theorem append_zero_add_zero_append {v w : Nat} {x : BitVec v} {y : BitVec w} :
|
||||
(HAppend.hAppend (γ := BitVec (no_index _)) x 0#w) +
|
||||
(HAppend.hAppend (γ := BitVec (no_index _)) 0#v y)
|
||||
= x ++ y := by
|
||||
rw [add_eq_or_of_and_eq_zero] <;> ext i <;> simp
|
||||
|
||||
/-- Adding bitvectors that are zero in complementary positions equals concatenation. -/
|
||||
theorem zero_append_add_append_zero {v w : Nat} {x : BitVec v} {y : BitVec w} :
|
||||
(HAppend.hAppend (γ := BitVec (no_index _)) 0#v y) +
|
||||
(HAppend.hAppend (γ := BitVec (no_index _)) x 0#w)
|
||||
= x ++ y := by
|
||||
theorem append_add_append_eq_append {v w : Nat} {x : BitVec v} {y : BitVec w} :
|
||||
(x ++ 0#w) + (0#v ++ y) = x ++ y := by
|
||||
rw [add_eq_or_of_and_eq_zero] <;> ext i <;> simp
|
||||
|
||||
/-- Heuristically, `y <<< x` is much larger than `x`,
|
||||
@@ -1844,10 +1796,4 @@ theorem add_shiftLeft_eq_or_shiftLeft {x y : BitVec w} :
|
||||
have : i < 2^i := by exact Nat.lt_two_pow_self
|
||||
omega
|
||||
|
||||
/-- Heuristically, `y <<< x` is much larger than `x`,
|
||||
and hence low bits of `y <<< x`. Thus, `(y <<< x) + x = (y <<< x) ||| x.` -/
|
||||
theorem shiftLeft_add_eq_shiftLeft_or {x y : BitVec w} :
|
||||
(y <<< x) + x = (y <<< x) ||| x := by
|
||||
rw [BitVec.add_comm, add_shiftLeft_eq_or_shiftLeft, or_comm]
|
||||
|
||||
end BitVec
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2023 Lean FRO, LLC. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Joe Hendrix, Harun Khan
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.BitVec.Lemmas
|
||||
import Init.Data.Nat.Lemmas
|
||||
|
||||
@@ -4,8 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Joe Hendrix, Harun Khan, Alex Keizer, Abdalrhman M Mohamed, Siddharth Bhat
|
||||
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Bool
|
||||
import Init.Data.BitVec.Basic
|
||||
@@ -620,10 +618,10 @@ theorem toInt_eq_toNat_bmod (x : BitVec n) : x.toInt = Int.bmod x.toNat (2^n) :=
|
||||
simp only [toInt_eq_toNat_cond]
|
||||
split
|
||||
next g =>
|
||||
rw [Int.bmod_pos] <;> simp only [←Int.natCast_emod, toNat_mod_cancel]
|
||||
rw [Int.bmod_pos] <;> simp only [←Int.ofNat_emod, toNat_mod_cancel]
|
||||
omega
|
||||
next g =>
|
||||
rw [Int.bmod_neg] <;> simp only [←Int.natCast_emod, toNat_mod_cancel]
|
||||
rw [Int.bmod_neg] <;> simp only [←Int.ofNat_emod, toNat_mod_cancel]
|
||||
omega
|
||||
|
||||
theorem toInt_neg_of_msb_true {x : BitVec w} (h : x.msb = true) : x.toInt < 0 := by
|
||||
@@ -639,7 +637,7 @@ theorem toInt_nonneg_of_msb_false {x : BitVec w} (h : x.msb = false) : 0 ≤ x.t
|
||||
@[simp] theorem toInt_one_of_lt {w : Nat} (h : 1 < w) : (1#w).toInt = 1 := by
|
||||
rw [toInt_eq_msb_cond]
|
||||
simp only [msb_one, show w ≠ 1 by omega, decide_false, Bool.false_eq_true, ↓reduceIte,
|
||||
toNat_ofNat, Int.natCast_emod]
|
||||
toNat_ofNat, Int.ofNat_emod]
|
||||
norm_cast
|
||||
apply Nat.mod_eq_of_lt
|
||||
apply Nat.one_lt_two_pow (by omega)
|
||||
@@ -2548,7 +2546,7 @@ where
|
||||
simp [getElem_signExtend, Nat.le_sub_one_of_lt hv]
|
||||
omega
|
||||
have H : 2^w ≤ 2^v := Nat.pow_le_pow_right (by omega) (by omega)
|
||||
simp only [this, toNat_setWidth, Int.natCast_add, Int.natCast_emod, Int.natCast_mul]
|
||||
simp only [this, toNat_setWidth, Int.natCast_add, Int.ofNat_emod, Int.natCast_mul]
|
||||
by_cases h : x.msb
|
||||
<;> norm_cast
|
||||
<;> simp [h, Nat.mod_eq_of_lt (Nat.lt_of_lt_of_le x.isLt H), -Int.natCast_pow]
|
||||
@@ -3871,7 +3869,7 @@ theorem le_zero_iff {x : BitVec w} : x ≤ 0#w ↔ x = 0#w := by
|
||||
theorem lt_one_iff {x : BitVec w} (h : 0 < w) : x < 1#w ↔ x = 0#w := by
|
||||
constructor
|
||||
· intro h₂
|
||||
rw [lt_def, toNat_ofNat, ← Int.ofNat_lt, Int.natCast_emod, Int.ofNat_one, Int.natCast_pow,
|
||||
rw [lt_def, toNat_ofNat, ← Int.ofNat_lt, Int.ofNat_emod, Int.ofNat_one, Int.natCast_pow,
|
||||
Int.ofNat_two, @Int.emod_eq_of_lt 1 (2^w) (by omega) (by omega)] at h₂
|
||||
simp [toNat_eq, show x.toNat = 0 by omega]
|
||||
· simp_all
|
||||
@@ -4150,110 +4148,6 @@ theorem sdiv_self {x : BitVec w} :
|
||||
rcases x.msb with msb | msb <;> simp
|
||||
· rcases x.msb with msb | msb <;> simp [h]
|
||||
|
||||
/-- Unsigned division never overflows. -/
|
||||
theorem toNat_div_toNat_lt {w : Nat} {x y : BitVec w} :
|
||||
x.toNat / y.toNat < 2 ^ w := by
|
||||
have hy : y.toNat = 0 ∨ y.toNat = 1 ∨ 1 < y.toNat := by omega
|
||||
rcases hy with hy|hy|hy
|
||||
· simp [hy]; omega
|
||||
· simp [hy]; omega
|
||||
· rw [Nat.div_lt_iff_lt_mul (k := y.toNat) (x := x.toNat) (y := 2 ^ w) (by omega), show x.toNat = x.toNat * 1 by omega]
|
||||
apply Nat.mul_lt_mul_of_le_of_lt (by omega) (by omega) (by omega)
|
||||
|
||||
/-- Non-overflowing signed division bounds when numerator is nonneg, denominator is nonneg. -/
|
||||
theorem toInt_ediv_toInt_lt_of_nonneg_of_nonneg {w : Nat} {x y : BitVec w} (hx : 0 ≤ x.toInt) (hy : 0 ≤ y.toInt) :
|
||||
x.toInt / y.toInt < 2 ^ (w - 1) := by
|
||||
rcases w with _|w
|
||||
· simp [of_length_zero]
|
||||
· have xle := le_two_mul_toInt (x := x); have xlt := two_mul_toInt_lt (x := x)
|
||||
by_cases hy' : y.toInt = 1
|
||||
· simp [hy', Int.ediv_one]; omega
|
||||
· by_cases hx' : x.toInt = 0
|
||||
· simp only [hx', Int.zero_ediv, Nat.add_one_sub_one, gt_iff_lt]
|
||||
norm_cast
|
||||
exact Nat.two_pow_pos (w := w)
|
||||
· have := Int.ediv_lt_self_of_pos_of_ne_one (x := x.toInt) (y := y.toInt) (by omega) (by omega)
|
||||
simp; omega
|
||||
|
||||
/-- Non-overflowing signed division bounds when numerator is nonpos, denominator is nonneg. -/
|
||||
theorem toInt_ediv_toInt_nonpos_of_nonpos_of_nonneg {w : Nat} {x y : BitVec w} (hx : x.toInt ≤ 0) (hy : 0 ≤ y.toInt) :
|
||||
x.toInt / y.toInt ≤ 0 := by
|
||||
rcases w with _|w
|
||||
· simp [of_length_zero]
|
||||
· by_cases hx' : x.toInt = 0
|
||||
· simp [hx']
|
||||
· by_cases hy' : y.toInt = 0
|
||||
· simp [hy']
|
||||
· have := Int.ediv_neg_of_neg_of_pos (a := x.toInt) (b := y.toInt) (by omega) (by omega)
|
||||
simp; omega
|
||||
|
||||
/-- Non-overflowing signed division bounds when numerator is nonneg, denominator is nonpos. -/
|
||||
theorem toInt_ediv_toInt_nonpos_of_nonneg_of_nonpos {w : Nat} {x y : BitVec w} (hx : 0 ≤ x.toInt) (hy : y.toInt ≤ 0) :
|
||||
x.toInt / y.toInt ≤ 0 := by
|
||||
rcases w with _|w
|
||||
· simp [of_length_zero]
|
||||
· by_cases hy' : y.toInt = -1
|
||||
· simp [hy']; omega
|
||||
· have := Int.ediv_nonpos_of_nonneg_of_nonpos (a := x.toInt) (b := y.toInt) (by omega) (by omega)
|
||||
simp; omega
|
||||
|
||||
/-- Given the definition of ediv/emod for signed integer division (https://dl.acm.org/doi/pdf/10.1145/128861.128862)
|
||||
we have that for two integers `x` and `y`: `x/y = q ↔ x.ediv y = q ↔ r = x.emod y`
|
||||
and in particular: `-1/y = q ↔ -1.ediv y = q ↔ r = -1.emod y`.
|
||||
from which it follows that:
|
||||
(-1)/0 = 0
|
||||
(-1)/y = -1 when 0 < y
|
||||
(-1)/(-5) = 1 when y < 0
|
||||
-/
|
||||
theorem neg_one_ediv_toInt_eq {w : Nat} {y : BitVec w} :
|
||||
(-1) / y.toInt = if y.toInt = 0 then 0 else if 0 < y.toInt then -1 else 1 := by
|
||||
rcases w with _|_|w
|
||||
· simp [of_length_zero]
|
||||
· cases eq_zero_or_eq_one y
|
||||
· case _ h => simp [h]
|
||||
· case _ h => simp [h]
|
||||
· by_cases 0 < y.toInt
|
||||
· simp [Int.sign_eq_one_of_pos (a := y.toInt) (by omega), Int.neg_one_ediv]
|
||||
omega
|
||||
· by_cases hy : y.toInt = 0
|
||||
· simp [hy]
|
||||
· simp [Int.sign_eq_neg_one_of_neg (a := y.toInt) (by omega), Int.neg_one_ediv]
|
||||
omega
|
||||
|
||||
/-- Non-overflowing signed division bounds when numerator is nonpos, denominator is less than -1. -/
|
||||
theorem toInt_ediv_toInt_lt_of_nonpos_of_lt_neg_one {w : Nat} {x y : BitVec w} (hx : x.toInt ≤ 0) (hy : y.toInt < -1) :
|
||||
x.toInt / y.toInt < 2 ^ (w - 1) := by
|
||||
rcases w with _|_|w
|
||||
· simp [of_length_zero]
|
||||
· have hy := eq_zero_or_eq_one (a := y)
|
||||
simp [← toInt_inj, toInt_zero, toInt_one] at hy
|
||||
omega
|
||||
· have xle := le_two_mul_toInt (x := x); have xlt := two_mul_toInt_lt (x := x)
|
||||
have hx' : x.toInt = 0 ∨ x.toInt = - 1 ∨ x.toInt < - 1 := by omega
|
||||
rcases hx' with hx'|hx'|hx'
|
||||
· simp [hx']; omega
|
||||
· have := BitVec.neg_one_ediv_toInt_eq (y := y)
|
||||
simp only [toInt_allOnes, Nat.lt_add_left_iff_pos, Nat.zero_lt_succ, ↓reduceIte,
|
||||
Int.reduceNeg] at this
|
||||
simp [hx', this]
|
||||
omega
|
||||
· have := Int.ediv_lt_natAbs_self_of_lt_neg_one_of_lt_neg_one (x := x.toInt) (y := y.toInt) (by omega) hy
|
||||
simp; omega
|
||||
|
||||
/-- Signed division of (x y : BitVec w) is always -2 ^ w ≤ x.toInt / y.toInt. -/
|
||||
theorem neg_two_pow_le_toInt_ediv {x y : BitVec w} :
|
||||
- 2 ^ (w - 1) ≤ x.toInt / y.toInt := by
|
||||
have xlt := @toInt_lt w x; have lex := @le_toInt w x
|
||||
by_cases hx : 0 ≤ x.toInt <;> by_cases hy : 0 ≤ y.toInt
|
||||
· have := Int.ediv_nonneg_of_nonneg_of_nonneg (x := x.toInt) (y := y.toInt) hx hy
|
||||
omega
|
||||
· have := Int.neg_self_le_ediv_of_nonneg_of_nonpos (x := x.toInt) (y := y.toInt) hx (by omega)
|
||||
omega
|
||||
· have := Int.self_le_ediv_of_nonpos_of_nonneg (x := x.toInt) (y := y.toInt) (by omega) hy
|
||||
omega
|
||||
· have := Int.ediv_nonneg_of_nonpos_of_nonpos (a := x.toInt) (b := y.toInt) (by omega) (by omega)
|
||||
omega
|
||||
|
||||
/-! ### smtSDiv -/
|
||||
|
||||
theorem smtSDiv_eq (x y : BitVec w) : smtSDiv x y =
|
||||
@@ -5056,7 +4950,7 @@ theorem toInt_intMin_le (x : BitVec w) :
|
||||
cases w
|
||||
case zero => simp [toInt_intMin, @of_length_zero x]
|
||||
case succ w =>
|
||||
simp only [toInt_intMin, Nat.add_one_sub_one, Int.natCast_emod]
|
||||
simp only [toInt_intMin, Nat.add_one_sub_one, Int.ofNat_emod]
|
||||
have : 0 < 2 ^ w := Nat.two_pow_pos w
|
||||
rw [Int.emod_eq_of_lt (by omega) (by omega)]
|
||||
rw [BitVec.toInt_eq_toNat_bmod]
|
||||
@@ -5251,22 +5145,6 @@ theorem sub_le_sub_iff_le {x y z : BitVec w} (hxz : z ≤ x) (hyz : z ≤ y) :
|
||||
BitVec.toNat_sub_of_le (by rw [BitVec.le_def]; omega)]
|
||||
omega
|
||||
|
||||
theorem sdiv_neg_one {w : Nat} {x : BitVec w} :
|
||||
x.toInt / -1 = -x.toInt := by
|
||||
rcases w with _|w
|
||||
· simp [of_length_zero]
|
||||
· simp [toInt_allOnes]
|
||||
|
||||
theorem sdivOverflow_eq_negOverflow_of_eq_allOnes {w : Nat} {x y : BitVec w} (hy : y = allOnes w) :
|
||||
sdivOverflow x y = negOverflow x := by
|
||||
rcases w with _|w
|
||||
· simp [sdivOverflow, negOverflow, of_length_zero]
|
||||
· have xle := le_two_mul_toInt (x := x); have xlt := two_mul_toInt_lt (x := x)
|
||||
simp only [sdivOverflow, hy, show ¬2 ^ w < x.toInt by omega, negOverflow]
|
||||
by_cases hx : x.toInt = - 2 ^ w
|
||||
· simp [hx]
|
||||
· simp [show ¬x.toInt == -2 ^ w by simp only [beq_iff_eq, hx, not_false_eq_true]]; omega
|
||||
|
||||
theorem two_pow_le_toInt_mul_toInt_iff {x y : BitVec w} :
|
||||
2 ^ (w - 1) ≤ x.toInt * y.toInt ↔
|
||||
(signExtend (w * 2) (intMax w)).slt (signExtend (w * 2) x * signExtend (w * 2) y) := by
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2023 F. G. Dorais. No rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: F. G. Dorais
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.NotationExtra
|
||||
|
||||
|
||||
@@ -3,7 +3,5 @@ Copyright (c) 2019 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Author: Leonardo de Moura
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.ByteArray.Basic
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2019 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Author: Leonardo de Moura
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Array.Basic
|
||||
import Init.Data.Array.Subarray
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2014 Mario Carneiro. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Mario Carneiro, Gabriel Ebner
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Coe
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2016 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Char.Basic
|
||||
import Init.Data.Char.Lemmas
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2016 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Author: Leonardo de Moura
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.UInt.BasicAux
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Char.Basic
|
||||
import Init.Data.UInt.Lemmas
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2017 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Author: Leonardo de Moura
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Fin.Basic
|
||||
import Init.Data.Fin.Log2
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2016 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Author: Leonardo de Moura, Robert Y. Lewis, Keeley Hoek, Mario Carneiro
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Nat.Bitwise.Basic
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2024 Lean FRO, LLC. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Markus Himmel
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Nat.Bitwise
|
||||
import Init.Data.Fin.Basic
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2023 François G. Dorais. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: François G. Dorais
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Nat.Linear
|
||||
import Init.Control.Lawful.Basic
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2024 Lean FRO, LLC. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Joe Hendrix
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.PropLemmas
|
||||
import Init.Data.Fin.Basic
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2022 Mario Carneiro. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Mario Carneiro, Leonardo de Moura
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Fin.Basic
|
||||
import Init.Data.Nat.Lemmas
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2022 Henrik Böving. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Henrik Böving
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Nat.Log2
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2020 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Core
|
||||
import Init.Data.Int.Basic
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Core
|
||||
import Init.Data.Int.Basic
|
||||
|
||||
@@ -3,7 +3,5 @@ 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
|
||||
import Init.Data.FloatArray.Basic
|
||||
|
||||
@@ -3,8 +3,6 @@ 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
|
||||
import Init.Data.Array.Basic
|
||||
import Init.Data.Float
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2018 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Author: Leonardo de Moura
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Data.Format.Basic
|
||||
import Init.Data.Format.Macro
|
||||
|
||||
@@ -3,8 +3,6 @@ Copyright (c) 2018 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Author: Leonardo de Moura
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
import Init.Control.State
|
||||
import Init.Data.Int.Basic
|
||||
|
||||
@@ -3,8 +3,6 @@ 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
|
||||
import Init.Data.Format.Basic
|
||||
import Init.Data.Array.Basic
|
||||
|
||||
@@ -3,8 +3,6 @@ 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
|
||||
import Init.Data.Format.Basic
|
||||
import Init.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