From fa58f4ef3a6c25d733870dc2759b6c296941b052 Mon Sep 17 00:00:00 2001 From: James Eversole Date: Sun, 10 May 2026 09:10:27 -0500 Subject: [PATCH] Fix fuel implementation in PHP --- AGENTS.md | 28 ++++------------------------ ext/php/run.php | 2 +- ext/php/src/functions.php | 17 +++++++++++++++-- 3 files changed, 20 insertions(+), 27 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 689a46f..0ed865c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,7 +2,7 @@ > For AI agents and contributors working in this repository. -## 0. TDD +## 0. Test Driven Development Write and discuss tests with the user before implementing any implementation code. @@ -178,27 +178,7 @@ tricu/ └── AGENTS.md # This file ``` -## 9. JS Arboricx Runtime - -A JavaScript implementation of the Arboricx portable bundle runtime lives in `ext/js/`. -It is a reference implementation — not a tricu source parser. It reads `.arboricx` files produced by the Haskell toolchain, verifies Merkle node hashes, reconstructs tree values, and reduces them. - -From project root: -```bash -node ext/js/src/cli.js inspect test/fixtures/id.arboricx -node ext/js/src/cli.js run test/fixtures/true.arboricx -``` - -The JS runtime implements: -- Bundle binary format parsing (header, section directory, manifest, nodes) -- SHA-256 Merkle node hash verification against canonical payloads -- Closure verification (all child references present) -- Tree reconstruction from node DAG -- Core `apply` reduction rules -- Basic codecs (decodeResult) -- CLI: `inspect` and `run` commands - -## 10. Content Store Workflow (Custom DB) +## 9. Content Store Workflow (Custom DB) The content store location is controlled by the `TRICU_DB_PATH` environment variable. When set, `eval` mode automatically loads all stored terms into the initial environment, so you can call any previously imported/evaluated term by name. @@ -226,14 +206,14 @@ t> !definitions Without `TRICU_DB_PATH` set, `eval` uses only the terms defined in the input file(s). -## 11. Development Tips +## 10. Development Tips - **REPL:** `nix run .#` starts the interactive tricu REPL. - **Evaluate files:** `nix run .# -- eval -f demos/equality.tri` - **GHC options:** `-threaded -rtsopts -with-rtsopts=-N` for parallel runtime. Use `-N` RTS flag for multi-core. - **Upx** is in the devShell for binary compression if needed. -## 12. Viewing Haskell Dependency Docs from Nix +## 11. Viewing Haskell Dependency Docs from Nix When you need Haddock documentation for a Haskell dependency available in Nixpkgs, build the package's `doc` output directly with `^doc`. diff --git a/ext/php/run.php b/ext/php/run.php index ff42a53..36bde0f 100644 --- a/ext/php/run.php +++ b/ext/php/run.php @@ -87,7 +87,7 @@ function cmdRun(string $bundlePath, array $args): void debugTime('built expression'); fwrite(STDERR, "Reducing kernel application...\n"); - $result = reduce($expr, 1_000_000); + $result = reduce($expr, 1_000_000_000); debugTime('reduced kernel application'); [$kind, $value, $rest] = unwrapResult($result); diff --git a/ext/php/src/functions.php b/ext/php/src/functions.php index 7a1b1bd..6da59ef 100644 --- a/ext/php/src/functions.php +++ b/ext/php/src/functions.php @@ -21,6 +21,14 @@ $GLOBALS['ARB_B'] = [0 => 0]; $GLOBALS['ARB_NEXT'] = 1; $GLOBALS['ARB_CONS_CACHE'] = []; +function spendFuel(int &$fuel): void +{ + if ($fuel <= 0) { + throw new \RuntimeException('fuel exhausted'); + } + $fuel--; +} + function newNode(int $tag, int $a, int $b = 0): int { $id = $GLOBALS['ARB_NEXT']++; @@ -100,12 +108,12 @@ function newAppFast(int $f, int $x, array &$TAG, array &$A, array &$B): int return $id; } -function apply_(int $a, int $b, int $fuel = 1_000_000): int +function apply_(int $a, int $b, int $fuel = 100_000_000_000_000_000): int { return reduce(app($a, $b), $fuel); } -function reduce(int $term, int $fuel = 1_000_000): int +function reduce(int $term, int $fuel = 100_000_000_000_000_000): int { return whnf($term, $fuel); } @@ -167,6 +175,7 @@ function whnf(int $term, int &$fuel): int if ($left === 0) { $term = $right; if ($orig !== $term) { $TAG[$orig] = 4; $A[$orig] = $term; $B[$orig] = 0; } + spendFuel($fuel); continue; } @@ -178,6 +187,7 @@ function whnf(int $term, int &$fuel): int $TAG, $A, $B ); if ($orig !== $term) { $TAG[$orig] = 4; $A[$orig] = $term; $B[$orig] = 0; } + spendFuel($fuel); continue; } @@ -195,6 +205,7 @@ function whnf(int $term, int &$fuel): int if ($arg === 0) { $term = $A[$left]; if ($orig !== $term) { $TAG[$orig] = 4; $A[$orig] = $term; $B[$orig] = 0; } + spendFuel($fuel); continue; } @@ -202,6 +213,7 @@ function whnf(int $term, int &$fuel): int if ($atag === 1) { $term = newAppFast($B[$left], $A[$arg], $TAG, $A, $B); if ($orig !== $term) { $TAG[$orig] = 4; $A[$orig] = $term; $B[$orig] = 0; } + spendFuel($fuel); continue; } @@ -213,6 +225,7 @@ function whnf(int $term, int &$fuel): int $TAG, $A, $B ); if ($orig !== $term) { $TAG[$orig] = 4; $A[$orig] = $term; $B[$orig] = 0; } + spendFuel($fuel); continue; }