Compare commits

...

39 Commits

Author SHA1 Message Date
Kim Morrison
5df70e4446 . 2024-11-07 14:12:57 +11:00
Kim Morrison
6bebfc430e feat: lemmas relating Array.findX and List.findX 2024-11-07 14:08:03 +11:00
Kim Morrison
b1dee4a42e chore: upstream List.insertIdx from Batteries, lemmas from Mathlib, and revise lemmas (#5969)
To follow, connecting this to `Array.insertAt` (and renaming).
2024-11-06 23:29:27 +00:00
Kim Morrison
a54226196d feat: minor lemmas about List.ofFn (#5982)
`List.ofFn` still has very incomplete API.
2024-11-06 23:05:42 +00:00
Henrik Böving
196b1e9250 feat: BitVec.twoPow in bv_decide (#5979) 2024-11-06 17:51:44 +00:00
Sebastian Ullrich
345ecd20c9 chore: tag prerelease builds with -pre (#5943) 2024-11-06 14:47:52 +00:00
dependabot[bot]
7f0fe20315 chore: CI: bump mymindstorm/setup-emsdk from 12 to 14 (#5963)
Bumps
[mymindstorm/setup-emsdk](https://github.com/mymindstorm/setup-emsdk)
from 12 to 14.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/mymindstorm/setup-emsdk/releases">mymindstorm/setup-emsdk's
releases</a>.</em></p>
<blockquote>
<h2>Version 14</h2>
<h1>Breaking Changes</h1>
<p>The default cache key naming scheme was changed from
<code>{Emscripten version}-{OS type}-${CPU architecture}-master</code>
to <code>{Github workflow name}-{Emscripten version}-{OS type}-${CPU
architecture}</code>. If <code>actions-cache-folder</code> is defined,
ensure that there are no conflicts with other caches to prevent
issues.</p>
<h1>Changelog</h1>
<ul>
<li>Add option to override cache key naming scheme (<a
href="https://redirect.github.com/mymindstorm/setup-emsdk/issues/20">#20</a>)</li>
<li>Add workflow name to cache key naming scheme (<a
href="https://redirect.github.com/mymindstorm/setup-emsdk/issues/20">#20</a>)</li>
<li>Updated dependencies to latest versions</li>
</ul>
<h2>Version 13</h2>
<ul>
<li>Updated to Node 20</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="6ab9eb1bda"><code>6ab9eb1</code></a>
v13 -&gt; v14</li>
<li><a
href="bb630c3bf4"><code>bb630c3</code></a>
Update all dependencies to latest versions</li>
<li><a
href="74881103d0"><code>7488110</code></a>
Add workflow ID to cache key and cache key override option (<a
href="https://redirect.github.com/mymindstorm/setup-emsdk/issues/40">#40</a>)</li>
<li><a
href="d233ac12b0"><code>d233ac1</code></a>
v13</li>
<li><a
href="1749b22b40"><code>1749b22</code></a>
npm audit fix + update runtime to node20</li>
<li>See full diff in <a
href="https://github.com/mymindstorm/setup-emsdk/compare/v12...v14">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=mymindstorm/setup-emsdk&package-manager=github_actions&previous-version=12&new-version=14)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-06 10:45:31 +00:00
Kim Morrison
1e98fd7f2d feat: add another List.find?_eq_some lemma (#5974)
Inspired by https://github.com/leanprover-community/mathlib4/pull/18593
2024-11-06 10:02:25 +00:00
Markus Himmel
76d32cbd2a chore: exclude leanruntest_task_test_io for now (#5973)
To be reenabled after investigation.
2024-11-06 09:40:20 +00:00
Kim Morrison
15139b6ef6 feat: relate Array.zipWith/zip/unzip with List versions (#5972) 2024-11-06 09:22:08 +00:00
Sebastian Ullrich
14c3d4b1a6 chore: CI: remove link checker for old manual
It started failing frequently after updating it and we're not actively working on this text anyway
2024-11-06 10:27:25 +01:00
Kim Morrison
910b20fb2c chore: consolidate decide_True and decide_true_eq_true (#5949) 2024-11-06 05:12:25 +00:00
Kim Morrison
4df71ed24f feat: relate Array.isPrefixOf with List.isPrefixOf (#5971) 2024-11-06 02:44:14 +00:00
Kyle Miller
406da78fc6 fix: arg conv tactic misreported number of arguments on error (#5968) 2024-11-06 02:13:24 +00:00
Kim Morrison
5d2bd1e2e4 chore: deprecate Array.split in favour of identical Array.partition (#5970) 2024-11-06 00:37:33 +00:00
Kyle Miller
c31daece6c chore: fix all_goals test, simulate the max rec depth error (#5967) 2024-11-05 20:09:06 +00:00
Markus Himmel
c157ddda11 fix: do not link statically against pthread/dl/rt (#5966) 2024-11-05 18:20:42 +00:00
Henrik Böving
c77b6a2c64 feat: define ISize and basic operations on it (#5961) 2024-11-05 15:08:19 +00:00
dependabot[bot]
c6e4947f4a chore: CI: bump dcarbone/install-jq-action from 1.0.1 to 2.1.0 (#5965)
Bumps
[dcarbone/install-jq-action](https://github.com/dcarbone/install-jq-action)
from 1.0.1 to 2.1.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/dcarbone/install-jq-action/releases">dcarbone/install-jq-action's
releases</a>.</em></p>
<blockquote>
<h2>v2.1.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Support running action inside containers by <a
href="https://github.com/TaxBusby"><code>@​TaxBusby</code></a> in <a
href="https://redirect.github.com/dcarbone/install-jq-action/pull/10">dcarbone/install-jq-action#10</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/TaxBusby"><code>@​TaxBusby</code></a>
made their first contribution in <a
href="https://redirect.github.com/dcarbone/install-jq-action/pull/10">dcarbone/install-jq-action#10</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dcarbone/install-jq-action/compare/v2.0.2...v2.1.0">https://github.com/dcarbone/install-jq-action/compare/v2.0.2...v2.1.0</a></p>
<h2>v2.0.2</h2>
<h2>What's Changed</h2>
<ul>
<li>use curl instead of wget to avoid download failure on macOS by <a
href="https://github.com/vaidyakhil"><code>@​vaidyakhil</code></a> in <a
href="https://redirect.github.com/dcarbone/install-jq-action/pull/8">dcarbone/install-jq-action#8</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/vaidyakhil"><code>@​vaidyakhil</code></a> made
their first contribution in <a
href="https://redirect.github.com/dcarbone/install-jq-action/pull/8">dcarbone/install-jq-action#8</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dcarbone/install-jq-action/compare/v2.0.1...v2.0.2">https://github.com/dcarbone/install-jq-action/compare/v2.0.1...v2.0.2</a></p>
<h2>v2.0.1</h2>
<h2>What's Changed</h2>
<ul>
<li>using macos as dl link os prefix in lieu of osx by <a
href="https://github.com/dcarbone"><code>@​dcarbone</code></a> in <a
href="https://redirect.github.com/dcarbone/install-jq-action/pull/7">dcarbone/install-jq-action#7</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dcarbone/install-jq-action/compare/v2.0.0...v2.0.1">https://github.com/dcarbone/install-jq-action/compare/v2.0.0...v2.0.1</a></p>
<h2>v2.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>quick &amp; dirty 1.7 support by <a
href="https://github.com/dcarbone"><code>@​dcarbone</code></a> in <a
href="https://redirect.github.com/dcarbone/install-jq-action/pull/4">dcarbone/install-jq-action#4</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/dcarbone"><code>@​dcarbone</code></a>
made their first contribution in <a
href="https://redirect.github.com/dcarbone/install-jq-action/pull/4">dcarbone/install-jq-action#4</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dcarbone/install-jq-action/compare/v1.0.1...v2.0.0">https://github.com/dcarbone/install-jq-action/compare/v1.0.1...v2.0.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="8867ddb478"><code>8867ddb</code></a>
remove windows gubbins from container tests</li>
<li><a
href="945d84920f"><code>945d849</code></a>
Support running action inside containers (<a
href="https://redirect.github.com/dcarbone/install-jq-action/issues/10">#10</a>)</li>
<li><a
href="1090b8bd11"><code>1090b8b</code></a>
use curl instead of wget to fix failure on macOS runners (<a
href="https://redirect.github.com/dcarbone/install-jq-action/issues/8">#8</a>)</li>
<li><a
href="ff922c75b7"><code>ff922c7</code></a>
Update example-windows.yaml</li>
<li><a
href="7f4d6f4833"><code>7f4d6f4</code></a>
Update example-macos.yaml</li>
<li><a
href="bfb9fa8e7d"><code>bfb9fa8</code></a>
Update example-linux.yaml</li>
<li><a
href="c1548c666d"><code>c1548c6</code></a>
using macos as dl link os prefix in lieu of osx (<a
href="https://redirect.github.com/dcarbone/install-jq-action/issues/7">#7</a>)</li>
<li><a
href="f07422da1e"><code>f07422d</code></a>
fixing version</li>
<li><a
href="183bc8df0e"><code>183bc8d</code></a>
trying without stupid</li>
<li><a
href="f6b58bacfe"><code>f6b58ba</code></a>
its late.</li>
<li>Additional commits viewable in <a
href="https://github.com/dcarbone/install-jq-action/compare/v1.0.1...v2.1.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dcarbone/install-jq-action&package-manager=github_actions&previous-version=1.0.1&new-version=2.1.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-05 11:23:59 +00:00
dependabot[bot]
01814185a6 chore: CI: bump dawidd6/action-download-artifact from 2 to 6 (#5964)
Bumps
[dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact)
from 2 to 6.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/dawidd6/action-download-artifact/releases">dawidd6/action-download-artifact's
releases</a>.</em></p>
<blockquote>
<h2>v6</h2>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dawidd6/action-download-artifact/compare/v5...v6">https://github.com/dawidd6/action-download-artifact/compare/v5...v6</a></p>
<h2>v5</h2>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dawidd6/action-download-artifact/compare/v4...v5">https://github.com/dawidd6/action-download-artifact/compare/v4...v5</a></p>
<h2>v4</h2>
<h2>What's Changed</h2>
<ul>
<li><strong>VERSIONING CHANGE</strong>: now there will only be major
releases of this action, e.g. v5, v6 and so on</li>
<li>build(deps): bump undici from 5.28.3 to 5.28.4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/284">dawidd6/action-download-artifact#284</a></li>
<li>build(deps): bump <code>@​actions/artifact</code> from 2.1.4 to
2.1.5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/285">dawidd6/action-download-artifact#285</a></li>
<li>build(deps): bump <code>@​actions/artifact</code> from 2.1.5 to
2.1.7 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/287">dawidd6/action-download-artifact#287</a></li>
<li>build(deps): bump adm-zip from 0.5.12 to 0.5.13 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/289">dawidd6/action-download-artifact#289</a></li>
<li>Set allow_forks to false by default by <a
href="https://github.com/timweri"><code>@​timweri</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/290">dawidd6/action-download-artifact#290</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/timweri"><code>@​timweri</code></a> made
their first contribution in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/290">dawidd6/action-download-artifact#290</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dawidd6/action-download-artifact/compare/v3...v4">https://github.com/dawidd6/action-download-artifact/compare/v3...v4</a></p>
<h2>v3.1.4</h2>
<h2>What's Changed</h2>
<ul>
<li>build(deps): bump adm-zip from 0.5.10 to 0.5.12 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/282">dawidd6/action-download-artifact#282</a></li>
<li>build(deps): bump <code>@​actions/artifact</code> from 2.1.2 to
2.1.4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/280">dawidd6/action-download-artifact#280</a></li>
<li>fix: accept expired artifacts with documentation url by <a
href="https://github.com/wdconinc"><code>@​wdconinc</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/283">dawidd6/action-download-artifact#283</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/wdconinc"><code>@​wdconinc</code></a>
made their first contribution in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/283">dawidd6/action-download-artifact#283</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dawidd6/action-download-artifact/compare/v3...v3.1.4">https://github.com/dawidd6/action-download-artifact/compare/v3...v3.1.4</a></p>
<h2>v3.1.3</h2>
<h2>What's Changed</h2>
<ul>
<li>node_modules: upgrade by <a
href="https://github.com/dawidd6"><code>@​dawidd6</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/276">dawidd6/action-download-artifact#276</a></li>
<li>build(deps): bump <code>@​actions/artifact</code> from 2.1.1 to
2.1.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/277">dawidd6/action-download-artifact#277</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dawidd6/action-download-artifact/compare/v3.1.2...v3.1.3">https://github.com/dawidd6/action-download-artifact/compare/v3.1.2...v3.1.3</a></p>
<h2>v3.1.2</h2>
<h2>What's Changed</h2>
<ul>
<li>Read workflow_search input as a boolean by <a
href="https://github.com/klutchell"><code>@​klutchell</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/273">dawidd6/action-download-artifact#273</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/klutchell"><code>@​klutchell</code></a>
made their first contribution in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/273">dawidd6/action-download-artifact#273</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dawidd6/action-download-artifact/compare/v3.1.1...v3.1.2">https://github.com/dawidd6/action-download-artifact/compare/v3.1.1...v3.1.2</a></p>
<h2>v3.1.1</h2>
<h2>What's Changed</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="bf251b5aa9"><code>bf251b5</code></a>
node_modules: upgrade</li>
<li><a
href="93c6296611"><code>93c6296</code></a>
README: v5</li>
<li><a
href="deb3bb8325"><code>deb3bb8</code></a>
node_modules: upgrade</li>
<li><a
href="1d93f37db2"><code>1d93f37</code></a>
README: v4</li>
<li><a
href="854e2de939"><code>854e2de</code></a>
Set allow_forks to false by default (<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/290">#290</a>)</li>
<li><a
href="436c9d3774"><code>436c9d3</code></a>
build(deps): bump adm-zip from 0.5.12 to 0.5.13 (<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/289">#289</a>)</li>
<li><a
href="14040524bb"><code>1404052</code></a>
build(deps): bump <code>@​actions/artifact</code> from 2.1.5 to 2.1.7
(<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/287">#287</a>)</li>
<li><a
href="8a9be734dc"><code>8a9be73</code></a>
build(deps): bump <code>@​actions/artifact</code> from 2.1.4 to 2.1.5
(<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/285">#285</a>)</li>
<li><a
href="df593bbd04"><code>df593bb</code></a>
build(deps): bump undici from 5.28.3 to 5.28.4 (<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/284">#284</a>)</li>
<li><a
href="09f2f74827"><code>09f2f74</code></a>
fix: accept expired artifacts with documentation url (<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/283">#283</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/dawidd6/action-download-artifact/compare/v2...v6">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dawidd6/action-download-artifact&package-manager=github_actions&previous-version=2&new-version=6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-05 11:12:20 +00:00
dependabot[bot]
47d0060934 chore: CI: bump actions/github-script from 6 to 7 (#5962)
Bumps [actions/github-script](https://github.com/actions/github-script)
from 6 to 7.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/github-script/releases">actions/github-script's
releases</a>.</em></p>
<blockquote>
<h2>v7.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Add base-url option by <a
href="https://github.com/robandpdx"><code>@​robandpdx</code></a> in <a
href="https://redirect.github.com/actions/github-script/pull/429">actions/github-script#429</a></li>
<li>Expose async-function argument type by <a
href="https://github.com/viktorlott"><code>@​viktorlott</code></a> in <a
href="https://redirect.github.com/actions/github-script/pull/402">actions/github-script#402</a>,
see for details <a
href="https://github.com/actions/github-script#use-scripts-with-jsdoc-support">https://github.com/actions/github-script#use-scripts-with-jsdoc-support</a></li>
<li>Update dependencies and use Node 20 by <a
href="https://github.com/joshmgross"><code>@​joshmgross</code></a> in <a
href="https://redirect.github.com/actions/github-script/pull/425">actions/github-script#425</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/navarroaxel"><code>@​navarroaxel</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/github-script/pull/285">actions/github-script#285</a></li>
<li><a href="https://github.com/robandpdx"><code>@​robandpdx</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/github-script/pull/429">actions/github-script#429</a></li>
<li><a
href="https://github.com/viktorlott"><code>@​viktorlott</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/github-script/pull/402">actions/github-script#402</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/github-script/compare/v6.4.1...v7.0.0">https://github.com/actions/github-script/compare/v6.4.1...v7.0.0</a></p>
<h2>v6.4.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Add <code>@​octokit/plugin-request-log</code>, to produce debug
output for requests by <a
href="https://github.com/mjpieters"><code>@​mjpieters</code></a> in <a
href="https://redirect.github.com/actions/github-script/pull/358">actions/github-script#358</a></li>
<li>fix input handling by <a
href="https://github.com/mjpieters"><code>@​mjpieters</code></a> in <a
href="https://redirect.github.com/actions/github-script/pull/357">actions/github-script#357</a></li>
<li>Remove unused dependencies by <a
href="https://github.com/mjpieters"><code>@​mjpieters</code></a> in <a
href="https://redirect.github.com/actions/github-script/pull/356">actions/github-script#356</a></li>
<li>Default debug to current runner debug state by <a
href="https://github.com/mjpieters"><code>@​mjpieters</code></a> in <a
href="https://redirect.github.com/actions/github-script/pull/363">actions/github-script#363</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/mjpieters"><code>@​mjpieters</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/github-script/pull/358">actions/github-script#358</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/github-script/compare/v6.4.0...v6.4.1">https://github.com/actions/github-script/compare/v6.4.0...v6.4.1</a></p>
<h2>v6.4.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Bump json5 from 2.1.3 to 2.2.3 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/github-script/pull/319">actions/github-script#319</a></li>
<li>Bump minimatch from 3.0.4 to 3.1.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/github-script/pull/320">actions/github-script#320</a></li>
<li>Add node-fetch by <a
href="https://github.com/danmichaelo"><code>@​danmichaelo</code></a> in
<a
href="https://redirect.github.com/actions/github-script/pull/321">actions/github-script#321</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/jongwooo"><code>@​jongwooo</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/github-script/pull/313">actions/github-script#313</a></li>
<li><a
href="https://github.com/austinvazquez"><code>@​austinvazquez</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/github-script/pull/306">actions/github-script#306</a></li>
<li><a
href="https://github.com/danmichaelo"><code>@​danmichaelo</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/github-script/pull/321">actions/github-script#321</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/github-script/compare/v6.3.3...v6.4.0">https://github.com/actions/github-script/compare/v6.3.3...v6.4.0</a></p>
<h2>v6.3.3</h2>
<h2>What's Changed</h2>
<ul>
<li>Update <code>@actions/glob</code> to 0.3.0 by <a
href="https://github.com/nineinchnick"><code>@​nineinchnick</code></a>
in <a
href="https://redirect.github.com/actions/github-script/pull/279">actions/github-script#279</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/nineinchnick"><code>@​nineinchnick</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/github-script/pull/279">actions/github-script#279</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/github-script/compare/v6.3.2...v6.3.3">https://github.com/actions/github-script/compare/v6.3.2...v6.3.3</a></p>
<h2>v6.3.2</h2>
<h2>What's Changed</h2>
<ul>
<li>Update <code>@​actions/core</code> to 1.10.0 by <a
href="https://github.com/rentziass"><code>@​rentziass</code></a> in <a
href="https://redirect.github.com/actions/github-script/pull/295">actions/github-script#295</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="60a0d83039"><code>60a0d83</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/github-script/issues/440">#440</a>
from actions/joshmgross/v7.0.1</li>
<li><a
href="b7fb2001b4"><code>b7fb200</code></a>
Update version to 7.0.1</li>
<li><a
href="12e22ed06b"><code>12e22ed</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/github-script/issues/439">#439</a>
from actions/joshmgross/avoid-setting-base-url</li>
<li><a
href="d319f8f5b5"><code>d319f8f</code></a>
Avoid setting <code>baseUrl</code> to undefined when input is not
provided</li>
<li><a
href="e69ef5462f"><code>e69ef54</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/github-script/issues/425">#425</a>
from actions/joshmgross/node-20</li>
<li><a
href="ee0914b839"><code>ee0914b</code></a>
Update licenses</li>
<li><a
href="d6fc56f33b"><code>d6fc56f</code></a>
Use <code>@types/node</code> for Node 20</li>
<li><a
href="384d6cf581"><code>384d6cf</code></a>
Fix quotations in tests</li>
<li><a
href="84724927e3"><code>8472492</code></a>
Only validate GraphQL <code>previews</code></li>
<li><a
href="84903f5182"><code>84903f5</code></a>
Remove <code>node-fetch</code> from type</li>
<li>Additional commits viewable in <a
href="https://github.com/actions/github-script/compare/v6...v7">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/github-script&package-manager=github_actions&previous-version=6&new-version=7)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-05 11:06:39 +00:00
dependabot[bot]
b1c2d851e5 chore: CI: bump lycheeverse/lychee-action from 1.9.0 to 2.0.2 (#5959)
Bumps
[lycheeverse/lychee-action](https://github.com/lycheeverse/lychee-action)
from 1.9.0 to 2.0.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/lycheeverse/lychee-action/releases">lycheeverse/lychee-action's
releases</a>.</em></p>
<blockquote>
<h2>Version 2.0.2</h2>
<h2>What's Changed</h2>
<ul>
<li>Fix a typos by <a
href="https://github.com/szepeviktor"><code>@​szepeviktor</code></a> in
<a
href="https://redirect.github.com/lycheeverse/lychee-action/pull/257">lycheeverse/lychee-action#257</a></li>
<li>Document and use correct permissions in the GitHub workflows by <a
href="https://github.com/dscho"><code>@​dscho</code></a> in <a
href="https://redirect.github.com/lycheeverse/lychee-action/pull/258">lycheeverse/lychee-action#258</a></li>
<li>Add security policy by <a
href="https://github.com/mondeja"><code>@​mondeja</code></a> in <a
href="https://redirect.github.com/lycheeverse/lychee-action/pull/259">lycheeverse/lychee-action#259</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/szepeviktor"><code>@​szepeviktor</code></a>
made their first contribution in <a
href="https://redirect.github.com/lycheeverse/lychee-action/pull/257">lycheeverse/lychee-action#257</a></li>
<li><a href="https://github.com/mondeja"><code>@​mondeja</code></a> made
their first contribution in <a
href="https://redirect.github.com/lycheeverse/lychee-action/pull/259">lycheeverse/lychee-action#259</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/lycheeverse/lychee-action/compare/v2...v2.0.2">https://github.com/lycheeverse/lychee-action/compare/v2...v2.0.2</a></p>
<h2>Version 2.0.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Don't remove the lychee config file by <a
href="https://github.com/dmathieu"><code>@​dmathieu</code></a> in <a
href="https://redirect.github.com/lycheeverse/lychee-action/pull/255">lycheeverse/lychee-action#255</a></li>
<li>Bump lycheeverse/lychee-action from 1 to 2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/lycheeverse/lychee-action/pull/252">lycheeverse/lychee-action#252</a></li>
<li>Fix variable name in docs by <a
href="https://github.com/kdeldycke"><code>@​kdeldycke</code></a> in <a
href="https://redirect.github.com/lycheeverse/lychee-action/pull/253">lycheeverse/lychee-action#253</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/dmathieu"><code>@​dmathieu</code></a>
made their first contribution in <a
href="https://redirect.github.com/lycheeverse/lychee-action/pull/255">lycheeverse/lychee-action#255</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/lycheeverse/lychee-action/compare/v2...v2.0.1">https://github.com/lycheeverse/lychee-action/compare/v2...v2.0.1</a></p>
<h2>Version 2.0.0</h2>
<h2>Breaking Changes</h2>
<p><strong>Note:</strong> This release improves the action's robustness
by changing default behaviors. Changes are only required if you want to
opt out of the new failure conditions. Most users won't need to modify
their existing configurations.</p>
<h3>Fail pipeline on error by default</h3>
<p>We've changed the default behavior: pipelines will now fail on broken
links automatically. This addresses user feedback that not failing on
broken links was unexpected (see [issue <a
href="https://redirect.github.com/lycheeverse/lychee-action/issues/71">#71</a>](<a
href="https://redirect.github.com/lycheeverse/lychee-action/issues/71">lycheeverse/lychee-action#71</a>)).</p>
<p><strong>What you need to do:</strong></p>
<ul>
<li>Update to version 2 of this action to apply this change.</li>
<li>Users of the <code>lychee-action@master</code> branch don't need to
make any changes, as <code>fail: true</code> has been the default there
for a while.</li>
<li>If you prefer the old behavior, explicitly set <code>fail</code> to
<code>false</code> when updating:</li>
</ul>
<pre lang="yaml"><code>- name: Link Checker
  id: lychee
  uses: lycheeverse/lychee-action@v2
  with:
    fail: false  # Don't fail action on broken links
</code></pre>
<h3>Fail pipeline if no links were found</h3>
<p>Similar to the above change, we now fail the pipeline if no links are
found during a run. This helps warn users about potential configuration
issues.</p>
<p><strong>What you need to do:</strong></p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="7cd0af4c74"><code>7cd0af4</code></a>
Merge commit from fork</li>
<li><a
href="8ad54d3568"><code>8ad54d3</code></a>
fix link</li>
<li><a
href="762333c189"><code>762333c</code></a>
Create SECURITY.md (<a
href="https://redirect.github.com/lycheeverse/lychee-action/issues/259">#259</a>)</li>
<li><a
href="71a38a3bd7"><code>71a38a3</code></a>
Document and use correct permissions in the GitHub workflows (<a
href="https://redirect.github.com/lycheeverse/lychee-action/issues/258">#258</a>)</li>
<li><a
href="f141760066"><code>f141760</code></a>
Fix a typos (<a
href="https://redirect.github.com/lycheeverse/lychee-action/issues/257">#257</a>)</li>
<li><a
href="2bb232618b"><code>2bb2326</code></a>
don't remove the lychee config file (<a
href="https://redirect.github.com/lycheeverse/lychee-action/issues/255">#255</a>)</li>
<li><a
href="731bf1a2af"><code>731bf1a</code></a>
Fix variable name (<a
href="https://redirect.github.com/lycheeverse/lychee-action/issues/253">#253</a>)</li>
<li><a
href="e360f3c891"><code>e360f3c</code></a>
Bump lycheeverse/lychee-action from 1 to 2 (<a
href="https://redirect.github.com/lycheeverse/lychee-action/issues/252">#252</a>)</li>
<li><a
href="f87f0a6299"><code>f87f0a6</code></a>
Update version to <code>lycheeverse/lychee-action@v2</code> in docs</li>
<li><a
href="7da8ec1fc4"><code>7da8ec1</code></a>
Test latest lychee version tag (<a
href="https://redirect.github.com/lycheeverse/lychee-action/issues/236">#236</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/lycheeverse/lychee-action/compare/v1.9.0...v2.0.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=lycheeverse/lychee-action&package-manager=github_actions&previous-version=1.9.0&new-version=2.0.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2024-11-05 10:41:16 +00:00
Sebastian Ullrich
970dc6f7aa chore: CI: give Linux Debug unlimited test stack size (#5953) 2024-11-05 10:06:53 +00:00
dependabot[bot]
8e2f92607f chore: CI: bump actions/stale from 8 to 9 (#5958)
Bumps [actions/stale](https://github.com/actions/stale) from 8 to 9.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/stale/releases">actions/stale's
releases</a>.</em></p>
<blockquote>
<h2>v9.0.0</h2>
<h2>Breaking Changes</h2>
<ol>
<li>Action is now stateful: If the action ends because of <a
href="https://github.com/actions/stale#operations-per-run">operations-per-run</a>
then the next run will start from the first unprocessed issue skipping
the issues processed during the previous run(s). The state is reset when
all the issues are processed. This should be considered for scheduling
workflow runs.</li>
<li>Version 9 of this action updated the runtime to Node.js 20. All
scripts are now run with Node.js 20 instead of Node.js 16 and are
affected by any breaking changes between Node.js 16 and 20.</li>
</ol>
<h2>What Else Changed</h2>
<ol>
<li>Performance optimization that removes unnecessary API calls by <a
href="https://github.com/dsame"><code>@​dsame</code></a> <a
href="https://redirect.github.com/actions/stale/pull/1033/">#1033</a>
fixes <a
href="https://redirect.github.com/actions/stale/issues/792">#792</a></li>
<li>Logs displaying current github API rate limit by <a
href="https://github.com/dsame"><code>@​dsame</code></a> <a
href="https://redirect.github.com/actions/stale/pull/1032">#1032</a>
addresses <a
href="https://redirect.github.com/actions/stale/issues/1029">#1029</a></li>
</ol>
<p>For more information, please read the <a
href="https://github.com/actions/stale#readme">action documentation</a>
and its <a href="https://github.com/actions/stale#statefulness">section
about statefulness</a></p>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/jmeridth"><code>@​jmeridth</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/stale/pull/984">actions/stale#984</a></li>
<li><a
href="https://github.com/nikolai-laevskii"><code>@​nikolai-laevskii</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/stale/pull/1020">actions/stale#1020</a></li>
<li><a
href="https://github.com/dusan-trickovic"><code>@​dusan-trickovic</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/stale/pull/1056">actions/stale#1056</a></li>
<li><a
href="https://github.com/aparnajyothi-y"><code>@​aparnajyothi-y</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/stale/pull/1110">actions/stale#1110</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/stale/compare/v8...v9.0.0">https://github.com/actions/stale/compare/v8...v9.0.0</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/actions/stale/blob/main/CHANGELOG.md">actions/stale's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h1>[7.0.0]</h1>
<p>⚠️ Breaking change ⚠️</p>
<ul>
<li>Allow daysBeforeStale options to be float by <a
href="https://github.com/irega"><code>@​irega</code></a> in <a
href="https://redirect.github.com/actions/stale/pull/841">actions/stale#841</a></li>
<li>Use cache in check-dist.yml by <a
href="https://github.com/jongwooo"><code>@​jongwooo</code></a> in <a
href="https://redirect.github.com/actions/stale/pull/876">actions/stale#876</a></li>
<li>fix print outputs step in existing workflows by <a
href="https://github.com/irega"><code>@​irega</code></a> in <a
href="https://redirect.github.com/actions/stale/pull/859">actions/stale#859</a></li>
<li>Update issue and PR templates, add/delete workflow files by <a
href="https://github.com/IvanZosimov"><code>@​IvanZosimov</code></a> in
<a
href="https://redirect.github.com/actions/stale/pull/880">actions/stale#880</a></li>
<li>Update how stale handles exempt items by <a
href="https://github.com/johnsudol"><code>@​johnsudol</code></a> in <a
href="https://redirect.github.com/actions/stale/pull/874">actions/stale#874</a></li>
</ul>
<h1>[6.0.1]</h1>
<p>Update <code>@​actions/core</code> to v1.10.0 (<a
href="https://redirect.github.com/actions/stale/pull/839">#839</a>)</p>
<h1>[6.0.0]</h1>
<p>⚠️ Breaking change ⚠️</p>
<p>Issues/PRs default <code>close-issue-reason</code> is now
<code>not_planned</code>(<a
href="https://redirect.github.com/actions/stale/issues/789">#789</a>)</p>
<h1>[5.1.0]</h1>
<p><a href="https://redirect.github.com/actions/stale/issues/696">Don't
process stale issues right after they're marked stale</a>
[Add close-issue-reason option]<a
href="https://redirect.github.com/actions/stale/pull/764">#764</a><a
href="https://redirect.github.com/actions/stale/pull/772">#772</a>
Various dependabot/dependency updates</p>
<h2><a
href="https://github.com/actions/stale/compare/v3.0.19...v4.1.0">4.1.0</a>
(2021-07-14)</h2>
<h2>Features</h2>
<ul>
<li><a
href="9912fa74d1">Ability
to exempt draft PRs</a></li>
</ul>
<h2><a
href="https://github.com/actions/stale/compare/v3.0.19...v4.0.0">4.0.0</a>
(2021-07-14)</h2>
<h3>Features</h3>
<ul>
<li><strong>options:</strong> simplify config by removing skip stale
message options (<a
href="https://redirect.github.com/actions/stale/issues/457">#457</a>)
(<a
href="6ec637d238">6ec637d</a>),
closes <a
href="https://redirect.github.com/actions/stale/issues/405">#405</a> <a
href="https://redirect.github.com/actions/stale/issues/455">#455</a></li>
<li><strong>output:</strong> print output parameters (<a
href="https://redirect.github.com/actions/stale/issues/458">#458</a>)
(<a
href="3e6d35b685">3e6d35b</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>dry-run:</strong> forbid mutations in dry-run (<a
href="https://redirect.github.com/actions/stale/issues/500">#500</a>)
(<a
href="f1017f33dd">f1017f3</a>),
closes <a
href="https://redirect.github.com/actions/stale/issues/499">#499</a></li>
<li><strong>logs:</strong> coloured logs (<a
href="https://redirect.github.com/actions/stale/issues/465">#465</a>)
(<a
href="5fbbfba142">5fbbfba</a>)</li>
<li><strong>operations:</strong> fail fast the current batch to respect
the operations limit (<a
href="https://redirect.github.com/actions/stale/issues/474">#474</a>)
(<a
href="5f6f311ca6">5f6f311</a>),
closes <a
href="https://redirect.github.com/actions/stale/issues/466">#466</a></li>
<li><strong>label comparison</strong>: make label comparison case
insensitive <a
href="https://redirect.github.com/actions/stale/pull/517">#517</a>,
closes <a
href="https://redirect.github.com/actions/stale/pull/516">#516</a></li>
<li><strong>filtering comments by actor could have strange
behavior</strong>: &quot;stale&quot; comments are now detected based on
if the message is the stale message not <em>who</em> made the comment(<a
href="https://redirect.github.com/actions/stale/pull/519">#519</a>),
fixes <a
href="https://redirect.github.com/actions/stale/pull/441">#441</a>, <a
href="https://redirect.github.com/actions/stale/pull/509">#509</a>, <a
href="https://redirect.github.com/actions/stale/pull/518">#518</a></li>
</ul>
<h3>Breaking Changes</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="28ca103628"><code>28ca103</code></a>
Upgrade Node to v20 (<a
href="https://redirect.github.com/actions/stale/issues/1110">#1110</a>)</li>
<li><a
href="b69b346013"><code>b69b346</code></a>
build(deps-dev): bump <code>@​types/node</code> from 18.16.18 to 20.5.1
(<a
href="https://redirect.github.com/actions/stale/issues/1079">#1079</a>)</li>
<li><a
href="88a6f4f6cb"><code>88a6f4f</code></a>
build(deps-dev): bump typescript from 5.1.3 to 5.2.2 (<a
href="https://redirect.github.com/actions/stale/issues/1083">#1083</a>)</li>
<li><a
href="796531a7b3"><code>796531a</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/stale/issues/1080">#1080</a>
from akv-platform/fix-delete-cache</li>
<li><a
href="8986f6218b"><code>8986f62</code></a>
Don not try to delete cache if it does not exists</li>
<li><a
href="cab99b362b"><code>cab99b3</code></a>
fix typo proceeded/processed</li>
<li><a
href="184e7afe93"><code>184e7af</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/stale/issues/1064">#1064</a>
from actions/dependabot/npm_and_yarn/typescript-esli...</li>
<li><a
href="523885cf3c"><code>523885c</code></a>
chore: update eslint-plugin, parser and eslint-plugin-jest</li>
<li><a
href="2487a1dc2b"><code>2487a1d</code></a>
build(deps-dev): bump
<code>@​typescript-eslint/eslint-plugin</code></li>
<li><a
href="60c722ee97"><code>60c722e</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/stale/issues/1063">#1063</a>
from actions/dependabot/npm_and_yarn/jest-29.6.2</li>
<li>Additional commits viewable in <a
href="https://github.com/actions/stale/compare/v8...v9">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/stale&package-manager=github_actions&previous-version=8&new-version=9)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-05 09:53:55 +00:00
dependabot[bot]
ee1fa6eeb7 chore: CI: bump raven-actions/actionlint from 1 to 2 (#5957)
Bumps
[raven-actions/actionlint](https://github.com/raven-actions/actionlint)
from 1 to 2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/raven-actions/actionlint/releases">raven-actions/actionlint's
releases</a>.</em></p>
<blockquote>
<h2>v2.0.0</h2>
<h2>🔄️ What's Changed</h2>
<ul>
<li>node20 support</li>
<li>ci(linter): add workflow permissions <a
href="https://github.com/DariuszPorowski"><code>@​DariuszPorowski</code></a>
(<a
href="https://redirect.github.com/raven-actions/actionlint/issues/24">#24</a>)</li>
<li>ci(deps): Bump actions/cache from 3 to 4 <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> (<a
href="https://redirect.github.com/raven-actions/actionlint/issues/20">#20</a>)</li>
</ul>
<h2>🚀 Features</h2>
<ul>
<li>feat: switch to pipx &amp; add github-token <a
href="https://github.com/DariuszPorowski"><code>@​DariuszPorowski</code></a>
(<a
href="https://redirect.github.com/raven-actions/actionlint/issues/23">#23</a>)</li>
</ul>
<h2>👥 Contributors</h2>
<p><a
href="https://github.com/DariuszPorowski"><code>@​DariuszPorowski</code></a>,
<a href="https://github.com/dependabot"><code>@​dependabot</code></a>
and <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]</p>
<p>See details of all code changes: <a
href="https://github.com/raven-actions/actionlint/compare/v1.0.3...v2.0.0">https://github.com/raven-actions/actionlint/compare/v1.0.3...v2.0.0</a>
since previous release.</p>
<h2>v1.0.3</h2>
<h2>🔄️ What's Changed</h2>
<ul>
<li>chore: yamllint config and files lint <a
href="https://github.com/DariuszPorowski"><code>@​DariuszPorowski</code></a>
(<a
href="https://redirect.github.com/raven-actions/actionlint/issues/18">#18</a>)</li>
<li>⬆️ github-actions(deps): Bump actions/github-script from 6 to 7 <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> (<a
href="https://redirect.github.com/raven-actions/actionlint/issues/17">#17</a>)</li>
<li>⬆️ github-actions(deps): bump actions/checkout from 3 to 4 <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> (<a
href="https://redirect.github.com/raven-actions/actionlint/issues/12">#12</a>)</li>
</ul>
<h2>🚀 Features</h2>
<ul>
<li>Make yamllint happy <a
href="https://github.com/bhundven"><code>@​bhundven</code></a> (<a
href="https://redirect.github.com/raven-actions/actionlint/issues/16">#16</a>)</li>
<li>Fix debian install shellcheck <a
href="https://github.com/bhundven"><code>@​bhundven</code></a> (<a
href="https://redirect.github.com/raven-actions/actionlint/issues/15">#15</a>)</li>
</ul>
<h2>🐛 Bug Fixes</h2>
<ul>
<li>fix: user flags parser <a
href="https://github.com/DariuszPorowski"><code>@​DariuszPorowski</code></a>
(<a
href="https://redirect.github.com/raven-actions/actionlint/issues/19">#19</a>)</li>
<li>Fix debian install shellcheck <a
href="https://github.com/bhundven"><code>@​bhundven</code></a> (<a
href="https://redirect.github.com/raven-actions/actionlint/issues/15">#15</a>)</li>
</ul>
<h2>👥 Contributors</h2>
<p><a
href="https://github.com/DariuszPorowski"><code>@​DariuszPorowski</code></a>,
<a href="https://github.com/bhundven"><code>@​bhundven</code></a>, <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> and
<a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]</p>
<p>See details of all code changes: <a
href="https://github.com/raven-actions/actionlint/compare/v1.0.2...v1.0.3">https://github.com/raven-actions/actionlint/compare/v1.0.2...v1.0.3</a>
since previous release.</p>
<h2>v1.0.2</h2>
<h2>🔄️ What's Changed</h2>
<ul>
<li> feat(inputs): group-result <a
href="https://github.com/DariuszPorowski"><code>@​DariuszPorowski</code></a>
(<a
href="https://redirect.github.com/raven-actions/actionlint/issues/10">#10</a>)</li>
<li>👷 chore(github): ci adjustments <a
href="https://github.com/DariuszPorowski"><code>@​DariuszPorowski</code></a>
(<a
href="https://redirect.github.com/raven-actions/actionlint/issues/9">#9</a>)</li>
<li>👷 refactor(ci): change to debug action <a
href="https://github.com/DariuszPorowski"><code>@​DariuszPorowski</code></a>
(<a
href="https://redirect.github.com/raven-actions/actionlint/issues/7">#7</a>)</li>
<li>📝 chore: minor docs and CI adjustments <a
href="https://github.com/DariuszPorowski"><code>@​DariuszPorowski</code></a>
(<a
href="https://redirect.github.com/raven-actions/actionlint/issues/6">#6</a>)</li>
</ul>
<h2>👥 Contributors</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="01fce4f43a"><code>01fce4f</code></a>
ci(linter): add workflow permissions (<a
href="https://redirect.github.com/raven-actions/actionlint/issues/24">#24</a>)</li>
<li><a
href="a30be5376b"><code>a30be53</code></a>
feat: switch to pipx &amp; add github-token (<a
href="https://redirect.github.com/raven-actions/actionlint/issues/23">#23</a>)</li>
<li><a
href="ea4eb57846"><code>ea4eb57</code></a>
ci(deps): Bump actions/cache from 3 to 4 (<a
href="https://redirect.github.com/raven-actions/actionlint/issues/20">#20</a>)</li>
<li>See full diff in <a
href="https://github.com/raven-actions/actionlint/compare/v1...v2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=raven-actions/actionlint&package-manager=github_actions&previous-version=1&new-version=2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-05 09:49:23 +00:00
dependabot[bot]
9d2a017704 chore: CI: bump softprops/action-gh-release from 1 to 2 (#5955)
Bumps
[softprops/action-gh-release](https://github.com/softprops/action-gh-release)
from 1 to 2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/softprops/action-gh-release/releases">softprops/action-gh-release's
releases</a>.</em></p>
<blockquote>
<h2>v2.0.0</h2>
<ul>
<li>update actions.yml declaration to node20 to address warnings</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md">softprops/action-gh-release's
changelog</a>.</em></p>
<blockquote>
<h2>0.1.12</h2>
<ul>
<li>fix bug leading to empty strings subsituted for inputs users don't
provide breaking api calls <a
href="https://redirect.github.com/softprops/action-gh-release/pull/144">#144</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="e7a8f85e1c"><code>e7a8f85</code></a>
chore: release 2.0.9</li>
<li><a
href="04afa1392e"><code>04afa13</code></a>
chore(deps): bump actions/setup-node from 4.0.4 to 4.1.0 (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/535">#535</a>)</li>
<li><a
href="894468a03c"><code>894468a</code></a>
chore(deps): bump actions/checkout from 4.2.1 to 4.2.2 (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/534">#534</a>)</li>
<li><a
href="3bd23aa9ec"><code>3bd23aa</code></a>
chore(deps): bump <code>@​types/node</code> from 22.7.5 to 22.8.2 (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/533">#533</a>)</li>
<li><a
href="21eb2f9554"><code>21eb2f9</code></a>
chore(deps): bump <code>@​types/jest</code> from 29.5.13 to 29.5.14 (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/532">#532</a>)</li>
<li><a
href="cd8b57e572"><code>cd8b57e</code></a>
remove unused imports (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/521">#521</a>)</li>
<li><a
href="820a5adc43"><code>820a5ad</code></a>
chore(deps): bump actions/checkout from 4.2.0 to 4.2.1 (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/522">#522</a>)</li>
<li><a
href="9d04f90cd8"><code>9d04f90</code></a>
chore(deps): bump <code>@​octokit/plugin-throttling</code> from 9.3.1 to
9.3.2 (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/523">#523</a>)</li>
<li><a
href="aaf1d5f6d5"><code>aaf1d5f</code></a>
chore(deps): bump <code>@​actions/core</code> from 1.10.1 to 1.11.1 (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/524">#524</a>)</li>
<li><a
href="7d33a7ecc3"><code>7d33a7e</code></a>
chore(deps): bump <code>@​types/node</code> from 22.5.5 to 22.7.5 (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/525">#525</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/softprops/action-gh-release/compare/v1...v2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=softprops/action-gh-release&package-manager=github_actions&previous-version=1&new-version=2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-05 09:40:03 +00:00
dependabot[bot]
574b86c247 chore: CI: bump nwtgck/actions-netlify from 2.0 to 3.0 (#5956)
Bumps
[nwtgck/actions-netlify](https://github.com/nwtgck/actions-netlify) from
2.0 to 3.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/nwtgck/actions-netlify/releases">nwtgck/actions-netlify's
releases</a>.</em></p>
<blockquote>
<h2>v3.0.0</h2>
<h3>Changed</h3>
<ul>
<li>Update dependencies</li>
<li>Updates the default runtime to node20</li>
</ul>
<h2>v2.1.0</h2>
<h3>Changed</h3>
<ul>
<li>Update dependencies</li>
</ul>
<h3>Added</h3>
<ul>
<li>Add &quot;enable-github-deployment&quot; input <a
href="https://redirect.github.com/nwtgck/actions-netlify/pull/901">#901</a>
by <a href="https://github.com/a-tokyo"><code>@​a-tokyo</code></a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/nwtgck/actions-netlify/blob/develop/CHANGELOG.md">nwtgck/actions-netlify's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<p>All notable changes to this project will be documented in this
file.</p>
<p>The format is based on <a
href="https://keepachangelog.com/en/1.0.0/">Keep a Changelog</a></p>
<h2>[Unreleased]</h2>
<h2>[3.0.0] - 2024-03-10</h2>
<h3>Changed</h3>
<ul>
<li>Update dependencies</li>
<li>Updates the default runtime to node20</li>
</ul>
<h2>[2.1.0] - 2023-08-18</h2>
<h3>Changed</h3>
<ul>
<li>Update dependencies</li>
</ul>
<h3>Added</h3>
<ul>
<li>Add &quot;enable-github-deployment&quot; input <a
href="https://redirect.github.com/nwtgck/actions-netlify/pull/901">#901</a>
by <a href="https://github.com/a-tokyo"><code>@​a-tokyo</code></a></li>
</ul>
<h2>[2.0.0] - 2022-12-08</h2>
<h3>Changed</h3>
<ul>
<li>Update dependencies</li>
<li>Updates the default runtime to node16</li>
</ul>
<h2>[1.2.4] - 2022-10-14</h2>
<h3>Changed</h3>
<ul>
<li>Update dependencies</li>
</ul>
<h2>[1.2.3] - 2021-12-20</h2>
<h3>Changed</h3>
<ul>
<li>Update dependencies</li>
</ul>
<h2>[1.2.2] - 2021-05-08</h2>
<h3>Fixed</h3>
<ul>
<li>Fix GitHub deployment description</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Update dependencies</li>
</ul>
<h2>[1.2.1] - 2021-05-05</h2>
<h3>Added</h3>
<ul>
<li>Add &quot;fails-without-credentials&quot; input to fail if the
credentials not provided <a
href="https://redirect.github.com/nwtgck/actions-netlify/pull/532">#532</a></li>
</ul>
<h3>Changed</h3>
<ul>
<li>Update dependencies</li>
</ul>
<h2>[1.2.0] - 2021-04-29</h2>
<h3>Changed</h3>
<ul>
<li>Update dependencies</li>
<li>(breaking change for <code>overwrites-pull-request-comment:
true</code>): Support multiple app deploys in a single PR <a
href="https://redirect.github.com/nwtgck/actions-netlify/pull/484">#484</a>
by <a
href="https://github.com/kaisermann"><code>@​kaisermann</code></a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="4cbaf4c08f"><code>4cbaf4c</code></a>
Merge branch 'release/3.0.0'</li>
<li><a
href="6b45669baf"><code>6b45669</code></a>
bump: 3.0.0</li>
<li><a
href="8d5d80bf73"><code>8d5d80b</code></a>
Merge pull request <a
href="https://redirect.github.com/nwtgck/actions-netlify/issues/1151">#1151</a>
from nwtgck/actions-build/nwtgck-dependabot/npm_and_...</li>
<li><a
href="85c2e8e35a"><code>85c2e8e</code></a>
build</li>
<li><a
href="ea3c314fcd"><code>ea3c314</code></a>
Build(deps): bump <code>@​actions/github</code> from 5.1.1 to 6.0.0</li>
<li><a
href="333815eadd"><code>333815e</code></a>
updates the default runtime to node20</li>
<li><a
href="06de7de77b"><code>06de7de</code></a>
Build(deps-dev): bump <code>@​vercel/ncc</code> from 0.36.1 to 0.38.1
(<a
href="https://redirect.github.com/nwtgck/actions-netlify/issues/1121">#1121</a>)</li>
<li><a
href="a7f64ad4e2"><code>a7f64ad</code></a>
deps: update</li>
<li><a
href="fee801f039"><code>fee801f</code></a>
Build(deps): bump actions/setup-node from 3 to 4 (<a
href="https://redirect.github.com/nwtgck/actions-netlify/issues/1124">#1124</a>)</li>
<li><a
href="e4998d22a0"><code>e4998d2</code></a>
README.md, sample workflow: bump to latest action versions (<a
href="https://redirect.github.com/nwtgck/actions-netlify/issues/1149">#1149</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/nwtgck/actions-netlify/compare/v2.0...v3.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=nwtgck/actions-netlify&package-manager=github_actions&previous-version=2.0&new-version=3.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-05 09:38:06 +00:00
Sebastian Ullrich
75602f7c29 chore: CI: adjust Dependabot prefix 2024-11-05 10:31:37 +01:00
Sebastian Ullrich
0fd90c1283 chore: CI: check for GitHub Actions updates once per month (#5954) 2024-11-05 10:20:23 +01:00
Kim Morrison
128b049904 feat: relate Array.eraseIdx with List.eraseIdx (#5952) 2024-11-05 06:13:29 +00:00
Kim Morrison
0e3f26e6df feat: relate Array.takeWhile with List.takeWhile (#5950) 2024-11-05 05:05:53 +00:00
Kim Morrison
1148e6e142 chore: remove @[simp] from BitVec.ofFin_sub and sub_ofFin (#5951)
Unused, and hurts confluence.
2024-11-05 04:56:21 +00:00
Violeta Hernández
02baaa42ff feat: add Option.or_some' (#5926)
`o.or (some a) = o.getD a`.

As discussed on
[Zulip](https://leanprover.zulipchat.com/#narrow/channel/217875-Is-there-code-for-X.3F/topic/a.2Eor.20.28some.20b.29.20.3D.20a.2EgetD.20b/near/472785093).
2024-11-05 01:39:02 +00:00
Violeta Hernández
e573676db1 feat: List.pmap_eq_self (#5927)
This is a `pmap` analog of
[`List.map_id''`](https://leanprover-community.github.io/mathlib4_docs/Init/Data/List/Lemmas.html#List.map_id'').

As discussed on
[Zulip](https://leanprover.zulipchat.com/#narrow/channel/217875-Is-there-code-for-X.3F/topic/.60pmap_eq_self.60/near/472496933).
2024-11-05 01:38:13 +00:00
Kim Morrison
4dab6a108c chore: port release notes for v4.13.0 to master (#5947) 2024-11-05 01:34:52 +00:00
Kyle Miller
a4d521cf96 fix: make all_goals admit goals on failure (#5934)
New behavior: when in recovery mode, if any tactic fails in `all_goals`
then the metacontext is restored and all goals are admitted.

Without this, it can leave partially-solved metavariables and incomplete
goal lists.
2024-11-04 21:12:59 +00:00
Mac Malone
99070bf304 feat: update toolchain on lake update (#5684)
Lake will now update a package's `lean-toolchain` file on `lake update`
if it finds the package's direct dependencies use a newer compatible
toolchain. To skip this step, use the `--keep-toolchain` CLI option.

Closes #2582. Closes #2752. Closes #5615.

### Toolchain update details

To determine "newest compatible" toolchain, Lake parses the toolchain
listed in the packages' `lean-toolchain` files into four categories:
release , nightly, PR, and other. For newness, release toolchains are
compared by semantic version (e.g., `"v4.4.0" < "v4.8.0"` and
`"v4.6.0-rc1" < "v4.6.0"`) and nightlies are compared by date (e.g.,
`"nightly-2024-01-10" < "nightly-2014-10-01"`). All other toolchain
types and mixtures are incompatible. If there is not a single newest
toolchain, Lake will print a warning and continue updating without
changing the toolchain.

If Lake does find a new toolchain, Lake updates the workspace's
`lean-toolchain` file accordingly and restarts the update process on the
new Lake. If Elan is detected, it will spawn the new Lake process via
`elan run` with the same arguments Lake was initially run with. If Elan
is missing, it will prompt the user to restart Lake manually and exit
with a special error code (4).

### Other changes

To implement this new logic, various other refactors were needed. Here
are some key highlights:

* Logs emitted during package and workspace loading are now eagerly
printed.
* The Elan executable used by Lake is now configurable by the `ELAN`
environment variable.
* The `--lean` CLI option was removed. Use the `LEAN` environment
variable instead.
* `Package.deps` / `Package.opaqueDeps` have been removed. Use
`findPackage?` with a dependency's name instead.
* The dependency resolver now uses a pure breadth-first traversal to
resolve dependencies. It also resolves dependencies in reverse order,
which is done for consistency with targets. Latter targets shadow
earlier ones and latter dependencies take precedence over earlier ones.
**These changes mean the order of dependencies in a Lake manifest will
change after the first `lake update` on this version of Lake.**
2024-11-04 14:31:40 +00:00
Henrik Böving
93dd6f2b36 feat: add Int16/Int32/Int64 (#5885)
This adds all fixed width integers with the exception of `ssize_t` so
the code is quick to review as everything just behaves the same.
2024-11-04 13:18:05 +00:00
Henrik Böving
c61ced3f15 feat: introduce synthetic atoms in bv_decide (#5942)
This introduces a notion of synthetic atoms into `bv_decide`'s
reflection framework. An atom can be declared synthetic if its behavior
is fully specified by additional lemmas that are added in the process of
creating it. This is for example useful in the code that handles `if` as
the entire `if` block is abstracted as an atom and then two lemmas to
describe either branch are added. Previously this had the effect of
creating error messages about potentially unsound counterexamples, now
the synthetic atoms get filtered from the counter example generation.
2024-11-04 10:14:51 +00:00
112 changed files with 4429 additions and 608 deletions

8
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,8 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
commit-message:
prefix: "chore: CI"

View File

@@ -17,6 +17,6 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
- name: actionlint
uses: raven-actions/actionlint@v1
uses: raven-actions/actionlint@v2
with:
pyflakes: false # we do not use python scripts

View File

@@ -318,7 +318,7 @@ jobs:
if: github.event_name == 'pull_request'
# (needs to be after "Checkout" so files don't get overridden)
- name: Setup emsdk
uses: mymindstorm/setup-emsdk@v12
uses: mymindstorm/setup-emsdk@v14
with:
version: 3.1.44
actions-cache-folder: emsdk
@@ -415,7 +415,11 @@ jobs:
- name: Test
id: test
run: |
time ctest --preset ${{ matrix.CMAKE_PRESET || 'release' }} --test-dir build/stage1 -j$NPROC --output-junit test-results.xml ${{ matrix.CTEST_OPTIONS }}
# give Linux debug unlimited stack, we're not interested in its specific stack usage
if [[ '${{ matrix.name }}' == 'Linux Debug' ]]; then
ulimit -s unlimited
fi
time ctest --preset ${{ matrix.CMAKE_PRESET || 'release' }} --test-dir build/stage1 -j$NPROC --output-junit test-results.xml ${{ matrix.CTEST_OPTIONS }} -E "leanruntest_task_test_io"
if: (matrix.wasm || !matrix.cross) && needs.configure.outputs.check-level >= 1
- name: Test Summary
uses: test-summary/action@v2
@@ -492,7 +496,7 @@ jobs:
with:
path: artifacts
- name: Release
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@v2
with:
files: artifacts/*/*
fail_on_unmatched_files: true
@@ -536,7 +540,7 @@ jobs:
echo -e "\n*Full commit log*\n" >> diff.md
git log --oneline "$last_tag"..HEAD | sed 's/^/* /' >> diff.md
- name: Release Nightly
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@v2
with:
body_path: diff.md
prerelease: true

View File

@@ -110,14 +110,6 @@ jobs:
# https://github.com/netlify/cli/issues/1809
cp -r --dereference ./result ./dist
if: matrix.name == 'Nix Linux'
- name: Check manual for broken links
id: lychee
uses: lycheeverse/lychee-action@v1.9.0
with:
fail: false # report errors but do not block CI on temporary failures
# gmplib.org consistently times out from GH actions
# the GitHub token is to avoid rate limiting
args: --base './dist' --no-progress --github-token ${{ secrets.GITHUB_TOKEN }} --exclude 'gmplib.org' './dist/**/*.html'
- name: Rebuild Nix Store Cache
run: |
rm -rf nix-store-cache || true
@@ -129,7 +121,7 @@ jobs:
python3 -c 'import base64; print("alias="+base64.urlsafe_b64encode(bytes.fromhex("${{github.sha}}")).decode("utf-8").rstrip("="))' >> "$GITHUB_OUTPUT"
echo "message=`git log -1 --pretty=format:"%s"`" >> "$GITHUB_OUTPUT"
- name: Publish manual to Netlify
uses: nwtgck/actions-netlify@v2.0
uses: nwtgck/actions-netlify@v3.0
id: publish-manual
with:
publish-dir: ./dist

View File

@@ -34,7 +34,7 @@ jobs:
- 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
uses: dawidd6/action-download-artifact@v6 # https://github.com/marketplace/actions/download-workflow-artifact
with:
run_id: ${{ github.event.workflow_run.id }}
path: artifacts
@@ -60,7 +60,7 @@ jobs:
GH_TOKEN: ${{ secrets.PR_RELEASES_TOKEN }}
- name: Release
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@v2
with:
name: Release for PR ${{ steps.workflow-info.outputs.pullRequestNumber }}
# There are coredumps files here as well, but all in deeper subdirectories.
@@ -75,7 +75,7 @@ jobs:
- name: Report release status
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
uses: actions/github-script@v6
uses: actions/github-script@v7
with:
script: |
await github.rest.repos.createCommitStatus({
@@ -111,7 +111,7 @@ jobs:
- name: 'Setup jq'
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
uses: dcarbone/install-jq-action@v1.0.1
uses: dcarbone/install-jq-action@v2.1.0
# Check that the most recently nightly coincides with 'git merge-base HEAD master'
- name: Check merge-base and nightly-testing-YYYY-MM-DD
@@ -208,7 +208,7 @@ jobs:
- name: Report mathlib base
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' && steps.ready.outputs.mathlib_ready == 'true' }}
uses: actions/github-script@v6
uses: actions/github-script@v7
with:
script: |
const description =

View File

@@ -11,7 +11,7 @@ jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v8
- uses: actions/stale@v9
with:
days-before-stale: -1
days-before-pr-stale: 30

View File

@@ -21,7 +21,315 @@ Release candidate, release notes will be copied from the branch `releases/v4.14.
v4.13.0
----------
Release candidate, release notes will be copied from the branch `releases/v4.13.0` once completed.
**Full Changelog**: https://github.com/leanprover/lean4/compare/v4.12.0...v4.13.0
### Language features, tactics, and metaprograms
* `structure` command
* [#5511](https://github.com/leanprover/lean4/pull/5511) allows structure parents to be type synonyms.
* [#5531](https://github.com/leanprover/lean4/pull/5531) allows default values for structure fields to be noncomputable.
* `rfl` and `apply_rfl` tactics
* [#3714](https://github.com/leanprover/lean4/pull/3714), [#3718](https://github.com/leanprover/lean4/pull/3718) improve the `rfl` tactic and give better error messages.
* [#3772](https://github.com/leanprover/lean4/pull/3772) makes `rfl` no longer use kernel defeq for ground terms.
* [#5329](https://github.com/leanprover/lean4/pull/5329) tags `Iff.refl` with `@[refl]` (@Parcly-Taxel)
* [#5359](https://github.com/leanprover/lean4/pull/5359) ensures that the `rfl` tactic tries `Iff.rfl` (@Parcly-Taxel)
* `unfold` tactic
* [#4834](https://github.com/leanprover/lean4/pull/4834) let `unfold` do zeta-delta reduction of local definitions, incorporating functionality of the Mathlib `unfold_let` tactic.
* `omega` tactic
* [#5382](https://github.com/leanprover/lean4/pull/5382) fixes spurious error in [#5315](https://github.com/leanprover/lean4/issues/5315)
* [#5523](https://github.com/leanprover/lean4/pull/5523) supports `Int.toNat`
* `simp` tactic
* [#5479](https://github.com/leanprover/lean4/pull/5479) lets `simp` apply rules with higher-order patterns.
* `induction` tactic
* [#5494](https://github.com/leanprover/lean4/pull/5494) fixes `induction`s "pre-tactic" block to always be indented, avoiding unintended uses of it.
* `ac_nf` tactic
* [#5524](https://github.com/leanprover/lean4/pull/5524) adds `ac_nf`, a counterpart to `ac_rfl`, for normalizing expressions with respect to associativity and commutativity. Tests it with `BitVec` expressions.
* `bv_decide`
* [#5211](https://github.com/leanprover/lean4/pull/5211) makes `extractLsb'` the primitive `bv_decide` understands, rather than `extractLsb` (@alexkeizer)
* [#5365](https://github.com/leanprover/lean4/pull/5365) adds `bv_decide` diagnoses.
* [#5375](https://github.com/leanprover/lean4/pull/5375) adds `bv_decide` normalization rules for `ofBool (a.getLsbD i)` and `ofBool a[i]` (@alexkeizer)
* [#5423](https://github.com/leanprover/lean4/pull/5423) enhances the rewriting rules of `bv_decide`
* [#5433](https://github.com/leanprover/lean4/pull/5433) presents the `bv_decide` counterexample at the API
* [#5484](https://github.com/leanprover/lean4/pull/5484) handles `BitVec.ofNat` with `Nat` fvars in `bv_decide`
* [#5506](https://github.com/leanprover/lean4/pull/5506), [#5507](https://github.com/leanprover/lean4/pull/5507) add `bv_normalize` rules.
* [#5568](https://github.com/leanprover/lean4/pull/5568) generalize the `bv_normalize` pipeline to support more general preprocessing passes
* [#5573](https://github.com/leanprover/lean4/pull/5573) gets `bv_normalize` up-to-date with the current `BitVec` rewrites
* Cleanups: [#5408](https://github.com/leanprover/lean4/pull/5408), [#5493](https://github.com/leanprover/lean4/pull/5493), [#5578](https://github.com/leanprover/lean4/pull/5578)
* Elaboration improvements
* [#5266](https://github.com/leanprover/lean4/pull/5266) preserve order of overapplied arguments in `elab_as_elim` procedure.
* [#5510](https://github.com/leanprover/lean4/pull/5510) generalizes `elab_as_elim` to allow arbitrary motive applications.
* [#5283](https://github.com/leanprover/lean4/pull/5283), [#5512](https://github.com/leanprover/lean4/pull/5512) refine how named arguments suppress explicit arguments. Breaking change: some previously omitted explicit arguments may need explicit `_` arguments now.
* [#5376](https://github.com/leanprover/lean4/pull/5376) modifies projection instance binder info for instances, making parameters that are instance implicit in the type be implicit.
* [#5402](https://github.com/leanprover/lean4/pull/5402) localizes universe metavariable errors to `let` bindings and `fun` binders if possible. Makes "cannot synthesize metavariable" errors take precedence over unsolved universe level errors.
* [#5419](https://github.com/leanprover/lean4/pull/5419) must not reduce `ite` in the discriminant of `match`-expression when reducibility setting is `.reducible`
* [#5474](https://github.com/leanprover/lean4/pull/5474) have autoparams report parameter/field on failure
* [#5530](https://github.com/leanprover/lean4/pull/5530) makes automatic instance names about types with hygienic names be hygienic.
* Deriving handlers
* [#5432](https://github.com/leanprover/lean4/pull/5432) makes `Repr` deriving instance handle explicit type parameters
* Functional induction
* [#5364](https://github.com/leanprover/lean4/pull/5364) adds more equalities in context, more careful cleanup.
* Linters
* [#5335](https://github.com/leanprover/lean4/pull/5335) fixes the unused variables linter complaining about match/tactic combinations
* [#5337](https://github.com/leanprover/lean4/pull/5337) fixes the unused variables linter complaining about some wildcard patterns
* Other fixes
* [#4768](https://github.com/leanprover/lean4/pull/4768) fixes a parse error when `..` appears with a `.` on the next line
* Metaprogramming
* [#3090](https://github.com/leanprover/lean4/pull/3090) handles level parameters in `Meta.evalExpr` (@eric-wieser)
* [#5401](https://github.com/leanprover/lean4/pull/5401) instance for `Inhabited (TacticM α)` (@alexkeizer)
* [#5412](https://github.com/leanprover/lean4/pull/5412) expose Kernel.check for debugging purposes
* [#5556](https://github.com/leanprover/lean4/pull/5556) improves the "invalid projection" type inference error in `inferType`.
* [#5587](https://github.com/leanprover/lean4/pull/5587) allows `MVarId.assertHypotheses` to set `BinderInfo` and `LocalDeclKind`.
* [#5588](https://github.com/leanprover/lean4/pull/5588) adds `MVarId.tryClearMany'`, a variant of `MVarId.tryClearMany`.
### Language server, widgets, and IDE extensions
* [#5205](https://github.com/leanprover/lean4/pull/5205) decreases the latency of auto-completion in tactic blocks.
* [#5237](https://github.com/leanprover/lean4/pull/5237) fixes symbol occurrence highlighting in VS Code not highlighting occurrences when moving the text cursor into the identifier from the right.
* [#5257](https://github.com/leanprover/lean4/pull/5257) fixes several instances of incorrect auto-completions being reported.
* [#5299](https://github.com/leanprover/lean4/pull/5299) allows auto-completion to report completions for global identifiers when the elaborator fails to provide context-specific auto-completions.
* [#5312](https://github.com/leanprover/lean4/pull/5312) fixes the server breaking when changing whitespace after the module header.
* [#5322](https://github.com/leanprover/lean4/pull/5322) fixes several instances of auto-completion reporting non-existent namespaces.
* [#5428](https://github.com/leanprover/lean4/pull/5428) makes sure to always report some recent file range as progress when waiting for elaboration.
### Pretty printing
* [#4979](https://github.com/leanprover/lean4/pull/4979) make pretty printer escape identifiers that are tokens.
* [#5389](https://github.com/leanprover/lean4/pull/5389) makes formatter use the current token table.
* [#5513](https://github.com/leanprover/lean4/pull/5513) use breakable instead of unbreakable whitespace when formatting tokens.
### Library
* [#5222](https://github.com/leanprover/lean4/pull/5222) reduces allocations in `Json.compress`.
* [#5231](https://github.com/leanprover/lean4/pull/5231) upstreams `Zero` and `NeZero`
* [#5292](https://github.com/leanprover/lean4/pull/5292) refactors `Lean.Elab.Deriving.FromToJson` (@arthur-adjedj)
* [#5415](https://github.com/leanprover/lean4/pull/5415) implements `Repr Empty` (@TomasPuverle)
* [#5421](https://github.com/leanprover/lean4/pull/5421) implements `To/FromJSON Empty` (@TomasPuverle)
* Logic
* [#5263](https://github.com/leanprover/lean4/pull/5263) allows simplifying `dite_not`/`decide_not` with only `Decidable (¬p)`.
* [#5268](https://github.com/leanprover/lean4/pull/5268) fixes binders on `ite_eq_left_iff`
* [#5284](https://github.com/leanprover/lean4/pull/5284) turns off `Inhabited (Sum α β)` instances
* [#5355](https://github.com/leanprover/lean4/pull/5355) adds simp lemmas for `LawfulBEq`
* [#5374](https://github.com/leanprover/lean4/pull/5374) add `Nonempty` instances for products, allowing more `partial` functions to elaborate successfully
* [#5447](https://github.com/leanprover/lean4/pull/5447) updates Pi instance names
* [#5454](https://github.com/leanprover/lean4/pull/5454) makes some instance arguments implicit
* [#5456](https://github.com/leanprover/lean4/pull/5456) adds `heq_comm`
* [#5529](https://github.com/leanprover/lean4/pull/5529) moves `@[simp]` from `exists_prop'` to `exists_prop`
* `Bool`
* [#5228](https://github.com/leanprover/lean4/pull/5228) fills gaps in Bool lemmas
* [#5332](https://github.com/leanprover/lean4/pull/5332) adds notation `^^` for Bool.xor
* [#5351](https://github.com/leanprover/lean4/pull/5351) removes `_root_.and` (and or/not/xor) and instead exports/uses `Bool.and` (etc.).
* `BitVec`
* [#5240](https://github.com/leanprover/lean4/pull/5240) removes BitVec simps with complicated RHS
* [#5247](https://github.com/leanprover/lean4/pull/5247) `BitVec.getElem_zeroExtend`
* [#5248](https://github.com/leanprover/lean4/pull/5248) simp lemmas for BitVec, improving confluence
* [#5249](https://github.com/leanprover/lean4/pull/5249) removes `@[simp]` from some BitVec lemmas
* [#5252](https://github.com/leanprover/lean4/pull/5252) changes `BitVec.intMin/Max` from abbrev to def
* [#5278](https://github.com/leanprover/lean4/pull/5278) adds `BitVec.getElem_truncate` (@tobiasgrosser)
* [#5281](https://github.com/leanprover/lean4/pull/5281) adds udiv/umod bitblasting for `bv_decide` (@bollu)
* [#5297](https://github.com/leanprover/lean4/pull/5297) `BitVec` unsigned order theoretic results
* [#5313](https://github.com/leanprover/lean4/pull/5313) adds more basic BitVec ordering theory for UInt
* [#5314](https://github.com/leanprover/lean4/pull/5314) adds `toNat_sub_of_le` (@bollu)
* [#5357](https://github.com/leanprover/lean4/pull/5357) adds `BitVec.truncate` lemmas
* [#5358](https://github.com/leanprover/lean4/pull/5358) introduces `BitVec.setWidth` to unify zeroExtend and truncate (@tobiasgrosser)
* [#5361](https://github.com/leanprover/lean4/pull/5361) some BitVec GetElem lemmas
* [#5385](https://github.com/leanprover/lean4/pull/5385) adds `BitVec.ofBool_[and|or|xor]_ofBool` theorems (@tobiasgrosser)
* [#5404](https://github.com/leanprover/lean4/pull/5404) more of `BitVec.getElem_*` (@tobiasgrosser)
* [#5410](https://github.com/leanprover/lean4/pull/5410) BitVec analogues of `Nat.{mul_two, two_mul, mul_succ, succ_mul}` (@bollu)
* [#5411](https://github.com/leanprover/lean4/pull/5411) `BitVec.toNat_{add,sub,mul_of_lt}` for BitVector non-overflow reasoning (@bollu)
* [#5413](https://github.com/leanprover/lean4/pull/5413) adds `_self`, `_zero`, and `_allOnes` for `BitVec.[and|or|xor]` (@tobiasgrosser)
* [#5416](https://github.com/leanprover/lean4/pull/5416) adds LawCommIdentity + IdempotentOp for `BitVec.[and|or|xor]` (@tobiasgrosser)
* [#5418](https://github.com/leanprover/lean4/pull/5418) decidable quantifers for BitVec
* [#5450](https://github.com/leanprover/lean4/pull/5450) adds `BitVec.toInt_[intMin|neg|neg_of_ne_intMin]` (@tobiasgrosser)
* [#5459](https://github.com/leanprover/lean4/pull/5459) missing BitVec lemmas
* [#5469](https://github.com/leanprover/lean4/pull/5469) adds `BitVec.[not_not, allOnes_shiftLeft_or_shiftLeft, allOnes_shiftLeft_and_shiftLeft]` (@luisacicolini)
* [#5478](https://github.com/leanprover/lean4/pull/5478) adds `BitVec.(shiftLeft_add_distrib, shiftLeft_ushiftRight)` (@luisacicolini)
* [#5487](https://github.com/leanprover/lean4/pull/5487) adds `sdiv_eq`, `smod_eq` to allow `sdiv`/`smod` bitblasting (@bollu)
* [#5491](https://github.com/leanprover/lean4/pull/5491) adds `BitVec.toNat_[abs|sdiv|smod]` (@tobiasgrosser)
* [#5492](https://github.com/leanprover/lean4/pull/5492) `BitVec.(not_sshiftRight, not_sshiftRight_not, getMsb_not, msb_not)` (@luisacicolini)
* [#5499](https://github.com/leanprover/lean4/pull/5499) `BitVec.Lemmas` - drop non-terminal simps (@tobiasgrosser)
* [#5505](https://github.com/leanprover/lean4/pull/5505) unsimps `BitVec.divRec_succ'`
* [#5508](https://github.com/leanprover/lean4/pull/5508) adds `BitVec.getElem_[add|add_add_bool|mul|rotateLeft|rotateRight…` (@tobiasgrosser)
* [#5554](https://github.com/leanprover/lean4/pull/5554) adds `Bitvec.[add, sub, mul]_eq_xor` and `width_one_cases` (@luisacicolini)
* `List`
* [#5242](https://github.com/leanprover/lean4/pull/5242) improve naming for `List.mergeSort` lemmas
* [#5302](https://github.com/leanprover/lean4/pull/5302) provide `mergeSort` comparator autoParam
* [#5373](https://github.com/leanprover/lean4/pull/5373) fix name of `List.length_mergeSort`
* [#5377](https://github.com/leanprover/lean4/pull/5377) upstream `map_mergeSort`
* [#5378](https://github.com/leanprover/lean4/pull/5378) modify signature of lemmas about `mergeSort`
* [#5245](https://github.com/leanprover/lean4/pull/5245) avoid importing `List.Basic` without List.Impl
* [#5260](https://github.com/leanprover/lean4/pull/5260) review of List API
* [#5264](https://github.com/leanprover/lean4/pull/5264) review of List API
* [#5269](https://github.com/leanprover/lean4/pull/5269) remove HashMap's duplicated Pairwise and Sublist
* [#5271](https://github.com/leanprover/lean4/pull/5271) remove @[simp] from `List.head_mem` and similar
* [#5273](https://github.com/leanprover/lean4/pull/5273) lemmas about `List.attach`
* [#5275](https://github.com/leanprover/lean4/pull/5275) reverse direction of `List.tail_map`
* [#5277](https://github.com/leanprover/lean4/pull/5277) more `List.attach` lemmas
* [#5285](https://github.com/leanprover/lean4/pull/5285) `List.count` lemmas
* [#5287](https://github.com/leanprover/lean4/pull/5287) use boolean predicates in `List.filter`
* [#5289](https://github.com/leanprover/lean4/pull/5289) `List.mem_ite_nil_left` and analogues
* [#5293](https://github.com/leanprover/lean4/pull/5293) cleanup of `List.findIdx` / `List.take` lemmas
* [#5294](https://github.com/leanprover/lean4/pull/5294) switch primes on `List.getElem_take`
* [#5300](https://github.com/leanprover/lean4/pull/5300) more `List.findIdx` theorems
* [#5310](https://github.com/leanprover/lean4/pull/5310) fix `List.all/any` lemmas
* [#5311](https://github.com/leanprover/lean4/pull/5311) fix `List.countP` lemmas
* [#5316](https://github.com/leanprover/lean4/pull/5316) `List.tail` lemma
* [#5331](https://github.com/leanprover/lean4/pull/5331) fix implicitness of `List.getElem_mem`
* [#5350](https://github.com/leanprover/lean4/pull/5350) `List.replicate` lemmas
* [#5352](https://github.com/leanprover/lean4/pull/5352) `List.attachWith` lemmas
* [#5353](https://github.com/leanprover/lean4/pull/5353) `List.head_mem_head?`
* [#5360](https://github.com/leanprover/lean4/pull/5360) lemmas about `List.tail`
* [#5391](https://github.com/leanprover/lean4/pull/5391) review of `List.erase` / `List.find` lemmas
* [#5392](https://github.com/leanprover/lean4/pull/5392) `List.fold` / `attach` lemmas
* [#5393](https://github.com/leanprover/lean4/pull/5393) `List.fold` relators
* [#5394](https://github.com/leanprover/lean4/pull/5394) lemmas about `List.maximum?`
* [#5403](https://github.com/leanprover/lean4/pull/5403) theorems about `List.toArray`
* [#5405](https://github.com/leanprover/lean4/pull/5405) reverse direction of `List.set_map`
* [#5448](https://github.com/leanprover/lean4/pull/5448) add lemmas about `List.IsPrefix` (@Command-Master)
* [#5460](https://github.com/leanprover/lean4/pull/5460) missing `List.set_replicate_self`
* [#5518](https://github.com/leanprover/lean4/pull/5518) rename `List.maximum?` to `max?`
* [#5519](https://github.com/leanprover/lean4/pull/5519) upstream `List.fold` lemmas
* [#5520](https://github.com/leanprover/lean4/pull/5520) restore `@[simp]` on `List.getElem_mem` etc.
* [#5521](https://github.com/leanprover/lean4/pull/5521) List simp fixes
* [#5550](https://github.com/leanprover/lean4/pull/5550) `List.unattach` and simp lemmas
* [#5594](https://github.com/leanprover/lean4/pull/5594) induction-friendly `List.min?_cons`
* `Array`
* [#5246](https://github.com/leanprover/lean4/pull/5246) cleanup imports of Array.Lemmas
* [#5255](https://github.com/leanprover/lean4/pull/5255) split Init.Data.Array.Lemmas for better bootstrapping
* [#5288](https://github.com/leanprover/lean4/pull/5288) rename `Array.data` to `Array.toList`
* [#5303](https://github.com/leanprover/lean4/pull/5303) cleanup of `List.getElem_append` variants
* [#5304](https://github.com/leanprover/lean4/pull/5304) `Array.not_mem_empty`
* [#5400](https://github.com/leanprover/lean4/pull/5400) reorganization in Array/Basic
* [#5420](https://github.com/leanprover/lean4/pull/5420) make `Array` functions either semireducible or use structural recursion
* [#5422](https://github.com/leanprover/lean4/pull/5422) refactor `DecidableEq (Array α)`
* [#5452](https://github.com/leanprover/lean4/pull/5452) refactor of Array
* [#5458](https://github.com/leanprover/lean4/pull/5458) cleanup of Array docstrings after refactor
* [#5461](https://github.com/leanprover/lean4/pull/5461) restore `@[simp]` on `Array.swapAt!_def`
* [#5465](https://github.com/leanprover/lean4/pull/5465) improve Array GetElem lemmas
* [#5466](https://github.com/leanprover/lean4/pull/5466) `Array.foldX` lemmas
* [#5472](https://github.com/leanprover/lean4/pull/5472) @[simp] lemmas about `List.toArray`
* [#5485](https://github.com/leanprover/lean4/pull/5485) reverse simp direction for `toArray_concat`
* [#5514](https://github.com/leanprover/lean4/pull/5514) `Array.eraseReps`
* [#5515](https://github.com/leanprover/lean4/pull/5515) upstream `Array.qsortOrd`
* [#5516](https://github.com/leanprover/lean4/pull/5516) upstream `Subarray.empty`
* [#5526](https://github.com/leanprover/lean4/pull/5526) fix name of `Array.length_toList`
* [#5527](https://github.com/leanprover/lean4/pull/5527) reduce use of deprecated lemmas in Array
* [#5534](https://github.com/leanprover/lean4/pull/5534) cleanup of Array GetElem lemmas
* [#5536](https://github.com/leanprover/lean4/pull/5536) fix `Array.modify` lemmas
* [#5551](https://github.com/leanprover/lean4/pull/5551) upstream `Array.flatten` lemmas
* [#5552](https://github.com/leanprover/lean4/pull/5552) switch obvious cases of array "bang"`[]!` indexing to rely on hypothesis (@TomasPuverle)
* [#5577](https://github.com/leanprover/lean4/pull/5577) add missing simp to `Array.size_feraseIdx`
* [#5586](https://github.com/leanprover/lean4/pull/5586) `Array/Option.unattach`
* `Option`
* [#5272](https://github.com/leanprover/lean4/pull/5272) remove @[simp] from `Option.pmap/pbind` and add simp lemmas
* [#5307](https://github.com/leanprover/lean4/pull/5307) restoring Option simp confluence
* [#5354](https://github.com/leanprover/lean4/pull/5354) remove @[simp] from `Option.bind_map`
* [#5532](https://github.com/leanprover/lean4/pull/5532) `Option.attach`
* [#5539](https://github.com/leanprover/lean4/pull/5539) fix explicitness of `Option.mem_toList`
* `Nat`
* [#5241](https://github.com/leanprover/lean4/pull/5241) add @[simp] to `Nat.add_eq_zero_iff`
* [#5261](https://github.com/leanprover/lean4/pull/5261) Nat bitwise lemmas
* [#5262](https://github.com/leanprover/lean4/pull/5262) `Nat.testBit_add_one` should not be a global simp lemma
* [#5267](https://github.com/leanprover/lean4/pull/5267) protect some Nat bitwise theorems
* [#5305](https://github.com/leanprover/lean4/pull/5305) rename Nat bitwise lemmas
* [#5306](https://github.com/leanprover/lean4/pull/5306) add `Nat.self_sub_mod` lemma
* [#5503](https://github.com/leanprover/lean4/pull/5503) restore @[simp] to upstreamed `Nat.lt_off_iff`
* `Int`
* [#5301](https://github.com/leanprover/lean4/pull/5301) rename `Int.div/mod` to `Int.tdiv/tmod`
* [#5320](https://github.com/leanprover/lean4/pull/5320) add `ediv_nonneg_of_nonpos_of_nonpos` to DivModLemmas (@sakehl)
* `Fin`
* [#5250](https://github.com/leanprover/lean4/pull/5250) missing lemma about `Fin.ofNat'`
* [#5356](https://github.com/leanprover/lean4/pull/5356) `Fin.ofNat'` uses `NeZero`
* [#5379](https://github.com/leanprover/lean4/pull/5379) remove some @[simp]s from Fin lemmas
* [#5380](https://github.com/leanprover/lean4/pull/5380) missing Fin @[simp] lemmas
* `HashMap`
* [#5244](https://github.com/leanprover/lean4/pull/5244) (`DHashMap`|`HashMap`|`HashSet`).(`getKey?`|`getKey`|`getKey!`|`getKeyD`)
* [#5362](https://github.com/leanprover/lean4/pull/5362) remove the last use of `Lean.(HashSet|HashMap)`
* [#5369](https://github.com/leanprover/lean4/pull/5369) `HashSet.ofArray`
* [#5370](https://github.com/leanprover/lean4/pull/5370) `HashSet.partition`
* [#5581](https://github.com/leanprover/lean4/pull/5581) `Singleton`/`Insert`/`Union` instances for `HashMap`/`Set`
* [#5582](https://github.com/leanprover/lean4/pull/5582) `HashSet.all`/`any`
* [#5590](https://github.com/leanprover/lean4/pull/5590) adding `Insert`/`Singleton`/`Union` instances for `HashMap`/`Set.Raw`
* [#5591](https://github.com/leanprover/lean4/pull/5591) `HashSet.Raw.all/any`
* `Monads`
* [#5463](https://github.com/leanprover/lean4/pull/5463) upstream some monad lemmas
* [#5464](https://github.com/leanprover/lean4/pull/5464) adjust simp attributes on monad lemmas
* [#5522](https://github.com/leanprover/lean4/pull/5522) more monadic simp lemmas
* Simp lemma cleanup
* [#5251](https://github.com/leanprover/lean4/pull/5251) remove redundant simp annotations
* [#5253](https://github.com/leanprover/lean4/pull/5253) remove Int simp lemmas that can't fire
* [#5254](https://github.com/leanprover/lean4/pull/5254) variables appearing on both sides of an iff should be implicit
* [#5381](https://github.com/leanprover/lean4/pull/5381) cleaning up redundant simp lemmas
### Compiler, runtime, and FFI
* [#4685](https://github.com/leanprover/lean4/pull/4685) fixes a typo in the C `run_new_frontend` signature
* [#4729](https://github.com/leanprover/lean4/pull/4729) has IR checker suggest using `noncomputable`
* [#5143](https://github.com/leanprover/lean4/pull/5143) adds a shared library for Lake
* [#5437](https://github.com/leanprover/lean4/pull/5437) removes (syntactically) duplicate imports (@euprunin)
* [#5462](https://github.com/leanprover/lean4/pull/5462) updates `src/lake/lakefile.toml` to the adjusted Lake build process
* [#5541](https://github.com/leanprover/lean4/pull/5541) removes new shared libs before build to better support Windows
* [#5558](https://github.com/leanprover/lean4/pull/5558) make `lean.h` compile with MSVC (@kant2002)
* [#5564](https://github.com/leanprover/lean4/pull/5564) removes non-conforming size-0 arrays (@eric-wieser)
### Lake
* Reservoir build cache. Lake will now attempt to fetch a pre-built copy of the package from Reservoir before building it. This is only enabled for packages in the leanprover or leanprover-community organizations on versions indexed by Reservoir. Users can force Lake to build packages from the source by passing --no-cache on the CLI or by setting the LAKE_NO_CACHE environment variable to true. [#5486](https://github.com/leanprover/lean4/pull/5486), [#5572](https://github.com/leanprover/lean4/pull/5572), [#5583](https://github.com/leanprover/lean4/pull/5583), [#5600](https://github.com/leanprover/lean4/pull/5600), [#5641](https://github.com/leanprover/lean4/pull/5641), [#5642](https://github.com/leanprover/lean4/pull/5642).
* [#5504](https://github.com/leanprover/lean4/pull/5504) lake new and lake init now produce TOML configurations by default.
* [#5878](https://github.com/leanprover/lean4/pull/5878) fixes a serious issue where Lake would delete path dependencies when attempting to cleanup a dependency required with an incorrect name.
* **Breaking changes**
* [#5641](https://github.com/leanprover/lean4/pull/5641) A Lake build of target within a package will no longer build a package's dependencies package-level extra target dependencies. At the technical level, a package's extraDep facet no longer transitively builds its dependencies extraDep facets (which include their extraDepTargets).
### Documentation fixes
* [#3918](https://github.com/leanprover/lean4/pull/3918) `@[builtin_doc]` attribute (@digama0)
* [#4305](https://github.com/leanprover/lean4/pull/4305) explains the borrow syntax (@eric-wieser)
* [#5349](https://github.com/leanprover/lean4/pull/5349) adds documentation for `groupBy.loop` (@vihdzp)
* [#5473](https://github.com/leanprover/lean4/pull/5473) fixes typo in `BitVec.mul` docstring (@llllvvuu)
* [#5476](https://github.com/leanprover/lean4/pull/5476) fixes typos in `Lean.MetavarContext`
* [#5481](https://github.com/leanprover/lean4/pull/5481) removes mention of `Lean.withSeconds` (@alexkeizer)
* [#5497](https://github.com/leanprover/lean4/pull/5497) updates documentation and tests for `toUIntX` functions (@TomasPuverle)
* [#5087](https://github.com/leanprover/lean4/pull/5087) mentions that `inferType` does not ensure type correctness
* Many fixes to spelling across the doc-strings, (@euprunin): [#5425](https://github.com/leanprover/lean4/pull/5425) [#5426](https://github.com/leanprover/lean4/pull/5426) [#5427](https://github.com/leanprover/lean4/pull/5427) [#5430](https://github.com/leanprover/lean4/pull/5430) [#5431](https://github.com/leanprover/lean4/pull/5431) [#5434](https://github.com/leanprover/lean4/pull/5434) [#5435](https://github.com/leanprover/lean4/pull/5435) [#5436](https://github.com/leanprover/lean4/pull/5436) [#5438](https://github.com/leanprover/lean4/pull/5438) [#5439](https://github.com/leanprover/lean4/pull/5439) [#5440](https://github.com/leanprover/lean4/pull/5440) [#5599](https://github.com/leanprover/lean4/pull/5599)
### Changes to CI
* [#5343](https://github.com/leanprover/lean4/pull/5343) allows addition of `release-ci` label via comment (@thorimur)
* [#5344](https://github.com/leanprover/lean4/pull/5344) sets check level correctly during workflow (@thorimur)
* [#5444](https://github.com/leanprover/lean4/pull/5444) Mathlib's `lean-pr-testing-NNNN` branches should use Batteries' `lean-pr-testing-NNNN` branches
* [#5489](https://github.com/leanprover/lean4/pull/5489) commit `lake-manifest.json` when updating `lean-pr-testing` branches
* [#5490](https://github.com/leanprover/lean4/pull/5490) use separate secrets for commenting and branching in `pr-release.yml`
v4.12.0
----------

View File

@@ -1,6 +1,6 @@
These are instructions to set up a working development environment for those who wish to make changes to Lean itself. It is part of the [Development Guide](doc/dev/index.md).
These are instructions to set up a working development environment for those who wish to make changes to Lean itself. It is part of the [Development Guide](../dev/index.md).
We strongly suggest that new users instead follow the [Quickstart](doc/quickstart.md) to get started using Lean, since this sets up an environment that can automatically manage multiple Lean toolchain versions, which is necessary when working within the Lean ecosystem.
We strongly suggest that new users instead follow the [Quickstart](../quickstart.md) to get started using Lean, since this sets up an environment that can automatically manage multiple Lean toolchain versions, which is necessary when working within the Lean ecosystem.
Requirements
------------

View File

@@ -64,7 +64,7 @@ fi
# use `-nostdinc` to make sure headers are not visible by default (in particular, not to `#include_next` in the clang headers),
# but do not change sysroot so users can still link against system libs
echo -n " -DLEANC_INTERNAL_FLAGS='-nostdinc -isystem ROOT/include/clang' -DLEANC_CC=ROOT/bin/clang"
echo -n " -DLEANC_INTERNAL_LINKER_FLAGS='-L ROOT/lib -L ROOT/lib/glibc ROOT/lib/glibc/libc_nonshared.a ROOT/lib/glibc/libpthread_nonshared.a -Wl,--as-needed -Wl,-Bstatic -lgmp -lunwind -luv -lpthread -ldl -lrt -Wl,-Bdynamic -Wl,--no-as-needed -fuse-ld=lld'"
echo -n " -DLEANC_INTERNAL_LINKER_FLAGS='-L ROOT/lib -L ROOT/lib/glibc ROOT/lib/glibc/libc_nonshared.a ROOT/lib/glibc/libpthread_nonshared.a -Wl,--as-needed -Wl,-Bstatic -lgmp -lunwind -luv -Wl,-Bdynamic -Wl,--no-as-needed -fuse-ld=lld'"
# when not using the above flags, link GMP dynamically/as usual
echo -n " -DLEAN_EXTRA_LINKER_FLAGS='-Wl,--as-needed -lgmp -luv -lpthread -ldl -lrt -Wl,--no-as-needed'"
# do not set `LEAN_CC` for tests

View File

@@ -17,6 +17,8 @@ set(LEAN_SPECIAL_VERSION_DESC "" CACHE STRING "Additional version description li
set(LEAN_VERSION_STRING "${LEAN_VERSION_MAJOR}.${LEAN_VERSION_MINOR}.${LEAN_VERSION_PATCH}")
if (LEAN_SPECIAL_VERSION_DESC)
string(APPEND LEAN_VERSION_STRING "-${LEAN_SPECIAL_VERSION_DESC}")
elseif (NOT LEAN_VERSION_IS_RELEASE)
string(APPEND LEAN_VERSION_STRING "-pre")
endif()
set(LEAN_PLATFORM_TARGET "" CACHE STRING "LLVM triple of the target platform")

View File

@@ -861,16 +861,21 @@ theorem Exists.elim {α : Sort u} {p : α → Prop} {b : Prop}
/-! # Decidable -/
theorem decide_true_eq_true (h : Decidable True) : @decide True h = true :=
@[simp] theorem decide_true (h : Decidable True) : @decide True h = true :=
match h with
| isTrue _ => rfl
| isFalse h => False.elim <| h
theorem decide_false_eq_false (h : Decidable False) : @decide False h = false :=
@[simp] theorem decide_false (h : Decidable False) : @decide False h = false :=
match h with
| isFalse _ => rfl
| isTrue h => False.elim h
set_option linter.missingDocs false in
@[deprecated decide_true (since := "2024-11-05")] abbrev decide_true_eq_true := decide_true
set_option linter.missingDocs false in
@[deprecated decide_false (since := "2024-11-05")] abbrev decide_false_eq_false := decide_false
/-- Similar to `decide`, but uses an explicit instance -/
@[inline] def toBoolUsing {p : Prop} (d : Decidable p) : Bool :=
decide (h := d)

View File

@@ -866,6 +866,7 @@ def zip (as : Array α) (bs : Array β) : Array (α × β) :=
def unzip (as : Array (α × β)) : Array α × Array β :=
as.foldl (init := (#[], #[])) fun (as, bs) (a, b) => (as.push a, bs.push b)
@[deprecated partition (since := "2024-11-06")]
def split (as : Array α) (p : α Bool) : Array α × Array α :=
as.foldl (init := (#[], #[])) fun (as, bs) a =>
if p a then (as.push a, bs) else (as, bs.push a)

View File

@@ -23,7 +23,7 @@ theorem foldlM_eq_foldlM_toList.aux [Monad m]
· cases Nat.not_le_of_gt _ (Nat.zero_add _ H)
· rename_i i; rw [Nat.succ_add] at H
simp [foldlM_eq_foldlM_toList.aux f arr i (j+1) H]
rw (occs := .pos [2]) [ List.get_drop_eq_drop _ _ _]
rw (occs := .pos [2]) [ List.getElem_cons_drop_succ_eq_drop _]
rfl
· rw [List.drop_of_length_le (Nat.ge_of_not_lt _)]; rfl
@@ -79,6 +79,17 @@ theorem foldr_eq_foldr_toList (f : α → β → β) (init : β) (arr : Array α
rw [foldl_eq_foldl_toList]
induction arr'.toList generalizing arr <;> simp [*]
@[simp] theorem toList_empty : (#[] : Array α).toList = [] := rfl
@[simp] theorem append_nil (as : Array α) : as ++ #[] = as := by
apply ext'; simp only [toList_append, toList_empty, List.append_nil]
@[simp] theorem nil_append (as : Array α) : #[] ++ as = as := by
apply ext'; simp only [toList_append, toList_empty, List.nil_append]
@[simp] theorem append_assoc (as bs cs : Array α) : as ++ bs ++ cs = as ++ (bs ++ cs) := by
apply ext'; simp only [toList_append, List.append_assoc]
@[simp] theorem appendList_eq_append
(arr : Array α) (l : List α) : arr.appendList l = arr ++ l := rfl

View File

@@ -41,6 +41,6 @@ where
getLit_eq (as : Array α) (i : Nat) (h₁ : as.size = n) (h₂ : i < n) : as.getLit i h₁ h₂ = getElem as.toList i ((id (α := as.toList.length = n) h₁) h₂) :=
rfl
go (i : Nat) (hi : i as.size) : toListLitAux as n hsz i hi (as.toList.drop i) = as.toList := by
induction i <;> simp only [List.drop, toListLitAux, getLit_eq, List.get_drop_eq_drop, *]
induction i <;> simp only [List.drop, toListLitAux, getLit_eq, List.getElem_cons_drop_succ_eq_drop, *]
end Array

View File

@@ -10,6 +10,7 @@ import Init.Data.List.Monadic
import Init.Data.List.Range
import Init.Data.List.Nat.TakeDrop
import Init.Data.List.Nat.Modify
import Init.Data.List.Nat.Erase
import Init.Data.List.Monadic
import Init.Data.List.OfFn
import Init.Data.Array.Mem
@@ -189,6 +190,151 @@ theorem foldl_toArray (f : β → α → β) (init : β) (l : List α) :
apply ext'
simp
@[simp] theorem push_append_toArray {as : Array α} {a : α} {bs : List α} : as.push a ++ bs.toArray = as ++ (a ::bs).toArray := by
cases as
simp
@[simp] theorem foldl_push {l : List α} {as : Array α} : l.foldl Array.push as = as ++ l.toArray := by
induction l generalizing as <;> simp [*]
@[simp] theorem findSomeM?_toArray [Monad m] [LawfulMonad m] (f : α m (Option β)) (l : List α) :
l.toArray.findSomeM? f = l.findSomeM? f := by
rw [Array.findSomeM?]
simp only [bind_pure_comp, map_pure, forIn_toArray]
induction l with
| nil => simp
| cons a l ih =>
simp only [forIn_cons, LawfulMonad.bind_assoc, findSomeM?]
congr
ext1 (_|_) <;> simp [ih]
theorem findSomeRevM?_find_toArray [Monad m] [LawfulMonad m] (f : α m (Option β)) (l : List α)
(i : Nat) (h) :
findSomeRevM?.find l.toArray f i h = (l.take i).reverse.findSomeM? f := by
induction i generalizing l with
| zero => simp [Array.findSomeRevM?.find.eq_def]
| succ i ih =>
rw [size_toArray] at h
rw [Array.findSomeRevM?.find, take_succ, getElem?_eq_getElem (by omega)]
simp only [ih, reverse_append]
congr
ext1 (_|_) <;> simp
-- This is not marked as `@[simp]` as later we simplify all occurrences of `findSomeRevM?`.
theorem findSomeRevM?_toArray [Monad m] [LawfulMonad m] (f : α m (Option β)) (l : List α) :
l.toArray.findSomeRevM? f = l.reverse.findSomeM? f := by
simp [Array.findSomeRevM?, findSomeRevM?_find_toArray]
-- This is not marked as `@[simp]` as later we simplify all occurrences of `findRevM?`.
theorem findRevM?_toArray [Monad m] [LawfulMonad m] (f : α m Bool) (l : List α) :
l.toArray.findRevM? f = l.reverse.findM? f := by
rw [Array.findRevM?, findSomeRevM?_toArray, findM?_eq_findSomeM?]
@[simp] theorem findM?_toArray [Monad m] [LawfulMonad m] (f : α m Bool) (l : List α) :
l.toArray.findM? f = l.findM? f := by
rw [Array.findM?]
simp only [bind_pure_comp, map_pure, forIn_toArray]
induction l with
| nil => simp
| cons a l ih =>
simp only [forIn_cons, LawfulMonad.bind_assoc, findM?]
congr
ext1 (_|_) <;> simp [ih]
@[simp] theorem findSome?_toArray (f : α Option β) (l : List α) :
l.toArray.findSome? f = l.findSome? f := by
rw [Array.findSome?, findSomeM?_id, findSomeM?_toArray, Id.run]
@[simp] theorem find?_toArray (f : α Bool) (l : List α) :
l.toArray.find? f = l.find? f := by
rw [Array.find?, findM?_id, findM?_toArray, Id.run]
theorem isPrefixOfAux_toArray_succ [BEq α] (l₁ l₂ : List α) (hle : l₁.length l₂.length) (i : Nat) :
Array.isPrefixOfAux l₁.toArray l₂.toArray hle (i + 1) =
Array.isPrefixOfAux l₁.tail.toArray l₂.tail.toArray (by simp; omega) i := by
rw [Array.isPrefixOfAux]
conv => rhs; rw [Array.isPrefixOfAux]
simp only [size_toArray, getElem_toArray, Bool.if_false_right, length_tail, getElem_tail]
split <;> rename_i h₁ <;> split <;> rename_i h₂
· rw [isPrefixOfAux_toArray_succ]
· omega
· omega
· rfl
theorem isPrefixOfAux_toArray_succ' [BEq α] (l₁ l₂ : List α) (hle : l₁.length l₂.length) (i : Nat) :
Array.isPrefixOfAux l₁.toArray l₂.toArray hle (i + 1) =
Array.isPrefixOfAux (l₁.drop (i+1)).toArray (l₂.drop (i+1)).toArray (by simp; omega) 0 := by
induction i generalizing l₁ l₂ with
| zero => simp [isPrefixOfAux_toArray_succ]
| succ i ih =>
rw [isPrefixOfAux_toArray_succ, ih]
simp
theorem isPrefixOfAux_toArray_zero [BEq α] (l₁ l₂ : List α) (hle : l₁.length l₂.length) :
Array.isPrefixOfAux l₁.toArray l₂.toArray hle 0 =
l₁.isPrefixOf l₂ := by
rw [Array.isPrefixOfAux]
match l₁, l₂ with
| [], _ => rw [dif_neg] <;> simp
| _::_, [] => simp at hle
| a::l₁, b::l₂ =>
simp [isPrefixOf_cons₂, isPrefixOfAux_toArray_succ', isPrefixOfAux_toArray_zero]
@[simp] theorem isPrefixOf_toArray [BEq α] (l₁ l₂ : List α) :
l₁.toArray.isPrefixOf l₂.toArray = l₁.isPrefixOf l₂ := by
rw [Array.isPrefixOf]
split <;> rename_i h
· simp [isPrefixOfAux_toArray_zero]
· simp only [Bool.false_eq]
induction l₁ generalizing l₂ with
| nil => simp at h
| cons a l₁ ih =>
cases l₂ with
| nil => simp
| cons b l₂ =>
simp only [isPrefixOf_cons₂, Bool.and_eq_false_imp]
intro w
rw [ih]
simp_all
theorem zipWithAux_toArray_succ (f : α β γ) (as : List α) (bs : List β) (i : Nat) (cs : Array γ) :
zipWithAux f as.toArray bs.toArray (i + 1) cs = zipWithAux f as.tail.toArray bs.tail.toArray i cs := by
rw [zipWithAux]
conv => rhs; rw [zipWithAux]
simp only [size_toArray, getElem_toArray, length_tail, getElem_tail]
split <;> rename_i h₁
· split <;> rename_i h₂
· rw [dif_pos (by omega), dif_pos (by omega), zipWithAux_toArray_succ]
· rw [dif_pos (by omega)]
rw [dif_neg (by omega)]
· rw [dif_neg (by omega)]
theorem zipWithAux_toArray_succ' (f : α β γ) (as : List α) (bs : List β) (i : Nat) (cs : Array γ) :
zipWithAux f as.toArray bs.toArray (i + 1) cs = zipWithAux f (as.drop (i+1)).toArray (bs.drop (i+1)).toArray 0 cs := by
induction i generalizing as bs cs with
| zero => simp [zipWithAux_toArray_succ]
| succ i ih =>
rw [zipWithAux_toArray_succ, ih]
simp
theorem zipWithAux_toArray_zero (f : α β γ) (as : List α) (bs : List β) (cs : Array γ) :
zipWithAux f as.toArray bs.toArray 0 cs = cs ++ (List.zipWith f as bs).toArray := by
rw [Array.zipWithAux]
match as, bs with
| [], _ => simp
| _, [] => simp
| a :: as, b :: bs =>
simp [zipWith_cons_cons, zipWithAux_toArray_succ', zipWithAux_toArray_zero, push_append_toArray]
@[simp] theorem zipWith_toArray (f : α β γ) (as : List α) (bs : List β) :
Array.zipWith as.toArray bs.toArray f = (List.zipWith f as bs).toArray := by
rw [Array.zipWith]
simp [zipWithAux_toArray_zero]
@[simp] theorem zip_toArray (as : List α) (bs : List β) :
Array.zip as.toArray bs.toArray = (List.zip as bs).toArray := by
simp [Array.zip, zipWith_toArray, zip]
end List
namespace Array
@@ -246,7 +392,7 @@ where
aux (i r) :
mapM.map f arr i r = (arr.toList.drop i).foldlM (fun bs a => bs.push <$> f a) r := by
unfold mapM.map; split
· rw [ List.get_drop_eq_drop _ i _]
· rw [ List.getElem_cons_drop_succ_eq_drop _]
simp only [aux (i + 1), map_eq_pure_bind, length_toList, List.foldlM_cons, bind_assoc,
pure_bind]
rfl
@@ -1050,8 +1196,6 @@ theorem filterMap_congr {as bs : Array α} (h : as = bs)
theorem size_empty : (#[] : Array α).size = 0 := rfl
@[simp] theorem toList_empty : (#[] : Array α).toList = [] := rfl
/-! ### append -/
theorem push_eq_append_singleton (as : Array α) (x) : as.push x = as ++ #[x] := rfl
@@ -1101,15 +1245,6 @@ theorem getElem?_append {as bs : Array α} {n : Nat} :
· exact getElem?_append_left h
· exact getElem?_append_right (by simpa using h)
@[simp] theorem append_nil (as : Array α) : as ++ #[] = as := by
apply ext'; simp only [toList_append, toList_empty, List.append_nil]
@[simp] theorem nil_append (as : Array α) : #[] ++ as = as := by
apply ext'; simp only [toList_append, toList_empty, List.nil_append]
@[simp] theorem append_assoc (as bs cs : Array α) : as ++ bs ++ cs = as ++ (bs ++ cs) := by
apply ext'; simp only [toList_append, List.append_assoc]
/-! ### flatten -/
@[simp] theorem toList_flatten {l : Array (Array α)} :
@@ -1460,6 +1595,54 @@ theorem swap_comm (a : Array α) {i j : Fin a.size} : a.swap i j = a.swap j i :=
· split <;> simp_all
· split <;> simp_all
/-! ### eraseIdx -/
theorem feraseIdx_eq_eraseIdx {a : Array α} {i : Fin a.size} :
a.feraseIdx i = a.eraseIdx i.1 := by
simp [eraseIdx]
/-! ### isPrefixOf -/
@[simp] theorem isPrefixOf_toList [BEq α] {as bs : Array α} :
as.toList.isPrefixOf bs.toList = as.isPrefixOf bs := by
cases as
cases bs
simp
/-! ### zipWith -/
@[simp] theorem toList_zipWith (f : α β γ) (as : Array α) (bs : Array β) :
(Array.zipWith as bs f).toList = List.zipWith f as.toList bs.toList := by
cases as
cases bs
simp
@[simp] theorem toList_zip (as : Array α) (bs : Array β) :
(Array.zip as bs).toList = List.zip as.toList bs.toList := by
simp [zip, toList_zipWith, List.zip]
/-! ### findSomeM?, findM?, findSome?, find? -/
@[simp] theorem findSomeM?_toList [Monad m] [LawfulMonad m] (p : α m (Option β)) (as : Array α) :
as.toList.findSomeM? p = as.findSomeM? p := by
cases as
simp
@[simp] theorem findM?_toList [Monad m] [LawfulMonad m] (p : α m Bool) (as : Array α) :
as.toList.findM? p = as.findM? p := by
cases as
simp
@[simp] theorem findSome?_toList (p : α Option β) (as : Array α) :
as.toList.findSome? p = as.findSome? p := by
cases as
simp
@[simp] theorem find?_toList (p : α Bool) (as : Array α) :
as.toList.find? p = as.find? p := by
cases as
simp
end Array
open Array
@@ -1475,11 +1658,6 @@ Our goal is to have `simp` "pull `List.toArray` outwards" as much as possible.
@[simp] theorem toListRev_toArray (l : List α) : l.toArray.toListRev = l.reverse := by
simp
@[simp] theorem push_append_toArray (as : Array α) (a : α) (l : List α) :
as.push a ++ l.toArray = as ++ (a :: l).toArray := by
apply ext'
simp
@[simp] theorem take_toArray (l : List α) (n : Nat) : l.toArray.take n = (l.take n).toArray := by
apply ext'
simp
@@ -1611,7 +1789,7 @@ theorem filterMap_toArray (f : α → Option β) (l : List α) :
apply ext'
simp
@[simp] theorem toArray_extract (l : List α) (start stop : Nat) :
@[simp] theorem extract_toArray (l : List α) (start stop : Nat) :
l.toArray.extract start stop = ((l.drop start).take (stop - start)).toArray := by
apply ext'
simp
@@ -1619,6 +1797,64 @@ theorem filterMap_toArray (f : α → Option β) (l : List α) :
@[simp] theorem toArray_ofFn (f : Fin n α) : (ofFn f).toArray = Array.ofFn f := by
ext <;> simp
theorem takeWhile_go_succ (p : α Bool) (a : α) (l : List α) (i : Nat) :
takeWhile.go p (a :: l).toArray (i+1) r = takeWhile.go p l.toArray i r := by
rw [takeWhile.go, takeWhile.go]
simp only [size_toArray, length_cons, Nat.add_lt_add_iff_right, Array.get_eq_getElem,
getElem_toArray, getElem_cons_succ]
split
rw [takeWhile_go_succ]
rfl
theorem takeWhile_go_toArray (p : α Bool) (l : List α) (i : Nat) :
Array.takeWhile.go p l.toArray i r = r ++ (takeWhile p (l.drop i)).toArray := by
induction l generalizing i r with
| nil => simp [takeWhile.go]
| cons a l ih =>
rw [takeWhile.go]
cases i with
| zero =>
simp [takeWhile_go_succ, ih, takeWhile_cons]
split <;> simp
| succ i =>
simp only [size_toArray, length_cons, Nat.add_lt_add_iff_right, Array.get_eq_getElem,
getElem_toArray, getElem_cons_succ, drop_succ_cons]
split <;> rename_i h₁
· rw [takeWhile_go_succ, ih]
rw [ getElem_cons_drop_succ_eq_drop h₁, takeWhile_cons]
split <;> simp_all
· simp_all [drop_eq_nil_of_le]
@[simp] theorem takeWhile_toArray (p : α Bool) (l : List α) :
l.toArray.takeWhile p = (l.takeWhile p).toArray := by
simp [Array.takeWhile, takeWhile_go_toArray]
@[simp] theorem feraseIdx_toArray (l : List α) (i : Fin l.toArray.size) :
l.toArray.feraseIdx i = (l.eraseIdx i).toArray := by
rw [feraseIdx]
split <;> rename_i h
· rw [feraseIdx_toArray]
simp only [swap_toArray, Fin.getElem_fin, toList_toArray, mk.injEq]
rw [eraseIdx_set_gt (by simp), eraseIdx_set_eq]
simp
· rcases i with i, w
simp at h w
have t : i = l.length - 1 := by omega
simp [t]
termination_by l.length - i
decreasing_by
rename_i h
simp at h
simp
omega
@[simp] theorem eraseIdx_toArray (l : List α) (i : Nat) :
l.toArray.eraseIdx i = (l.eraseIdx i).toArray := by
rw [Array.eraseIdx]
split
· simp
· simp_all [eraseIdx_eq_self.2]
end List
namespace Array
@@ -1629,6 +1865,84 @@ namespace Array
@[simp] theorem toList_ofFn (f : Fin n α) : (Array.ofFn f).toList = List.ofFn f := by
apply List.ext_getElem <;> simp
@[simp] theorem toList_takeWhile (p : α Bool) (as : Array α) :
(as.takeWhile p).toList = as.toList.takeWhile p := by
induction as; simp
@[simp] theorem toList_feraseIdx (as : Array α) (i : Fin as.size) :
(as.feraseIdx i).toList = as.toList.eraseIdx i.1 := by
induction as
simp
@[simp] theorem toList_eraseIdx (as : Array α) (i : Nat) :
(as.eraseIdx i).toList = as.toList.eraseIdx i := by
induction as
simp
/-! ### findSomeRevM?, findRevM?, findSomeRev?, findRev? -/
@[simp] theorem findSomeRevM?_eq_findSomeM?_reverse
[Monad m] [LawfulMonad m] (f : α m (Option β)) (as : Array α) :
as.findSomeRevM? f = as.reverse.findSomeM? f := by
cases as
rw [List.findSomeRevM?_toArray]
simp
@[simp] theorem findRevM?_eq_findM?_reverse
[Monad m] [LawfulMonad m] (f : α m Bool) (as : Array α) :
as.findRevM? f = as.reverse.findM? f := by
cases as
rw [List.findRevM?_toArray]
simp
@[simp] theorem findSomeRev?_eq_findSome?_reverse (f : α Option β) (as : Array α) :
as.findSomeRev? f = as.reverse.findSome? f := by
cases as
simp [findSomeRev?, Id.run]
@[simp] theorem findRev?_eq_find?_reverse (f : α Bool) (as : Array α) :
as.findRev? f = as.reverse.find? f := by
cases as
simp [findRev?, Id.run]
/-! ### unzip -/
@[simp] theorem fst_unzip (as : Array (α × β)) : (Array.unzip as).fst = as.map Prod.fst := by
simp only [unzip]
rcases as with as
simp only [List.foldl_toArray']
rw [ List.foldl_hom (f := Prod.fst) (g₂ := fun bs x => bs.push x.1) (H := by simp), List.foldl_map]
simp
@[simp] theorem snd_unzip (as : Array (α × β)) : (Array.unzip as).snd = as.map Prod.snd := by
simp only [unzip]
rcases as with as
simp only [List.foldl_toArray']
rw [ List.foldl_hom (f := Prod.snd) (g₂ := fun bs x => bs.push x.2) (H := by simp), List.foldl_map]
simp
end Array
namespace List
@[simp] theorem unzip_toArray (as : List (α × β)) :
as.toArray.unzip = Prod.map List.toArray List.toArray as.unzip := by
ext1 <;> simp
end List
namespace Array
@[simp] theorem toList_fst_unzip (as : Array (α × β)) :
as.unzip.1.toList = as.toList.unzip.1 := by
cases as
simp
@[simp] theorem toList_snd_unzip (as : Array (α × β)) :
as.unzip.2.toList = as.toList.unzip.2 := by
cases as
simp
end Array
/-! ### Deprecations -/

View File

@@ -180,7 +180,7 @@ theorem carry_succ_one (i : Nat) (x : BitVec w) (h : 0 < w) :
| zero => simp [carry_succ, h]
| succ i ih =>
rw [carry_succ, ih]
simp only [getLsbD_one, add_one_ne_zero, decide_False, Bool.and_false, atLeastTwo_false_mid]
simp only [getLsbD_one, add_one_ne_zero, decide_false, Bool.and_false, atLeastTwo_false_mid]
cases hx : x.getLsbD (i+1)
case false =>
have : j i + 1, x.getLsbD j = false :=
@@ -249,7 +249,7 @@ theorem getLsbD_add_add_bool {i : Nat} (i_lt : i < w) (x y : BitVec w) (c : Bool
[ Nat.testBit_mod_two_pow,
Nat.testBit_mul_two_pow_add_eq,
i_lt,
decide_True,
decide_true,
Bool.true_and,
Nat.add_assoc,
Nat.add_left_comm (_%_) (_ * _) _,
@@ -392,7 +392,7 @@ theorem getLsbD_neg {i : Nat} {x : BitVec w} :
by_cases hi : i < w
· rw [getLsbD_add hi]
have : 0 < w := by omega
simp only [getLsbD_not, hi, decide_True, Bool.true_and, getLsbD_one, this, not_bne,
simp only [getLsbD_not, hi, decide_true, Bool.true_and, getLsbD_one, this, not_bne,
_root_.true_and, not_eq_eq_eq_not]
cases i with
| zero =>
@@ -401,7 +401,7 @@ theorem getLsbD_neg {i : Nat} {x : BitVec w} :
simp [hi, carry_zero]
| succ =>
rw [carry_succ_one _ _ (by omega), Bool.xor_not, decide_not]
simp only [add_one_ne_zero, decide_False, getLsbD_not, and_eq_true, decide_eq_true_eq,
simp only [add_one_ne_zero, decide_false, getLsbD_not, and_eq_true, decide_eq_true_eq,
not_eq_eq_eq_not, Bool.not_true, false_bne, not_exists, _root_.not_and, not_eq_true,
bne_left_inj, decide_eq_decide]
constructor
@@ -419,7 +419,7 @@ theorem getMsbD_neg {i : Nat} {x : BitVec w} :
simp [hi]; omega
case pos =>
have h₁ : w - 1 - i < w := by omega
simp only [hi, decide_True, h₁, Bool.true_and, Bool.bne_left_inj, decide_eq_decide]
simp only [hi, decide_true, h₁, Bool.true_and, Bool.bne_left_inj, decide_eq_decide]
constructor
· rintro j, hj, h
refine w - 1 - j, by omega, by omega, by omega, _root_.cast ?_ h
@@ -455,7 +455,7 @@ theorem msb_neg {w : Nat} {x : BitVec w} :
apply hmin
apply eq_of_getMsbD_eq
rintro i, hi
simp only [getMsbD_intMin, w_pos, decide_True, Bool.true_and]
simp only [getMsbD_intMin, w_pos, decide_true, Bool.true_and]
cases i
case zero => exact hmsb
case succ => exact getMsbD_x _ hi (by omega)
@@ -476,7 +476,7 @@ theorem msb_abs {w : Nat} {x : BitVec w} :
by_cases h₀ : 0 < w
· by_cases h₁ : x = intMin w
· simp [h₁, msb_intMin]
· simp only [neg_eq, h₁, decide_False]
· simp only [neg_eq, h₁, decide_false]
by_cases h₂ : x.msb
· simp [h₂, msb_neg]
and_intros
@@ -566,18 +566,18 @@ theorem setWidth_setWidth_succ_eq_setWidth_setWidth_add_twoPow (x : BitVec w) (i
setWidth w (x.setWidth i) + (x &&& twoPow w i) := by
rw [add_eq_or_of_and_eq_zero]
· ext k
simp only [getLsbD_setWidth, Fin.is_lt, decide_True, Bool.true_and, getLsbD_or, getLsbD_and]
simp only [getLsbD_setWidth, Fin.is_lt, decide_true, Bool.true_and, getLsbD_or, getLsbD_and]
by_cases hik : i = k
· subst hik
simp
· simp only [getLsbD_twoPow, hik, decide_False, Bool.and_false, Bool.or_false]
· simp only [getLsbD_twoPow, hik, decide_false, Bool.and_false, Bool.or_false]
by_cases hik' : k < (i + 1)
· have hik'' : k < i := by omega
simp [hik', hik'']
· have hik'' : ¬ (k < i) := by omega
simp [hik', hik'']
· ext k
simp only [and_twoPow, getLsbD_and, getLsbD_setWidth, Fin.is_lt, decide_True, Bool.true_and,
simp only [and_twoPow, getLsbD_and, getLsbD_setWidth, Fin.is_lt, decide_true, Bool.true_and,
getLsbD_zero, and_eq_false_imp, and_eq_true, decide_eq_true_eq, and_imp]
by_cases hi : x.getLsbD i <;> simp [hi] <;> omega

View File

@@ -123,7 +123,7 @@ theorem getMsbD_eq_getLsbD (x : BitVec w) (i : Nat) : x.getMsbD i = (decide (i <
theorem getLsbD_eq_getMsbD (x : BitVec w) (i : Nat) : x.getLsbD i = (decide (i < w) && x.getMsbD (w - 1 - i)) := by
rw [getMsbD]
by_cases h₁ : i < w <;> by_cases h₂ : w - 1 - i < w <;>
simp only [h₁, h₂] <;> simp only [decide_True, decide_False, Bool.false_and, Bool.and_false, Bool.true_and, Bool.and_true]
simp only [h₁, h₂] <;> simp only [decide_true, decide_false, Bool.false_and, Bool.and_false, Bool.true_and, Bool.and_true]
· congr
omega
all_goals
@@ -386,7 +386,7 @@ theorem msb_eq_getLsbD_last (x : BitVec w) :
· simp [Nat.div_eq_of_lt h, h]
· simp only [h]
rw [Nat.div_eq_sub_div (Nat.two_pow_pos w) h, Nat.div_eq_of_lt]
· decide
· simp
· omega
@[bv_toNat] theorem getLsbD_succ_last (x : BitVec (w + 1)) :
@@ -633,7 +633,7 @@ theorem getElem?_setWidth (m : Nat) (x : BitVec n) (i : Nat) :
@[simp] theorem setWidth_setWidth_of_le (x : BitVec w) (h : k l) :
(x.setWidth l).setWidth k = x.setWidth k := by
ext i
simp only [getLsbD_setWidth, Fin.is_lt, decide_True, Bool.true_and]
simp only [getLsbD_setWidth, Fin.is_lt, decide_true, Bool.true_and]
have p := lt_of_getLsbD (x := x) (i := i)
revert p
cases getLsbD x i <;> simp; omega
@@ -663,7 +663,7 @@ theorem setWidth_one_eq_ofBool_getLsb_zero (x : BitVec w) :
theorem setWidth_ofNat_one_eq_ofNat_one_of_lt {v w : Nat} (hv : 0 < v) :
(BitVec.ofNat v 1).setWidth w = BitVec.ofNat w 1 := by
ext i, hilt
simp only [getLsbD_setWidth, hilt, decide_True, getLsbD_ofNat, Bool.true_and,
simp only [getLsbD_setWidth, hilt, decide_true, getLsbD_ofNat, Bool.true_and,
Bool.and_iff_right_iff_imp, decide_eq_true_eq]
intros hi₁
have hv := Nat.testBit_one_eq_true_iff_self_eq_zero.mp hi₁
@@ -735,9 +735,9 @@ theorem extractLsb'_eq_extractLsb {w : Nat} (x : BitVec w) (start len : Nat) (h
@[simp] theorem ofFin_add_rev (x : Fin (2^n)) : ofFin (x + x.rev) = allOnes n := by
ext
simp only [Fin.rev, getLsbD_ofFin, getLsbD_allOnes, Fin.is_lt, decide_True]
simp only [Fin.rev, getLsbD_ofFin, getLsbD_allOnes, Fin.is_lt, decide_true]
rw [Fin.add_def]
simp only [Nat.testBit_mod_two_pow, Fin.is_lt, decide_True, Bool.true_and]
simp only [Nat.testBit_mod_two_pow, Fin.is_lt, decide_true, Bool.true_and]
have h : (x : Nat) + (2 ^ n - (x + 1)) = 2 ^ n - 1 := by omega
rw [h, Nat.testBit_two_pow_sub_one]
simp
@@ -1089,21 +1089,21 @@ theorem zero_shiftLeft (n : Nat) : 0#w <<< n = 0#w := by
theorem shiftLeft_xor_distrib (x y : BitVec w) (n : Nat) :
(x ^^^ y) <<< n = (x <<< n) ^^^ (y <<< n) := by
ext i
simp only [getLsbD_shiftLeft, Fin.is_lt, decide_True, Bool.true_and, getLsbD_xor]
simp only [getLsbD_shiftLeft, Fin.is_lt, decide_true, Bool.true_and, getLsbD_xor]
by_cases h : i < n
<;> simp [h]
theorem shiftLeft_and_distrib (x y : BitVec w) (n : Nat) :
(x &&& y) <<< n = (x <<< n) &&& (y <<< n) := by
ext i
simp only [getLsbD_shiftLeft, Fin.is_lt, decide_True, Bool.true_and, getLsbD_and]
simp only [getLsbD_shiftLeft, Fin.is_lt, decide_true, Bool.true_and, getLsbD_and]
by_cases h : i < n
<;> simp [h]
theorem shiftLeft_or_distrib (x y : BitVec w) (n : Nat) :
(x ||| y) <<< n = (x <<< n) ||| (y <<< n) := by
ext i
simp only [getLsbD_shiftLeft, Fin.is_lt, decide_True, Bool.true_and, getLsbD_or]
simp only [getLsbD_shiftLeft, Fin.is_lt, decide_true, Bool.true_and, getLsbD_or]
by_cases h : i < n
<;> simp [h]
@@ -1114,9 +1114,9 @@ theorem shiftLeft_or_distrib (x y : BitVec w) (n : Nat) :
· subst h; simp
have t : w - 1 - k < w := by omega
simp only [t]
simp only [decide_True, Nat.sub_sub, Bool.true_and, Nat.add_assoc]
simp only [decide_true, Nat.sub_sub, Bool.true_and, Nat.add_assoc]
by_cases h₁ : k < w <;> by_cases h₂ : w - (1 + k) < i <;> by_cases h₃ : k + i < w
<;> simp only [h₁, h₂, h₃, decide_False, h₂, decide_True, Bool.not_true, Bool.false_and, Bool.and_self,
<;> simp only [h₁, h₂, h₃, decide_false, h₂, decide_true, Bool.not_true, Bool.false_and, Bool.and_self,
Bool.true_and, Bool.false_eq, Bool.false_and, Bool.not_false]
<;> (first | apply getLsbD_ge | apply Eq.symm; apply getLsbD_ge)
<;> omega
@@ -1160,7 +1160,7 @@ theorem shiftLeftZeroExtend_eq {x : BitVec w} :
theorem shiftLeft_add {w : Nat} (x : BitVec w) (n m : Nat) :
x <<< (n + m) = (x <<< n) <<< m := by
ext i
simp only [getLsbD_shiftLeft, Fin.is_lt, decide_True, Bool.true_and]
simp only [getLsbD_shiftLeft, Fin.is_lt, decide_true, Bool.true_and]
rw [show i - (n + m) = (i - m - n) by omega]
cases h₂ : decide (i < m) <;>
cases h₃ : decide (i - m < w) <;>
@@ -1258,7 +1258,8 @@ theorem getMsbD_ushiftRight {x : BitVec w} {i n : Nat} :
· simp [getLsbD_ge, show w (n + (w - 1 - i)) by omega]
omega
· by_cases h₁ : i < w
· simp only [h, ushiftRight_eq, getLsbD_ushiftRight, show i - n < w by omega]
· simp only [h, decide_false, Bool.not_false, show i - n < w by omega, decide_true,
Bool.true_and]
congr
omega
· simp [h, h₁]
@@ -1327,17 +1328,17 @@ theorem getLsbD_sshiftRight (x : BitVec w) (s i : Nat) :
rcases hmsb : x.msb with rfl | rfl
· simp only [sshiftRight_eq_of_msb_false hmsb, getLsbD_ushiftRight, Bool.if_false_right]
by_cases hi : i w
· simp only [hi, decide_True, Bool.not_true, Bool.false_and]
· simp only [hi, decide_true, Bool.not_true, Bool.false_and]
apply getLsbD_ge
omega
· simp only [hi, decide_False, Bool.not_false, Bool.true_and, Bool.iff_and_self,
· simp only [hi, decide_false, Bool.not_false, Bool.true_and, Bool.iff_and_self,
decide_eq_true_eq]
intros hlsb
apply BitVec.lt_of_getLsbD hlsb
· by_cases hi : i w
· simp [hi]
· simp only [sshiftRight_eq_of_msb_true hmsb, getLsbD_not, getLsbD_ushiftRight, Bool.not_and,
Bool.not_not, hi, decide_False, Bool.not_false, Bool.if_true_right, Bool.true_and,
Bool.not_not, hi, decide_false, Bool.not_false, Bool.if_true_right, Bool.true_and,
Bool.and_iff_right_iff_imp, Bool.or_eq_true, Bool.not_eq_true', decide_eq_false_iff_not,
Nat.not_lt, decide_eq_true_eq]
omega
@@ -1382,7 +1383,7 @@ theorem msb_sshiftRight {n : Nat} {x : BitVec w} :
rw [msb_eq_getLsbD_last, getLsbD_sshiftRight, msb_eq_getLsbD_last]
by_cases hw₀ : w = 0
· simp [hw₀]
· simp only [show ¬(w w - 1) by omega, decide_False, Bool.not_false, Bool.true_and,
· simp only [show ¬(w w - 1) by omega, decide_false, Bool.not_false, Bool.true_and,
ite_eq_right_iff]
intros h
simp [show n = 0 by omega]
@@ -1401,7 +1402,7 @@ theorem sshiftRight_add {x : BitVec w} {m n : Nat} :
simp only [getLsbD_sshiftRight, Nat.add_assoc]
by_cases h₁ : w (i : Nat)
· simp [h₁]
· simp only [h₁, decide_False, Bool.not_false, Bool.true_and]
· simp only [h₁, decide_false, Bool.not_false, Bool.true_and]
by_cases h₂ : n + i < w
· simp [h₂]
· simp only [h₂, reduceIte]
@@ -1413,7 +1414,7 @@ theorem sshiftRight_add {x : BitVec w} {m n : Nat} :
theorem not_sshiftRight {b : BitVec w} :
~~~b.sshiftRight n = (~~~b).sshiftRight n := by
ext i
simp only [getLsbD_not, Fin.is_lt, decide_True, getLsbD_sshiftRight, Bool.not_and, Bool.not_not,
simp only [getLsbD_not, Fin.is_lt, decide_true, getLsbD_sshiftRight, Bool.not_and, Bool.not_not,
Bool.true_and, msb_not]
by_cases h : w i
<;> by_cases h' : n + i < w
@@ -1431,15 +1432,15 @@ theorem getMsbD_sshiftRight {x : BitVec w} {i n : Nat} :
getMsbD (x.sshiftRight n) i = (decide (i < w) && if i < n then x.msb else getMsbD x (i - n)) := by
simp only [getMsbD, BitVec.getLsbD_sshiftRight]
by_cases h : i < w
· simp only [h, decide_True, Bool.true_and]
· simp only [h, decide_true, Bool.true_and]
by_cases h₁ : w w - 1 - i
· simp [h₁]
omega
· simp only [h₁, decide_False, Bool.not_false, Bool.true_and]
· simp only [h₁, decide_false, Bool.not_false, Bool.true_and]
by_cases h₂ : i < n
· simp only [h₂, reduceIte, ite_eq_right_iff]
omega
· simp only [show i - n < w by omega, h₂, reduceIte, decide_True, Bool.true_and]
· simp only [show i - n < w by omega, h₂, reduceIte, decide_true, Bool.true_and]
by_cases h₄ : n + (w - 1 - i) < w <;> (simp only [h₄, reduceIte]; congr; omega)
· simp [h]
@@ -1459,15 +1460,15 @@ theorem getMsbD_sshiftRight' {x y: BitVec w} {i : Nat} :
(x.sshiftRight y.toNat).getMsbD i = (decide (i < w) && if i < y.toNat then x.msb else x.getMsbD (i - y.toNat)) := by
simp only [BitVec.sshiftRight', getMsbD, BitVec.getLsbD_sshiftRight]
by_cases h : i < w
· simp only [h, decide_True, Bool.true_and]
· simp only [h, decide_true, Bool.true_and]
by_cases h₁ : w w - 1 - i
· simp [h₁]
omega
· simp only [h₁, decide_False, Bool.not_false, Bool.true_and]
· simp only [h₁, decide_false, Bool.not_false, Bool.true_and]
by_cases h₂ : i < y.toNat
· simp only [h₂, reduceIte, ite_eq_right_iff]
omega
· simp only [show i - y.toNat < w by omega, h₂, reduceIte, decide_True, Bool.true_and]
· simp only [show i - y.toNat < w by omega, h₂, reduceIte, decide_true, Bool.true_and]
by_cases h₄ : y.toNat + (w - 1 - i) < w <;> (simp only [h₄, reduceIte]; congr; omega)
· simp [h]
@@ -1492,11 +1493,11 @@ theorem signExtend_eq_not_setWidth_not_of_msb_false {x : BitVec w} {v : Nat} (hm
x.signExtend v = x.setWidth v := by
ext i
by_cases hv : i < v
· simp only [signExtend, getLsbD, getLsbD_setWidth, hv, decide_True, Bool.true_and, toNat_ofInt,
· simp only [signExtend, getLsbD, getLsbD_setWidth, hv, decide_true, Bool.true_and, toNat_ofInt,
BitVec.toInt_eq_msb_cond, hmsb, reduceIte, reduceCtorEq]
rw [Int.ofNat_mod_ofNat, Int.toNat_ofNat, Nat.testBit_mod_two_pow]
simp [BitVec.testBit_toNat]
· simp only [getLsbD_setWidth, hv, decide_False, Bool.false_and]
· simp only [getLsbD_setWidth, hv, decide_false, Bool.false_and]
apply getLsbD_ge
omega
@@ -1538,7 +1539,7 @@ theorem getElem_signExtend {x : BitVec w} {v i : Nat} (h : i < v) :
theorem signExtend_eq_setWidth_of_lt (x : BitVec w) {v : Nat} (hv : v w):
x.signExtend v = x.setWidth v := by
ext i
simp only [getLsbD_signExtend, Fin.is_lt, decide_True, Bool.true_and, getLsbD_setWidth,
simp only [getLsbD_signExtend, Fin.is_lt, decide_true, Bool.true_and, getLsbD_setWidth,
ite_eq_left_iff, Nat.not_lt]
omega
@@ -1622,7 +1623,7 @@ theorem setWidth_append {x : BitVec w} {y : BitVec v} :
(x ++ y).setWidth k = if h : k v then y.setWidth k else (x.setWidth (k - v) ++ y).cast (by omega) := by
apply eq_of_getLsbD_eq
intro i
simp only [getLsbD_setWidth, Fin.is_lt, decide_True, getLsbD_append, Bool.true_and]
simp only [getLsbD_setWidth, Fin.is_lt, decide_true, getLsbD_append, Bool.true_and]
split
· have t : i < v := by omega
simp [t]
@@ -1634,7 +1635,7 @@ theorem setWidth_append {x : BitVec w} {y : BitVec v} :
@[simp] theorem setWidth_append_of_eq {x : BitVec v} {y : BitVec w} (h : w' = w) : setWidth (v' + w') (x ++ y) = setWidth v' x ++ setWidth w' y := by
subst h
ext i
simp only [getLsbD_setWidth, Fin.is_lt, decide_True, getLsbD_append, cond_eq_if,
simp only [getLsbD_setWidth, Fin.is_lt, decide_true, getLsbD_append, cond_eq_if,
decide_eq_true_eq, Bool.true_and, setWidth_eq]
split
· simp_all
@@ -1705,13 +1706,13 @@ theorem shiftRight_shiftRight {w : Nat} (x : BitVec w) (n m : Nat) :
theorem getLsbD_rev (x : BitVec w) (i : Fin w) :
x.getLsbD i.rev = x.getMsbD i := by
simp only [getLsbD, Fin.val_rev, getMsbD, Fin.is_lt, decide_True, Bool.true_and]
simp only [getLsbD, Fin.val_rev, getMsbD, Fin.is_lt, decide_true, Bool.true_and]
congr 1
omega
theorem getElem_rev {x : BitVec w} {i : Fin w}:
x[i.rev] = x.getMsbD i := by
simp only [Fin.getElem_fin, Fin.val_rev, getMsbD, Fin.is_lt, decide_True, Bool.true_and]
simp only [Fin.getElem_fin, Fin.val_rev, getMsbD, Fin.is_lt, decide_true, Bool.true_and]
congr 1
omega
@@ -1741,7 +1742,7 @@ theorem getLsbD_cons (b : Bool) {n} (x : BitVec n) (i : Nat) :
· have p1 : ¬(n i) := by omega
have p2 : i n := by omega
simp [p1, p2]
· simp only [i_eq_n, ge_iff_le, Nat.le_refl, decide_True, Nat.sub_self, Nat.testBit_zero,
· simp only [i_eq_n, ge_iff_le, Nat.le_refl, decide_true, Nat.sub_self, Nat.testBit_zero,
Bool.true_and, testBit_toNat, getLsbD_ge, Bool.or_false, reduceIte]
cases b <;> trivial
· have p1 : i n := by omega
@@ -1756,7 +1757,7 @@ theorem getElem_cons {b : Bool} {n} {x : BitVec n} {i : Nat} (h : i < n + 1) :
· have p1 : ¬(n i) := by omega
have p2 : i n := by omega
simp [p1, p2]
· simp only [i_eq_n, ge_iff_le, Nat.le_refl, decide_True, Nat.sub_self, Nat.testBit_zero,
· simp only [i_eq_n, ge_iff_le, Nat.le_refl, decide_true, Nat.sub_self, Nat.testBit_zero,
Bool.true_and, testBit_toNat, getLsbD_ge, Bool.or_false, reduceIte]
cases b <;> trivial
· have p1 : i n := by omega
@@ -1776,7 +1777,7 @@ theorem setWidth_succ (x : BitVec w) :
setWidth (i+1) x = cons (getLsbD x i) (setWidth i x) := by
apply eq_of_getLsbD_eq
intro j
simp only [getLsbD_setWidth, getLsbD_cons, j.isLt, decide_True, Bool.true_and]
simp only [getLsbD_setWidth, getLsbD_cons, j.isLt, decide_true, Bool.true_and]
if j_eq : j.val = i then
simp [j_eq]
else
@@ -1884,7 +1885,7 @@ theorem getLsbD_shiftConcat_eq_decide (x : BitVec w) (b : Bool) (i : Nat) :
theorem shiftRight_sub_one_eq_shiftConcat (n : BitVec w) (hwn : 0 < wn) :
n >>> (wn - 1) = (n >>> wn).shiftConcat (n.getLsbD (wn - 1)) := by
ext i
simp only [getLsbD_ushiftRight, getLsbD_shiftConcat, Fin.is_lt, decide_True, Bool.true_and]
simp only [getLsbD_ushiftRight, getLsbD_shiftConcat, Fin.is_lt, decide_true, Bool.true_and]
split
· simp [*]
· congr 1; omega
@@ -1925,7 +1926,7 @@ theorem getMsbD_concat {i w : Nat} {b : Bool} {x : BitVec w} :
· simp [h₀]
· by_cases h₁ : i < w
· simp [h₀, h₁, show ¬ w - i = 0 by omega, show i < w + 1 by omega, Nat.sub_sub, Nat.add_comm]
· simp only [show w - i = 0 by omega, reduceIte, h₁, h₀, decide_False, Bool.false_and,
· simp only [show w - i = 0 by omega, reduceIte, h₁, h₀, decide_false, Bool.false_and,
Bool.and_eq_false_imp, decide_eq_true_eq]
intro
omega
@@ -1933,10 +1934,10 @@ theorem getMsbD_concat {i w : Nat} {b : Bool} {x : BitVec w} :
@[simp]
theorem msb_concat {w : Nat} {b : Bool} {x : BitVec w} :
(x.concat b).msb = if 0 < w then x.msb else b := by
simp only [BitVec.msb, getMsbD_eq_getLsbD, Nat.zero_lt_succ, decide_True, Nat.add_one_sub_one,
simp only [BitVec.msb, getMsbD_eq_getLsbD, Nat.zero_lt_succ, decide_true, Nat.add_one_sub_one,
Nat.sub_zero, Bool.true_and]
by_cases h₀ : 0 < w
· simp only [Nat.lt_add_one, getLsbD_eq_getElem, getElem_concat, h₀, reduceIte, decide_True,
· simp only [Nat.lt_add_one, getLsbD_eq_getElem, getElem_concat, h₀, reduceIte, decide_true,
Bool.true_and, ite_eq_right_iff]
intro
omega
@@ -2026,9 +2027,9 @@ theorem sub_def {n} (x y : BitVec n) : x - y = .ofNat n ((2^n - y.toNat) + x.toN
@[simp] theorem toFin_sub (x y : BitVec n) : (x - y).toFin = toFin x - toFin y := rfl
@[simp] theorem ofFin_sub (x : Fin (2^n)) (y : BitVec n) : .ofFin x - y = .ofFin (x - y.toFin) :=
theorem ofFin_sub (x : Fin (2^n)) (y : BitVec n) : .ofFin x - y = .ofFin (x - y.toFin) :=
rfl
@[simp] theorem sub_ofFin (x : BitVec n) (y : Fin (2^n)) : x - .ofFin y = .ofFin (x.toFin - y) :=
theorem sub_ofFin (x : BitVec n) (y : Fin (2^n)) : x - .ofFin y = .ofFin (x.toFin - y) :=
rfl
-- Remark: we don't use `[simp]` here because simproc` subsumes it for literals.
@@ -2506,7 +2507,7 @@ theorem smod_zero {x : BitVec n} : x.smod 0#n = x := by
@[simp] theorem getElem_ofBoolListBE (h : i < bs.length) :
(ofBoolListBE bs)[i] = bs[bs.length - 1 - i] := by
rw [ getLsbD_eq_getElem, getLsbD_ofBoolListBE]
simp only [h, decide_True, List.getD_eq_getElem?_getD, Bool.true_and]
simp only [h, decide_true, List.getD_eq_getElem?_getD, Bool.true_and]
rw [List.getElem?_eq_getElem (by omega)]
simp
@@ -2694,6 +2695,9 @@ theorem getElem_rotateRight {x : BitVec w} {r i : Nat} (h : i < w) :
/- ## twoPow -/
theorem twoPow_eq (w : Nat) (i : Nat) : twoPow w i = 1#w <<< i := by
dsimp [twoPow]
@[simp, bv_toNat]
theorem toNat_twoPow (w : Nat) (i : Nat) : (twoPow w i).toNat = 2^i % 2^w := by
rcases w with rfl | w
@@ -2708,7 +2712,7 @@ theorem getLsbD_twoPow (i j : Nat) : (twoPow w i).getLsbD j = ((i < w) && (i = j
· simp
· simp only [twoPow, getLsbD_shiftLeft, getLsbD_ofNat]
by_cases hj : j < i
· simp only [hj, decide_True, Bool.not_true, Bool.and_false, Bool.false_and, Bool.false_eq,
· simp only [hj, decide_true, Bool.not_true, Bool.and_false, Bool.false_and, Bool.false_eq,
Bool.and_eq_false_imp, decide_eq_true_eq, decide_eq_false_iff_not]
omega
· by_cases hi : Nat.testBit 1 (j - i)
@@ -2771,7 +2775,7 @@ theorem twoPow_zero {w : Nat} : twoPow w 0 = 1#w := by
theorem shiftLeft_eq_mul_twoPow (x : BitVec w) (n : Nat) :
x <<< n = x * (BitVec.twoPow w n) := by
ext i
simp [getLsbD_shiftLeft, Fin.is_lt, decide_True, Bool.true_and, mul_twoPow_eq_shiftLeft]
simp [getLsbD_shiftLeft, Fin.is_lt, decide_true, Bool.true_and, mul_twoPow_eq_shiftLeft]
/- ### cons -/
@@ -2799,7 +2803,7 @@ theorem setWidth_setWidth_succ_eq_setWidth_setWidth_of_getLsbD_false
setWidth w (x.setWidth (i + 1)) =
setWidth w (x.setWidth i) := by
ext k
simp only [getLsbD_setWidth, Fin.is_lt, decide_True, Bool.true_and, getLsbD_or, getLsbD_and]
simp only [getLsbD_setWidth, Fin.is_lt, decide_true, Bool.true_and, getLsbD_or, getLsbD_and]
by_cases hik : i = k
· subst hik
simp [hx]
@@ -2815,7 +2819,7 @@ theorem setWidth_setWidth_succ_eq_setWidth_setWidth_or_twoPow_of_getLsbD_true
setWidth w (x.setWidth (i + 1)) =
setWidth w (x.setWidth i) ||| (twoPow w i) := by
ext k
simp only [getLsbD_setWidth, Fin.is_lt, decide_True, Bool.true_and, getLsbD_or, getLsbD_and]
simp only [getLsbD_setWidth, Fin.is_lt, decide_true, Bool.true_and, getLsbD_or, getLsbD_and]
by_cases hik : i = k
· subst hik
simp [hx]
@@ -2825,7 +2829,7 @@ theorem setWidth_setWidth_succ_eq_setWidth_setWidth_or_twoPow_of_getLsbD_true
theorem and_one_eq_setWidth_ofBool_getLsbD {x : BitVec w} :
(x &&& 1#w) = setWidth w (ofBool (x.getLsbD 0)) := by
ext i
simp only [getLsbD_and, getLsbD_one, getLsbD_setWidth, Fin.is_lt, decide_True, getLsbD_ofBool,
simp only [getLsbD_and, getLsbD_one, getLsbD_setWidth, Fin.is_lt, decide_true, getLsbD_ofBool,
Bool.true_and]
by_cases h : ((i : Nat) = 0) <;> simp [h] <;> omega
@@ -2862,13 +2866,13 @@ theorem getLsbD_replicate {n w : Nat} (x : BitVec w) :
case succ n ih =>
simp only [replicate_succ_eq, getLsbD_cast, getLsbD_append]
by_cases hi : i < w * (n + 1)
· simp only [hi, decide_True, Bool.true_and]
· simp only [hi, decide_true, Bool.true_and]
by_cases hi' : i < w * n
· simp [hi', ih]
· simp only [hi', decide_False, cond_false]
· simp only [hi', decide_false, cond_false]
rw [Nat.sub_mul_eq_mod_of_lt_of_le] <;> omega
· rw [Nat.mul_succ] at hi
simp only [show ¬i < w * n by omega, decide_False, cond_false, hi, Bool.false_and]
simp only [show ¬i < w * n by omega, decide_false, cond_false, hi, Bool.false_and]
apply BitVec.getLsbD_ge (x := x) (i := i - w * n) (ge := by omega)
@[simp]
@@ -2929,7 +2933,7 @@ theorem toInt_intMin_le (x : BitVec w) :
apply Int.le_bmod (by omega)
theorem intMin_sle (x : BitVec w) : (intMin w).sle x := by
simp only [BitVec.sle, toInt_intMin_le x, decide_True]
simp only [BitVec.sle, toInt_intMin_le x, decide_true]
@[simp]
theorem neg_intMin {w : Nat} : -intMin w = intMin w := by

View File

@@ -169,6 +169,13 @@ theorem pmap_ne_nil_iff {P : α → Prop} (f : (a : α) → P a → β) {xs : Li
(H : (a : α), a xs P a) : xs.pmap f H [] xs [] := by
simp
theorem pmap_eq_self {l : List α} {p : α Prop} (hp : (a : α), a l p a)
(f : (a : α) p a α) : l.pmap f hp = l a (h : a l), f a (hp a h) = a := by
rw [pmap_eq_map_attach]
conv => lhs; rhs; rw [ attach_map_subtype_val l]
rw [map_inj_left]
simp
@[simp]
theorem attach_eq_nil_iff {l : List α} : l.attach = [] l = [] :=
pmap_eq_nil_iff

View File

@@ -38,7 +38,7 @@ The operations are organized as follow:
* Sublists: `take`, `drop`, `takeWhile`, `dropWhile`, `partition`, `dropLast`,
`isPrefixOf`, `isPrefixOf?`, `isSuffixOf`, `isSuffixOf?`, `Subset`, `Sublist`,
`rotateLeft` and `rotateRight`.
* Manipulating elements: `replace`, `insert`, `modify`, `erase`, `eraseP`, `eraseIdx`.
* Manipulating elements: `replace`, `modify`, `insert`, `insertIdx`, `erase`, `eraseP`, `eraseIdx`.
* Finding elements: `find?`, `findSome?`, `findIdx`, `indexOf`, `findIdx?`, `indexOf?`,
`countP`, `count`, and `lookup`.
* Logic: `any`, `all`, `or`, and `and`.
@@ -1113,12 +1113,6 @@ theorem replace_cons [BEq α] {a : α} :
(a::as).replace b c = match b == a with | true => c::as | false => a :: replace as b c :=
rfl
/-! ### insert -/
/-- Inserts an element into a list without duplication. -/
@[inline] protected def insert [BEq α] (a : α) (l : List α) : List α :=
if l.elem a then l else a :: l
/-! ### modify -/
/--
@@ -1148,6 +1142,21 @@ Apply `f` to the nth element of the list, if it exists, replacing that element w
def modify (f : α α) : Nat List α List α :=
modifyTailIdx (modifyHead f)
/-! ### insert -/
/-- Inserts an element into a list without duplication. -/
@[inline] protected def insert [BEq α] (a : α) (l : List α) : List α :=
if l.elem a then l else a :: l
/--
`insertIdx n a l` inserts `a` into the list `l` after the first `n` elements of `l`
```
insertIdx 2 1 [1, 2, 3, 4] = [1, 2, 1, 3, 4]
```
-/
def insertIdx (n : Nat) (a : α) : List α List α :=
modifyTailIdx (cons a) n
/-! ### erase -/
/--

View File

@@ -5,6 +5,8 @@ Author: Leonardo de Moura
-/
prelude
import Init.Control.Basic
import Init.Control.Id
import Init.Control.Lawful
import Init.Data.List.Basic
namespace List
@@ -207,6 +209,16 @@ def findM? {m : Type → Type u} [Monad m] {α : Type} (p : α → m Bool) : Lis
| true => pure (some a)
| false => findM? p as
@[simp]
theorem findM?_id (p : α Bool) (as : List α) : findM? (m := Id) p as = as.find? p := by
induction as with
| nil => rfl
| cons a as ih =>
simp only [findM?, find?]
cases p a with
| true => rfl
| false => rw [ih]; rfl
@[specialize]
def findSomeM? {m : Type u Type v} [Monad m] {α : Type w} {β : Type u} (f : α m (Option β)) : List α m (Option β)
| [] => pure none
@@ -215,6 +227,28 @@ def findSomeM? {m : Type u → Type v} [Monad m] {α : Type w} {β : Type u} (f
| some b => pure (some b)
| none => findSomeM? f as
@[simp]
theorem findSomeM?_id (f : α Option β) (as : List α) : findSomeM? (m := Id) f as = as.findSome? f := by
induction as with
| nil => rfl
| cons a as ih =>
simp only [findSomeM?, findSome?]
cases f a with
| some b => rfl
| none => rw [ih]; rfl
theorem findM?_eq_findSomeM? [Monad m] [LawfulMonad m] (p : α m Bool) (as : List α) :
as.findM? p = as.findSomeM? fun a => return if ( p a) then some a else none := by
induction as with
| nil => rfl
| cons a as ih =>
simp only [findM?, findSomeM?]
simp [ih]
congr
apply funext
intro b
cases b <;> simp
@[inline] protected def forIn' {α : Type u} {β : Type v} {m : Type v Type w} [Monad m] (as : List α) (init : β) (f : (a : α) a as β m (ForInStep β)) : m β :=
let rec @[specialize] loop : (as' : List α) (b : β) Exists (fun bs => bs ++ as' = as) m β
| [], b, _ => pure b

View File

@@ -206,7 +206,8 @@ theorem IsInfix.findSome?_eq_none {l₁ l₂ : List α} {f : α → Option β} (
@[simp] theorem find?_eq_none : find? p l = none x l, ¬ p x := by
induction l <;> simp [find?_cons]; split <;> simp [*]
theorem find?_eq_some : xs.find? p = some b p b as bs, xs = as ++ b :: bs a as, !p a := by
theorem find?_eq_some_iff_append :
xs.find? p = some b p b as bs, xs = as ++ b :: bs a as, !p a := by
induction xs with
| nil => simp
| cons x xs ih =>
@@ -242,6 +243,9 @@ theorem find?_eq_some : xs.find? p = some b ↔ p b ∧ ∃ as bs, xs = as ++ b
cases h₁
simp
@[deprecated find?_eq_some_iff_append (since := "2024-11-06")]
abbrev find?_eq_some := @find?_eq_some_iff_append
@[simp]
theorem find?_cons_eq_some : (a :: xs).find? p = some b (p a a = b) (!p a xs.find? p = some b) := by
rw [find?_cons]
@@ -347,7 +351,7 @@ theorem find?_flatten_eq_some {xs : List (List α)} {p : α → Bool} {a : α} :
xs.flatten.find? p = some a
p a as ys zs bs, xs = as ++ (ys ++ a :: zs) :: bs
( a as, x a, !p x) ( x ys, !p x) := by
rw [find?_eq_some]
rw [find?_eq_some_iff_append]
constructor
· rintro h, ys, zs, h₁, h₂
refine h, ?_

View File

@@ -38,7 +38,7 @@ The following operations were already given `@[csimp]` replacements in `Init/Dat
The following operations are given `@[csimp]` replacements below:
`set`, `filterMap`, `foldr`, `append`, `bind`, `join`,
`take`, `takeWhile`, `dropLast`, `replace`, `modify`, `erase`, `eraseIdx`, `zipWith`,
`take`, `takeWhile`, `dropLast`, `replace`, `modify`, `insertIdx`, `erase`, `eraseIdx`, `zipWith`,
`enumFrom`, and `intercalate`.
-/
@@ -215,6 +215,23 @@ theorem modifyTR_go_eq : ∀ l n, modifyTR.go f l n acc = acc.toList ++ modify f
@[csimp] theorem modify_eq_modifyTR : @modify = @modifyTR := by
funext α f n l; simp [modifyTR, modifyTR_go_eq]
/-! ### insertIdx -/
/-- Tail-recursive version of `insertIdx`. -/
@[inline] def insertIdxTR (n : Nat) (a : α) (l : List α) : List α := go n l #[] where
/-- Auxiliary for `insertIdxTR`: `insertIdxTR.go a n l acc = acc.toList ++ insertIdx n a l`. -/
go : Nat List α Array α List α
| 0, l, acc => acc.toListAppend (a :: l)
| _, [], acc => acc.toList
| n+1, a :: l, acc => go n l (acc.push a)
theorem insertIdxTR_go_eq : n l, insertIdxTR.go a n l acc = acc.toList ++ insertIdx n a l
| 0, l | _+1, [] => by simp [insertIdxTR.go, insertIdx]
| n+1, a :: l => by simp [insertIdxTR.go, insertIdx, insertIdxTR_go_eq n l]
@[csimp] theorem insertIdx_eq_insertIdxTR : @insertIdx = @insertIdxTR := by
funext α f n l; simp [insertIdxTR, insertIdxTR_go_eq]
/-! ### erase -/
/-- Tail recursive version of `List.erase`. -/

View File

@@ -863,14 +863,14 @@ theorem foldr_map (f : α₁ → α₂) (g : α₂ → β → β) (l : List α
(l.map f).foldr g init = l.foldr (fun x y => g (f x) y) init := by
induction l generalizing init <;> simp [*]
theorem foldl_map' {α β : Type u} (g : α β) (f : α α α) (f' : β β β) (a : α) (l : List α)
theorem foldl_map' (g : α β) (f : α α α) (f' : β β β) (a : α) (l : List α)
(h : x y, f' (g x) (g y) = g (f x y)) :
(l.map g).foldl f' (g a) = g (l.foldl f a) := by
induction l generalizing a
· simp
· simp [*, h]
theorem foldr_map' {α β : Type u} (g : α β) (f : α α α) (f' : β β β) (a : α) (l : List α)
theorem foldr_map' (g : α β) (f : α α α) (f' : β β β) (a : α) (l : List α)
(h : x y, f' (g x) (g y) = g (f x y)) :
(l.map g).foldr f' (g a) = g (l.foldr f a) := by
induction l generalizing a
@@ -2700,6 +2700,12 @@ theorem flatMap_reverse {β} (l : List α) (f : α → List β) : (l.reverse.fla
l.reverse.foldr f b = l.foldl (fun x y => f y x) b :=
(foldl_reverse ..).symm.trans <| by simp
theorem foldl_eq_foldr_reverse (l : List α) (f : β α β) (b) :
l.foldl f b = l.reverse.foldr (fun x y => f y x) b := by simp
theorem foldr_eq_foldl_reverse (l : List α) (f : α β β) (b) :
l.foldr f b = l.reverse.foldl (fun x y => f y x) b := by simp
@[simp] theorem reverse_replicate (n) (a : α) : reverse (replicate n a) = replicate n a :=
eq_replicate_iff.2
by rw [length_reverse, length_replicate],

View File

@@ -14,3 +14,4 @@ import Init.Data.List.Nat.Erase
import Init.Data.List.Nat.Find
import Init.Data.List.Nat.BEq
import Init.Data.List.Nat.Modify
import Init.Data.List.Nat.InsertIdx

View File

@@ -64,3 +64,82 @@ theorem getElem_eraseIdx_of_ge (l : List α) (i : Nat) (j : Nat) (h : j < (l.era
(l.eraseIdx i)[j] = l[j + 1]'(by rw [length_eraseIdx] at h; split at h <;> omega) := by
rw [getElem_eraseIdx, dif_neg]
omega
theorem eraseIdx_set_eq {l : List α} {i : Nat} {a : α} :
(l.set i a).eraseIdx i = l.eraseIdx i := by
apply ext_getElem
· simp [length_eraseIdx]
· intro n h₁ h₂
rw [getElem_eraseIdx, getElem_eraseIdx]
split <;>
· rw [getElem_set_ne]
omega
theorem eraseIdx_set_lt {l : List α} {i : Nat} {j : Nat} {a : α} (h : j < i) :
(l.set i a).eraseIdx j = (l.eraseIdx j).set (i - 1) a := by
apply ext_getElem
· simp [length_eraseIdx]
· intro n h₁ h₂
simp only [length_eraseIdx, length_set] at h₁
simp only [getElem_eraseIdx, getElem_set]
split
· split
· split
· rfl
· omega
· split
· omega
· rfl
· split
· split
· rfl
· omega
· have t : i - 1 n := by omega
simp [t]
theorem eraseIdx_set_gt {l : List α} {i : Nat} {j : Nat} {a : α} (h : i < j) :
(l.set i a).eraseIdx j = (l.eraseIdx j).set i a := by
apply ext_getElem
· simp [length_eraseIdx]
· intro n h₁ h₂
simp only [length_eraseIdx, length_set] at h₁
simp only [getElem_eraseIdx, getElem_set]
split
· rfl
· split
· split
· rfl
· omega
· have t : i n := by omega
simp [t]
@[simp] theorem set_getElem_succ_eraseIdx_succ
{l : List α} {i : Nat} (h : i + 1 < l.length) :
(l.eraseIdx (i + 1)).set i l[i + 1] = l.eraseIdx i := by
apply ext_getElem
· simp only [length_set, length_eraseIdx, h, reduceIte]
rw [if_pos]
omega
· intro n h₁ h₂
simp [getElem_set, getElem_eraseIdx]
split
· split
· omega
· simp_all
· split
· split
· rfl
· omega
· have t : ¬ n < i := by omega
simp [t]
@[simp] theorem eraseIdx_length_sub_one (l : List α) :
(l.eraseIdx (l.length - 1)) = l.dropLast := by
apply ext_getElem
· simp [length_eraseIdx]
omega
· intro n h₁ h₂
rw [getElem_eraseIdx_of_lt, getElem_dropLast]
simp_all
end List

View File

@@ -9,6 +9,32 @@ import Init.Data.List.Find
namespace List
open Nat
theorem find?_eq_some_iff_getElem {xs : List α} {p : α Bool} {b : α} :
xs.find? p = some b p b i h, xs[i] = b j : Nat, (hj : j < i) !p xs[j] := by
rw [find?_eq_some_iff_append]
simp only [Bool.not_eq_eq_eq_not, Bool.not_true, exists_and_right, and_congr_right_iff]
intro w
constructor
· rintro as, bs, rfl, h
refine as.length, ?_, ?_, ?_
· simp only [length_append, length_cons]
refine Nat.lt_add_of_pos_right (zero_lt_succ bs.length)
· rw [getElem_append_right (Nat.le_refl as.length)]
simp
· intro j h'
rw [getElem_append_left h']
exact h _ (getElem_mem h')
· rintro i, h, rfl, h'
refine xs.take i, xs.drop (i+1), ?_, ?_
· rw [getElem_cons_drop, take_append_drop]
· intro a m
rw [mem_take_iff_getElem] at m
obtain j, h, rfl := m
apply h'
omega
theorem findIdx?_eq_some_le_of_findIdx?_eq_some {xs : List α} {p q : α Bool} (w : x xs, p x q x) {i : Nat}
(h : xs.findIdx? p = some i) : j, j i xs.findIdx? q = some j := by
simp only [findIdx?_eq_findSome?_enum] at h

View File

@@ -0,0 +1,242 @@
/-
Copyright (c) 2014 Parikshit Khanna. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, Mario Carneiro
-/
prelude
import Init.Data.List.Nat.Modify
/-!
# insertIdx
Proves various lemmas about `List.insertIdx`.
-/
open Function
open Nat
namespace List
universe u
variable {α : Type u}
section InsertIdx
variable {a : α}
@[simp]
theorem insertIdx_zero (s : List α) (x : α) : insertIdx 0 x s = x :: s :=
rfl
@[simp]
theorem insertIdx_succ_nil (n : Nat) (a : α) : insertIdx (n + 1) a [] = [] :=
rfl
@[simp]
theorem insertIdx_succ_cons (s : List α) (hd x : α) (n : Nat) :
insertIdx (n + 1) x (hd :: s) = hd :: insertIdx n x s :=
rfl
theorem length_insertIdx : n as, (insertIdx n a as).length = if n as.length then as.length + 1 else as.length
| 0, _ => by simp
| n + 1, [] => by simp
| n + 1, a :: as => by
simp only [insertIdx_succ_cons, length_cons, length_insertIdx, Nat.add_le_add_iff_right]
split <;> rfl
theorem length_insertIdx_of_le_length (h : n length as) : length (insertIdx n a as) = length as + 1 := by
simp [length_insertIdx, h]
theorem length_insertIdx_of_length_lt (h : length as < n) : length (insertIdx n a as) = length as := by
simp [length_insertIdx, h]
theorem eraseIdx_insertIdx (n : Nat) (l : List α) : (l.insertIdx n a).eraseIdx n = l := by
rw [eraseIdx_eq_modifyTailIdx, insertIdx, modifyTailIdx_modifyTailIdx_eq]
exact modifyTailIdx_id _ _
theorem insertIdx_eraseIdx_of_ge :
n m as,
n < length as n m insertIdx m a (as.eraseIdx n) = (as.insertIdx (m + 1) a).eraseIdx n
| 0, 0, [], has, _ => (Nat.lt_irrefl _ has).elim
| 0, 0, _ :: as, _, _ => by simp [eraseIdx, insertIdx]
| 0, _ + 1, _ :: _, _, _ => rfl
| n + 1, m + 1, a :: as, has, hmn =>
congrArg (cons a) <|
insertIdx_eraseIdx_of_ge n m as (Nat.lt_of_succ_lt_succ has) (Nat.le_of_succ_le_succ hmn)
theorem insertIdx_eraseIdx_of_le :
n m as,
n < length as m n insertIdx m a (as.eraseIdx n) = (as.insertIdx m a).eraseIdx (n + 1)
| _, 0, _ :: _, _, _ => rfl
| n + 1, m + 1, a :: as, has, hmn =>
congrArg (cons a) <|
insertIdx_eraseIdx_of_le n m as (Nat.lt_of_succ_lt_succ has) (Nat.le_of_succ_le_succ hmn)
theorem insertIdx_comm (a b : α) :
(i j : Nat) (l : List α) (_ : i j) (_ : j length l),
(l.insertIdx i a).insertIdx (j + 1) b = (l.insertIdx j b).insertIdx i a
| 0, j, l => by simp [insertIdx]
| _ + 1, 0, _ => fun h => (Nat.not_lt_zero _ h).elim
| i + 1, j + 1, [] => by simp
| i + 1, j + 1, c :: l => fun h₀ h₁ => by
simp only [insertIdx_succ_cons, cons.injEq, true_and]
exact insertIdx_comm a b i j l (Nat.le_of_succ_le_succ h₀) (Nat.le_of_succ_le_succ h₁)
theorem mem_insertIdx {a b : α} :
{n : Nat} {l : List α} (_ : n l.length), a l.insertIdx n b a = b a l
| 0, as, _ => by simp
| _ + 1, [], h => (Nat.not_succ_le_zero _ h).elim
| n + 1, a' :: as, h => by
rw [List.insertIdx_succ_cons, mem_cons, mem_insertIdx (Nat.le_of_succ_le_succ h),
or_assoc, @or_comm (a = a'), or_assoc, mem_cons]
theorem insertIdx_of_length_lt (l : List α) (x : α) (n : Nat) (h : l.length < n) :
insertIdx n x l = l := by
induction l generalizing n with
| nil =>
cases n
· simp at h
· simp
| cons x l ih =>
cases n
· simp at h
· simp only [Nat.succ_lt_succ_iff, length] at h
simpa using ih _ h
@[simp]
theorem insertIdx_length_self (l : List α) (x : α) : insertIdx l.length x l = l ++ [x] := by
induction l with
| nil => simp
| cons x l ih => simpa using ih
theorem length_le_length_insertIdx (l : List α) (x : α) (n : Nat) :
l.length (insertIdx n x l).length := by
simp only [length_insertIdx]
split <;> simp
theorem length_insertIdx_le_succ (l : List α) (x : α) (n : Nat) :
(insertIdx n x l).length l.length + 1 := by
simp only [length_insertIdx]
split <;> simp
theorem getElem_insertIdx_of_lt {l : List α} {x : α} {n k : Nat} (hn : k < n)
(hk : k < (insertIdx n x l).length) :
(insertIdx n x l)[k] = l[k]'(by simp [length_insertIdx] at hk; split at hk <;> omega) := by
induction n generalizing k l with
| zero => simp at hn
| succ n ih =>
cases l with
| nil => simp
| cons _ _=>
cases k
· simp [get]
· rw [Nat.succ_lt_succ_iff] at hn
simpa using ih hn _
@[simp]
theorem getElem_insertIdx_self {l : List α} {x : α} {n : Nat} (hn : n < (insertIdx n x l).length) :
(insertIdx n x l)[n] = x := by
induction l generalizing n with
| nil =>
simp [length_insertIdx] at hn
split at hn
· simp_all
· omega
| cons _ _ ih =>
cases n
· simp
· simp only [insertIdx_succ_cons, length_cons, length_insertIdx, Nat.add_lt_add_iff_right] at hn ih
simpa using ih hn
theorem getElem_insertIdx_of_ge {l : List α} {x : α} {n k : Nat} (hn : n + 1 k)
(hk : k < (insertIdx n x l).length) :
(insertIdx n x l)[k] = l[k - 1]'(by simp [length_insertIdx] at hk; split at hk <;> omega) := by
induction l generalizing n k with
| nil =>
cases n with
| zero =>
simp only [insertIdx_zero, length_singleton, lt_one_iff] at hk
omega
| succ n => simp at hk
| cons _ _ ih =>
cases n with
| zero =>
simp only [insertIdx_zero] at hk
cases k with
| zero => omega
| succ k => simp
| succ n =>
cases k with
| zero => simp
| succ k =>
simp only [insertIdx_succ_cons, getElem_cons_succ]
rw [ih (by omega)]
cases k with
| zero => omega
| succ k => simp
theorem getElem_insertIdx {l : List α} {x : α} {n k : Nat} (h : k < (insertIdx n x l).length) :
(insertIdx n x l)[k] =
if h₁ : k < n then
l[k]'(by simp [length_insertIdx] at h; split at h <;> omega)
else
if h₂ : k = n then
x
else
l[k-1]'(by simp [length_insertIdx] at h; split at h <;> omega) := by
split <;> rename_i h₁
· rw [getElem_insertIdx_of_lt h₁]
· split <;> rename_i h₂
· subst h₂
rw [getElem_insertIdx_self h]
· rw [getElem_insertIdx_of_ge (by omega)]
theorem getElem?_insertIdx {l : List α} {x : α} {n k : Nat} :
(insertIdx n x l)[k]? =
if k < n then
l[k]?
else
if k = n then
if k l.length then some x else none
else
l[k-1]? := by
rw [getElem?_def]
split <;> rename_i h
· rw [getElem_insertIdx h]
simp only [length_insertIdx] at h
split <;> rename_i h₁
· rw [getElem?_def, dif_pos]
· split <;> rename_i h₂
· rw [if_pos]
split at h <;> omega
· rw [getElem?_def]
simp only [Option.some_eq_dite_none_right, exists_prop, and_true]
split at h <;> omega
· simp only [length_insertIdx] at h
split <;> rename_i h₁
· rw [getElem?_eq_none]
split at h <;> omega
· split <;> rename_i h₂
· rw [if_neg]
split at h <;> omega
· rw [getElem?_eq_none]
split at h <;> omega
theorem getElem?_insertIdx_of_lt {l : List α} {x : α} {n k : Nat} (h : k < n) :
(insertIdx n x l)[k]? = l[k]? := by
rw [getElem?_insertIdx, if_pos h]
theorem getElem?_insertIdx_self {l : List α} {x : α} {n : Nat} :
(insertIdx n x l)[n]? = if n l.length then some x else none := by
rw [getElem?_insertIdx, if_neg (by omega)]
simp
theorem getElem?_insertIdx_of_ge {l : List α} {x : α} {n k : Nat} (h : n + 1 k) :
(insertIdx n x l)[k]? = l[k - 1]? := by
rw [getElem?_insertIdx, if_neg (by omega), if_neg (by omega)]
end InsertIdx
end List

View File

@@ -110,6 +110,25 @@ theorem exists_of_modifyTailIdx (f : List α → List α) {n} {l : List α} (h :
_, _, (take_append_drop n l).symm, length_take_of_le h
_, _, eq, hl, hl eq modifyTailIdx_add (n := 0) ..
theorem modifyTailIdx_modifyTailIdx {f g : List α List α} (m : Nat) :
(n) (l : List α),
(l.modifyTailIdx f n).modifyTailIdx g (m + n) =
l.modifyTailIdx (fun l => (f l).modifyTailIdx g m) n
| 0, _ => rfl
| _ + 1, [] => rfl
| n + 1, a :: l => congrArg (List.cons a) (modifyTailIdx_modifyTailIdx m n l)
theorem modifyTailIdx_modifyTailIdx_le {f g : List α List α} (m n : Nat) (l : List α)
(h : n m) :
(l.modifyTailIdx f n).modifyTailIdx g m =
l.modifyTailIdx (fun l => (f l).modifyTailIdx g (m - n)) n := by
rcases Nat.exists_eq_add_of_le h with m, rfl
rw [Nat.add_comm, modifyTailIdx_modifyTailIdx, Nat.add_sub_cancel]
theorem modifyTailIdx_modifyTailIdx_eq {f g : List α List α} (n : Nat) (l : List α) :
(l.modifyTailIdx f n).modifyTailIdx g n = l.modifyTailIdx (g f) n := by
rw [modifyTailIdx_modifyTailIdx_le n n l (Nat.le_refl n), Nat.sub_self]; rfl
/-! ### modify -/
@[simp] theorem modify_nil (f : α α) (n) : [].modify f n = [] := by cases n <;> rfl

View File

@@ -108,7 +108,7 @@ theorem range'_eq_append_iff : range' s n = xs ++ ys ↔ ∃ k, k ≤ n ∧ xs =
@[simp] theorem find?_range'_eq_some {s n : Nat} {i : Nat} {p : Nat Bool} :
(range' s n).find? p = some i p i i range' s n j, s j j < i !p j := by
rw [find?_eq_some]
rw [find?_eq_some_iff_append]
simp only [Bool.not_eq_eq_eq_not, Bool.not_true, exists_and_right, mem_range'_1,
and_congr_right_iff]
simp only [range'_eq_append_iff, eq_comm (a := i :: _), range'_eq_cons_iff]
@@ -282,7 +282,7 @@ theorem find?_iota_eq_none {n : Nat} {p : Nat → Bool} :
@[simp] theorem find?_iota_eq_some {n : Nat} {i : Nat} {p : Nat Bool} :
(iota n).find? p = some i p i i iota n j, i < j j n !p j := by
rw [find?_eq_some]
rw [find?_eq_some_iff_append]
simp only [iota_eq_reverse_range', reverse_eq_append_iff, reverse_cons, append_assoc, cons_append,
nil_append, Bool.not_eq_eq_eq_not, Bool.not_true, exists_and_right, mem_reverse, mem_range'_1,
and_congr_right_iff]

View File

@@ -52,4 +52,29 @@ protected theorem getElem?_ofFn (f : Fin n → α) (i) : (ofFn f)[i]? = if h : i
rw [dif_neg] <;>
simpa using h
/-- `ofFn` on an empty domain is the empty list. -/
@[simp]
theorem ofFn_zero (f : Fin 0 α) : ofFn f = [] :=
ext_get (by simp) (fun i hi₁ hi₂ => by contradiction)
@[simp]
theorem ofFn_succ {n} (f : Fin (n + 1) α) : ofFn f = f 0 :: ofFn fun i => f i.succ :=
ext_get (by simp) (fun i hi₁ hi₂ => by
cases i
· simp
· simp)
@[simp]
theorem ofFn_eq_nil_iff {f : Fin n α} : ofFn f = [] n = 0 := by
cases n <;> simp only [ofFn_zero, ofFn_succ, eq_self_iff_true, Nat.succ_ne_zero, reduceCtorEq]
theorem head_ofFn {n} (f : Fin n α) (h : ofFn f []) :
(ofFn f).head h = f 0, Nat.pos_of_ne_zero (mt ofFn_eq_nil_iff.2 h) := by
rw [ getElem_zero (length_ofFn _ Nat.pos_of_ne_zero (mt ofFn_eq_nil_iff.2 h)),
List.getElem_ofFn]
theorem getLast_ofFn {n} (f : Fin n α) (h : ofFn f []) :
(ofFn f).getLast h = f n - 1, Nat.sub_one_lt (mt ofFn_eq_nil_iff.2 h) := by
simp [getLast_eq_getElem, length_ofFn, List.getElem_ofFn]
end List

View File

@@ -190,7 +190,7 @@ theorem set_drop {l : List α} {n m : Nat} {a : α} :
theorem take_concat_get (l : List α) (i : Nat) (h : i < l.length) :
(l.take i).concat l[i] = l.take (i+1) :=
Eq.symm <| (append_left_inj _).1 <| (take_append_drop (i+1) l).trans <| by
rw [concat_eq_append, append_assoc, singleton_append, get_drop_eq_drop, take_append_drop]
rw [concat_eq_append, append_assoc, singleton_append, getElem_cons_drop_succ_eq_drop, take_append_drop]
@[deprecated take_succ_cons (since := "2024-07-25")]
theorem take_cons_succ : (a::as).take (i+1) = a :: as.take i := rfl

View File

@@ -357,7 +357,7 @@ theorem testBit_two_pow_of_ne {n m : Nat} (hm : n ≠ m) : testBit (2 ^ n) m = f
| zero => simp
| succ n =>
rw [mod_eq_of_lt (a := 1) (Nat.one_lt_two_pow (by omega)), mod_two_eq_one_iff_testBit_zero, testBit_two_pow_sub_one ]
simp only [zero_lt_succ, decide_True]
simp only [zero_lt_succ, decide_true]
@[simp] theorem mod_two_pos_mod_two_eq_one : x % 2 ^ j % 2 = 1 (0 < j) x % 2 = 1 := by
rw [mod_two_eq_one_iff_testBit_zero, testBit_mod_two_pow]

View File

@@ -374,9 +374,15 @@ end choice
-- See `Init.Data.Option.List` for lemmas about `toList`.
@[simp] theorem or_some : (some a).or o = some a := rfl
@[simp] theorem some_or : (some a).or o = some a := rfl
@[simp] theorem none_or : none.or o = o := rfl
@[deprecated some_or (since := "2024-11-03")] theorem or_some : (some a).or o = some a := rfl
/-- This will be renamed to `or_some` once the existing deprecated lemma is removed. -/
@[simp] theorem or_some' {o : Option α} : o.or (some a) = o.getD a := by
cases o <;> rfl
theorem or_eq_bif : or o o' = bif o.isSome then o else o' := by
cases o <;> rfl

View File

@@ -22,6 +22,48 @@ structure Int8 where
-/
toUInt8 : UInt8
/--
The type of signed 16-bit integers. This type has special support in the
compiler to make it actually 16 bits rather than wrapping a `Nat`.
-/
structure Int16 where
/--
Obtain the `UInt16` that is 2's complement equivalent to the `Int16`.
-/
toUInt16 : UInt16
/--
The type of signed 32-bit integers. This type has special support in the
compiler to make it actually 32 bits rather than wrapping a `Nat`.
-/
structure Int32 where
/--
Obtain the `UInt32` that is 2's complement equivalent to the `Int32`.
-/
toUInt32 : UInt32
/--
The type of signed 64-bit integers. This type has special support in the
compiler to make it actually 64 bits rather than wrapping a `Nat`.
-/
structure Int64 where
/--
Obtain the `UInt64` that is 2's complement equivalent to the `Int64`.
-/
toUInt64 : UInt64
/--
A `ISize` is a signed integer with the size of a word for the platform's architecture.
For example, if running on a 32-bit machine, ISize is equivalent to `Int32`.
Or on a 64-bit machine, `Int64`.
-/
structure ISize where
/--
Obtain the `USize` that is 2's complement equivalent to the `ISize`.
-/
toUSize : USize
/-- The size of type `Int8`, that is, `2^8 = 256`. -/
abbrev Int8.size : Nat := 256
@@ -32,12 +74,16 @@ Obtain the `BitVec` that contains the 2's complement representation of the `Int8
@[extern "lean_int8_of_int"]
def Int8.ofInt (i : @& Int) : Int8 := BitVec.ofInt 8 i
@[extern "lean_int8_of_int"]
@[extern "lean_int8_of_nat"]
def Int8.ofNat (n : @& Nat) : Int8 := BitVec.ofNat 8 n
abbrev Int.toInt8 := Int8.ofInt
abbrev Nat.toInt8 := Int8.ofNat
@[extern "lean_int8_to_int"]
def Int8.toInt (i : Int8) : Int := i.toBitVec.toInt
/--
This function has the same behavior as `Int.toNat` for negative numbers.
If you want to obtain the 2's complement representation use `toBitVec`.
-/
@[inline] def Int8.toNat (i : Int8) : Nat := i.toInt.toNat
@[extern "lean_int8_neg"]
def Int8.neg (i : Int8) : Int8 := -i.toBitVec
@@ -58,7 +104,7 @@ def Int8.mul (a b : Int8) : Int8 := ⟨⟨a.toBitVec * b.toBitVec⟩⟩
@[extern "lean_int8_div"]
def Int8.div (a b : Int8) : Int8 := BitVec.sdiv a.toBitVec b.toBitVec
@[extern "lean_int8_mod"]
def Int8.mod (a b : Int8) : Int8 := BitVec.smod a.toBitVec b.toBitVec
def Int8.mod (a b : Int8) : Int8 := BitVec.srem a.toBitVec b.toBitVec
@[extern "lean_int8_land"]
def Int8.land (a b : Int8) : Int8 := a.toBitVec &&& b.toBitVec
@[extern "lean_int8_lor"]
@@ -66,9 +112,9 @@ def Int8.lor (a b : Int8) : Int8 := ⟨⟨a.toBitVec ||| b.toBitVec⟩⟩
@[extern "lean_int8_xor"]
def Int8.xor (a b : Int8) : Int8 := a.toBitVec ^^^ b.toBitVec
@[extern "lean_int8_shift_left"]
def Int8.shiftLeft (a b : Int8) : Int8 := a.toBitVec <<< (mod b 8).toBitVec
def Int8.shiftLeft (a b : Int8) : Int8 := a.toBitVec <<< (b.toBitVec.smod 8)
@[extern "lean_int8_shift_right"]
def Int8.shiftRight (a b : Int8) : Int8 := BitVec.sshiftRight' a.toBitVec (mod b 8).toBitVec
def Int8.shiftRight (a b : Int8) : Int8 := BitVec.sshiftRight' a.toBitVec (b.toBitVec.smod 8)
@[extern "lean_int8_complement"]
def Int8.complement (a : Int8) : Int8 := ~~~a.toBitVec
@@ -114,3 +160,429 @@ instance (a b : Int8) : Decidable (a < b) := Int8.decLt a b
instance (a b : Int8) : Decidable (a b) := Int8.decLe a b
instance : Max Int8 := maxOfLe
instance : Min Int8 := minOfLe
/-- The size of type `Int16`, that is, `2^16 = 65536`. -/
abbrev Int16.size : Nat := 65536
/--
Obtain the `BitVec` that contains the 2's complement representation of the `Int16`.
-/
@[inline] def Int16.toBitVec (x : Int16) : BitVec 16 := x.toUInt16.toBitVec
@[extern "lean_int16_of_int"]
def Int16.ofInt (i : @& Int) : Int16 := BitVec.ofInt 16 i
@[extern "lean_int16_of_nat"]
def Int16.ofNat (n : @& Nat) : Int16 := BitVec.ofNat 16 n
abbrev Int.toInt16 := Int16.ofInt
abbrev Nat.toInt16 := Int16.ofNat
@[extern "lean_int16_to_int"]
def Int16.toInt (i : Int16) : Int := i.toBitVec.toInt
/--
This function has the same behavior as `Int.toNat` for negative numbers.
If you want to obtain the 2's complement representation use `toBitVec`.
-/
@[inline] def Int16.toNat (i : Int16) : Nat := i.toInt.toNat
@[extern "lean_int16_to_int8"]
def Int16.toInt8 (a : Int16) : Int8 := a.toBitVec.signExtend 8
@[extern "lean_int8_to_int16"]
def Int8.toInt16 (a : Int8) : Int16 := a.toBitVec.signExtend 16
@[extern "lean_int16_neg"]
def Int16.neg (i : Int16) : Int16 := -i.toBitVec
instance : ToString Int16 where
toString i := toString i.toInt
instance : OfNat Int16 n := Int16.ofNat n
instance : Neg Int16 where
neg := Int16.neg
@[extern "lean_int16_add"]
def Int16.add (a b : Int16) : Int16 := a.toBitVec + b.toBitVec
@[extern "lean_int16_sub"]
def Int16.sub (a b : Int16) : Int16 := a.toBitVec - b.toBitVec
@[extern "lean_int16_mul"]
def Int16.mul (a b : Int16) : Int16 := a.toBitVec * b.toBitVec
@[extern "lean_int16_div"]
def Int16.div (a b : Int16) : Int16 := BitVec.sdiv a.toBitVec b.toBitVec
@[extern "lean_int16_mod"]
def Int16.mod (a b : Int16) : Int16 := BitVec.srem a.toBitVec b.toBitVec
@[extern "lean_int16_land"]
def Int16.land (a b : Int16) : Int16 := a.toBitVec &&& b.toBitVec
@[extern "lean_int16_lor"]
def Int16.lor (a b : Int16) : Int16 := a.toBitVec ||| b.toBitVec
@[extern "lean_int16_xor"]
def Int16.xor (a b : Int16) : Int16 := a.toBitVec ^^^ b.toBitVec
@[extern "lean_int16_shift_left"]
def Int16.shiftLeft (a b : Int16) : Int16 := a.toBitVec <<< (b.toBitVec.smod 16)
@[extern "lean_int16_shift_right"]
def Int16.shiftRight (a b : Int16) : Int16 := BitVec.sshiftRight' a.toBitVec (b.toBitVec.smod 16)
@[extern "lean_int16_complement"]
def Int16.complement (a : Int16) : Int16 := ~~~a.toBitVec
@[extern "lean_int16_dec_eq"]
def Int16.decEq (a b : Int16) : Decidable (a = b) :=
match a, b with
| n, m =>
if h : n = m then
isTrue <| h rfl
else
isFalse (fun h' => Int16.noConfusion h' (fun h' => absurd h' h))
def Int16.lt (a b : Int16) : Prop := a.toBitVec.slt b.toBitVec
def Int16.le (a b : Int16) : Prop := a.toBitVec.sle b.toBitVec
instance : Inhabited Int16 where
default := 0
instance : Add Int16 := Int16.add
instance : Sub Int16 := Int16.sub
instance : Mul Int16 := Int16.mul
instance : Mod Int16 := Int16.mod
instance : Div Int16 := Int16.div
instance : LT Int16 := Int16.lt
instance : LE Int16 := Int16.le
instance : Complement Int16 := Int16.complement
instance : AndOp Int16 := Int16.land
instance : OrOp Int16 := Int16.lor
instance : Xor Int16 := Int16.xor
instance : ShiftLeft Int16 := Int16.shiftLeft
instance : ShiftRight Int16 := Int16.shiftRight
instance : DecidableEq Int16 := Int16.decEq
@[extern "lean_int16_dec_lt"]
def Int16.decLt (a b : Int16) : Decidable (a < b) :=
inferInstanceAs (Decidable (a.toBitVec.slt b.toBitVec))
@[extern "lean_int16_dec_le"]
def Int16.decLe (a b : Int16) : Decidable (a b) :=
inferInstanceAs (Decidable (a.toBitVec.sle b.toBitVec))
instance (a b : Int16) : Decidable (a < b) := Int16.decLt a b
instance (a b : Int16) : Decidable (a b) := Int16.decLe a b
instance : Max Int16 := maxOfLe
instance : Min Int16 := minOfLe
/-- The size of type `Int32`, that is, `2^32 = 4294967296`. -/
abbrev Int32.size : Nat := 4294967296
/--
Obtain the `BitVec` that contains the 2's complement representation of the `Int32`.
-/
@[inline] def Int32.toBitVec (x : Int32) : BitVec 32 := x.toUInt32.toBitVec
@[extern "lean_int32_of_int"]
def Int32.ofInt (i : @& Int) : Int32 := BitVec.ofInt 32 i
@[extern "lean_int32_of_nat"]
def Int32.ofNat (n : @& Nat) : Int32 := BitVec.ofNat 32 n
abbrev Int.toInt32 := Int32.ofInt
abbrev Nat.toInt32 := Int32.ofNat
@[extern "lean_int32_to_int"]
def Int32.toInt (i : Int32) : Int := i.toBitVec.toInt
/--
This function has the same behavior as `Int.toNat` for negative numbers.
If you want to obtain the 2's complement representation use `toBitVec`.
-/
@[inline] def Int32.toNat (i : Int32) : Nat := i.toInt.toNat
@[extern "lean_int32_to_int8"]
def Int32.toInt8 (a : Int32) : Int8 := a.toBitVec.signExtend 8
@[extern "lean_int32_to_int16"]
def Int32.toInt16 (a : Int32) : Int16 := a.toBitVec.signExtend 16
@[extern "lean_int8_to_int32"]
def Int8.toInt32 (a : Int8) : Int32 := a.toBitVec.signExtend 32
@[extern "lean_int16_to_int32"]
def Int16.toInt32 (a : Int16) : Int32 := a.toBitVec.signExtend 32
@[extern "lean_int32_neg"]
def Int32.neg (i : Int32) : Int32 := -i.toBitVec
instance : ToString Int32 where
toString i := toString i.toInt
instance : OfNat Int32 n := Int32.ofNat n
instance : Neg Int32 where
neg := Int32.neg
@[extern "lean_int32_add"]
def Int32.add (a b : Int32) : Int32 := a.toBitVec + b.toBitVec
@[extern "lean_int32_sub"]
def Int32.sub (a b : Int32) : Int32 := a.toBitVec - b.toBitVec
@[extern "lean_int32_mul"]
def Int32.mul (a b : Int32) : Int32 := a.toBitVec * b.toBitVec
@[extern "lean_int32_div"]
def Int32.div (a b : Int32) : Int32 := BitVec.sdiv a.toBitVec b.toBitVec
@[extern "lean_int32_mod"]
def Int32.mod (a b : Int32) : Int32 := BitVec.srem a.toBitVec b.toBitVec
@[extern "lean_int32_land"]
def Int32.land (a b : Int32) : Int32 := a.toBitVec &&& b.toBitVec
@[extern "lean_int32_lor"]
def Int32.lor (a b : Int32) : Int32 := a.toBitVec ||| b.toBitVec
@[extern "lean_int32_xor"]
def Int32.xor (a b : Int32) : Int32 := a.toBitVec ^^^ b.toBitVec
@[extern "lean_int32_shift_left"]
def Int32.shiftLeft (a b : Int32) : Int32 := a.toBitVec <<< (b.toBitVec.smod 32)
@[extern "lean_int32_shift_right"]
def Int32.shiftRight (a b : Int32) : Int32 := BitVec.sshiftRight' a.toBitVec (b.toBitVec.smod 32)
@[extern "lean_int32_complement"]
def Int32.complement (a : Int32) : Int32 := ~~~a.toBitVec
@[extern "lean_int32_dec_eq"]
def Int32.decEq (a b : Int32) : Decidable (a = b) :=
match a, b with
| n, m =>
if h : n = m then
isTrue <| h rfl
else
isFalse (fun h' => Int32.noConfusion h' (fun h' => absurd h' h))
def Int32.lt (a b : Int32) : Prop := a.toBitVec.slt b.toBitVec
def Int32.le (a b : Int32) : Prop := a.toBitVec.sle b.toBitVec
instance : Inhabited Int32 where
default := 0
instance : Add Int32 := Int32.add
instance : Sub Int32 := Int32.sub
instance : Mul Int32 := Int32.mul
instance : Mod Int32 := Int32.mod
instance : Div Int32 := Int32.div
instance : LT Int32 := Int32.lt
instance : LE Int32 := Int32.le
instance : Complement Int32 := Int32.complement
instance : AndOp Int32 := Int32.land
instance : OrOp Int32 := Int32.lor
instance : Xor Int32 := Int32.xor
instance : ShiftLeft Int32 := Int32.shiftLeft
instance : ShiftRight Int32 := Int32.shiftRight
instance : DecidableEq Int32 := Int32.decEq
@[extern "lean_int32_dec_lt"]
def Int32.decLt (a b : Int32) : Decidable (a < b) :=
inferInstanceAs (Decidable (a.toBitVec.slt b.toBitVec))
@[extern "lean_int32_dec_le"]
def Int32.decLe (a b : Int32) : Decidable (a b) :=
inferInstanceAs (Decidable (a.toBitVec.sle b.toBitVec))
instance (a b : Int32) : Decidable (a < b) := Int32.decLt a b
instance (a b : Int32) : Decidable (a b) := Int32.decLe a b
instance : Max Int32 := maxOfLe
instance : Min Int32 := minOfLe
/-- The size of type `Int64`, that is, `2^64 = 18446744073709551616`. -/
abbrev Int64.size : Nat := 18446744073709551616
/--
Obtain the `BitVec` that contains the 2's complement representation of the `Int64`.
-/
@[inline] def Int64.toBitVec (x : Int64) : BitVec 64 := x.toUInt64.toBitVec
@[extern "lean_int64_of_int"]
def Int64.ofInt (i : @& Int) : Int64 := BitVec.ofInt 64 i
@[extern "lean_int64_of_nat"]
def Int64.ofNat (n : @& Nat) : Int64 := BitVec.ofNat 64 n
abbrev Int.toInt64 := Int64.ofInt
abbrev Nat.toInt64 := Int64.ofNat
@[extern "lean_int64_to_int_sint"]
def Int64.toInt (i : Int64) : Int := i.toBitVec.toInt
/--
This function has the same behavior as `Int.toNat` for negative numbers.
If you want to obtain the 2's complement representation use `toBitVec`.
-/
@[inline] def Int64.toNat (i : Int64) : Nat := i.toInt.toNat
@[extern "lean_int64_to_int8"]
def Int64.toInt8 (a : Int64) : Int8 := a.toBitVec.signExtend 8
@[extern "lean_int64_to_int16"]
def Int64.toInt16 (a : Int64) : Int16 := a.toBitVec.signExtend 16
@[extern "lean_int64_to_int32"]
def Int64.toInt32 (a : Int64) : Int32 := a.toBitVec.signExtend 32
@[extern "lean_int8_to_int64"]
def Int8.toInt64 (a : Int8) : Int64 := a.toBitVec.signExtend 64
@[extern "lean_int16_to_int64"]
def Int16.toInt64 (a : Int16) : Int64 := a.toBitVec.signExtend 64
@[extern "lean_int32_to_int64"]
def Int32.toInt64 (a : Int32) : Int64 := a.toBitVec.signExtend 64
@[extern "lean_int64_neg"]
def Int64.neg (i : Int64) : Int64 := -i.toBitVec
instance : ToString Int64 where
toString i := toString i.toInt
instance : OfNat Int64 n := Int64.ofNat n
instance : Neg Int64 where
neg := Int64.neg
@[extern "lean_int64_add"]
def Int64.add (a b : Int64) : Int64 := a.toBitVec + b.toBitVec
@[extern "lean_int64_sub"]
def Int64.sub (a b : Int64) : Int64 := a.toBitVec - b.toBitVec
@[extern "lean_int64_mul"]
def Int64.mul (a b : Int64) : Int64 := a.toBitVec * b.toBitVec
@[extern "lean_int64_div"]
def Int64.div (a b : Int64) : Int64 := BitVec.sdiv a.toBitVec b.toBitVec
@[extern "lean_int64_mod"]
def Int64.mod (a b : Int64) : Int64 := BitVec.srem a.toBitVec b.toBitVec
@[extern "lean_int64_land"]
def Int64.land (a b : Int64) : Int64 := a.toBitVec &&& b.toBitVec
@[extern "lean_int64_lor"]
def Int64.lor (a b : Int64) : Int64 := a.toBitVec ||| b.toBitVec
@[extern "lean_int64_xor"]
def Int64.xor (a b : Int64) : Int64 := a.toBitVec ^^^ b.toBitVec
@[extern "lean_int64_shift_left"]
def Int64.shiftLeft (a b : Int64) : Int64 := a.toBitVec <<< (b.toBitVec.smod 64)
@[extern "lean_int64_shift_right"]
def Int64.shiftRight (a b : Int64) : Int64 := BitVec.sshiftRight' a.toBitVec (b.toBitVec.smod 64)
@[extern "lean_int64_complement"]
def Int64.complement (a : Int64) : Int64 := ~~~a.toBitVec
@[extern "lean_int64_dec_eq"]
def Int64.decEq (a b : Int64) : Decidable (a = b) :=
match a, b with
| n, m =>
if h : n = m then
isTrue <| h rfl
else
isFalse (fun h' => Int64.noConfusion h' (fun h' => absurd h' h))
def Int64.lt (a b : Int64) : Prop := a.toBitVec.slt b.toBitVec
def Int64.le (a b : Int64) : Prop := a.toBitVec.sle b.toBitVec
instance : Inhabited Int64 where
default := 0
instance : Add Int64 := Int64.add
instance : Sub Int64 := Int64.sub
instance : Mul Int64 := Int64.mul
instance : Mod Int64 := Int64.mod
instance : Div Int64 := Int64.div
instance : LT Int64 := Int64.lt
instance : LE Int64 := Int64.le
instance : Complement Int64 := Int64.complement
instance : AndOp Int64 := Int64.land
instance : OrOp Int64 := Int64.lor
instance : Xor Int64 := Int64.xor
instance : ShiftLeft Int64 := Int64.shiftLeft
instance : ShiftRight Int64 := Int64.shiftRight
instance : DecidableEq Int64 := Int64.decEq
@[extern "lean_int64_dec_lt"]
def Int64.decLt (a b : Int64) : Decidable (a < b) :=
inferInstanceAs (Decidable (a.toBitVec.slt b.toBitVec))
@[extern "lean_int64_dec_le"]
def Int64.decLe (a b : Int64) : Decidable (a b) :=
inferInstanceAs (Decidable (a.toBitVec.sle b.toBitVec))
instance (a b : Int64) : Decidable (a < b) := Int64.decLt a b
instance (a b : Int64) : Decidable (a b) := Int64.decLe a b
instance : Max Int64 := maxOfLe
instance : Min Int64 := minOfLe
/-- The size of type `ISize`, that is, `2^System.Platform.numBits`. -/
abbrev ISize.size : Nat := 2^System.Platform.numBits
/--
Obtain the `BitVec` that contains the 2's complement representation of the `ISize`.
-/
@[inline] def ISize.toBitVec (x : ISize) : BitVec System.Platform.numBits := x.toUSize.toBitVec
@[extern "lean_isize_of_int"]
def ISize.ofInt (i : @& Int) : ISize := BitVec.ofInt System.Platform.numBits i
@[extern "lean_isize_of_nat"]
def ISize.ofNat (n : @& Nat) : ISize := BitVec.ofNat System.Platform.numBits n
abbrev Int.toISize := ISize.ofInt
abbrev Nat.toISize := ISize.ofNat
@[extern "lean_isize_to_int"]
def ISize.toInt (i : ISize) : Int := i.toBitVec.toInt
/--
This function has the same behavior as `Int.toNat` for negative numbers.
If you want to obtain the 2's complement representation use `toBitVec`.
-/
@[inline] def ISize.toNat (i : ISize) : Nat := i.toInt.toNat
@[extern "lean_isize_to_int32"]
def ISize.toInt32 (a : ISize) : Int32 := a.toBitVec.signExtend 32
/--
Upcast `ISize` to `Int64`. This function is losless as `ISize` is either `Int32` or `Int64`.
-/
@[extern "lean_isize_to_int64"]
def ISize.toInt64 (a : ISize) : Int64 := a.toBitVec.signExtend 64
/--
Upcast `Int32` to `ISize`. This function is losless as `ISize` is either `Int32` or `Int64`.
-/
@[extern "lean_int32_to_isize"]
def Int32.toISize (a : Int32) : ISize := a.toBitVec.signExtend System.Platform.numBits
@[extern "lean_int64_to_isize"]
def Int64.toISize (a : Int64) : ISize := a.toBitVec.signExtend System.Platform.numBits
@[extern "lean_isize_neg"]
def ISize.neg (i : ISize) : ISize := -i.toBitVec
instance : ToString ISize where
toString i := toString i.toInt
instance : OfNat ISize n := ISize.ofNat n
instance : Neg ISize where
neg := ISize.neg
@[extern "lean_isize_add"]
def ISize.add (a b : ISize) : ISize := a.toBitVec + b.toBitVec
@[extern "lean_isize_sub"]
def ISize.sub (a b : ISize) : ISize := a.toBitVec - b.toBitVec
@[extern "lean_isize_mul"]
def ISize.mul (a b : ISize) : ISize := a.toBitVec * b.toBitVec
@[extern "lean_isize_div"]
def ISize.div (a b : ISize) : ISize := BitVec.sdiv a.toBitVec b.toBitVec
@[extern "lean_isize_mod"]
def ISize.mod (a b : ISize) : ISize := BitVec.srem a.toBitVec b.toBitVec
@[extern "lean_isize_land"]
def ISize.land (a b : ISize) : ISize := a.toBitVec &&& b.toBitVec
@[extern "lean_isize_lor"]
def ISize.lor (a b : ISize) : ISize := a.toBitVec ||| b.toBitVec
@[extern "lean_isize_xor"]
def ISize.xor (a b : ISize) : ISize := a.toBitVec ^^^ b.toBitVec
@[extern "lean_isize_shift_left"]
def ISize.shiftLeft (a b : ISize) : ISize := a.toBitVec <<< (b.toBitVec.smod System.Platform.numBits)
@[extern "lean_isize_shift_right"]
def ISize.shiftRight (a b : ISize) : ISize := BitVec.sshiftRight' a.toBitVec (b.toBitVec.smod System.Platform.numBits)
@[extern "lean_isize_complement"]
def ISize.complement (a : ISize) : ISize := ~~~a.toBitVec
@[extern "lean_isize_dec_eq"]
def ISize.decEq (a b : ISize) : Decidable (a = b) :=
match a, b with
| n, m =>
if h : n = m then
isTrue <| h rfl
else
isFalse (fun h' => ISize.noConfusion h' (fun h' => absurd h' h))
def ISize.lt (a b : ISize) : Prop := a.toBitVec.slt b.toBitVec
def ISize.le (a b : ISize) : Prop := a.toBitVec.sle b.toBitVec
instance : Inhabited ISize where
default := 0
instance : Add ISize := ISize.add
instance : Sub ISize := ISize.sub
instance : Mul ISize := ISize.mul
instance : Mod ISize := ISize.mod
instance : Div ISize := ISize.div
instance : LT ISize := ISize.lt
instance : LE ISize := ISize.le
instance : Complement ISize := ISize.complement
instance : AndOp ISize := ISize.land
instance : OrOp ISize := ISize.lor
instance : Xor ISize := ISize.xor
instance : ShiftLeft ISize := ISize.shiftLeft
instance : ShiftRight ISize := ISize.shiftRight
instance : DecidableEq ISize := ISize.decEq
@[extern "lean_isize_dec_lt"]
def ISize.decLt (a b : ISize) : Decidable (a < b) :=
inferInstanceAs (Decidable (a.toBitVec.slt b.toBitVec))
@[extern "lean_isize_dec_le"]
def ISize.decLe (a b : ISize) : Decidable (a b) :=
inferInstanceAs (Decidable (a.toBitVec.sle b.toBitVec))
instance (a b : ISize) : Decidable (a < b) := ISize.decLt a b
instance (a b : ISize) : Decidable (a b) := ISize.decLe a b
instance : Max ISize := maxOfLe
instance : Min ISize := minOfLe

View File

@@ -211,10 +211,13 @@ instance : GetElem (List α) Nat α fun as i => i < as.length where
| _ :: _, 0, _ => .head ..
| _ :: l, _+1, _ => .tail _ (getElem_mem (l := l) ..)
theorem get_drop_eq_drop (as : List α) (i : Nat) (h : i < as.length) : as[i] :: as.drop (i+1) = as.drop i :=
theorem getElem_cons_drop_succ_eq_drop {as : List α} {i : Nat} (h : i < as.length) :
as[i] :: as.drop (i+1) = as.drop i :=
match as, i with
| _::_, 0 => rfl
| _::_, i+1 => get_drop_eq_drop _ i _
| _::_, i+1 => getElem_cons_drop_succ_eq_drop (i := i) _
@[deprecated (since := "2024-11-05")] abbrev get_drop_eq_drop := @getElem_cons_drop_succ_eq_drop
end List

View File

@@ -263,7 +263,7 @@ theorem Bool.not_eq_false' (b : Bool) : ((!b) = false) = (b = true) := by simp
of_decide_eq_false, decide_eq_false
@[simp] theorem decide_not [g : Decidable p] [h : Decidable (Not p)] : decide (Not p) = !(decide p) := by
cases g <;> (rename_i gp; simp [gp]; rfl)
cases g <;> (rename_i gp; simp [gp])
theorem not_decide_eq_true [h : Decidable p] : ((!decide p) = true) = ¬ p := by simp
@[simp] theorem heq_eq_eq (a b : α) : HEq a b = (a = b) := propext <| Iff.intro eq_of_heq heq_of_eq
@@ -277,8 +277,10 @@ theorem beq_self_eq_true' [DecidableEq α] (a : α) : (a == a) = true := by simp
@[simp] theorem bne_self_eq_false [BEq α] [LawfulBEq α] (a : α) : (a != a) = false := by simp [bne]
theorem bne_self_eq_false' [DecidableEq α] (a : α) : (a != a) = false := by simp
@[simp] theorem decide_False : decide False = false := rfl
@[simp] theorem decide_True : decide True = true := rfl
set_option linter.missingDocs false in
@[deprecated decide_false (since := "2024-11-05")] abbrev decide_False := decide_false
set_option linter.missingDocs false in
@[deprecated decide_true (since := "2024-11-05")] abbrev decide_True := decide_true
@[simp] theorem bne_iff_ne [BEq α] [LawfulBEq α] {a b : α} : a != b a b := by
simp [bne]; rw [ beq_iff_eq (a := a) (b := b)]; simp [-beq_iff_eq]

View File

@@ -272,12 +272,20 @@ macro nextTk:"next " args:binderIdent* arrowTk:" => " tac:tacticSeq : tactic =>
-- Limit ref variability for incrementality; see Note [Incremental Macros]
withRef arrowTk `(tactic| case%$nextTk _ $args* =>%$arrowTk $tac)
/-- `all_goals tac` runs `tac` on each goal, concatenating the resulting goals, if any. -/
/--
`all_goals tac` runs `tac` on each goal, concatenating the resulting goals.
If the tactic fails on any goal, the entire `all_goals` tactic fails.
See also `any_goals tac`.
-/
syntax (name := allGoals) "all_goals " tacticSeq : tactic
/--
`any_goals tac` applies the tactic `tac` to every goal, and succeeds if at
least one application succeeds.
`any_goals tac` applies the tactic `tac` to every goal,
concating the resulting goals for successful tactic applications.
If the tactic fails on all of the goals, the entire `any_goals` tactic fails.
This tactic is like `all_goals try tac` except that it fails if none of the applications of `tac` succeeds.
-/
syntax (name := anyGoals) "any_goals " tacticSeq : tactic

View File

@@ -957,7 +957,7 @@ where
let mut s : CollectFVars.State := {}
for discr in discrs do
s := collectFVars s ( instantiateMVars ( inferType discr))
let (indicesFVar, indicesNonFVar) := indices.split Expr.isFVar
let (indicesFVar, indicesNonFVar) := indices.partition Expr.isFVar
let indicesFVar := indicesFVar.map Expr.fvarId!
let mut toAdd := #[]
for fvarId in s.fvarSet.toList do

View File

@@ -35,9 +35,13 @@ Reconstruct bit by bit which value expression must have had which `BitVec` value
expression - pair values.
-/
def reconstructCounterExample (var2Cnf : Std.HashMap BVBit Nat) (assignment : Array (Bool × Nat))
(aigSize : Nat) (atomsAssignment : Std.HashMap Nat (Nat × Expr)) :
(aigSize : Nat) (atomsAssignment : Std.HashMap Nat (Nat × Expr × Bool)) :
Array (Expr × BVExpr.PackedBitVec) := Id.run do
let mut sparseMap : Std.HashMap Nat (RBMap Nat Bool Ord.compare) := {}
let filter bvBit _ :=
let (_, _, synthetic) := atomsAssignment.get! bvBit.var
!synthetic
let var2Cnf := var2Cnf.filter filter
for (bitVar, cnfVar) in var2Cnf.toArray do
/-
The setup of the variables in CNF is as follows:
@@ -70,7 +74,7 @@ def reconstructCounterExample (var2Cnf : Std.HashMap BVBit Nat) (assignment : Ar
if bitValue then
value := value ||| (1 <<< currentBit)
currentBit := currentBit + 1
let atomExpr := atomsAssignment.get! bitVecVar |>.snd
let (_, atomExpr, _) := atomsAssignment.get! bitVecVar
finalMap := finalMap.push (atomExpr, BitVec.ofNat currentBit value)
return finalMap
@@ -101,7 +105,7 @@ structure UnsatProver.Result where
proof : Expr
lratCert : LratCert
abbrev UnsatProver := MVarId ReflectionResult Std.HashMap Nat (Nat × Expr)
abbrev UnsatProver := MVarId ReflectionResult Std.HashMap Nat (Nat × Expr × Bool)
MetaM (Except CounterExample UnsatProver.Result)
/--
@@ -183,7 +187,7 @@ def explainCounterExampleQuality (counterExample : CounterExample) : MetaM Messa
return err
def lratBitblaster (goal : MVarId) (cfg : TacticContext) (reflectionResult : ReflectionResult)
(atomsAssignment : Std.HashMap Nat (Nat × Expr)) :
(atomsAssignment : Std.HashMap Nat (Nat × Expr × Bool)) :
MetaM (Except CounterExample UnsatProver.Result) := do
let bvExpr := reflectionResult.bvExpr
let entry
@@ -253,7 +257,8 @@ def closeWithBVReflection (g : MVarId) (unsatProver : UnsatProver) :
reflectBV g
trace[Meta.Tactic.bv] "Reflected bv logical expression: {reflectionResult.bvExpr}"
let atomsPairs := ( getThe State).atoms.toList.map (fun (expr, width, ident) => (ident, (width, expr)))
let flipper := (fun (expr, {width, atomNumber, synthetic}) => (atomNumber, (width, expr, synthetic)))
let atomsPairs := ( getThe State).atoms.toList.map flipper
let atomsAssignment := Std.HashMap.ofList atomsPairs
match unsatProver g reflectionResult atomsAssignment with
| .ok bvExprUnsat, cert =>

View File

@@ -107,6 +107,25 @@ where
open Lean.Meta
/--
A `BitVec` atom.
-/
structure Atom where
/--
The width of the `BitVec` that is being abstracted.
-/
width : Nat
/--
A unique numeric identifier for the atom.
-/
atomNumber : Nat
/--
Whether the atom is synthetic. The effect of this is that values for this atom are not considered
for the counter example deriviation. This is for example useful when we introduce an atom over
an expression, together with additional lemmas that fully describe the behavior of the atom.
-/
synthetic : Bool
/--
The state of the reflection monad
-/
@@ -115,7 +134,7 @@ structure State where
The atoms encountered so far. Saved as a map from `BitVec` expressions to a (width, atomNumber)
pair.
-/
atoms : Std.HashMap Expr (Nat × Nat) := {}
atoms : Std.HashMap Expr Atom := {}
/--
A cache for `atomsAssignment`.
-/
@@ -208,8 +227,8 @@ def run (m : M α) : MetaM α :=
Retrieve the atoms as pairs of their width and expression.
-/
def atoms : M (List (Nat × Expr)) := do
let sortedAtoms := ( getThe State).atoms.toArray.qsort (·.2.2 < ·.2.2)
return sortedAtoms.map (fun (expr, width, _) => (width, expr)) |>.toList
let sortedAtoms := ( getThe State).atoms.toArray.qsort (·.2.atomNumber < ·.2.atomNumber)
return sortedAtoms.map (fun (expr, {width, ..}) => (width, expr)) |>.toList
/--
Retrieve a `BitVec.Assignment` representing the atoms we found so far.
@@ -220,16 +239,17 @@ def atomsAssignment : M Expr := do
/--
Look up an expression in the atoms, recording it if it has not previously appeared.
-/
def lookup (e : Expr) (width : Nat) : M Nat := do
def lookup (e : Expr) (width : Nat) (synthetic : Bool) : M Nat := do
match ( getThe State).atoms[e]? with
| some (width', ident) =>
if width != width' then
| some atom =>
if width != atom.width then
panic! "The same atom occurs with different widths, this is a bug"
return ident
return atom.atomNumber
| none =>
trace[Meta.Tactic.bv] "New atom of width {width}: {e}"
trace[Meta.Tactic.bv] "New atom of width {width}, synthetic? {synthetic}: {e}"
let ident modifyGetThe State fun s =>
(s.atoms.size, { s with atoms := s.atoms.insert e (width, s.atoms.size) })
let newAtom := { width, synthetic, atomNumber := s.atoms.size}
(s.atoms.size, { s with atoms := s.atoms.insert e newAtom })
updateAtomsAssignment
return ident
where

View File

@@ -32,10 +32,10 @@ def mkBVRefl (w : Nat) (expr : Expr) : Expr :=
expr
/--
Register `e` as an atom of width `width`.
Register `e` as an atom of `width` that might potentially be `synthetic`.
-/
def mkAtom (e : Expr) (width : Nat) : M ReifiedBVExpr := do
let ident M.lookup e width
def mkAtom (e : Expr) (width : Nat) (synthetic : Bool) : M ReifiedBVExpr := do
let ident M.lookup e width synthetic
let expr := mkApp2 (mkConst ``BVExpr.var) (toExpr width) (toExpr ident)
let proof := do
let evalExpr mkEvalExpr width expr
@@ -55,13 +55,13 @@ def getNatOrBvValue? (ty : Expr) (expr : Expr) : M (Option Nat) := do
| _ => return none
/--
Construct an uninterpreted `BitVec` atom from `x`.
Construct an uninterpreted `BitVec` atom from `x`, potentially `synthetic`.
-/
def bitVecAtom (x : Expr) : M (Option ReifiedBVExpr) := do
def bitVecAtom (x : Expr) (synthetic : Bool) : M (Option ReifiedBVExpr) := do
let t instantiateMVars ( whnfR ( inferType x))
let_expr BitVec widthExpr := t | return none
let some width getNatValue? widthExpr | return none
let atom mkAtom x width
let atom mkAtom x width synthetic
return some atom
/--

View File

@@ -31,7 +31,7 @@ def boolAtom (t : Expr) : M (Option ReifiedBVPred) := do
-/
let ty inferType t
let_expr Bool := ty | return none
let atom ReifiedBVExpr.mkAtom (mkApp (mkConst ``BitVec.ofBool) t) 1
let atom ReifiedBVExpr.mkAtom (mkApp (mkConst ``BitVec.ofBool) t) 1 false
let bvExpr : BVPred := .getLsbD atom.bvExpr 0
let expr := mkApp3 (mkConst ``BVPred.getLsbD) (toExpr 1) atom.expr (toExpr 0)
let proof := do

View File

@@ -209,7 +209,7 @@ where
let_expr Eq α discrExpr val := discrExpr | return none
let_expr Bool := α | return none
let_expr Bool.true := val | return none
let some atom ReifiedBVExpr.bitVecAtom x | return none
let some atom ReifiedBVExpr.bitVecAtom x true | return none
let some discr ReifiedBVLogical.of discrExpr | return none
let some lhs goOrAtom lhsExpr | return none
let some rhs goOrAtom rhsExpr | return none
@@ -226,7 +226,7 @@ where
let res go x
match res with
| some exp => return some exp
| none => ReifiedBVExpr.bitVecAtom x
| none => ReifiedBVExpr.bitVecAtom x false
shiftConstLikeReflection (distance : Nat) (innerExpr : Expr) (shiftOp : Nat BVUnOp)
(shiftOpName : Name) (congrThm : Name) :
@@ -316,7 +316,7 @@ where
return mkApp4 congrProof (toExpr inner.width) innerExpr innerEval innerProof
goBvLit (x : Expr) : M (Option ReifiedBVExpr) := do
let some _, bvVal getBitVecValue? x | return ReifiedBVExpr.bitVecAtom x
let some _, bvVal getBitVecValue? x | return ReifiedBVExpr.bitVecAtom x false
ReifiedBVExpr.mkBVConst bvVal
/--

View File

@@ -263,19 +263,26 @@ private def getOptRotation (stx : Syntax) : Nat :=
@[builtin_tactic Parser.Tactic.allGoals] def evalAllGoals : Tactic := fun stx => do
let mvarIds getGoals
let mut mvarIdsNew := #[]
let mut abort := false
let mut mctxSaved getMCtx
for mvarId in mvarIds do
unless ( mvarId.isAssigned) do
setGoals [mvarId]
mvarIdsNew Tactic.tryCatch
abort Tactic.tryCatch
(do
evalTactic stx[1]
return mvarIdsNew ++ ( getUnsolvedGoals))
pure abort)
(fun ex => do
if ( read).recover then
logException ex
return mvarIdsNew.push mvarId
pure true
else
throw ex)
mvarIdsNew := mvarIdsNew ++ ( getUnsolvedGoals)
if abort then
setMCtx mctxSaved
mvarIds.forM fun mvarId => unless ( mvarId.isAssigned) do admitGoal mvarId
throwAbortTactic
setGoals mvarIdsNew.toList
@[builtin_tactic Parser.Tactic.anyGoals] def evalAnyGoals : Tactic := fun stx => do

View File

@@ -200,7 +200,7 @@ where
if explicit then
let i := if i > 0 then i - 1 else i + xs.size
if i < 0 || i xs.size then
throwError "invalid '{tacticName}' tactic, application has {xs.size} arguments but the index is out of bounds"
throwError "invalid '{tacticName}' tactic, application has {xs.size} argument(s) but the index is out of bounds"
let idx := i.natAbs
return (mkAppN f xs[0:idx], xs[idx:])
else
@@ -217,7 +217,7 @@ where
explicitIdxs := explicitIdxs.push k
let i := if i > 0 then i - 1 else i + explicitIdxs.size
if i < 0 || i explicitIdxs.size then
throwError "invalid '{tacticName}' tactic, application has {xs.size} explicit argument(s) but the index is out of bounds"
throwError "invalid '{tacticName}' tactic, application has {explicitIdxs.size} explicit argument(s) but the index is out of bounds"
let idx := explicitIdxs[i.natAbs]!
return (mkAppN f xs[0:idx], xs[idx:])

View File

@@ -69,7 +69,7 @@ theorem go_denote_eq (aig : AIG BVBit) (expr : BVExpr w) (assign : Assignment) :
simp [go, hidx, denote_blastVar]
| zeroExtend v inner ih =>
simp only [go, denote_blastZeroExtend, ih, dite_eq_ite, Bool.if_false_right,
eval_zeroExtend, BitVec.getLsbD_setWidth, hidx, decide_True, Bool.true_and,
eval_zeroExtend, BitVec.getLsbD_setWidth, hidx, decide_true, Bool.true_and,
Bool.and_iff_right_iff_imp, decide_eq_true_eq]
apply BitVec.lt_of_getLsbD
| append lhs rhs lih rih =>
@@ -78,10 +78,10 @@ theorem go_denote_eq (aig : AIG BVBit) (expr : BVExpr w) (assign : Assignment) :
BitVec.getLsbD_append]
split
· next hsplit =>
simp only [hsplit, decide_True, cond_true]
simp only [hsplit, decide_true, cond_true]
rw [rih]
· next hsplit =>
simp only [hsplit, decide_False, cond_false]
simp only [hsplit, decide_false, cond_false]
rw [go_denote_mem_prefix, lih]
| replicate n expr ih => simp [go, ih, hidx]
| signExtend v inner ih =>
@@ -97,7 +97,7 @@ theorem go_denote_eq (aig : AIG BVBit) (expr : BVExpr w) (assign : Assignment) :
simp only [eval_signExtend]
rw [BitVec.signExtend_eq_not_setWidth_not_of_msb_false]
· simp only [denote_blastZeroExtend, ih, dite_eq_ite, Bool.if_false_right,
BitVec.getLsbD_setWidth, hidx, decide_True, Bool.true_and, Bool.and_iff_right_iff_imp,
BitVec.getLsbD_setWidth, hidx, decide_true, Bool.true_and, Bool.and_iff_right_iff_imp,
decide_eq_true_eq]
apply BitVec.lt_of_getLsbD
· subst heq
@@ -108,7 +108,7 @@ theorem go_denote_eq (aig : AIG BVBit) (expr : BVExpr w) (assign : Assignment) :
rw [denote_blastSignExtend]
simp only [eval_signExtend]
rw [BitVec.getLsbD_signExtend]
· simp only [hidx, decide_True, Bool.true_and]
· simp only [hidx, decide_true, Bool.true_and]
split
· rw [ih]
· rw [BitVec.msb_eq_getLsbD_last]
@@ -116,7 +116,7 @@ theorem go_denote_eq (aig : AIG BVBit) (expr : BVExpr w) (assign : Assignment) :
· dsimp only; omega
| @extract w start len inner ih =>
simp only [go, denote_blastExtract, Bool.if_false_right, eval_extract,
BitVec.getLsbD_extractLsb', hidx, decide_True, Bool.true_and]
BitVec.getLsbD_extractLsb', hidx, decide_true, Bool.true_and]
split
· next hsplit =>
rw [ih]

View File

@@ -39,7 +39,7 @@ theorem denote_blastNeg (aig : AIG α) (value : BitVec w) (target : RefVec aig w
rw [denote_blastAdd]
· intro idx hidx
rw [AIG.LawfulVecOperator.denote_mem_prefix (f := blastConst)]
· simp only [RefVec.get_cast, Ref.gate_cast, BitVec.getLsbD_not, hidx, decide_True,
· simp only [RefVec.get_cast, Ref.gate_cast, BitVec.getLsbD_not, hidx, decide_true,
Bool.true_and]
rw [denote_blastNot, htarget]
· simp [Ref.hgate]

View File

@@ -210,7 +210,7 @@ theorem twoPowShift_eq (aig : AIG α) (target : TwoPowShiftTarget aig w) (lhs :
omega
· rw [hleft]
simp only [BitVec.shiftLeft_eq', BitVec.toNat_twoPow, hmod, BitVec.getLsbD_shiftLeft, hidx,
decide_True, Bool.true_and, Bool.iff_and_self, Bool.not_eq_true', decide_eq_false_iff_not,
decide_true, Bool.true_and, Bool.iff_and_self, Bool.not_eq_true', decide_eq_false_iff_not,
Nat.not_lt]
omega
· next hif1 =>

View File

@@ -42,7 +42,7 @@ theorem mkUlt_denote_eq (aig : AIG α) (lhs rhs : BitVec w) (input : BinaryRefVe
· dsimp only
intro idx hidx
rw [AIG.LawfulOperator.denote_mem_prefix (f := AIG.mkConstCached)]
· simp only [RefVec.get_cast, Ref.gate_cast, BitVec.getLsbD_not, hidx, decide_True,
· simp only [RefVec.get_cast, Ref.gate_cast, BitVec.getLsbD_not, hidx, decide_true,
Bool.true_and]
rw [BVExpr.bitblast.denote_blastNot]
congr 1

View File

@@ -306,7 +306,7 @@ theorem sat_of_insertRat {n : Nat} (f : DefaultFormula n)
simp +decide only [hasAssignment, hasPosAssignment, heq]
have p_entails_i := hf.2.2 i false hasNegAssignment_fi p pf
simp only [(· ·)] at p_entails_i
simp only [p_entails_i, decide_True]
simp only [p_entails_i, decide_true]
· next heq =>
exfalso
rw [heq] at h3

View File

@@ -171,7 +171,7 @@ theorem sat_of_insertRup {n : Nat} (f : DefaultFormula n) (f_readyForRupAdd : Re
decide
have p_entails_i := (assignmentsInvariant_of_strongAssignmentsInvariant f f_readyForRupAdd.2).2 i false hasNegAssignment_fi p pf
simp only [(· ·)] at p_entails_i
simp only [p_entails_i, decide_True]
simp only [p_entails_i, decide_true]
· next heq =>
exfalso
rw [heq] at h3
@@ -424,7 +424,7 @@ theorem reduce_fold_fn_preserves_induction_motive {c_arr : Array (Literal (PosFi
· simp only [(· ·), i_eq_idx, c_arr_idx_eq_false] at p_entails_c_arr_i
simp only [(· ·), Bool.not_eq_true] at p_entails_assignment
specialize p_entails_assignment c_arr[idx.1].1
simp +decide only [p_entails_c_arr_i, decide_True, heq] at p_entails_assignment
simp +decide only [p_entails_c_arr_i, decide_true, heq] at p_entails_assignment
· next h =>
exact Or.inr h
· exact Or.inr ih1
@@ -443,7 +443,7 @@ theorem reduce_fold_fn_preserves_induction_motive {c_arr : Array (Literal (PosFi
· simp only [(· ·), i_eq_idx, c_arr_idx_eq_false] at p_entails_c_arr_i
simp only [(· ·), Bool.not_eq_true] at p_entails_assignment
specialize p_entails_assignment c_arr[idx.1].1
simp +decide only [p_entails_c_arr_i, decide_True, heq] at p_entails_assignment
simp +decide only [p_entails_c_arr_i, decide_true, heq] at p_entails_assignment
· next h =>
exact Or.inr h
· exact Or.inr ih1
@@ -519,7 +519,7 @@ theorem reduce_fold_fn_preserves_induction_motive {c_arr : Array (Literal (PosFi
· simp only [j_eq_idx, (· ·), c_arr_idx_eq_false] at p_entails_c_arr_j
simp only [(· ·), Bool.not_eq_true] at hp
specialize hp c_arr[idx.1].1
simp +decide only [p_entails_c_arr_j, decide_True, heq] at hp
simp +decide only [p_entails_c_arr_j, decide_true, heq] at hp
· next heq =>
split at h
· simp at h
@@ -534,7 +534,7 @@ theorem reduce_fold_fn_preserves_induction_motive {c_arr : Array (Literal (PosFi
· simp only [j_eq_idx, (· ·), c_arr_idx_eq_true] at p_entails_c_arr_j
simp only [(· ·), Bool.not_eq_true] at hp
specialize hp c_arr[idx.1].1
simp +decide only [p_entails_c_arr_j, decide_True, heq] at hp
simp +decide only [p_entails_c_arr_j, decide_true, heq] at hp
· simp at h
· simp at h
· simp at h
@@ -683,8 +683,8 @@ theorem confirmRupHint_preserves_motive {n : Nat} (f : DefaultFormula n) (rupHin
Array.get_eq_getElem, l_eq_i, Array.getElem_modify_self (addAssignment b), decidableGetElem?]
simp only [getElem!, i_in_bounds, dite_true, Array.get_eq_getElem, decidableGetElem?] at pacc
by_cases pi : p i
· simp only [pi, decide_False]
simp only [hasAssignment, pi, decide_False, ite_false] at pacc
· simp only [pi, decide_false]
simp only [hasAssignment, pi, decide_false, ite_false] at pacc
by_cases hb : b
· simp only [hasAssignment, reduceIte, addAssignment]
simp only [hb]
@@ -694,8 +694,8 @@ theorem confirmRupHint_preserves_motive {n : Nat} (f : DefaultFormula n) (rupHin
simp only [Bool.not_eq_true] at hb
simp [(· ·), hb, Subtype.ext l_eq_i, pi] at plb
· simp only [Bool.not_eq_true] at pi
simp only [pi, decide_True]
simp only [pi, decide_True] at pacc
simp only [pi, decide_true]
simp only [pi, decide_true] at pacc
by_cases hb : b
· simp [(· ·), hb, Subtype.ext l_eq_i, pi] at plb
· simp only [Bool.not_eq_true] at hb

View File

@@ -120,6 +120,7 @@ theorem BitVec.srem_umod (x y : BitVec w) :
attribute [bv_normalize] Bool.cond_eq_if
attribute [bv_normalize] BitVec.abs_eq
attribute [bv_normalize] BitVec.twoPow_eq
end Reduce

View File

@@ -1651,7 +1651,7 @@ static inline uint8_t lean_uint8_dec_lt(uint8_t a1, uint8_t a2) { return a1 < a2
static inline uint8_t lean_uint8_dec_le(uint8_t a1, uint8_t a2) { return a1 <= a2; }
/* Unit8 -> other */
/* UInt8 -> other */
static inline uint16_t lean_uint8_to_uint16(uint8_t a) { return ((uint16_t)a); }
static inline uint32_t lean_uint8_to_uint32(uint8_t a) { return ((uint32_t)a); }
static inline uint64_t lean_uint8_to_uint64(uint8_t a) { return ((uint64_t)a); }
@@ -1686,7 +1686,7 @@ static inline uint8_t lean_uint16_dec_eq(uint16_t a1, uint16_t a2) { return a1 =
static inline uint8_t lean_uint16_dec_lt(uint16_t a1, uint16_t a2) { return a1 < a2; }
static inline uint8_t lean_uint16_dec_le(uint16_t a1, uint16_t a2) { return a1 <= a2; }
/*uint16 -> other */
/* UInt16 -> other */
static inline uint8_t lean_uint16_to_uint8(uint16_t a) { return ((uint8_t)a); }
static inline uint32_t lean_uint16_to_uint32(uint16_t a) { return ((uint32_t)a); }
static inline uint64_t lean_uint16_to_uint64(uint16_t a) { return ((uint64_t)a); }
@@ -1721,7 +1721,7 @@ static inline uint8_t lean_uint32_dec_eq(uint32_t a1, uint32_t a2) { return a1 =
static inline uint8_t lean_uint32_dec_lt(uint32_t a1, uint32_t a2) { return a1 < a2; }
static inline uint8_t lean_uint32_dec_le(uint32_t a1, uint32_t a2) { return a1 <= a2; }
/* uint32 -> other */
/* UInt32 -> other */
static inline uint8_t lean_uint32_to_uint8(uint32_t a) { return ((uint8_t)a); }
static inline uint16_t lean_uint32_to_uint16(uint32_t a) { return ((uint16_t)a); }
static inline uint64_t lean_uint32_to_uint64(uint32_t a) { return ((uint64_t)a); }
@@ -1759,7 +1759,7 @@ static inline uint8_t lean_uint64_dec_le(uint64_t a1, uint64_t a2) { return a1 <
LEAN_EXPORT uint64_t lean_uint64_mix_hash(uint64_t a1, uint64_t a2);
/* uint64 -> other */
/* UInt64 -> other */
static inline uint8_t lean_uint64_to_uint8(uint64_t a) { return ((uint8_t)a); }
static inline uint16_t lean_uint64_to_uint16(uint64_t a) { return ((uint16_t)a); }
static inline uint32_t lean_uint64_to_uint32(uint64_t a) { return ((uint32_t)a); }
@@ -1826,6 +1826,18 @@ static inline uint8_t lean_int8_of_int(b_lean_obj_arg a) {
return (uint8_t)res;
}
static inline uint8_t lean_int8_of_nat(b_lean_obj_arg a) {
int8_t res;
if (lean_is_scalar(a)) {
res = (int8_t)lean_unbox(a);
} else {
res = lean_int8_of_big_int(a);
}
return (uint8_t)res;
}
static inline lean_obj_res lean_int8_to_int(uint8_t a) {
int8_t arg = (int8_t)a;
return lean_int64_to_int((int64_t)arg);
@@ -1838,73 +1850,73 @@ static inline uint8_t lean_int8_neg(uint8_t a) {
}
static inline uint8_t lean_int8_add(uint8_t a1, uint8_t a2) {
int8_t lhs = (int8_t) a1;
int8_t rhs = (int8_t) a2;
int8_t lhs = (int8_t)a1;
int8_t rhs = (int8_t)a2;
return (uint8_t)(lhs + rhs);
}
static inline uint8_t lean_int8_sub(uint8_t a1, uint8_t a2) {
int8_t lhs = (int8_t) a1;
int8_t rhs = (int8_t) a2;
int8_t lhs = (int8_t)a1;
int8_t rhs = (int8_t)a2;
return (uint8_t)(lhs - rhs);
}
static inline uint8_t lean_int8_mul(uint8_t a1, uint8_t a2) {
int8_t lhs = (int8_t) a1;
int8_t rhs = (int8_t) a2;
int8_t lhs = (int8_t)a1;
int8_t rhs = (int8_t)a2;
return (uint8_t)(lhs * rhs);
}
static inline uint8_t lean_int8_div(uint8_t a1, uint8_t a2) {
int8_t lhs = (int8_t) a1;
int8_t rhs = (int8_t) a2;
int8_t lhs = (int8_t)a1;
int8_t rhs = (int8_t)a2;
return (uint8_t)(rhs == 0 ? 0 : lhs / rhs);
}
static inline uint8_t lean_int8_mod(uint8_t a1, uint8_t a2) {
int8_t lhs = (int8_t) a1;
int8_t rhs = (int8_t) a2;
int8_t lhs = (int8_t)a1;
int8_t rhs = (int8_t)a2;
return (uint8_t)(rhs == 0 ? 0 : lhs % rhs);
return (uint8_t)(rhs == 0 ? lhs : lhs % rhs);
}
static inline uint8_t lean_int8_land(uint8_t a1, uint8_t a2) {
int8_t lhs = (int8_t) a1;
int8_t rhs = (int8_t) a2;
int8_t lhs = (int8_t)a1;
int8_t rhs = (int8_t)a2;
return (uint8_t)(lhs & rhs);
}
static inline uint8_t lean_int8_lor(uint8_t a1, uint8_t a2) {
int8_t lhs = (int8_t) a1;
int8_t rhs = (int8_t) a2;
int8_t lhs = (int8_t)a1;
int8_t rhs = (int8_t)a2;
return (uint8_t)(lhs | rhs);
}
static inline uint8_t lean_int8_xor(uint8_t a1, uint8_t a2) {
int8_t lhs = (int8_t) a1;
int8_t rhs = (int8_t) a2;
int8_t lhs = (int8_t)a1;
int8_t rhs = (int8_t)a2;
return (uint8_t)(lhs ^ rhs);
}
static inline uint8_t lean_int8_shift_right(uint8_t a1, uint8_t a2) {
int8_t lhs = (int8_t) a1;
int8_t rhs = (int8_t) a2;
int8_t lhs = (int8_t)a1;
int8_t rhs = (((int8_t)a2 % 8) + 8) % 8; // this is smod 8
return (uint8_t)(lhs >> (rhs % 8));
return (uint8_t)(lhs >> rhs);
}
static inline uint8_t lean_int8_shift_left(uint8_t a1, uint8_t a2) {
int8_t lhs = (int8_t) a1;
int8_t rhs = (int8_t) a2;
int8_t lhs = (int8_t)a1;
int8_t rhs = (((int8_t)a2 % 8) + 8) % 8; // this is smod 8
return (uint8_t)(lhs << (rhs % 8));
return (uint8_t)(lhs << rhs);
}
static inline uint8_t lean_int8_complement(uint8_t a) {
@@ -1914,26 +1926,591 @@ static inline uint8_t lean_int8_complement(uint8_t a) {
}
static inline uint8_t lean_int8_dec_eq(uint8_t a1, uint8_t a2) {
int8_t lhs = (int8_t) a1;
int8_t rhs = (int8_t) a2;
int8_t lhs = (int8_t)a1;
int8_t rhs = (int8_t)a2;
return lhs == rhs;
}
static inline uint8_t lean_int8_dec_lt(uint8_t a1, uint8_t a2) {
int8_t lhs = (int8_t) a1;
int8_t rhs = (int8_t) a2;
int8_t lhs = (int8_t)a1;
int8_t rhs = (int8_t)a2;
return lhs < rhs;
}
static inline uint8_t lean_int8_dec_le(uint8_t a1, uint8_t a2) {
int8_t lhs = (int8_t) a1;
int8_t rhs = (int8_t) a2;
int8_t lhs = (int8_t)a1;
int8_t rhs = (int8_t)a2;
return lhs <= rhs;
}
/* Int8 -> other */
static inline uint16_t lean_int8_to_int16(uint8_t a) { return (uint16_t)(int16_t)(int8_t)a; }
static inline uint32_t lean_int8_to_int32(uint8_t a) { return (uint32_t)(int32_t)(int8_t)a; }
static inline uint64_t lean_int8_to_int64(uint8_t a) { return (uint64_t)(int64_t)(int8_t)a; }
/* Int16 */
LEAN_EXPORT int16_t lean_int16_of_big_int(b_lean_obj_arg a);
static inline uint16_t lean_int16_of_int(b_lean_obj_arg a) {
int16_t res;
if (lean_is_scalar(a)) {
res = (int16_t)lean_scalar_to_int64(a);
} else {
res = lean_int16_of_big_int(a);
}
return (uint16_t)res;
}
static inline uint16_t lean_int16_of_nat(b_lean_obj_arg a) {
int16_t res;
if (lean_is_scalar(a)) {
res = (int16_t)lean_unbox(a);
} else {
res = lean_int16_of_big_int(a);
}
return (uint16_t)res;
}
static inline lean_obj_res lean_int16_to_int(uint16_t a) {
int16_t arg = (int16_t)a;
return lean_int64_to_int((int64_t)arg);
}
static inline uint16_t lean_int16_neg(uint16_t a) {
int16_t arg = (int16_t)a;
return (uint16_t)(-arg);
}
static inline uint16_t lean_int16_add(uint16_t a1, uint16_t a2) {
int16_t lhs = (int16_t)a1;
int16_t rhs = (int16_t)a2;
return (uint16_t)(lhs + rhs);
}
static inline uint16_t lean_int16_sub(uint16_t a1, uint16_t a2) {
int16_t lhs = (int16_t)a1;
int16_t rhs = (int16_t)a2;
return (uint16_t)(lhs - rhs);
}
static inline uint16_t lean_int16_mul(uint16_t a1, uint16_t a2) {
int16_t lhs = (int16_t)a1;
int16_t rhs = (int16_t)a2;
return (uint16_t)(lhs * rhs);
}
static inline uint16_t lean_int16_div(uint16_t a1, uint16_t a2) {
int16_t lhs = (int16_t)a1;
int16_t rhs = (int16_t)a2;
return (uint16_t)(rhs == 0 ? 0 : lhs / rhs);
}
static inline uint16_t lean_int16_mod(uint16_t a1, uint16_t a2) {
int16_t lhs = (int16_t)a1;
int16_t rhs = (int16_t)a2;
return (uint16_t)(rhs == 0 ? lhs : lhs % rhs);
}
static inline uint16_t lean_int16_land(uint16_t a1, uint16_t a2) {
int16_t lhs = (int16_t)a1;
int16_t rhs = (int16_t)a2;
return (uint16_t)(lhs & rhs);
}
static inline uint16_t lean_int16_lor(uint16_t a1, uint16_t a2) {
int16_t lhs = (int16_t)a1;
int16_t rhs = (int16_t)a2;
return (uint16_t)(lhs | rhs);
}
static inline uint16_t lean_int16_xor(uint16_t a1, uint16_t a2) {
int16_t lhs = (int16_t)a1;
int16_t rhs = (int16_t)a2;
return (uint16_t)(lhs ^ rhs);
}
static inline uint16_t lean_int16_shift_right(uint16_t a1, uint16_t a2) {
int16_t lhs = (int16_t)a1;
int16_t rhs = (((int16_t)a2 % 16) + 16) % 16; // this is smod 16
return (uint16_t)(lhs >> rhs);
}
static inline uint16_t lean_int16_shift_left(uint16_t a1, uint16_t a2) {
int16_t lhs = (int16_t)a1;
int16_t rhs = (((int16_t)a2 % 16) + 16) % 16; // this is smod 16
return (uint16_t)(lhs << rhs);
}
static inline uint16_t lean_int16_complement(uint16_t a) {
int16_t arg = (int16_t)a;
return (uint16_t)(~arg);
}
static inline uint8_t lean_int16_dec_eq(uint16_t a1, uint16_t a2) {
int16_t lhs = (int16_t)a1;
int16_t rhs = (int16_t)a2;
return lhs == rhs;
}
static inline uint8_t lean_int16_dec_lt(uint16_t a1, uint16_t a2) {
int16_t lhs = (int16_t)a1;
int16_t rhs = (int16_t)a2;
return lhs < rhs;
}
static inline uint8_t lean_int16_dec_le(uint16_t a1, uint16_t a2) {
int16_t lhs = (int16_t)a1;
int16_t rhs = (int16_t)a2;
return lhs <= rhs;
}
/* Int16 -> other */
static inline uint8_t lean_int16_to_int8(uint16_t a) { return (uint8_t)(int8_t)(int16_t)a; }
static inline uint32_t lean_int16_to_int32(uint16_t a) { return (uint32_t)(int32_t)(int16_t)a; }
static inline uint64_t lean_int16_to_int64(uint16_t a) { return (uint64_t)(int64_t)(int16_t)a; }
/* Int32 */
LEAN_EXPORT int32_t lean_int32_of_big_int(b_lean_obj_arg a);
static inline uint32_t lean_int32_of_int(b_lean_obj_arg a) {
int32_t res;
if (lean_is_scalar(a)) {
res = (int32_t)lean_scalar_to_int64(a);
} else {
res = lean_int32_of_big_int(a);
}
return (uint32_t)res;
}
static inline uint32_t lean_int32_of_nat(b_lean_obj_arg a) {
int32_t res;
if (lean_is_scalar(a)) {
res = (int32_t)lean_unbox(a);
} else {
res = lean_int32_of_big_int(a);
}
return (uint32_t)res;
}
static inline lean_obj_res lean_int32_to_int(uint32_t a) {
int32_t arg = (int32_t)a;
return lean_int64_to_int((int64_t)arg);
}
static inline uint32_t lean_int32_neg(uint32_t a) {
int32_t arg = (int32_t)a;
return (uint32_t)(-arg);
}
static inline uint32_t lean_int32_add(uint32_t a1, uint32_t a2) {
int32_t lhs = (int32_t)a1;
int32_t rhs = (int32_t)a2;
return (uint32_t)(lhs + rhs);
}
static inline uint32_t lean_int32_sub(uint32_t a1, uint32_t a2) {
int32_t lhs = (int32_t)a1;
int32_t rhs = (int32_t)a2;
return (uint32_t)(lhs - rhs);
}
static inline uint32_t lean_int32_mul(uint32_t a1, uint32_t a2) {
int32_t lhs = (int32_t)a1;
int32_t rhs = (int32_t)a2;
return (uint32_t)(lhs * rhs);
}
static inline uint32_t lean_int32_div(uint32_t a1, uint32_t a2) {
int32_t lhs = (int32_t)a1;
int32_t rhs = (int32_t)a2;
return (uint32_t)(rhs == 0 ? 0 : lhs / rhs);
}
static inline uint32_t lean_int32_mod(uint32_t a1, uint32_t a2) {
int32_t lhs = (int32_t)a1;
int32_t rhs = (int32_t)a2;
return (uint32_t)(rhs == 0 ? lhs : lhs % rhs);
}
static inline uint32_t lean_int32_land(uint32_t a1, uint32_t a2) {
int32_t lhs = (int32_t)a1;
int32_t rhs = (int32_t)a2;
return (uint32_t)(lhs & rhs);
}
static inline uint32_t lean_int32_lor(uint32_t a1, uint32_t a2) {
int32_t lhs = (int32_t)a1;
int32_t rhs = (int32_t)a2;
return (uint32_t)(lhs | rhs);
}
static inline uint32_t lean_int32_xor(uint32_t a1, uint32_t a2) {
int32_t lhs = (int32_t)a1;
int32_t rhs = (int32_t)a2;
return (uint32_t)(lhs ^ rhs);
}
static inline uint32_t lean_int32_shift_right(uint32_t a1, uint32_t a2) {
int32_t lhs = (int32_t)a1;
int32_t rhs = (((int32_t)a2 % 32) + 32) % 32; // this is smod 32
return (uint32_t)(lhs >> rhs);
}
static inline uint32_t lean_int32_shift_left(uint32_t a1, uint32_t a2) {
int32_t lhs = (int32_t)a1;
int32_t rhs = (((int32_t)a2 % 32) + 32) % 32; // this is smod 32
return (uint32_t)(lhs << rhs);
}
static inline uint32_t lean_int32_complement(uint32_t a) {
int32_t arg = (int32_t)a;
return (uint32_t)(~arg);
}
static inline uint8_t lean_int32_dec_eq(uint32_t a1, uint32_t a2) {
int32_t lhs = (int32_t)a1;
int32_t rhs = (int32_t)a2;
return lhs == rhs;
}
static inline uint8_t lean_int32_dec_lt(uint32_t a1, uint32_t a2) {
int32_t lhs = (int32_t)a1;
int32_t rhs = (int32_t)a2;
return lhs < rhs;
}
static inline uint8_t lean_int32_dec_le(uint32_t a1, uint32_t a2) {
int32_t lhs = (int32_t)a1;
int32_t rhs = (int32_t)a2;
return lhs <= rhs;
}
/* Int32 -> other */
static inline uint8_t lean_int32_to_int8(uint32_t a) { return (uint8_t)(int8_t)(int32_t)a; }
static inline uint16_t lean_int32_to_int16(uint32_t a) { return (uint16_t)(int16_t)(int32_t)a; }
static inline uint64_t lean_int32_to_int64(uint32_t a) { return (uint64_t)(int64_t)(int32_t)a; }
static inline size_t lean_int32_to_isize(uint32_t a) { return (size_t)(ptrdiff_t)(int32_t)a; }
/* Int64 */
LEAN_EXPORT int64_t lean_int64_of_big_int(b_lean_obj_arg a);
static inline uint64_t lean_int64_of_int(b_lean_obj_arg a) {
int64_t res;
if (lean_is_scalar(a)) {
res = lean_scalar_to_int64(a);
} else {
res = lean_int64_of_big_int(a);
}
return (uint64_t)res;
}
static inline uint64_t lean_int64_of_nat(b_lean_obj_arg a) {
int64_t res;
if (lean_is_scalar(a)) {
res = (int64_t)lean_unbox(a);
} else {
res = lean_int64_of_big_int(a);
}
return (uint64_t)res;
}
static inline lean_obj_res lean_int64_to_int_sint(uint64_t a) {
int64_t arg = (int64_t)a;
return lean_int64_to_int(arg);
}
static inline uint64_t lean_int64_neg(uint64_t a) {
int64_t arg = (int64_t)a;
return (uint64_t)(-arg);
}
static inline uint64_t lean_int64_add(uint64_t a1, uint64_t a2) {
int64_t lhs = (int64_t)a1;
int64_t rhs = (int64_t)a2;
return (uint64_t)(lhs + rhs);
}
static inline uint64_t lean_int64_sub(uint64_t a1, uint64_t a2) {
int64_t lhs = (int64_t)a1;
int64_t rhs = (int64_t)a2;
return (uint64_t)(lhs - rhs);
}
static inline uint64_t lean_int64_mul(uint64_t a1, uint64_t a2) {
int64_t lhs = (int64_t)a1;
int64_t rhs = (int64_t)a2;
return (uint64_t)(lhs * rhs);
}
static inline uint64_t lean_int64_div(uint64_t a1, uint64_t a2) {
int64_t lhs = (int64_t)a1;
int64_t rhs = (int64_t)a2;
return (uint64_t)(rhs == 0 ? 0 : lhs / rhs);
}
static inline uint64_t lean_int64_mod(uint64_t a1, uint64_t a2) {
int64_t lhs = (int64_t)a1;
int64_t rhs = (int64_t)a2;
return (uint64_t)(rhs == 0 ? lhs : lhs % rhs);
}
static inline uint64_t lean_int64_land(uint64_t a1, uint64_t a2) {
int64_t lhs = (int64_t)a1;
int64_t rhs = (int64_t)a2;
return (uint64_t)(lhs & rhs);
}
static inline uint64_t lean_int64_lor(uint64_t a1, uint64_t a2) {
int64_t lhs = (int64_t)a1;
int64_t rhs = (int64_t)a2;
return (uint64_t)(lhs | rhs);
}
static inline uint64_t lean_int64_xor(uint64_t a1, uint64_t a2) {
int64_t lhs = (int64_t)a1;
int64_t rhs = (int64_t)a2;
return (uint64_t)(lhs ^ rhs);
}
static inline uint64_t lean_int64_shift_right(uint64_t a1, uint64_t a2) {
int64_t lhs = (int64_t)a1;
int64_t rhs = (((int64_t)a2 % 64) + 64) % 64; // this is smod 64
return (uint64_t)(lhs >> rhs);
}
static inline uint64_t lean_int64_shift_left(uint64_t a1, uint64_t a2) {
int64_t lhs = (int64_t)a1;
int64_t rhs = (((int64_t)a2 % 64) + 64) % 64; // this is smod 64
return (uint64_t)(lhs << rhs);
}
static inline uint64_t lean_int64_complement(uint64_t a) {
int64_t arg = (int64_t)a;
return (uint64_t)(~arg);
}
static inline uint8_t lean_int64_dec_eq(uint64_t a1, uint64_t a2) {
int64_t lhs = (int64_t)a1;
int64_t rhs = (int64_t)a2;
return lhs == rhs;
}
static inline uint8_t lean_int64_dec_lt(uint64_t a1, uint64_t a2) {
int64_t lhs = (int64_t)a1;
int64_t rhs = (int64_t)a2;
return lhs < rhs;
}
static inline uint8_t lean_int64_dec_le(uint64_t a1, uint64_t a2) {
int64_t lhs = (int64_t)a1;
int64_t rhs = (int64_t)a2;
return lhs <= rhs;
}
/* Int64 -> other */
static inline uint8_t lean_int64_to_int8(uint64_t a) { return (uint8_t)(int8_t)(int64_t)a; }
static inline uint16_t lean_int64_to_int16(uint64_t a) { return (uint16_t)(int16_t)(int64_t)a; }
static inline uint32_t lean_int64_to_int32(uint64_t a) { return (uint32_t)(int32_t)(int64_t)a; }
static inline size_t lean_int64_to_isize(uint64_t a) { return (size_t)(ptrdiff_t)(int64_t)a; }
/* ISize */
LEAN_EXPORT ptrdiff_t lean_isize_of_big_int(b_lean_obj_arg a);
static inline size_t lean_isize_of_int(b_lean_obj_arg a) {
ptrdiff_t res;
if (lean_is_scalar(a)) {
res = (ptrdiff_t)lean_scalar_to_int64(a);
} else {
res = lean_isize_of_big_int(a);
}
return (size_t)res;
}
static inline size_t lean_isize_of_nat(b_lean_obj_arg a) {
ptrdiff_t res;
if (lean_is_scalar(a)) {
res = (ptrdiff_t)lean_unbox(a);
} else {
res = lean_isize_of_big_int(a);
}
return (size_t)res;
}
static inline lean_obj_res lean_isize_to_int(size_t a) {
ptrdiff_t arg = (ptrdiff_t)a;
return lean_int64_to_int((int64_t)arg);
}
static inline size_t lean_isize_neg(size_t a) {
ptrdiff_t arg = (ptrdiff_t)a;
return (size_t)(-arg);
}
static inline size_t lean_isize_add(size_t a1, size_t a2) {
ptrdiff_t lhs = (ptrdiff_t)a1;
ptrdiff_t rhs = (ptrdiff_t)a2;
return (size_t)(lhs + rhs);
}
static inline size_t lean_isize_sub(size_t a1, size_t a2) {
ptrdiff_t lhs = (ptrdiff_t)a1;
ptrdiff_t rhs = (ptrdiff_t)a2;
return (size_t)(lhs - rhs);
}
static inline size_t lean_isize_mul(size_t a1, size_t a2) {
ptrdiff_t lhs = (ptrdiff_t)a1;
ptrdiff_t rhs = (ptrdiff_t)a2;
return (size_t)(lhs * rhs);
}
static inline size_t lean_isize_div(size_t a1, size_t a2) {
ptrdiff_t lhs = (ptrdiff_t)a1;
ptrdiff_t rhs = (ptrdiff_t)a2;
return (size_t)(rhs == 0 ? 0 : lhs / rhs);
}
static inline size_t lean_isize_mod(size_t a1, size_t a2) {
ptrdiff_t lhs = (ptrdiff_t)a1;
ptrdiff_t rhs = (ptrdiff_t)a2;
return (size_t)(rhs == 0 ? lhs : lhs % rhs);
}
static inline size_t lean_isize_land(size_t a1, size_t a2) {
ptrdiff_t lhs = (ptrdiff_t)a1;
ptrdiff_t rhs = (ptrdiff_t)a2;
return (size_t)(lhs & rhs);
}
static inline size_t lean_isize_lor(size_t a1, size_t a2) {
ptrdiff_t lhs = (ptrdiff_t)a1;
ptrdiff_t rhs = (ptrdiff_t)a2;
return (size_t)(lhs | rhs);
}
static inline size_t lean_isize_xor(size_t a1, size_t a2) {
ptrdiff_t lhs = (ptrdiff_t)a1;
ptrdiff_t rhs = (ptrdiff_t)a2;
return (size_t)(lhs ^ rhs);
}
static inline size_t lean_isize_shift_right(size_t a1, size_t a2) {
ptrdiff_t lhs = (ptrdiff_t)a1;
ptrdiff_t size = sizeof(ptrdiff_t) * 8;
ptrdiff_t rhs = (((ptrdiff_t)a2 % size) + size) % size; // this is smod
return (size_t)(lhs >> rhs);
}
static inline size_t lean_isize_shift_left(size_t a1, size_t a2) {
ptrdiff_t lhs = (ptrdiff_t)a1;
ptrdiff_t size = sizeof(ptrdiff_t) * 8;
ptrdiff_t rhs = (((ptrdiff_t)a2 % size) + size) % size; // this is smod
return (size_t)(lhs << rhs);
}
static inline size_t lean_isize_complement(size_t a) {
ptrdiff_t arg = (ptrdiff_t)a;
return (size_t)(~arg);
}
static inline uint8_t lean_isize_dec_eq(size_t a1, size_t a2) {
ptrdiff_t lhs = (ptrdiff_t)a1;
ptrdiff_t rhs = (ptrdiff_t)a2;
return lhs == rhs;
}
static inline uint8_t lean_isize_dec_lt(size_t a1, size_t a2) {
ptrdiff_t lhs = (ptrdiff_t)a1;
ptrdiff_t rhs = (ptrdiff_t)a2;
return lhs < rhs;
}
static inline uint8_t lean_isize_dec_le(size_t a1, size_t a2) {
ptrdiff_t lhs = (ptrdiff_t)a1;
ptrdiff_t rhs = (ptrdiff_t)a2;
return lhs <= rhs;
}
/* ISize -> other */
static inline uint32_t lean_isize_to_int32(size_t a) { return (uint32_t)(int32_t)(ptrdiff_t)a; }
static inline uint64_t lean_isize_to_int64(size_t a) { return (uint64_t)(int64_t)(ptrdiff_t)a; }
/* Float */
LEAN_EXPORT lean_obj_res lean_float_to_string(double a);

View File

@@ -19,7 +19,10 @@ open Lean (Name)
/-- Compute a topological ordering of the package's transitive dependencies. -/
def Package.recComputeDeps (self : Package) : FetchM (Array Package) := do
(·.toArray) <$> self.deps.foldlM (init := OrdPackageSet.empty) fun deps dep => do
(·.toArray) <$> self.depConfigs.foldlM (init := OrdPackageSet.empty) fun deps cfg => do
let some dep findPackage? cfg.name
| error s!"{self.name}: package not found for dependency '{cfg.name}' \
(this is likely a bug in Lake)"
return ( fetch <| dep.facet `deps).foldl (·.insert ·) deps |>.insert dep
/-- The `PackageFacetConfig` for the builtin `depsFacet`. -/

View File

@@ -36,6 +36,10 @@ fetch functions, but not all fetch functions need build something.
abbrev DFetchFn (α : Type u) (β : α Type v) (m : Type v Type w) :=
(a : α) m (β a)
/-- A `DFetchFn` that is not dependently typed. -/
abbrev FetchFn (α : Type u) (β : Type v) (m : Type v Type w) :=
α m β
/-!
In order to nest builds / fetches within one another,
we equip the monad `m` with a fetch function of its own.

View File

@@ -41,12 +41,12 @@ BASIC OPTIONS:
--help, -h print help of the program or a command and exit
--dir, -d=file use the package configuration in a specific directory
--file, -f=file use a specific file for the package configuration
--lean=cmd specify the `lean` command used by Lake
-K key[=value] set the configuration file option named key
--old only rebuild modified modules (ignore transitive deps)
--rehash, -H hash all files for traces (do not trust `.hash` files)
--update, -U update manifest before building
--update, -U update dependencies on load (e.g., before a build)
--reconfigure, -R elaborate configuration files instead of using OLeans
--keep-toolchain do not update toolchain on workspace update
--no-build exit immediately if a build target is not up-to-date
--no-cache build packages locally; do not download build caches
--try-cache attempt to download build caches for supported packages

View File

@@ -5,6 +5,7 @@ Authors: Gabriel Ebner, Sebastian Ullrich, Mac Malone
-/
import Lake.Util.Git
import Lake.Util.Sugar
import Lake.Util.Version
import Lake.Config.Lang
import Lake.Config.Package
import Lake.Config.Workspace
@@ -18,9 +19,6 @@ open Lean (Name)
/-- The default module of an executable in `std` package. -/
def defaultExeRoot : Name := `Main
/-- `elan` toolchain file name -/
def toolchainFileName : FilePath := "lean-toolchain"
def gitignoreContents :=
s!"/{defaultLakeDir}
"

View File

@@ -26,6 +26,7 @@ namespace Lake
/-! ## General options for top-level `lake` -/
structure LakeOptions where
args : List String := []
rootDir : FilePath := "."
configFile : FilePath := defaultConfigFile
elanInstall? : Option ElanInstall := none
@@ -36,6 +37,7 @@ structure LakeOptions where
wantsHelp : Bool := false
verbosity : Verbosity := .normal
updateDeps : Bool := false
updateToolchain : Bool := true
reconfigure : Bool := false
oldMode : Bool := false
trustHash : Bool := true
@@ -72,12 +74,15 @@ def LakeOptions.computeEnv (opts : LakeOptions) : EIO CliError Lake.Env := do
/-- Make a `LoadConfig` from a `LakeOptions`. -/
def LakeOptions.mkLoadConfig (opts : LakeOptions) : EIO CliError LoadConfig :=
return {
lakeArgs? := opts.args.toArray
lakeEnv := opts.computeEnv
wsDir := opts.rootDir
relConfigFile := opts.configFile
lakeOpts := opts.configOpts
leanOpts := Lean.Options.empty
reconfigure := opts.reconfigure
updateDeps := opts.updateDeps
updateToolchain := opts.updateToolchain
}
/-- Make a `BuildConfig` from a `LakeOptions`. -/
@@ -101,7 +106,7 @@ abbrev CliM := ArgsT CliStateM
def CliM.run (self : CliM α) (args : List String) : BaseIO ExitCode := do
let (elanInstall?, leanInstall?, lakeInstall?) findInstall?
let main := self.run' args |>.run' {elanInstall?, leanInstall?, lakeInstall?}
let main := self.run' args |>.run' {args, elanInstall?, leanInstall?, lakeInstall?}
let main := main.run >>= fun | .ok a => pure a | .error e => error e.toString
main.run
@@ -111,6 +116,12 @@ def CliM.run (self : CliM α) (args : List String) : BaseIO ExitCode := do
instance (priority := low) : MonadLift LogIO CliStateM := CliStateM.runLogIO
@[inline] def CliStateM.runLoggerIO (x : LoggerIO α) : CliStateM α := do
let opts get
MainM.runLoggerIO x opts.outLv opts.ansiMode
instance (priority := low) : MonadLift LoggerIO CliStateM := CliStateM.runLoggerIO
/-! ## Argument Parsing -/
def takeArg (arg : String) : CliM String := do
@@ -141,10 +152,6 @@ def noArgsRem (act : CliStateM α) : CliM α := do
def getWantsHelp : CliStateM Bool :=
(·.wantsHelp) <$> get
def setLean (lean : String) : CliStateM PUnit := do
let leanInstall? findLeanCmdInstall? lean
modify ({· with leanInstall?})
def setConfigOpt (kvPair : String) : CliM PUnit :=
let pos := kvPair.posOf '='
let (key, val) :=
@@ -171,6 +178,7 @@ def lakeLongOption : (opt : String) → CliM PUnit
| "--quiet" => modifyThe LakeOptions ({· with verbosity := .quiet})
| "--verbose" => modifyThe LakeOptions ({· with verbosity := .verbose})
| "--update" => modifyThe LakeOptions ({· with updateDeps := true})
| "--keep-toolchain" => modifyThe LakeOptions ({· with updateToolchain := false})
| "--reconfigure" => modifyThe LakeOptions ({· with reconfigure := true})
| "--old" => modifyThe LakeOptions ({· with oldMode := true})
| "--no-build" => modifyThe LakeOptions ({· with noBuild := true})
@@ -193,7 +201,6 @@ def lakeLongOption : (opt : String) → CliM PUnit
| "--file" => do
let configFile takeOptArg "--file" "path"
modifyThe LakeOptions ({· with configFile})
| "--lean" => do setLean <| takeOptArg "--lean" "path or command"
| "--help" => modifyThe LakeOptions ({· with wantsHelp := true})
| "--" => do
let subArgs takeArgs
@@ -331,7 +338,7 @@ protected def build : CliM PUnit := do
processOptions lakeOption
let opts getThe LakeOptions
let config mkLoadConfig opts
let ws loadWorkspace config opts.updateDeps
let ws loadWorkspace config
let targetSpecs takeArgs
let specs parseTargetSpecs ws targetSpecs
let buildConfig := mkBuildConfig opts (out := .stdout)
@@ -350,7 +357,7 @@ protected def resolveDeps : CliM PUnit := do
let opts getThe LakeOptions
let config mkLoadConfig opts
noArgsRem do
discard <| loadWorkspace config opts.updateDeps
discard <| loadWorkspace config
protected def update : CliM PUnit := do
processOptions lakeOption

View File

@@ -38,7 +38,7 @@ def setupFile
IO.eprintln s!"Invalid Lake configuration. Please restart the server after fixing the Lake configuration file."
exit 1
let outLv := buildConfig.verbosity.minLogLv
let ws MainM.runLogIO (minLv := outLv) (ansiMode := .noAnsi) do
let ws MainM.runLoggerIO (minLv := outLv) (ansiMode := .noAnsi) do
loadWorkspace loadConfig
let imports := imports.foldl (init := #[]) fun imps imp =>
if let some mod := ws.findModule? imp.toName then imps.push mod else imps
@@ -71,7 +71,7 @@ with the given additional `args`.
-/
def serve (config : LoadConfig) (args : Array String) : IO UInt32 := do
let (extraEnv, moreServerArgs) do
let (ws?, log) (loadWorkspace config).run?
let (ws?, log) (loadWorkspace config).captureLog
log.replay (logger := MonadLog.stderr)
if let some ws := ws? then
let ctx := mkLakeContext ws

View File

@@ -63,7 +63,7 @@ def compute
lake, lean, elan?,
pkgUrlMap := computePkgUrlMap
reservoirApiUrl := getUrlD "RESERVOIR_API_URL" s!"{reservoirBaseUrl}/v1"
noCache := (noCache <|> ( IO.getEnv "LAKE_NO_CACHE").bind toBool?).getD false
noCache := (noCache <|> ( IO.getEnv "LAKE_NO_CACHE").bind envToBool?).getD false
githashOverride := ( IO.getEnv "LEAN_GITHASH").getD ""
initToolchain := ( IO.getEnv "ELAN_TOOLCHAIN").getD ""
initLeanPath := getSearchPath "LEAN_PATH",
@@ -72,10 +72,6 @@ def compute
initPath := getSearchPath "PATH"
}
where
toBool? (o : String) : Option Bool :=
if ["y", "yes", "t", "true", "on", "1"].contains o.toLower then true
else if ["n", "no", "f", "false", "off", "0"].contains o.toLower then false
else none
computePkgUrlMap := do
let some urlMapStr IO.getEnv "LAKE_PKG_URL_MAP" | return {}
match Json.parse urlMapStr |>.bind fromJson? with
@@ -144,14 +140,29 @@ Combines the initial path of the environment with that of the Lean installation.
def sharedLibPath (env : Env) : SearchPath :=
env.lean.sharedLibPath ++ env.initSharedLibPath
/-- Unset toolchain-specific environment variables. -/
def noToolchainVars : Array (String × Option String) :=
#[
("ELAN_TOOLCHAIN", none),
("LAKE", none),
("LAKE_OVERRIDE_LEAN", none),
("LAKE_HOME", none),
("LEAN", none),
("LEAN_GITHASH", none),
("LEAN_SYSROOT", none),
("LEAN_AR", none)
]
/-- Environment variable settings that are not augmented by a Lake workspace. -/
def baseVars (env : Env) : Array (String × Option String) :=
#[
("ELAN", env.elan?.map (·.elan.toString)),
("ELAN_HOME", env.elan?.map (·.home.toString)),
("ELAN_TOOLCHAIN", if env.toolchain.isEmpty then none else env.toolchain),
("LAKE", env.lake.lake.toString),
("LAKE_HOME", env.lake.home.toString),
("LAKE_PKG_URL_MAP", toJson env.pkgUrlMap |>.compress),
("LEAN", env.lean.lean.toString),
("LEAN_GITHASH", env.leanGithash),
("LEAN_SYSROOT", env.lean.sysroot.toString),
("LEAN_AR", env.lean.ar.toString),

View File

@@ -9,16 +9,18 @@ import Lake.Config.Defaults
open System
namespace Lake
/-! ## Data Structures -/
/-- Convert the string value of an environment variable to a boolean. -/
def envToBool? (o : String) : Option Bool :=
if ["y", "yes", "t", "true", "on", "1"].contains o.toLower then true
else if ["n", "no", "f", "false", "off", "0"].contains o.toLower then false
else none
/-- Standard path of `elan` in a Elan installation. -/
def elanExe (home : FilePath) :=
home / "bin" / "elan" |>.addExtension FilePath.exeExtension
/-! ## Data Structures -/
/-- Information about the local Elan setup. -/
structure ElanInstall where
home : FilePath
elan := elanExe home
elan : FilePath
binDir := home / "bin"
toolchainsDir := home / "toolchains"
deriving Inhabited, Repr
@@ -57,7 +59,7 @@ def initSharedLib : FilePath :=
/-- Path information about the local Lean installation. -/
structure LeanInstall where
sysroot : FilePath
githash : String
githash : String := ""
srcDir := sysroot / "src" / "lean"
leanLibDir := sysroot / "lib" / "lean"
includeDir := sysroot / "include"
@@ -67,9 +69,9 @@ structure LeanInstall where
leanc := leancExe sysroot
sharedLib := leanSharedLibDir sysroot / leanSharedLib
initSharedLib := leanSharedLibDir sysroot / initSharedLib
ar : FilePath
cc : FilePath
customCc : Bool
ar : FilePath := "ar"
cc : FilePath := "cc"
customCc : Bool := false
deriving Inhabited, Repr
/--
@@ -110,12 +112,16 @@ def LakeInstall.ofLean (lean : LeanInstall) : LakeInstall where
/-! ## Detection Functions -/
/--
Attempt to detect a Elan installation by checking the `ELAN_HOME`
environment variable for a installation location.
Attempt to detect an Elan installation by checking the `ELAN` and `ELAN_HOME`
environment variables. If `ELAN` is set but empty, Elan is considered disabled.
-/
def findElanInstall? : BaseIO (Option ElanInstall) := do
if let some home IO.getEnv "ELAN_HOME" then
return some {home}
let elan := ( IO.getEnv "ELAN").getD "elan"
if elan.trim.isEmpty then
return none
else
return some {elan, home}
return none
/--
@@ -149,9 +155,9 @@ set to the empty string.
For (2), if `LEAN_AR` or `LEAN_CC` are defined, it uses those paths.
Otherwise, if Lean is packaged with an `llvm-ar` and/or `clang`, use them.
If not, use the `ar` and/or `cc` in the system's `PATH`. This last step is
needed because internal builds of Lean do not bundle these tools
(unlike user-facing releases).
If not, use the `ar` and/or `cc` from the `AR` / `CC` environment variables
or the system's `PATH`. This last step is needed because internal builds of
Lean do not bundle these tools (unlike user-facing releases).
We also track whether `LEAN_CC` was set to determine whether it should
be set in the future for `lake env`. This is because if `LEAN_CC` was not set,
@@ -187,18 +193,29 @@ where
return FilePath.mk ar
else
let ar := leanArExe sysroot
if ( ar.pathExists) then pure ar else pure "ar"
if ( ar.pathExists) then
return ar
else if let some ar IO.getEnv "AR" then
return ar
else
return "ar"
findCc := do
if let some cc IO.getEnv "LEAN_CC" then
return (FilePath.mk cc, true)
else
let cc := leanCcExe sysroot
let cc := if ( cc.pathExists) then cc else "cc"
let cc
if ( cc.pathExists) then
pure cc
else if let some cc IO.getEnv "CC" then
pure cc
else
pure "cc"
return (cc, false)
/--
Attempt to detect the installation of the given `lean` command
by calling `findLeanCmdHome?`. See `LeanInstall.get` for how it assumes the
by calling `findLeanSysroot?`. See `LeanInstall.get` for how it assumes the
Lean install is organized.
-/
def findLeanCmdInstall? (lean := "lean") : BaseIO (Option LeanInstall) :=
@@ -235,14 +252,28 @@ def getLakeInstall? (lake : FilePath) : BaseIO (Option LakeInstall) := do
return none
/--
Attempt to detect Lean's installation by first checking the
`LEAN_SYSROOT` environment variable and then by trying `findLeanCmdHome?`.
Attempt to detect Lean's installation by using the `LEAN` and `LEAN_SYSROOT`
environment variables.
If `LEAN_SYSROOT` is set, use it. Otherwise, check `LEAN` for the `lean`
executable. If `LEAN` is set but empty, Lean will be considered disabled.
Otherwise, Lean's location will be determined by trying `findLeanSysroot?`
using value of `LEAN` or, if unset, the `lean` in `PATH`.
See `LeanInstall.get` for how it assumes the Lean install is organized.
-/
def findLeanInstall? : BaseIO (Option LeanInstall) := do
if let some sysroot IO.getEnv "LEAN_SYSROOT" then
return some <| LeanInstall.get sysroot
if let some sysroot findLeanSysroot? then
let lean do
if let some lean IO.getEnv "LEAN" then
if lean.trim.isEmpty then
return none
else
pure lean
else
pure "lean"
if let some sysroot findLeanSysroot? lean then
return some <| LeanInstall.get sysroot
return none
@@ -271,7 +302,8 @@ Then it attempts to detect if Lake and Lean are part of a single installation
where the `lake` executable is co-located with the `lean` executable (i.e., they
are in the same directory). If Lean and Lake are not co-located, Lake will
attempt to find the their installations separately by calling
`findLeanInstall?` and `findLakeInstall?`.
`findLeanInstall?` and `findLakeInstall?`. Setting `LAKE_OVERRIDE_LEAN` to true
will force Lake to use `findLeanInstall?` even if co-located.
When co-located, Lake will assume that Lean and Lake's binaries are located in
`<sysroot>/bin`, their Lean libraries in `<sysroot>/lib/lean`, Lean's source files
@@ -280,9 +312,13 @@ following the pattern of a regular Lean toolchain.
-/
def findInstall? : BaseIO (Option ElanInstall × Option LeanInstall × Option LakeInstall) := do
let elan? findElanInstall?
if let some home findLakeLeanJointHome? then
let lean LeanInstall.get home (collocated := true)
let lake := LakeInstall.ofLean lean
return (elan?, lean, lake)
if let some sysroot findLakeLeanJointHome? then
if ( IO.getEnv "LAKE_OVERRIDE_LEAN").bind envToBool? |>.getD false then
let lake := LakeInstall.ofLean {sysroot}
return (elan?, findLeanInstall?, lake)
else
let lean LeanInstall.get sysroot (collocated := true)
let lake := LakeInstall.ofLean lean
return (elan?, lean, lake)
else
return (elan?, findLeanInstall?, findLakeInstall?)

View File

@@ -45,6 +45,10 @@ abbrev MonadLake (m : Type → Type u) :=
@[inline] def mkLakeContext (ws : Workspace) : Lake.Context where
opaqueWs := ws
/-- Run a `LakeT` monad in the context of this workspace. -/
@[inline] def Workspace.runLakeT (ws : Workspace) (x : LakeT m α) : m α :=
x.run (mkLakeContext ws)
instance [MonadWorkspace m] [Functor m] : MonadLake m where
read := (mkLakeContext ·) <$> getWorkspace

View File

@@ -8,9 +8,6 @@ import Lake.Util.Opaque
namespace Lake
/-- Opaque reference to a `Package` used for forward declaration. -/
declare_opaque_type OpaquePackage
/-- Opaque reference to a `Workspace` used for forward declaration. -/
declare_opaque_type OpaqueWorkspace

View File

@@ -380,11 +380,9 @@ structure Package where
/-- The path to the package's JSON manifest of remote dependencies (relative to `dir`). -/
relManifestFile : FilePath := config.manifestFile.getD defaultManifestFile
/-- The package's scope (e.g., in Reservoir). -/
scope : String := ""
scope : String
/-- The URL to this package's Git remote. -/
remoteUrl : String := ""
/-- (Opaque references to) the package's direct dependencies. -/
opaqueDeps : Array OpaquePackage := #[]
remoteUrl : String
/-- Dependency configurations for the package. -/
depConfigs : Array Dependency := #[]
/-- Lean library configurations for the package. -/
@@ -419,8 +417,6 @@ instance : Nonempty Package :=
have : Inhabited Environment := Classical.inhabited_of_nonempty inferInstance
by constructor <;> exact default
hydrate_opaque_type OpaquePackage Package
instance : Hashable Package where hash pkg := hash pkg.config.name
instance : BEq Package where beq p1 p2 := p1.config.name == p2.config.name
@@ -508,10 +504,6 @@ namespace Package
@[inline] def readmeFile (self : Package) : FilePath :=
self.dir / self.config.readmeFile
/-- The package's direct dependencies. -/
@[inline] def deps (self : Package) : Array Package :=
self.opaqueDeps.map (·.get)
/-- The path to the package's Lake directory relative to `dir` (e.g., `.lake`). -/
@[inline] def relLakeDir (_ : Package) : FilePath :=
defaultLakeDir

View File

@@ -18,8 +18,14 @@ open Lean (Name)
structure Workspace : Type where
/-- The root package of the workspace. -/
root : Package
/-- The detect `Lake.Env` of the workspace. -/
/-- The detected `Lake.Env` of the workspace. -/
lakeEnv : Lake.Env
/--
The CLI arguments Lake was run with.
Used by `lake update` to perform a restart of Lake on a toolchain update.
A value of `none` means that Lake is not restartable via the CLI.
-/
lakeArgs? : Option (Array String) := none
/-- The packages within the workspace (in `require` declaration order). -/
packages : Array Package := {}
/-- Name-package map of packages within the workspace. -/
@@ -77,7 +83,7 @@ def addPackage (pkg : Package) (self : Workspace) : Workspace :=
/-- Try to find a script in the workspace with the given name. -/
protected def findScript? (script : Name) (self : Workspace) : Option Script :=
self.packages.findSomeRev? (·.scripts.find? script)
self.packages.findSome? (·.scripts.find? script)
/-- Check if the module is local to any package in the workspace. -/
def isLocalModule (mod : Name) (self : Workspace) : Bool :=
@@ -89,27 +95,27 @@ def isBuildableModule (mod : Name) (self : Workspace) : Bool :=
/-- Locate the named, buildable, importable, local module in the workspace. -/
protected def findModule? (mod : Name) (self : Workspace) : Option Module :=
self.packages.findSomeRev? (·.findModule? mod)
self.packages.findSome? (·.findModule? mod)
/-- Locate the named, buildable, but not necessarily importable, module in the workspace. -/
def findTargetModule? (mod : Name) (self : Workspace) : Option Module :=
self.packages.findSomeRev? (·.findTargetModule? mod)
self.packages.findSome? (·.findTargetModule? mod)
/-- Try to find a Lean library in the workspace with the given name. -/
protected def findLeanLib? (name : Name) (self : Workspace) : Option LeanLib :=
self.packages.findSomeRev? fun pkg => pkg.findLeanLib? name
self.packages.findSome? fun pkg => pkg.findLeanLib? name
/-- Try to find a Lean executable in the workspace with the given name. -/
protected def findLeanExe? (name : Name) (self : Workspace) : Option LeanExe :=
self.packages.findSomeRev? fun pkg => pkg.findLeanExe? name
self.packages.findSome? fun pkg => pkg.findLeanExe? name
/-- Try to find an external library in the workspace with the given name. -/
protected def findExternLib? (name : Name) (self : Workspace) : Option ExternLib :=
self.packages.findSomeRev? fun pkg => pkg.findExternLib? name
self.packages.findSome? fun pkg => pkg.findExternLib? name
/-- Try to find a target configuration in the workspace with the given name. -/
def findTargetConfig? (name : Name) (self : Workspace) : Option ((pkg : Package) × TargetConfig pkg.name name) :=
self.packages.findSomeRev? fun pkg => pkg.findTargetConfig? name <&> (pkg, ·)
self.packages.findSome? fun pkg => pkg.findTargetConfig? name <&> (pkg, ·)
/-- Add a module facet to the workspace. -/
def addModuleFacetConfig (cfg : ModuleFacetConfig name) (self : Workspace) : Workspace :=
@@ -137,15 +143,15 @@ def findLibraryFacetConfig? (name : Name) (self : Workspace) : Option (LibraryFa
/-- The workspace's binary directories (which are added to `Path`). -/
def binPath (self : Workspace) : SearchPath :=
self.packages.foldr (fun pkg dirs => pkg.binDir :: dirs) []
self.packages.foldl (fun dirs pkg => pkg.binDir :: dirs) []
/-- The workspace's Lean library directories (which are added to `LEAN_PATH`). -/
def leanPath (self : Workspace) : SearchPath :=
self.packages.foldr (fun pkg dirs => pkg.leanLibDir :: dirs) []
self.packages.foldl (fun dirs pkg => pkg.leanLibDir :: dirs) []
/-- The workspace's source directories (which are added to `LEAN_SRC_PATH`). -/
def leanSrcPath (self : Workspace) : SearchPath :=
self.packages.foldr (init := {}) fun pkg dirs =>
self.packages.foldl (init := {}) fun dirs pkg =>
pkg.leanLibConfigs.foldr (init := dirs) fun cfg dirs =>
pkg.srcDir / cfg.srcDir :: dirs

View File

@@ -8,6 +8,7 @@ import Lean.Data.Options
import Lake.Config.Defaults
import Lake.Config.Env
import Lake.Util.Log
import Lake.Util.Version
namespace Lake
open System Lean
@@ -16,6 +17,12 @@ open System Lean
structure LoadConfig where
/-- The Lake environment of the load process. -/
lakeEnv : Lake.Env
/--
The CLI arguments Lake was run with.
Used to perform a restart of Lake on a toolchain update.
A value of `none` means that Lake is not restartable via the CLI.
-/
lakeArgs? : Option (Array String) := none
/-- The root directory of the Lake workspace. -/
wsDir : FilePath
/-- The directory of the loaded package (relative to the root). -/
@@ -26,8 +33,15 @@ structure LoadConfig where
lakeOpts : NameMap String := {}
/-- The Lean options with which to elaborate the configuration file. -/
leanOpts : Options := {}
/-- If `true`, Lake will elaborate configuration files instead of using OLeans. -/
/-- Whether Lake should re-elaborate configuration files instead of using cached OLeans. -/
reconfigure : Bool := false
/-- Whether to update dependencies when loading the workspace. -/
updateDeps : Bool := false
/--
Whether to update the workspace's `lean-toolchain` when dependencies are updated.
If `true` and a toolchain update occurs, Lake will need to be restarted.
-/
updateToolchain : Bool := true
/-- The package's scope (e.g., in Reservoir). -/
scope : String := ""
/-- The URL to this package's Git remote (if any). -/

View File

@@ -20,31 +20,36 @@ or resolve a local path dependency.
namespace Lake
/-- Update the Git package in `repo` to `rev` if not already at it. -/
def updateGitPkg (name : String) (repo : GitRepo) (rev? : Option String) : LogIO PUnit := do
def updateGitPkg
(name : String) (repo : GitRepo) (rev? : Option String)
: LogIO PUnit := do
let rev repo.findRemoteRevision rev?
if ( repo.getHeadRevision) = rev then
if ( repo.hasDiff) then
logWarning s!"{name}: repository '{repo.dir}' has local changes"
else
logInfo s!"{name}: updating repository '{repo.dir}' to revision '{rev}'"
logInfo s!"{name}: checking out revision '{rev}'"
repo.checkoutDetach rev
/-- Clone the Git package as `repo`. -/
def cloneGitPkg (name : String) (repo : GitRepo)
(url : String) (rev? : Option String) : LogIO PUnit := do
logInfo s!"{name}: cloning {url} to '{repo.dir}'"
def cloneGitPkg
(name : String) (repo : GitRepo) (url : String) (rev? : Option String)
: LogIO PUnit := do
logInfo s!"{name}: cloning {url}"
repo.clone url
if let some rev := rev? then
let hash repo.resolveRemoteRevision rev
repo.checkoutDetach hash
let rev repo.resolveRemoteRevision rev
logInfo s!"{name}: checking out revision '{rev}'"
repo.checkoutDetach rev
/--
Update the Git repository from `url` in `repo` to `rev?`.
If `repo` is already from `url`, just checkout the new revision.
Otherwise, delete the local repository and clone a fresh copy from `url`.
-/
def updateGitRepo (name : String) (repo : GitRepo)
(url : String) (rev? : Option String) : LogIO Unit := do
def updateGitRepo
(name : String) (repo : GitRepo) (url : String) (rev? : Option String)
: LogIO Unit := do
let sameUrl EIO.catchExceptions (h := fun _ => pure false) <| show IO Bool from do
let some remoteUrl repo.getRemoteUrl? | return false
if remoteUrl = url then return true
@@ -65,8 +70,9 @@ def updateGitRepo (name : String) (repo : GitRepo)
Materialize the Git repository from `url` into `repo` at `rev?`.
Clone it if no local copy exists, otherwise update it.
-/
def materializeGitRepo (name : String) (repo : GitRepo)
(url : String) (rev? : Option String) : LogIO Unit := do
def materializeGitRepo
(name : String) (repo : GitRepo) (url : String) (rev? : Option String)
: LogIO Unit := do
if ( repo.dirExists) then
updateGitRepo name repo url rev?
else
@@ -110,11 +116,7 @@ def Dependency.materialize
match src with
| .path dir =>
let relPkgDir := relParentDir / dir
return {
relPkgDir
remoteUrl := ""
manifestEntry := mkEntry <| .path relPkgDir
}
return mkDep relPkgDir "" (.path relPkgDir)
| .git url inputRev? subDir? => do
let sname := dep.name.toString (escape := false)
let repoUrl := Git.filterUrl? url |>.getD ""
@@ -127,7 +129,7 @@ def Dependency.materialize
if ver.startsWith "git#" then
return ver.drop 4
else
error s!"{dep.name} unsupported dependency version format '{ver}' (should be \"git#>rev>\")"
error s!"{dep.name}: unsupported dependency version format '{ver}' (should be \"git#>rev>\")"
let depName := dep.name.toString (escape := false)
let some pkg Reservoir.fetchPkg? lakeEnv dep.scope depName
| error s!"{dep.scope}/{depName}: could not materialize package: \
@@ -139,18 +141,17 @@ def Dependency.materialize
(githubUrl?.getD "") (verRev? <|> defaultBranch?) subDir?
| _ => error s!"{pkg.fullName}: Git source not found on Reservoir"
where
mkEntry src : PackageEntry :=
{name := dep.name, scope := dep.scope, inherited, src}
materializeGit name relPkgDir gitUrl remoteUrl inputRev? subDir? : LogIO MaterializedDep := do
let repo := GitRepo.mk (wsDir / relPkgDir)
let gitUrl := lakeEnv.pkgUrlMap.find? dep.name |>.getD gitUrl
materializeGitRepo name repo gitUrl inputRev?
let rev repo.getHeadRevision
let relPkgDir := if let some subDir := subDir? then relPkgDir / subDir else relPkgDir
return {
relPkgDir, remoteUrl
manifestEntry := mkEntry <| .git gitUrl rev inputRev? subDir?
}
return mkDep relPkgDir remoteUrl <| .git gitUrl rev inputRev? subDir?
@[inline] mkDep relPkgDir remoteUrl src : MaterializedDep := {
relPkgDir, remoteUrl,
manifestEntry := {name := dep.name, scope := dep.scope, inherited, src}
}
/--
Materializes a manifest package entry, cloning and/or checking it out as necessary.
@@ -161,11 +162,7 @@ def PackageEntry.materialize
: LogIO MaterializedDep :=
match manifestEntry.src with
| .path (dir := relPkgDir) .. =>
return {
relPkgDir
remoteUrl := ""
manifestEntry
}
return mkDep relPkgDir ""
| .git (url := url) (rev := rev) (subDir? := subDir?) .. => do
let sname := manifestEntry.name.toString (escape := false)
let relGitDir := relPkgsDir / sname
@@ -188,8 +185,7 @@ def PackageEntry.materialize
let url := lakeEnv.pkgUrlMap.find? manifestEntry.name |>.getD url
cloneGitPkg sname repo url rev
let relPkgDir := match subDir? with | .some subDir => relGitDir / subDir | .none => relGitDir
return {
relPkgDir
remoteUrl := Git.filterUrl? url |>.getD ""
manifestEntry
}
return mkDep relPkgDir (Git.filterUrl? url |>.getD "")
where
@[inline] mkDep relPkgDir remoteUrl : MaterializedDep :=
{relPkgDir, remoteUrl, manifestEntry}

View File

@@ -18,6 +18,21 @@ This module contains definitions for resolving the dependencies of a package.
namespace Lake
def stdMismatchError (newName : String) (rev : String) :=
s!"the 'std' package has been renamed to '{newName}' and moved to the
'leanprover-community' organization; downstream packages which wish to
update to the new std should replace
require std from
git \"https://github.com/leanprover/std4\"{rev}
in their Lake configuration file with
require {newName} from
git \"https://github.com/leanprover-community/{newName}\"{rev}
"
/--
Loads the package configuration of a materialized dependency.
Adds the facets defined in the package to the `Workspace`.
@@ -43,100 +58,82 @@ def loadDepPackage
else
return (pkg, ws)
/-- The monad of the dependency resolver. -/
abbrev ResolveT m := CallStackT Name <| StateT Workspace m
/--
The resolver's call stack of dependencies.
That is, the dependency currently being resolved plus its parents.
-/
abbrev DepStack := CallStack Name
@[inline] nonrec def ResolveT.run (ws : Workspace) (x : ResolveT m α) (stack : CallStack Name := {}) : m (α × Workspace) :=
x.run stack |>.run ws
/--
A monad transformer for recursive dependency resolution.
It equips the monad with the stack of dependencies currently being resolved.
-/
abbrev DepStackT m := CallStackT Name m
@[inline] nonrec def DepStackT.run
(x : DepStackT m α) (stack : DepStack := {})
: m α :=
x.run stack
/-- Log dependency cycle and error. -/
@[specialize] def depCycleError [MonadError m] (cycle : Cycle Name) : m α :=
error s!"dependency cycle detected:\n{"\n".intercalate <| cycle.map (s!" {·}")}"
instance [Monad m] [MonadError m] : MonadCycleOf Name (ResolveT m) where
instance [Monad m] [MonadError m] : MonadCycleOf Name (DepStackT m) where
throwCycle := depCycleError
/--
Recursively visits the workspace dependency graph, starting from `root`.
At each package, loops through each direct dependency performing just `breath`.
Them, loops again through the results applying `depth`, recursing, and adding
the package to workspace's package set. Errors if a cycle is encountered.
/-- The monad of the dependency resolver. -/
abbrev ResolveT m := DepStackT <| StateT Workspace m
**Traversal Order**
@[inline] nonrec def ResolveT.run
(ws : Workspace) (x : ResolveT m α) (stack : DepStack := {})
: m (α × Workspace) :=
x.run stack |>.run ws
All dependencies of a package are visited in order before recursing to the
dependencies' dependencies. For example, given the dependency graph:
```
R
|- A
|- B
|- X
|- Y
|- C
```
Lake follows the order `R`, `A`, `B`, `C`, `X`, `Y`.
The logic behind this design is that users would expect the dependencies
they write in a package configuration to be resolved accordingly and would be
surprised if they are overridden by nested dependencies referring to the same
package.
For example, were Lake to use a pure depth-first traversal, Lake would follow
the order `R`, `A`, `B`, `X`, `Y`, `C`. If `X` and `C` are both the package
`foo`, Lake would use the configuration of `foo` found in `B` rather than in
the root `R`, which would likely confuse the user.
-/
@[specialize] def Workspace.resolveDeps
/-- Recursively run a `ResolveT` monad starting from the workspace's root. -/
@[specialize] private def Workspace.runResolveT
[Monad m] [MonadError m] (ws : Workspace)
(breadth : Package Dependency ResolveT m Package)
(depth : Package m PUnit := fun _ => pure ())
(go : RecFetchFn Package PUnit (ResolveT m))
(root := ws.root) (stack : DepStack := {})
: m Workspace := do
let (root, ws) ResolveT.run ws <| StateT.run' (s := {}) <|
inline <| recFetchAcyclic (·.name) go ws.root
return {ws with root}
let (_, ws) ResolveT.run ws (stack := stack) do
inline <| recFetchAcyclic (·.name) go root
return ws
/-
Recursively visits each node in a package's dependency graph, starting from
the workspace package `root`. Each dependency missing from the workspace is
resolved using the `resolve` function and added into the workspace.
Recursion occurs breadth-first. Each direct dependency of a package is
resolved in reverse order before recursing to the dependencies' dependencies.
See `Workspace.updateAndMaterializeCore` for more details.
-/
@[inline] private def Workspace.resolveDepsCore
[Monad m] [MonadError m] (ws : Workspace)
(load : Package Dependency StateT Workspace m Package)
(root : Package := ws.root) (stack : DepStack := {})
: m Workspace := do
ws.runResolveT go root stack
where
@[specialize] go pkg resolve : StateT (NameMap Package) (ResolveT m) Package := do
pkg.depConfigs.forM fun dep => do
if ( getThe (NameMap Package)).contains dep.name then
return
if ( getThe Workspace).packageMap.contains dep.name then
return -- already resolved in another branch
@[specialize] go pkg recurse : ResolveT m Unit := do
let start := ( getWorkspace).packages.size
-- Materialize and load the missing direct dependencies of `pkg`
pkg.depConfigs.forRevM fun dep => do
let ws getWorkspace
if ws.packageMap.contains dep.name then
return -- already handled in another branch
if pkg.name = dep.name then
error s!"{pkg.name}: package requires itself (or a package with the same name)"
let pre breadth pkg dep -- package w/o dependencies
store dep.name pre
let deps pkg.depConfigs.mapM fun dep => do
if let some pre fetch? dep.name then
modifyThe (NameMap Package) (·.erase dep.name) -- for `dep` linearity
depth pre
return OpaquePackage.mk ( resolve pre)
if let some dep findPackage? dep.name then
return OpaquePackage.mk dep -- already resolved in another branch
error s!"{dep.name}: impossible resolution state reached"
let pkg := {pkg with opaqueDeps := deps}
modifyThe Workspace (·.addPackage pkg)
return pkg
def stdMismatchError (newName : String) (rev : String) :=
s!"the 'std' package has been renamed to '{newName}' and moved to the
'leanprover-community' organization; downstream packages which wish to
update to the new std should replace
require std from
git \"https://github.com/leanprover/std4\"{rev}
in their Lake configuration file with
require {newName} from
git \"https://github.com/leanprover-community/{newName}\"{rev}
"
let depPkg load pkg dep
modifyThe Workspace (·.addPackage depPkg)
-- Recursively load the dependencies' dependencies
( getWorkspace).packages.forM recurse start
/--
The monad of the manifest updater.
It is equipped with and entry map entries for the updated manifest.
Adds monad state used to update the manifest.
It equips the monad with a map of locked dependencies.
-/
abbrev UpdateT := StateT (NameMap PackageEntry)
@@ -147,7 +144,9 @@ abbrev UpdateT := StateT (NameMap PackageEntry)
Reuse manifest versions of root packages that should not be updated.
Also, move the packages directory if its location has changed.
-/
def reuseManifest (ws : Workspace) (toUpdate : NameSet) : UpdateT LogIO PUnit := do
private def reuseManifest
(ws : Workspace) (toUpdate : NameSet)
: UpdateT LogIO PUnit := do
let rootName := ws.root.name.toString (escape := false)
match ( Manifest.load ws.manifestFile |>.toBaseIO) with
| .ok manifest =>
@@ -175,7 +174,7 @@ def reuseManifest (ws : Workspace) (toUpdate : NameSet) : UpdateT LogIO PUnit :=
logWarning s!"{rootName}: ignoring previous manifest because it failed to load: {e}"
/-- Add a package dependency's manifest entries to the update state. -/
def addDependencyEntries (pkg : Package) : UpdateT LogIO PUnit := do
private def addDependencyEntries (pkg : Package) : UpdateT LogIO PUnit := do
match ( Manifest.load pkg.manifestFile |>.toBaseIO) with
| .ok manifest =>
manifest.packages.forM fun entry => do
@@ -187,22 +186,31 @@ def addDependencyEntries (pkg : Package) : UpdateT LogIO PUnit := do
| .error e =>
logWarning s!"{pkg.name}: ignoring manifest because it failed to load: {e}"
/-- Update a single dependency. -/
def updateDep
(pkg : Package) (dep : Dependency) (leanOpts : Options := {})
: ResolveT (UpdateT LogIO) Package := do
let ws getThe Workspace
let inherited := pkg.name != ws.root.name
-- Materialize the dependency
let matDep id do
if let some entry fetch? dep.name then
entry.materialize ws.lakeEnv ws.dir ws.relPkgsDir
else
let matDep dep.materialize inherited ws.lakeEnv ws.dir ws.relPkgsDir pkg.relDir
store matDep.name matDep.manifestEntry
return matDep
-- Load the package
let depPkg loadDepPackage matDep dep.opts leanOpts true
/-- Materialize a single dependency, updating it if desired. -/
private def updateAndMaterializeDep
(ws : Workspace) (pkg : Package) (dep : Dependency)
: UpdateT LogIO MaterializedDep := do
if let some entry fetch? dep.name then
entry.materialize ws.lakeEnv ws.dir ws.relPkgsDir
else
let inherited := pkg.name ws.root.name
/-
NOTE: A path dependency inherited from another dependency's manifest
will always be of the form a `./<relPath>` (i.e., be relative to its
workspace). Thus, when relativized to this workspace, it will have the
path `<relPkgDir>/./<relPath>`. However, if defining dependency lacks
a manifest, it will instead be locked as `<relPkgDir>/<relPath>`.
Adding a `.` here eliminates this difference.
-/
let relPkgDir := if pkg.relDir == "." then pkg.relDir else pkg.relDir / "."
let matDep dep.materialize inherited ws.lakeEnv ws.dir ws.relPkgsDir relPkgDir
store matDep.name matDep.manifestEntry
return matDep
/-- Verify that a dependency was loaded with the correct name. -/
private def validateDep
(pkg : Package) (dep : Dependency) (matDep : MaterializedDep) (depPkg : Package)
: LogIO PUnit := do
if depPkg.name dep.name then
if dep.name = .mkSimple "std" then
let rev :=
@@ -216,24 +224,144 @@ def updateDep
logError s!"'{dep.name}' was downloaded incorrectly; \
you will need to manually delete '{depPkg.dir}': {e}"
error s!"{pkg.name}: package '{depPkg.name}' was required as '{dep.name}'"
return depPkg
/--
Rebuild the workspace's Lake manifest and materialize missing dependencies.
Packages are updated to latest specific revision matching that in `require`
(e.g., if the `require` is `@master`, update to latest commit on master) or
removed if the `require` is removed. If `tuUpdate` is empty, update/remove all
root dependencies. Otherwise, only update the root dependencies specified.
Package are always reconfigured when updated.
Exit code returned if Lake needs a manual restart.
Used, for instance, if the toolchain is updated and no Elan is detected.
-/
def Workspace.updateAndMaterialize
(ws : Workspace) (toUpdate : NameSet := {}) (leanOpts : Options := {})
: LogIO Workspace := do
let (ws, entries) UpdateT.run do
reuseManifest ws toUpdate
ws.resolveDeps (updateDep · · leanOpts) (addDependencyEntries ·)
def restartCode : ExitCode := 4
/--
Update the workspace's `lean-toolchain` if necessary.
Compares the root's toolchain with that of its direct dependencies to find the
best match. If none can be found, issue warning and return normally. If an
update is found
-/
def Workspace.updateToolchain
(ws : Workspace) (rootDeps : Array MaterializedDep)
: LoggerIO PUnit := do
let rootToolchainFile := ws.root.dir / toolchainFileName
let rootTc? ToolchainVer.ofDir? ws.dir
let (src, tc?, tcs) rootDeps.foldlM (init := (ws.root.name, rootTc?, #[])) fun s dep => do
let depTc? ToolchainVer.ofDir? (ws.dir / dep.relPkgDir)
let some depTc := depTc?
| return s
let (src, tc?, tcs) := s
let some tc := tc?
| return (dep.name, depTc?, tcs)
if depTc tc then
return (src, tc, tcs)
else if tc < depTc then
return (dep.name, depTc, tcs)
else
return (src, tc, tcs.push (dep.name, depTc))
if 0 < tcs.size then
let s := "toolchain not updated; multiple toolchain candidates:"
let s := if let some tc := tc? then s!"{s}\n {tc}\n from {src}" else s
let s := tcs.foldl (init := s) fun s (d, tc) => s!"{s}\n {tc}\n from {d}"
logWarning s
else if let some tc := tc? then
if rootTc?.any (· == tc) then
logInfo "toolchain not updated; already up-to-date"
return
logInfo s!"updating toolchain to '{tc}'"
IO.FS.writeFile rootToolchainFile tc.toString
let some lakeArgs := ws.lakeArgs?
| logInfo s!"cannot auto-restart; you will need to manually restart Lake"
IO.Process.exit restartCode.toUInt8
let some elanInstall := ws.lakeEnv.elan?
| logInfo s!"no Elan detected; you will need to manually restart Lake"
IO.Process.exit restartCode.toUInt8
logInfo s!"restarting Lake via Elan"
let child IO.Process.spawn {
cmd := elanInstall.elan.toString
args := #["run", "--install", tc.toString, "lake"] ++ lakeArgs
env := Env.noToolchainVars
}
IO.Process.exit ( child.wait).toUInt8
else
logInfo s!"toolchain not updated; no toolchain information found"
/--
Updates the workspace, materializing and reconfiguring dependencies.
Dependencies are updated to latest specific revision matching that in `require`
(e.g., if the `require` is `@master`, update to latest commit on master) or
removed if the `require` is removed.
If `tuUpdate` is empty, all direct dependencies of the workspace's root will be
updated and/or remove. Otherwise, only those specified will be updated.
If `updateToolchain := true`, the workspace's toolchain is also updated to the
latest toolchain compatible with the root and its direct dependencies.
If there are multiple incomparable toolchain versions across them,
a warning will be issued and no update performed.
If an update is performed, Lake will automatically restart the update on the new
toolchain (via `elan`). If `elan` is missing, it will instead request a manual
restart from the user and exit immediately with `restartCode`.
**Dependency Traversal Order**
All dependencies of a package are visited in reverse order before recursing
to the dependencies' dependencies. For example, given the dependency graph:
```
R
|- A
|- B
|- X
|- Y
|- C
```
Lake follows the order `R`, `C`, `A`, `B`, `Y`, `X`.
The reason for this is two-fold:
1. Like targets, later requires should shadow earlier definitions.
2. Requires written by a user should take priority over those inherited
from dependencies.
Were Lake to use a depth-first traversal, for example, Lake would follow
the order `R`, `A`, `B`, `X`, `Y`, `C`. If `X` and `C` are both the package
`foo`, Lake would use the configuration of `foo` found in `B` rather than in
the root `R`, which would likely confuse the user.
-/
def Workspace.updateAndMaterializeCore
(ws : Workspace)
(toUpdate : NameSet := {}) (leanOpts : Options := {})
(updateToolchain := true)
: LoggerIO (Workspace × NameMap PackageEntry) := UpdateT.run do
reuseManifest ws toUpdate
let ws := ws.addPackage ws.root
if updateToolchain then
let deps := ws.root.depConfigs.reverse
let matDeps deps.mapM fun dep => do
logVerbose s!"{ws.root.name}: updating '{dep.name}' with {toJson dep.opts}"
updateAndMaterializeDep ws ws.root dep
ws.updateToolchain matDeps
let start := ws.packages.size
let ws (deps.zip matDeps).foldlM (init := ws) fun ws (dep, matDep) => do
let (depPkg, ws) loadUpdatedDep ws.root dep matDep ws
let ws := ws.addPackage depPkg
return ws
ws.packages.foldlM (init := ws) (start := start) fun ws pkg =>
ws.resolveDepsCore (stack := [ws.root.name]) updateAndLoadDep pkg
else
ws.resolveDepsCore updateAndLoadDep
where
@[inline] updateAndLoadDep pkg dep := do
let matDep updateAndMaterializeDep ( getWorkspace) pkg dep
loadUpdatedDep pkg dep matDep
@[inline] loadUpdatedDep pkg dep matDep : StateT Workspace (UpdateT LogIO) Package := do
let depPkg loadDepPackage matDep dep.opts leanOpts true
validateDep pkg dep matDep depPkg
addDependencyEntries depPkg
return depPkg
/-- Write package entries to the workspace manifest. -/
def Workspace.writeManifest
(ws : Workspace) (entries : NameMap PackageEntry)
: LogIO PUnit := do
let manifestEntries := ws.packages.foldl (init := #[]) fun arr pkg =>
match entries.find? pkg.name with
| some entry => arr.push <|
@@ -246,10 +374,28 @@ def Workspace.updateAndMaterialize
packages := manifestEntries
}
manifest.saveToFile ws.manifestFile
LakeT.run ws <| ws.packages.forM fun pkg => do
unless pkg.postUpdateHooks.isEmpty do
logInfo s!"{pkg.name}: running post-update hooks"
pkg.postUpdateHooks.forM fun hook => hook.get.fn pkg
/-- Run a package's `post_update` hooks. -/
def Package.runPostUpdateHooks (pkg : Package) : LakeT LogIO PUnit := do
unless pkg.postUpdateHooks.isEmpty do
logInfo s!"{pkg.name}: running post-update hooks"
pkg.postUpdateHooks.forM fun hook => hook.get.fn pkg
/--
Updates the workspace, writes the new Lake manifest, and runs package
post-update hooks.
See `Workspace.updateAndMaterializeCore` for details on the update process.
-/
def Workspace.updateAndMaterialize
(ws : Workspace)
(toUpdate : NameSet := {}) (leanOpts : Options := {})
(updateToolchain := true)
: LoggerIO Workspace := do
let (ws, entries)
ws.updateAndMaterializeCore toUpdate leanOpts updateToolchain
ws.writeManifest entries
ws.runLakeT do ws.packages.forM (·.runPostUpdateHooks)
return ws
/--
@@ -293,8 +439,9 @@ def Workspace.materializeDeps
let pkgEntries : NameMap PackageEntry := manifest.packages.foldl (init := {})
fun map entry => map.insert entry.name entry
validateManifest pkgEntries ws.root.depConfigs
ws.resolveDeps fun pkg dep => do
let ws getThe Workspace
let ws := ws.addPackage ws.root
ws.resolveDepsCore fun pkg dep => do
let ws getWorkspace
if let some entry := pkgEntries.find? dep.name then
let result entry.materialize ws.lakeEnv ws.dir relPkgsDir
loadDepPackage result dep.opts leanOpts reconfigure

View File

@@ -25,7 +25,9 @@ def loadWorkspaceRoot (config : LoadConfig) : LogIO Workspace := do
Lean.searchPathRef.set config.lakeEnv.leanSearchPath
let (root, env?) loadPackageCore "[root]" config
let ws : Workspace := {
root, lakeEnv := config.lakeEnv
root
lakeEnv := config.lakeEnv
lakeArgs? := config.lakeArgs?
moduleFacetConfigs := initModuleFacetConfigs
packageFacetConfigs := initPackageFacetConfigs
libraryFacetConfigs := initLibraryFacetConfigs
@@ -40,19 +42,19 @@ Load a `Workspace` for a Lake package by
elaborating its configuration file and resolving its dependencies.
If `updateDeps` is true, updates the manifest before resolving dependencies.
-/
def loadWorkspace (config : LoadConfig) (updateDeps := false) : LogIO Workspace := do
let rc := config.reconfigure
let leanOpts := config.leanOpts
def loadWorkspace (config : LoadConfig) : LoggerIO Workspace := do
let {reconfigure, leanOpts, updateDeps, updateToolchain, ..} := config
let ws loadWorkspaceRoot config
if updateDeps then
ws.updateAndMaterialize {} leanOpts
ws.updateAndMaterialize {} leanOpts updateToolchain
else if let some manifest Manifest.load? ws.manifestFile then
ws.materializeDeps manifest leanOpts rc
ws.materializeDeps manifest leanOpts reconfigure
else
ws.updateAndMaterialize {} leanOpts
ws.updateAndMaterialize {} leanOpts updateToolchain
/-- Updates the manifest for the loaded Lake workspace (see `updateAndMaterialize`). -/
def updateManifest (config : LoadConfig) (toUpdate : NameSet := {}) : LogIO Unit := do
let leanOpts := config.leanOpts
def updateManifest (config : LoadConfig) (toUpdate : NameSet := {})
: LoggerIO Unit := do
let {leanOpts, updateToolchain, ..} := config
let ws loadWorkspaceRoot config
discard <| ws.updateAndMaterialize toUpdate leanOpts
discard <| ws.updateAndMaterialize toUpdate leanOpts updateToolchain

View File

@@ -3,6 +3,7 @@ Copyright (c) 2024 Mac Malone. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Mac Malone
-/
import Lake.Util.Date
/-!
# TOML Date-Time
@@ -22,62 +23,10 @@ optionally left out, creating four distinct variants.
namespace Lake.Toml
def lpad (s : String) (c : Char) (len : Nat) : String :=
"".pushn c (len - s.length) ++ s
def rpad (s : String) (c : Char) (len : Nat) : String :=
s.pushn c (len - s.length)
def zpad (n : Nat) (len : Nat) : String :=
lpad (toString n) '0' len
/-- A TOML date (year-month-day). -/
structure Date where
year : Nat
month : Nat
day : Nat
deriving Inhabited, DecidableEq, Ord
namespace Date
abbrev IsLeapYear (y : Nat) : Prop :=
y % 4 = 0 (y % 100 0 y % 400 = 0)
abbrev IsValidMonth (m : Nat) : Prop :=
m 1 m 12
def maxDay (y m : Nat) : Nat :=
if m = 2 then
if IsLeapYear y then 29 else 28
else if m 7 then
30 + (m % 2)
else
31 - (m % 2)
abbrev IsValidDay (y m d : Nat) : Prop :=
d 1 d maxDay y m
def ofValid? (year month day : Nat) : Option Date := do
guard (IsValidMonth month IsValidDay year month day)
return {year, month, day}
def ofString? (t : String) : Option Date := do
match t.split (· == '-') with
| [y,m,d] =>
ofValid? ( y.toNat?) ( m.toNat?) ( d.toNat?)
| _ => none
protected def toString (d : Date) : String :=
s!"{zpad d.year 4}-{zpad d.month 2}-{zpad d.day 2}"
instance : ToString Date := Date.toString
end Date
/--
A TOML time (hour:minute:second.fraction).
We do not represent whole time as seconds to due to the possibility
We do not represent the whole time as seconds to due to the possibility
of leap seconds in RFC 3339 times.
-/
structure Time where

View File

@@ -0,0 +1,69 @@
/-
Copyright (c) 2024 Mac Malone. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Mac Malone
-/
/-!
# Date
A year-mont-day date. Used by Lake's TOML parser and its toolchain version
parser (for nightlies).
-/
namespace Lake
def lpad (s : String) (c : Char) (len : Nat) : String :=
"".pushn c (len - s.length) ++ s
def rpad (s : String) (c : Char) (len : Nat) : String :=
s.pushn c (len - s.length)
def zpad (n : Nat) (len : Nat) : String :=
lpad (toString n) '0' len
/-- A date (year-month-day). -/
structure Date where
year : Nat
month : Nat
day : Nat
deriving Inhabited, DecidableEq, Ord, Repr
namespace Date
instance : LT Date := ltOfOrd
instance : LE Date := leOfOrd
instance : Min Date := minOfLe
instance : Max Date := maxOfLe
abbrev IsLeapYear (y : Nat) : Prop :=
y % 4 = 0 (y % 100 0 y % 400 = 0)
abbrev IsValidMonth (m : Nat) : Prop :=
m 1 m 12
def maxDay (y m : Nat) : Nat :=
if m = 2 then
if IsLeapYear y then 29 else 28
else if m 7 then
30 + (m % 2)
else
31 - (m % 2)
abbrev IsValidDay (y m d : Nat) : Prop :=
d 1 d maxDay y m
def ofValid? (year month day : Nat) : Option Date := do
guard (IsValidMonth month IsValidDay year month day)
return {year, month, day}
def ofString? (t : String) : Option Date := do
match t.split (· == '-') with
| [y,m,d] =>
ofValid? ( y.toNat?) ( m.toNat?) ( d.toNat?)
| _ => none
protected def toString (d : Date) : String :=
s!"{zpad d.year 4}-{zpad d.month 2}-{zpad d.day 2}"
instance : ToString Date := Date.toString

View File

@@ -5,33 +5,39 @@ Authors: Mac Malone
-/
namespace Lake
instance (priority := low) [Monad m] [MonadExceptOf PUnit m] : Alternative m where
failure := throw ()
orElse := tryCatch
/-- Ensure direct lifts are preferred over indirect ones. -/
instance (priority := high) [MonadLift α β] : MonadLiftT α β := MonadLift.monadLift
instance [Pure m] : MonadLiftT Id m where
instance (priority := low) [Pure m] : MonadLiftT Id m where
monadLift act := pure act.run
instance [Alternative m] : MonadLiftT Option m where
instance (priority := low) [Alternative m] : MonadLiftT Option m where
monadLift
| some a => pure a
| none => failure
instance [Pure m] [MonadExceptOf ε m] : MonadLiftT (Except ε) m where
instance (priority := low) [Pure m] [MonadExceptOf ε m] : MonadLiftT (Except ε) m where
monadLift
| .ok a => pure a
| .error e => throw e
instance [Bind m] [MonadReaderOf ρ m] [MonadLiftT n m] : MonadLiftT (ReaderT ρ n) m where
-- Remark: not necessarily optimal; uses context non-linearly
instance (priority := low) [Bind m] [MonadReaderOf ρ m] [MonadLiftT n m] : MonadLiftT (ReaderT ρ n) m where
monadLift act := do act ( read)
instance [Monad m] [MonadStateOf σ m] [MonadLiftT n m] : MonadLiftT (StateT σ n) m where
-- Remark: not necessarily optimal; uses state non-linearly
instance (priority := low) [Monad m] [MonadStateOf σ m] [MonadLiftT n m] : MonadLiftT (StateT σ n) m where
monadLift act := do let (a, s) act ( get); set s; pure a
instance [Monad m] [Alternative m] [MonadLiftT n m] : MonadLiftT (OptionT n) m where
instance (priority := low) [Monad m] [Alternative m] [MonadLiftT n m] : MonadLiftT (OptionT n) m where
monadLift act := act.run >>= liftM
instance [Monad m] [MonadExceptOf ε m] [MonadLiftT n m] : MonadLiftT (ExceptT ε n) m where
instance (priority := low) [Monad m] [MonadExceptOf ε m] [MonadLiftT n m] : MonadLiftT (ExceptT ε n) m where
monadLift act := act.run >>= liftM
instance [Monad m] [MonadExceptOf ε m] [MonadLiftT BaseIO m] : MonadLiftT (EIO ε) m where
instance (priority := low) [Monad m] [MonadExceptOf ε m] [MonadLiftT BaseIO m] : MonadLiftT (EIO ε) m where
monadLift act := act.toBaseIO >>= liftM

View File

@@ -5,6 +5,7 @@ Authors: Mac Malone
-/
import Lake.Util.Error
import Lake.Util.EStateT
import Lake.Util.Lift
import Lean.Data.Json
import Lean.Message
@@ -195,6 +196,9 @@ abbrev stream [MonadLiftT BaseIO m]
(out : IO.FS.Stream) (minLv := LogLevel.info) (useAnsi := false)
: MonadLog m where logEntry e := logToStream e out minLv useAnsi
@[inline] def error [Alternative m] [MonadLog m] (msg : String) : m α :=
logError msg *> failure
end MonadLog
def OutStream.logEntry
@@ -404,7 +408,7 @@ from an `ELogT` (e.g., `LogIO`).
(msg : String)
: m α := errorWithLog (logError msg)
/-- `Alternative` instance for monads with `Log` state and `Log.Pos` errors. -/
/-- `MonadError` instance for monads with `Log` state and `Log.Pos` errors. -/
abbrev ELog.monadError
[Monad m] [MonadLog m] [MonadStateOf Log m] [MonadExceptOf Log.Pos m]
: MonadError m := ELog.error
@@ -505,7 +509,7 @@ abbrev run?' [Functor m] (self : ELogT m α) (log : Log := {}) : m (Option α) :
Run `self` with the log taken from the state of the monad `n`,
**Warning:** If lifting `self` from `m` to `n` fails, the log will be lost.
Thus, this is best used when the lift cannot fail. Note excludes the
Thus, this is best used when the lift cannot fail. This excludes the
native log position failure of `ELogT`, which are lifted safely.
-/
@[inline] def takeAndRun
@@ -545,8 +549,6 @@ instance : MonadLift IO LogIO := ⟨MonadError.runIO⟩
namespace LogIO
@[deprecated ELogT.run? (since := "2024-05-18")] abbrev captureLog := @ELogT.run?
/--
Runs a `LogIO` action in `BaseIO`.
Prints log entries of at least `minLv` to `out`.
@@ -563,4 +565,46 @@ where
replay (log : Log) (logger : MonadLog BaseIO) : BaseIO Unit :=
log.replay (logger := logger)
-- deprecated 2024-05-18, reversed 2024-10-18
abbrev captureLog := @ELogT.run?
end LogIO
/--
A monad equipped with a log function and the ability to perform I/O.
Unlike `LogIO`, log entries are not retained by the monad but instead eagerly
passed to the log function.
-/
abbrev LoggerIO := MonadLogT BaseIO (EIO PUnit)
instance : MonadError LoggerIO := MonadLog.error
instance : MonadLift IO LoggerIO := MonadError.runIO
instance : MonadLift LogIO LoggerIO := ELogT.replayLog
namespace LoggerIO
/--
Runs a `LoggerIO` action in `BaseIO`.
Prints log entries of at least `minLv` to `out`.
-/
@[inline] def toBaseIO
(self : LoggerIO α)
(minLv := LogLevel.info) (ansiMode := AnsiMode.auto) (out := OutStream.stderr)
: BaseIO (Option α) := do
(·.toOption) <$> (self.run ( out.getLogger minLv ansiMode)).toBaseIO
def captureLog (self : LoggerIO α) : BaseIO (Option α × Log) := do
let ref IO.mkRef ({} : Log)
let e self.run fun e => ref.modify (·.push e) |>.toBaseIO
return (e.toOption, ref.get)
-- For parity with `LogIO.run?`
abbrev run? := @captureLog
-- For parity with `LogIO.run?'`
@[inline] def run?'
(self : LoggerIO α) (logger : LogEntry BaseIO PUnit := fun _ => pure ())
: BaseIO (Option α) := do
(·.toOption) <$> (self.run logger).toBaseIO
end LoggerIO

View File

@@ -88,3 +88,12 @@ where
log.replay (logger := logger)
instance (priority := low) : MonadLift LogIO MainM := runLogIO
@[inline] def runLoggerIO (x : LoggerIO α)
(minLv := LogLevel.info) (ansiMode := AnsiMode.auto) (out := OutStream.stderr)
: MainM α := do
let some a x.run ( out.getLogger minLv ansiMode) |>.toBaseIO
| exit 1
return a
instance (priority := low) : MonadLift LoggerIO MainM := runLoggerIO

View File

@@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Mac Malone
-/
import Lean.Elab.Eval
import Lake.Util.Date
/-! # Version
@@ -11,7 +12,7 @@ This module contains useful definitions for manipulating versions.
It also defines a `v!"<ver>"` syntax for version literals.
-/
open Lean
open System Lean
namespace Lake
@@ -117,6 +118,112 @@ instance : ToExpr StdVer where
#[toExpr ver.toSemVerCore, toExpr ver.specialDescr]
toTypeExpr := mkConst ``StdVer
/-- A Lean toolchain version. -/
inductive ToolchainVer
| release (ver : LeanVer)
| nightly (date : Date)
| pr (no : Nat)
| other (name : String)
deriving Repr, DecidableEq
instance : Coe LeanVer ToolchainVer := ToolchainVer.release
def ToolchainVer.defaultOrigin := "leanprover/lean4"
def ToolchainVer.prOrigin := "leanprover/lean4-pr-releases"
def ToolchainVer.ofString (ver : String) : ToolchainVer := Id.run do
let colonPos := ver.posOf ':'
let (origin, tag) :=
if h : colonPos < ver.endPos then
let pos := ver.next' colonPos (by simp_all [h, String.endPos, String.atEnd])
(ver.extract 0 colonPos, ver.extract pos ver.endPos)
else
("", ver)
if tag.startsWith "v" then
if let .ok ver := StdVer.parse (tag.drop 1) then
if origin.isEmpty || origin == defaultOrigin then
return .release ver
return .other ver
else if tag.startsWith "nightly-" then
if let some date := Date.ofString? (tag.drop "nightly-".length) then
if origin.isEmpty || origin == defaultOrigin then
return .nightly date
else if tag.startsWith "pr-release-" then
if let some n := (tag.drop "pr-release-".length).toNat? then
if origin.isEmpty || origin == prOrigin then
return .pr n
else
if let .ok ver := StdVer.parse ver then
if origin.isEmpty || origin == defaultOrigin then
return .release ver
return .other ver
/-- Parse a toolchain from a `lean-toolchain` file. -/
def ToolchainVer.ofFile? (toolchainFile : FilePath) : IO (Option ToolchainVer) := do
try
let toolchainString IO.FS.readFile toolchainFile
return some <| ToolchainVer.ofString toolchainString.trim
catch
| .noFileOrDirectory .. =>
return none
| e => throw e
/-- The `elan` toolchain file name (i.e., `lean-toolchain`). -/
def toolchainFileName : FilePath := "lean-toolchain"
/-- Parse a toolchain from the `lean-toolchain` file of the directory `dir`. -/
@[inline] def ToolchainVer.ofDir? (dir : FilePath) : IO (Option ToolchainVer) :=
ToolchainVer.ofFile? (dir / toolchainFileName)
protected def ToolchainVer.toString (ver : ToolchainVer) : String :=
match ver with
| .release ver => s!"{defaultOrigin}:v{ver}"
| .nightly date => s!"{defaultOrigin}:nightly-{date}"
| .pr n => s!"{prOrigin}:pr-release-{n}"
| .other s => s
instance : ToString ToolchainVer := ToolchainVer.toString
instance : ToJson ToolchainVer := (·.toString)
instance : FromJson ToolchainVer := (ToolchainVer.ofString <$> fromJson? ·)
protected def ToolchainVer.lt (a b : ToolchainVer) : Prop :=
match a, b with
| .release v1, .release v2 => v1 < v2
| .nightly d1, .nightly d2 => d1 < d2
| _, _ => False
instance : LT ToolchainVer := ToolchainVer.lt
instance ToolchainVer.decLt (a b : ToolchainVer) : Decidable (a < b) :=
match a, b with
| .release v1, .release v2 => inferInstanceAs (Decidable (v1 < v2))
| .nightly d1, .nightly d2 => inferInstanceAs (Decidable (d1 < d2))
| .release _, .pr _ | .release _, .nightly _ | .release _, .other _
| .nightly _, .release _ | .nightly _, .pr _ | .nightly _, .other _
| .pr _, _ | .other _, _ => .isFalse (by simp [LT.lt, ToolchainVer.lt])
protected def ToolchainVer.le (a b : ToolchainVer) : Prop :=
match a, b with
| .release v1, .release v2 => v1 v2
| .nightly d1, .nightly d2 => d1 d2
| .pr n1, .pr n2 => n1 = n2
| .other v1, .other v2 => v1 = v2
| _, _ => False
instance : LE ToolchainVer := ToolchainVer.le
instance ToolchainVer.decLe (a b : ToolchainVer) : Decidable (a b) :=
match a, b with
| .release v1, .release v2 => inferInstanceAs (Decidable (v1 v2))
| .nightly d1, .nightly d2 => inferInstanceAs (Decidable (d1 d2))
| .pr n1, .pr n2 => inferInstanceAs (Decidable (n1 = n2))
| .other v1, .other v2 => inferInstanceAs (Decidable (v1 = v2))
| .release _, .pr _ | .release _, .nightly _ | .release _, .other _
| .nightly _, .release _ | .nightly _, .pr _ | .nightly _, other _
| .pr _, .release _ | .pr _, .nightly _ | .pr _, .other _
| .other _, .release _ | .other _, .nightly _ | .other _, .pr _ =>
.isFalse (by simp [LE.le, ToolchainVer.le])
/-! ## Version Literals
Defines the `v!"<ver>"` syntax for version literals.
@@ -134,6 +241,7 @@ export DecodeVersion (decodeVersion)
instance : DecodeVersion SemVerCore := SemVerCore.parse
@[default_instance] instance : DecodeVersion StdVer := StdVer.parse
instance : DecodeVersion ToolchainVer := (pure <| ToolchainVer.ofString ·)
private def toResultExpr [ToExpr α] (x : Except String α) : Except String Expr :=
Functor.map toExpr x

View File

@@ -3,31 +3,31 @@
"packages":
[{"type": "path",
"scope": "",
"name": "root",
"name": "foo",
"manifestFile": "lake-manifest.json",
"inherited": true,
"dir": "./../foo/../a/../root",
"configFile": "lakefile.lean"},
{"type": "path",
"scope": "",
"name": "a",
"manifestFile": "lake-manifest.json",
"inherited": true,
"dir": "./../foo/../a",
"inherited": false,
"dir": "./../foo",
"configFile": "lakefile.lean"},
{"type": "path",
"scope": "",
"name": "b",
"manifestFile": "lake-manifest.json",
"inherited": true,
"dir": "./../foo/../b",
"dir": "./../foo/./../b",
"configFile": "lakefile.lean"},
{"type": "path",
"scope": "",
"name": "foo",
"name": "a",
"manifestFile": "lake-manifest.json",
"inherited": false,
"dir": "./../foo",
"inherited": true,
"dir": "./../foo/./../a",
"configFile": "lakefile.lean"},
{"type": "path",
"scope": "",
"name": "root",
"manifestFile": "lake-manifest.json",
"inherited": true,
"dir": "./../foo/./../b/./../root",
"configFile": "lakefile.lean"}],
"name": "bar",
"lakeDir": ".lake"}

View File

@@ -1,6 +1,6 @@
dep/hello
scripts/say-goodbye
scripts/greet
dep/hello
Hello, world!
Hello, me!
Hello, --me!
@@ -16,8 +16,8 @@ Hello from Dep!
Goodbye!
error: unknown script nonexistent
error: unknown script nonexistent
dep/hello
scripts/say-goodbye
scripts/greet
dep/hello
Hello, world!
Goodbye!

View File

@@ -17,6 +17,7 @@ fi
mkdir hello
pushd hello
$LAKE init hello
rm -f lean-toolchain
$LAKE update
git init
git checkout -b master
@@ -34,7 +35,7 @@ cd test
LAKE_PKG_URL_MAP=$HELLO_MAP $LAKE update 2>&1 | grep --color "file://"
# test that a second `lake update` is a no-op (with URLs)
# see https://github.com/leanprover/lean4/commit/6176fdba9e5a888225a23e5d558a005e0d1eb2f6#r125905901
LAKE_PKG_URL_MAP=$HELLO_MAP $LAKE update 2>&1 | diff - /dev/null
LAKE_PKG_URL_MAP=$HELLO_MAP $LAKE update --keep-toolchain 2>&1 | diff - /dev/null
rm -rf .lake/packages
# Test that Lake produces no warnings on a `lake build` after a `lake update`
@@ -42,7 +43,7 @@ rm -rf .lake/packages
$LAKE update
# test that a second `lake update` is a no-op (with file paths)
$LAKE update 2>&1 | diff - /dev/null
$LAKE update --keep-toolchain 2>&1 | diff - /dev/null
test -d .lake/packages/hello
# test that Lake produces no warnings
$LAKE build 3>&1 1>&2 2>&3 | diff - /dev/null

View File

@@ -75,8 +75,8 @@ pushd d
git init
git checkout -b master
cat >>lakefile.lean <<EOF
require b from git "../b" @ "master"
require c from git "../c" @ "master"
require b from git "../b" @ "master"
EOF
# make sure we pick up the version from b's manifest (a@1)
$LAKE update -v 2>&1 | grep --color 'first commit in a'
@@ -129,13 +129,20 @@ $LAKE update a -v
git commit -am 'second commit in b'
popd
pushd a
# a@4
# a@4/main
sed_i 's/third commit/fourth commit/' A.lean
git commit -am 'fourth commit in a'
popd
pushd c
# c@2
echo '-- second commit in c' >>C.lean
git commit -am 'second commit in c'
popd
pushd d
# d: b@1 -> b@2 => a@1 -> a@3
$LAKE update b -v
# test that Lake does not update c
grep --color 'second commit in c' .lake/packages/c/C.lean && exit 1 || true
# test 119: pickup a@3 and not a@4
grep --color 'third commit in a' .lake/packages/a/A.lean
# test the removal of `c` from the manifest

View File

@@ -13,6 +13,7 @@ $LAKE env | grep ".*=.*"
# NOTE: `printenv` exits with code 1 if the variable is not set
$LAKE env printenv LAKE
$LAKE env printenv LAKE_HOME
$LAKE env printenv LEAN
$LAKE env printenv LEAN_GITHASH
$LAKE env printenv LEAN_SYSROOT
$LAKE env printenv LEAN_AR | grep --color ar

View File

@@ -1,14 +1,7 @@
{"version": "1.1.0",
"packagesDir": ".lake/packages",
"packages":
[{"type": "path",
"scope": "",
"name": "foo",
"manifestFile": "lake-manifest.json",
"inherited": false,
"dir": "./foo",
"configFile": "lakefile.lean"},
{"url": "bar",
[{"url": "bar",
"type": "git",
"subDir": null,
"scope": "foo",
@@ -17,6 +10,13 @@
"manifestFile": "lake-manifest.json",
"inputRev": null,
"inherited": false,
"configFile": "lakefile.lean"},
{"type": "path",
"scope": "",
"name": "foo",
"manifestFile": "lake-manifest.json",
"inherited": false,
"dir": "./foo",
"configFile": "lakefile.lean"}],
"name": "«foo-bar»",
"lakeDir": ".lake"}

View File

@@ -11,13 +11,13 @@ export ELAN_TOOLCHAIN=test
grep --color "error: bogus/bogus: could not materialize package: dependency has no explicit source and was not found on Reservoir"
./clean.sh
$LAKE -f git.toml update
$LAKE -f git.toml update --keep-toolchain
# Test that barrels are not fetched for non-Reservoir dependencies
$LAKE -v -f git.toml build @Cli:extraDep |
grep --color "Cli:optBarrel" && exit 1 || true
./clean.sh
$LAKE -f barrel.lean update
$LAKE -f barrel.lean update --keep-toolchain
# Test that a barrel is not fetched for an unbuilt dependency
$LAKE -v -f barrel.lean build @test:extraDep |
grep --color "Cli:optBarrel" && exit 1 || true
@@ -53,11 +53,11 @@ LEAN_GITHASH=ec3042d94bd11a42430f9e14d39e26b1f880f99b \
$LAKE -f barrel.lean build Cli --no-build
./clean.sh
$LAKE -f require.lean update -v
$LAKE -f require.lean update -v --keep-toolchain
test -d .lake/packages/doc-gen4
$LAKE -f require.lean resolve-deps # validate manifest
./clean.sh
$LAKE -f require.toml update v
$LAKE -f require.toml update -v --keep-toolchain
test -d .lake/packages/doc-gen4
$LAKE -f require.toml resolve-deps # validate manifest

View File

@@ -4,6 +4,7 @@ open Lake DSL
package bar where
moreLeanArgs := #["-DmaxHeartbeats=888000"]
require baz from ".." / "baz"
require leaf from ".." / "leaf" with NameMap.empty.insert `val "888000"
lean_lib X

View File

View File

@@ -0,0 +1,7 @@
import Lake
open Lake DSL
package baz where
moreLeanArgs := #["-DmaxHeartbeats=999000"]
lean_lib X

View File

@@ -1,3 +1,3 @@
rm -rf .lake foo/.lake bar/.lake leaf/.lake
rm -f lake-manifest.json foo/lake-manifest.json bar/lake-manifest.json leaf/lake-manifest.json
rm -rf .lake foo/.lake bar/.lake baz/.lake leaf/.lake
rm -f lake-manifest.json foo/lake-manifest.json bar/lake-manifest.json baz/lake-manifest.json leaf/lake-manifest.json
rm -f lake-manifest-1.json

View File

@@ -10,13 +10,13 @@ LAKE=${LAKE:-../../.lake/build/bin/lake}
# Later packages and libraries in the dependency tree shadow earlier ones.
# https://github.com/leanprover/lean4/issues/2548
$LAKE update
$LAKE update -v
$LAKE build +A -v | grep --color 222000
$LAKE build +A.B -v | grep --color 333000
$LAKE build +A.B.C -v | grep --color 333000
$LAKE build +X -v | grep --color 888000
$LAKE build +Y -v | grep --color 666000
$LAKE build +Z -v | grep --color 666000
$LAKE build +X -v | grep --color 888000 # bar
$LAKE build +Y -v | grep --color 666000 # order
$LAKE build +Z -v | grep --color 666000 # leaf from order
$LAKE exe Y | grep --color root
# Tests that `lake update` does not reorder packages in the manifest

View File

@@ -1 +1,2 @@
/foo
lean-toolchain

View File

@@ -1 +1,2 @@
rm -rf foo
rm -f lake-manifest.json lean-toolchain

View File

@@ -0,0 +1,6 @@
import Lake
open System Lake DSL
package test
require foo from "foo"

View File

@@ -1,9 +1,9 @@
#!/usr/bin/env bash
set -euxo pipefail
# Tests that Lake rebuilds when toolchain changes
# See https://github.com/leanprover/lake/issues/62
# Requires Elan to download a toolchain
LAKE=${LAKE:-../../../.lake/build/bin/lake}
# Tests which require Elan to download a toolchain
# skip if no elan found
if ! command -v elan > /dev/null; then
@@ -11,9 +11,20 @@ if ! command -v elan > /dev/null; then
exit 0
fi
# Test that Lake rebuilds when toolchain changes
# See https://github.com/leanprover/lake/issues/62
TOOLCHAIN=leanprover/lean4:v4.0.0
./clean.sh
elan run --install leanprover/lean4:v4.0.0 lake new foo
cd foo
elan run leanprover/lean4:v4.0.0 lake build +Foo:olean -v | grep --color Foo.olean
rm lean-toolchain
${LAKE:-../../../.lake/build/bin/lake} build -v | grep --color Foo.olean
elan run --install $TOOLCHAIN lake new foo
pushd foo
elan run $TOOLCHAIN lake build +Foo:olean -v | grep --color Foo.olean
rm lean-toolchain # switch to Lake under test
$LAKE build -v | grep --color Foo.olean
popd
# Test Lake runs under the new toolchain after Lake updates it
rm -f foo/lake-manifest.json
echo $TOOLCHAIN > foo/lean-toolchain
$LAKE update
grep --color -F '"version": 5' lake-manifest.json

View File

@@ -0,0 +1 @@
lean-toolchain

View File

@@ -0,0 +1 @@
name = "a"

View File

@@ -0,0 +1 @@
name = "b"

View File

@@ -0,0 +1 @@
rm -f lean-toolchain a/lean-toolchain b/lean-toolchain

View File

@@ -0,0 +1,9 @@
name = "test"
[[require]]
name = "a"
path = "a"
[[require]]
name = "b"
path = "b"

View File

@@ -0,0 +1,35 @@
import Lake.Util.Version
open Lake
def checkParse (tc : String) :=
IO.println <| repr <| ToolchainVer.ofString tc
def checkLt (tc1 tc2 : String) :=
IO.println <| decide <| ToolchainVer.ofString tc1 < ToolchainVer.ofString tc2
def test := do
IO.println ""
checkParse "leanprover/lean4:v4.13.0-rc1"
checkParse "leanprover/lean4:nightly-2024-09-15"
checkParse "leanprover/lean4-pr-releases:pr-release-101"
checkParse "leanprover/lean:v4.1.0"
checkParse "4.12.0"
checkLt "4.6.0-rc1" "v4.6.0"
checkLt "4.12.0" "leanprover/lean4:v4.13.0-rc1"
checkLt "nightly-2024-09-08" "nightly-2024-10-09"
checkLt "nightly-2024-09-08" "4.0.0"
/--
info:
Lake.ToolchainVer.release { toSemVerCore := { major := 4, minor := 13, patch := 0 }, specialDescr := "rc1" }
Lake.ToolchainVer.nightly { year := 2024, month := 9, day := 15 }
Lake.ToolchainVer.pr 101
Lake.ToolchainVer.other "leanprover/lean:v4.1.0"
Lake.ToolchainVer.release { toSemVerCore := { major := 4, minor := 12, patch := 0 }, specialDescr := "" }
true
true
true
false
-/
#guard_msgs in #eval test

View File

@@ -0,0 +1,68 @@
#!/usr/bin/env bash
set -euxo pipefail
LAKE=${LAKE:-../../.lake/build/bin/lake}
# Ensure Lake thinks there is a elan environment configured
export ELAN_HOME=
# Tests the toolchain update functionality of `lake update`
RESTART_CODE=4
test_update(){
ELAN=true $LAKE update 2>&1 | grep --color "updating toolchain to '$1'"
cat lean-toolchain | diff - <(echo -n "$1")
}
# Test toolchain version API
$LAKE lean test.lean
# Test no toolchain information
./clean.sh
$LAKE update 2>&1 | grep --color "toolchain not updated; no toolchain information found"
# Test a single unknown candidate
./clean.sh
echo lean-a > a/lean-toolchain
test_update lean-a
# Test a single known (PR) candidate
./clean.sh
echo pr-release-101 > a/lean-toolchain
test_update leanprover/lean4-pr-releases:pr-release-101
# Test release comparison
./clean.sh
echo v4.4.0 > a/lean-toolchain
echo v4.8.0 > b/lean-toolchain
test_update leanprover/lean4:v4.8.0
# Test nightly comparison
./clean.sh
echo nightly-2024-10-01 > a/lean-toolchain
echo nightly-2024-01-10 > b/lean-toolchain
test_update leanprover/lean4:nightly-2024-10-01
# Test up-to-date root
./clean.sh
echo v4.4.0 > a/lean-toolchain
echo v4.8.0 > b/lean-toolchain
echo v4.10.0 > lean-toolchain
$LAKE update 2>&1 | grep --color "toolchain not updated; already up-to-date"
# Test multiple candidates
./clean.sh
echo lean-a > a/lean-toolchain
echo lean-b > b/lean-toolchain
$LAKE update 2>&1 | grep --color "toolchain not updated; multiple toolchain candidates"
# Test manual restart
./clean.sh
echo lean-a > a/lean-toolchain
ELAN= $LAKE update 2>&1 && exit 1 || [ $? = $RESTART_CODE ]
# Test elan restart
./clean.sh
echo lean-a > a/lean-toolchain
ELAN=echo $LAKE update | grep --color "run --install lean-a lake update"

View File

@@ -61,7 +61,9 @@ struct olean_header {
0b0;
#endif
// 33 bytes: Lean version string, padded with '\0' to the right
// e.g. "4.12.0-nightly-2024-10-18". May not be null-terminated.
// e.g. "4.12.0-nightly-2024-10-18". Other suffixes after the version
// triple currently in use are `-rcN` for some `N` and `-pre` for any
// other non-release commit. Not necessarily null-terminated.
char lean_version[33];
// 81b008650766442a0dfa9faa796e4588c9d7d3a1
// 40 bytes: build githash, padded with `\0` to the right

View File

@@ -861,11 +861,7 @@ void initialize_library_util() {
sstream out;
out << LEAN_VERSION_MAJOR << "."
<< LEAN_VERSION_MINOR << "." << LEAN_VERSION_PATCH;
if (std::strlen(LEAN_SPECIAL_VERSION_DESC) > 0) {
out << "-" << LEAN_SPECIAL_VERSION_DESC;
}
out << LEAN_VERSION_STRING;
g_short_version_string = new std::string(out.str());
if (std::strlen(LEAN_PLATFORM_TARGET) > 0) {
out << ", " << LEAN_PLATFORM_TARGET;

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