This PR cleans up many duplicate instances (or, in some cases, needlessly duplicated `def X := ...; instance Y := X`).
1992 lines
72 KiB
Text
1992 lines
72 KiB
Text
/-
|
|
Copyright (c) 2024 Lean FRO, LLC. All rights reserved.
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
Authors: Henrik Böving
|
|
-/
|
|
module
|
|
|
|
prelude
|
|
import Init.Data.UInt.Basic
|
|
|
|
set_option linter.missingDocs true
|
|
|
|
/-!
|
|
This module contains the definition of signed fixed width integer types as well as basic arithmetic
|
|
and bitwise operations on top of it.
|
|
-/
|
|
|
|
/--
|
|
Signed 8-bit integers.
|
|
|
|
This type has special support in the compiler so it can be represented by an unboxed 8-bit value.
|
|
-/
|
|
structure Int8 where
|
|
private ofUInt8 ::
|
|
/--
|
|
Converts an 8-bit signed integer into the 8-bit unsigned integer that is its two's complement
|
|
encoding.
|
|
-/
|
|
toUInt8 : UInt8
|
|
|
|
/--
|
|
Signed 16-bit integers.
|
|
|
|
This type has special support in the compiler so it can be represented by an unboxed 16-bit value.
|
|
-/
|
|
structure Int16 where
|
|
private ofUInt16 ::
|
|
/--
|
|
Converts an 16-bit signed integer into the 16-bit unsigned integer that is its two's complement
|
|
encoding.
|
|
-/
|
|
toUInt16 : UInt16
|
|
|
|
/--
|
|
Signed 32-bit integers.
|
|
|
|
This type has special support in the compiler so it can be represented by an unboxed 32-bit value.
|
|
-/
|
|
structure Int32 where
|
|
private ofUInt32 ::
|
|
/--
|
|
Converts an 32-bit signed integer into the 32-bit unsigned integer that is its two's complement
|
|
encoding.
|
|
-/
|
|
toUInt32 : UInt32
|
|
|
|
/--
|
|
Signed 64-bit integers.
|
|
|
|
This type has special support in the compiler so it can be represented by an unboxed 64-bit value.
|
|
-/
|
|
structure Int64 where
|
|
private ofUInt64 ::
|
|
/--
|
|
Converts an 64-bit signed integer into the 64-bit unsigned integer that is its two's complement
|
|
encoding.
|
|
-/
|
|
toUInt64 : UInt64
|
|
|
|
/--
|
|
Signed integers that are the size of a word on the platform's architecture.
|
|
|
|
On a 32-bit architecture, `ISize` is equivalent to `Int32`. On a 64-bit machine, it is equivalent to
|
|
`Int64`. This type has special support in the compiler so it can be represented by an unboxed value.
|
|
-/
|
|
structure ISize where
|
|
private ofUSize ::
|
|
/--
|
|
Converts a word-sized signed integer into the word-sized unsigned integer that is its two's
|
|
complement encoding.
|
|
-/
|
|
toUSize : USize
|
|
|
|
/-- The number of distinct values representable by `Int8`, that is, `2^8 = 256`. -/
|
|
abbrev Int8.size : Nat := 256
|
|
|
|
/--
|
|
Obtain the `BitVec` that contains the 2's complement representation of the `Int8`.
|
|
-/
|
|
@[inline] def Int8.toBitVec (x : Int8) : BitVec 8 := x.toUInt8.toBitVec
|
|
|
|
theorem Int8.toBitVec.inj : {x y : Int8} → x.toBitVec = y.toBitVec → x = y
|
|
| ⟨⟨_⟩⟩, ⟨⟨_⟩⟩, rfl => rfl
|
|
|
|
/-- Obtains the `Int8` that is 2's complement equivalent to the `UInt8`. -/
|
|
@[inline] def UInt8.toInt8 (i : UInt8) : Int8 := Int8.ofUInt8 i
|
|
@[inline, deprecated UInt8.toInt8 (since := "2025-02-13"), inherit_doc UInt8.toInt8]
|
|
def Int8.mk (i : UInt8) : Int8 := UInt8.toInt8 i
|
|
/--
|
|
Converts an arbitrary-precision integer to an 8-bit integer, wrapping on overflow or underflow.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `Int8.ofInt 48 = 48`
|
|
* `Int8.ofInt (-115) = -115`
|
|
* `Int8.ofInt (-129) = 127`
|
|
* `Int8.ofInt (128) = -128`
|
|
-/
|
|
@[extern "lean_int8_of_int"]
|
|
def Int8.ofInt (i : @& Int) : Int8 := ⟨⟨BitVec.ofInt 8 i⟩⟩
|
|
/--
|
|
Converts a natural number to an 8-bit signed integer, wrapping around on overflow.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `Int8.ofNat 53 = 53`
|
|
* `Int8.ofNat 127 = 127`
|
|
* `Int8.ofNat 128 = -128`
|
|
* `Int8.ofNat 255 = -1`
|
|
-/
|
|
@[extern "lean_int8_of_nat"]
|
|
def Int8.ofNat (n : @& Nat) : Int8 := ⟨⟨BitVec.ofNat 8 n⟩⟩
|
|
/--
|
|
Converts an arbitrary-precision integer to an 8-bit integer, wrapping on overflow or underflow.
|
|
|
|
Examples:
|
|
* `Int.toInt8 48 = 48`
|
|
* `Int.toInt8 (-115) = -115`
|
|
* `Int.toInt8 (-129) = 127`
|
|
* `Int.toInt8 (128) = -128`
|
|
-/
|
|
abbrev Int.toInt8 := Int8.ofInt
|
|
/--
|
|
Converts a natural number to an 8-bit signed integer, wrapping around to negative numbers on
|
|
overflow.
|
|
|
|
Examples:
|
|
* `Nat.toInt8 53 = 53`
|
|
* `Nat.toInt8 127 = 127`
|
|
* `Nat.toInt8 128 = -128`
|
|
* `Nat.toInt8 255 = -1`
|
|
-/
|
|
abbrev Nat.toInt8 := Int8.ofNat
|
|
|
|
/--
|
|
Converts an 8-bit signed integer to an arbitrary-precision integer that denotes the same number.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int8_to_int"]
|
|
def Int8.toInt (i : Int8) : Int := i.toBitVec.toInt
|
|
/--
|
|
Converts an 8-bit signed integer to a natural number, mapping all negative numbers to `0`.
|
|
|
|
Use `Int8.toBitVec` to obtain the two's complement representation.
|
|
-/
|
|
@[inline] def Int8.toNatClampNeg (i : Int8) : Nat := i.toInt.toNat
|
|
@[inline, deprecated Int8.toNatClampNeg (since := "2025-02-13"), inherit_doc Int8.toNatClampNeg]
|
|
def Int8.toNat (i : Int8) : Nat := i.toInt.toNat
|
|
/-- Obtains the `Int8` whose 2's complement representation is the given `BitVec 8`. -/
|
|
@[inline] def Int8.ofBitVec (b : BitVec 8) : Int8 := ⟨⟨b⟩⟩
|
|
/--
|
|
Negates 8-bit signed integers. Usually accessed via the `-` prefix operator.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int8_neg"]
|
|
def Int8.neg (i : Int8) : Int8 := ⟨⟨-i.toBitVec⟩⟩
|
|
|
|
instance : ToString Int8 where
|
|
toString i := toString i.toInt
|
|
instance : Repr Int8 where
|
|
reprPrec i prec := reprPrec i.toInt prec
|
|
instance : ReprAtom Int8 := ⟨⟩
|
|
|
|
instance : Hashable Int8 where
|
|
hash i := i.toUInt8.toUInt64
|
|
|
|
instance Int8.instOfNat : OfNat Int8 n := ⟨Int8.ofNat n⟩
|
|
instance Int8.instNeg : Neg Int8 where
|
|
neg := Int8.neg
|
|
|
|
/-- The largest number that `Int8` can represent: `2^7 - 1 = 127`. -/
|
|
abbrev Int8.maxValue : Int8 := 127
|
|
/-- The smallest number that `Int8` can represent: `-2^7 = -128`. -/
|
|
abbrev Int8.minValue : Int8 := -128
|
|
/-- Constructs an `Int8` from an `Int` that is known to be in bounds. -/
|
|
@[inline]
|
|
def Int8.ofIntLE (i : Int) (_hl : Int8.minValue.toInt ≤ i) (_hr : i ≤ Int8.maxValue.toInt) : Int8 :=
|
|
Int8.ofInt i
|
|
/-- Constructs an `Int8` from an `Int`, clamping if the value is too small or too large. -/
|
|
def Int8.ofIntTruncate (i : Int) : Int8 :=
|
|
if hl : Int8.minValue.toInt ≤ i then
|
|
if hr : i ≤ Int8.maxValue.toInt then
|
|
Int8.ofIntLE i hl hr
|
|
else
|
|
Int8.minValue
|
|
else
|
|
Int8.minValue
|
|
/--
|
|
Adds two 8-bit signed integers, wrapping around on over- or underflow. Usually accessed via the `+`
|
|
operator.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int8_add"]
|
|
protected def Int8.add (a b : Int8) : Int8 := ⟨⟨a.toBitVec + b.toBitVec⟩⟩
|
|
/--
|
|
Subtracts one 8-bit signed integer from another, wrapping around on over- or underflow. Usually
|
|
accessed via the `-` operator.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int8_sub"]
|
|
protected def Int8.sub (a b : Int8) : Int8 := ⟨⟨a.toBitVec - b.toBitVec⟩⟩
|
|
/--
|
|
Multiplies two 8-bit signed integers, wrapping around on over- or underflow. Usually accessed via
|
|
the `*` operator.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int8_mul"]
|
|
protected def Int8.mul (a b : Int8) : Int8 := ⟨⟨a.toBitVec * b.toBitVec⟩⟩
|
|
/--
|
|
Truncating division for 8-bit signed integers, rounding towards zero. Usually accessed via the `/`
|
|
operator.
|
|
|
|
Division by zero is defined to be zero.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `Int8.div 10 3 = 3`
|
|
* `Int8.div 10 (-3) = (-3)`
|
|
* `Int8.div (-10) (-3) = 3`
|
|
* `Int8.div (-10) 3 = (-3)`
|
|
* `Int8.div 10 0 = 0`
|
|
-/
|
|
@[extern "lean_int8_div"]
|
|
protected def Int8.div (a b : Int8) : Int8 := ⟨⟨BitVec.sdiv a.toBitVec b.toBitVec⟩⟩
|
|
/--
|
|
The power operation, raising an 8-bit signed integer to a natural number power,
|
|
wrapping around on overflow. Usually accessed via the `^` operator.
|
|
|
|
This function is currently *not* overridden at runtime with an efficient implementation,
|
|
and should be used with caution. See https://github.com/leanprover/lean4/issues/7887.
|
|
-/
|
|
protected def Int8.pow (x : Int8) (n : Nat) : Int8 :=
|
|
match n with
|
|
| 0 => 1
|
|
| n + 1 => Int8.mul (Int8.pow x n) x
|
|
/--
|
|
The modulo operator for 8-bit signed integers, which computes the remainder when dividing one
|
|
integer by another with the T-rounding convention used by `Int8.div`. Usually accessed via the `%`
|
|
operator.
|
|
|
|
When the divisor is `0`, the result is the dividend rather than an error.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `Int8.mod 5 2 = 1`
|
|
* `Int8.mod 5 (-2) = 1`
|
|
* `Int8.mod (-5) 2 = (-1)`
|
|
* `Int8.mod (-5) (-2) = (-1)`
|
|
* `Int8.mod 4 2 = 0`
|
|
* `Int8.mod 4 (-2) = 0`
|
|
* `Int8.mod 4 0 = 4`
|
|
* `Int8.mod (-4) 0 = (-4)`
|
|
-/
|
|
@[extern "lean_int8_mod"]
|
|
protected def Int8.mod (a b : Int8) : Int8 := ⟨⟨BitVec.srem a.toBitVec b.toBitVec⟩⟩
|
|
/--
|
|
Bitwise and for 8-bit signed integers. Usually accessed via the `&&&` operator.
|
|
|
|
Each bit of the resulting integer is set if the corresponding bits of both input integers are set,
|
|
according to the two's complement representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int8_land"]
|
|
protected def Int8.land (a b : Int8) : Int8 := ⟨⟨a.toBitVec &&& b.toBitVec⟩⟩
|
|
/--
|
|
Bitwise or for 8-bit signed integers. Usually accessed via the `|||` operator.
|
|
|
|
Each bit of the resulting integer is set if at least one of the corresponding bits of the input
|
|
integers is set, according to the two's complement representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int8_lor"]
|
|
protected def Int8.lor (a b : Int8) : Int8 := ⟨⟨a.toBitVec ||| b.toBitVec⟩⟩
|
|
/--
|
|
Bitwise exclusive or for 8-bit signed integers. Usually accessed via the `^^^` operator.
|
|
|
|
Each bit of the resulting integer is set if exactly one of the corresponding bits of the input
|
|
integers is set, according to the two's complement representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int8_xor"]
|
|
protected def Int8.xor (a b : Int8) : Int8 := ⟨⟨a.toBitVec ^^^ b.toBitVec⟩⟩
|
|
/--
|
|
Bitwise left shift for 8-bit signed integers. Usually accessed via the `<<<` operator.
|
|
|
|
Signed integers are interpreted as bitvectors according to the two's complement representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int8_shift_left"]
|
|
protected def Int8.shiftLeft (a b : Int8) : Int8 := ⟨⟨a.toBitVec <<< (b.toBitVec.smod 8)⟩⟩
|
|
/--
|
|
Arithmetic right shift for 8-bit signed integers. Usually accessed via the `<<<` operator.
|
|
|
|
The high bits are filled with the value of the most significant bit.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int8_shift_right"]
|
|
protected def Int8.shiftRight (a b : Int8) : Int8 := ⟨⟨BitVec.sshiftRight' a.toBitVec (b.toBitVec.smod 8)⟩⟩
|
|
/--
|
|
Bitwise complement, also known as bitwise negation, for 8-bit signed integers. Usually accessed via
|
|
the `~~~` prefix operator.
|
|
|
|
Each bit of the resulting integer is the opposite of the corresponding bit of the input integer.
|
|
Integers use the two's complement representation, so `Int8.complement a = -(a + 1)`.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int8_complement"]
|
|
protected def Int8.complement (a : Int8) : Int8 := ⟨⟨~~~a.toBitVec⟩⟩
|
|
/--
|
|
Computes the absolute value of an 8-bit signed integer.
|
|
|
|
This function is equivalent to `if a < 0 then -a else a`, so in particular `Int8.minValue` will be
|
|
mapped to `Int8.minValue`.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int8_abs"]
|
|
protected def Int8.abs (a : Int8) : Int8 := ⟨⟨a.toBitVec.abs⟩⟩
|
|
|
|
/--
|
|
Decides whether two 8-bit signed integers are equal. Usually accessed via the `DecidableEq Int8`
|
|
instance.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `Int8.decEq 123 123 = .isTrue rfl`
|
|
* `(if ((-7) : Int8) = 7 then "yes" else "no") = "no"`
|
|
* `show (7 : Int8) = 7 by decide`
|
|
-/
|
|
@[extern "lean_int8_dec_eq"]
|
|
def Int8.decEq (a b : Int8) : Decidable (a = b) :=
|
|
match a, b with
|
|
| ⟨n⟩, ⟨m⟩ =>
|
|
if h : n = m then
|
|
isTrue <| h ▸ rfl
|
|
else
|
|
isFalse (fun h' => Int8.noConfusion h' (fun h' => absurd h' h))
|
|
|
|
/--
|
|
Strict inequality of 8-bit signed integers, defined as inequality of the corresponding integers.
|
|
Usually accessed via the `<` operator.
|
|
-/
|
|
protected def Int8.lt (a b : Int8) : Prop := a.toBitVec.slt b.toBitVec
|
|
/--
|
|
Non-strict inequality of 8-bit signed integers, defined as inequality of the corresponding integers.
|
|
Usually accessed via the `≤` operator.
|
|
-/
|
|
protected def Int8.le (a b : Int8) : Prop := a.toBitVec.sle b.toBitVec
|
|
|
|
instance : Inhabited Int8 where
|
|
default := 0
|
|
|
|
instance : Add Int8 := ⟨Int8.add⟩
|
|
instance : Sub Int8 := ⟨Int8.sub⟩
|
|
instance : Mul Int8 := ⟨Int8.mul⟩
|
|
instance : Pow Int8 Nat := ⟨Int8.pow⟩
|
|
instance : Mod Int8 := ⟨Int8.mod⟩
|
|
instance : Div Int8 := ⟨Int8.div⟩
|
|
instance : LT Int8 := ⟨Int8.lt⟩
|
|
instance : LE Int8 := ⟨Int8.le⟩
|
|
instance : Complement Int8 := ⟨Int8.complement⟩
|
|
instance : AndOp Int8 := ⟨Int8.land⟩
|
|
instance : OrOp Int8 := ⟨Int8.lor⟩
|
|
instance : Xor Int8 := ⟨Int8.xor⟩
|
|
instance : ShiftLeft Int8 := ⟨Int8.shiftLeft⟩
|
|
instance : ShiftRight Int8 := ⟨Int8.shiftRight⟩
|
|
instance : DecidableEq Int8 := Int8.decEq
|
|
|
|
/--
|
|
Converts `true` to `1` and `false` to `0`.
|
|
-/
|
|
@[extern "lean_bool_to_int8"]
|
|
def Bool.toInt8 (b : Bool) : Int8 := if b then 1 else 0
|
|
|
|
/--
|
|
Decides whether one 8-bit signed integer is strictly less than another. Usually accessed via the
|
|
`DecidableLT Int8` instance.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `(if ((-7) : Int8) < 7 then "yes" else "no") = "yes"`
|
|
* `(if (5 : Int8) < 5 then "yes" else "no") = "no"`
|
|
* `show ¬((7 : Int8) < 7) by decide`
|
|
-/
|
|
@[extern "lean_int8_dec_lt"]
|
|
def Int8.decLt (a b : Int8) : Decidable (a < b) :=
|
|
inferInstanceAs (Decidable (a.toBitVec.slt b.toBitVec))
|
|
|
|
/--
|
|
Decides whether one 8-bit signed integer is less than or equal to another. Usually accessed via the
|
|
`DecidableLE Int8` instance.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `(if ((-7) : Int8) ≤ 7 then "yes" else "no") = "yes"`
|
|
* `(if (15 : Int8) ≤ 15 then "yes" else "no") = "yes"`
|
|
* `(if (15 : Int8) ≤ 5 then "yes" else "no") = "no"`
|
|
* `show (7 : Int8) ≤ 7 by decide`
|
|
-/
|
|
@[extern "lean_int8_dec_le"]
|
|
def Int8.decLe (a b : Int8) : Decidable (a ≤ b) :=
|
|
inferInstanceAs (Decidable (a.toBitVec.sle b.toBitVec))
|
|
|
|
attribute [instance] Int8.decLt Int8.decLe
|
|
|
|
instance : Max Int8 := maxOfLe
|
|
instance : Min Int8 := minOfLe
|
|
|
|
/-- The number of distinct values representable by `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
|
|
|
|
theorem Int16.toBitVec.inj : {x y : Int16} → x.toBitVec = y.toBitVec → x = y
|
|
| ⟨⟨_⟩⟩, ⟨⟨_⟩⟩, rfl => rfl
|
|
|
|
/-- Obtains the `Int16` that is 2's complement equivalent to the `UInt16`. -/
|
|
@[inline] def UInt16.toInt16 (i : UInt16) : Int16 := Int16.ofUInt16 i
|
|
@[inline, deprecated UInt16.toInt16 (since := "2025-02-13"), inherit_doc UInt16.toInt16]
|
|
def Int16.mk (i : UInt16) : Int16 := UInt16.toInt16 i
|
|
/--
|
|
Converts an arbitrary-precision integer to a 16-bit signed integer, wrapping on overflow or underflow.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `Int16.ofInt 48 = 48`
|
|
* `Int16.ofInt (-129) = -129`
|
|
* `Int16.ofInt (128) = 128`
|
|
* `Int16.ofInt 70000 = 4464`
|
|
* `Int16.ofInt (-40000) = 25536`
|
|
-/
|
|
@[extern "lean_int16_of_int"]
|
|
def Int16.ofInt (i : @& Int) : Int16 := ⟨⟨BitVec.ofInt 16 i⟩⟩
|
|
/--
|
|
Converts a natural number to a 16-bit signed integer, wrapping around on overflow.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `Int16.ofNat 127 = 127`
|
|
* `Int16.ofNat 32767 = 32767`
|
|
* `Int16.ofNat 32768 = -32768`
|
|
* `Int16.ofNat 32770 = -32766`
|
|
-/
|
|
@[extern "lean_int16_of_nat"]
|
|
def Int16.ofNat (n : @& Nat) : Int16 := ⟨⟨BitVec.ofNat 16 n⟩⟩
|
|
/--
|
|
Converts an arbitrary-precision integer to a 16-bit integer, wrapping on overflow or underflow.
|
|
|
|
Examples:
|
|
* `Int.toInt16 48 = 48`
|
|
* `Int.toInt16 (-129) = -129`
|
|
* `Int.toInt16 (128) = 128`
|
|
* `Int.toInt16 70000 = 4464`
|
|
* `Int.toInt16 (-40000) = 25536`
|
|
-/
|
|
abbrev Int.toInt16 := Int16.ofInt
|
|
/--
|
|
Converts a natural number to a 16-bit signed integer, wrapping around to negative numbers on
|
|
overflow.
|
|
|
|
Examples:
|
|
* `Nat.toInt16 127 = 127`
|
|
* `Nat.toInt16 32767 = 32767`
|
|
* `Nat.toInt16 32768 = -32768`
|
|
* `Nat.toInt16 32770 = -32766`
|
|
-/
|
|
abbrev Nat.toInt16 := Int16.ofNat
|
|
|
|
/--
|
|
Converts a 16-bit signed integer to an arbitrary-precision integer that denotes the same number.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int16_to_int"]
|
|
def Int16.toInt (i : Int16) : Int := i.toBitVec.toInt
|
|
/--
|
|
Converts a 16-bit signed integer to a natural number, mapping all negative numbers to `0`.
|
|
|
|
Use `Int16.toBitVec` to obtain the two's complement representation.
|
|
-/
|
|
@[inline] def Int16.toNatClampNeg (i : Int16) : Nat := i.toInt.toNat
|
|
@[inline, deprecated Int16.toNatClampNeg (since := "2025-02-13"), inherit_doc Int16.toNatClampNeg]
|
|
def Int16.toNat (i : Int16) : Nat := i.toInt.toNat
|
|
/-- Obtains the `Int16` whose 2's complement representation is the given `BitVec 16`. -/
|
|
@[inline] def Int16.ofBitVec (b : BitVec 16) : Int16 := ⟨⟨b⟩⟩
|
|
/--
|
|
Converts 16-bit signed integers to 8-bit signed integers by truncating their bitvector
|
|
representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int16_to_int8"]
|
|
def Int16.toInt8 (a : Int16) : Int8 := ⟨⟨a.toBitVec.signExtend 8⟩⟩
|
|
/--
|
|
Converts 8-bit signed integers to 16-bit signed integers that denote the same number.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int8_to_int16"]
|
|
def Int8.toInt16 (a : Int8) : Int16 := ⟨⟨a.toBitVec.signExtend 16⟩⟩
|
|
/--
|
|
Negates 16-bit signed integers. Usually accessed via the `-` prefix operator.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int16_neg"]
|
|
def Int16.neg (i : Int16) : Int16 := ⟨⟨-i.toBitVec⟩⟩
|
|
|
|
instance : ToString Int16 where
|
|
toString i := toString i.toInt
|
|
instance : Repr Int16 where
|
|
reprPrec i prec := reprPrec i.toInt prec
|
|
instance : ReprAtom Int16 := ⟨⟩
|
|
|
|
instance : Hashable Int16 where
|
|
hash i := i.toUInt16.toUInt64
|
|
|
|
instance Int16.instOfNat : OfNat Int16 n := ⟨Int16.ofNat n⟩
|
|
instance Int16.instNeg : Neg Int16 where
|
|
neg := Int16.neg
|
|
|
|
/-- The largest number that `Int16` can represent: `2^15 - 1 = 32767`. -/
|
|
abbrev Int16.maxValue : Int16 := 32767
|
|
/-- The smallest number that `Int16` can represent: `-2^15 = -32768`. -/
|
|
abbrev Int16.minValue : Int16 := -32768
|
|
/-- Constructs an `Int16` from an `Int` that is known to be in bounds. -/
|
|
@[inline]
|
|
def Int16.ofIntLE (i : Int) (_hl : Int16.minValue.toInt ≤ i) (_hr : i ≤ Int16.maxValue.toInt) : Int16 :=
|
|
Int16.ofInt i
|
|
/-- Constructs an `Int16` from an `Int`, clamping if the value is too small or too large. -/
|
|
def Int16.ofIntTruncate (i : Int) : Int16 :=
|
|
if hl : Int16.minValue.toInt ≤ i then
|
|
if hr : i ≤ Int16.maxValue.toInt then
|
|
Int16.ofIntLE i hl hr
|
|
else
|
|
Int16.minValue
|
|
else
|
|
Int16.minValue
|
|
|
|
/--
|
|
Adds two 16-bit signed integers, wrapping around on over- or underflow. Usually accessed via the `+`
|
|
operator.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int16_add"]
|
|
protected def Int16.add (a b : Int16) : Int16 := ⟨⟨a.toBitVec + b.toBitVec⟩⟩
|
|
/--
|
|
Subtracts one 16-bit signed integer from another, wrapping around on over- or underflow. Usually
|
|
accessed via the `-` operator.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int16_sub"]
|
|
protected def Int16.sub (a b : Int16) : Int16 := ⟨⟨a.toBitVec - b.toBitVec⟩⟩
|
|
/--
|
|
Multiplies two 16-bit signed integers, wrapping around on over- or underflow. Usually accessed via
|
|
the `*` operator.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int16_mul"]
|
|
protected def Int16.mul (a b : Int16) : Int16 := ⟨⟨a.toBitVec * b.toBitVec⟩⟩
|
|
/--
|
|
Truncating division for 16-bit signed integers, rounding towards zero. Usually accessed via the `/`
|
|
operator.
|
|
|
|
Division by zero is defined to be zero.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `Int16.div 10 3 = 3`
|
|
* `Int16.div 10 (-3) = (-3)`
|
|
* `Int16.div (-10) (-3) = 3`
|
|
* `Int16.div (-10) 3 = (-3)`
|
|
* `Int16.div 10 0 = 0`
|
|
-/
|
|
@[extern "lean_int16_div"]
|
|
protected def Int16.div (a b : Int16) : Int16 := ⟨⟨BitVec.sdiv a.toBitVec b.toBitVec⟩⟩
|
|
/--
|
|
The power operation, raising a 16-bit signed integer to a natural number power,
|
|
wrapping around on overflow. Usually accessed via the `^` operator.
|
|
|
|
This function is currently *not* overridden at runtime with an efficient implementation,
|
|
and should be used with caution. See https://github.com/leanprover/lean4/issues/7887.
|
|
-/
|
|
protected def Int16.pow (x : Int16) (n : Nat) : Int16 :=
|
|
match n with
|
|
| 0 => 1
|
|
| n + 1 => Int16.mul (Int16.pow x n) x
|
|
/--
|
|
The modulo operator for 16-bit signed integers, which computes the remainder when dividing one
|
|
integer by another with the T-rounding convention used by `Int16.div`. Usually accessed via the `%`
|
|
operator.
|
|
|
|
When the divisor is `0`, the result is the dividend rather than an error.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `Int16.mod 5 2 = 1`
|
|
* `Int16.mod 5 (-2) = 1`
|
|
* `Int16.mod (-5) 2 = (-1)`
|
|
* `Int16.mod (-5) (-2) = (-1)`
|
|
* `Int16.mod 4 2 = 0`
|
|
* `Int16.mod 4 (-2) = 0`
|
|
* `Int16.mod 4 0 = 4`
|
|
* `Int16.mod (-4) 0 = (-4)`
|
|
-/
|
|
@[extern "lean_int16_mod"]
|
|
protected def Int16.mod (a b : Int16) : Int16 := ⟨⟨BitVec.srem a.toBitVec b.toBitVec⟩⟩
|
|
/--
|
|
Bitwise and for 16-bit signed integers. Usually accessed via the `&&&` operator.
|
|
|
|
Each bit of the resulting integer is set if the corresponding bits of both input integers are set,
|
|
according to the two's complement representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int16_land"]
|
|
protected def Int16.land (a b : Int16) : Int16 := ⟨⟨a.toBitVec &&& b.toBitVec⟩⟩
|
|
/--
|
|
Bitwise or for 16-bit signed integers. Usually accessed via the `|||` operator.
|
|
|
|
Each bit of the resulting integer is set if at least one of the corresponding bits of the input
|
|
integers is set, according to the two's complement representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int16_lor"]
|
|
protected def Int16.lor (a b : Int16) : Int16 := ⟨⟨a.toBitVec ||| b.toBitVec⟩⟩
|
|
/--
|
|
Bitwise exclusive or for 16-bit signed integers. Usually accessed via the `^^^` operator.
|
|
|
|
Each bit of the resulting integer is set if exactly one of the corresponding bits of the input
|
|
integers is set, according to the two's complement representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int16_xor"]
|
|
protected def Int16.xor (a b : Int16) : Int16 := ⟨⟨a.toBitVec ^^^ b.toBitVec⟩⟩
|
|
/--
|
|
Bitwise left shift for 16-bit signed integers. Usually accessed via the `<<<` operator.
|
|
|
|
Signed integers are interpreted as bitvectors according to the two's complement representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int16_shift_left"]
|
|
protected def Int16.shiftLeft (a b : Int16) : Int16 := ⟨⟨a.toBitVec <<< (b.toBitVec.smod 16)⟩⟩
|
|
/--
|
|
Arithmetic right shift for 16-bit signed integers. Usually accessed via the `<<<` operator.
|
|
|
|
The high bits are filled with the value of the most significant bit.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int16_shift_right"]
|
|
protected def Int16.shiftRight (a b : Int16) : Int16 := ⟨⟨BitVec.sshiftRight' a.toBitVec (b.toBitVec.smod 16)⟩⟩
|
|
/--
|
|
Bitwise complement, also known as bitwise negation, for 16-bit signed integers. Usually accessed via
|
|
the `~~~` prefix operator.
|
|
|
|
Each bit of the resulting integer is the opposite of the corresponding bit of the input integer.
|
|
Integers use the two's complement representation, so `Int16.complement a = -(a + 1)`.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int16_complement"]
|
|
protected def Int16.complement (a : Int16) : Int16 := ⟨⟨~~~a.toBitVec⟩⟩
|
|
/--
|
|
Computes the absolute value of a 16-bit signed integer.
|
|
|
|
This function is equivalent to `if a < 0 then -a else a`, so in particular `Int16.minValue` will be
|
|
mapped to `Int16.minValue`.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int16_abs"]
|
|
protected def Int16.abs (a : Int16) : Int16 := ⟨⟨a.toBitVec.abs⟩⟩
|
|
|
|
/--
|
|
Decides whether two 16-bit signed integers are equal. Usually accessed via the `DecidableEq Int16`
|
|
instance.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `Int16.decEq 123 123 = .isTrue rfl`
|
|
* `(if ((-7) : Int16) = 7 then "yes" else "no") = "no"`
|
|
* `show (7 : Int16) = 7 by decide`
|
|
-/
|
|
@[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))
|
|
|
|
/--
|
|
Strict inequality of 16-bit signed integers, defined as inequality of the corresponding integers.
|
|
Usually accessed via the `<` operator.
|
|
-/
|
|
protected def Int16.lt (a b : Int16) : Prop := a.toBitVec.slt b.toBitVec
|
|
/--
|
|
Non-strict inequality of 16-bit signed integers, defined as inequality of the corresponding
|
|
integers. Usually accessed via the `≤` operator.
|
|
-/
|
|
protected 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 : Pow Int16 Nat := ⟨Int16.pow⟩
|
|
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
|
|
|
|
/--
|
|
Converts `true` to `1` and `false` to `0`.
|
|
-/
|
|
@[extern "lean_bool_to_int16"]
|
|
def Bool.toInt16 (b : Bool) : Int16 := if b then 1 else 0
|
|
|
|
/--
|
|
Decides whether one 16-bit signed integer is strictly less than another. Usually accessed via the
|
|
`DecidableLT Int16` instance.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `(if ((-7) : Int16) < 7 then "yes" else "no") = "yes"`
|
|
* `(if (5 : Int16) < 5 then "yes" else "no") = "no"`
|
|
* `show ¬((7 : Int16) < 7) by decide`
|
|
-/
|
|
@[extern "lean_int16_dec_lt"]
|
|
def Int16.decLt (a b : Int16) : Decidable (a < b) :=
|
|
inferInstanceAs (Decidable (a.toBitVec.slt b.toBitVec))
|
|
|
|
/--
|
|
Decides whether one 16-bit signed integer is less than or equal to another. Usually accessed via the
|
|
`DecidableLE Int16` instance.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `(if ((-7) : Int16) ≤ 7 then "yes" else "no") = "yes"`
|
|
* `(if (15 : Int16) ≤ 15 then "yes" else "no") = "yes"`
|
|
* `(if (15 : Int16) ≤ 5 then "yes" else "no") = "no"`
|
|
* `show (7 : Int16) ≤ 7 by decide`
|
|
-/
|
|
@[extern "lean_int16_dec_le"]
|
|
def Int16.decLe (a b : Int16) : Decidable (a ≤ b) :=
|
|
inferInstanceAs (Decidable (a.toBitVec.sle b.toBitVec))
|
|
|
|
attribute [instance] Int16.decLt Int16.decLe
|
|
|
|
instance : Max Int16 := maxOfLe
|
|
instance : Min Int16 := minOfLe
|
|
|
|
/-- The number of distinct values representable by `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
|
|
|
|
theorem Int32.toBitVec.inj : {x y : Int32} → x.toBitVec = y.toBitVec → x = y
|
|
| ⟨⟨_⟩⟩, ⟨⟨_⟩⟩, rfl => rfl
|
|
|
|
/-- Obtains the `Int32` that is 2's complement equivalent to the `UInt32`. -/
|
|
@[inline] def UInt32.toInt32 (i : UInt32) : Int32 := Int32.ofUInt32 i
|
|
@[inline, deprecated UInt32.toInt32 (since := "2025-02-13"), inherit_doc UInt32.toInt32]
|
|
def Int32.mk (i : UInt32) : Int32 := UInt32.toInt32 i
|
|
/--
|
|
Converts an arbitrary-precision integer to a 32-bit integer, wrapping on overflow or underflow.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `Int32.ofInt 48 = 48`
|
|
* `Int32.ofInt (-129) = -129`
|
|
* `Int32.ofInt 70000 = 70000`
|
|
* `Int32.ofInt (-40000) = -40000`
|
|
* `Int32.ofInt 2147483648 = -2147483648`
|
|
* `Int32.ofInt (-2147483649) = 2147483647`
|
|
-/
|
|
@[extern "lean_int32_of_int"]
|
|
def Int32.ofInt (i : @& Int) : Int32 := ⟨⟨BitVec.ofInt 32 i⟩⟩
|
|
/--
|
|
Converts a natural number to a 32-bit signed integer, wrapping around on overflow.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `Int32.ofNat 127 = 127`
|
|
* `Int32.ofNat 32770 = 32770`
|
|
* `Int32.ofNat 2_147_483_647 = 2_147_483_647`
|
|
* `Int32.ofNat 2_147_483_648 = -2_147_483_648`
|
|
-/
|
|
@[extern "lean_int32_of_nat"]
|
|
def Int32.ofNat (n : @& Nat) : Int32 := ⟨⟨BitVec.ofNat 32 n⟩⟩
|
|
/--
|
|
Converts an arbitrary-precision integer to a 32-bit integer, wrapping on overflow or underflow.
|
|
|
|
Examples:
|
|
* `Int.toInt32 48 = 48`
|
|
* `Int.toInt32 (-129) = -129`
|
|
* `Int.toInt32 70000 = 70000`
|
|
* `Int.toInt32 (-40000) = -40000`
|
|
* `Int.toInt32 2147483648 = -2147483648`
|
|
* `Int.toInt32 (-2147483649) = 2147483647`
|
|
-/
|
|
abbrev Int.toInt32 := Int32.ofInt
|
|
/--
|
|
Converts a natural number to a 32-bit signed integer, wrapping around to negative numbers on
|
|
overflow.
|
|
|
|
Examples:
|
|
* `Nat.toInt32 127 = 127`
|
|
* `Nat.toInt32 32770 = 32770`
|
|
* `Nat.toInt32 2_147_483_647 = 2_147_483_647`
|
|
* `Nat.toInt32 2_147_483_648 = -2_147_483_648`
|
|
-/
|
|
abbrev Nat.toInt32 := Int32.ofNat
|
|
/--
|
|
Converts a 32-bit signed integer to an arbitrary-precision integer that denotes the same number.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int32_to_int"]
|
|
def Int32.toInt (i : Int32) : Int := i.toBitVec.toInt
|
|
/--
|
|
Converts a 32-bit signed integer to a natural number, mapping all negative numbers to `0`.
|
|
|
|
Use `Int32.toBitVec` to obtain the two's complement representation.
|
|
-/
|
|
@[inline] def Int32.toNatClampNeg (i : Int32) : Nat := i.toInt.toNat
|
|
@[inline, deprecated Int32.toNatClampNeg (since := "2025-02-13"), inherit_doc Int32.toNatClampNeg]
|
|
def Int32.toNat (i : Int32) : Nat := i.toInt.toNat
|
|
/-- Obtains the `Int32` whose 2's complement representation is the given `BitVec 32`. -/
|
|
@[inline] def Int32.ofBitVec (b : BitVec 32) : Int32 := ⟨⟨b⟩⟩
|
|
/--
|
|
Converts a 32-bit signed integer to an 8-bit signed integer by truncating its bitvector
|
|
representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int32_to_int8"]
|
|
def Int32.toInt8 (a : Int32) : Int8 := ⟨⟨a.toBitVec.signExtend 8⟩⟩
|
|
/--
|
|
Converts a 32-bit signed integer to an 16-bit signed integer by truncating its bitvector
|
|
representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int32_to_int16"]
|
|
def Int32.toInt16 (a : Int32) : Int16 := ⟨⟨a.toBitVec.signExtend 16⟩⟩
|
|
/--
|
|
Converts 8-bit signed integers to 32-bit signed integers that denote the same number.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int8_to_int32"]
|
|
def Int8.toInt32 (a : Int8) : Int32 := ⟨⟨a.toBitVec.signExtend 32⟩⟩
|
|
/--
|
|
Converts 8-bit signed integers to 32-bit signed integers that denote the same number.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int16_to_int32"]
|
|
def Int16.toInt32 (a : Int16) : Int32 := ⟨⟨a.toBitVec.signExtend 32⟩⟩
|
|
/--
|
|
Negates 32-bit signed integers. Usually accessed via the `-` prefix operator.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int32_neg"]
|
|
def Int32.neg (i : Int32) : Int32 := ⟨⟨-i.toBitVec⟩⟩
|
|
|
|
instance : ToString Int32 where
|
|
toString i := toString i.toInt
|
|
instance : Repr Int32 where
|
|
reprPrec i prec := reprPrec i.toInt prec
|
|
instance : ReprAtom Int32 := ⟨⟩
|
|
|
|
instance : Hashable Int32 where
|
|
hash i := i.toUInt32.toUInt64
|
|
|
|
instance Int32.instOfNat : OfNat Int32 n := ⟨Int32.ofNat n⟩
|
|
instance Int32.instNeg : Neg Int32 where
|
|
neg := Int32.neg
|
|
|
|
/-- The largest number that `Int32` can represent: `2^31 - 1 = 2147483647`. -/
|
|
abbrev Int32.maxValue : Int32 := 2147483647
|
|
/-- The smallest number that `Int32` can represent: `-2^31 = -2147483648`. -/
|
|
abbrev Int32.minValue : Int32 := -2147483648
|
|
/-- Constructs an `Int32` from an `Int` that is known to be in bounds. -/
|
|
@[inline]
|
|
def Int32.ofIntLE (i : Int) (_hl : Int32.minValue.toInt ≤ i) (_hr : i ≤ Int32.maxValue.toInt) : Int32 :=
|
|
Int32.ofInt i
|
|
/-- Constructs an `Int32` from an `Int`, clamping if the value is too small or too large. -/
|
|
def Int32.ofIntTruncate (i : Int) : Int32 :=
|
|
if hl : Int32.minValue.toInt ≤ i then
|
|
if hr : i ≤ Int32.maxValue.toInt then
|
|
Int32.ofIntLE i hl hr
|
|
else
|
|
Int32.minValue
|
|
else
|
|
Int32.minValue
|
|
|
|
/--
|
|
Adds two 32-bit signed integers, wrapping around on over- or underflow. Usually accessed via the
|
|
`+` operator.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int32_add"]
|
|
protected def Int32.add (a b : Int32) : Int32 := ⟨⟨a.toBitVec + b.toBitVec⟩⟩
|
|
/--
|
|
Subtracts one 32-bit signed integer from another, wrapping around on over- or underflow. Usually
|
|
accessed via the `-` operator.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int32_sub"]
|
|
protected def Int32.sub (a b : Int32) : Int32 := ⟨⟨a.toBitVec - b.toBitVec⟩⟩
|
|
/--
|
|
Multiplies two 32-bit signed integers, wrapping around on over- or underflow. Usually accessed via
|
|
the `*` operator.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int32_mul"]
|
|
protected def Int32.mul (a b : Int32) : Int32 := ⟨⟨a.toBitVec * b.toBitVec⟩⟩
|
|
/--
|
|
Truncating division for 32-bit signed integers, rounding towards zero. Usually accessed via the `/`
|
|
operator.
|
|
|
|
Division by zero is defined to be zero.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `Int32.div 10 3 = 3`
|
|
* `Int32.div 10 (-3) = (-3)`
|
|
* `Int32.div (-10) (-3) = 3`
|
|
* `Int32.div (-10) 3 = (-3)`
|
|
* `Int32.div 10 0 = 0`
|
|
-/
|
|
@[extern "lean_int32_div"]
|
|
protected def Int32.div (a b : Int32) : Int32 := ⟨⟨BitVec.sdiv a.toBitVec b.toBitVec⟩⟩
|
|
/--
|
|
The power operation, raising a 32-bit signed integer to a natural number power,
|
|
wrapping around on overflow. Usually accessed via the `^` operator.
|
|
|
|
This function is currently *not* overridden at runtime with an efficient implementation,
|
|
and should be used with caution. See https://github.com/leanprover/lean4/issues/7887.
|
|
-/
|
|
protected def Int32.pow (x : Int32) (n : Nat) : Int32 :=
|
|
match n with
|
|
| 0 => 1
|
|
| n + 1 => Int32.mul (Int32.pow x n) x
|
|
/--
|
|
The modulo operator for 32-bit signed integers, which computes the remainder when dividing one
|
|
integer by another with the T-rounding convention used by `Int32.div`. Usually accessed via the `%`
|
|
operator.
|
|
|
|
When the divisor is `0`, the result is the dividend rather than an error.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `Int32.mod 5 2 = 1`
|
|
* `Int32.mod 5 (-2) = 1`
|
|
* `Int32.mod (-5) 2 = (-1)`
|
|
* `Int32.mod (-5) (-2) = (-1)`
|
|
* `Int32.mod 4 2 = 0`
|
|
* `Int32.mod 4 (-2) = 0`
|
|
* `Int32.mod 4 0 = 4`
|
|
* `Int32.mod (-4) 0 = (-4)`
|
|
-/
|
|
@[extern "lean_int32_mod"]
|
|
protected def Int32.mod (a b : Int32) : Int32 := ⟨⟨BitVec.srem a.toBitVec b.toBitVec⟩⟩
|
|
/--
|
|
Bitwise and for 32-bit signed integers. Usually accessed via the `&&&` operator.
|
|
|
|
Each bit of the resulting integer is set if the corresponding bits of both input integers are set,
|
|
according to the two's complement representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int32_land"]
|
|
protected def Int32.land (a b : Int32) : Int32 := ⟨⟨a.toBitVec &&& b.toBitVec⟩⟩
|
|
/--
|
|
Bitwise or for 32-bit signed integers. Usually accessed via the `|||` operator.
|
|
|
|
Each bit of the resulting integer is set if at least one of the corresponding bits of the input
|
|
integers is set, according to the two's complement representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int32_lor"]
|
|
protected def Int32.lor (a b : Int32) : Int32 := ⟨⟨a.toBitVec ||| b.toBitVec⟩⟩
|
|
/--
|
|
Bitwise exclusive or for 32-bit signed integers. Usually accessed via the `^^^` operator.
|
|
|
|
Each bit of the resulting integer is set if exactly one of the corresponding bits of the input
|
|
integers is set, according to the two's complement representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int32_xor"]
|
|
protected def Int32.xor (a b : Int32) : Int32 := ⟨⟨a.toBitVec ^^^ b.toBitVec⟩⟩
|
|
/--
|
|
Bitwise left shift for 32-bit signed integers. Usually accessed via the `<<<` operator.
|
|
|
|
Signed integers are interpreted as bitvectors according to the two's complement representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int32_shift_left"]
|
|
protected def Int32.shiftLeft (a b : Int32) : Int32 := ⟨⟨a.toBitVec <<< (b.toBitVec.smod 32)⟩⟩
|
|
/--
|
|
Arithmetic right shift for 32-bit signed integers. Usually accessed via the `<<<` operator.
|
|
|
|
The high bits are filled with the value of the most significant bit.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int32_shift_right"]
|
|
protected def Int32.shiftRight (a b : Int32) : Int32 := ⟨⟨BitVec.sshiftRight' a.toBitVec (b.toBitVec.smod 32)⟩⟩
|
|
/--
|
|
Bitwise complement, also known as bitwise negation, for 32-bit signed integers. Usually accessed via
|
|
the `~~~` prefix operator.
|
|
|
|
Each bit of the resulting integer is the opposite of the corresponding bit of the input integer.
|
|
Integers use the two's complement representation, so `Int32.complement a = -(a + 1)`.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int32_complement"]
|
|
protected def Int32.complement (a : Int32) : Int32 := ⟨⟨~~~a.toBitVec⟩⟩
|
|
/--
|
|
Computes the absolute value of a 32-bit signed integer.
|
|
|
|
This function is equivalent to `if a < 0 then -a else a`, so in particular `Int32.minValue` will be
|
|
mapped to `Int32.minValue`.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int32_abs"]
|
|
protected def Int32.abs (a : Int32) : Int32 := ⟨⟨a.toBitVec.abs⟩⟩
|
|
|
|
/--
|
|
Decides whether two 32-bit signed integers are equal. Usually accessed via the `DecidableEq Int32`
|
|
instance.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `Int32.decEq 123 123 = .isTrue rfl`
|
|
* `(if ((-7) : Int32) = 7 then "yes" else "no") = "no"`
|
|
* `show (7 : Int32) = 7 by decide`
|
|
-/
|
|
@[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))
|
|
|
|
/--
|
|
Strict inequality of 32-bit signed integers, defined as inequality of the corresponding integers.
|
|
Usually accessed via the `<` operator.
|
|
-/
|
|
protected def Int32.lt (a b : Int32) : Prop := a.toBitVec.slt b.toBitVec
|
|
/--
|
|
Non-strict inequality of 32-bit signed integers, defined as inequality of the corresponding integers.
|
|
Usually accessed via the `≤` operator.
|
|
-/
|
|
protected 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 : Pow Int32 Nat := ⟨Int32.pow⟩
|
|
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
|
|
|
|
/--
|
|
Converts `true` to `1` and `false` to `0`.
|
|
-/
|
|
@[extern "lean_bool_to_int32"]
|
|
def Bool.toInt32 (b : Bool) : Int32 := if b then 1 else 0
|
|
|
|
/--
|
|
Decides whether one 32-bit signed integer is strictly less than another. Usually accessed via the
|
|
`DecidableLT Int32` instance.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `(if ((-7) : Int32) < 7 then "yes" else "no") = "yes"`
|
|
* `(if (5 : Int32) < 5 then "yes" else "no") = "no"`
|
|
* `show ¬((7 : Int32) < 7) by decide`
|
|
-/
|
|
@[extern "lean_int32_dec_lt"]
|
|
def Int32.decLt (a b : Int32) : Decidable (a < b) :=
|
|
inferInstanceAs (Decidable (a.toBitVec.slt b.toBitVec))
|
|
|
|
/--
|
|
Decides whether one 32-bit signed integer is less than or equal to another. Usually accessed via the
|
|
`DecidableLE Int32` instance.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `(if ((-7) : Int32) ≤ 7 then "yes" else "no") = "yes"`
|
|
* `(if (15 : Int32) ≤ 15 then "yes" else "no") = "yes"`
|
|
* `(if (15 : Int32) ≤ 5 then "yes" else "no") = "no"`
|
|
* `show (7 : Int32) ≤ 7 by decide`
|
|
-/
|
|
@[extern "lean_int32_dec_le"]
|
|
def Int32.decLe (a b : Int32) : Decidable (a ≤ b) :=
|
|
inferInstanceAs (Decidable (a.toBitVec.sle b.toBitVec))
|
|
|
|
attribute [instance] Int32.decLt Int32.decLe
|
|
|
|
instance : Max Int32 := maxOfLe
|
|
instance : Min Int32 := minOfLe
|
|
|
|
/-- The number of distinct values representable by `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
|
|
|
|
theorem Int64.toBitVec.inj : {x y : Int64} → x.toBitVec = y.toBitVec → x = y
|
|
| ⟨⟨_⟩⟩, ⟨⟨_⟩⟩, rfl => rfl
|
|
|
|
/-- Obtains the `Int64` that is 2's complement equivalent to the `UInt64`. -/
|
|
@[inline] def UInt64.toInt64 (i : UInt64) : Int64 := Int64.ofUInt64 i
|
|
@[inline, deprecated UInt64.toInt64 (since := "2025-02-13"), inherit_doc UInt64.toInt64]
|
|
def Int64.mk (i : UInt64) : Int64 := UInt64.toInt64 i
|
|
/--
|
|
Converts an arbitrary-precision integer to a 64-bit integer, wrapping on overflow or underflow.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `Int64.ofInt 48 = 48`
|
|
* `Int64.ofInt (-40_000) = -40_000`
|
|
* `Int64.ofInt 2_147_483_648 = 2_147_483_648`
|
|
* `Int64.ofInt (-2_147_483_649) = -2_147_483_649`
|
|
* `Int64.ofInt 9_223_372_036_854_775_808 = -9_223_372_036_854_775_808`
|
|
* `Int64.ofInt (-9_223_372_036_854_775_809) = 9_223_372_036_854_775_807`
|
|
-/
|
|
@[extern "lean_int64_of_int"]
|
|
def Int64.ofInt (i : @& Int) : Int64 := ⟨⟨BitVec.ofInt 64 i⟩⟩
|
|
/--
|
|
Converts a natural number to a 64-bit signed integer, wrapping around to negative numbers on
|
|
overflow.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `Int64.ofNat 127 = 127`
|
|
* `Int64.ofNat 2_147_483_648 = 2_147_483_648`
|
|
* `Int64.ofNat 9_223_372_036_854_775_807 = 9_223_372_036_854_775_807`
|
|
* `Int64.ofNat 9_223_372_036_854_775_808 = -9_223_372_036_854_775_808`
|
|
* `Int64.ofNat 18_446_744_073_709_551_618 = 0`
|
|
-/
|
|
@[extern "lean_int64_of_nat"]
|
|
def Int64.ofNat (n : @& Nat) : Int64 := ⟨⟨BitVec.ofNat 64 n⟩⟩
|
|
/--
|
|
Converts an arbitrary-precision integer to a 64-bit integer, wrapping on overflow or underflow.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `Int.toInt64 48 = 48`
|
|
* `Int.toInt64 (-40_000) = -40_000`
|
|
* `Int.toInt64 2_147_483_648 = 2_147_483_648`
|
|
* `Int.toInt64 (-2_147_483_649) = -2_147_483_649`
|
|
* `Int.toInt64 9_223_372_036_854_775_808 = -9_223_372_036_854_775_808`
|
|
* `Int.toInt64 (-9_223_372_036_854_775_809) = 9_223_372_036_854_775_807`
|
|
-/
|
|
abbrev Int.toInt64 := Int64.ofInt
|
|
/--
|
|
Converts a natural number to a 64-bit signed integer, wrapping around to negative numbers on
|
|
overflow.
|
|
|
|
Examples:
|
|
* `Nat.toInt64 127 = 127`
|
|
* `Nat.toInt64 2_147_483_648 = 2_147_483_648`
|
|
* `Nat.toInt64 9_223_372_036_854_775_807 = 9_223_372_036_854_775_807`
|
|
* `Nat.toInt64 9_223_372_036_854_775_808 = -9_223_372_036_854_775_808`
|
|
* `Nat.toInt64 18_446_744_073_709_551_618 = 0`
|
|
-/
|
|
abbrev Nat.toInt64 := Int64.ofNat
|
|
/--
|
|
Converts a 64-bit signed integer to an arbitrary-precision integer that denotes the same number.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int64_to_int_sint"]
|
|
def Int64.toInt (i : Int64) : Int := i.toBitVec.toInt
|
|
/--
|
|
Converts a 64-bit signed integer to a natural number, mapping all negative numbers to `0`.
|
|
|
|
Use `Int64.toBitVec` to obtain the two's complement representation.
|
|
-/
|
|
@[inline] def Int64.toNatClampNeg (i : Int64) : Nat := i.toInt.toNat
|
|
@[inline, deprecated Int64.toNatClampNeg (since := "2025-02-13"), inherit_doc Int64.toNatClampNeg]
|
|
def Int64.toNat (i : Int64) : Nat := i.toInt.toNat
|
|
/-- Obtains the `Int64` whose 2's complement representation is the given `BitVec 64`. -/
|
|
@[inline] def Int64.ofBitVec (b : BitVec 64) : Int64 := ⟨⟨b⟩⟩
|
|
/--
|
|
Converts a 64-bit signed integer to an 8-bit signed integer by truncating its bitvector
|
|
representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int64_to_int8"]
|
|
def Int64.toInt8 (a : Int64) : Int8 := ⟨⟨a.toBitVec.signExtend 8⟩⟩
|
|
/--
|
|
Converts a 64-bit signed integer to a 16-bit signed integer by truncating its bitvector
|
|
representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int64_to_int16"]
|
|
def Int64.toInt16 (a : Int64) : Int16 := ⟨⟨a.toBitVec.signExtend 16⟩⟩
|
|
/--
|
|
Converts a 64-bit signed integer to a 32-bit signed integer by truncating its bitvector
|
|
representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int64_to_int32"]
|
|
def Int64.toInt32 (a : Int64) : Int32 := ⟨⟨a.toBitVec.signExtend 32⟩⟩
|
|
/--
|
|
Converts 8-bit signed integers to 64-bit signed integers that denote the same number.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int8_to_int64"]
|
|
def Int8.toInt64 (a : Int8) : Int64 := ⟨⟨a.toBitVec.signExtend 64⟩⟩
|
|
/--
|
|
Converts 16-bit signed integers to 64-bit signed integers that denote the same number.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int16_to_int64"]
|
|
def Int16.toInt64 (a : Int16) : Int64 := ⟨⟨a.toBitVec.signExtend 64⟩⟩
|
|
/--
|
|
Converts 32-bit signed integers to 64-bit signed integers that denote the same number.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int32_to_int64"]
|
|
def Int32.toInt64 (a : Int32) : Int64 := ⟨⟨a.toBitVec.signExtend 64⟩⟩
|
|
/--
|
|
Negates 64-bit signed integers. Usually accessed via the `-` prefix operator.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int64_neg"]
|
|
def Int64.neg (i : Int64) : Int64 := ⟨⟨-i.toBitVec⟩⟩
|
|
|
|
instance : ToString Int64 where
|
|
toString i := toString i.toInt
|
|
instance : Repr Int64 where
|
|
reprPrec i prec := reprPrec i.toInt prec
|
|
instance : ReprAtom Int64 := ⟨⟩
|
|
|
|
instance : Hashable Int64 where
|
|
hash i := i.toUInt64
|
|
|
|
instance Int64.instOfNat : OfNat Int64 n := ⟨Int64.ofNat n⟩
|
|
instance Int64.instNeg : Neg Int64 where
|
|
neg := Int64.neg
|
|
|
|
/-- The largest number that `Int64` can represent: `2^63 - 1 = 9223372036854775807`. -/
|
|
abbrev Int64.maxValue : Int64 := 9223372036854775807
|
|
/-- The smallest number that `Int64` can represent: `-2^63 = -9223372036854775808`. -/
|
|
abbrev Int64.minValue : Int64 := -9223372036854775808
|
|
/-- Constructs an `Int64` from an `Int` that is known to be in bounds. -/
|
|
@[inline]
|
|
def Int64.ofIntLE (i : Int) (_hl : Int64.minValue.toInt ≤ i) (_hr : i ≤ Int64.maxValue.toInt) : Int64 :=
|
|
Int64.ofInt i
|
|
/-- Constructs an `Int64` from an `Int`, clamping if the value is too small or too large. -/
|
|
def Int64.ofIntTruncate (i : Int) : Int64 :=
|
|
if hl : Int64.minValue.toInt ≤ i then
|
|
if hr : i ≤ Int64.maxValue.toInt then
|
|
Int64.ofIntLE i hl hr
|
|
else
|
|
Int64.minValue
|
|
else
|
|
Int64.minValue
|
|
|
|
/--
|
|
Adds two 64-bit signed integers, wrapping around on over- or underflow. Usually accessed via the
|
|
`+` operator.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int64_add"]
|
|
protected def Int64.add (a b : Int64) : Int64 := ⟨⟨a.toBitVec + b.toBitVec⟩⟩
|
|
/--
|
|
Subtracts one 64-bit signed integer from another, wrapping around on over- or underflow. Usually
|
|
accessed via the `-` operator.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int64_sub"]
|
|
protected def Int64.sub (a b : Int64) : Int64 := ⟨⟨a.toBitVec - b.toBitVec⟩⟩
|
|
/--
|
|
Multiplies two 64-bit signed integers, wrapping around on over- or underflow. Usually accessed via
|
|
the `*` operator.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int64_mul"]
|
|
protected def Int64.mul (a b : Int64) : Int64 := ⟨⟨a.toBitVec * b.toBitVec⟩⟩
|
|
/--
|
|
Truncating division for 64-bit signed integers, rounding towards zero. Usually accessed via the `/`
|
|
operator.
|
|
|
|
Division by zero is defined to be zero.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `Int64.div 10 3 = 3`
|
|
* `Int64.div 10 (-3) = (-3)`
|
|
* `Int64.div (-10) (-3) = 3`
|
|
* `Int64.div (-10) 3 = (-3)`
|
|
* `Int64.div 10 0 = 0`
|
|
-/
|
|
@[extern "lean_int64_div"]
|
|
protected def Int64.div (a b : Int64) : Int64 := ⟨⟨BitVec.sdiv a.toBitVec b.toBitVec⟩⟩
|
|
/--
|
|
The power operation, raising a 64-bit signed integer to a natural number power,
|
|
wrapping around on overflow. Usually accessed via the `^` operator.
|
|
|
|
This function is currently *not* overridden at runtime with an efficient implementation,
|
|
and should be used with caution. See https://github.com/leanprover/lean4/issues/7887.
|
|
-/
|
|
protected def Int64.pow (x : Int64) (n : Nat) : Int64 :=
|
|
match n with
|
|
| 0 => 1
|
|
| n + 1 => Int64.mul (Int64.pow x n) x
|
|
/--
|
|
The modulo operator for 64-bit signed integers, which computes the remainder when dividing one
|
|
integer by another with the T-rounding convention used by `Int64.div`. Usually accessed via the `%`
|
|
operator.
|
|
|
|
When the divisor is `0`, the result is the dividend rather than an error.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `Int64.mod 5 2 = 1`
|
|
* `Int64.mod 5 (-2) = 1`
|
|
* `Int64.mod (-5) 2 = (-1)`
|
|
* `Int64.mod (-5) (-2) = (-1)`
|
|
* `Int64.mod 4 2 = 0`
|
|
* `Int64.mod 4 (-2) = 0`
|
|
* `Int64.mod 4 0 = 4`
|
|
* `Int64.mod (-4) 0 = (-4)`
|
|
-/
|
|
@[extern "lean_int64_mod"]
|
|
protected def Int64.mod (a b : Int64) : Int64 := ⟨⟨BitVec.srem a.toBitVec b.toBitVec⟩⟩
|
|
/--
|
|
Bitwise and for 64-bit signed integers. Usually accessed via the `&&&` operator.
|
|
|
|
Each bit of the resulting integer is set if the corresponding bits of both input integers are set,
|
|
according to the two's complement representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int64_land"]
|
|
protected def Int64.land (a b : Int64) : Int64 := ⟨⟨a.toBitVec &&& b.toBitVec⟩⟩
|
|
/--
|
|
Bitwise or for 64-bit signed integers. Usually accessed via the `|||` operator.
|
|
|
|
Each bit of the resulting integer is set if at least one of the corresponding bits of the input
|
|
integers is set, according to the two's complement representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int64_lor"]
|
|
protected def Int64.lor (a b : Int64) : Int64 := ⟨⟨a.toBitVec ||| b.toBitVec⟩⟩
|
|
/--
|
|
Bitwise exclusive or for 64-bit signed integers. Usually accessed via the `^^^` operator.
|
|
|
|
Each bit of the resulting integer is set if exactly one of the corresponding bits of the input
|
|
integers is set, according to the two's complement representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int64_xor"]
|
|
protected def Int64.xor (a b : Int64) : Int64 := ⟨⟨a.toBitVec ^^^ b.toBitVec⟩⟩
|
|
/--
|
|
Bitwise left shift for 64-bit signed integers. Usually accessed via the `<<<` operator.
|
|
|
|
Signed integers are interpreted as bitvectors according to the two's complement representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int64_shift_left"]
|
|
protected def Int64.shiftLeft (a b : Int64) : Int64 := ⟨⟨a.toBitVec <<< (b.toBitVec.smod 64)⟩⟩
|
|
/--
|
|
Arithmetic right shift for 64-bit signed integers. Usually accessed via the `<<<` operator.
|
|
|
|
The high bits are filled with the value of the most significant bit.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int64_shift_right"]
|
|
protected def Int64.shiftRight (a b : Int64) : Int64 := ⟨⟨BitVec.sshiftRight' a.toBitVec (b.toBitVec.smod 64)⟩⟩
|
|
/--
|
|
Bitwise complement, also known as bitwise negation, for 64-bit signed integers. Usually accessed via
|
|
the `~~~` prefix operator.
|
|
|
|
Each bit of the resulting integer is the opposite of the corresponding bit of the input integer.
|
|
Integers use the two's complement representation, so `Int64.complement a = -(a + 1)`.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int64_complement"]
|
|
protected def Int64.complement (a : Int64) : Int64 := ⟨⟨~~~a.toBitVec⟩⟩
|
|
/--
|
|
Computes the absolute value of a 64-bit signed integer.
|
|
|
|
This function is equivalent to `if a < 0 then -a else a`, so in particular `Int64.minValue` will be
|
|
mapped to `Int64.minValue`.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int64_abs"]
|
|
protected def Int64.abs (a : Int64) : Int64 := ⟨⟨a.toBitVec.abs⟩⟩
|
|
|
|
/--
|
|
Decides whether two 64-bit signed integers are equal. Usually accessed via the `DecidableEq Int64`
|
|
instance.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `Int64.decEq 123 123 = .isTrue rfl`
|
|
* `(if ((-7) : Int64) = 7 then "yes" else "no") = "no"`
|
|
* `show (7 : Int64) = 7 by decide`
|
|
-/
|
|
@[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))
|
|
|
|
/--
|
|
Strict inequality of 64-bit signed integers, defined as inequality of the corresponding integers.
|
|
Usually accessed via the `<` operator.
|
|
-/
|
|
protected def Int64.lt (a b : Int64) : Prop := a.toBitVec.slt b.toBitVec
|
|
/--
|
|
Non-strict inequality of 64-bit signed integers, defined as inequality of the corresponding integers.
|
|
Usually accessed via the `≤` operator.
|
|
-/
|
|
protected 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 : Pow Int64 Nat := ⟨Int64.pow⟩
|
|
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
|
|
|
|
/--
|
|
Converts `true` to `1` and `false` to `0`.
|
|
-/
|
|
@[extern "lean_bool_to_int64"]
|
|
def Bool.toInt64 (b : Bool) : Int64 := if b then 1 else 0
|
|
|
|
/--
|
|
Decides whether one 8-bit signed integer is strictly less than another. Usually accessed via the
|
|
`DecidableLT Int64` instance.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `(if ((-7) : Int64) < 7 then "yes" else "no") = "yes"`
|
|
* `(if (5 : Int64) < 5 then "yes" else "no") = "no"`
|
|
* `show ¬((7 : Int64) < 7) by decide`
|
|
-/
|
|
@[extern "lean_int64_dec_lt"]
|
|
def Int64.decLt (a b : Int64) : Decidable (a < b) :=
|
|
inferInstanceAs (Decidable (a.toBitVec.slt b.toBitVec))
|
|
/--
|
|
Decides whether one 8-bit signed integer is less than or equal to another. Usually accessed via the
|
|
`DecidableLE Int64` instance.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `(if ((-7) : Int64) ≤ 7 then "yes" else "no") = "yes"`
|
|
* `(if (15 : Int64) ≤ 15 then "yes" else "no") = "yes"`
|
|
* `(if (15 : Int64) ≤ 5 then "yes" else "no") = "no"`
|
|
* `show (7 : Int64) ≤ 7 by decide`
|
|
-/
|
|
@[extern "lean_int64_dec_le"]
|
|
def Int64.decLe (a b : Int64) : Decidable (a ≤ b) :=
|
|
inferInstanceAs (Decidable (a.toBitVec.sle b.toBitVec))
|
|
|
|
attribute [instance] Int64.decLt Int64.decLe
|
|
|
|
instance : Max Int64 := maxOfLe
|
|
instance : Min Int64 := minOfLe
|
|
|
|
/-- The number of distinct values representable by `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
|
|
|
|
theorem ISize.toBitVec.inj : {x y : ISize} → x.toBitVec = y.toBitVec → x = y
|
|
| ⟨⟨_⟩⟩, ⟨⟨_⟩⟩, rfl => rfl
|
|
|
|
/-- Obtains the `ISize` that is 2's complement equivalent to the `USize`. -/
|
|
@[inline] def USize.toISize (i : USize) : ISize := ISize.ofUSize i
|
|
@[inline, deprecated USize.toISize (since := "2025-02-13"), inherit_doc USize.toISize]
|
|
def ISize.mk (i : USize) : ISize := USize.toISize i
|
|
/--
|
|
Converts an arbitrary-precision integer to a word-sized signed integer, wrapping around on over- or
|
|
underflow.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_isize_of_int"]
|
|
def ISize.ofInt (i : @& Int) : ISize := ⟨⟨BitVec.ofInt System.Platform.numBits i⟩⟩
|
|
/--
|
|
Converts an arbitrary-precision natural number to a word-sized signed integer, wrapping around on
|
|
overflow.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_isize_of_nat"]
|
|
def ISize.ofNat (n : @& Nat) : ISize := ⟨⟨BitVec.ofNat System.Platform.numBits n⟩⟩
|
|
@[inherit_doc ISize.ofInt]
|
|
abbrev Int.toISize := ISize.ofInt
|
|
@[inherit_doc ISize.ofNat] abbrev Nat.toISize := ISize.ofNat
|
|
/--
|
|
Converts a word-sized signed integer to an arbitrary-precision integer that denotes the same number.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_isize_to_int"]
|
|
def ISize.toInt (i : ISize) : Int := i.toBitVec.toInt
|
|
/--
|
|
Converts a word-sized signed integer to a natural number, mapping all negative numbers to `0`.
|
|
|
|
Use `ISize.toBitVec` to obtain the two's complement representation.
|
|
-/
|
|
@[inline] def ISize.toNatClampNeg (i : ISize) : Nat := i.toInt.toNat
|
|
@[inline, deprecated ISize.toNatClampNeg (since := "2025-02-13"), inherit_doc ISize.toNatClampNeg]
|
|
def ISize.toNat (i : ISize) : Nat := i.toInt.toNat
|
|
/-- Obtains the `ISize` whose 2's complement representation is the given `BitVec`. -/
|
|
@[inline] def ISize.ofBitVec (b : BitVec System.Platform.numBits) : ISize := ⟨⟨b⟩⟩
|
|
/--
|
|
Converts a word-sized signed integer to an 8-bit signed integer by truncating its bitvector representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_isize_to_int8"]
|
|
def ISize.toInt8 (a : ISize) : Int8 := ⟨⟨a.toBitVec.signExtend 8⟩⟩
|
|
/--
|
|
Converts a word-sized integer to a 16-bit integer by truncating its bitvector representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_isize_to_int16"]
|
|
def ISize.toInt16 (a : ISize) : Int16 := ⟨⟨a.toBitVec.signExtend 16⟩⟩
|
|
/--
|
|
Converts a word-sized signed integer to a 32-bit signed integer.
|
|
|
|
On 32-bit platforms, this conversion is lossless. On 64-bit platforms, the integer's bitvector
|
|
representation is truncated to 32 bits. This function is overridden at runtime with an efficient
|
|
implementation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_isize_to_int32"]
|
|
def ISize.toInt32 (a : ISize) : Int32 := ⟨⟨a.toBitVec.signExtend 32⟩⟩
|
|
/--
|
|
Converts word-sized signed integers to 64-bit signed integers that denote the same number. This
|
|
conversion is lossless, because `ISize` is either `Int32` or `Int64`.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_isize_to_int64"]
|
|
def ISize.toInt64 (a : ISize) : Int64 := ⟨⟨a.toBitVec.signExtend 64⟩⟩
|
|
/--
|
|
Converts 8-bit signed integers to word-sized signed integers that denote the same number. This
|
|
conversion is lossless, because `ISize` is either `Int32` or `Int64`.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int8_to_isize"]
|
|
def Int8.toISize (a : Int8) : ISize := ⟨⟨a.toBitVec.signExtend System.Platform.numBits⟩⟩
|
|
/--
|
|
Converts 16-bit signed integers to word-sized signed integers that denote the same number. This conversion is lossless, because
|
|
`ISize` is either `Int32` or `Int64`.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int16_to_isize"]
|
|
def Int16.toISize (a : Int16) : ISize := ⟨⟨a.toBitVec.signExtend System.Platform.numBits⟩⟩
|
|
/--
|
|
Converts 32-bit signed integers to word-sized signed integers that denote the same number. This
|
|
conversion is lossless, because `ISize` is either `Int32` or `Int64`.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int32_to_isize"]
|
|
def Int32.toISize (a : Int32) : ISize := ⟨⟨a.toBitVec.signExtend System.Platform.numBits⟩⟩
|
|
/--
|
|
Converts 64-bit signed integers to word-sized signed integers, truncating the bitvector
|
|
representation on 32-bit platforms. This conversion is lossless on 64-bit platforms.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_int64_to_isize"]
|
|
def Int64.toISize (a : Int64) : ISize := ⟨⟨a.toBitVec.signExtend System.Platform.numBits⟩⟩
|
|
/--
|
|
Negates word-sized signed integers. Usually accessed via the `-` prefix operator.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_isize_neg"]
|
|
protected def ISize.neg (i : ISize) : ISize := ⟨⟨-i.toBitVec⟩⟩
|
|
|
|
instance : ToString ISize where
|
|
toString i := toString i.toInt
|
|
instance : Repr ISize where
|
|
reprPrec i prec := reprPrec i.toInt prec
|
|
instance : ReprAtom ISize := ⟨⟩
|
|
|
|
instance : Hashable ISize where
|
|
hash i := i.toUSize.toUInt64
|
|
|
|
instance ISize.instOfNat : OfNat ISize n := ⟨ISize.ofNat n⟩
|
|
instance ISize.instNeg : Neg ISize where
|
|
neg := ISize.neg
|
|
|
|
/-- The largest number that `ISize` can represent: `2^(System.Platform.numBits - 1) - 1`. -/
|
|
abbrev ISize.maxValue : ISize := .ofInt (2 ^ (System.Platform.numBits - 1) - 1)
|
|
/-- The smallest number that `ISize` can represent: `-2^(System.Platform.numBits - 1)`. -/
|
|
abbrev ISize.minValue : ISize := .ofInt (-2 ^ (System.Platform.numBits - 1))
|
|
|
|
/-- Constructs an `ISize` from an `Int` that is known to be in bounds. -/
|
|
@[inline]
|
|
def ISize.ofIntLE (i : Int) (_hl : ISize.minValue.toInt ≤ i) (_hr : i ≤ ISize.maxValue.toInt) : ISize :=
|
|
ISize.ofInt i
|
|
/-- Constructs an `ISize` from an `Int`, clamping if the value is too small or too large. -/
|
|
def ISize.ofIntTruncate (i : Int) : ISize :=
|
|
if hl : ISize.minValue.toInt ≤ i then
|
|
if hr : i ≤ ISize.maxValue.toInt then
|
|
ISize.ofIntLE i hl hr
|
|
else
|
|
ISize.minValue
|
|
else
|
|
ISize.minValue
|
|
|
|
/--
|
|
Adds two word-sized signed integers, wrapping around on over- or underflow. Usually accessed via
|
|
the `+` operator.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_isize_add"]
|
|
protected def ISize.add (a b : ISize) : ISize := ⟨⟨a.toBitVec + b.toBitVec⟩⟩
|
|
/--
|
|
Subtracts one word-sized signed integer from another, wrapping around on over- or underflow. Usually
|
|
accessed via the `-` operator.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_isize_sub"]
|
|
protected def ISize.sub (a b : ISize) : ISize := ⟨⟨a.toBitVec - b.toBitVec⟩⟩
|
|
/--
|
|
Multiplies two word-sized signed integers, wrapping around on over- or underflow. Usually accessed
|
|
via the `*` operator.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_isize_mul"]
|
|
protected def ISize.mul (a b : ISize) : ISize := ⟨⟨a.toBitVec * b.toBitVec⟩⟩
|
|
/--
|
|
Truncating division for word-sized signed integers, rounding towards zero. Usually accessed via the
|
|
`/` operator.
|
|
|
|
Division by zero is defined to be zero.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `ISize.div 10 3 = 3`
|
|
* `ISize.div 10 (-3) = (-3)`
|
|
* `ISize.div (-10) (-3) = 3`
|
|
* `ISize.div (-10) 3 = (-3)`
|
|
* `ISize.div 10 0 = 0`
|
|
-/
|
|
@[extern "lean_isize_div"]
|
|
protected def ISize.div (a b : ISize) : ISize := ⟨⟨BitVec.sdiv a.toBitVec b.toBitVec⟩⟩
|
|
/--
|
|
The power operation, raising a word-sized signed integer to a natural number power,
|
|
wrapping around on overflow. Usually accessed via the `^` operator.
|
|
|
|
This function is currently *not* overridden at runtime with an efficient implementation,
|
|
and should be used with caution. See https://github.com/leanprover/lean4/issues/7887.
|
|
-/
|
|
protected def ISize.pow (x : ISize) (n : Nat) : ISize :=
|
|
match n with
|
|
| 0 => 1
|
|
| n + 1 => ISize.mul (ISize.pow x n) x
|
|
/--
|
|
The modulo operator for word-sized signed integers, which computes the remainder when dividing one
|
|
integer by another with the T-rounding convention used by `ISize.div`. Usually accessed via the `%`
|
|
operator.
|
|
|
|
When the divisor is `0`, the result is the dividend rather than an error.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `ISize.mod 5 2 = 1`
|
|
* `ISize.mod 5 (-2) = 1`
|
|
* `ISize.mod (-5) 2 = (-1)`
|
|
* `ISize.mod (-5) (-2) = (-1)`
|
|
* `ISize.mod 4 2 = 0`
|
|
* `ISize.mod 4 (-2) = 0`
|
|
* `ISize.mod 4 0 = 4`
|
|
* `ISize.mod (-4) 0 = (-4)`
|
|
-/
|
|
@[extern "lean_isize_mod"]
|
|
protected def ISize.mod (a b : ISize) : ISize := ⟨⟨BitVec.srem a.toBitVec b.toBitVec⟩⟩
|
|
/--
|
|
Bitwise and for word-sized signed integers. Usually accessed via the `&&&` operator.
|
|
|
|
Each bit of the resulting integer is set if the corresponding bits of both input integers are set,
|
|
according to the two's complement representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_isize_land"]
|
|
protected def ISize.land (a b : ISize) : ISize := ⟨⟨a.toBitVec &&& b.toBitVec⟩⟩
|
|
/--
|
|
Bitwise or for word-sized signed integers. Usually accessed via the `|||` operator.
|
|
|
|
Each bit of the resulting integer is set if at least one of the corresponding bits of the input
|
|
integers is set, according to the two's complement representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_isize_lor"]
|
|
protected def ISize.lor (a b : ISize) : ISize := ⟨⟨a.toBitVec ||| b.toBitVec⟩⟩
|
|
/--
|
|
Bitwise exclusive or for word-sized signed integers. Usually accessed via the `^^^` operator.
|
|
|
|
Each bit of the resulting integer is set if exactly one of the corresponding bits of the input
|
|
integers is set, according to the two's complement representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_isize_xor"]
|
|
protected def ISize.xor (a b : ISize) : ISize := ⟨⟨a.toBitVec ^^^ b.toBitVec⟩⟩
|
|
/--
|
|
Bitwise left shift for word-sized signed integers. Usually accessed via the `<<<` operator.
|
|
|
|
Signed integers are interpreted as bitvectors according to the two's complement representation.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_isize_shift_left"]
|
|
protected def ISize.shiftLeft (a b : ISize) : ISize := ⟨⟨a.toBitVec <<< (b.toBitVec.smod System.Platform.numBits)⟩⟩
|
|
/--
|
|
Arithmetic right shift for word-sized signed integers. Usually accessed via the `<<<` operator.
|
|
|
|
The high bits are filled with the value of
|
|
the most significant bit.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_isize_shift_right"]
|
|
protected def ISize.shiftRight (a b : ISize) : ISize := ⟨⟨BitVec.sshiftRight' a.toBitVec (b.toBitVec.smod System.Platform.numBits)⟩⟩
|
|
/--
|
|
Bitwise complement, also known as bitwise negation, for word-sized signed integers. Usually accessed
|
|
via the `~~~` prefix operator.
|
|
|
|
Each bit of the resulting integer is the opposite of the corresponding bit of the input integer.
|
|
Integers use the two's complement representation, so `ISize.complement a = -(a + 1)`.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_isize_complement"]
|
|
protected def ISize.complement (a : ISize) : ISize := ⟨⟨~~~a.toBitVec⟩⟩
|
|
|
|
/--
|
|
Computes the absolute value of a word-sized signed integer.
|
|
|
|
This function is equivalent to `if a < 0 then -a else a`, so in particular `ISize.minValue` will be
|
|
mapped to `ISize.minValue`.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
-/
|
|
@[extern "lean_isize_abs"]
|
|
protected def ISize.abs (a : ISize) : ISize := ⟨⟨a.toBitVec.abs⟩⟩
|
|
|
|
/--
|
|
Decides whether two word-sized signed integers are equal. Usually accessed via the
|
|
`DecidableEq ISize` instance.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `ISize.decEq 123 123 = .isTrue rfl`
|
|
* `(if ((-7) : ISize) = 7 then "yes" else "no") = "no"`
|
|
* `show (7 : ISize) = 7 by decide`
|
|
-/
|
|
@[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))
|
|
|
|
/--
|
|
Strict inequality of word-sized signed integers, defined as inequality of the corresponding
|
|
integers. Usually accessed via the `<` operator.
|
|
-/
|
|
protected def ISize.lt (a b : ISize) : Prop := a.toBitVec.slt b.toBitVec
|
|
/--
|
|
Non-strict inequality of word-sized signed integers, defined as inequality of the corresponding
|
|
integers. Usually accessed via the `≤` operator.
|
|
-/
|
|
protected 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 : Pow ISize Nat := ⟨ISize.pow⟩
|
|
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
|
|
|
|
/--
|
|
Converts `true` to `1` and `false` to `0`.
|
|
-/
|
|
@[extern "lean_bool_to_isize"]
|
|
def Bool.toISize (b : Bool) : ISize := if b then 1 else 0
|
|
|
|
/--
|
|
Decides whether one word-sized signed integer is strictly less than another. Usually accessed via the
|
|
`DecidableLT ISize` instance.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `(if ((-7) : ISize) < 7 then "yes" else "no") = "yes"`
|
|
* `(if (5 : ISize) < 5 then "yes" else "no") = "no"`
|
|
* `show ¬((7 : ISize) < 7) by decide`
|
|
-/
|
|
@[extern "lean_isize_dec_lt"]
|
|
def ISize.decLt (a b : ISize) : Decidable (a < b) :=
|
|
inferInstanceAs (Decidable (a.toBitVec.slt b.toBitVec))
|
|
|
|
/--
|
|
Decides whether one word-sized signed integer is less than or equal to another. Usually accessed via
|
|
the `DecidableLE ISize` instance.
|
|
|
|
This function is overridden at runtime with an efficient implementation.
|
|
|
|
Examples:
|
|
* `(if ((-7) : ISize) ≤ 7 then "yes" else "no") = "yes"`
|
|
* `(if (15 : ISize) ≤ 15 then "yes" else "no") = "yes"`
|
|
* `(if (15 : ISize) ≤ 5 then "yes" else "no") = "no"`
|
|
* `show (7 : ISize) ≤ 7 by decide`
|
|
-/
|
|
@[extern "lean_isize_dec_le"]
|
|
def ISize.decLe (a b : ISize) : Decidable (a ≤ b) :=
|
|
inferInstanceAs (Decidable (a.toBitVec.sle b.toBitVec))
|
|
|
|
attribute [instance] ISize.decLt ISize.decLe
|
|
|
|
instance : Max ISize := maxOfLe
|
|
instance : Min ISize := minOfLe
|