From 7ca5bfbb70d8ae3d5d8acf1df6f2a7beabf72b40 Mon Sep 17 00:00:00 2001 From: giles Date: Sat, 9 May 2026 06:05:31 +0000 Subject: [PATCH] ocaml: phase 5.1 fraction.ml baseline (rational arithmetic, 4/3 -> num+den=7) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Defines: type frac = { num : int; den : int } let rec gcd a b = if b = 0 then a else gcd b (a mod b) let make n d = (* canonicalise: gcd-reduce and force den > 0 *) let add x y = make (x.num * y.den + y.num * x.den) (x.den * y.den) let mul x y = make (x.num * y.num) (x.den * y.den) Test: let r = add (make 1 2) (make 1 3) in (* 5/6 *) let s = mul (make 2 3) (make 3 4) in (* 1/2 *) let t = add r s in (* 5/6 + 1/2 = 4/3 *) t.num + t.den (* = 7 *) Exercises records, recursive gcd, mod, abs, integer division (the truncate-toward-zero semantics from iter 94 are essential here — make would diverge from real OCaml's behaviour with float division). 28 baseline programs total. --- lib/ocaml/baseline/expected.json | 1 + lib/ocaml/baseline/fraction.ml | 20 ++++++++++++++++++++ plans/ocaml-on-sx.md | 7 +++++++ 3 files changed, 28 insertions(+) create mode 100644 lib/ocaml/baseline/fraction.ml diff --git a/lib/ocaml/baseline/expected.json b/lib/ocaml/baseline/expected.json index 6f5186e2..b2697a83 100644 --- a/lib/ocaml/baseline/expected.json +++ b/lib/ocaml/baseline/expected.json @@ -10,6 +10,7 @@ "exception_handle.ml": 4, "expr_eval.ml": 16, "factorial.ml": 3628800, + "fraction.ml": 7, "frequency.ml": 5, "fizzbuzz.ml": 57, "list_ops.ml": 30, diff --git a/lib/ocaml/baseline/fraction.ml b/lib/ocaml/baseline/fraction.ml new file mode 100644 index 00000000..e67715f0 --- /dev/null +++ b/lib/ocaml/baseline/fraction.ml @@ -0,0 +1,20 @@ +type frac = { num : int; den : int } + +let rec gcd a b = if b = 0 then a else gcd b (a mod b) + +let make n d = + let g = gcd (abs n) (abs d) in + if d < 0 then { num = -n / g; den = -d / g } + else { num = n / g; den = d / g } + +let add x y = + make (x.num * y.den + y.num * x.den) (x.den * y.den) + +let mul x y = make (x.num * y.num) (x.den * y.den) + +;; + +let r = add (make 1 2) (make 1 3) in +let s = mul (make 2 3) (make 3 4) in +let t = add r s in +t.num + t.den diff --git a/plans/ocaml-on-sx.md b/plans/ocaml-on-sx.md index 212bfbb7..301ede2f 100644 --- a/plans/ocaml-on-sx.md +++ b/plans/ocaml-on-sx.md @@ -407,6 +407,13 @@ _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-09 Phase 5.1 — fraction.ml baseline (rational arithmetic + via record + gcd canonicalization). Defines `type frac = { num; + den }`, `make` that reduces via gcd and forces den > 0, `add` and + `mul` constructors. Computes (1/2 + 1/3) + (2/3 * 3/4) = 4/3, sums + num + den = 7. Exercises records, recursive gcd, `mod`, `abs`, + integer division, and the new `Int.rem`-style truncate-zero + division semantics from iteration 94. 28 baseline programs total. - 2026-05-09 Phase 6 — Seq module (eager, list-backed) (+4 tests, 576 total). Real OCaml's Seq is lazy (a thunk producing Cons / Nil); ours is just a list, which is adequate for most