Python rewrite of the Urb/Homemaker stack
Answers "are any config requirements actively fighting the engine". One is. §39.1 NEGATIVE (recorded): no room spec in any corpus programme is internally contradictory. Using shapecurve.leaf_constraints' validated FAIL_THRESHOLD inversions, every code admits an (area, aspect) satisfying size, width, proportion and crinkliness at once, and none needs more than one exposed side. The "estimated targets are mutually unsatisfiable" hypothesis is falsified. §39.2 SEVERE: Urb's type system is prefix-based (c = circulation, o/s = outside) and programme codes share that namespace. A code starting with those letters is silently reinterpreted, with three unannounced consequences: check_space_counts SKIPS it outright (never required, no missing or too-many fail); get_space_params returns generic *_circulation/*_outside params before consulting self.spaces; and is_circulation/is_outside flip, changing value rate, crinkliness exemption, and whether it supplies daylight to neighbours. harbor-house is affected (maple-court, health-centre, programme-house are clean): cr1 "Common Room with Fireplace" has all three declared targets overridden (size 80.0 -> 0.0/14.0) and is valued at 50/m2 not 300; of x2 and st1/st2 lose width/proportion and are treated as outside space. 5 of 37 room instances (14%) are silently optional. Measured: the two cr1 leaves converged to 32.9 and 17.1 m2 against a declared 80, with no too-many-spaces fail despite count:1; of/st1/st2 are absent from the result with zero fails. Compounds with §38.2 -- the largest room in the programme sits on the wrong side of the x6 circulation value gap, so the objective is paid to shrink it. Benchmark validity: every harbor-house fail count in this document was measured against a 32-instance effective programme, not the 37 its config declares. Adds experiments/audit_programme_config.py (namespace + satisfiability reports). Filed homemaker-py-ju3 (P0). No src changes; 336 passed, same 7 pre-existing fixture failures. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MJ84Feep79Hhm3E4zZJmnB |
||
|---|---|---|
| .beads | ||
| .claude | ||
| examples | ||
| experiments | ||
| src/homemaker_layout | ||
| tests | ||
| .gitignore | ||
| AGENTS.md | ||
| CLAUDE.md | ||
| DESIGN.md | ||
| pyproject.toml | ||
| README.md | ||
homemaker-layout
Programme-driven building-layout search over slicing trees. A clean-room Python successor to the Perl Urb project, intended to eventually be 100% Python.
Why a rewrite
Urb represents a building as a binary slicing tree where room sizes are derived top-down from division ratios. That makes room area an emergent property of every cut above it, which:
- gives the genome low locality (a cut near the root rescales every descendant),
- makes target room sizes nearly impossible to hit, so the gaussian size penalty dominates fitness, and
- defeats crossover (transplanted subtrees lose their proportions).
homemaker inverts this: leaves carry target dimensions from the programme and division ratios are solved bottom-up for a fixed topology. The evolutionary search then only explores topology + types + adjacency.
Phase plan
Solver experiment: port Urb's geometry, re-solve ratios from programme targets, score the result against the original via the Perl oracle.✓Native Python fitness (retire the Perl oracle).✓Memetic search: canonical slicing genome + high-locality operators + Nelder-Mead inner loop.✓Penalty reshaping: lexicographic✓(-n_fails, fitness)outer-search comparison.Representation upgrade: canonical slicing encoding + bottom-up shape feasibility, scaled to larger programmes.✓- Search-quality experiments (current): a long running series of
opt-in levers tried against the
harbor-house,health-centre, andprogramme-houseexample corpora — leaf-sharing, finish-time cell→room collapse, ruin-and-recreate LNS, 2-opt polish, multi-use/co-located leaves, adjacency-graph and bubble-diagram fitness signals, and more. Most of these are negative/null results kept as opt-in flags or reference code rather than defaults. SeeDESIGN.md§11 onward for the full, numbered experiment log with methodology and results for each.
Layout
src/homemaker_layout/dom.py— read/write Urb.domYAML into aNodetree.src/homemaker_layout/geometry.py— faithful port of Urb's top-down geometry.src/homemaker_layout/programme.py— parsepatterns.configspace requirements.src/homemaker_layout/solver.py— bottom-up ratio solve (scipy).src/homemaker_layout/fitness.py— native Python fitness evaluator.src/homemaker_layout/fitness_cmd.py—homemaker-fitnessCLI (drop-in forurb-fitness.pl).src/homemaker_layout/collapse_cmd.py—homemaker-collapseCLI: finish-time global cell→room relabel of a.dom.src/homemaker_layout/graph.py— leaf-adjacency graph for programme-driven checks.src/homemaker_layout/genome.py— topology genome: base-floor tree + per-storey deltas.src/homemaker_layout/operators.py— high-locality mutation and subtree crossover.src/homemaker_layout/innerloop.py— ratio optimisation inner loop (Nelder-Mead / CMA-ES).src/homemaker_layout/driver.py— memetic search outer loop.src/homemaker_layout/evolve.py—homemaker-evolveCLI entry point.src/homemaker_layout/oracle.py— legacy Perl shim, kept for cross-validation only.src/homemaker_layout/bubble.py— 3D bubble-diagram adjacency fitness-signal prototype (DESIGN.md §27); validated null, not wired intofitness.py— reference only.