From fd1f94f292a41fd8c775c4a4225be25957d46894 Mon Sep 17 00:00:00 2001 From: giles Date: Mon, 11 May 2026 00:20:30 +0000 Subject: [PATCH] ocaml: phase 5.1 lru_cache.ml baseline (cap=3 LRU, fingerprint 499) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Functional LRU cache via association-list ordered most-recent-first. Get / put both: - find or remove the existing entry - cons the fresh (k, v) to the front - on put, trim the tail when over capacity Sequence: put 1 100; put 2 200; put 3 300 a = get 1 -> 100 (moves 1 to front) put 4 400 (evicts 2) b = get 2 -> -1 (no longer cached) c = get 3 -> 300 d = get 1 -> 100 a + b + c + d = 499 Tests `match … with (k', v) :: rest when k' = k -> …` tuple-cons patterns with `when` guards, `function` keyword for arg-less match, recursive find/remove/take over the same list. Parser limit found: `match n, lst with` ad-hoc tuple-scrutinee is not yet supported (got "expected op -> got op ,"); workaround uses outer `if` plus inner match. 171 baseline programs total. --- lib/ocaml/baseline/expected.json | 1 + lib/ocaml/baseline/lru_cache.ml | 51 ++++++++++++++++++++++++++++++++ plans/ocaml-on-sx.md | 11 +++++++ 3 files changed, 63 insertions(+) create mode 100644 lib/ocaml/baseline/lru_cache.ml diff --git a/lib/ocaml/baseline/expected.json b/lib/ocaml/baseline/expected.json index 8f4df2a9..90b74c93 100644 --- a/lib/ocaml/baseline/expected.json +++ b/lib/ocaml/baseline/expected.json @@ -82,6 +82,7 @@ "floyd_warshall.ml": 9, "lis.ml": 6, "list_ops.ml": 30, + "lru_cache.ml": 499, "luhn.ml": 2, "magic_square.ml": 65, "mat_mul.ml": 621, diff --git a/lib/ocaml/baseline/lru_cache.ml b/lib/ocaml/baseline/lru_cache.ml new file mode 100644 index 00000000..9153db10 --- /dev/null +++ b/lib/ocaml/baseline/lru_cache.ml @@ -0,0 +1,51 @@ +let cache = ref [] +let cap = 3 + +let get k = + let rec find = function + | [] -> None + | (k', v) :: _ when k' = k -> Some v + | _ :: rest -> find rest + in + match find !cache with + | None -> -1 + | Some v -> + let rec remove = function + | [] -> [] + | (k', _) :: rest when k' = k -> rest + | h :: rest -> h :: remove rest + in + cache := (k, v) :: remove !cache; + v + +let put k v = + let rec remove = function + | [] -> [] + | (k', _) :: rest when k' = k -> rest + | h :: rest -> h :: remove rest + in + let cleaned = remove !cache in + let trimmed = + if List.length cleaned >= cap then + let rec take n lst = + if n = 0 then [] + else match lst with + | [] -> [] + | h :: r -> h :: take (n - 1) r + in + take (cap - 1) cleaned + else cleaned + in + cache := (k, v) :: trimmed + +;; + +put 1 100; +put 2 200; +put 3 300; +let a = get 1 in +put 4 400; +let b = get 2 in +let c = get 3 in +let d = get 1 in +a + b + c + d diff --git a/plans/ocaml-on-sx.md b/plans/ocaml-on-sx.md index 292124dc..5f209ede 100644 --- a/plans/ocaml-on-sx.md +++ b/plans/ocaml-on-sx.md @@ -407,6 +407,17 @@ _Newest first._ binary search tree (`type 'a tree = Leaf | Node of 'a * 'a tree * 'a tree`) with insert + in-order traversal. Tests parametric ADT, recursive match, List.append, List.fold_left. +- 2026-05-11 Phase 5.1 — lru_cache.ml baseline (list-backed LRU + cache of capacity 3, fingerprint 100 + (-1) + 300 + 100 = 499). + Each `get` / `put` removes the existing entry then conses the + fresh one to the front; `put` evicts the tail when over capacity. + Tests `match … with [] -> … | (k', v) :: rest when k' = k -> …` + pattern matching with `when` guards over tuple-cons patterns, + `function` keyword for short scrutinee-free matches, recursive + `find` / `remove` / `take` over the same list. Note: parser does + not yet handle `match n, lst with` ad-hoc tuple-scrutinee (got + "expected op -> got op ,"); workaround uses an outer `if` then + inner `match lst with`. 171 baseline programs total. - 2026-05-11 Phase 5.1 — convex_hull.ml baseline (Andrew's monotone chain over 8 points → 5-vertex convex hull). Sorts points lexicographically, then builds lower hull left-to-right and upper