ocaml: && / || short-circuit fix + bfs_grid.ml baseline (5x5 grid, dist 8)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 22s

Before: `:op` handler always evaluated both operands before dispatching
to ocaml-eval-op. For pure binops that's fine, but `&&` / `||` MUST
short-circuit:

  if nr >= 0 && grid.(nr).(nc) = 0 then ...

When nr = -1, real OCaml never evaluates `grid.(-1)`. Our evaluator
did, and crashed with "nth: list/string and number".

Fix: special-case `&&` and `||` in :op dispatch, mirroring the same
pattern already used for `:=` and `<-`. Evaluate lhs, branch on it,
and only evaluate rhs when needed.

Latent since baseline 1 — earlier programs never triggered it because
the rhs was unconditionally safe.

bfs_grid.ml: shortest path through a 5x5 grid with walls. Standard
BFS using Queue.{push,pop,is_empty} + Array.init for the 2D distance
matrix. Path 0,0 -> ... -> 4,4 has length 8. 155 baseline programs
total.
This commit is contained in:
2026-05-10 21:37:41 +00:00
parent bed374c9e1
commit 4761d41a0d
4 changed files with 64 additions and 0 deletions

View File

@@ -657,6 +657,14 @@
(error
(str "ocaml-eval: <- expects a field-access lhs, got "
(ocaml-tag-of lhs-ast)))))))
;; && and || short-circuit — must NOT evaluate rhs when
;; lhs already decides. Mirrors real OCaml semantics.
((= op "&&")
(let ((lhs (ocaml-eval (nth ast 2) env)))
(if lhs (ocaml-eval (nth ast 3) env) false)))
((= op "||")
(let ((lhs (ocaml-eval (nth ast 2) env)))
(if lhs true (ocaml-eval (nth ast 3) env))))
(else
(ocaml-eval-op op
(ocaml-eval (nth ast 2) env)