From 6b1a5a99f3f694c3e2cb53efa1cbeec9811652d1 Mon Sep 17 00:00:00 2001 From: Pavel Panchekha Date: Fri, 6 Feb 2026 22:41:43 -0700 Subject: [PATCH 1/2] Fix fmin/fmax movability --- ops/core.rkt | 46 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/ops/core.rkt b/ops/core.rkt index c115ae0..4f79744 100644 --- a/ops/core.rkt +++ b/ops/core.rkt @@ -661,16 +661,46 @@ (ival (endpoint lo #f) (endpoint hi #f) err? err)) (define (ival-fmin x y) - (ival (endpoint-min2 (ival-lo x) (ival-lo y) 'down) - (endpoint-min2 (ival-hi x) (ival-hi y) 'up) - (or (ival-err? x) (ival-err? y)) - (or (ival-err x) (ival-err y)))) + (match-define (ival (endpoint xlo xlo!) (endpoint xhi xhi!) xerr? xerr) x) + (match-define (ival (endpoint ylo ylo!) (endpoint yhi yhi!) yerr? yerr) y) + (define lo (bf 0)) + (define hi (bf 0)) + (define lo-exact? (= 0 (mpfr-min! lo xlo ylo 'down))) + (define hi-exact? (= 0 (mpfr-min! hi xhi yhi 'up))) + ;; For lower endpoints (which can only move upward under refinement), + ;; a fixed minimum is stable if one fixed endpoint is <= the other. + (define lo-stable? + (cond + [(and xlo! ylo!) #t] + [xlo! (bflte? xlo ylo)] + [ylo! (bflte? ylo xlo)] + [else #f])) + (define lo! (and lo-exact? lo-stable?)) + ;; For upper endpoints (which can only move downward), a fixed minimum is + ;; only guaranteed when both endpoints are fixed. + (define hi! (and hi-exact? xhi! yhi!)) + (ival (endpoint lo lo!) (endpoint hi hi!) (or xerr? yerr?) (or xerr yerr))) (define (ival-fmax x y) - (ival (endpoint-max2 (ival-lo x) (ival-lo y) 'down) - (endpoint-max2 (ival-hi x) (ival-hi y) 'up) - (or (ival-err? x) (ival-err? y)) - (or (ival-err x) (ival-err y)))) + (match-define (ival (endpoint xlo xlo!) (endpoint xhi xhi!) xerr? xerr) x) + (match-define (ival (endpoint ylo ylo!) (endpoint yhi yhi!) yerr? yerr) y) + (define lo (bf 0)) + (define hi (bf 0)) + (define lo-exact? (= 0 (mpfr-max! lo xlo ylo 'down))) + (define hi-exact? (= 0 (mpfr-max! hi xhi yhi 'up))) + ;; For lower endpoints (which can only move upward), a fixed maximum is + ;; only guaranteed when both endpoints are fixed. + (define lo! (and lo-exact? xlo! ylo!)) + ;; For upper endpoints (which can only move downward), a fixed maximum is + ;; stable if one fixed endpoint is >= the other. + (define hi-stable? + (cond + [(and xhi! yhi!) #t] + [xhi! (bfgte? xhi yhi)] + [yhi! (bfgte? yhi xhi)] + [else #f])) + (define hi! (and hi-exact? hi-stable?)) + (ival (endpoint lo lo!) (endpoint hi hi!) (or xerr? yerr?) (or xerr yerr))) (define (ival-copysign x y) (match-define (ival xlo xhi xerr? xerr) (ival-fabs x)) From 907d03a8a7729509d2a8cc1086abe794f929d686 Mon Sep 17 00:00:00 2001 From: Pavel Panchekha Date: Fri, 6 Feb 2026 22:48:20 -0700 Subject: [PATCH 2/2] Fix movability flags for pow that straddles zero --- ops/core.rkt | 1 + ops/pow.rkt | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ops/core.rkt b/ops/core.rkt index 4f79744..b85e174 100644 --- a/ops/core.rkt +++ b/ops/core.rkt @@ -105,6 +105,7 @@ ival-== ival-!= ival-if + ival-mobilize ival-and ival-or ival-not diff --git a/ops/pow.rkt b/ops/pow.rkt index 9c768ee..fa4b5fb 100644 --- a/ops/pow.rkt +++ b/ops/pow.rkt @@ -161,4 +161,9 @@ [(or (= (mpfr-sign (ival-lo-val x)) 1) (bfzero? (ival-lo-val x))) (ival-pow-pos x y)] [else (define-values (neg pos) (split-ival x 0.bf)) - (ival-union (ival-pow-neg neg y) (ival-pow-pos pos y))])) + (define out (ival-union (ival-pow-neg neg y) (ival-pow-pos pos y))) + ;; If x straddles 0 with movable endpoints, a refinement can drop one + ;; branch entirely, so branch-derived endpoint fixedness is not stable. + (if (and (ival-lo-fixed? x) (ival-hi-fixed? x)) + out + (ival-mobilize out))]))