Skip to content

Add shift_arithmetic_left for signed integers#4112

Draft
remix7531 wants to merge 1 commit intoFStarLang:masterfrom
remix7531:fix-integer-shift
Draft

Add shift_arithmetic_left for signed integers#4112
remix7531 wants to merge 1 commit intoFStarLang:masterfrom
remix7531:fix-integer-shift

Conversation

@remix7531
Copy link
Contributor

Add shift_arithmetic_left to FStar.Int and FStar.Int{8,16,32,64,128}. This performs a left shift on the two's complement representation without requiring the input to be non-negative.

The existing shift_left requires 0 <= a, matching C semantics where left-shifting a negative signed integer is undefined behavior. shift_arithmetic_left accepts any signed integer, matching the semantics of << on signed integers in Rust and C++20+.

Changes:

  • FStar.Int.fsti: definition + two bit-level lemmas
  • FStar.Int.fst: trivial proofs for the lemmas
  • .scripts/FStar.IntN.fstip: val + infix operator (<<<^)
  • .scripts/FStar.IntN.fstp: implementation
  • Regenerated FStar.Int{8,16,32,64,128}.{fsti,fst} via mk_int.sh

This commit was created with the assistance of Claude (Anthropic).

Add shift_arithmetic_left to FStar.Int and FStar.Int{8,16,32,64,128}.
This performs a left shift on the two's complement representation
without requiring the input to be non-negative.

The existing shift_left requires 0 <= a, matching C semantics where
left-shifting a negative signed integer is undefined behavior.
shift_arithmetic_left accepts any signed integer, matching the
semantics of << on signed integers in Rust and C++20+.

Changes:
- FStar.Int.fsti: definition + two bit-level lemmas
- FStar.Int.fst: trivial proofs for the lemmas
- .scripts/FStar.IntN.fstip: val + infix operator (<<<^)
- .scripts/FStar.IntN.fstp: implementation
- Regenerated FStar.Int{8,16,32,64,128}.{fsti,fst} via mk_int.sh

This commit was created with the assistance of Claude (Anthropic).
@remix7531
Copy link
Contributor Author

The name shift_arithmetic_left was chosen for symmetry with the existing shift_arithmetic_right. However, the term is a misnomer. Arithmetic and logical shifts only differ for right shifts (sign-extending vs zero-filling). For left shifts, both operations are identical at the bit level. The only difference here is the relaxed precondition (negative inputs are allowed).

Alternatives considered, open to suggestions on naming:

  • shift_left_twos_complement: more precise, but verbose
  • shift_left_unrestricted: describes the relaxed precondition, but doesn't convey semantics

Relaxing the precondition on the existing shift_left, would break existing C-orientation as that would be undefined behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant