Research-Stack/0-Core-Formalism/lean/Semantics/Semantics/FixedPointBoundary.lean
Devin AI 8e741199bf refactor(lean): remove Float from FixedPoint core, implement integer-only sqrt/log2/expNeg
Core FixedPoint.lean is now fully Float-free:
- Q16_16.sqrt: integer Newton method (intSqrt, 64-step fuel)
- Q16_16.log2: bit-position extraction + linear interpolation
- Q16_16.expNeg: 7-segment piecewise-linear (~0.02 max error)
- Q0_16.log2: bit extraction with 1/ln(2) scaling

Removed from core: ofFloat, toFloat, ln (Q16_16); toFloat, ofFloat
(Q0_16); q0_64ScaleFloat, ofFloat, toFloat (Q0_64).

Created Semantics.FixedPointBoundary for I/O boundary Float
conversions. 14 downstream files updated to import boundary module.

Build: 3573 jobs, 0 errors (lake build)
Co-Authored-By: Allaun Silverfox <bigdataiscoming+9i37y6j2@protonmail.com>
2026-06-15 02:07:21 +00:00

89 lines
3.3 KiB
Text

import Semantics.FixedPoint
/-!
# FixedPointBoundary — Float ↔ Q16_16 / Q0_16 / Q0_64 conversion
These functions are **only** for the I/O boundary: parsing JSON, reading sensor
data, or displaying values in `#eval` witnesses. They must NOT be used in any
compute-path definition that feeds into a receipt, score, or gate.
The core `Semantics.FixedPoint` module is Float-free by design.
-/
namespace Semantics.FixedPoint
-- ═══════════════════════════════════════════════════════════════════════════
-- Q0.16 Float boundary
-- ═══════════════════════════════════════════════════════════════════════════
namespace Q0_16
def toFloat (q : Q0_16) : Float :=
Float.ofInt q.toInt / 32767.0
def ofFloat (f : Float) : Q0_16 :=
if f.isNaN then zero
else if f ≥ 1.0 then one
else if f ≤ -1.0 then neg one
else if f < 0.0 then
ofRawInt (-(Int.ofNat ((-f * 32767.0).round.toUInt16.toNat)))
else
ofRawInt (Int.ofNat ((f * 32767.0).round.toUInt16.toNat))
end Q0_16
-- ═══════════════════════════════════════════════════════════════════════════
-- Q16.16 Float boundary
-- ═══════════════════════════════════════════════════════════════════════════
namespace Q16_16
@[inline]
def ofFloat (f : Float) : Q16_16 :=
if f.isNaN || f ≥ 32768.0 then infinity
else if f ≤ -32768.0 then minVal
else if f < 0.0 then
ofRawInt (-(Int.ofNat ((-f * 65536.0).floor.toUInt32.toNat)))
else
ofRawInt (Int.ofNat ((f * 65536.0).floor.toUInt32.toNat))
@[inline]
def toFloat (q : Q16_16) : Float :=
Float.ofInt q.toInt / 65536.0
end Q16_16
-- ═══════════════════════════════════════════════════════════════════════════
-- Q0.64 Float boundary
-- ═══════════════════════════════════════════════════════════════════════════
def q0_64ScaleFloat : Float := 9223372036854775808.0
namespace Q0_64
def ofFloat (f : Float) : Q0_64 :=
if f.isNaN || f ≥ 1.0 then one
else if f ≤ -1.0 then ofRawInt q0_64MinRaw
else if f < 0.0 then
ofRawInt (-(Int.ofNat ((-f * q0_64ScaleFloat).floor.toUInt64.toNat)))
else
ofRawInt (Int.ofNat ((f * q0_64ScaleFloat).floor.toUInt64.toNat))
def toFloat (q : Q0_64) : Float :=
Float.ofInt q.toInt / q0_64ScaleFloat
end Q0_64
end Semantics.FixedPoint
namespace Semantics
namespace Q16_16
export FixedPoint.Q16_16 (ofFloat toFloat)
end Q16_16
namespace Q0_16
export FixedPoint.Q0_16 (toFloat ofFloat)
end Q0_16
namespace Q0_64
export FixedPoint.Q0_64 (ofFloat toFloat)
end Q0_64
end Semantics