Skip to content

Commit 0db98d5

Browse files
pirapiraclaude
andcommitted
Complete Phase 9b, begin Phase 9c: consensus containers with math.isqrt
Add math.isqrt builtin (Newton's method integer square root) for Slot.is_justifiable_after(). Implement Phase 9c consensus container tests: Slot/ValidatorIndex with custom methods, nested Containers (Checkpoint, Config, BlockHeader, BlockBody, Block), model_copy on nested containers, default field values, SSZList with Container elements composite hash_tree_root, and State.generate_genesis classmethod factory. All hash_tree_root results verified byte-for-byte against CPython. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 1d4576a commit 0db98d5

5 files changed

Lines changed: 60 additions & 2 deletions

File tree

LeanPython/Interpreter/Eval.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2914,6 +2914,7 @@ partial def getBuiltinModule (name : String) : InterpM (Option Value) := do
29142914
ns := ns.insert "fabs" (.builtin "math.fabs")
29152915
ns := ns.insert "isnan" (.builtin "math.isnan")
29162916
ns := ns.insert "isinf" (.builtin "math.isinf")
2917+
ns := ns.insert "isqrt" (.builtin "math.isqrt")
29172918
ns := ns.insert "inf" (.float (1.0 / 0.0))
29182919
ns := ns.insert "nan" (.float (0.0 / 0.0))
29192920
ns := ns.insert "pi" (.float 3.141592653589793)

LeanPython/Runtime/Builtins.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,6 +835,7 @@ partial def callBuiltin (name : String) (args : List Value)
835835
| "math.ceil" => mathCeil args
836836
| "math.floor" => mathFloor args
837837
| "math.sqrt" => mathSqrt args
838+
| "math.isqrt" => mathIsqrt args
838839
| "math.log" => mathLog args
839840
| "math.log2" => mathLog2 args
840841
| "math.fabs" => mathFabs args

LeanPython/Stdlib/Math.lean

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,23 @@ partial def mathIsinf (args : List Value) : InterpM Value := do
9595
| [.int _] => return .bool false
9696
| _ => throwTypeError "math.isinf() requires a numeric argument"
9797

98+
/-- Newton step for integer square root. -/
99+
private partial def isqrtLoop (n x : Nat) : Nat :=
100+
let y := (x + n / x) / 2
101+
if y < x then isqrtLoop n y else x
102+
103+
/-- Integer square root: largest k such that k*k <= n. -/
104+
private def natIsqrt (n : Nat) : Nat :=
105+
if n == 0 then 0
106+
else isqrtLoop n n
107+
108+
/-- Python math.isqrt: return integer square root of non-negative integer -/
109+
partial def mathIsqrt (args : List Value) : InterpM Value := do
110+
match args with
111+
| [.int n] =>
112+
if n < 0 then throwValueError "isqrt() argument must be nonnegative"
113+
else return .int (Int.ofNat (natIsqrt n.toNat))
114+
| [.bool b] => return .int (if b then 1 else 0)
115+
| _ => throwTypeError "math.isqrt() requires an integer argument"
116+
98117
end LeanPython.Stdlib.Math

0 commit comments

Comments
 (0)