832375f2ac
All 176 files in the four accumulating directories now use a zero-padded 4-digit counter prefix that reflects creation order (`NNNN-slug.md`). The counter is assigned per directory in strict git-log creation order; ties broken alphabetically by original name. The old `YYYY-MM-DD-` prefix on docs/specs/ and docs/plans/ files is dropped — the date is recoverable from git log and the counter carries the ordering. A file's counter is stable for the life of the file: never reassigned, never reused, never compacted. Deleted files retire their counter; subsequent files do not fill the gap. This is the property that lets cross-references stay literal — refs use the full filename including the counter (`design/contracts/0007-honesty-rule.md`) so they grep cleanly and resolve directly without a glob step. 313 cross-references updated across .md/.rs/.toml/.c/.json files (test pins, include_str! paths, design-INDEX entries, baseline notes, runtime C comments, inter-contract markdown links incl. bare basename and `../models/foo.md` forms). CLAUDE.md gets a new "File-naming convention" section spelling out the rule and rationale. skills/brainstorm/SKILL.md and skills/planner/SKILL.md updated so new spec/plan creation produces counter-prefixed names from the start. The full test suite (cargo test --workspace) passes.
56 lines
1.9 KiB
Plaintext
56 lines
1.9 KiB
Plaintext
; Fieldtest — Floats milestone, axis 3: NaN / Inf / is_nan handling.
|
|
;
|
|
; safe_div(a, b) returns a/b when b != 0; falls through to the IEEE
|
|
; result otherwise. The fixture exercises four cases:
|
|
; 1) 6.0 / 3.0 -> 2.0 (normal)
|
|
; 2) 1.0 / 0.0 -> +inf (use is_nan to confirm finite-vs-NaN)
|
|
; 3) 0.0 / 0.0 -> NaN (is_nan should report true)
|
|
; 4) (- 1.0 1.0) / 0.0 -> NaN (subexpr drives same)
|
|
;
|
|
; classify(x) returns:
|
|
; -1 if x is NaN
|
|
; 0 if x is +inf or -inf (we test via x > <huge> / x < -<huge>)
|
|
; 1 otherwise
|
|
;
|
|
; The subtle point: the IEEE-correct way to test for NaN is `is_nan`,
|
|
; NOT `(== x x)` (which is false for NaN — but the LLM author who
|
|
; reaches for `==` first will get the right answer by accident here,
|
|
; only because the natural reading of the operator doesn't apply).
|
|
; design/contracts/0005-float-semantics.md says explicitly to use `is_nan`.
|
|
;
|
|
; Expected stdout (one per line):
|
|
; 2.0 ; 6/3
|
|
; 1 ; classify(2.0) -> normal
|
|
; inf ; 1/0
|
|
; 0 ; classify(1/0) -> infinite
|
|
; nan ; 0/0
|
|
; -1 ; classify(0/0) -> NaN
|
|
;
|
|
; (`print` for Float routes through `float_to_str`, which uses "%g", so inf prints as "inf", NaN as "nan".)
|
|
|
|
(module floats_3_safe_division
|
|
|
|
(fn classify
|
|
(doc "-1=NaN, 0=infinite, 1=finite. Uses is_nan + abs > huge.")
|
|
(type (fn-type (params (con Float)) (ret (con Int))))
|
|
(params x)
|
|
(body
|
|
(if (app is_nan x)
|
|
-1
|
|
(if (app float_gt x 1.0e308)
|
|
0
|
|
(if (app float_lt x -1.0e308)
|
|
0
|
|
1)))))
|
|
|
|
(fn main
|
|
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
|
(params)
|
|
(body
|
|
(seq (app print (app / 6.0 3.0))
|
|
(seq (app print (app classify (app / 6.0 3.0)))
|
|
(seq (app print (app / 1.0 0.0))
|
|
(seq (app print (app classify (app / 1.0 0.0)))
|
|
(seq (app print (app / 0.0 0.0))
|
|
(app print (app classify (app / 0.0 0.0)))))))))))
|