Documentation

Complexity.Computability.WordRAM.Signed.Arithmetic

Signed arithmetic implemented by unsigned word-RAM instructions #

The input registers hold the encodings of two signed integers. The routines use only ordinary unsigned arithmetic, comparisons and branches; no signed operation is added to the machine. The bounds exclude the final halt; Exec.executes adds exactly one instruction. Registers left (index 0) and right (index 1) are inputs, result (index 2) is the output, and indices 3 through 8 are scratch, including two (index 3). Memory and all other registers are preserved. Code.rename can place the routines in a larger register file.

The source semantics are GenericRAM.Signed.Arithmetic.eval, covering all five operations: addition, subtraction, multiplication, Euclidean division and Euclidean remainder, including Lean's total zero-divisor conventions (a / 0 = 0 and a % 0 = a). The common w + 2 allowance covers exact out-of-range sums, differences and minimum/-1 quotients; it is not a minimal-width claim for results that fit the source range.

Main definitions #

Main results #

References #

The instruction blocks and their representation are original implementation choices.

@[reducible, inline]
abbrev Cslib.WordRAM.Signed.left {r : ℕ} :
Fin (r + 9)

First encoded operand.

Instances For
    @[reducible, inline]
    abbrev Cslib.WordRAM.Signed.right {r : ℕ} :
    Fin (r + 9)

    Second encoded operand.

    Instances For
      @[reducible, inline]
      abbrev Cslib.WordRAM.Signed.result {r : ℕ} :
      Fin (r + 9)

      Encoded result.

      Instances For
        @[reducible, inline]
        abbrev Cslib.WordRAM.Signed.two {r : ℕ} :
        Fin (r + 9)

        Constant two, used to extract magnitudes and signs.

        Instances For
          @[reducible, inline]
          abbrev Cslib.WordRAM.Signed.magA {r : ℕ} :
          Fin (r + 9)

          Decoded magnitude of the first operand.

          Instances For
            @[reducible, inline]
            abbrev Cslib.WordRAM.Signed.magB {r : ℕ} :
            Fin (r + 9)

            Decoded magnitude of the second operand.

            Instances For
              @[reducible, inline]
              abbrev Cslib.WordRAM.Signed.signA {r : ℕ} :
              Fin (r + 9)

              First operand sign, later reused for the result sign.

              Instances For
                @[reducible, inline]
                abbrev Cslib.WordRAM.Signed.signB {r : ℕ} :
                Fin (r + 9)

                Second operand sign.

                Instances For
                  @[reducible, inline]
                  abbrev Cslib.WordRAM.Signed.zero {r : ℕ} :
                  Fin (r + 9)

                  Constant zero, used to normalize the result.

                  Instances For

                    Decode the two input words into four scratch registers in six instructions.

                    Instances For

                      Encode a magnitude and sign, setting the sign of zero to zero.

                      Instances For

                        Add equal-sign magnitudes, or subtract the smaller opposite-sign magnitude.

                        Instances For

                          Combine decoded operands and encode their sum.

                          Instances For

                            Add two sign-and-magnitude words, normalizing the sign of zero.

                            Instances For

                              Reverse the right sign bit; the result register temporarily holds the constant one.

                              Instances For

                                Subtract by reversing the second operand's sign before the addition block. The temporary sign of zero is immaterial and the result is normalized.

                                Instances For

                                  Multiply the decoded magnitudes and set the product sign.

                                  Instances For

                                    Multiply the magnitudes and compare the signs, normalizing the sign of zero.

                                    Instances For

                                      Compute the Euclidean quotient magnitude and sign from decoded operands.

                                      Instances For

                                        Signed Euclidean division on sign-and-magnitude words, matching Lean's a / 0 = 0 convention and, for b ≠ 0, Lean's Euclidean Int.ediv: the quotient for which a % b lies in [0, |b|) (rounding toward -∞ when b > 0 and toward +∞ when b < 0).

                                        Instances For

                                          Compute the encoded Euclidean remainder from decoded operands, preserving a % 0 = a.

                                          Instances For

                                            Signed Euclidean remainder on sign-and-magnitude words, matching Lean's a % 0 = a convention and returning a nonnegative remainder below |b| when b ≠ 0.

                                            Instances For
                                              def Cslib.WordRAM.Signed.Frame {r : ℕ} (x y : Data (r + 9)) :

                                              Memory and registers outside the output and six scratch registers are unchanged.

                                              Instances For
                                                theorem Cslib.WordRAM.Signed.exec_add {r w : ℕ} {a b : ℤ} (ha : GenericRAM.Signed.Fits w a) (hb : GenericRAM.Signed.Fits w b) (x : Data (r + 9)) (hxa : x.regs left = encode a) (hxb : x.regs right = encode b) :

                                                Signed addition runs within fifteen instructions at unsigned width w + 2. The result is exact even when the sum does not fit the source signed range.

                                                theorem Cslib.WordRAM.Signed.exec_subtract {r w : ℕ} {a b : ℤ} (ha : GenericRAM.Signed.Fits w a) (hb : GenericRAM.Signed.Fits w b) (x : Data (r + 9)) (hxa : x.regs left = encode a) (hxb : x.regs right = encode b) :

                                                Signed subtraction runs within seventeen instructions at unsigned width w + 2. The result is exact even when the difference does not fit the source signed range.

                                                theorem Cslib.WordRAM.Signed.exec_multiply {r w : ℕ} {a b : ℤ} (ha : GenericRAM.Signed.Fits w a) (hb : GenericRAM.Signed.Fits w b) (hp : GenericRAM.Signed.Fits w (a * b)) (x : Data (r + 9)) (hxa : x.regs left = encode a) (hxb : x.regs right = encode b) :

                                                Signed multiplication runs within fourteen instructions at unsigned width w + 2, provided the mathematical product fits the source signed range. No double-width unsigned product is needed: the magnitudes' product equals the magnitude of the signed result.

                                                theorem Cslib.WordRAM.Signed.exec_divide {r w : ℕ} {a b : ℤ} (ha : GenericRAM.Signed.Fits w a) (hb : GenericRAM.Signed.Fits w b) (x : Data (r + 9)) (hxa : x.regs left = encode a) (hxb : x.regs right = encode b) :

                                                Signed Euclidean division runs within twenty instructions at unsigned width w + 2, including Lean's a / 0 = 0 convention. The result is exact even at the minimum/-1 signed overflow (-2 ^ (w - 1)) / (-1) = 2 ^ (w - 1), where GenericRAM.Signed.model faults and the compiled block returns encode (2 ^ (w - 1)) without fault reflection.

                                                theorem Cslib.WordRAM.Signed.exec_modulo {r w : ℕ} {a b : ℤ} (ha : GenericRAM.Signed.Fits w a) (hb : GenericRAM.Signed.Fits w b) (x : Data (r + 9)) (hxa : x.regs left = encode a) (hxb : x.regs right = encode b) :

                                                Signed Euclidean remainder runs within thirteen instructions at unsigned width w + 2, including Lean's a % 0 = a convention.