haskell: Phase 11 — Data.Map BST skeleton (Adams weight-balanced)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 1m6s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 1m6s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
134
lib/haskell/map.sx
Normal file
134
lib/haskell/map.sx
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
;; map.sx — Phase 11 Data.Map: weight-balanced BST in pure SX.
|
||||||
|
;;
|
||||||
|
;; Algorithm: Adams's weight-balanced tree (the same family as Haskell's
|
||||||
|
;; Data.Map). Each node tracks its size; rotations maintain the invariant
|
||||||
|
;;
|
||||||
|
;; size(small-side) * delta >= size(large-side) (delta = 3)
|
||||||
|
;;
|
||||||
|
;; with single or double rotations chosen by the gamma ratio (gamma = 2).
|
||||||
|
;; The size field is an Int and is included so `size`, `lookup`, etc. are
|
||||||
|
;; O(log n) on both extremes of the tree.
|
||||||
|
;;
|
||||||
|
;; Representation:
|
||||||
|
;; Empty → ("Map-Empty")
|
||||||
|
;; Node → ("Map-Node" key val left right size)
|
||||||
|
;;
|
||||||
|
;; All operations are pure SX — no mutation of nodes once constructed.
|
||||||
|
;; The user-facing Haskell layer (Phase 11 next iteration) wraps these
|
||||||
|
;; for `import Data.Map as Map`.
|
||||||
|
|
||||||
|
;; ── Constructors ────────────────────────────────────────────
|
||||||
|
(define hk-map-empty (list "Map-Empty"))
|
||||||
|
|
||||||
|
(define
|
||||||
|
hk-map-node
|
||||||
|
(fn
|
||||||
|
(k v l r)
|
||||||
|
(list "Map-Node" k v l r (+ 1 (+ (hk-map-size l) (hk-map-size r))))))
|
||||||
|
|
||||||
|
;; ── Predicates and accessors ────────────────────────────────
|
||||||
|
(define hk-map-empty? (fn (m) (and (list? m) (= (first m) "Map-Empty"))))
|
||||||
|
|
||||||
|
(define hk-map-node? (fn (m) (and (list? m) (= (first m) "Map-Node"))))
|
||||||
|
|
||||||
|
(define
|
||||||
|
hk-map-size
|
||||||
|
(fn (m) (cond ((hk-map-empty? m) 0) (:else (nth m 5)))))
|
||||||
|
|
||||||
|
(define hk-map-key (fn (m) (nth m 1)))
|
||||||
|
(define hk-map-val (fn (m) (nth m 2)))
|
||||||
|
(define hk-map-left (fn (m) (nth m 3)))
|
||||||
|
(define hk-map-right (fn (m) (nth m 4)))
|
||||||
|
|
||||||
|
;; ── Weight-balanced rotations ───────────────────────────────
|
||||||
|
;; delta and gamma per Adams 1992 / Haskell Data.Map.
|
||||||
|
|
||||||
|
(define hk-map-delta 3)
|
||||||
|
(define hk-map-gamma 2)
|
||||||
|
|
||||||
|
(define
|
||||||
|
hk-map-single-l
|
||||||
|
(fn
|
||||||
|
(k v l r)
|
||||||
|
(let
|
||||||
|
((rk (hk-map-key r))
|
||||||
|
(rv (hk-map-val r))
|
||||||
|
(rl (hk-map-left r))
|
||||||
|
(rr (hk-map-right r)))
|
||||||
|
(hk-map-node rk rv (hk-map-node k v l rl) rr))))
|
||||||
|
|
||||||
|
(define
|
||||||
|
hk-map-single-r
|
||||||
|
(fn
|
||||||
|
(k v l r)
|
||||||
|
(let
|
||||||
|
((lk (hk-map-key l))
|
||||||
|
(lv (hk-map-val l))
|
||||||
|
(ll (hk-map-left l))
|
||||||
|
(lr (hk-map-right l)))
|
||||||
|
(hk-map-node lk lv ll (hk-map-node k v lr r)))))
|
||||||
|
|
||||||
|
(define
|
||||||
|
hk-map-double-l
|
||||||
|
(fn
|
||||||
|
(k v l r)
|
||||||
|
(let
|
||||||
|
((rk (hk-map-key r))
|
||||||
|
(rv (hk-map-val r))
|
||||||
|
(rl (hk-map-left r))
|
||||||
|
(rr (hk-map-right r))
|
||||||
|
(rlk (hk-map-key (hk-map-left r)))
|
||||||
|
(rlv (hk-map-val (hk-map-left r)))
|
||||||
|
(rll (hk-map-left (hk-map-left r)))
|
||||||
|
(rlr (hk-map-right (hk-map-left r))))
|
||||||
|
(hk-map-node
|
||||||
|
rlk
|
||||||
|
rlv
|
||||||
|
(hk-map-node k v l rll)
|
||||||
|
(hk-map-node rk rv rlr rr)))))
|
||||||
|
|
||||||
|
(define
|
||||||
|
hk-map-double-r
|
||||||
|
(fn
|
||||||
|
(k v l r)
|
||||||
|
(let
|
||||||
|
((lk (hk-map-key l))
|
||||||
|
(lv (hk-map-val l))
|
||||||
|
(ll (hk-map-left l))
|
||||||
|
(lr (hk-map-right l))
|
||||||
|
(lrk (hk-map-key (hk-map-right l)))
|
||||||
|
(lrv (hk-map-val (hk-map-right l)))
|
||||||
|
(lrl (hk-map-left (hk-map-right l)))
|
||||||
|
(lrr (hk-map-right (hk-map-right l))))
|
||||||
|
(hk-map-node
|
||||||
|
lrk
|
||||||
|
lrv
|
||||||
|
(hk-map-node lk lv ll lrl)
|
||||||
|
(hk-map-node k v lrr r)))))
|
||||||
|
|
||||||
|
;; ── Balanced node constructor ──────────────────────────────
|
||||||
|
;; Use this in place of hk-map-node when one side may have grown
|
||||||
|
;; or shrunk by one and we need to restore the weight invariant.
|
||||||
|
(define
|
||||||
|
hk-map-balance
|
||||||
|
(fn
|
||||||
|
(k v l r)
|
||||||
|
(let
|
||||||
|
((sl (hk-map-size l)) (sr (hk-map-size r)))
|
||||||
|
(cond
|
||||||
|
((<= (+ sl sr) 1) (hk-map-node k v l r))
|
||||||
|
((> sr (* hk-map-delta sl))
|
||||||
|
(let
|
||||||
|
((rl (hk-map-left r)) (rr (hk-map-right r)))
|
||||||
|
(cond
|
||||||
|
((< (hk-map-size rl) (* hk-map-gamma (hk-map-size rr)))
|
||||||
|
(hk-map-single-l k v l r))
|
||||||
|
(:else (hk-map-double-l k v l r)))))
|
||||||
|
((> sl (* hk-map-delta sr))
|
||||||
|
(let
|
||||||
|
((ll (hk-map-left l)) (lr (hk-map-right l)))
|
||||||
|
(cond
|
||||||
|
((< (hk-map-size lr) (* hk-map-gamma (hk-map-size ll)))
|
||||||
|
(hk-map-single-r k v l r))
|
||||||
|
(:else (hk-map-double-r k v l r)))))
|
||||||
|
(:else (hk-map-node k v l r))))))
|
||||||
@@ -179,7 +179,7 @@ No OCaml changes are needed. The view type is fully representable as an SX dict.
|
|||||||
|
|
||||||
### Phase 11 — Data.Map
|
### Phase 11 — Data.Map
|
||||||
|
|
||||||
- [ ] Implement a weight-balanced BST in pure SX in `lib/haskell/map.sx`.
|
- [x] Implement a weight-balanced BST in pure SX in `lib/haskell/map.sx`.
|
||||||
Internal node representation: `("Map-Node" key val left right size)`.
|
Internal node representation: `("Map-Node" key val left right size)`.
|
||||||
Leaf: `("Map-Empty")`.
|
Leaf: `("Map-Empty")`.
|
||||||
- [ ] Core operations: `empty`, `singleton`, `insert`, `lookup`, `delete`,
|
- [ ] Core operations: `empty`, `singleton`, `insert`, `lookup`, `delete`,
|
||||||
@@ -304,6 +304,13 @@ No OCaml changes are needed. The view type is fully representable as an SX dict.
|
|||||||
|
|
||||||
_Newest first._
|
_Newest first._
|
||||||
|
|
||||||
|
**2026-05-07** — Phase 11 BST skeleton in `lib/haskell/map.sx`:
|
||||||
|
- Adams-style weight-balanced tree: node = `("Map-Node" k v l r size)`,
|
||||||
|
empty = `("Map-Empty")`. delta=3 / gamma=2 ratios. Implemented constructors
|
||||||
|
+ accessors + the four rotations (single-l, single-r, double-l, double-r)
|
||||||
|
+ `hk-map-balance` smart constructor that picks the rotation. Spot-checked
|
||||||
|
with eval calls; user-facing operations (insert/lookup/etc.) come next.
|
||||||
|
|
||||||
**2026-05-07** — Phase 10 conformance: statistics.hs (5/5) + newton.hs (5/5) → Phase 10 complete:
|
**2026-05-07** — Phase 10 conformance: statistics.hs (5/5) + newton.hs (5/5) → Phase 10 complete:
|
||||||
- `program-statistics.sx`: mean / variance / stdDev on a [Double], exercising
|
- `program-statistics.sx`: mean / variance / stdDev on a [Double], exercising
|
||||||
`sum`, `map`, `fromIntegral`, `/`, `sqrt`. 5/5.
|
`sum`, `map`, `fromIntegral`, `/`, `sqrt`. 5/5.
|
||||||
|
|||||||
Reference in New Issue
Block a user