Compare commits

..

3 Commits

Author SHA1 Message Date
Wojciech Nawrocki
f1f693fcd5 Update Trace.lean 2023-07-27 15:27:56 -07:00
Wojciech Nawrocki
a75fc1d756 Update src/Lean/Util/Trace.lean
Co-authored-by: Gabriel Ebner <gebner@gebner.org>
2023-07-27 15:27:24 -07:00
Wojciech Nawrocki
b4f08799fb fix: handle error in withTrace message action 2023-07-27 12:36:56 -07:00
722 changed files with 3052 additions and 7171 deletions

2
.gitattributes vendored
View File

@@ -2,5 +2,3 @@
*.expected.out -text
RELEASES.md merge=union
stage0/** binary linguist-generated
# The following file is often manually edited, so do show it in diffs
stage0/src/stdlib_flags.h -binary -linguist-generated

30
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,30 @@
### Prerequisites
* [ ] Put an X between the brackets on this line if you have done all of the following:
* Checked that your issue isn't already [filed](https://github.com/leanprover/lean4/issues).
* Reduced the issue to a self-contained, reproducible test case.
### Description
[Description of the issue]
### Steps to Reproduce
1. [First Step]
2. [Second Step]
3. [and so on...]
**Expected behavior:** [What you expect to happen]
**Actual behavior:** [What actually happens]
**Reproduces how often:** [What percentage of the time does it reproduce?]
### Versions
You can get this information from copy and pasting the output of `lean --version`,
please include the OS and what version of the OS you're running.
### Additional Information
Any additional information, configuration or data that might be necessary to reproduce the issue.

View File

@@ -1,45 +0,0 @@
---
name: Bug report
about: Create a bug report
title: ''
labels: bug
assignees: ''
---
### Prerequisites
* [ ] Put an X between the brackets on this line if you have done all of the following:
* Check that your issue is not already [filed](https://github.com/leanprover/lean4/issues).
* Reduce the issue to a minimal, self-contained, reproducible test case. Avoid dependencies to mathlib4 or std4.
### Description
[Clear and concise description of the issue]
### Context
[Broader context that the issue occured in. If there was any prior discussion on [the Lean Zulip](https://leanprover.zulipchat.com), link it here as well.]
### Steps to Reproduce
1.
2.
3.
**Expected behavior:** [Clear and concise description of what you expect to happen]
**Actual behavior:** [Clear and concise description of what actually happens]
### Versions
[Output of `lean --version` in the folder that the issue occured in]
[OS version]
### Additional Information
[Additional information, configuration or data that might be necessary to reproduce the issue]
### Impact
Add :+1: to [issues you consider important](https://github.com/leanprover/lean4/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc). If others are impacted by this issue, please ask them to add :+1: to it.

View File

@@ -1,26 +0,0 @@
---
name: Request for comments
about: Create a feature proposal
title: 'RFC: '
labels: RFC
assignees: ''
---
### Proposal
Clear and detailed description of the proposal. Consider the following questions:
- **User Experience**: How does this feature improve the user experience?
- **Beneficiaries**: Which Lean users and projects benefit most from this feature/change?
- **Maintainability**: Will this change streamline code maintenance or simplify its structure?
### Community Feedback
Ideas should be discussed on [the Lean Zulip](https://leanprover.zulipchat.com) prior to submitting a proposal. Summarize all prior discussions and link them here.
### Impact
Add :+1: to [issues you consider important](https://github.com/leanprover/lean4/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc). If others benefit from the changes in this proposal being added, please ask them to add :+1: to it.

View File

@@ -1,14 +0,0 @@
* [ ] Put an X in this bracket to confirm you have read the
[External Contribution Guidelines](https://github.com/leanprover/lean4/blob/master/doc/contributions.md).
* Please put the link to your `RFC` or `bug` issue here.
PRs missing this link will be marked as `missing RFC`.
* If that issue does not already have approval from a developer,
please be sure to open this PR in "Draft" mode.
* Please make sure the PR has excellent documentation and tests.
If we label it `missing documentation` or `missing tests` then it needs fixing!
* You can manage the `awaiting-review`, `awaiting-author`, and `WIP` labels
yourself, by writing a comment containing one of these labels on its own line.

View File

@@ -1,26 +0,0 @@
name: Backport
on:
pull_request_target:
types:
- closed
- labeled
jobs:
backport:
name: Backport
runs-on: ubuntu-latest
# Only react to merged PRs for security reasons.
# See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target.
if: >
github.event.pull_request.merged
&& (
github.event.action == 'closed'
|| (
github.event.action == 'labeled'
&& contains(github.event.label.name, 'backport')
)
)
steps:
- uses: tibdex/backport@v2
with:
github_token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -39,55 +39,8 @@ jobs:
fi
fi
# This job determines if this CI build is for a tagged release.
# It only runs when a tag is pushed to the `leanprover` repository.
# It sets `set-release.outputs.RELEASE_TAG` to the tag, if the tag is "v" followed by a valid semver,
# and sets `set-release.outputs.{LEAN_VERSION_MAJOR,LEAN_VERSION_MINOR,LEAN_VERSION_PATCH,LEAN_SPECIAL_VERSION_DESC}`
# to the semver components parsed via regex.
set-release:
runs-on: ubuntu-latest
outputs:
LEAN_VERSION_MAJOR: ${{ steps.set.outputs.LEAN_VERSION_MAJOR }}
LEAN_VERSION_MINOR: ${{ steps.set.outputs.LEAN_VERSION_MINOR }}
LEAN_VERSION_PATCH: ${{ steps.set.outputs.LEAN_VERSION_PATCH }}
LEAN_SPECIAL_VERSION_DESC: ${{ steps.set.outputs.LEAN_SPECIAL_VERSION_DESC }}
RELEASE_TAG: ${{ steps.set.outputs.RELEASE_TAG }}
steps:
- name: Checkout
uses: actions/checkout@v3
if: startsWith(github.ref, 'refs/tags/') && github.repository == 'leanprover/lean4'
- name: Check for official release
if: startsWith(github.ref, 'refs/tags/') && github.repository == 'leanprover/lean4'
id: set
run: |
TAG_NAME=${GITHUB_REF##*/}
# From https://github.com/fsaintjacques/semver-tool/blob/master/src/semver
NAT='0|[1-9][0-9]*'
ALPHANUM='[0-9]*[A-Za-z-][0-9A-Za-z-]*'
IDENT="$NAT|$ALPHANUM"
FIELD='[0-9A-Za-z-]+'
SEMVER_REGEX="\
^[vV]?\
($NAT)\\.($NAT)\\.($NAT)\
(\\-(${IDENT})(\\.(${IDENT}))*)?\
(\\+${FIELD}(\\.${FIELD})*)?$"
if [[ ${TAG_NAME} =~ ${SEMVER_REGEX} ]]; then
echo "Tag ${TAG_NAME} matches SemVer regex, with groups ${BASH_REMATCH[1]} ${BASH_REMATCH[2]} ${BASH_REMATCH[3]} ${BASH_REMATCH[4]}"
echo "LEAN_VERSION_MAJOR=${BASH_REMATCH[1]}" >> $GITHUB_OUTPUT
echo "LEAN_VERSION_MINOR=${BASH_REMATCH[2]}" >> $GITHUB_OUTPUT
echo "LEAN_VERSION_PATCH=${BASH_REMATCH[3]}" >> $GITHUB_OUTPUT
echo "LEAN_SPECIAL_VERSION_DESC=${BASH_REMATCH[4]##-}" >> $GITHUB_OUTPUT
echo "RELEASE_TAG=$TAG_NAME" >> $GITHUB_OUTPUT
else
echo "Tag ${TAG_NAME} did not match SemVer regex."
fi
build:
needs: [set-nightly, set-release]
needs: set-nightly
if: github.event_name != 'schedule' || github.repository == 'leanprover/lean4'
runs-on: ${{ matrix.os }}
defaults:
@@ -97,17 +50,6 @@ jobs:
matrix:
include:
# portable release build: use channel with older glibc (2.27)
- name: Linux LLVM
os: ubuntu-latest
release: false
shell: nix-shell --arg pkgsDist "import (fetchTarball \"channel:nixos-19.03\") {{}}" --run "bash -euxo pipefail {0}"
llvm-url: https://github.com/leanprover/lean-llvm/releases/download/15.0.1/lean-llvm-x86_64-linux-gnu.tar.zst
prepare-llvm: ../script/prepare-llvm-linux.sh lean-llvm*
binary-check: ldd -v
# foreign code may be linked against more recent glibc
# reverse-ffi needs to be updated to link to LLVM libraries
CTEST_OPTIONS: -E 'foreign|leanlaketest_reverse-ffi'
CMAKE_OPTIONS: -DLLVM=ON -DLLVM_CONFIG=${GITHUB_WORKSPACE}/build/llvm-host/bin/llvm-config
- name: Linux release
os: ubuntu-latest
release: true
@@ -116,7 +58,7 @@ jobs:
prepare-llvm: ../script/prepare-llvm-linux.sh lean-llvm*
binary-check: ldd -v
# foreign code may be linked against more recent glibc
CTEST_OPTIONS: -E 'foreign'
CTEST_OPTIONS: -E 'foreign|leanlaketest_git'
- name: Linux
os: ubuntu-latest
check-stage3: true
@@ -136,6 +78,7 @@ jobs:
os: macos-latest
release: true
shell: bash -euxo pipefail {0}
CMAKE_OPTIONS: -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15
llvm-url: https://github.com/leanprover/lean-llvm/releases/download/15.0.1/lean-llvm-x86_64-apple-darwin.tar.zst
prepare-llvm: ../script/prepare-llvm-macos.sh lean-llvm*
binary-check: otool -L
@@ -145,7 +88,7 @@ jobs:
release: true
cross: true
shell: bash -euxo pipefail {0}
CMAKE_OPTIONS: -DUSE_GMP=OFF -DLEAN_INSTALL_SUFFIX=-darwin_aarch64
CMAKE_OPTIONS: -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DUSE_GMP=OFF -DLEAN_INSTALL_SUFFIX=-darwin_aarch64
llvm-url: https://github.com/leanprover/lean-llvm/releases/download/15.0.1/lean-llvm-aarch64-apple-darwin.tar.zst https://github.com/leanprover/lean-llvm/releases/download/15.0.1/lean-llvm-x86_64-apple-darwin.tar.zst
prepare-llvm: EXTRA_FLAGS=--target=aarch64-apple-darwin ../script/prepare-llvm-macos.sh lean-llvm-aarch64-* lean-llvm-x86_64-*
binary-check: otool -L
@@ -168,15 +111,6 @@ jobs:
shell: nix-shell --arg pkgsDist "import (fetchTarball \"channel:nixos-19.03\") {{ localSystem.config = \"aarch64-unknown-linux-gnu\"; }}" --run "bash -euxo pipefail {0}"
llvm-url: https://github.com/leanprover/lean-llvm/releases/download/15.0.1/lean-llvm-x86_64-linux-gnu.tar.zst https://github.com/leanprover/lean-llvm/releases/download/15.0.1/lean-llvm-aarch64-linux-gnu.tar.zst
prepare-llvm: EXTRA_FLAGS=--target=aarch64-unknown-linux-gnu ../script/prepare-llvm-linux.sh lean-llvm-aarch64-* lean-llvm-x86_64-*
- name: Web Assembly
os: ubuntu-latest
# Build a native 32bit binary in stage0 and use it to compile the oleans and the wasm build
CMAKE_OPTIONS: -DCMAKE_C_COMPILER_WORKS=1 -DSTAGE0_USE_GMP=OFF -DSTAGE0_LEAN_EXTRA_CXX_FLAGS='-m32' -DSTAGE0_LEANC_OPTS='-m32' -DSTAGE0_CMAKE_CXX_COMPILER=clang++ -DSTAGE0_CMAKE_C_COMPILER=clang -DSTAGE0_CMAKE_EXECUTABLE_SUFFIX="" -DUSE_GMP=OFF -DMMAP=OFF -DSTAGE0_MMAP=OFF -DUSE_GMP=OFF -DCMAKE_AR=../emsdk/emsdk-main/upstream/emscripten/emar -DCMAKE_TOOLCHAIN_FILE=../emsdk/emsdk-main/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake
wasm: true
cross: true
shell: bash -euxo pipefail {0}
# Just a few selected test because wasm is slow
CTEST_OPTIONS: -R "leantest_1007\.lean|leantest_Format\.lean|leanruntest\_1037.lean|leanruntest_ac_rfl\.lean"
# complete all jobs
fail-fast: false
name: ${{ matrix.name }}
@@ -191,7 +125,6 @@ jobs:
LSAN_OPTIONS: max_leaks=10
# somehow MinGW clang64 (or cmake?) defaults to `g++` even though it doesn't exist
CXX: c++
MACOSX_DEPLOYMENT_TARGET: 10.15
steps:
- name: Checkout
uses: actions/checkout@v3
@@ -201,7 +134,7 @@ jobs:
uses: cachix/install-nix-action@v18
with:
install_url: https://releases.nixos.org/nix/nix-2.12.0/install
if: matrix.os == 'ubuntu-latest' && !matrix.wasm
if: matrix.os == 'ubuntu-latest'
- name: Install MSYS2
uses: msys2/setup-msys2@v2
with:
@@ -213,17 +146,6 @@ jobs:
run: |
brew install ccache tree zstd coreutils gmp
if: matrix.os == 'macos-latest'
- name: Setup emsdk
uses: mymindstorm/setup-emsdk@v11
with:
version: 3.1.44
actions-cache-folder: emsdk
if: matrix.wasm
- name: Install 32bit c libs
run: |
sudo apt-get update
sudo apt-get install -y gcc-multilib g++-multilib ccache
if: matrix.wasm
- name: Cache
uses: actions/cache@v3
with:
@@ -257,13 +179,6 @@ jobs:
if [[ -n '${{ matrix.release }}' && -n '${{ needs.set-nightly.outputs.nightly }}' ]]; then
OPTIONS+=(-DLEAN_SPECIAL_VERSION_DESC=${{ needs.set-nightly.outputs.nightly }})
fi
if [[ -n '${{ matrix.release }}' && -n '${{ needs.set-release.outputs.RELEASE_TAG }}' ]]; then
OPTIONS+=(-DLEAN_VERSION_MAJOR=${{ needs.set-release.outputs.LEAN_VERSION_MAJOR }})
OPTIONS+=(-DLEAN_VERSION_MINOR=${{ needs.set-release.outputs.LEAN_VERSION_MINOR }})
OPTIONS+=(-DLEAN_VERSION_PATCH=${{ needs.set-release.outputs.LEAN_VERSION_PATCH }})
OPTIONS+=(-DLEAN_VERSION_IS_RELEASE=1)
OPTIONS+=(-DLEAN_SPECIAL_VERSION_DESC=${{ needs.set-release.outputs.LEAN_SPECIAL_VERSION_DESC }})
fi
# contortion to support empty OPTIONS with old macOS bash
cmake .. ${{ matrix.CMAKE_OPTIONS }} ${OPTIONS[@]+"${OPTIONS[@]}"} -DLEAN_INSTALL_PREFIX=$PWD/..
make -j4
@@ -279,7 +194,7 @@ jobs:
dir=$(echo lean-*)
mkdir pack
# high-compression tar.zst + zip for release, fast tar.zst otherwise
if [[ '${{ startsWith(github.ref, 'refs/tags/') && matrix.release }}' == true || -n '${{ needs.set-nightly.outputs.nightly }}' || -n '${{ needs.set-release.outputs.RELEASE_TAG }}' ]]; then
if [[ '${{ startsWith(github.ref, 'refs/tags/') && matrix.release }}' == true || -n '${{ needs.set-nightly.outputs.nightly }}' ]]; then
${{ matrix.tar || 'tar' }} cf - $dir | zstd -T0 --no-progress -19 -o pack/$dir.tar.zst
zip -rq pack/$dir.zip $dir
else
@@ -299,8 +214,8 @@ jobs:
cd build/stage1
ulimit -c unlimited # coredumps
# exclude nonreproducible test
ctest -j4 --output-on-failure ${{ matrix.CTEST_OPTIONS }} < /dev/null
if: matrix.wasm || !matrix.cross
ctest -j4 --output-on-failure -E leanlaketest_git ${{ matrix.CTEST_OPTIONS }} < /dev/null
if: ${{ !matrix.cross }}
- name: Check Test Binary
run: ${{ matrix.binary-check }} tests/compiler/534.lean.out
if: ${{ !matrix.cross }}
@@ -352,10 +267,6 @@ jobs:
./build/stage2/bin/lean
./build/stage2/lib/lean/libleanshared.so
# This job creates releases from tags
# (whether they are "unofficial" releases for experiments, or official releases when the tag is "v" followed by a semver string.)
# We do not attempt to automatically construct a changelog here:
# unofficial releases don't need them, and official release notes will be written by a human.
release:
if: startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
@@ -372,8 +283,6 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# This job creates nightly releases during the cron job.
# It is responsible for creating the tag, and automatically generating a changelog.
release-nightly:
needs: [set-nightly, build]
if: needs.set-nightly.outputs.nightly
@@ -394,7 +303,7 @@ jobs:
git fetch nightly --tags
git tag ${{ needs.set-nightly.outputs.nightly }}
git push nightly ${{ needs.set-nightly.outputs.nightly }}
last_tag=$(git log HEAD^ --simplify-by-decoration --pretty="format:%d" | grep -o "nightly-[-0-9]*" | head -n 1)
last_tag=$(git describe HEAD^ --abbrev=0 --tags)
echo -e "*Changes since ${last_tag}:*\n\n" > diff.md
git show $last_tag:RELEASES.md > old.md
#./script/diff_changelogs.py old.md doc/changes.md >> diff.md

View File

@@ -1,43 +0,0 @@
# This workflow allows any user to add one of the `awaiting-review`, `awaiting-author`, or `WIP` labels,
# by commenting on the PR or issue.
# Other labels from this set are removed automatically at the same time.
name: Label PR based on Comment
on:
issue_comment:
types: [created]
jobs:
update-label:
if: github.event.issue.pull_request != null && (contains(github.event.comment.body, 'awaiting-review') || contains(github.event.comment.body, 'awaiting-author') || contains(github.event.comment.body, 'WIP'))
runs-on: ubuntu-latest
steps:
- name: Add label based on comment
uses: actions/github-script@v6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { owner, repo, number: issue_number } = context.issue;
const commentLines = context.payload.comment.body.split('\r\n');
const awaitingReview = commentLines.includes('awaiting-review');
const awaitingAuthor = commentLines.includes('awaiting-author');
const wip = commentLines.includes('WIP');
if (awaitingReview || awaitingAuthor || wip) {
await github.rest.issues.removeLabel({ owner, repo, issue_number, name: 'awaiting-review' }).catch(() => {});
await github.rest.issues.removeLabel({ owner, repo, issue_number, name: 'awaiting-author' }).catch(() => {});
await github.rest.issues.removeLabel({ owner, repo, issue_number, name: 'WIP' }).catch(() => {});
}
if (awaitingReview) {
await github.rest.issues.addLabels({ owner, repo, issue_number, labels: ['awaiting-review'] });
}
if (awaitingAuthor) {
await github.rest.issues.addLabels({ owner, repo, issue_number, labels: ['awaiting-author'] });
}
if (wip) {
await github.rest.issues.addLabels({ owner, repo, issue_number, labels: ['WIP'] });
}

View File

