From 9642b21c7de3549a139dffd90935baffc5c3a0dc Mon Sep 17 00:00:00 2001 From: Sigilante Date: Mon, 13 Jul 2026 10:51:26 -0600 Subject: [PATCH] saloon: fix rtol sample mismatch in scalar transcendental dispatch +sa's scalar helpers (+trans-scalar, +fun-scalar, +fadd/+fsub/+fmul/+fdiv/ +fabs/+fgte/+flte -- ~80 call sites total) called /lib/math's rh/rs/rd/rq doors as `~(fn rX:math [rnd rtol])`, but those doors take a 3-field sample `[r rtol atol]`, not 2. Since +sa's own `rtol` field is a bare `@r` atom (not a cell), this could never type-check at any precision -- confirmed by isolating the exact call pattern in a standalone probe and by testing the unmodified file directly: saloon.hoon failed `-build-file` on its own, before any of this change, at every one of rh/rs/rd/rq (the compiler just stops at the first failure in a `?-`, so only one bloq's error surfaced per attempt, making it look narrower than it is). Fixed by supplying an explicit, width-matched zero atol (`` `@rX`0 ``) at each call site, matching /lib/math's own documented "atol: absolute tolerance floor (default 0)". tests/lib/saloon-rays.hoon's existing suite only ever exercised bloq 5 (@rs) -- the type fix is mechanically identical across all four bloqs, but to actually prove it at runtime (not just "compiles"), this adds +close-rh/rd/rq + +test-exp-rh/rd/rq spot checks at the three previously- untested widths, cross-checked against ship-computed values. Also found, NOT fixed here (separate, unrelated issues; out of scope): - tests/lib/saloon.hoon (the pre-`saloon-rays.hoon` scalar test file) is stale, testing an `rs:saloon` API that no longer exists post-refactor -- saloon-rays.hoon's own header comment already documents this split. - tests/lib/saloon-eig.hoon and saloon-eigh.hoon (GENERATED by saloon/tools/eig_check.py) hit the exact same rtol-sample bug in their own hand-rolled `~(lth rd:math [%n .~1e-10])` sort comparator -- the fix belongs in the generator script, not the generated output. - tests/lib/saloon-unum.hoon has pre-existing 1-ULP mismatches at posit32 (tan/log/exp/cos), predating this fix: the test's expected values were captured before /lib/unum's Chebyshev-basis transcendental rewrite and were never refreshed. Verified: saloon-rays/-cplx/-eig-tol/-eigh-cc all green (`ok=%.y`). Co-Authored-By: Claude Sonnet 5 --- saloon/desk/lib/saloon.hoon | 118 ++++++++++++------------- saloon/desk/tests/lib/saloon-rays.hoon | 48 ++++++++++ 2 files changed, 107 insertions(+), 59 deletions(-) diff --git a/saloon/desk/lib/saloon.hoon b/saloon/desk/lib/saloon.hoon index 69d3c31..8f8c43d 100644 --- a/saloon/desk/lib/saloon.hoon +++ b/saloon/desk/lib/saloon.hoon @@ -399,59 +399,59 @@ ?+ bloq !! %7 ?- fun - %neg ~(neg rq:math [rnd rtol]) - %factorial ~(factorial rq:math [rnd rtol]) - %exp ~(exp rq:math [rnd rtol]) - %sin ~(sin rq:math [rnd rtol]) - %cos ~(cos rq:math [rnd rtol]) - %tan ~(tan rq:math [rnd rtol]) - %log ~(log rq:math [rnd rtol]) - %log-10 ~(log-10 rq:math [rnd rtol]) - %log-2 ~(log-2 rq:math [rnd rtol]) - %sqrt ~(sqrt rq:math [rnd rtol]) - %cbrt ~(cbrt rq:math [rnd rtol]) + %neg ~(neg rq:math [rnd rtol `@rq`0]) + %factorial ~(factorial rq:math [rnd rtol `@rq`0]) + %exp ~(exp rq:math [rnd rtol `@rq`0]) + %sin ~(sin rq:math [rnd rtol `@rq`0]) + %cos ~(cos rq:math [rnd rtol `@rq`0]) + %tan ~(tan rq:math [rnd rtol `@rq`0]) + %log ~(log rq:math [rnd rtol `@rq`0]) + %log-10 ~(log-10 rq:math [rnd rtol `@rq`0]) + %log-2 ~(log-2 rq:math [rnd rtol `@rq`0]) + %sqrt ~(sqrt rq:math [rnd rtol `@rq`0]) + %cbrt ~(cbrt rq:math [rnd rtol `@rq`0]) == :: fun %6 ?- fun - %neg ~(neg rd:math [rnd rtol]) - %factorial ~(factorial rd:math [rnd rtol]) - %exp ~(exp rd:math [rnd rtol]) - %sin ~(sin rd:math [rnd rtol]) - %cos ~(cos rd:math [rnd rtol]) - %tan ~(tan rd:math [rnd rtol]) - %log ~(log rd:math [rnd rtol]) - %log-10 ~(log-10 rd:math [rnd rtol]) - %log-2 ~(log-2 rd:math [rnd rtol]) - %sqrt ~(sqrt rd:math [rnd rtol]) - %cbrt ~(cbrt rd:math [rnd rtol]) + %neg ~(neg rd:math [rnd rtol `@rd`0]) + %factorial ~(factorial rd:math [rnd rtol `@rd`0]) + %exp ~(exp rd:math [rnd rtol `@rd`0]) + %sin ~(sin rd:math [rnd rtol `@rd`0]) + %cos ~(cos rd:math [rnd rtol `@rd`0]) + %tan ~(tan rd:math [rnd rtol `@rd`0]) + %log ~(log rd:math [rnd rtol `@rd`0]) + %log-10 ~(log-10 rd:math [rnd rtol `@rd`0]) + %log-2 ~(log-2 rd:math [rnd rtol `@rd`0]) + %sqrt ~(sqrt rd:math [rnd rtol `@rd`0]) + %cbrt ~(cbrt rd:math [rnd rtol `@rd`0]) == :: fun %5 ?- fun - %neg ~(neg rs:math [rnd rtol]) - %factorial ~(factorial rs:math [rnd rtol]) - %exp ~(exp rs:math [rnd rtol]) - %sin ~(sin rs:math [rnd rtol]) - %cos ~(cos rs:math [rnd rtol]) - %tan ~(tan rs:math [rnd rtol]) - %log ~(log rs:math [rnd rtol]) - %log-10 ~(log-10 rs:math [rnd rtol]) - %log-2 ~(log-2 rs:math [rnd rtol]) - %sqrt ~(sqrt rs:math [rnd rtol]) - %cbrt ~(cbrt rs:math [rnd rtol]) + %neg ~(neg rs:math [rnd rtol `@rs`0]) + %factorial ~(factorial rs:math [rnd rtol `@rs`0]) + %exp ~(exp rs:math [rnd rtol `@rs`0]) + %sin ~(sin rs:math [rnd rtol `@rs`0]) + %cos ~(cos rs:math [rnd rtol `@rs`0]) + %tan ~(tan rs:math [rnd rtol `@rs`0]) + %log ~(log rs:math [rnd rtol `@rs`0]) + %log-10 ~(log-10 rs:math [rnd rtol `@rs`0]) + %log-2 ~(log-2 rs:math [rnd rtol `@rs`0]) + %sqrt ~(sqrt rs:math [rnd rtol `@rs`0]) + %cbrt ~(cbrt rs:math [rnd rtol `@rs`0]) == :: fun %4 ?- fun - %neg ~(neg rh:math [rnd rtol]) - %factorial ~(factorial rh:math [rnd rtol]) - %exp ~(exp rh:math [rnd rtol]) - %sin ~(sin rh:math [rnd rtol]) - %cos ~(cos rh:math [rnd rtol]) - %tan ~(tan rh:math [rnd rtol]) - %log ~(log rh:math [rnd rtol]) - %log-10 ~(log-10 rh:math [rnd rtol]) - %log-2 ~(log-2 rh:math [rnd rtol]) - %sqrt ~(sqrt rh:math [rnd rtol]) - %cbrt ~(cbrt rh:math [rnd rtol]) + %neg ~(neg rh:math [rnd rtol `@rh`0]) + %factorial ~(factorial rh:math [rnd rtol `@rh`0]) + %exp ~(exp rh:math [rnd rtol `@rh`0]) + %sin ~(sin rh:math [rnd rtol `@rh`0]) + %cos ~(cos rh:math [rnd rtol `@rh`0]) + %tan ~(tan rh:math [rnd rtol `@rh`0]) + %log ~(log rh:math [rnd rtol `@rh`0]) + %log-10 ~(log-10 rh:math [rnd rtol `@rh`0]) + %log-2 ~(log-2 rh:math [rnd rtol `@rh`0]) + %sqrt ~(sqrt rh:math [rnd rtol `@rh`0]) + %cbrt ~(cbrt rh:math [rnd rtol `@rh`0]) == :: fun == :: bloq :: @@ -496,23 +496,23 @@ ?+ bloq.meta !! %7 ?- fun - %pow-n ~(pow-n rq:math [rnd rtol]) - %pow ~(pow rq:math [rnd rtol]) + %pow-n ~(pow-n rq:math [rnd rtol `@rq`0]) + %pow ~(pow rq:math [rnd rtol `@rq`0]) == :: fun %6 ?- fun - %pow-n ~(pow-n rd:math [rnd rtol]) - %pow ~(pow rd:math [rnd rtol]) + %pow-n ~(pow-n rd:math [rnd rtol `@rd`0]) + %pow ~(pow rd:math [rnd rtol `@rd`0]) == :: fun %5 ?- fun - %pow-n ~(pow-n rs:math [rnd rtol]) - %pow ~(pow rs:math [rnd rtol]) + %pow-n ~(pow-n rs:math [rnd rtol `@rs`0]) + %pow ~(pow rs:math [rnd rtol `@rs`0]) == :: fun %4 ?- fun - %pow-n ~(pow-n rh:math [rnd rtol]) - %pow ~(pow rh:math [rnd rtol]) + %pow-n ~(pow-n rh:math [rnd rtol `@rh`0]) + %pow ~(pow rh:math [rnd rtol `@rh`0]) == :: fun == :: bloq :: posits (/lib/unum): bloq 3/4/5/6. @@ -544,13 +544,13 @@ :: 6=@rd, 7=@rq). Each takes the bloq as its first argument and operates on :: raw component atoms. :: - ++ fadd |=([b=@ x=@ y=@] ^-(@ ?:(=(4 b) (~(add rh:math [rnd rtol]) x y) ?:(=(5 b) (~(add rs:math [rnd rtol]) x y) ?:(=(6 b) (~(add rd:math [rnd rtol]) x y) (~(add rq:math [rnd rtol]) x y)))))) - ++ fsub |=([b=@ x=@ y=@] ^-(@ ?:(=(4 b) (~(sub rh:math [rnd rtol]) x y) ?:(=(5 b) (~(sub rs:math [rnd rtol]) x y) ?:(=(6 b) (~(sub rd:math [rnd rtol]) x y) (~(sub rq:math [rnd rtol]) x y)))))) - ++ fmul |=([b=@ x=@ y=@] ^-(@ ?:(=(4 b) (~(mul rh:math [rnd rtol]) x y) ?:(=(5 b) (~(mul rs:math [rnd rtol]) x y) ?:(=(6 b) (~(mul rd:math [rnd rtol]) x y) (~(mul rq:math [rnd rtol]) x y)))))) - ++ fdiv |=([b=@ x=@ y=@] ^-(@ ?:(=(4 b) (~(div rh:math [rnd rtol]) x y) ?:(=(5 b) (~(div rs:math [rnd rtol]) x y) ?:(=(6 b) (~(div rd:math [rnd rtol]) x y) (~(div rq:math [rnd rtol]) x y)))))) - ++ fabs |=([b=@ x=@] ^-(@ ?:(=(4 b) (~(abs rh:math [rnd rtol]) x) ?:(=(5 b) (~(abs rs:math [rnd rtol]) x) ?:(=(6 b) (~(abs rd:math [rnd rtol]) x) (~(abs rq:math [rnd rtol]) x)))))) - ++ fgte |=([b=@ x=@ y=@] ^-(? ?:(=(4 b) (~(gte rh:math [rnd rtol]) x y) ?:(=(5 b) (~(gte rs:math [rnd rtol]) x y) ?:(=(6 b) (~(gte rd:math [rnd rtol]) x y) (~(gte rq:math [rnd rtol]) x y)))))) - ++ flte |=([b=@ x=@ y=@] ^-(? ?:(=(4 b) (~(lte rh:math [rnd rtol]) x y) ?:(=(5 b) (~(lte rs:math [rnd rtol]) x y) ?:(=(6 b) (~(lte rd:math [rnd rtol]) x y) (~(lte rq:math [rnd rtol]) x y)))))) + ++ fadd |=([b=@ x=@ y=@] ^-(@ ?:(=(4 b) (~(add rh:math [rnd rtol `@rh`0]) x y) ?:(=(5 b) (~(add rs:math [rnd rtol `@rs`0]) x y) ?:(=(6 b) (~(add rd:math [rnd rtol `@rd`0]) x y) (~(add rq:math [rnd rtol `@rq`0]) x y)))))) + ++ fsub |=([b=@ x=@ y=@] ^-(@ ?:(=(4 b) (~(sub rh:math [rnd rtol `@rh`0]) x y) ?:(=(5 b) (~(sub rs:math [rnd rtol `@rs`0]) x y) ?:(=(6 b) (~(sub rd:math [rnd rtol `@rd`0]) x y) (~(sub rq:math [rnd rtol `@rq`0]) x y)))))) + ++ fmul |=([b=@ x=@ y=@] ^-(@ ?:(=(4 b) (~(mul rh:math [rnd rtol `@rh`0]) x y) ?:(=(5 b) (~(mul rs:math [rnd rtol `@rs`0]) x y) ?:(=(6 b) (~(mul rd:math [rnd rtol `@rd`0]) x y) (~(mul rq:math [rnd rtol `@rq`0]) x y)))))) + ++ fdiv |=([b=@ x=@ y=@] ^-(@ ?:(=(4 b) (~(div rh:math [rnd rtol `@rh`0]) x y) ?:(=(5 b) (~(div rs:math [rnd rtol `@rs`0]) x y) ?:(=(6 b) (~(div rd:math [rnd rtol `@rd`0]) x y) (~(div rq:math [rnd rtol `@rq`0]) x y)))))) + ++ fabs |=([b=@ x=@] ^-(@ ?:(=(4 b) (~(abs rh:math [rnd rtol `@rh`0]) x) ?:(=(5 b) (~(abs rs:math [rnd rtol `@rs`0]) x) ?:(=(6 b) (~(abs rd:math [rnd rtol `@rd`0]) x) (~(abs rq:math [rnd rtol `@rq`0]) x)))))) + ++ fgte |=([b=@ x=@ y=@] ^-(? ?:(=(4 b) (~(gte rh:math [rnd rtol `@rh`0]) x y) ?:(=(5 b) (~(gte rs:math [rnd rtol `@rs`0]) x y) ?:(=(6 b) (~(gte rd:math [rnd rtol `@rd`0]) x y) (~(gte rq:math [rnd rtol `@rq`0]) x y)))))) + ++ flte |=([b=@ x=@ y=@] ^-(? ?:(=(4 b) (~(lte rh:math [rnd rtol `@rh`0]) x y) ?:(=(5 b) (~(lte rs:math [rnd rtol `@rs`0]) x y) ?:(=(6 b) (~(lte rd:math [rnd rtol `@rd`0]) x y) (~(lte rq:math [rnd rtol `@rq`0]) x y)))))) ++ f0 |=(b=@ ^-(@ ?:(=(4 b) .~~0 ?:(=(5 b) .0 ?:(=(6 b) .~0 .~~~0))))) ++ f1 |=(b=@ ^-(@ ?:(=(4 b) .~~1 ?:(=(5 b) .1 ?:(=(6 b) .~1 .~~~1))))) ++ f2 |=(b=@ ^-(@ ?:(=(4 b) .~~2 ?:(=(5 b) .2 ?:(=(6 b) .~2 .~~~2))))) diff --git a/saloon/desk/tests/lib/saloon-rays.hoon b/saloon/desk/tests/lib/saloon-rays.hoon index 1e6d0b7..45fc9a2 100644 --- a/saloon/desk/tests/lib/saloon-rays.hoon +++ b/saloon/desk/tests/lib/saloon-rays.hoon @@ -31,6 +31,34 @@ |= [a=@ b=@] ^- ray:ls (en-ray:(lake %n) [[~[2] 5 %i754 ~] ~[a b]]) :: +:: ++close-rh/rd/rq + ++rh1/rd1/rq1: the same pattern as ++close-rs/++rs1 +:: above, at the other three %i754 bloqs (4=@rh, 6=@rd, 7=@rq). Added +:: alongside the saloon.hoon +sa scalar-dispatch rtol fix (rand-spec.md +:: milestone 8 prerequisite): the existing tests here only ever exercised +:: bloq 5 (@rs), so the fix's bloq 4/6/7 branches -- mechanically +:: identical, but otherwise untested at runtime -- get one spot check +:: each below (+test-exp-rh/rd/rq). +:: +++ close-rh + |= [x=ray:ls y=ray:ls] ^- ? + (all:(lake %n) (is-close:(lake %n) x y [.~~1e-2 .~~1e-2])) +++ close-rd + |= [x=ray:ls y=ray:ls] ^- ? + (all:(lake %n) (is-close:(lake %n) x y [.~1e-9 .~1e-9])) +++ close-rq + |= [x=ray:ls y=ray:ls] ^- ? + (all:(lake %n) (is-close:(lake %n) x y [.~~~1e-15 .~~~1e-15])) +:: +++ rh1 + |= [a=@] ^- ray:ls + (en-ray:(lake %n) [[~[1] 4 %i754 ~] ~[a]]) +++ rd1 + |= [a=@] ^- ray:ls + (en-ray:(lake %n) [[~[1] 6 %i754 ~] ~[a]]) +++ rq1 + |= [a=@] ^- ray:ls + (en-ray:(lake %n) [[~[1] 7 %i754 ~] ~[a]]) +:: :: Unary ops: input and expected-output rays share the same values as the :: scalar tests in saloon.hoon so the two suites cross-validate. :: @@ -111,4 +139,24 @@ =/ a (en-ray:(lake %n) [[~[3 2] 5 %i754 ~] ~[.1 .2 .3 .4 .5 .6]]) =/ res (exp:sa a) (expect !>(=(shape.meta.res ~[3 2]))) +:: +:: +test-exp-rh/rd/rq: see the ++close-rh/rd/rq header comment above. +:: +++ test-exp-rh + ^- tang + =/ a (rh1 .~~4) + =/ w (rh1 .~~54.6) + (expect !>((close-rh (exp:sa a) w))) +:: +++ test-exp-rd + ^- tang + =/ a (rd1 .~4) + =/ w (rd1 .~54.598150033144236) + (expect !>((close-rd (exp:sa a) w))) +:: +++ test-exp-rq + ^- tang + =/ a (rq1 .~~~4) + =/ w (rq1 .~~~54.59815003314423907811026120286088) + (expect !>((close-rq (exp:sa a) w))) --