Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: BitVec.toInt_abs #6154

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open

feat: BitVec.toInt_abs #6154

wants to merge 9 commits into from

Conversation

bollu
Copy link
Contributor

@bollu bollu commented Nov 21, 2024

This PR implements BitVec.toInt_abs.

The absolute value of x : BitVec w is naively a case split on the sign of x.
However, recall that when x = intMin w, -x = x.
Thus, the full value of abs x is computed by the case split:

  • If x : BitVec w is intMin, then its absolute value is also intMin w, and
    thus toInt will equal intMin.toInt.
  • Otherwise, if x is negative, then x.abs.toInt = (-x).toInt.
  • Finally, when x is nonnegative, then x.abs.toInt = x.toInt.
theorem toInt_abs {x : BitVec w} :
  x.abs.toInt =
    if x = intMin w then (intMin w).toInt
    else if x.msb then -x.toInt
    else x.toInt

We also provide a variant of toInt_abs that
hides the case split for x being positive or negative by using natAbs.

theorem toInt_abs_eq_natAbs {x : BitVec w} : x.abs.toInt =
    if x = intMin w then (intMin w).toInt else x.toInt.natAbs

Supercedes #5787

This PR adds a theorem that describes `(-x).toInt` as a case-split:
- If `x = intMin w`, then `(-x)` overflows and is equal to `intMin w = x = -x`.
  and thus `(-x).toInt = x.toInt`.
- otherwise, `(-x).toInt = - (x.toInt)`.

This is a building block to prove `BitVec.toInt_abs`,
from leanprover#5787
This PR implements `BitVec.toInt_abs`.

The absolute value of `x : BitVec w` is naively a case split on the sign of `x`.
However, recall that when `x = intMin w`, `-x = x`.
Thus, the full value of `abs x` is computed by the case split:
- If `x : BitVec w` is `intMin`, then its absolute value is also `intMin w`, and
  thus `toInt` will equal `intMin.toInt`.
- Otherwise, if `x` is negative, then `x.abs.toInt = (-x).toInt`.
- If `x` is positive, then it is equal to `x.abs.toInt = x.toInt`.

```lean
theorem toInt_abs {x : BitVec w} :
  x.abs.toInt =
    if x = intMin w then (intMin w).toInt
    else if x.msb then -x.toInt
    else x.toInt
```

We also provide a variant of `toInt_abs` that
hides the case split for `x` being positive or negative by using `natAbs`.
```lean
theorem toInt_abs_eq_natAbs {x : BitVec w} : x.abs.toInt =
    if x = intMin w then (intMin w).toInt else x.toInt.natAbs
```

Supercedes leanprover#5787
@github-actions github-actions bot added the toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN label Nov 21, 2024
@leanprover-community-bot
Copy link
Collaborator

leanprover-community-bot commented Nov 21, 2024

Mathlib CI status (docs):

  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase 799b2b662825e646609963921f2c68489b2e664a --onto 72e952eadc6a171310f1d8e9d6e78acf98421494. (2024-11-21 13:01:42)
  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase 799b2b662825e646609963921f2c68489b2e664a --onto 884a9ea2ff70bb4d0c6da4a1c23ffc26c3a974ee. (2024-11-25 14:16:57)
  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase 799b2b662825e646609963921f2c68489b2e664a --onto 9a17919ef11c2dba824498229633b8333a0b53d9. (2024-11-26 15:27:00)

Co-authored-by: Tobias Grosser <github@grosser.es>
Co-authored-by: Tobias Grosser <github@grosser.es>
@tobiasgrosser
Copy link
Contributor

Can you drop the mention of 'stacked pr' in the commit message?

@bollu bollu changed the title feat: BitVec.toInt_abs [2/2] feat: BitVec.toInt_abs Nov 21, 2024
@bollu
Copy link
Contributor Author

bollu commented Nov 21, 2024

@tobiasgrosser done

@bollu bollu marked this pull request as ready for review November 21, 2024 17:27
@bollu bollu requested a review from kim-em as a code owner November 21, 2024 17:27
@bollu
Copy link
Contributor Author

bollu commented Nov 21, 2024

awaiting-review

@bollu
Copy link
Contributor Author

bollu commented Nov 21, 2024

changelog-library

@github-actions github-actions bot added the changelog-library Library label Nov 21, 2024
@kim-em
Copy link
Collaborator

kim-em commented Nov 21, 2024

It doesn't need to be in this PR, but I would like to also have

theorem natAbs_toInt (x : BitVec w) : x.toInt.natAbs = if x.msb then x.toNat - (2^(w-1) - 1) else x.toNat

(didn't check the RHS carefully, but something like that ought to be true).

@kim-em kim-em added the awaiting-author Waiting for PR author to address issues label Nov 21, 2024
Co-authored-by: Tobias Grosser <github@grosser.es>
@kim-em
Copy link
Collaborator

kim-em commented Nov 26, 2024

Otherwise looking good now. Switch back to awaiting-review when you're ready for me to merge.

@bollu
Copy link
Contributor Author

bollu commented Nov 26, 2024

awaiting-review

@github-actions github-actions bot added awaiting-review Waiting for someone to review the PR and removed awaiting-author Waiting for PR author to address issues labels Nov 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting-review Waiting for someone to review the PR changelog-library Library toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants