ocaml: phase 6 Map.Make / Set.Make functors (+4 tests, 418 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 45s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 45s
Both written in OCaml inside lib/ocaml/runtime.sx:
module Map = struct module Make (Ord) = struct
let empty = []
let add k v m = ... (* sorted insert via Ord.compare *)
let find_opt / find / mem / remove / bindings / cardinal
end end
module Set = struct module Make (Ord) = struct
let empty = []
let mem / add / remove / elements / cardinal
end end
Sorted association list / sorted list backing — linear ops but
correct. Strong substrate-validation: Map.Make is a non-trivial
functor implemented entirely on top of the OCaml-on-SX evaluator.
This commit is contained in:
@@ -389,6 +389,90 @@
|
|||||||
| Some v -> v
|
| Some v -> v
|
||||||
let mem t k = _hashtbl_mem t k
|
let mem t k = _hashtbl_mem t k
|
||||||
let length t = _hashtbl_length t
|
let length t = _hashtbl_length t
|
||||||
|
end ;;
|
||||||
|
|
||||||
|
module Map = struct
|
||||||
|
module Make (Ord) = struct
|
||||||
|
let empty = []
|
||||||
|
|
||||||
|
let rec add k v m =
|
||||||
|
match m with
|
||||||
|
| [] -> [(k, v)]
|
||||||
|
| (k2, v2) :: rest ->
|
||||||
|
begin
|
||||||
|
let c = Ord.compare k k2 in
|
||||||
|
if c = 0 then (k, v) :: rest
|
||||||
|
else if c < 0 then (k, v) :: m
|
||||||
|
else (k2, v2) :: add k v rest
|
||||||
|
end
|
||||||
|
|
||||||
|
let rec find_opt k m =
|
||||||
|
match m with
|
||||||
|
| [] -> None
|
||||||
|
| (k2, v) :: rest ->
|
||||||
|
if Ord.compare k k2 = 0 then Some v
|
||||||
|
else find_opt k rest
|
||||||
|
|
||||||
|
let find k m =
|
||||||
|
match find_opt k m with
|
||||||
|
| None -> failwith \"Map.find: not found\"
|
||||||
|
| Some v -> v
|
||||||
|
|
||||||
|
let rec mem k m =
|
||||||
|
match m with
|
||||||
|
| [] -> false
|
||||||
|
| (k2, _) :: rest -> if Ord.compare k k2 = 0 then true else mem k rest
|
||||||
|
|
||||||
|
let rec remove k m =
|
||||||
|
match m with
|
||||||
|
| [] -> []
|
||||||
|
| (k2, v) :: rest ->
|
||||||
|
if Ord.compare k k2 = 0 then rest else (k2, v) :: remove k rest
|
||||||
|
|
||||||
|
let rec bindings m = m
|
||||||
|
|
||||||
|
let rec cardinal m =
|
||||||
|
match m with
|
||||||
|
| [] -> 0
|
||||||
|
| _ :: t -> 1 + cardinal t
|
||||||
|
end
|
||||||
|
end ;;
|
||||||
|
|
||||||
|
module Set = struct
|
||||||
|
module Make (Ord) = struct
|
||||||
|
let empty = []
|
||||||
|
|
||||||
|
let rec mem x s =
|
||||||
|
match s with
|
||||||
|
| [] -> false
|
||||||
|
| h :: t ->
|
||||||
|
let c = Ord.compare x h in
|
||||||
|
if c = 0 then true
|
||||||
|
else if c < 0 then false
|
||||||
|
else mem x t
|
||||||
|
|
||||||
|
let rec add x s =
|
||||||
|
match s with
|
||||||
|
| [] -> [x]
|
||||||
|
| h :: t ->
|
||||||
|
let c = Ord.compare x h in
|
||||||
|
if c = 0 then s
|
||||||
|
else if c < 0 then x :: s
|
||||||
|
else h :: add x t
|
||||||
|
|
||||||
|
let rec remove x s =
|
||||||
|
match s with
|
||||||
|
| [] -> []
|
||||||
|
| h :: t ->
|
||||||
|
if Ord.compare x h = 0 then t else h :: remove x t
|
||||||
|
|
||||||
|
let rec elements s = s
|
||||||
|
|
||||||
|
let rec cardinal s =
|
||||||
|
match s with
|
||||||
|
| [] -> 0
|
||||||
|
| _ :: t -> 1 + cardinal t
|
||||||
|
end
|
||||||
end")
|
end")
|
||||||
|
|
||||||
(define ocaml-stdlib-loaded false)
|
(define ocaml-stdlib-loaded false)
|
||||||
|
|||||||
@@ -1024,6 +1024,16 @@ cat > "$TMPFILE" << 'EPOCHS'
|
|||||||
(epoch 3204)
|
(epoch 3204)
|
||||||
(eval "(ocaml-run \"Sys.executable_name\")")
|
(eval "(ocaml-run \"Sys.executable_name\")")
|
||||||
|
|
||||||
|
;; ── Map.Make / Set.Make functors ──────────────────────────────
|
||||||
|
(epoch 3300)
|
||||||
|
(eval "(ocaml-run-program \"module IntOrd = struct let compare a b = compare a b end ;; module IntMap = Map.Make(IntOrd) ;; let m = IntMap.add 1 \\\"a\\\" IntMap.empty ;; let m = IntMap.add 2 \\\"b\\\" m ;; IntMap.find 1 m\")")
|
||||||
|
(epoch 3301)
|
||||||
|
(eval "(ocaml-run-program \"module IntOrd = struct let compare a b = compare a b end ;; module IntMap = Map.Make(IntOrd) ;; IntMap.cardinal (IntMap.add 1 \\\"a\\\" (IntMap.add 2 \\\"b\\\" IntMap.empty))\")")
|
||||||
|
(epoch 3302)
|
||||||
|
(eval "(ocaml-run-program \"module IntOrd = struct let compare a b = compare a b end ;; module IntSet = Set.Make(IntOrd) ;; IntSet.elements (IntSet.add 3 (IntSet.add 1 (IntSet.add 2 IntSet.empty)))\")")
|
||||||
|
(epoch 3303)
|
||||||
|
(eval "(ocaml-run-program \"module IntOrd = struct let compare a b = compare a b end ;; module IntSet = Set.Make(IntOrd) ;; IntSet.mem 2 (IntSet.add 3 (IntSet.add 1 (IntSet.add 2 IntSet.empty)))\")")
|
||||||
|
|
||||||
EPOCHS
|
EPOCHS
|
||||||
|
|
||||||
OUTPUT=$(timeout 180 "$SX_SERVER" < "$TMPFILE" 2>/dev/null)
|
OUTPUT=$(timeout 180 "$SX_SERVER" < "$TMPFILE" 2>/dev/null)
|
||||||
@@ -1620,6 +1630,12 @@ check 3202 "Sys.unix" 'true'
|
|||||||
check 3203 "Sys.win32" 'false'
|
check 3203 "Sys.win32" 'false'
|
||||||
check 3204 "Sys.executable_name" '"ocaml-on-sx"'
|
check 3204 "Sys.executable_name" '"ocaml-on-sx"'
|
||||||
|
|
||||||
|
# ── Map.Make / Set.Make ────────────────────────────────────────
|
||||||
|
check 3300 "Map.find via functor" '"a"'
|
||||||
|
check 3301 "Map.cardinal" '2'
|
||||||
|
check 3302 "Set.elements sorted" '(1 2 3)'
|
||||||
|
check 3303 "Set.mem" 'true'
|
||||||
|
|
||||||
TOTAL=$((PASS + FAIL))
|
TOTAL=$((PASS + FAIL))
|
||||||
if [ $FAIL -eq 0 ]; then
|
if [ $FAIL -eq 0 ]; then
|
||||||
echo "ok $PASS/$TOTAL OCaml-on-SX tests passed"
|
echo "ok $PASS/$TOTAL OCaml-on-SX tests passed"
|
||||||
|
|||||||
@@ -286,8 +286,11 @@ SX CEK evaluator (both JS and OCaml hosts)
|
|||||||
- [ ] `Int`/`Float`: arithmetic, `to_string`, `of_string_opt`, `min_int`, `max_int`.
|
- [ ] `Int`/`Float`: arithmetic, `to_string`, `of_string_opt`, `min_int`, `max_int`.
|
||||||
- [ ] `Hashtbl`: `create`, `add`, `replace`, `find`, `find_opt`, `remove`, `mem`,
|
- [ ] `Hashtbl`: `create`, `add`, `replace`, `find`, `find_opt`, `remove`, `mem`,
|
||||||
`iter`, `fold`, `length` — backed by SX mutable dict.
|
`iter`, `fold`, `length` — backed by SX mutable dict.
|
||||||
- [ ] `Map.Make` functor — balanced BST backed by SX sorted dict.
|
- [x] `Map.Make` functor — sorted association list backed
|
||||||
- [ ] `Set.Make` functor.
|
(insert/find/remove/mem/cardinal/bindings); not a balanced tree
|
||||||
|
but linear with parametric `Ord` ordering.
|
||||||
|
- [x] `Set.Make` functor — sorted list backed
|
||||||
|
(add/mem/remove/elements/cardinal).
|
||||||
- [ ] `Printf`: `sprintf`, `printf`, `eprintf` — format strings via `(format ...)`.
|
- [ ] `Printf`: `sprintf`, `printf`, `eprintf` — format strings via `(format ...)`.
|
||||||
- [ ] `Sys`: `argv`, `getenv_opt`, `getcwd` — via `perform` IO.
|
- [ ] `Sys`: `argv`, `getenv_opt`, `getcwd` — via `perform` IO.
|
||||||
- [ ] Scoreboard runner: `lib/ocaml/conformance.sh` + `scoreboard.json`.
|
- [ ] Scoreboard runner: `lib/ocaml/conformance.sh` + `scoreboard.json`.
|
||||||
@@ -383,6 +386,14 @@ the "mother tongue" closure: OCaml → SX → OCaml. This means:
|
|||||||
|
|
||||||
_Newest first._
|
_Newest first._
|
||||||
|
|
||||||
|
- 2026-05-08 Phase 6 — `Map.Make` / `Set.Make` functors written in
|
||||||
|
OCaml (+4 tests, 418 total). Sorted association list / sorted list
|
||||||
|
backed (linear ops, but correct). Both take an `Ord` module supplying
|
||||||
|
`compare`. Tested: `module IntMap = Map.Make(IntOrd) ;; IntMap.find
|
||||||
|
…` and `IntSet.elements (IntSet.add 3 (IntSet.add 1 …))` returning
|
||||||
|
`[1; 2; 3]`. Strong substrate-validation for the functor system —
|
||||||
|
Map.Make is a non-trivial functor implemented entirely on top of the
|
||||||
|
OCaml-on-SX evaluator.
|
||||||
- 2026-05-08 Phase 6 — `Sys` module constants (+5 tests, 414 total).
|
- 2026-05-08 Phase 6 — `Sys` module constants (+5 tests, 414 total).
|
||||||
os_type, word_size, max_array_length, max_string_length,
|
os_type, word_size, max_array_length, max_string_length,
|
||||||
executable_name, big_endian, unix, win32, cygwin. Constants-only
|
executable_name, big_endian, unix, win32, cygwin. Constants-only
|
||||||
|
|||||||
Reference in New Issue
Block a user