@@ -1,126 +0,0 @@
# Push a release to the lean4-pr-releases repository, whenever someone pushes to a PR branch.
# This needs to run with the `secrets.PR_RELEASES_TOKEN` token available,
# but PR branches will generally come from forks,
# so it is not possible to run this using the `pull_request` or `pull_request_target` workflows.
# Instead we use `workflow_run`, which essentially allows us to escalate privileges
# (but only runs the CI as described in the `master` branch, not in the PR branch).
name: PR release
on:
workflow_run: # https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run
workflows: [CI]
types: [completed]
jobs:
on-success:
runs-on: ubuntu-latest
if: github.event.workflow_run.conclusion == 'success' && github.repository == 'leanprover/lean4'
steps:
- name: Retrieve information about the original workflow
uses: potiuk/get-workflow-origin@v1_1 # https://github.com/marketplace/actions/get-workflow-origin
id: workflow-info
with:
token: ${{ secrets.GITHUB_TOKEN }}
sourceRunId: ${{ github.event.workflow_run.id }}
- name: Checkout
# Only proceed if the previous workflow had a pull request number.
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
uses: actions/checkout@v3
with:
token: ${{ secrets.PR_RELEASES_TOKEN }}
# Since `workflow_run` runs on master, we need to specify which commit to check out,
# so that we tag the PR.
ref: ${{ steps.workflow-info.outputs.targetCommitSha }}
# We need a full checkout, so that we can push the PR commits to the `lean4-pr-releases` repo.
fetch-depth: 0
- name: Download artifact from the previous workflow.
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
id: download-artifact
uses: dawidd6/action-download-artifact@v2 # https://github.com/marketplace/actions/download-workflow-artifact
with:
run_id: ${{ github.event.workflow_run.id }}
path: artifacts
name: build-.*
name_is_regexp: true
- name: Prepare release
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
run: |
git remote add pr-releases https://foo:'${{ secrets.PR_RELEASES_TOKEN }}'@github.com/${{ github.repository_owner }}/lean4-pr-releases.git
# Try to delete any existing release for the current PR.
gh release delete --repo ${{ github.repository_owner }}/lean4-pr-releases pr-release-${{ steps.workflow-info.outputs.pullRequestNumber }} -y || true
git tag -f pr-release-${{ steps.workflow-info.outputs.pullRequestNumber }}
git push -f pr-releases pr-release-${{ steps.workflow-info.outputs.pullRequestNumber }}
env:
GH_TOKEN: ${{ secrets.PR_RELEASES_TOKEN }}
- name: Release
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
uses: softprops/action-gh-release@v1
with:
name: Release for PR ${{ steps.workflow-info.outputs.pullRequestNumber }}
# There are coredumps files here as well, but all in deeper subdirectories.
files: artifacts/*/*
fail_on_unmatched_files: true
draft: false
tag_name: pr-release-${{ steps.workflow-info.outputs.pullRequestNumber }}
repository: ${{ github.repository_owner }}/lean4-pr-releases
env:
# The token used here must have `workflow` privileges.
GITHUB_TOKEN: ${{ secrets.PR_RELEASES_TOKEN }}
- name: Add label
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
uses: actions-ecosystem/action-add-labels@v1
with:
number: ${{ steps.workflow-info.outputs.pullRequestNumber }}
labels: toolchain-available
# We next automatically create a Mathlib branch using this toolchain.
# Mathlib CI will be responsible for reporting back success or failure
# to the PR comments asynchronously.
- name: Cleanup workspace
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
run: |
sudo rm -rf *
# Checkout the mathlib4 repository with all branches
- name: Checkout mathlib4 repository
uses: actions/checkout@v2
with:
repository: leanprover-community/mathlib4
token: ${{ secrets.MATHLIB4_BOT }}
ref: nightly-testing # This is more likely than `master` to work with the base of this PR.
fetch-depth: 0
- name: Check if branch exists
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
id: check_branch
run: |
git config user.name "leanprover-community-mathlib4-bot"
git config user.email "leanprover-community-mathlib4-bot@users.noreply.github.com"
EXISTS=$(git ls-remote --heads origin lean-pr-testing-${{ steps.workflow-info.outputs.pullRequestNumber }} | wc -l)
echo "Branch exists: $EXISTS"
if [ "$EXISTS" = "0" ]; then
echo "Branch does not exist, creating it."
git checkout -b lean-pr-testing-${{ steps.workflow-info.outputs.pullRequestNumber }}
echo "leanprover/lean4-pr-releases:pr-release-${{ steps.workflow-info.outputs.pullRequestNumber }}" > lean-toolchain
git add lean-toolchain
git commit -m "Update lean-toolchain for testing https://github.com/leanprover/lean4/pull/${{ steps.workflow-info.outputs.pullRequestNumber }}"
else
echo "Branch already exists, pushing an empty commit."
git checkout lean-pr-testing-${{ steps.workflow-info.outputs.pullRequestNumber }}
# The Mathlib `nightly-testing` branch may have moved since this branch was created, so merge their changes.
# If the base of this Lean4 PR becomes significantly older than the nightly being used by `nightly-testing`
# this will cause breakages rather than fixing them!
# Without cumbersome requirements that Lean4 PRs are based off nightlies, I'm not sure there is a perfect solution here.
git merge nightly-testing --strategy-option ours --no-commit --allow-unrelated-histories
git commit --allow-empty -m "Trigger CI for https://github.com/leanprover/lean4/pull/${{ steps.workflow-info.outputs.pullRequestNumber }}"
fi
- name: Push changes
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
run: |
git push origin lean-pr-testing-${{ steps.workflow-info.outputs.pullRequestNumber }}

View File

@@ -1,20 +0,0 @@
name: 'Label stale PRs'
on:
schedule:
- cron: '30 1 * * *'
workflow_dispatch:
permissions:
pull-requests: write
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v8
with:
days-before-stale: -1
days-before-pr-stale: 30
days-before-close: -1
stale-pr-label: 'stale'
only-labels: 'awaiting-author'

3
.gitignore vendored
View File

@@ -3,7 +3,6 @@
.#*
*.lock
build
!/src/lake/Lake/Build
GPATH
GRTAGS
GSYMS
@@ -26,4 +25,4 @@ fwIn.txt
fwOut.txt
wdErr.txt
wdIn.txt
wdOut.txt
wdOut.txt

View File

@@ -15,9 +15,6 @@ foreach(var ${vars})
# must forward options that generate incompatible .olean format
list(APPEND STAGE0_ARGS "-D${var}=${${var}}")
endif()
if("${var}" MATCHES "LLVM*")
list(APPEND STAGE0_ARGS "-D${var}=${${var}}")
endif()
elseif(("${var}" MATCHES "CMAKE_.*") AND NOT ("${var}" MATCHES "CMAKE_BUILD_TYPE") AND NOT ("${var}" MATCHES "CMAKE_HOME_DIRECTORY"))
list(APPEND PLATFORM_ARGS "-D${var}=${${var}}")
endif()
@@ -26,10 +23,23 @@ endforeach()
include(ExternalProject)
project(LEAN CXX C)
if(NOT (DEFINED STAGE0_CMAKE_EXECUTABLE_SUFFIX))
set(STAGE0_CMAKE_EXECUTABLE_SUFFIX "${CMAKE_EXECUTABLE_SUFFIX}")
if("${CMAKE_SYSTEM_NAME}" MATCHES "Emscripten")
# For Emscripten, we build GMP before any of the stages and reuse it in all of them.
set(GMP_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/gmp-root)
set(EMSCRIPTEN_FLAGS "-s ALLOW_MEMORY_GROWTH=1 -s MAIN_MODULE=1 -O3")
ExternalProject_Add(
gmp
URL https://gmplib.org/download/gmp/gmp-6.2.1.tar.bz2
URL_HASH SHA256=eae9326beb4158c386e39a356818031bd28f3124cf915f8c5b1dc4c7a36b4d7c
BUILD_IN_SOURCE 1
CONFIGURE_COMMAND emconfigure ./configure "CFLAGS=${EMSCRIPTEN_FLAGS}" --host=wasm32-unknown-emscripten --disable-assembly --prefix=${GMP_INSTALL_PREFIX}
BUILD_COMMAND emmake make -j4
INSTALL_COMMAND emmake make install
)
set(EXTRA_DEPENDS "gmp")
list(APPEND CL_ARGS "-DGMP_INSTALL_PREFIX=${GMP_INSTALL_PREFIX}")
list(APPEND PLATFORM_ARGS "-DGMP_INSTALL_PREFIX=${GMP_INSTALL_PREFIX}")
endif()
ExternalProject_add(stage0
SOURCE_DIR "${LEAN_SOURCE_DIR}/stage0"
SOURCE_SUBDIR src
@@ -44,7 +54,7 @@ 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}
CMAKE_ARGS -DSTAGE=1 -DPREV_STAGE=${CMAKE_BINARY_DIR}/stage0 ${CL_ARGS}
BUILD_ALWAYS ON
INSTALL_COMMAND ""
DEPENDS stage0
@@ -53,7 +63,7 @@ ExternalProject_add(stage2
SOURCE_DIR "${LEAN_SOURCE_DIR}"
SOURCE_SUBDIR src
BINARY_DIR stage2
CMAKE_ARGS -DSTAGE=2 -DPREV_STAGE=${CMAKE_BINARY_DIR}/stage1 -DPREV_STAGE_CMAKE_EXECUTABLE_SUFFIX=${CMAKE_EXECUTABLE_SUFFIX} ${CL_ARGS}
CMAKE_ARGS -DSTAGE=2 -DPREV_STAGE=${CMAKE_BINARY_DIR}/stage1 ${CL_ARGS}
BUILD_ALWAYS ON
INSTALL_COMMAND ""
DEPENDS stage1
@@ -63,7 +73,7 @@ ExternalProject_add(stage3
SOURCE_DIR "${LEAN_SOURCE_DIR}"
SOURCE_SUBDIR src
BINARY_DIR stage3
CMAKE_ARGS -DSTAGE=3 -DPREV_STAGE=${CMAKE_BINARY_DIR}/stage2 -DPREV_STAGE_CMAKE_EXECUTABLE_SUFFIX=${CMAKE_EXECUTABLE_SUFFIX} ${CL_ARGS}
CMAKE_ARGS -DSTAGE=3 -DPREV_STAGE=${CMAKE_BINARY_DIR}/stage2 ${CL_ARGS}
BUILD_ALWAYS ON
INSTALL_COMMAND ""
DEPENDS stage2

View File

@@ -54,8 +54,8 @@ We don't want to waste your time by you implementing a feature and then us not b
## How to Contribute
* Always follow the [commit convention](https://lean-lang.org/lean4/doc/dev/commit_convention.html).
* Always follow the [commit convention](https://leanprover.github.io/lean4/doc/dev/commit_convention.html).
* Follow the style of the surrounding code. When in doubt, look at other files using the particular syntax as well.
* Make sure your code is documented.
* New features or bug fixes should come with appropriate tests.
* Ensure all tests work before submitting a PR; see [Development Setup](https://lean-lang.org/lean4/doc/make/index.html#development-setup) and [Fixing Tests](https://lean-lang.org/lean4/doc/dev/fixing_tests.html).
* Ensure all tests work before submitting a PR; see [Development Setup](https://leanprover.github.io/lean4/doc/make/index.html#development-setup) and [Fixing Tests](https://leanprover.github.io/lean4/doc/dev/fixing_tests.html).

View File

@@ -1,25 +1,22 @@
This is the repository for **Lean 4**.
We provide [nightly releases](https://github.com/leanprover/lean4-nightly/releases)
and have just begun regular [stable point releases](https://github.com/leanprover/lean4/releases).
This is the repository for **Lean 4**, which is being actively developed and published as nightly releases.
Stable point releases are planned for a later date after establishing a robust release process.
# About
- [Quickstart](https://github.com/leanprover/lean4/blob/master/doc/quickstart.md)
- [Walkthrough installation video](https://www.youtube.com/watch?v=yZo6k48L0VY)
- [Quick tour video](https://youtu.be/zyXtbb_eYbY)
- [Homepage](https://lean-lang.org)
- [Theorem Proving Tutorial](https://lean-lang.org/theorem_proving_in_lean4/)
- [Functional Programming in Lean](https://lean-lang.org/functional_programming_in_lean/)
- [Manual](https://lean-lang.org/lean4/doc/)
- [Homepage](https://leanprover.github.io)
- [Theorem Proving Tutorial](https://leanprover.github.io/theorem_proving_in_lean4/)
- [Functional Programming in Lean](https://leanprover.github.io/functional_programming_in_lean/)
- [Manual](https://leanprover.github.io/lean4/doc/)
- [Release notes](RELEASES.md) starting at v4.0.0-m3
- [Examples](https://lean-lang.org/lean4/doc/examples.html)
- [External Contribution Guidelines](https://github.com/leanprover/lean4/blob/master/doc/contributions.md)
- [FAQ](https://lean-lang.org/lean4/doc/faq.html)
- [Examples](https://leanprover.github.io/lean4/doc/examples.html)
- [FAQ](https://leanprover.github.io/lean4/doc/faq.html)
# Installation
See [Setting Up Lean](https://lean-lang.org/lean4/doc/setup.html).
See [Setting Up Lean](https://leanprover.github.io/lean4/doc/setup.html).
# Contributing
@@ -27,4 +24,4 @@ Please read our [Contribution Guidelines](CONTRIBUTING.md) first.
# Building from Source
See [Building Lean](https://lean-lang.org/lean4/doc/make/index.html).
See [Building Lean](https://leanprover.github.io/lean4/doc/make/index.html).

View File

@@ -1,79 +1,6 @@
# Lean 4 releases
We intend to provide regular "minor version" releases of the Lean language at approximately monthly intervals.
There is not yet a strong guarantee of backwards compatibility between versions,
only an expectation that breaking changes will be documented in this file.
This file contains work-in-progress notes for the upcoming release, as well as previous stable releases.
Please check the [releases](https://github.com/leanprover/lean4/releases) page for the current status of each version.
v4.3.0 (development in progress)
Unreleased
---------
* The derive handler for `DecidableEq` [now handles](https://github.com/leanprover/lean4/pull/2591) mutual inductive types.
* [Show path of failed import in Lake](https://github.com/leanprover/lean4/pull/2616).
* [Fix linker warnings on macOS](https://github.com/leanprover/lean4/pull/2598).
v4.2.0
---------
* Improvements to Lake startup time ([#2572](https://github.com/leanprover/lean4/pull/2572), [#2573](https://github.com/leanprover/lean4/pull/2573))
* `refine e` now replaces the main goal with metavariables which were created during elaboration of `e` and no longer captures pre-existing metavariables that occur in `e` ([#2502](https://github.com/leanprover/lean4/pull/2502)).
* This is accomplished via changes to `withCollectingNewGoalsFrom`, which also affects `elabTermWithHoles`, `refine'`, `calc` (tactic), and `specialize`. Likewise, all of these now only include newly-created metavariables in their output.
* Previously, both newly-created and pre-existing metavariables occurring in `e` were returned inconsistently in different edge cases, causing duplicated goals in the infoview (issue [#2495](https://github.com/leanprover/lean4/issues/2495)), erroneously closed goals (issue [#2434](https://github.com/leanprover/lean4/issues/2434)), and unintuitive behavior due to `refine e` capturing previously-created goals appearing unexpectedly in `e` (no issue; see PR).
v4.1.0
---------
* The error positioning on missing tokens has been [improved](https://github.com/leanprover/lean4/pull/2393). In particular, this should make it easier to spot errors in incomplete tactic proofs.
* After elaborating a configuration file, Lake will now cache the configuration to a `lakefile.olean`. Subsequent runs of Lake will import this OLean instead of elaborating the configuration file. This provides a significant performance improvement (benchmarks indicate that using the OLean cuts Lake's startup time in half), but there are some important details to keep in mind:
+ Lake will regenerate this OLean after each modification to the `lakefile.lean` or `lean-toolchain`. You can also force a reconfigure by passing the new `--reconfigure` / `-R` option to `lake`.
+ Lake configuration options (i.e., `-K`) will be fixed at the moment of elaboration. Setting these options when `lake` is using the cached configuration will have no effect. To change options, run `lake` with `-R` / `--reconfigure`.
+ **The `lakefile.olean` is a local configuration and should not be committed to Git. Therefore, existing Lake packages need to add it to their `.gitignore`.**
* The signature of `Lake.buildO` has changed, `args` has been split into `weakArgs` and `traceArgs`. `traceArgs` are included in the input trace and `weakArgs` are not. See Lake's [FFI example](src/lake/examples/ffi/lib/lakefile.lean) for a demonstration of how to adapt to this change.
* The signatures of `Lean.importModules`, `Lean.Elab.headerToImports`, and `Lean.Elab.parseImports`
have [changed](https://github.com/leanprover/lean4/pull/2480) from taking `List Import` to `Array Import`.
* There is now [an `occs` field](https://github.com/leanprover/lean4/pull/2470)
in the configuration object for the `rewrite` tactic,
allowing control of which occurrences of a pattern should be rewritten.
This was previously a separate argument for `Lean.MVarId.rewrite`,
and this has been removed in favour of an additional field of `Rewrite.Config`.
It was not previously accessible from user tactics.
v4.0.0
---------
* [`Lean.Meta.getConst?` has been renamed](https://github.com/leanprover/lean4/pull/2454).
We have renamed `getConst?` to `getUnfoldableConst?` (and `getConstNoEx?` to `getUnfoldableConstNoEx?`).
These were not intended to be part of the public API, but downstream projects had been using them
(sometimes expecting different behaviour) incorrectly instead of `Lean.getConstInfo`.
* [`dsimp` / `simp` / `simp_all` now fail by default if they make no progress](https://github.com/leanprover/lean4/pull/2336).
This can be overridden with the `(config := { failIfUnchanged := false })` option.
This change was made to ease manual use of `simp` (with complicated goals it can be hard to tell if it was effective)
and to allow easier flow control in tactics internally using `simp`.
See the [summary discussion](https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/simp.20fails.20if.20no.20progress/near/380153295)
on zulip for more details.
* [`simp_all` now preserves order of hypotheses](https://github.com/leanprover/lean4/pull/2334).
In order to support the `failIfUnchanged` configuration option for `dsimp` / `simp` / `simp_all`
the way `simp_all` replaces hypotheses has changed.
In particular it is now more likely to preserve the order of hypotheses.
See [`simp_all` reorders hypotheses unnecessarily](https://github.com/leanprover/lean4/pull/2334).
(Previously all non-dependent propositional hypotheses were reverted and reintroduced.
Now only such hypotheses which were changed, or which come after a changed hypothesis,
are reverted and reintroduced.
This has the effect of preserving the ordering amongst the non-dependent propositional hypotheses,
but now any dependent or non-propositional hypotheses retain their position amongst the unchanged
non-dependent propositional hypotheses.)
This may affect proofs that use `rename_i`, `case ... =>`, or `next ... =>`.
* [New `have this` implementation](https://github.com/leanprover/lean4/pull/2247).
`this` is now a regular identifier again that is implicitly introduced by anonymous `have :=` for the remainder of the tactic block. It used to be a keyword that was visible in all scopes and led to unexpected behavior when explicitly used as a binder name.
@@ -153,7 +80,7 @@ v4.0.0
* New [code generator](https://github.com/leanprover/lean4/tree/master/src/Lean/Compiler/LCNF) project has started.
* Remove description argument from `register_simp_attr`. [PR #1566](https://github.com/leanprover/lean4/pull/1566).
* Remove description argument frome `register_simp_attr`. [PR #1566](https://github.com/leanprover/lean4/pull/1566).
* [Additional concurrency primitives](https://github.com/leanprover/lean4/pull/1555).
@@ -673,7 +600,7 @@ v4.0.0-m5 (07 August 2022)
`Foo : {Foo : Type u} → List Foo → Type`.
* Fix syntax highlighting for recursive declarations. Example
* Fix syntax hightlighting for recursive declarations. Example
```lean
inductive List (α : Type u) where
| nil : List α -- `List` is not highlighted as a variable anymore
@@ -982,7 +909,7 @@ For example, given `f : Nat → Nat` and `g : Nat → Nat`, `f.comp g` is now no
* Various improvements to go-to-definition & find-all-references accuracy.
* Auto generated congruence lemmas with support for casts on proofs and `Decidable` instances (see [wishlist](https://github.com/leanprover/lean4/issues/988)).
* Auto generated congruence lemmas with support for casts on proofs and `Decidable` instances (see [whishlist](https://github.com/leanprover/lean4/issues/988)).
* Rename option `autoBoundImplicitLocal` => `autoImplicit`.

View File

@@ -11,4 +11,4 @@ the following command executes a simple set of examples
% bin/lean examples/ex.lean
For more information on Lean and supported editors, please see https://lean-lang.org/documentation/.
For more information on Lean and supported editors, please see https://leanprover.github.io/documentation/.

View File

@@ -1,68 +0,0 @@
External Contribution Guidelines
============
**In the past, we accepted most pull requests. This practice produced hard to maintain code, performance problems, and bugs.** In order to improve the quality and maintainability of our codebase, we've established the following guidelines for external contributions.
Before You Submit a Pull Request (PR):
-------
**Start with an Issue**: Before submitting a PR, always open an issue discussing the problem you wish to solve or the feature you'd like to add. Use the prefix `RFC:` (request for comments) if you are proposing a new feature. Ask for feedback from other users. Take the time to summarize all the feedback. This allows the maintainers to evaluate your proposal more efficiently. When creating a RFC, consider the following questions:
- **User Experience**: How does this feature improve the user experience?
- **Beneficiaries**: Which Lean users and projects do benefit most from this feature/change?
- **Community Feedback**: Have you sought feedback or insights from other Lean users?
- **Maintainability**: Will this change streamline code maintenance or simplify its structure?
**Understand the Project**: Familiarize yourself with the project, existing issues, and latest commits. Ensure your contribution aligns with the project's direction and priorities.
**Stay Updated**: Regularly fetch and merge changes from the main branch to ensure your branch is up-to-date and can be smoothly integrated.
**Help wanted**: We have issues tagged with ["help wanted"](https://github.com/leanprover/lean4/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22), if you want to contribute to the project, please take a look at them. If you are interested in one of them, post comments, ask questions, and engage with the core developers there.
Quality Over Quantity:
-----
**Focused Changes**: Each PR should address a single, clearly-defined issue or feature. Avoid making multiple unrelated changes in a single PR.
**Write Tests**: Every new feature or bug fix should come with relevant tests. This ensures the robustness and reliability of the contribution.
**Documentation**: Update relevant documentation, including comments in the code, to explain the logic and reasoning behind your changes.
Coding Standards:
----
**Follow the Code Style**: Ensure that your code follows the established coding style of the project.
**Lean on Lean**: Use Lean's built-in features and libraries effectively, avoiding reinventions.
**Performance**: Make sure that your changes do not introduce performance regressions. If possible, optimize the solution for speed and resource usage.
PR Submission:
---
**Descriptive Title and Summary**: The PR title should briefly explain the purpose of the PR. The summary should give more detailed information on what changes are made and why. Links to Zulip threads are not acceptable as a summary. You are responsible for summarizing the discussion, and getting support for it.
**Link to Relevant Issues**: Reference any issues that your PR addresses to provide context.
**Stay Responsive**: Once the PR is submitted, stay responsive to feedback and be prepared to make necessary revisions. We will close any PR that has been inactive (no response or updates from the submitter) for more than a month.
Reviews and Feedback:
----
**Be Patient**: Given the limited number of full-time maintainers and the volume of PRs, reviews may take some time.
**Engage Constructively**: Always approach feedback positively and constructively. Remember, reviews are about ensuring the best quality for the project, not personal criticism.
**Continuous Integration**: Ensure that all CI checks pass on your PR. Failed checks will delay the review process. The maintainers will not check PRs containing failures.
What to Expect:
----
**Not All PRs Get Merged**: While we appreciate every contribution, not all PRs will be merged. Ensure your changes align with the project's goals and quality standards.
**Feedback is a Gift**: It helps improve the project and can also help you grow as a developer or contributor.
**Community Involvement**: Engage with the Lean community on our communication channels. This can lead to better collaboration and understanding of the project's direction.

View File

@@ -11,8 +11,6 @@ There are two primary attributes for interoperating with other languages:
It can also be used with `def` to provide an internal definition, but ensuring consistency of both definitions is up to the user.
* `@[export sym] def leanSym : ...` exports `leanSym` under the unmangled symbol name `sym`.
For simple examples of how to call foreign code from Lean and vice versa, see <https://github.com/leanprover/lean4/blob/master/src/lake/examples/ffi> and <https://github.com/leanprover/lean4/blob/master/src/lake/examples/reverse-ffi>, respectively.
## The Lean ABI
The Lean Application Binary Interface (ABI) describes how the signature of a Lean declaration is encoded as a native calling convention.

View File

@@ -1,6 +1,6 @@
# Documentation
The Lean `doc` folder contains the [Lean Manual](https://lean-lang.org/lean4/doc/) and is
The Lean `doc` folder contains the [Lean Manual](https://leanprover.github.io/lean4/doc/) and is
authored in a combination of markdown (`*.md`) files and literate Lean files. The .lean files are
preprocessed using a tool called [LeanInk](https://github.com/leanprover/leanink) and
[Alectryon](https://github.com/Kha/alectryon) which produces a generated markdown file. We then run
@@ -83,7 +83,7 @@ Then run the following:
```
This will put the HTML in a `out` folder so you can load `out/index.html` in your web browser and
it should look like https://lean-lang.org/lean4/doc/.
it should look like https://leanprover.github.io/lean4/doc/.
1. It is also handy to use e.g. [`mdbook watch`](https://rust-lang.github.io/mdBook/cli/watch.html)
in the `doc/` folder so that it keeps the html up to date while you are editing.

View File

@@ -87,16 +87,6 @@ All these tests are included by [src/shell/CMakeLists.txt](https://github.com/le
- `tests/plugin`: tests that compiled Lean code can be loaded into
`lean` via the `--plugin` command line option.
## Writing Good Tests
Every test file should contain:
* an initial `/-! -/` module docstring summarizing the test's purpose
* a module docstring for each test section that describes what is tested
and, if not 100% clear, why that is the desirable behavior
At the time of writing, most tests do not follow these new guidelines yet.
For an example of a conforming test, see `tests/lean/1971.lean`.
## Fixing Tests
When the Lean source code or the standard library are modified, some of the
@@ -111,7 +101,7 @@ First, we must install [meld](http://meldmerge.org/). On Ubuntu, we can do it by
sudo apt-get install meld
```
Now, suppose `bad_class.lean` test is broken. We can see the problem by going to `tests/lean` directory and
Now, suppose `bad_class.lean` test is broken. We can see the problem by going to `test/lean` directory and
executing
```

View File

@@ -5,7 +5,7 @@ If the type of keys can be totally ordered -- that is, it supports a well-behave
then maps can be implemented with binary search trees (BSTs). Insert and lookup operations on BSTs take time
proportional to the height of the tree. If the tree is balanced, the operations therefore take logarithmic time.
This example is based on a similar example found in the ["Software Foundations"](https://softwarefoundations.cis.upenn.edu/vfa-current/SearchTree.html)
This example is based on a similar example found in the ["Sofware Foundations"](https://softwarefoundations.cis.upenn.edu/vfa-current/SearchTree.html)
book (volume 3).
-/
@@ -81,9 +81,9 @@ def Tree.toList (t : Tree β) : List (Nat × β) :=
|>.toList
/-!
The implementation of `Tree.toList` is inefficient because of how it uses the `++` operator.
The implemention of `Tree.toList` is inefficient because of how it uses the `++` operator.
On a balanced tree its running time is linearithmic, because it does a linear number of
concatenations at each level of the tree. On an unbalanced tree it's quadratic time.
concatentations at each level of the tree. On an unbalanced tree it's quadratic time.
Here's a tail-recursive implementation than runs in linear time, regardless of whether the tree is balanced:
-/
def Tree.toListTR (t : Tree β) : List (Nat × β) :=
@@ -114,9 +114,9 @@ concatenating all goals produced by `tac'`. In this theorem, we use it to apply
The `simp` parameters `toListTR.go` and `toList` instruct the simplifier to try to reduce
and/or apply auto generated equation theorems for these two functions.
The parameter `*` instructs the simplifier to use any equation in a goal as rewriting rules.
The parameter `*` intructs the simplifier to use any equation in a goal as rewriting rules.
In this particular case, `simp` uses the induction hypotheses as rewriting rules.
Finally, the parameter `List.append_assoc` instructs the simplifier to use the
Finally, the parameter `List.append_assoc` intructs the simplifier to use the
`List.append_assoc` theorem as a rewriting rule.
-/
theorem Tree.toList_eq_toListTR (t : Tree β)
@@ -186,7 +186,7 @@ local macro "have_eq " lhs:term:max rhs:term:max : tactic =>
The `by_cases' e` is just the regular `by_cases` followed by `simp` using all
hypotheses in the current goal as rewriting rules.
Recall that the `by_cases` tactic creates two goals. One where we have `h : e` and
another one containing `h : ¬ e`. The simplifier uses the `h` to rewrite `e` to `True`
another one containing `h : ¬ e`. The simplier uses the `h` to rewrite `e` to `True`
in the first subgoal, and `e` to `False` in the second. This is particularly
useful if `e` is the condition of an `if`-statement.
-/
@@ -282,7 +282,7 @@ theorem BinTree.find_insert_of_ne (b : BinTree β) (h : k ≠ k') (v : β)
let t, h := b; simp
induction t with simp
| leaf =>
split <;> (try simp) <;> split <;> (try simp)
split <;> simp <;> split <;> simp
have_eq k k'
contradiction
| node left key value right ihl ihr =>

View File

@@ -152,7 +152,7 @@ We prove all cases but the one for `plus` using `simp [*]`. This tactic instruct
use hypotheses such as `a = b` as rewriting/simplications rules.
We use the `split` to break the nested `match` expression in the `plus` case into two cases.
The local variables `iha` and `ihb` are the induction hypotheses for `a` and `b`.
The modifier `←` in a term simplifier argument instructs the term simplifier to use the equation as a rewriting rule in
The modifier `←` in a term simplifier argument instructs the term simplier to use the equation as a rewriting rule in
the "reverse direction". That is, given `h : a = b`, `← h` instructs the term simplifier to rewrite `b` subterms to `a`.
-/
theorem Term.constFold_sound (e : Term ctx ty) : e.constFold.denote env = e.denote env := by

View File

@@ -83,7 +83,7 @@ In practice, this means we use `stop` to refer to the most recently defined vari
A value `Expr.val` carries a concrete representation of an integer.
A lambda `Expr.lam` creates a function. In the scope of a function of type `Ty.fn a ty`, there is a
A lambda `Expr.lam` creates a function. In the scope of a function ot type `Ty.fn a ty`, there is a
new local variable of type `a`.
A function application `Expr.app` produces a value of type `ty` given a function from `a` to `ty` and a value of type `a`.
@@ -139,7 +139,7 @@ def add : Expr ctx (Ty.fn Ty.int (Ty.fn Ty.int Ty.int)) :=
More interestingly, a factorial function fact (e.g. `fun x => if (x == 0) then 1 else (fact (x-1) * x)`), can be written as.
Note that this is a recursive (non-terminating) definition. For every input value, the interpreter terminates, but the
definition itself is non-terminating. We use two tricks to make sure Lean accepts it. First, we use the auxiliary constructor
`Expr.delay` to delay its unfolding. Second, we add the annotation `decreasing_by sorry` which can be viewed as
`Expr.delay` to delay its unfolding. Second, we add the annotation `decreasing_by sorry` which can be viwed as
"trust me, this recursive definition makes sense". Recall that `sorry` is an unsound axiom in Lean.
-/

View File

@@ -228,7 +228,7 @@ We prove all cases but the one for `plus` using `simp [*]`. This tactic instruct
use hypotheses such as `a = b` as rewriting/simplications rules.
We use the `split` to break the nested `match` expression in the `plus` case into two cases.
The local variables `iha` and `ihb` are the induction hypotheses for `a` and `b`.
The modifier `←` in a term simplifier argument instructs the term simplifier to use the equation as a rewriting rule in
The modifier `←` in a term simplifier argument instructs the term simplier to use the equation as a rewriting rule in
the "reverse direction. That is, given `h : a = b`, `← h` instructs the term simplifier to rewrite `b` subterms to `a`.
-/
theorem constFold_sound (e : Term' Ty.denote ty) : denote (constFold e) = denote e := by

View File

@@ -38,7 +38,7 @@ theorem HasType.det (h₁ : HasType e t₁) (h₂ : HasType e t₂) : t₁ = t
cases h₁ <;> cases h₂ <;> rfl
/-!
The inductive type `Maybe p` has two constructors: `found a h` and `unknown`.
The inductive type `Maybe p` has two contructors: `found a h` and `unknown`.
The former contains an element `a : α` and a proof that `a` satisfies the predicate `p`.
The constructor `unknown` is used to encode "failure".
-/

View File

@@ -111,8 +111,8 @@ def getType (params : GetTypeParams) : RequestM (RequestTask CodeWithInfos) :=
withWaitFindSnapAtPos params.pos fun snap => do
runTermElabM snap do
let name resolveGlobalConstNoOverloadCore params.name
let c try getConstInfo name
catch _ => throwThe RequestError .invalidParams, s!"no constant named '{name}'"
let some c Meta.getConst? name
| throwThe RequestError .invalidParams, s!"no constant named '{name}'"
Widget.ppExprTagged c.type
/-!

View File

@@ -7,6 +7,15 @@ Lean is a new open source theorem prover being developed at Microsoft Research.
It is a research project that aims to bridge the gap between interactive and automated theorem proving.
Lean can be also used as a programming language. Actually, some Lean features are implemented in Lean itself.
### Are pull requests welcome?
In the past, we accepted most pull requests. This practice produced hard to maintain code, performance problems, and bugs.
It takes time to review a pull request and make sure it is correct, useful and is not in conflict with our plans.
Small bug fixes (few lines of code) are always welcome. Any other kind of unrequested pull request is not.
Thus, before implementing a feature or modifying the system, please ask whether the change is welcome or not.
We have issues tagged with ["help wanted"](https://github.com/leanprover/lean4/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22), if you want to contribute to the project, please take a look at them.
If you are interested in one of them, post comments, ask questions, and engage with the core developers there.
### Should I use Lean?
Lean is under heavy development, and we are constantly trying new
@@ -27,7 +36,7 @@ It is a good place to interact with other Lean users.
### Should I use Lean to teach a course?
Lean has been used to teach courses on logic, type theory and programming languages at CMU and the University of Washington.
The lecture notes for the CMU course [Logic and Proof](https://lean-lang.org/logic_and_proof) are available online,
The lecture notes for the CMU course [Logic and Proof](https://leanprover.github.io/logic_and_proof) are available online,
but they are for Lean 3.
If you decide to teach a course using Lean, we suggest you prepare all material before the beginning of the course, and
make sure that Lean attends all your needs. You should not expect we will fix bugs and/or add features needed for your course.
@@ -47,7 +56,7 @@ We expect similar independent checkers will be built for Lean 4.
We use [GitHub](https://github.com/leanprover/lean4/issues) to track bugs and new features.
Bug reports are always welcome, but nitpicking issues are not (e.g., the error message is confusing).
See also our [contribution guidelines](https://github.com/leanprover/lean4/blob/master/CONTRIBUTING.md).
See also our [contribution guidelines](../CONTRIBUTING.md).
### Is it Lean, LEAN, or L∃∀N?

View File

@@ -27,7 +27,7 @@
src = inputs.mdBook;
cargoDeps = drv.cargoDeps.overrideAttrs (_: {
inherit src;
outputHash = "sha256-1YlPS6cqgxE4fjy9G8pWrpP27YrrbCDnfeyIsX81ZNw=";
outputHash = "sha256-mhTWHs/bsmm3FH59SkUxBTl5lEH2Rlz/aF9CuBTu1TE=";
});
doCheck = false;
});

View File

@@ -1,7 +1,7 @@
Functional Programming in Lean
=======================
The goal of [this book](https://lean-lang.org/functional_programming_in_lean/) is to be an accessible introduction to using Lean 4 as a programming language.
The goal of [this book](https://leanprover.github.io/functional_programming_in_lean/) is to be an accessible introduction to using Lean 4 as a programming language.
It should be useful both to people who want to use Lean as a general-purpose programming language and to mathematicians who want to develop larger-scale proof automation but do not have a background in functional programming.
It does not assume any background with functional programming, though it's probably not a good first book on programming in general.
New content will be added once per month until it's done.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -1,3 +1,3 @@
# Inductive Types
[Theorem Proving in Lean](https://lean-lang.org/theorem_proving_in_lean4/inductive_types.html) has a chapter about inductive datatypes.
[Theorem Proving in Lean](https://leanprover.github.io/theorem_proving_in_lean4/inductive_types.html) has a chapter about inductive datatypes.

View File

@@ -4,7 +4,7 @@
\lstdefinelanguage{lean} {
% Anything between $ becomes LaTeX math mode
% Anything betweeen $ becomes LaTeX math mode
mathescape=false,
% Comments may or not include Latex commands
texcl=false,
@@ -265,7 +265,7 @@ columns=[l]fullflexible,
% Style for (listings') identifiers
identifierstyle={\ttfamily\color{black}},
% Note : highlighting of Coq identifiers is done through a new
% delimiter definition through an lstset at the beginning of the
% delimiter definition through an lstset at the begining of the
% document. Don't know how to do better.
% Style for declaration keywords

View File

@@ -113,7 +113,7 @@ the monadic container type.
to write `(readerFunc3 args).run env` and this is a bit ugly, so Lean provides an infix operator
`|>` that eliminates those parentheses so you can write `readerFunc3 args |>.run env` and then you can
chain multiple monadic actions like this `m1 args1 |>.run args2 |>.run args3` and this is the
recommended style. You will see this pattern used heavily in Lean code.
recommended style. You will see this patten used heavily in Lean code.
The `let env ← read` expression in `readerFunc1` unwraps the environment from the `ReaderM` so we
can use it. Each type of monad might provide one or more extra functions like this, functions that

View File

@@ -17,12 +17,12 @@ See quick [walkthrough demo video](https://www.youtube.com/watch?v=yZo6k48L0VY).
Click the "Install Lean using Elan" button. You should see some progress output like this:
```
info: syncing channel updates for 'stable'
info: latest update on stable, lean version v4.0.0
info: syncing channel updates for 'nightly'
info: latest update on nightly, lean version nightly-2023-06-27
info: downloading component 'lean'
```
If there is no popup, you probably have Elan installed already.
You may want to make sure that your default toolchain is Lean 4 in this case by running `elan default leanprover/lean4:stable` and reopen the file, as the next step will fail otherwise.
You may want to make sure that your default toolchain is Lean 4 in this case by running `elan default leanprover/lean4:nightly` and reopen the file, as the next step will fail otherwise.
1. While it is installing, you can paste the following Lean program into the new file:
@@ -39,7 +39,7 @@ You are set up!
## Create a Lean Project
*If your goal is to contribute to [mathlib4](https://github.com/leanprover-community/mathlib4) or use it as a dependency, please see its readme for specific instructions on how to do that.*
*If your goal is to contribute to [mathlib4](https://github.com/leanprover-community/mathlib4) or use it as a depdency, please see its readme for specific instructions on how to do that.*
You can now create a Lean project in a new folder. Run `lake init foo` from "View > Terminal" to create a package, followed by `lake build` to get an executable version of your Lean program.
On Linux/macOS, you first have to follow the instructions printed by the Lean installation or log out and in again for the Lean executables to be available in you terminal.

View File

@@ -4,7 +4,7 @@ Semantic Highlighting
The Lean language server provides semantic highlighting information to editors. In order to benefit from this in VSCode, you may need to activate the "Editor > Semantic Highlighting" option in the preferences (this is translates to `"editor.semanticHighlighting.enabled": true,`
in `settings.json`). The default option here is to let your color theme decides whether it activates semantic highlighting (the default themes Dark+ and Light+ do activate it for instance).
However this may be insufficient if your color theme does not distinguish enough syntax categories or distinguishes them very subtly. For instance the default Light+ theme uses color `#001080` for variables. This is awfully close to `#000000` that is used as the default text color. This makes it very easy to miss an accidental use of [auto bound implicit arguments](https://lean-lang.org/lean4/doc/autobound.html). For instance in
However this may be insufficient if your color theme does not distinguish enough syntax categories or distinguishes them very subtly. For instance the default Light+ theme uses color `#001080` for variables. This is awfully close to `#000000` that is used as the default text color. This makes it very easy to miss an accidental use of [auto bound implicit arguments](https://leanprover.github.io/lean4/doc/autobound.html). For instance in
```lean
def my_id (n : nat) := n
```

View File

@@ -32,8 +32,8 @@ Release builds for all supported platforms are available at <https://github.com/
Instead of downloading these and setting up the paths manually, however, it is recommended to use the Lean version manager [`elan`](https://github.com/leanprover/elan) instead:
```sh
$ elan self update # in case you haven't updated elan in a while
# download & activate latest Lean 4 stable release (https://github.com/leanprover/lean4/releases)
$ elan default leanprover/lean4:stable
# download & activate latest Lean 4 nightly release (https://github.com/leanprover/lean4-nightly/releases)
$ elan default leanprover/lean4:nightly
```
## `lake`

View File

@@ -1,5 +1,5 @@
Theorem Proving in Lean
=======================
We strongly encourage you to read the book [Theorem Proving in Lean](https://lean-lang.org/theorem_proving_in_lean4/title_page.html).
We strongly encourage you to read the book [Theorem Proving in Lean](https://leanprover.github.io/theorem_proving_in_lean4/title_page.html).
Many Lean users consider it to be the Lean Bible.

View File

@@ -36,7 +36,7 @@ Lean has numerous features, including:
- [Monads](./monads/intro.md)
- [Extensible syntax](./syntax.md)
- Hygienic macros
- [Dependent types](https://lean-lang.org/theorem_proving_in_lean4/dependent_type_theory.html)
- [Dependent types](https://leanprover.github.io/theorem_proving_in_lean4/dependent_type_theory.html)
- [Metaprogramming](./metaprogramming.md)
- Multithreading
- Verification: you can prove properties of your functions using Lean itself

6
flake.lock generated
View File

@@ -101,11 +101,11 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1686089707,
"narHash": "sha256-LTNlJcru2qJ0XhlhG9Acp5KyjB774Pza3tRH0pKIb3o=",
"lastModified": 1657208011,
"narHash": "sha256-BlIFwopAykvdy1DYayEkj6ZZdkn+cVgPNX98QVLc0jM=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "af21c31b2a1ec5d361ed8050edd0303c31306397",
"rev": "2770cc0b1e8faa0e20eb2c6aea64c256a706d4f2",
"type": "github"
},
"original": {

View File

@@ -158,7 +158,7 @@ with builtins; let
buildCommand = ''
dir=$(dirname $relpath)
mkdir -p $dir $out/$dir $ilean/$dir $c/$dir
if [ -d $src ]; then cp -r $src/. .; else cp $src $leanPath; fi
if [ -d $src ]; then cp -r $src/. $dir/; else cp $src $leanPath; fi
lean -o $out/$oleanPath -i $ilean/$ileanPath -c $c/$cPath $leanPath $leanFlags $leanPluginFlags $leanLoadDynlibFlags
'';
}) // {

View File

@@ -5,7 +5,7 @@ let
${nix.packages.${system}.default}/bin/nix --experimental-features 'nix-command flakes' --extra-substituters https://lean4.cachix.org/ --option warn-dirty false "$@"
'';
# https://github.com/NixOS/nixpkgs/issues/130963
llvmPackages = if stdenv.isDarwin then llvmPackages_11 else llvmPackages_15;
llvmPackages = if stdenv.isDarwin then llvmPackages_11 else llvmPackages_14;
cc = (ccacheWrapper.override rec {
cc = llvmPackages.clang;
extraConfig = ''

View File

@@ -7,7 +7,7 @@
# Author: Leonardo de Moura
#
# Given a text file containing constants defined in the Lean libraries,
# this script generates .h and .cpp files for initialing/finalizing these constants
# this script generates .h and .cpp files for initialing/finalizing theses constants
# as C++ name objects.
#
# This script is used to generate src/library/constants.cpp and src/library/constants.h

View File

@@ -7,7 +7,7 @@
# Author: Leonardo de Moura
#
# Given a text file containing id and token strings,
# this script generates .h and .cpp files for initialing/finalizing these tokens
# this script generates .h and .cpp files for initialing/finalizing theses tokens
# as C++ name objects.
#
# This script is used to generate src/frontends/lean/tokens.cpp and src/frontends/lean/tokens.h

View File

@@ -48,6 +48,7 @@ $CP -r llvm/include/*-*-* llvm-host/include/
$CP $GLIBC/lib/libc_nonshared.a stage1/lib/glibc
for f in $GLIBC/lib/lib{c,dl,m,rt,pthread}-*; do b=$(basename $f); cp $f stage1/lib/glibc/${b%-*}.so; done
OPTIONS=()
echo -n " -DLLVM=ON -DLLVM_CONFIG=$PWD/llvm-host/bin/llvm-config" # manually point to `llvm-config` location
echo -n " -DLEAN_STANDALONE=ON"
echo -n " -DCMAKE_CXX_COMPILER=$PWD/llvm-host/bin/clang++ -DLEAN_CXX_STDLIB='-Wl,-Bstatic -lc++ -lc++abi -Wl,-Bdynamic'"
echo -n " -DLEAN_EXTRA_CXX_FLAGS='--sysroot $PWD/llvm -idirafter $GLIBC_DEV/include ${EXTRA_FLAGS:-}'"

View File

@@ -39,6 +39,7 @@ gcp llvm/lib/libc++.dylib stage1/lib/libc
# make sure we search for the library in /usr/lib instead of the rpath, which should not contain `/usr/lib`
# and apparently since Sonoma does not do so implicitly either
install_name_tool -id /usr/lib/libc++.dylib stage1/lib/libc/libc++.dylib
echo -n " -DLLVM=ON -DLLVM_CONFIG=$PWD/llvm-host/bin/llvm-config" # manually point to `llvm-config` location
echo -n " -DLEAN_STANDALONE=ON"
# do not change C++ compiler; libc++ etc. being system libraries means there's no danger of conflicts,
# and the custom clang++ outputs a myriad of warnings when consuming the SDK

View File

@@ -32,6 +32,7 @@ cp /clang64/lib/{crtbegin,crtend,crt2,dllcrt2}.o stage1/lib/
(cd llvm; cp --parents lib/clang/*/lib/*/libclang_rt.builtins* ../stage1)
# further dependencies
cp /clang64/lib/lib{m,bcrypt,mingw32,moldname,mingwex,msvcrt,pthread,advapi32,shell32,user32,kernel32,ucrtbase}.* /clang64/lib/libgmp.a llvm/lib/lib{c++,c++abi,unwind}.a stage1/lib/
echo -n " -DLLVM=ON -DLLVM_CONFIG=$PWD/llvm/bin/llvm-config" # manually point to `llvm-config` location
echo -n " -DLEAN_STANDALONE=ON"
echo -n " -DCMAKE_C_COMPILER=$PWD/stage1/bin/clang.exe -DCMAKE_C_COMPILER_WORKS=1 -DCMAKE_CXX_COMPILER=$PWD/llvm/bin/clang++.exe -DCMAKE_CXX_COMPILER_WORKS=1 -DLEAN_CXX_STDLIB='-lc++ -lc++abi'"
echo -n " -DSTAGE0_CMAKE_C_COMPILER=clang -DSTAGE0_CMAKE_CXX_COMPILER=clang++"

View File

@@ -9,7 +9,7 @@ in { pkgs ? flakePkgs.nixpkgs, pkgsDist ? pkgs }:
} (rec {
buildInputs = with pkgs; [
cmake gmp ccache
flakePkgs.llvmPackages.llvm # llvm-symbolizer for asan/lsan
llvmPackages.llvm # llvm-symbolizer for asan/lsan
];
# https://github.com/NixOS/nixpkgs/issues/60919
hardeningDisable = [ "all" ];

View File

@@ -9,7 +9,7 @@ endif()
include(ExternalProject)
project(LEAN CXX C)
set(LEAN_VERSION_MAJOR 4)
set(LEAN_VERSION_MINOR 3)
set(LEAN_VERSION_MINOR 0)
set(LEAN_VERSION_PATCH 0)
set(LEAN_VERSION_IS_RELEASE 0) # This number is 1 in the release revision, and 0 otherwise.
set(LEAN_SPECIAL_VERSION_DESC "" CACHE STRING "Additional version description like 'nightly-2018-03-11'")
@@ -57,7 +57,6 @@ option(CUSTOM_ALLOCATORS "CUSTOM_ALLOCATORS" ON)
option(SAVE_SNAPSHOT "SAVE_SNAPSHOT" ON)
option(SAVE_INFO "SAVE_INFO" ON)
option(SMALL_ALLOCATOR "SMALL_ALLOCATOR" ON)
option(MMAP "MMAP" ON)
option(LAZY_RC "LAZY_RC" OFF)
option(RUNTIME_STATS "RUNTIME_STATS" OFF)
option(BSYMBOLIC "Link with -Bsymbolic to reduce call overhead in shared libraries (Linux)" ON)
@@ -85,10 +84,6 @@ else()
set(NumBits 32)
endif()
if ("${MMAP}" MATCHES "ON")
string(APPEND LEAN_EXTRA_CXX_FLAGS " -D LEAN_MMAP")
endif()
if ("${RUNTIME_STATS}" MATCHES "ON")
string(APPEND LEAN_EXTRA_CXX_FLAGS " -D LEAN_RUNTIME_STATS")
endif()
@@ -98,19 +93,29 @@ if (NOT("${CHECK_OLEAN_VERSION}" MATCHES "ON"))
endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Emscripten")
set(MULTI_THREAD OFF)
# TODO(WN): code size/performance tradeoffs
# - we're using -O3; it's /okay/
# - -flto crashes at runtime
# - -Oz produces quite slow code
# - system libraries such as OpenGL are included in the JS but shouldn't be
# - we need EMSCRIPTEN_KEEPALIVE annotations on exports to run meta-dce (-s MAIN_MODULE=2)
# - -fexceptions is a slow JS blob, remove when more runtimes support the WASM exceptions spec
# From https://emscripten.org/docs/compiling/WebAssembly.html#backends:
# > The simple and safe thing is to pass all -s flags at both compile and link time.
set(EMSCRIPTEN_SETTINGS "-s ALLOW_MEMORY_GROWTH=1 -fwasm-exceptions -pthread -flto")
string(APPEND LEANC_EXTRA_FLAGS " -pthread")
set(EMSCRIPTEN_SETTINGS "-s ALLOW_MEMORY_GROWTH=1 -s DISABLE_EXCEPTION_CATCHING=0 -s MAIN_MODULE=1 -fexceptions")
string(APPEND LEAN_EXTRA_CXX_FLAGS " -D LEAN_EMSCRIPTEN ${EMSCRIPTEN_SETTINGS}")
string(APPEND LEAN_EXTRA_LINKER_FLAGS " ${EMSCRIPTEN_SETTINGS}")
endif()
if (CMAKE_CROSSCOMPILING_EMULATOR)
# emscripten likes to quote "node"
string(REPLACE "\"" "" CMAKE_CROSSCOMPILING_EMULATOR ${CMAKE_CROSSCOMPILING_EMULATOR})
# HACK(WN): lazy compilation makes Node.js startup time a bad but tolerable ~4s
string(APPEND CMAKE_CROSSCOMPILING_EMULATOR " --wasm-lazy-compilation")
else()
set(CMAKE_CROSSCOMPILING_EMULATOR)
endif()
# Added for CTest
include(CTest)
@@ -138,7 +143,7 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/lean")
# OSX default thread stack size is very small. Moreover, in Debug mode, each new stack frame consumes a lot of extra memory.
if ((${MULTI_THREAD} MATCHES "ON") AND (${CMAKE_SYSTEM_NAME} MATCHES "Darwin"))
string(APPEND LEAN_EXTRA_MAKE_OPTS " -s40000")
set(LEAN_EXTRA_MAKE_OPTS -s40000 ${LEAN_EXTRA_MAKE_OPTS})
endif ()
# We want explicit stack probes in huge Lean stack frames for robust stack overflow detection
@@ -307,26 +312,23 @@ endif()
string(APPEND LEANC_STATIC_LINKER_FLAGS " ${LEAN_CXX_STDLIB}")
string(APPEND LEANSHARED_LINKER_FLAGS " ${LEAN_CXX_STDLIB}")
if (LLVM)
string(APPEND LEANSHARED_LINKER_FLAGS " -L${LLVM_CONFIG_LIBDIR} ${LLVM_CONFIG_LDFLAGS} ${LLVM_CONFIG_LIBS} ${LLVM_CONFIG_SYSTEM_LIBS}")
string(APPEND CMAKE_CXX_FLAGS " -I${LLVM_CONFIG_INCLUDEDIR}")
endif()
if(LLVM AND ${STAGE} GREATER 0)
if(LLVM)
# Here, we perform a replacement of `llvm-host` with `llvm`. This is necessary for our cross-compile
# builds in `script/prepare-llvm-*.sh`.
# builds in `script/prepare-llvm-*.sh`.
# - Recall that the host's copy of LLVM binaries and libraries is at
# `llvm-host`, and the target's copy of LLVM binaries and libraries is at
# `llvm`.
# - In an ideal world, we would run the target's `llvm/bin/llvm-config` and get the correct link options for the target
# - In an ideal world, we would run the target's `llvm/bin/llvm-config` and get the corrct link options for the target
# (e.g. `-Lllvm/lib/libLLVM`.)
# - However, the target's `llvm/bin/llvm-config` has a different target
# triple from the host, and thus cannot be run on the host.
# - So, we run the host `llvm-host/bin/llvm-config` from which we pick up
# compiler options, and change the output of the host to point to the target.
# - In particular, `host/bin/llvm-config` produces flags like `-Lllvm-host/lib/libLLVM`, while
# - In particular, `host/bin/llvm-config` produces flags like `-Lllvm-host/lib/libLLVM`, while
# we need the path to be `-Lllvm/lib/libLLVM`. Thus, we perform this replacement here.
string(APPEND LEANSHARED_LINKER_FLAGS " -L${LLVM_CONFIG_LIBDIR} ${LLVM_CONFIG_LDFLAGS} ${LLVM_CONFIG_LIBS} ${LLVM_CONFIG_SYSTEM_LIBS}")
string(REPLACE "llvm-host" "llvm" LEANSHARED_LINKER_FLAGS ${LEANSHARED_LINKER_FLAGS})
string(APPEND CMAKE_CXX_FLAGS " -I${LLVM_CONFIG_INCLUDEDIR}")
string(REPLACE "llvm-host" "llvm" LEAN_EXTRA_CXX_FLAGS ${LEAN_EXTRA_CXX_FLAGS})
message(VERBOSE "leanshared linker flags: '${LEANSHARED_LINKER_FLAGS}' | lean extra cxx flags '${LEAN_EXTR_CXX_FLAGS}'")
endif()
@@ -334,7 +336,7 @@ endif()
# get rid of unused parts of C++ stdlib
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
string(APPEND LEANSHARED_LINKER_FLAGS " -Wl,-dead_strip")
elseif(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Emscripten")
else()
string(APPEND LEANSHARED_LINKER_FLAGS " -Wl,--gc-sections")
endif()
@@ -350,28 +352,18 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
string(APPEND CMAKE_CXX_FLAGS " -fPIC -ftls-model=initial-exec")
string(APPEND LEANC_EXTRA_FLAGS " -fPIC")
string(APPEND LEANSHARED_LINKER_FLAGS " -Wl,-rpath=\\$$ORIGIN/..:\\$$ORIGIN")
string(APPEND CMAKE_EXE_LINKER_FLAGS " -lleanshared -Wl,-rpath=\\\$ORIGIN/../lib:\\\$ORIGIN/../lib/lean")
string(APPEND CMAKE_EXE_LINKER_FLAGS " -Wl,-rpath=\\\$ORIGIN/../lib:\\\$ORIGIN/../lib/lean")
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
string(APPEND CMAKE_CXX_FLAGS " -ftls-model=initial-exec")
string(APPEND LEANSHARED_LINKER_FLAGS " -install_name @rpath/libleanshared.dylib")
string(APPEND CMAKE_EXE_LINKER_FLAGS " -lleanshared -Wl,-rpath,@executable_path/../lib -Wl,-rpath,@executable_path/../lib/lean")
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Emscripten")
string(APPEND CMAKE_CXX_FLAGS " -fPIC")
string(APPEND LEANC_EXTRA_FLAGS " -fPIC")
# We do not use dynamic linking via leanshared for Emscripten to keep things
# simple. (And we are not interested in `Lake` anyway.) To use dynamic
# linking, we would probably have to set MAIN_MODULE=2 on `leanshared`,
# SIDE_MODULE=2 on `lean`, and set CMAKE_SHARED_LIBRARY_SUFFIX to ".js".
string(APPEND CMAKE_EXE_LINKER_FLAGS " -Wl,--whole-archive -lInit -lLean -lleancpp -lleanrt ${EMSCRIPTEN_SETTINGS} -lnodefs.js -s EXIT_RUNTIME=1 -s MAIN_MODULE=1 -s LINKABLE=1 -s EXPORT_ALL=1")
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
string(APPEND CMAKE_EXE_LINKER_FLAGS " -lleanshared")
string(APPEND CMAKE_EXE_LINKER_FLAGS " -Wl,-rpath,@executable_path/../lib -Wl,-rpath,@executable_path/../lib/lean")
endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
string(APPEND LEAN_EXTRA_LINKER_FLAGS " -ldl")
endif()
if(NOT(${CMAKE_SYSTEM_NAME} MATCHES "Windows") AND NOT(${CMAKE_SYSTEM_NAME} MATCHES "Emscripten"))
if(NOT(${CMAKE_SYSTEM_NAME} MATCHES "Windows"))
# export symbols for the interpreter (done via `LEAN_EXPORT` for Windows)
string(APPEND LEAN_DYN_EXE_LINKER_FLAGS " -rdynamic")
string(APPEND CMAKE_EXE_LINKER_FLAGS " -rdynamic")
@@ -454,6 +446,9 @@ string(APPEND LEANC_OPTS " ${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}}")
if(CMAKE_OSX_SYSROOT AND NOT LEAN_STANDALONE)
string(APPEND LEANC_OPTS " ${CMAKE_CXX_SYSROOT_FLAG}${CMAKE_OSX_SYSROOT}")
endif()
if(CMAKE_OSX_DEPLOYMENT_TARGET)
string(APPEND LEANC_OPTS " ${CMAKE_CXX_OSX_DEPLOYMENT_TARGET_FLAG}${CMAKE_OSX_DEPLOYMENT_TARGET}")
endif()
if(${STAGE} GREATER 1)
# reuse C++ parts, which don't change
@@ -513,12 +508,6 @@ else()
endif()
endif()
# Build the compiler using the bootstrapped C sources for stage0, and use
# the LLVM build for stage1 and further.
if (LLVM AND ${STAGE} GREATER 0)
set(EXTRA_LEANMAKE_OPTS "LLVM=1")
endif()
# Escape for `make`. Yes, twice.
string(REPLACE "$" "$$" CMAKE_EXE_LINKER_FLAGS_MAKE "${CMAKE_EXE_LINKER_FLAGS}")
string(REPLACE "$" "$$" CMAKE_EXE_LINKER_FLAGS_MAKE_MAKE "${CMAKE_EXE_LINKER_FLAGS_MAKE}")
@@ -531,12 +520,6 @@ add_custom_target(make_stdlib ALL
COMMAND $(MAKE) -f ${CMAKE_BINARY_DIR}/stdlib.make Init Lean
VERBATIM)
# if we have LLVM enabled, then build `lean.h.bc` which has the LLVM bitcode
# of Lean runtime to be built.
if (LLVM AND ${STAGE} EQUAL 1)
add_dependencies(make_stdlib runtime_bc)
endif()
# We declare these as separate custom targets so they use separate `make` invocations, which makes `make` recompute which dependencies
# (e.g. `libLean.a`) are now newer than the target file

View File

@@ -286,13 +286,13 @@ macro:1 x:conv tk:" <;> " y:conv:0 : conv =>
/-- `repeat convs` runs the sequence `convs` repeatedly until it fails to apply. -/
syntax "repeat " convSeq : conv
macro_rules
| `(conv| repeat $seq) => `(conv| first | ($seq); repeat $seq | skip)
| `(conv| repeat $seq) => `(conv| first | ($seq); repeat $seq | rfl)
/--
`conv => ...` allows the user to perform targeted rewriting on a goal or hypothesis,
by focusing on particular subexpressions.
See <https://lean-lang.org/theorem_proving_in_lean4/conv.html> for more details.
See <https://leanprover.github.io/theorem_proving_in_lean4/conv.html> for more details.
Basic forms:
* `conv => cs` will rewrite the goal with conv tactics `cs`.

View File

@@ -464,13 +464,13 @@ theorem optParam_eq (α : Sort u) (default : α) : optParam α default = α := r
`strictOr` is the same as `or`, but it does not use short-circuit evaluation semantics:
both sides are evaluated, even if the first value is `true`.
-/
@[extern "lean_strict_or"] def strictOr (b₁ b₂ : Bool) := b₁ || b₂
@[extern c inline "#1 || #2"] def strictOr (b₁ b₂ : Bool) := b₁ || b₂
/--
`strictAnd` is the same as `and`, but it does not use short-circuit evaluation semantics:
both sides are evaluated, even if the first value is `false`.
-/
@[extern "lean_strict_and"] def strictAnd (b₁ b₂ : Bool) := b₁ && b₂
@[extern c inline "#1 && #2"] def strictAnd (b₁ b₂ : Bool) := b₁ && b₂
/--
`x != y` is boolean not-equal. It is the negation of `x == y` which is supplied by
@@ -1612,11 +1612,6 @@ class Antisymm {α : Sort u} (r : αα → Prop) where
namespace Lean
/-! # Kernel reduction hints -/
/--
Depends on the correctness of the Lean compiler, interpreter, and all `[implemented_by ...]` and `[extern ...]` annotations.
-/
axiom trustCompiler : True
/--
When the kernel tries to reduce a term `Lean.reduceBool c`, it will invoke the Lean interpreter to evaluate `c`.
The kernel will not use the interpreter if `c` is not a constant.
@@ -1636,10 +1631,7 @@ Recall that the compiler trusts the correctness of all `[implemented_by ...]` an
If an extern function is executed, then the trusted code base will also include the implementation of the associated
foreign function.
-/
opaque reduceBool (b : Bool) : Bool :=
-- This ensures that `#print axioms` will track use of `reduceBool`.
have := trustCompiler
b
opaque reduceBool (b : Bool) : Bool := b
/--
Similar to `Lean.reduceBool` for closed `Nat` terms.
@@ -1648,11 +1640,7 @@ Remark: we do not have plans for supporting a generic `reduceValue {α} (a : α)
The main issue is that it is non-trivial to convert an arbitrary runtime object back into a Lean expression.
We believe `Lean.reduceBool` enables most interesting applications (e.g., proof by reflection).
-/
opaque reduceNat (n : Nat) : Nat :=
-- This ensures that `#print axioms` will track use of `reduceNat`.
have := trustCompiler
n
opaque reduceNat (n : Nat) : Nat := n
/--
The axiom `ofReduceBool` is used to perform proofs by reflection. See `reduceBool`.

View File

@@ -47,7 +47,7 @@ protected def sub : Fin n → Fin n → Fin n
/-!
Remark: mod/div/modn/land/lor can be defined without using (% n), but
we are trying to minimize the number of Nat theorems
needed to bootstrap Lean.
needed to boostrap Lean.
-/
protected def mod : Fin n Fin n Fin n

View File

@@ -315,7 +315,7 @@ class ToFormat (α : Type u) where
export ToFormat (format)
-- note: must take precedence over the above instance to avoid premature formatting
-- note: must take precendence over the above instance to avoid premature formatting
instance : ToFormat Format where
format f := f

View File

@@ -353,7 +353,7 @@ theorem Poly.denote_eq_cancelAux (ctx : Context) (fuel : Nat) (m₁ m₂ r₁ r
| zero => assumption
| succ fuel ih =>
simp
split <;> try (simp at h; try assumption)
split <;> simp at h <;> try assumption
rename_i k₁ v₁ m₁ k₂ v₂ m₂
by_cases hltv : Nat.blt v₁ v₂ <;> simp [hltv]
· apply ih; simp [denote_eq] at h |-; assumption
@@ -387,7 +387,7 @@ theorem Poly.of_denote_eq_cancelAux (ctx : Context) (fuel : Nat) (m₁ m₂ r₁
| zero => assumption
| succ fuel ih =>
simp at h
split at h <;> (try simp; assumption)
split at h <;> simp <;> try assumption
rename_i k₁ v₁ m₁ k₂ v₂ m₂
by_cases hltv : Nat.blt v₁ v₂ <;> simp [hltv] at h
· have ih := ih (h := h); simp [denote_eq] at ih ; assumption
@@ -413,9 +413,10 @@ theorem Poly.of_denote_eq_cancelAux (ctx : Context) (fuel : Nat) (m₁ m₂ r₁
rw [ Nat.add_assoc, ih, Nat.add_assoc]
theorem Poly.denote_eq_cancel {ctx : Context} {m₁ m₂ : Poly} (h : denote_eq ctx (m₁, m₂)) : denote_eq ctx (cancel m₁ m₂) := by
apply denote_eq_cancelAux; simp [h]
simp; apply denote_eq_cancelAux; simp [h]
theorem Poly.of_denote_eq_cancel {ctx : Context} {m₁ m₂ : Poly} (h : denote_eq ctx (cancel m₁ m₂)) : denote_eq ctx (m₁, m₂) := by
simp at h
have := Poly.of_denote_eq_cancelAux (h := h)
simp at this
assumption
@@ -431,7 +432,7 @@ theorem Poly.denote_le_cancelAux (ctx : Context) (fuel : Nat) (m₁ m₂ r₁ r
| zero => assumption
| succ fuel ih =>
simp
split <;> try (simp at h; assumption)
split <;> simp at h <;> try assumption
rename_i k₁ v₁ m₁ k₂ v₂ m₂
by_cases hltv : Nat.blt v₁ v₂ <;> simp [hltv]
· apply ih; simp [denote_le] at h |-; assumption
@@ -465,7 +466,7 @@ theorem Poly.of_denote_le_cancelAux (ctx : Context) (fuel : Nat) (m₁ m₂ r₁
| zero => assumption
| succ fuel ih =>
simp at h
split at h <;> try (simp; assumption)
split at h <;> simp <;> try assumption
rename_i k₁ v₁ m₁ k₂ v₂ m₂
by_cases hltv : Nat.blt v₁ v₂ <;> simp [hltv] at h
· have ih := ih (h := h); simp [denote_le] at ih ; assumption
@@ -493,9 +494,10 @@ theorem Poly.of_denote_le_cancelAux (ctx : Context) (fuel : Nat) (m₁ m₂ r₁
exact this
theorem Poly.denote_le_cancel {ctx : Context} {m₁ m₂ : Poly} (h : denote_le ctx (m₁, m₂)) : denote_le ctx (cancel m₁ m₂) := by
apply denote_le_cancelAux; simp [h]
simp; apply denote_le_cancelAux; simp [h]
theorem Poly.of_denote_le_cancel {ctx : Context} {m₁ m₂ : Poly} (h : denote_le ctx (cancel m₁ m₂)) : denote_le ctx (m₁, m₂) := by
simp at h
have := Poly.of_denote_le_cancelAux (h := h)
simp at this
assumption

View File

@@ -566,7 +566,7 @@ def prevn : Substring → Nat → String.Pos → String.Pos
@[inline] def front (s : Substring) : Char :=
s.get 0
/-- Return the offset into `s` of the first occurrence of `c` in `s`,
/-- Return the offset into `s` of the first occurence of `c` in `s`,
or `s.bsize` if `c` doesn't occur. -/
@[inline] def posOf (s : Substring) (c : Char) : String.Pos :=
match s with

View File

@@ -33,10 +33,6 @@ opaque fromUTF8Unchecked (a : @& ByteArray) : String
@[extern "lean_string_to_utf8"]
opaque toUTF8 (a : @& String) : ByteArray
/-- Accesses a byte in the UTF-8 encoding of the `String`. O(1) -/
@[extern "lean_string_get_byte_fast"]
opaque getUtf8Byte (s : @& String) (n : Nat) (h : n < s.utf8ByteSize) : UInt8
theorem Iterator.sizeOf_next_lt_of_hasNext (i : String.Iterator) (h : i.hasNext) : sizeOf i.next < sizeOf i := by
cases i; rename_i s pos; simp [Iterator.next, Iterator.sizeOf_eq]; simp [Iterator.hasNext] at h
exact Nat.sub_lt_sub_left h (String.lt_next s pos)

View File

@@ -11,15 +11,15 @@ import Init.Data.Option.BasicAux
namespace Lean
@[extern "lean_version_get_major"]
@[extern c inline "lean_box(LEAN_VERSION_MAJOR)"]
private opaque version.getMajor (u : Unit) : Nat
def version.major : Nat := version.getMajor ()
@[extern "lean_version_get_minor"]
@[extern c inline "lean_box(LEAN_VERSION_MINOR)"]
private opaque version.getMinor (u : Unit) : Nat
def version.minor : Nat := version.getMinor ()
@[extern "lean_version_get_patch"]
@[extern c inline "lean_box(LEAN_VERSION_PATCH)"]
private opaque version.getPatch (u : Unit) : Nat
def version.patch : Nat := version.getPatch ()
@@ -27,12 +27,12 @@ def version.patch : Nat := version.getPatch ()
opaque getGithash (u : Unit) : String
def githash : String := getGithash ()
@[extern "lean_version_get_is_release"]
@[extern c inline "LEAN_VERSION_IS_RELEASE"]
opaque version.getIsRelease (u : Unit) : Bool
def version.isRelease : Bool := version.getIsRelease ()
/-- Additional version description like "nightly-2018-03-11" -/
@[extern "lean_version_get_special_desc"]
@[extern c inline "lean_mk_string(LEAN_SPECIAL_VERSION_DESC)"]
opaque version.getSpecialDesc (u : Unit) : String
def version.specialDesc : String := version.getSpecialDesc ()
@@ -61,7 +61,7 @@ def toolchain :=
else
""
@[extern "lean_internal_is_stage0"]
@[extern c inline "LEAN_IS_STAGE0"]
opaque Internal.isStage0 (u : Unit) : Bool
/-- Valid identifier names -/
@@ -480,7 +480,7 @@ structure Module where
1- A proper extensible tactic feature that does not rely on the macro system.
2- Typed macros that know the syntax categories they're working in. Then, we would be able to select which
syntactic categories are expanded by `expandMacros`.
syntatic categories are expanded by `expandMacros`.
-/
partial def expandMacros (stx : Syntax) (p : SyntaxNodeKind Bool := fun k => k != `Lean.Parser.Term.byTactic) : MacroM Syntax :=
withRef stx do
@@ -1227,9 +1227,6 @@ structure Config where
proj : Bool := true
decide : Bool := false
autoUnfold : Bool := false
/-- If `failIfUnchanged := true`, then calls to `simp`, `dsimp`, or `simp_all`
will fail if they do not make progress. -/
failIfUnchanged : Bool := true
deriving Inhabited, BEq, Repr
end DSimp
@@ -1258,9 +1255,6 @@ structure Config where
`simp` to visit them. If `dsimp := false`, then argument is not visited.
-/
dsimp : Bool := true
/-- If `failIfUnchanged := true`, then calls to `simp`, `dsimp`, or `simp_all`
will fail if they do not make progress. -/
failIfUnchanged : Bool := true
deriving Inhabited, BEq, Repr
-- Configuration object for `simp_all`
@@ -1280,27 +1274,11 @@ def neutralConfig : Simp.Config := {
end Simp
inductive Occurrences where
| all
| pos (idxs : List Nat)
| neg (idxs : List Nat)
deriving Inhabited, BEq
def Occurrences.contains : Occurrences → Nat → Bool
| all, _ => true
| pos idxs, idx => idxs.contains idx
| neg idxs, idx => !idxs.contains idx
def Occurrences.isAll : Occurrences → Bool
| all => true
| _ => false
namespace Rewrite
structure Config where
transparency : TransparencyMode := TransparencyMode.reducible
offsetCnstrs : Bool := true
occs : Occurrences := Occurrences.all
end Rewrite

View File

@@ -86,14 +86,14 @@ namespace Parser.Syntax
/-! DSL for specifying parser precedences and priorities -/
/-- Addition of precedences. This is normally used only for offsetting, e.g. `max + 1`. -/
/-- Addition of precedences. This is normally used only for offseting, e.g. `max + 1`. -/
syntax:65 (name := addPrec) prec " + " prec:66 : prec
/-- Subtraction of precedences. This is normally used only for offsetting, e.g. `max - 1`. -/
/-- Subtraction of precedences. This is normally used only for offseting, e.g. `max - 1`. -/
syntax:65 (name := subPrec) prec " - " prec:66 : prec
/-- Addition of priorities. This is normally used only for offsetting, e.g. `default + 1`. -/
/-- Addition of priorities. This is normally used only for offseting, e.g. `default + 1`. -/
syntax:65 (name := addPrio) prio " + " prio:66 : prio
/-- Subtraction of priorities. This is normally used only for offsetting, e.g. `default - 1`. -/
/-- Subtraction of priorities. This is normally used only for offseting, e.g. `default - 1`. -/
syntax:65 (name := subPrio) prio " - " prio:66 : prio
end Parser.Syntax
@@ -132,7 +132,7 @@ macro "default" : prio => `(prio| 1000)
/-- The standardized "low" priority `low = 100`, for things that should be lower than default priority. -/
macro "low" : prio => `(prio| 100)
/--
The standardized "medium" priority `mid = 500`. This is lower than `default`, and higher than `low`.
The standardized "medium" priority `med = 1000`. This is lower than `default`, and higher than `low`.
-/
macro "mid" : prio => `(prio| 500)
/-- The standardized "high" priority `high = 10000`, for things that should be higher than default priority. -/

View File

@@ -92,7 +92,7 @@ end
syntax calcFirstStep := ppIndent(colGe term (" := " term)?)
-- enforce indentation of calc steps so we know when to stop parsing them
syntax calcStep := ppIndent(colGe term " := " term)
syntax calcSteps := ppLine withPosition(calcFirstStep) withPosition((ppLine linebreak calcStep)*)
syntax calcSteps := ppLine withPosition(calcFirstStep) withPosition((ppLine calcStep)*)
/-- Step-wise reasoning over transitive relations.
```
@@ -127,7 +127,7 @@ calc abc
See [Theorem Proving in Lean 4][tpil4] for more information.
[tpil4]: https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#calculational-proofs
[tpil4]: https://leanprover.github.io/theorem_proving_in_lean4/quantifiers_and_equality.html#calculational-proofs
-/
syntax (name := calc) "calc" calcSteps : term
@@ -166,7 +166,7 @@ leave a subgoal proving `z = z'`.
See [Theorem Proving in Lean 4][tpil4] for more information.
[tpil4]: https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#calculational-proofs
[tpil4]: https://leanprover.github.io/theorem_proving_in_lean4/quantifiers_and_equality.html#calculational-proofs
-/
syntax (name := calcTactic) "calc" calcSteps : tactic

View File

@@ -104,7 +104,7 @@ set_option bootstrap.inductiveCheckResultingUniverse false in
The unit type, the canonical type with one element, named `unit` or `()`.
This is the universe-polymorphic version of `Unit`; it is preferred to use
`Unit` instead where applicable.
For more information about universe levels: [Types as objects](https://lean-lang.org/theorem_proving_in_lean4/dependent_type_theory.html#types-as-objects)
For more information about universe levels: [Types as objects](https://leanprover.github.io/theorem_proving_in_lean4/dependent_type_theory.html#types-as-objects)
-/
inductive PUnit : Sort u where
/-- `PUnit.unit : PUnit` is the canonical element of the unit type. -/
@@ -116,7 +116,7 @@ In other words, it describes only a single value, which consists of said constru
to no arguments whatsoever.
The `Unit` type is similar to `void` in languages derived from C.
`Unit` is actually defined as `PUnit.{1}` where `PUnit` is the universe
`Unit` is actually defined as `PUnit.{0}` where `PUnit` is the universe
polymorphic version. The `Unit` should be preferred over `PUnit` where possible to avoid
unnecessary universe parameters.
@@ -171,7 +171,7 @@ unsafe axiom lcUnreachable {α : Sort u} : α
/--
`True` is a proposition and has only an introduction rule, `True.intro : True`.
In other words, `True` is simply true, and has a canonical proof, `True.intro`
For more information: [Propositional Logic](https://lean-lang.org/theorem_proving_in_lean4/propositions_and_proofs.html#propositional-logic)
For more information: [Propositional Logic](https://leanprover.github.io/theorem_proving_in_lean4/propositions_and_proofs.html#propositional-logic)
-/
inductive True : Prop where
/-- `True` is true, and `True.intro` (or more commonly, `trivial`)
@@ -184,7 +184,7 @@ It represents a contradiction. `False` elimination rule, `False.rec`,
expresses the fact that anything follows from a contradiction.
This rule is sometimes called ex falso (short for ex falso sequitur quodlibet),
or the principle of explosion.
For more information: [Propositional Logic](https://lean-lang.org/theorem_proving_in_lean4/propositions_and_proofs.html#propositional-logic)
For more information: [Propositional Logic](https://leanprover.github.io/theorem_proving_in_lean4/propositions_and_proofs.html#propositional-logic)
-/
inductive False : Prop
@@ -206,7 +206,7 @@ inductive PEmpty : Sort u where
so if your goal is `¬p` you can use `intro h` to turn the goal into
`h : p ⊢ False`, and if you have `hn : ¬p` and `h : p` then `hn h : False`
and `(hn h).elim` will prove anything.
For more information: [Propositional Logic](https://lean-lang.org/theorem_proving_in_lean4/propositions_and_proofs.html#propositional-logic)
For more information: [Propositional Logic](https://leanprover.github.io/theorem_proving_in_lean4/propositions_and_proofs.html#propositional-logic)
-/
def Not (a : Prop) : Prop := a False
@@ -228,7 +228,7 @@ Anything follows from two contradictory hypotheses. Example:
```
example (hp : p) (hnp : ¬p) : q := absurd hp hnp
```
For more information: [Propositional Logic](https://lean-lang.org/theorem_proving_in_lean4/propositions_and_proofs.html#propositional-logic)
For more information: [Propositional Logic](https://leanprover.github.io/theorem_proving_in_lean4/propositions_and_proofs.html#propositional-logic)
-/
@[macro_inline] def absurd {a : Prop} {b : Sort v} (h₁ : a) (h₂ : Not a) : b :=
(h₂ h₁).rec
@@ -258,7 +258,7 @@ example (α : Type) (a b : α) (p : α → Prop)
h1 ▸ h2
```
The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
For more information: [Equality](https://leanprover.github.io/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
-/
inductive Eq : α α Prop where
/-- `Eq.refl a : a = a` is reflexivity, the unique constructor of the
@@ -294,7 +294,7 @@ essentially a fancy algorithm for finding good `motive` arguments to usefully
apply this theorem to replace occurrences of `a` with `b` in the goal or
hypotheses.
For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
For more information: [Equality](https://leanprover.github.io/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
-/
theorem Eq.subst {α : Sort u} {motive : α Prop} {a b : α} (h₁ : Eq a b) (h₂ : motive a) : motive b :=
Eq.ndrec h₂ h₁
@@ -305,7 +305,7 @@ Equality is symmetric: if `a = b` then `b = a`.
Because this is in the `Eq` namespace, if you have a variable `h : a = b`,
`h.symm` can be used as shorthand for `Eq.symm h` as a proof of `b = a`.
For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
For more information: [Equality](https://leanprover.github.io/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
-/
theorem Eq.symm {α : Sort u} {a b : α} (h : Eq a b) : Eq b a :=
h rfl
@@ -317,7 +317,7 @@ Because this is in the `Eq` namespace, if you have variables or expressions
`h₁ : a = b` and `h₂ : b = c`, you can use `h₁.trans h₂ : a = c` as shorthand
for `Eq.trans h₁ h₂`.
For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
For more information: [Equality](https://leanprover.github.io/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
-/
theorem Eq.trans {α : Sort u} {a b c : α} (h₁ : Eq a b) (h₂ : Eq b c) : Eq a c :=
h₂ h₁
@@ -331,7 +331,7 @@ It is best to avoid this function if you can, because it is more complicated
to reason about terms containing casts, but if the types don't match up
definitionally sometimes there isn't anything better you can do.
For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
For more information: [Equality](https://leanprover.github.io/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
-/
@[macro_inline] def cast {α β : Sort u} (h : Eq α β) (a : α) : β :=
h.rec a
@@ -344,7 +344,7 @@ you can also use a lambda expression for `f` to prove that
internally by tactics like `congr` and `simp` to apply equalities inside
subterms.
For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
For more information: [Equality](https://leanprover.github.io/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
-/
theorem congrArg {α : Sort u} {β : Sort v} {a₁ a₂ : α} (f : α β) (h : Eq a₁ a₂) : Eq (f a₁) (f a₂) :=
h rfl
@@ -354,7 +354,7 @@ Congruence in both function and argument. If `f₁ = f₂` and `a₁ = a₂` the
`f₁ a₁ = f₂ a₂`. This only works for nondependent functions; the theorem
statement is more complex in the dependent case.
For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
For more information: [Equality](https://leanprover.github.io/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
-/
theorem congr {α : Sort u} {β : Sort v} {f₁ f₂ : α β} {a₁ a₂ : α} (h₁ : Eq f₁ f₂) (h₂ : Eq a₁ a₂) : Eq (f₁ a₁) (f₂ a₂) :=
h₁ h₂ rfl
@@ -461,7 +461,7 @@ as notation for `Prod.mk a b`. Moreover, `(a, b, c)` is notation for
`Prod.mk a (Prod.mk b c)`.
Given `p : Prod α β`, `p.1 : α` and `p.2 : β`. They are short for `Prod.fst p`
and `Prod.snd p` respectively. You can also write `p.fst` and `p.snd`.
For more information: [Constructors with Arguments](https://lean-lang.org/theorem_proving_in_lean4/inductive_types.html?highlight=Prod#constructors-with-arguments)
For more information: [Constructors with Arguments](https://leanprover.github.io/theorem_proving_in_lean4/inductive_types.html?highlight=Prod#constructors-with-arguments)
-/
structure Prod (α : Type u) (β : Type v) where
/-- The first projection out of a pair. if `p : α × β` then `p.1 : α`. -/
@@ -1615,7 +1615,7 @@ The predecessor function on natural numbers.
This definition is overridden in the compiler to use `n - 1` instead.
The definition provided here is the logical model.
-/
@[extern "lean_nat_pred"]
@[extern c inline "lean_nat_sub(#1, lean_box(1))"]
def Nat.pred : (@& Nat) Nat
| 0 => 0
| succ a => a
@@ -1706,7 +1706,7 @@ instance : Min Nat := minOfLe
set_option bootstrap.genMatcherCode false in
/--
(Truncated) subtraction of natural numbers. Because natural numbers are not
closed under subtraction, we define `n - m` to be `0` when `n < m`.
closed under subtraction, we define `m - n` to be `0` when `n < m`.
This definition is overridden in both the kernel and the compiler to efficiently
evaluate using the "bignum" representation (see `Nat`). The definition provided
@@ -2744,7 +2744,7 @@ Like many functional programming languages, Lean makes extensive use of monads
for structuring programs. In particular, the `do` notation is a very powerful
syntax over monad operations, and it depends on a `Monad` instance.
See [the `do` notation](https://lean-lang.org/lean4/doc/do.html)
See [the `do` notation](https://leanprover.github.io/lean4/doc/do.html)
chapter of the manual for details.
-/
class Monad (m : Type u Type v) extends Applicative m, Bind m : Type (max (u+1) v) where

View File

@@ -1,7 +1,7 @@
/-
Copyright (c) 2017 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Luke Nelson, Jared Roesch, Leonardo de Moura, Sebastian Ullrich, Mac Malone
Authors: Luke Nelson, Jared Roesch, Leonardo de Moura, Sebastian Ullrich
-/
prelude
import Init.Control.EState
@@ -16,7 +16,7 @@ import Init.Data.Ord
open System
/-- Like <https://hackage.haskell.org/package/ghc-Prim-0.5.2.0/docs/GHC-Prim.html#t:RealWorld>.
/-- Like https://hackage.haskell.org/package/ghc-Prim-0.5.2.0/docs/GHC-Prim.html#t:RealWorld.
Makes sure we never reorder `IO` operations.
TODO: mark opaque -/
@@ -219,67 +219,8 @@ local macro "nonempty_list" : tactic =>
/-- Helper method for implementing "deterministic" timeouts. It is the number of "small" memory allocations performed by the current execution thread. -/
@[extern "lean_io_get_num_heartbeats"] opaque getNumHeartbeats : BaseIO Nat
/--
The mode of a file handle (i.e., a set of `open` flags and an `fdopen` mode).
All modes do not translate line endings (i.e., `O_BINARY` on Windows) and
are not inherited across process creation (i.e., `O_NOINHERIT` on Windows,
`O_CLOEXEC` elsewhere).
**References:**
* Windows:
[`_open`](https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/open-wopen?view=msvc-170),
[`_fdopen`](https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/fdopen-wfdopen?view=msvc-170)
* Linux:
[`open`](https://linux.die.net/man/2/open),
[`fdopen`](https://linux.die.net/man/3/fdopen)
-/
inductive FS.Mode where
/--
File opened for reading.
On open, the stream is positioned at the beginning of the file.
Errors if the file does not exist.
* `open` flags: `O_RDONLY`
* `fdopen` mode: `r`
-/
| read
/--
File opened for writing.
On open, truncate an existing file to zero length or create a new file.
The stream is positioned at the beginning of the file.
* `open` flags: `O_WRONLY | O_CREAT | O_TRUNC`
* `fdopen` mode: `w`
-/
| write
/--
New file opened for writing.
On open, create a new file with the stream positioned at the start.
Errors if the file already exists.
* `open` flags: `O_WRONLY | O_CREAT | O_TRUNC | O_EXCL`
* `fdopen` mode: `w`
-/
| writeNew
/--
File opened for reading and writing.
On open, the stream is positioned at the beginning of the file.
Errors if the file does not exist.
* `open` flags: `O_RDWR`
* `fdopen` mode: `r+`
-/
| readWrite
/--
File opened for writing.
On open, create a new file if it does not exist.
The stream is positioned at the end of the file.
* `open` flags: `O_WRONLY | O_CREAT | O_APPEND`
* `fdopen` mode: `a`
-/
| append
| read | write | readWrite | append
opaque FS.Handle : Type := Unit
@@ -576,10 +517,6 @@ partial def FS.removeDirAll (p : FilePath) : IO Unit := do
removeDir p
namespace Process
/-- Returns the process ID of the current process. -/
@[extern "lean_io_process_get_pid"] opaque getPID : BaseIO UInt32
inductive Stdio where
| piped
| inherit

View File

@@ -20,7 +20,7 @@ namespace UriEscape
@[inline] def letterF : UInt8 := 'F'.toNat.toUInt8
/-- Decode %HH escapings in the given string. Note that sometimes a consecutive
sequence of multiple escapings can represent a utf-8 encoded sequence for
sequence of multiple escapings can represet a utf-8 encoded sequence for
a single unicode code point and these will also be decoded correctly. -/
def decodeUri (uri : String) : String := Id.run do
let mut decoded : ByteArray := ByteArray.empty
@@ -78,7 +78,7 @@ def escapeUri (uri: String) : String :=
/-- Replaces all %HH Uri escapings in the given string with their
corresponding unicode code points. Note that sometimes a consecutive
sequence of multiple escapings can represent a utf-8 encoded sequence for
sequence of multiple escapings can represet a utf-8 encoded sequence for
a single unicode code point and these will also be decoded correctly. -/
def unescapeUri (s: String) : String :=
UriEscape.decodeUri s

View File

@@ -202,19 +202,19 @@ can be either separated by newlines or `;`.
syntax (name := paren) "(" withoutPosition(tacticSeq) ")" : tactic
/--
`with_reducible tacs` executes `tacs` using the reducible transparency setting.
`with_reducible tacs` excutes `tacs` using the reducible transparency setting.
In this setting only definitions tagged as `[reducible]` are unfolded.
-/
syntax (name := withReducible) "with_reducible " tacticSeq : tactic
/--
`with_reducible_and_instances tacs` executes `tacs` using the `.instances` transparency setting.
`with_reducible_and_instances tacs` excutes `tacs` using the `.instances` transparency setting.
In this setting only definitions tagged as `[reducible]` or type class instances are unfolded.
-/
syntax (name := withReducibleAndInstances) "with_reducible_and_instances " tacticSeq : tactic
/--
`with_unfolding_all tacs` executes `tacs` using the `.all` transparency setting.
`with_unfolding_all tacs` excutes `tacs` using the `.all` transparency setting.
In this setting all definitions that are not opaque are unfolded.
-/
syntax (name := withUnfoldingAll) "with_unfolding_all " tacticSeq : tactic
@@ -350,15 +350,6 @@ This provides a convenient way to unfold `e`.
- `rewrite [e] at l` rewrites `e` at location(s) `l`, where `l` is either `*` or a
list of hypotheses in the local context. In the latter case, a turnstile `⊢` or `|-`
can also be used, to signify the target of the goal.
Using `rw (config := {occs := .pos L}) [e]`,
where `L : List Nat`, you can control which "occurrences" are rewritten.
(This option applies to each rule, so usually this will only be used with a single rule.)
Occurrences count from `1`.
At the first occurrence, whether allowed or not,
arguments of the rewrite rule `e` may be instantiated,
restricting which later rewrites can be found.
`{occs := .neg L}` allows skipping specified occurrences.
-/
syntax (name := rewriteSeq) "rewrite" (config)? rwRuleSeq (location)? : tactic
@@ -438,7 +429,7 @@ syntax (name := simp) "simp" (config)? (discharger)? (&" only")?
(" [" withoutPosition((simpStar <|> simpErase <|> simpLemma),*) "]")? (location)? : tactic
/--
`simp_all` is a stronger version of `simp [*] at *` where the hypotheses and target
are simplified multiple times until no simplification is applicable.
are simplified multiple times until no simplication is applicable.
Only non-dependent propositional hypotheses are considered.
-/
syntax (name := simpAll) "simp_all" (config)? (discharger)? (&" only")?
@@ -527,7 +518,7 @@ macro "let' " d:letDecl : tactic => `(tactic| refine_lift' let $d:letDecl; ?_)
/--
The left hand side of an induction arm, `| foo a b c` or `| @foo a b c`
where `foo` is a constructor of the inductive type and `a b c` are the arguments
to the constructor.
to the contstructor.
-/
syntax inductionAltLHS := "| " (("@"? ident) <|> hole) (ident <|> hole)*
/--

View File

@@ -222,8 +222,8 @@ section
variable {α : Type u} {β : Type v}
variable {ra : α α Prop} {rb : β β Prop}
def lexAccessible {a : α} (aca : Acc ra a) (acb : (b : β) Acc rb b) (b : β) : Acc (Prod.Lex ra rb) (a, b) := by
induction aca generalizing b with
def lexAccessible (aca : (a : α) Acc ra a) (acb : (b : β) Acc rb b) (a : α) (b : β) : Acc (Prod.Lex ra rb) (a, b) := by
induction (aca a) generalizing b with
| intro xa _ iha =>
induction (acb b) with
| intro xb _ ihb =>
@@ -236,7 +236,7 @@ def lexAccessible {a : α} (aca : Acc ra a) (acb : (b : β) → Acc rb b) (b :
-- The lexicographical order of well founded relations is well-founded
@[reducible] def lex (ha : WellFoundedRelation α) (hb : WellFoundedRelation β) : WellFoundedRelation (α × β) where
rel := Prod.Lex ha.rel hb.rel
wf := fun (a, b) => lexAccessible (WellFounded.apply ha.wf a) (WellFounded.apply hb.wf) b
wf := fun (a, b) => lexAccessible (WellFounded.apply ha.wf) (WellFounded.apply hb.wf) a b
instance [ha : WellFoundedRelation α] [hb : WellFoundedRelation β] : WellFoundedRelation (α × β) :=
lex ha hb

View File

@@ -10,7 +10,8 @@ import Init.WF
/-- Unfold definitions commonly used in well founded relation definitions.
This is primarily intended for internal use in `decreasing_tactic`. -/
macro "simp_wf" : tactic =>
`(tactic| try simp [invImage, InvImage, Prod.lex, sizeOfWFRel, measure, Nat.lt_wfRel, WellFoundedRelation.rel])
`(tactic| simp [invImage, InvImage, Prod.lex, sizeOfWFRel,
measure, Nat.lt_wfRel, WellFoundedRelation.rel])
/-- Extensible helper tactic for `decreasing_tactic`. This handles the "base case"
reasoning after applying lexicographic order lemmas.
@@ -21,7 +22,7 @@ macro_rules | `(tactic| decreasing_trivial) => `(tactic| linarith)
-/
syntax "decreasing_trivial" : tactic
macro_rules | `(tactic| decreasing_trivial) => `(tactic| (simp (config := { arith := true, failIfUnchanged := false })); done)
macro_rules | `(tactic| decreasing_trivial) => `(tactic| simp (config := { arith := true }); done)
macro_rules | `(tactic| decreasing_trivial) => `(tactic| assumption)
macro_rules | `(tactic| decreasing_trivial) => `(tactic| apply Nat.sub_succ_lt_self; assumption) -- a - (i+1) < a - i if i < a
macro_rules | `(tactic| decreasing_trivial) => `(tactic| apply Nat.pred_lt'; assumption) -- i-1 < i if j < i

View File

@@ -8,19 +8,19 @@ import Lean.Compiler.IR.Format
namespace Lean.IR.Checker
@[extern "lean_get_max_ctor_fields"]
@[extern c inline "lean_box(LEAN_MAX_CTOR_FIELDS)"]
opaque getMaxCtorFields : Unit Nat
def maxCtorFields := getMaxCtorFields ()
@[extern "lean_get_max_ctor_scalars_size"]
@[extern c inline "lean_box(LEAN_MAX_CTOR_SCALARS_SIZE)"]
opaque getMaxCtorScalarsSize : Unit Nat
def maxCtorScalarsSize := getMaxCtorScalarsSize ()
@[extern "lean_get_max_ctor_tag"]
@[extern c inline "lean_box(LeanMaxCtorTag)"]
opaque getMaxCtorTag : Unit Nat
def maxCtorTag := getMaxCtorTag ()
@[extern "lean_get_usize_size"]
@[extern c inline "lean_box(sizeof(size_t))"]
opaque getUSizeSize : Unit Nat
def usizeSize := getUSizeSize ()

View File

@@ -27,27 +27,6 @@ namespace LLVM
-- TODO(bollu): instantiate target triple and find out what size_t is.
def size_tType (llvmctx : LLVM.Context) : IO (LLVM.LLVMType llvmctx) :=
LLVM.i64Type llvmctx
-- Helper to add a function if it does not exist, and to return the function handle if it does.
def getOrAddFunction (m : LLVM.Module ctx) (name : String) (type : LLVM.LLVMType ctx) : BaseIO (LLVM.Value ctx) := do
match ( LLVM.getNamedFunction m name) with
| some fn => return fn
| none =>
/-
By the evidence shown in: https://github.com/leanprover/lean4/issues/2373#issuecomment-1658743284
this is how clang implements `-fstack-clash-protection` in the LLVM IR, we want this feature
for robust stack overflow detection.
-/
let fn LLVM.addFunction m name type
let attr LLVM.createStringAttribute "probe-stack" "inline-asm"
LLVM.addAttributeAtIndex fn LLVM.AttributeIndex.AttributeFunctionIndex attr
return fn
def getOrAddGlobal (m : LLVM.Module ctx) (name : String) (type : LLVM.LLVMType ctx) : BaseIO (LLVM.Value ctx) := do
match ( LLVM.getNamedGlobal m name) with
| .some fn => return fn
| .none => LLVM.addGlobal m name type
end LLVM
namespace EmitLLVM
@@ -132,11 +111,11 @@ instance : ToString RefcountKind where
def callLeanRefcountFn (builder : LLVM.Builder llvmctx)
(kind : RefcountKind) (checkRef? : Bool) (arg : LLVM.Value llvmctx)
(delta : Option (LLVM.Value llvmctx) := Option.none) : M llvmctx Unit := do
let fnName := s!"lean_{kind}{if checkRef? then "" else "_ref"}{if delta.isNone then "" else "_n"}"
let fnName := s!"lean_{kind}{if checkRef? then "" else "_ref"}{if delta.isNone then "" else "_n"}"
let retty LLVM.voidType llvmctx
let argtys := if delta.isNone then #[ LLVM.voidPtrType llvmctx] else #[ LLVM.voidPtrType llvmctx, LLVM.size_tType llvmctx]
let fn getOrCreateFunctionPrototype ( getLLVMModule) retty fnName argtys
let fnty LLVM.functionType retty argtys
let fnty LLVM.functionType retty argtys
match delta with
| .none => do
-- since refcount δ is 1, we only supply the pointer.
@@ -1044,7 +1023,7 @@ mutual
partial def emitCase (builder : LLVM.Builder llvmctx)
(x : VarId) (xType : IRType) (alts : Array Alt) : M llvmctx Unit := do
let oldBB LLVM.getInsertBlock builder
-- NOTE: In this context, 'Zext' versus 'Sext' have a meaningful semantic difference.
-- NOTE: In this context, 'Zext' versus 'Sext' have a meaninful semantic difference.
-- We perform a zero extend so that one-bit tags of `0/-1` actually extend to `0/1`
-- in 64-bit space.
let tag emitTag builder x xType
@@ -1140,12 +1119,12 @@ def emitFnArgs (builder : LLVM.Builder llvmctx)
let llvmty toLLVMType param.ty
-- pv := *(argsi) = *(args + i)
let pv LLVM.buildLoad2 builder llvmty argsi
-- slot for arg[i] which is always void* ?
-- slot for arg[i] which is always void* ?
let alloca LLVM.buildAlloca builder llvmty s!"arg_{i}"
LLVM.buildStore builder pv alloca
addVartoState params[i]!.x alloca llvmty
else
let n LLVM.countParams llvmfn
let n := LLVM.countParams llvmfn
for i in (List.range n.toNat) do
let llvmty toLLVMType params[i]!.ty
let alloca LLVM.buildAlloca builder llvmty s!"arg_{i}"
@@ -1202,7 +1181,7 @@ def emitFns (mod : LLVM.Module llvmctx) (builder : LLVM.Builder llvmctx) : M llv
let decls := getDecls env
decls.reverse.forM (emitDecl mod builder)
def callIODeclInitFn (builder : LLVM.Builder llvmctx)
def callIODeclInitFn (builder : LLVM.Builder llvmctx)
(initFnName : String)
(world : LLVM.Value llvmctx): M llvmctx (LLVM.Value llvmctx) := do
let retty LLVM.voidPtrType llvmctx
@@ -1224,7 +1203,7 @@ def emitDeclInit (builder : LLVM.Builder llvmctx)
let env getEnv
if isIOUnitInitFn env d.name then do
let world callLeanIOMkWorld builder
let resv callIODeclInitFn builder ( toCName d.name) world
let resv callIODeclInitFn builder ( toCName d.name) world
let err? callLeanIOResultIsError builder resv "is_error"
buildIfThen_ builder s!"init_{d.name}_isError" err?
(fun builder => do
@@ -1243,7 +1222,7 @@ def emitDeclInit (builder : LLVM.Builder llvmctx)
if checkBuiltin? then
-- `builtin` is set to true if the initializer is part of the executable,
-- and not loaded dynamically.
let builtinParam LLVM.getParam parentFn 0
let builtinParam LLVM.getParam parentFn 0
let cond buildLeanBoolTrue? builder builtinParam "is_builtin_true"
let _ LLVM.buildCondBr builder cond initBB restBB
else
@@ -1266,7 +1245,7 @@ def emitDeclInit (builder : LLVM.Builder llvmctx)
callLeanMarkPersistentFn builder dval
let _ LLVM.buildBr builder restBB
LLVM.positionBuilderAtEnd builder restBB
| none => do
| none => do
let llvmty toLLVMType d.resultType
let dslot LLVM.getOrAddGlobal ( getLLVMModule) ( toCName d.name) llvmty
LLVM.setInitializer dslot ( LLVM.getUndef llvmty)
@@ -1345,7 +1324,7 @@ def callLeanSetPanicMessages (builder : LLVM.Builder llvmctx)
let argtys := #[ LLVM.i1Type llvmctx ]
let fn getOrCreateFunctionPrototype ( getLLVMModule) retty fnName argtys
let fnty LLVM.functionType retty argtys
let _ LLVM.buildCall2 builder fnty fn #[enable?]
let _ LLVM.buildCall2 builder fnty fn #[enable?]
def callLeanIOMarkEndInitialization (builder : LLVM.Builder llvmctx) : M llvmctx Unit := do
let fnName := "lean_io_mark_end_initialization"
@@ -1398,7 +1377,7 @@ def callLeanIOResultShowError (builder : LLVM.Builder llvmctx)
let fnty LLVM.functionType retty argtys
let _ LLVM.buildCall2 builder fnty fn #[v] name
def callLeanMainFn (builder : LLVM.Builder llvmctx)
def callLeanMainFn (builder : LLVM.Builder llvmctx)
(argv? : Option (LLVM.Value llvmctx))
(world : LLVM.Value llvmctx)
(name : String) : M llvmctx (LLVM.Value llvmctx) := do
@@ -1407,7 +1386,7 @@ def callLeanMainFn (builder : LLVM.Builder llvmctx)
let argtys := if argv?.isSome then #[ voidptr, voidptr ] else #[ voidptr ]
let fn getOrCreateFunctionPrototype ( getLLVMModule) retty leanMainFn argtys
let fnty LLVM.functionType retty argtys
let args := match argv? with
let args := match argv? with
| .some argv => #[argv, world]
| .none => #[world]
LLVM.buildCall2 builder fnty fn args name
@@ -1550,20 +1529,6 @@ def optimizeLLVMModule (mod : LLVM.Module ctx) : IO Unit := do
LLVM.disposePassManager pm
LLVM.disposePassManagerBuilder pmb
/-- Get the names of all global symbols in the module -/
partial def getModuleGlobals (mod : LLVM.Module llvmctx) : IO (Array (LLVM.Value llvmctx)) := do
let rec go (v : LLVM.Value llvmctx) (acc : Array (LLVM.Value llvmctx)) : IO (Array (LLVM.Value llvmctx)) := do
if v.isNull then return acc
else go ( LLVM.getNextGlobal v) (acc.push v)
go ( LLVM.getFirstGlobal mod) #[]
/-- Get the names of all global functions in the module -/
partial def getModuleFunctions (mod : LLVM.Module llvmctx) : IO (Array (LLVM.Value llvmctx)) := do
let rec go (v : LLVM.Value llvmctx) (acc : Array (LLVM.Value llvmctx)) : IO (Array (LLVM.Value llvmctx)) := do
if v.isNull then return acc
else go ( LLVM.getNextFunction v) (acc.push v)
go ( LLVM.getFirstFunction mod) #[]
/--
`emitLLVM` is the entrypoint for the lean shell to code generate LLVM.
-/
@@ -1579,29 +1544,7 @@ def emitLLVM (env : Environment) (modName : Name) (filepath : String) (tripleStr
| .ok _ => do
let membuf LLVM.createMemoryBufferWithContentsOfFile ( getLeanHBcPath).toString
let modruntime LLVM.parseBitcode llvmctx membuf
/- It is important that we extract the names here because
pointers into modruntime get invalidated by linkModules -/
let runtimeGlobals ( getModuleGlobals modruntime).mapM (·.getName)
let filter func := do
-- | Do not insert internal linkage for
-- intrinsics such as `@llvm.umul.with.overflow.i64` which clang generates, and also
-- for declarations such as `lean_inc_ref_cold` which are externally defined.
if ( LLVM.isDeclaration func) then
return none
else
return some ( func.getName)
let runtimeFunctions ( getModuleFunctions modruntime).filterMapM filter
LLVM.linkModules (dest := emitLLVMCtx.llvmmodule) (src := modruntime)
-- Mark every global and function as having internal linkage.
for name in runtimeGlobals do
let some global LLVM.getNamedGlobal emitLLVMCtx.llvmmodule name
| throw <| IO.Error.userError s!"ERROR: linked module must have global from runtime module: '{name}'"
LLVM.setLinkage global LLVM.Linkage.internal
for name in runtimeFunctions do
let some fn LLVM.getNamedFunction emitLLVMCtx.llvmmodule name
| throw <| IO.Error.userError s!"ERROR: linked module must have function from runtime module: '{name}'"
LLVM.setLinkage fn LLVM.Linkage.internal
optimizeLLVMModule emitLLVMCtx.llvmmodule
LLVM.writeBitcodeToFile emitLLVMCtx.llvmmodule filepath
let tripleStr := tripleStr?.getD ( LLVM.getDefaultTargetTriple)

View File

@@ -86,7 +86,7 @@ partial def eraseProjIncForAux (y : VarId) (bs : Array FnBody) (mask : Mask) (ke
def eraseProjIncFor (n : Nat) (y : VarId) (bs : Array FnBody) : Array FnBody × Mask :=
eraseProjIncForAux y bs (mkArray n none) #[]
/-- Replace `reuse x ctor ...` with `ctor ...`, and remove `dec x` -/
/-- Replace `reuse x ctor ...` with `ctor ...`, and remoce `dec x` -/
partial def reuseToCtor (x : VarId) : FnBody FnBody
| FnBody.dec y n c p b =>
if x == y then b -- n must be 1 since `x := reset ...`
@@ -236,7 +236,7 @@ def mkFastPath (x y : VarId) (mask : Mask) (b : FnBody) : M FnBody := do
partial def expand (mainFn : FnBody Array FnBody M FnBody)
(bs : Array FnBody) (x : VarId) (n : Nat) (y : VarId) (b : FnBody) : M FnBody := do
let (bs, mask) := eraseProjIncFor n y bs
/- Remark: we may be duplicating variable/JP indices. That is, `bSlow` and `bFast` may
/- Remark: we may be duplicting variable/JP indices. That is, `bSlow` and `bFast` may
have duplicate indices. We run `normalizeIds` to fix the ids after we have expand them. -/
let bSlow := mkSlowPath x y mask b
let bFast mkFastPath x y mask b

View File

@@ -29,14 +29,6 @@ def IntPredicate.EQ : IntPredicate := { val := 32 }
def IntPredicate.NE : IntPredicate := { val := IntPredicate.EQ.val + 1 }
def IntPredicate.UGT : IntPredicate := { val := IntPredicate.NE.val + 1 }
-- https://github.com/llvm/llvm-project/blob/c3e073bcbdc523b0f758d44a89a6333e38bff863/llvm/include/llvm-c/Core.h#L457
structure AttributeIndex where
private mk :: val : UInt64
def AttributeIndex.AttributeReturnIndex : AttributeIndex := { val := 0 }
-- This value is ~0 for 64 bit
def AttributeIndex.AttributeFunctionIndex : AttributeIndex := { val := 18446744073709551615 }
structure BasicBlock (ctx : Context) where
private mk :: ptr : USize
instance : Nonempty (BasicBlock ctx) := { ptr := default }
@@ -81,16 +73,6 @@ structure Value (ctx : Context) where
private mk :: ptr : USize
instance : Nonempty (Value ctx) := { ptr := default }
/-- Check if the value is a null pointer. --/
def Value.isNull (v : Value ctx) : Bool := v.ptr == 0
@[extern "lean_llvm_get_value_name2"]
opaque Value.getName {ctx : Context} (value : Value ctx) : BaseIO String
structure Attribute (ctx : Context) where
private mk :: ptr : USize
instance : Nonempty (Attribute ctx) := { ptr := default }
@[extern "lean_llvm_initialize_target_info"]
opaque llvmInitializeTargetInfo : BaseIO (Unit)
@@ -109,12 +91,6 @@ opaque writeBitcodeToFile (m : Module ctx) (path : @&String) : BaseIO Unit
@[extern "lean_llvm_add_function"]
opaque addFunction (m : Module ctx) (name : @&String) (type : LLVMType ctx) : BaseIO (Value ctx)
@[extern "lean_llvm_get_first_function"]
opaque getFirstFunction (m : Module ctx) : BaseIO (Value ctx)
@[extern "lean_llvm_get_next_function"]
opaque getNextFunction (glbl : Value ctx) : BaseIO (Value ctx)
@[extern "lean_llvm_get_named_function"]
opaque getNamedFunction (m : Module ctx) (name : @&String) : BaseIO (Option (Value ctx))
@@ -124,18 +100,9 @@ opaque addGlobal (m : Module ctx) (name : @&String) (type : LLVMType ctx) : Base
@[extern "lean_llvm_get_named_global"]
opaque getNamedGlobal (m : Module ctx) (name : @&String) : BaseIO (Option (Value ctx))
@[extern "lean_llvm_get_first_global"]
opaque getFirstGlobal (m : Module ctx) : BaseIO (Value ctx)
@[extern "lean_llvm_get_next_global"]
opaque getNextGlobal (glbl : Value ctx) : BaseIO (Value ctx)
@[extern "lean_llvm_build_global_string"]
opaque buildGlobalString (builder : Builder ctx) (value : @&String) (name : @&String := "") : BaseIO (Value ctx)
@[extern "llvm_is_declaration"]
opaque isDeclaration (global : Value ctx) : BaseIO Bool
@[extern "lean_llvm_set_initializer"]
opaque setInitializer (glbl : Value ctx) (val : Value ctx) : BaseIO Unit
@@ -273,7 +240,7 @@ opaque printModuletoString (mod : Module ctx) : BaseIO (String)
opaque printModuletoFile (mod : Module ctx) (file : @&String) : BaseIO Unit
@[extern "llvm_count_params"]
opaque countParams (fn : Value ctx) : BaseIO UInt64
opaque countParams (fn : Value ctx) : UInt64
@[extern "llvm_get_param"]
opaque getParam (fn : Value ctx) (ix : UInt64) : BaseIO (Value ctx)
@@ -326,12 +293,6 @@ opaque disposeTargetMachine (tm : TargetMachine ctx) : BaseIO Unit
@[extern "lean_llvm_dispose_module"]
opaque disposeModule (m : Module ctx) : BaseIO Unit
@[extern "lean_llvm_create_string_attribute"]
opaque createStringAttribute (key : String) (value : String) : BaseIO (Attribute ctx)
@[extern "lean_llvm_add_attribute_at_index"]
opaque addAttributeAtIndex (fn : Value ctx) (idx: AttributeIndex) (attr: Attribute ctx) : BaseIO Unit
-- https://github.com/llvm/llvm-project/blob/c3e073bcbdc523b0f758d44a89a6333e38bff863/llvm/include/llvm-c/Core.h#L198
structure Visibility where
@@ -355,46 +316,16 @@ def DLLStorageClass.export : DLLStorageClass := { val := 2 }
@[extern "lean_llvm_set_dll_storage_class"]
opaque setDLLStorageClass {ctx : Context} (value : Value ctx) (dllStorageClass : DLLStorageClass) : BaseIO Unit
-- https://github.com/llvm/llvm-project/blob/c3e073bcbdc523b0f758d44a89a6333e38bff863/llvm/include/llvm-c/Core.h#L192
structure Linkage where
private mk :: val : UInt64
-- Helper to add a function if it does not exist, and to return the function handle if it does.
def getOrAddFunction(m : Module ctx) (name : String) (type : LLVMType ctx) : BaseIO (Value ctx) := do
match ( getNamedFunction m name) with
| .some fn => return fn
| .none => addFunction m name type
/-- Externally visible function -/
def Linkage.external : Linkage := { val := 0 }
def Linkage.availableExternally : Linkage := { val := 1 }
/-- Keep one copy of function when linking (inline) -/
def Linkage.linkOnceAny : Linkage := { val := 2 }
/-- Same, but only replaced by something equivalent -/
def Linkage.linkOnceODR : Linkage := { val := 3 }
/-- Obsolete -/
def Linkage.linkOnceODRAutoHide : Linkage := { val := 4 }
/-- Keep one copy of function when linking (weak) -/
def Linkage.weakAny : Linkage := { val := 5 }
/-- Same, but only replaced by something equivalent -/
def Linkage.weakODR : Linkage := { val := 6 }
/-- Special purpose, only applies to global arrays -/
def Linkage.appending : Linkage := { val := 7 }
/-- Rename collisions when linking (static functions) -/
def Linkage.internal : Linkage := { val := 8 }
/-- Like Internal, but omit from symbol table -/
def Linkage.private : Linkage := { val := 9 }
/-- Obsolete -/
def Linkage.dllImport : Linkage := { val := 10 }
/-- Obsolete -/
def Linkage.dllExport : Linkage := { val := 11 }
/-- ExternalWeak linkage description -/
def Linkage.externalWeak : Linkage := { val := 12 }
/-- Obsolete -/
def Linkage.ghost : Linkage := { val := 13 }
/-- Tentative definitions -/
def Linkage.common : Linkage := { val := 14 }
/-- Like Private, but linker removes. -/
def Linkage.linkerPrivate : Linkage := { val := 15 }
/-- Like LinkerPrivate, but is weak. -/
def Linkage.linkerPrivateWeak : Linkage := { val := 16 }
@[extern "lean_llvm_set_linkage"]
opaque setLinkage {ctx : Context} (value : Value ctx) (linkage : Linkage) : BaseIO Unit
def getOrAddGlobal(m : Module ctx) (name : String) (type : LLVMType ctx) : BaseIO (Value ctx) := do
match ( getNamedGlobal m name) with
| .some fn => return fn
| .none => addGlobal m name type
def i1Type (ctx : LLVM.Context) : BaseIO (LLVM.LLVMType ctx) :=

View File

@@ -9,7 +9,7 @@ import Lean.Compiler.IR.Format
namespace Lean.IR.ResetReuse
/-! Remark: the insertResetReuse transformation is applied before we have
inserted `inc/dec` instructions, and performed lower level optimizations
inserted `inc/dec` instructions, and perfomed lower level optimizations
that introduce the instructions `release` and `set`. -/
/-! Remark: the functions `S`, `D` and `R` defined here implement the

View File

@@ -31,9 +31,6 @@ unsafe opaque runModInit (mod : Name) : IO Bool
@[extern "lean_run_init"]
unsafe opaque runInit (env : @& Environment) (opts : @& Options) (decl initDecl : @& Name) : IO Unit
/-- Set of modules for which we have already run the module initializer in the interpreter. -/
builtin_initialize interpretedModInits : IO.Ref NameSet IO.mkRef {}
unsafe def registerInitAttrUnsafe (attrName : Name) (runAfterImport : Bool) (ref : Name) : IO (ParametricAttribute Name) :=
registerParametricAttribute {
ref := ref
@@ -71,11 +68,6 @@ unsafe def registerInitAttrUnsafe (attrName : Name) (runAfterImport : Bool) (ref
-- We do this after trying `runModInit` as that one may also efficiently initialize
-- nullary functions.
continue
-- As `[init]` decls can have global side effects, ensure we run them at most once,
-- just like the compiled code does.
if ( interpretedModInits.get).contains mod then
continue
interpretedModInits.modify (·.insert mod)
for c in modData.constNames do
-- make sure to run initializers in declaration order, not extension state order, to respect dependencies
if let some (decl, initDecl) := modEntries.binSearch (c, default) (Name.quickLt ·.1 ·.1) then

View File

@@ -471,7 +471,7 @@ structure Decl where
of this kind. See `DefinitionSafety`.
`partial` and `unsafe` functions may not be terminating, but Lean
functions terminate, and some static analyzers exploit this
fact. So, we use the following semantics. Suppose we have a (large) natural
fact. So, we use the following semantics. Suppose whe hav a (large) natural
number `C`. We consider a nondeterministic model for computation of Lean expressions as
follows:
Each call to a partial/unsafe function uses up one "recursion token".
@@ -490,7 +490,7 @@ structure Decl where
safe : Bool := true
/--
We store the inline attribute at LCNF declarations to make sure we can set them for
auxiliary declarations created during compilation.
auxliary declarations created during compilation.
-/
inlineAttr? : Option InlineAttributeKind
deriving Inhabited, BEq

View File

@@ -24,7 +24,7 @@ structure Context where
inScope : FVarId Bool
/--
If `abstract x` returns `true`, we convert `x` into a closure parameter. Otherwise,
we collect the dependencies in the `let`/`fun`-declaration too, and include the declaration in the closure.
we collect the dependecies in the `let`/`fun`-declaration too, and include the declaration in the closure.
Remark: the lambda lifting pass abstracts all `let`/`fun`-declarations.
-/
abstract : FVarId Bool

View File

@@ -26,7 +26,7 @@ inductive Value where
-/
| top
/--
A certain constructor with a certain sets of parameters is possible.
A certian consructor with a certain sets of parameters is possible.
-/
| ctor (i : Name) (vs : Array Value)
/--
@@ -531,7 +531,7 @@ partial def inferMain : InterpM Unit := do
return ()
/--
Use the information produced by the abstract interpreter to:
Use the information produced by the abstract interpeter to:
- Eliminate branches that we know cannot be hit
- Eliminate values that we know have to be constants.
-/

View File

@@ -187,7 +187,7 @@ Will:
| n => x * y
| m => z
```
If we are at `y` `x` is already marked to be floated into `n` as well.
If we are at `y` `x` is alreayd marked to be floated into `n` as well.
- if there hasn't be a decision yet, that is they are marked with `.unknown` we float
them into the same arm as the current value:
```
@@ -211,7 +211,7 @@ Will:
When we visit `a` `x` is now marked as getting moved into `n` but since it also occurs
in `a` which wants to be moved somewhere else we will instead decide to not move `x`
at all.
- if they are meant to be floated somewhere else decide that they won't get floated:
- if they are meant to be floated somewhere else decide that they wont get floated:
```
let x := ...
let y := x + z
@@ -234,7 +234,7 @@ where
modify fun s => { s with decision := s.decision.insert fvar arm }
/--
Iterate through `decl`, pushing local declarations that are only used in one
Iterate throgh `decl`, pushing local declarations that are only used in one
control flow arm into said arm in order to avoid useless computations.
-/
partial def floatLetIn (decl : Decl) : CompilerM Decl := do

View File

@@ -342,7 +342,7 @@ def mergeJpContextIfNecessary (jp : FVarId) : ExtendM Unit := do
/--
We call this whenever we enter a new local function. It clears both the
current join point and the list of candidates since we can't lift join
current join point and the list of candidates since we cant lift join
points outside of functions as explained in `mergeJpContextIfNecessary`.
-/
def withNewFunScope (decl : FunDecl) (x : ExtendM α): ExtendM α := do

View File

@@ -33,7 +33,7 @@ structure State where
/-- Parameters that have been normalized. -/
paramNames : Array Name := #[]
/-- Monad for the universe level normalizer -/
/-- Monad for the universe leve normalizer -/
abbrev M := StateM State
/--

View File

@@ -13,7 +13,7 @@ namespace Lean.Compiler.LCNF
# Function arity reduction
This module finds "used" parameters in a declaration, and then
create an auxiliary declaration that contains only used parameters.
create an auxliary declaration that contains only used parameters.
For example:
```
def f (x y : Nat) : Nat :=

View File

@@ -105,7 +105,7 @@ abbrev Ctor2JpCasesAlt := FVarIdMap (NameMap JpCasesAlt)
open Internalize in
/--
Construct an auxiliary join point for a particular alternative in a join-point that satisfies `isJpCases?`.
Construct an auxiliary join point for a particular alternative in a join-point that satifies `isJpCases?`.
- `decls` is the prefix (before the `cases`). See `isJpCases?`.
- `params` are the parameters of the main join point that satisfies `isJpCases?`.
- `targetParamIdx` is the index of the parameter that we are expanding to `fields`
@@ -149,7 +149,7 @@ private def mkJmpArgsAtJp (params : Array Param) (targetParamIdx : Nat) (fields
/--
Try to optimize `jpCases` join points.
We say a join point is a `jpCases` when it satisfies the predicate `isJpCases`.
We say a join point is a `jpCases` when it satifies the predicate `isJpCases`.
If we have a jump to `jpCases` with a constructor, then we can optimize the code by creating an new join point for
the constructor.
Example: suppose we have

View File

@@ -139,7 +139,7 @@ where
return numOccs
/--
Similar to the default `Lean.withIncRecDepth`, but include the `inlineStack` in the error message.
Similar to the default `Lean.withIncRecDepth`, but include the `inlineStack` in the error messsage.
-/
@[inline] def withIncRecDepth (x : SimpM α) : SimpM α := do
let curr MonadRecDepth.getRecDepth

View File

@@ -103,7 +103,7 @@ private def isNoSpecType (env : Environment) (type : Expr) : Bool :=
*Note*: `fixedNeutral` must have forward dependencies.
The code specializer consider a `fixedNeutral` parameter during code specialization
only if it contains forward dependencies that are tagged as `.user`, `.fixedHO`, or `.fixedInst`.
only if it contains forward dependecies that are tagged as `.user`, `.fixedHO`, or `.fixedInst`.
The motivation is to minimize the number of code specializations that have little or no impact on
performance. For example, let's consider the function.
```

View File

@@ -15,6 +15,7 @@ import Lean.Data.LOption
import Lean.Data.Lsp
import Lean.Data.Name
import Lean.Data.NameMap
import Lean.Data.Occurrences
import Lean.Data.OpenDecl
import Lean.Data.Options
import Lean.Data.Parsec

View File

@@ -31,7 +31,7 @@ namespace HashMapImp
variable {α : Type u} {β : Type v}
/- Remark: we use a C implementation because this function is performance critical. -/
@[extern "lean_hashmap_mk_idx"]
@[extern "lean_data_hashmap_mk_idx"]
private def mkIdx {sz : Nat} (hash : UInt64) (h : sz.isPowerOfTwo) : { u : USize // u.toNat < sz } :=
-- TODO: avoid `if` in the reference implementation
let u := hash.toUSize &&& (sz.toUSize - 1)

View File

@@ -27,7 +27,7 @@ namespace HashSetImp
variable {α : Type u}
/- Remark: we use a C implementation because this function is performance critical. -/
@[extern "lean_hashset_mk_idx"]
@[extern c inline "(size_t)(#2) & (lean_unbox(#1) - 1)"]
private def mkIdx {sz : Nat} (hash : UInt64) (h : sz.isPowerOfTwo) : { u : USize // u.toNat < sz } :=
-- TODO: avoid `if` in the reference implementation
let u := hash.toUSize &&& (sz.toUSize - 1)

View File

@@ -114,7 +114,7 @@ protected def toString : JsonNumber → String
protected def shiftl : JsonNumber Nat JsonNumber
-- if s ≤ e, then 10 ^ (s - e) = 1, and hence the mantissa remains unchanged.
-- otherwise, the expression pads the mantissa with zeroes
-- to accommodate for the remaining places to shift.
-- to accomodate for the remaining places to shift.
| m, e, s => m * (10 ^ (s - e) : Nat), e - s
-- shift a JsonNumber by a specified amount of places to the right

View File

@@ -64,11 +64,11 @@ instance [ToJson α] : ToJson (Option α) :=
| none => Json.null
| some a => toJson a
instance {α : Type u} {β : Type v} [FromJson α] [FromJson β] : FromJson (α × β) where
instance [FromJson α] [FromJson β] : FromJson (α × β) where
fromJson?
| Json.arr #[ja, jb] => do
let a : ULift.{v} α := (fromJson? ja).map ULift.up
let b : ULift.{u} β := (fromJson? jb).map ULift.up
let a fromJson? ja
let b fromJson? jb
return (a, b)
| j => throw s!"expected pair, got '{j}'"

View File

@@ -83,7 +83,7 @@ structure CodeActionParams extends WorkDoneProgressParams, PartialResultParams w
context : CodeActionContext := {}
deriving FromJson, ToJson
/-- If the code action is disabled, this type gives the reason why. -/
/-- If the code action is disabled, this type gives the reson why. -/
structure CodeActionDisabled where
reason : String
deriving FromJson, ToJson

View File

@@ -133,7 +133,7 @@ def isNum : Name → Bool
| _ => false
/--
Return `true` if `n` contains a string part `s` that satisfies `f`.
Return `true` if `n` contains a string part `s` that satifies `f`.
Examples:
```

View File

@@ -46,13 +46,6 @@ def contains (s : NameSet) (n : Name) : Bool := RBMap.contains s n
instance : ForIn m NameSet Name :=
inferInstanceAs (ForIn _ (RBTree ..) ..)
/-- The union of two `NameSet`s. -/
def append (s t : NameSet) : NameSet :=
s.mergeBy (fun _ _ _ => .unit) t
instance : Append NameSet where
append := NameSet.append
end NameSet
def NameSSet := SSet Name

View File

@@ -0,0 +1,23 @@
/-
Copyright (c) 2020 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Leonardo de Moura
-/
namespace Lean
inductive Occurrences where
| all
| pos (idxs : List Nat)
| neg (idxs : List Nat)
deriving Inhabited, BEq
def Occurrences.contains : Occurrences Nat Bool
| all, _ => true
| pos idxs, idx => idxs.contains idx
| neg idxs, idx => !idxs.contains idx
def Occurrences.isAll : Occurrences Bool
| all => true
| _ => false
end Lean

View File

@@ -1,202 +1,110 @@
/-
Copyright (c) 2018 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Sebastian Ullrich, Leonardo de Moura, Joachim Breitner
Author: Sebastian Ullrich, Leonardo de Moura
A string trie data structure, used for tokenizing the Lean language
Trie for tokenizing the Lean language
-/
import Lean.Data.Format
namespace Lean
namespace Data
namespace Parser
/-
## Implementation notes
Tries have typically many nodes with small degree, where a linear scan
through the (compact) `ByteArray` is faster than using binary search or
search trees like `RBTree`.
Moreover, many nodes have degree 1, which justifies the special case `Node1`
constructor.
The code would be a bit less repetitive if we used something like the following
```
mutual
def Trie α := Option α × ByteAssoc α
inductive ByteAssoc α where
| leaf : Trie α
| node1 : UInt8 → Trie α → Trie α
| node : ByteArray → Array (Trie α) → Trie α
end
```
but that would come at the cost of extra indirections.
-/
/-- A Trie is a key-value store where the keys are of type `String`,
and the internal structure is a tree that branches on the bytes of the string. -/
inductive Trie (α : Type) where
| leaf : Option α Trie α
| node1 : Option α UInt8 Trie α Trie α
| node : Option α ByteArray Array (Trie α) Trie α
| Node : Option α RBNode Char (fun _ => Trie α) Trie α
namespace Trie
variable {α : Type}
/-- The empty `Trie` -/
def empty : Trie α := leaf none
def empty : Trie α :=
none, RBNode.leaf
instance : EmptyCollection (Trie α) :=
empty
instance : Inhabited (Trie α) where
default := empty
default := Node none RBNode.leaf
/-- Insert or update the value at a the given key `s`. -/
partial def upsert (t : Trie α) (s : String) (f : Option α α) : Trie α :=
let rec insertEmpty (i : Nat) : Trie α :=
if h : i < s.utf8ByteSize then
let c := s.getUtf8Byte i h
let t := insertEmpty (i + 1)
node1 none c t
else
leaf (f .none)
let rec loop
| i, leaf v =>
if h : i < s.utf8ByteSize then
let c := s.getUtf8Byte i h
let t := insertEmpty (i + 1)
node1 v c t
else
leaf (f v)
| i, node1 v c' t' =>
if h : i < s.utf8ByteSize then
let c := s.getUtf8Byte i h
if c == c'
then node1 v c' (loop (i + 1) t')
else
let t := insertEmpty (i + 1)
node v (.mk #[c, c']) #[t, t']
else
node1 (f v) c' t'
| i, node v cs ts =>
if h : i < s.utf8ByteSize then
let c := s.getUtf8Byte i h
match cs.findIdx? (· == c) with
| none =>
let t := insertEmpty (i + 1)
node v (cs.push c) (ts.push t)
| some idx =>
node v cs (ts.modify idx (loop (i + 1)))
else
node (f v) cs ts
loop 0 t
/-- Inserts a value at a the given key `s`, overriding an existing value if present. -/
partial def insert (t : Trie α) (s : String) (val : α) : Trie α :=
upsert t s (fun _ => val)
let rec insertEmpty (i : String.Pos) : Trie α :=
match s.atEnd i with
| true => Trie.Node (some val) RBNode.leaf
| false =>
let c := s.get i
let t := insertEmpty (s.next i)
Trie.Node none (RBNode.singleton c t)
let rec loop
| Trie.Node v m, i =>
match s.atEnd i with
| true => Trie.Node (some val) m -- overrides old value
| false =>
let c := s.get i
let i := s.next i
let t := match RBNode.find compare m c with
| none => insertEmpty i
| some t => loop t i
Trie.Node v (RBNode.insert compare m c t)
loop t 0
/-- Looks up a value at the given key `s`. -/
partial def find? (t : Trie α) (s : String) : Option α :=
let rec loop
| i, leaf val =>
if i < s.utf8ByteSize then
none
else
val
| i, node1 val c' t' =>
if h : i < s.utf8ByteSize then
let c := s.getUtf8Byte i h
if c == c'
then loop (i + 1) t'
else none
else
val
| i, node val cs ts =>
if h : i < s.utf8ByteSize then
let c := s.getUtf8Byte i h
match cs.findIdx? (· == c) with
| Trie.Node val m, i =>
match s.atEnd i with
| true => val
| false =>
let c := s.get i
let i := s.next i
match RBNode.find compare m c with
| none => none
| some idx => loop (i + 1) (ts.get! idx)
else
val
loop 0 t
| some t => loop t i
loop t 0
/-- Returns an `Array` of all values in the trie, in no particular order. -/
partial def values (t : Trie α) : Array α := go t |>.run #[] |>.2
where
go : Trie α StateM (Array α) Unit
| leaf a? => do
if let some a := a? then
modify (·.push a)
| node1 a? _ t' => do
if let some a := a? then
modify (·.push a)
go t'
| node a? _ ts => do
if let some a := a? then
modify (·.push a)
ts.forM fun t' => go t'
/-- Return values that match the given `prefix` -/
partial def findPrefix (t : Trie α) (pre : String) : Array α :=
go t 0 |>.run #[] |>.2
where
go (t : Trie α) (i : String.Pos) : StateM (Array α) Unit :=
if pre.atEnd i then
collect t
else
let k := pre.get i
let i := pre.next i
let _, cs := t
cs.forM fun k' c => do
if k == k' then go c i
/-- Returns all values whose key have the given string `pre` as a prefix, in no particular order. -/
partial def findPrefix (t : Trie α) (pre : String) : Array α := go t 0
where
go (t : Trie α) (i : Nat) : Array α :=
if h : i < pre.utf8ByteSize then
let c := pre.getUtf8Byte i h
match t with
| leaf _val => .empty
| node1 _val c' t' =>
if c == c'
then go t' (i + 1)
else .empty
| node _val cs ts =>
match cs.findIdx? (· == c) with
| none => .empty
| some idx => go (ts.get! idx) (i + 1)
else
t.values
collect (t : Trie α) : StateM (Array α) Unit := do
let a?, cs := t
if let some a := a? then
modify (·.push a)
cs.forM fun _ c => collect c
/-- Find the longest _key_ in the trie that is contained in the given string `s` at position `i`,
and return the associated value. -/
partial def matchPrefix (s : String) (t : Trie α) (i : String.Pos) : Option α :=
private def updtAcc (v : Option α) (i : String.Pos) (acc : String.Pos × Option α) : String.Pos × Option α :=
match v, acc with
| some v, (_, _) => (i, some v) -- we pattern match on `acc` to enable memory reuse
| none, acc => acc
partial def matchPrefix (s : String) (t : Trie α) (i : String.Pos) : String.Pos × Option α :=
let rec loop
| leaf v, _, res =>
if v.isSome then v else res
| node1 v c' t', i, res =>
let res := if v.isSome then v else res
if h : i < s.utf8ByteSize then
let c := s.getUtf8Byte i h
if c == c'
then loop t' (i + 1) res
else res
else
res
| node v cs ts, i, res =>
let res := if v.isSome then v else res
if h : i < s.utf8ByteSize then
let c := s.getUtf8Byte i h
match cs.findIdx? (· == c) with
| none => res
| some idx => loop (ts.get! idx) (i + 1) res
else
res
loop t i.byteIdx none
| Trie.Node v m, i, acc =>
match s.atEnd i with
| true => updtAcc v i acc
| false =>
let acc := updtAcc v i acc
let c := s.get i
let i := s.next i
match RBNode.find compare m c with
| some t => loop t i acc
| none => acc
loop t i (i, none)
private partial def toStringAux {α : Type} : Trie α List Format
| leaf _ => []
| node1 _ c t =>
[ format (repr c), Format.group $ Format.nest 4 $ flip Format.joinSep Format.line $ toStringAux t ]
| node _ cs ts =>
List.join $ List.zipWith (fun c t =>
[ format (repr c), (Format.group $ Format.nest 4 $ flip Format.joinSep Format.line $ toStringAux t) ]
) cs.toList ts.toList
| Trie.Node _ map => map.fold (fun Fs c t =>
format (repr c) :: (Format.group $ Format.nest 2 $ flip Format.joinSep Format.line $ toStringAux t) :: Fs) []
instance {α : Type} : ToString (Trie α) :=
fun t => (flip Format.joinSep Format.line $ toStringAux t).pretty
end Trie
end Data
end Parser
end Lean

View File

@@ -119,7 +119,7 @@ def XMLdecl : Parsec Unit := do
def Comment : Parsec String :=
let notDash := Char.toString <$> satisfy (λ c => c '-')
skipString "<!--" *>
Array.foldl String.append "" <$> many (attempt <| notDash <|> (do
Array.foldl String.append "" <$> many (notDash <|> (do
let d pchar '-'
let c notDash
pure $ d.toString ++ c))
@@ -408,7 +408,7 @@ def Attribute : Parsec (String × String) := do
protected def elementPrefix : Parsec (Array Content Element) := do
skipChar '<'
let name Name
let attributes many (attempt <| S *> Attribute)
let attributes many (S *> Attribute)
optional S *> pure ()
return Element.Element name (RBMap.fromList attributes.toList compare)

View File

@@ -70,11 +70,11 @@ structure ConstantVal where
name : Name
levelParams : List Name
type : Expr
deriving Inhabited, BEq
deriving Inhabited
structure AxiomVal extends ConstantVal where
isUnsafe : Bool
deriving Inhabited, BEq
deriving Inhabited
@[export lean_mk_axiom_val]
def mkAxiomValEx (name : Name) (levelParams : List Name) (type : Expr) (isUnsafe : Bool) : AxiomVal := {
@@ -119,7 +119,7 @@ structure TheoremVal extends ConstantVal where
List of all (including this one) declarations in the same mutual block.
See comment at `DefinitionVal.all`. -/
all : List Name := [name]
deriving Inhabited, BEq
deriving Inhabited
/-- Value for an opaque constant declaration `opaque x : t := e` -/
structure OpaqueVal extends ConstantVal where
@@ -129,7 +129,7 @@ structure OpaqueVal extends ConstantVal where
List of all (including this one) declarations in the same mutual block.
See comment at `DefinitionVal.all`. -/
all : List Name := [name]
deriving Inhabited, BEq
deriving Inhabited
@[export lean_mk_opaque_val]
def mkOpaqueValEx (name : Name) (levelParams : List Name) (type : Expr) (value : Expr) (isUnsafe : Bool) (all : List Name) : OpaqueVal := {
@@ -272,7 +272,7 @@ structure ConstructorVal extends ConstantVal where
/-- Number of fields (i.e., arity - nparams) -/
numFields : Nat
isUnsafe : Bool
deriving Inhabited, BEq
deriving Inhabited
@[export lean_mk_constructor_val]
def mkConstructorValEx (name : Name) (levelParams : List Name) (type : Expr) (induct : Name) (cidx numParams numFields : Nat) (isUnsafe : Bool) : ConstructorVal := {
@@ -296,7 +296,7 @@ structure RecursorRule where
nfields : Nat
/-- Right hand side of the reduction rule -/
rhs : Expr
deriving Inhabited, BEq
deriving Inhabited
structure RecursorVal extends ConstantVal where
/-- List of all inductive datatypes in the mutual declaration that generated this recursor -/
@@ -322,7 +322,7 @@ structure RecursorVal extends ConstantVal where
-/
k : Bool
isUnsafe : Bool
deriving Inhabited, BEq
deriving Inhabited
@[export lean_mk_recursor_val]
def mkRecursorValEx (name : Name) (levelParams : List Name) (type : Expr) (all : List Name) (numParams numIndices numMotives numMinors : Nat)
@@ -441,10 +441,6 @@ def isInductive : ConstantInfo → Bool
| inductInfo _ => true
| _ => false
def inductiveVal! : ConstantInfo InductiveVal
| .inductInfo val => val
| _ => panic! "Expected a `ConstantInfo.inductInfo`."
/--
List of all (including this one) declarations in the same mutual block.
-/

View File

@@ -132,7 +132,7 @@ private def getBinderIds (ids : Syntax) : TermElabM (Array Syntax) :=
/--
Convert `stx` into an array of `BinderView`s.
`stx` must be an identifier, `_`, `explicitBinder`, `implicitBinder`, `strictImplicitBinder`, or `instBinder`.
`stx` must be an indentifier, `_`, `explicitBinder`, `implicitBinder`, `strictImplicitBinder`, or `instBinder`.
-/
private def toBinderViews (stx : Syntax) : TermElabM (Array BinderView) := do
let k := stx.getKind
@@ -233,7 +233,7 @@ def elabBindersEx (binders : Array Syntax) (k : Array (Syntax × Expr) → TermE
/--
Elaborate the given binders (i.e., `Syntax` objects for `bracketedBinder`),
update the local context, set of local instances, reset instance cache (if needed), and then
update the local context, set of local instances, reset instance chache (if needed), and then
execute `k` with the updated context.
The local context will only be included inside `k`.

View File

@@ -158,7 +158,7 @@ private def containsId (ids : Array (TSyntax [`ident, ``Parser.Term.hole])) (id
/--
Auxiliary method for processing binder annotation update commands: `variable (α)` and `variable {α}`.
The argument `binder` is the binder of the `variable` command.
The method returns an array containing the "residue", that is, variables that do not correspond to updates.
The method retuns an array containing the "residue", that is, variables that do not correspond to updates.
Recall that a `bracketedBinder` can be of the form `(x y)`.
```
variable {α β : Type}

View File

@@ -82,7 +82,7 @@ open Meta
let type withSynthesize (mayPostpone := true) do
let type elabType type
if let some expectedType := expectedType? then
-- Recall that a similar approach is used when elaborating applications
-- Recall that a similiar approach is used when elaborating applications
discard <| isDefEq expectedType type
return type
/-

View File

@@ -46,7 +46,7 @@ def mkCalcTrans (result resultType step stepType : Expr) : MetaM (Expr × Expr)
/--
Adds a type annotation to a hole that occurs immediately at the beginning of the term.
This is so that coercions can trigger when elaborating the term.
See https://github.com/leanprover/lean4/issues/2040 for further rationale.
See https://github.com/leanprover/lean4/issues/2040 for futher rationale.
- `_ < 3` is annotated
- `(_) < 3` is not, because it occurs after an atom
@@ -68,7 +68,6 @@ where
| _ => set false; return t
def getCalcFirstStep (step0 : TSyntax ``calcFirstStep) : TermElabM (TSyntax ``calcStep) :=
withRef step0 do
match step0 with
| `(calcFirstStep| $term:term) =>
`(calcStep| $term = _ := rfl)
@@ -78,9 +77,7 @@ def getCalcFirstStep (step0 : TSyntax ``calcFirstStep) : TermElabM (TSyntax ``ca
def getCalcSteps (steps : TSyntax ``calcSteps) : TermElabM (Array (TSyntax ``calcStep)) :=
match steps with
| `(calcSteps|
$step0:calcFirstStep
$rest*) => do
| `(calcSteps| $step0:calcFirstStep $rest*) => do
let step0 getCalcFirstStep step0
pure (#[step0] ++ rest)
| _ => unreachable!

View File

@@ -48,7 +48,7 @@ def getDeclarationSelectionRef (stx : Syntax) : Syntax :=
/--
Store the `range` and `selectionRange` for `declName` where `stx` is the whole syntax object describing `declName`.
Store the `range` and `selectionRange` for `declName` where `stx` is the whole syntax object decribing `declName`.
This method is for the builtin declarations only.
User-defined commands should use `Lean.addDeclarationRanges` to store this information for their commands. -/
def addDeclarationRanges [Monad m] [MonadEnv m] [MonadFileMap m] (declName : Name) (stx : Syntax) : m Unit := do

View File

@@ -15,12 +15,12 @@ open Meta
def mkDecEqHeader (indVal : InductiveVal) : TermElabM Header := do
mkHeader `DecidableEq 2 indVal
def mkMatch (ctx : Context) (header : Header) (indVal : InductiveVal) : TermElabM Term := do
def mkMatch (header : Header) (indVal : InductiveVal) (auxFunName : Name) : TermElabM Term := do
let discrs mkDiscrs header indVal
let alts mkAlts
`(match $[$discrs],* with $alts:matchAlt*)
where
mkSameCtorRhs : List (Ident × Ident × Option Name × Bool) TermElabM Term
mkSameCtorRhs : List (Ident × Ident × Bool × Bool) TermElabM Term
| [] => ``(isTrue rfl)
| (a, b, recField, isProof) :: todo => withFreshMacroScope do
let rhs if isProof then
@@ -30,7 +30,7 @@ where
by subst h; exact $( mkSameCtorRhs todo):term
else
isFalse (by intro n; injection n; apply h _; assumption))
if let some auxFunName := recField then
if recField then
-- add local instance for `a = b` using the function being defined `auxFunName`
`(let inst := $(mkIdent auxFunName) $a $b; $rhs)
else
@@ -67,11 +67,8 @@ where
let b := mkIdent ( mkFreshUserName `b)
ctorArgs1 := ctorArgs1.push a
ctorArgs2 := ctorArgs2.push b
let indValNum :=
ctx.typeInfos.findIdx?
(( inferType x).isAppOf ConstantVal.name InductiveVal.toConstantVal)
let recField := indValNum.map (ctx.auxFunNames[·]!)
let isProof := ( inferType ( inferType x)).isProp
let recField := ( inferType x).isAppOf indVal.name
let isProof := ( inferType ( inferType x)).isProp
todo := todo.push (a, b, recField, isProof)
patterns := patterns.push ( `(@$(mkIdent ctorName₁):ident $ctorArgs1:term*))
patterns := patterns.push ( `(@$(mkIdent ctorName₁):ident $ctorArgs2:term*))
@@ -84,24 +81,18 @@ where
alts := alts.push ( `(matchAltExpr| | $[$patterns:term],* => $rhs:term))
return alts
def mkAuxFunction (ctx : Context) (auxFunName : Name) (indVal : InductiveVal): TermElabM (TSyntax `command) := do
let header mkDecEqHeader indVal
let body mkMatch ctx header indVal
let binders := header.binders
let type `(Decidable ($(mkIdent header.targetNames[0]!) = $(mkIdent header.targetNames[1]!)))
def mkAuxFunction (ctx : Context) : TermElabM Syntax := do
let auxFunName := ctx.auxFunNames[0]!
let indVal :=ctx.typeInfos[0]!
let header mkDecEqHeader indVal
let mut body mkMatch header indVal auxFunName
let binders := header.binders
let type `(Decidable ($(mkIdent header.targetNames[0]!) = $(mkIdent header.targetNames[1]!)))
`(private def $(mkIdent auxFunName):ident $binders:bracketedBinder* : $type:term := $body:term)
def mkAuxFunctions (ctx : Context) : TermElabM (TSyntax `command) := do
let mut res : Array (TSyntax `command) := #[]
for i in [:ctx.auxFunNames.size] do
let auxFunName := ctx.auxFunNames[i]!
let indVal := ctx.typeInfos[i]!
res := res.push ( mkAuxFunction ctx auxFunName indVal)
`(command| mutual $[$res:command]* end)
def mkDecEqCmds (indVal : InductiveVal) : TermElabM (Array Syntax) := do
let ctx mkContext "decEq" indVal.name
let cmds := #[ mkAuxFunctions ctx] ++ ( mkInstanceCmds ctx `DecidableEq #[indVal.name] (useAnonCtor := false))
let cmds := #[ mkAuxFunction ctx] ++ ( mkInstanceCmds ctx `DecidableEq #[indVal.name] (useAnonCtor := false))
trace[Elab.Deriving.decEq] "\n{cmds}"
return cmds
@@ -183,7 +174,9 @@ def mkDecEqEnum (declName : Name) : CommandElabM Unit := do
elabCommand cmd
def mkDecEqInstanceHandler (declNames : Array Name) : CommandElabM Bool := do
if ( isEnumType declNames[0]!) then
if declNames.size != 1 then
return false -- mutually inductive types are not supported yet
else if ( isEnumType declNames[0]!) then
mkDecEqEnum declNames[0]!
return true
else

View File

@@ -27,7 +27,7 @@ def mkInductArgNames (indVal : InductiveVal) : TermElabM (Array Name) := do
/-- Return the inductive declaration's type applied to the arguments in `argNames`. -/
def mkInductiveApp (indVal : InductiveVal) (argNames : Array Name) : TermElabM Term :=
let f := mkCIdent indVal.name
let f := mkIdent indVal.name
let args := argNames.map mkIdent
`(@$f $args*)
@@ -54,7 +54,7 @@ def mkInstImplicitBinders (className : Name) (indVal : InductiveVal) (argNames :
let c mkAppM className #[x]
if ( isTypeCorrect c) then
let argName := argNames[i]!
let binder : Syntax `(instBinderF| [ $(mkCIdent className):ident $(mkIdent argName):ident ])
let binder : Syntax `(instBinderF| [ $(mkIdent className):ident $(mkIdent argName):ident ])
binders := binders.push binder
catch _ =>
pure ()
@@ -94,7 +94,7 @@ def mkLocalInstanceLetDecls (ctx : Context) (className : Name) (argNames : Array
let binders mkImplicitBinders currIndices
let argNamesNew := argNames[:numParams] ++ currIndices
let indType mkInductiveApp indVal argNamesNew
let type `($(mkCIdent className) $indType)
let type `($(mkIdent className) $indType)
let val `($(mkIdent auxFunName))
let instName mkFreshUserName `localinst
let letDecl `(Parser.Term.letDecl| $(mkIdent instName):ident $binders:implicitBinder* : $type := $val)
@@ -116,10 +116,8 @@ def mkInstanceCmds (ctx : Context) (className : Name) (typeNames : Array Name) (
let binders mkImplicitBinders argNames
let binders := binders ++ ( mkInstImplicitBinders className indVal argNames)
let indType mkInductiveApp indVal argNames
let type `($(mkCIdent className) $indType)
let mut val := mkIdent auxFunName
if useAnonCtor then
val `($val)
let type `($(mkIdent className) $indType)
let val if useAnonCtor then `($(mkIdent auxFunName)) else pure <| mkIdent auxFunName
let instCmd `(instance $binders:implicitBinder* : $type := $val)
instances := instances.push instCmd
return instances

View File

@@ -501,7 +501,7 @@ def homogenize (c₁ c₂ : CodeBlock) : TermElabM (CodeBlock × CodeBlock) := d
/--
Extending code blocks with variable declarations: `let x : t := v` and `let x : t ← v`.
We remove `x` from the collection of updated variables.
We remove `x` from the collection of updated varibles.
Remark: `stx` is the syntax for the declaration (e.g., `letDecl`), and `xs` are the variables
declared by it. It is an array because we have let-declarations that declare multiple variables.
Example: `let (x, y) := t`

Some files were not shown because too many files have changed in this diff Show More