23
29evalNode(Op, P, Is, R) :-
30 g_inc('$clpBNR:evalNode'), 31 narrowing_op(Op, P, Is, R),
32 !.
33evalNode(_Op, _, _, _):-
34 g_inc('$clpBNR:evalNodeFail'), 35 debugging(clpBNR), 36 current_node_(C),
37 debug_clpBNR_("** fail ** ~w.",C),
38 fail.
39
40sandbox:safe_global_variable('$clpBNR:evalNode').
41sandbox:safe_global_variable('$clpBNR:evalNodeFail').
42
43clpStatistics :-
44 g_assign('$clpBNR:evalNode',0),
45 g_assign('$clpBNR:evalNodeFail',0),
46 fail. 47
48clpStatistic(narrowingOps(C)) :- g_read('$clpBNR:evalNode',C).
49
50clpStatistic(narrowingFails(C)) :- g_read('$clpBNR:evalNodeFail',C).
51
55clpStatistics :-
56 57 findall(Op-0,(clause(clpBNR:narrowing_op(Op,_,_,_),_),atom(Op)),Data),
58 dict_create(Dict,'$clpBNR:ops_dict',Data),
59 g_assign('$clpBNR:ops_dict',Dict),
60 fail. 61
62clpStatistic(opCounts(Cs)) :- 63 g_read('$clpBNR:ops_dict',Dict),
64 dict_pairs(Dict,'$clpBNR:ops_dict',Raw),
65 exclude_zeros(Raw,Cs). 66
67exclude_zeros([],[]).
68exclude_zeros([_-0|Raw],Cs) :- !, exclude_zeros(Raw,Cs).
69exclude_zeros([C|Raw],[C|Cs]) :- exclude_zeros(Raw,Cs).
70
72counts_clpBNR(Bool) :- 73 ( current_predicate_wrapper(clpBNR:evalNode(_Op, _P, _Is, _R),
74 'clpBNR:evalNode', _Wrapped, _Body)
75 -> Bool = true ; Bool = false
76 ),
77 !.
78counts_clpBNR(true) :- 79 wrap_predicate(clpBNR:evalNode(Op, _P, _Is, _R),
80 'clpBNR:evalNode',
81 Wrapped, evalNode_wrap_(Wrapped, Op)).
82counts_clpBNR(false) :- 83 unwrap_predicate(clpBNR:evalNode/4, 84 'clpBNR:evalNode').
85
86evalNode_wrap_(Wrapped, Op) :-
87 88 g_read('$clpBNR:ops_dict',Dict),
89 get_dict(Op,Dict,N), N1 is N+1, nb_link_dict(Op,Dict,N1),
90 Wrapped. 91
92sandbox:safe_global_variable('$clpBNR:ops_dict').
93
97goal_expansion(non_empty(L,H), 1 =\= cmpr(L,H)). 98
99non_empty((L,H)) :- non_empty(L,H).
100non_empty(L,H) :- 1 =\= cmpr(L,H).
101
105intCase(C, (L,H)) :-
106 ( L>=0 -> C=p 107 ; H=<0 -> C=n 108 ; C=s 109 ).
110
114^((Xl,Xh), (Yl,Yh), (Zl,Zh)) :-
115 Zl is maxr(Xl, Yl), Zh is minr(Xh, Yh), 116 non_empty(Zl,Zh).
117
121union_((Xl,Xh),(Yl,Yh),(Zl,Zh)) :-
122 Zl is minr(Xl,Yl), Zh is maxr(Xh,Yh). 123
127int_contains((Xl,Xh),(Yl,Yh)) :-
128 Xl is minr(Xl,Yl), Xh is maxr(Xh,Yh).
129
135to_float((L,H),(FL,FH)) :-
136 ( float(L) -> FL = L ; FL is roundtoward(float(L), to_negative) ),
137 ( float(H) -> FH = H ; FH is roundtoward(float(H), to_positive) ).
138
143:- discontiguous clpBNR:narrowing_op/4. 144:- style_check(-singleton). 147
149
150narrowing_op(integral, P, $(X), $(NewX)) :-
151 integral_(X,NewX).
152
153integral_((Xl,Xh),(NXl,NXh)) :-
154 NXl is ceiling(Xl), NXh is floor(Xh),
155 non_empty(NXl,NXh).
156
158
162
163narrowing_op(int, P, $(Z,X), $(NewZ,NewX)) :-
164 int_(Z,X,P,NewZ,NewX).
165
166int_(Z,X,p,NewZ,X) :- 167 X = (Xl,Xh),
168 (0 is cmpr(Xl,Xh) 169 -> (0 is cmpr(Xl,integer(Xl)) -> B = 1 ; B = 0) 170 ; ceiling(Xl) > floor(Xh), 171 B = 0
172 ),
173 !, 174 ^(Z,(B,B),NewZ).
175
176int_(Z,X,P,NewZ,NewX) :- 177 (Z = (1,1)
178 -> integral_(X,NewX), 179 (NewX = (N,N) -> P=p ; true), 180 NewZ = Z
181 ; NewX = X, 182 ^(Z,(0,1),NewZ) 183 ).
184
189narrowing_op(sgn, P, $(Z,X), $((NZl,NZh),NewX)) :-
190 X = (Xl,Xh),
191 SXl is cmpr(Xl,0), SXh is cmpr(Xh,0),
192 ^(Z,(SXl,SXh),(NZl,NZh)),
193 (NZl >= 0 -> ^(X, (0,1.0Inf), X1) ; X1=X),
194 (NZh =< 0 -> ^(X1,(-1.0Inf,0),NewX) ; NewX = X1),
195 (NZl == NZh -> P=p ; true). 196
198
200
201narrowing_op(eq, P, $(Z,X,Y), Out) :-
202 (^(X,Y,New) 203 -> (Z = (1,1)
204 -> Out = $(Z,New,New),
205 New = (L,H),
206 (0 is cmpr(L,H) -> P = p ; true) 207 ; 208 ( X = (Xl,Xh), Y = (Yl,Yh),
209 0 is cmpr(Xl,Xh) \/ cmpr(Yl,Yh) \/ cmpr(Xl,Yl) 210 -> ^(Z,(1,1),NewZ), 211 P = p 212 ; ^(Z,(0,1),NewZ) 213 ),
214 Out = $(NewZ,X,Y)
215 )
216 ; 217 ^(Z, (0,0), NewZ), 218 Out = $(NewZ,X,Y), P = p 219 ).
220
222
224
225narrowing_op(ne, P, $(Z,X,Y), Out) :-
226 (^(X,Y,(L,H))
227 -> (Z = (1,1)
228 -> ne_int_(X,Y,NewX), 229 ne_int_(Y,NewX,NewY), 230 Out = $(Z,NewX,NewY)
231 ; (X = Y, L = H -> B = (0,0), P = p ; B = (0,1)),
232 ^(Z,B,NewZ),
233 Out = $(NewZ,X,Y)
234 )
235 ; 236 ^(Z, (1,1), NewZ), 237 P = p, 238 Out = $(NewZ,X,Y)
239 ).
240
243ne_int_((X,H), (X,X), (NewL,H)) :- !, 244 NewL is X+1, NewL=<H.
245ne_int_((L,X), (X,X), (L,NewH)) :- !, 246 NewH is X-1, L=<NewH.
247ne_int_(Y, _X, Y). 248
250
252
253narrowing_op(le, P, $(Z, X, Y), Out) :-
254 X = (Xl,Xh), Y = (Yl,Yh),
255 (non_empty(Xh,Yl) 256 -> ^(Z,(1,1),NewZ), P = p, Out = $(NewZ,X,Y) 257 ; (-1 is cmpr(Yh,Xl) 258 -> ^(Z,(0,0),NewZ), P = p, Out = $(NewZ,X,Y) 259 ; le_int_(Z,Xl,Xh,Yl,Yh,P,Out) 260 )
261 ).
262
263le_int_((1,1),Xl,Xh,Yl,Yh,P,$((1,1),(Xl,NXh),(NYl,Yh))) :- !, 264 NXh is minr(Xh,Yh), 265 NYl is maxr(Xl,Yl), 266 (non_empty(NXh,NYl) -> P=p ; true). 267le_int_(Z,Xl,Xh,Yl,Yh,P,$(NewZ,NewX,NewY)) :- !,
268 (Z = (0,0)
269 -> le_int_((1,1),Yl,Yh,Xl,Xh,P,$(_,NewY,NewX)), 270 NewZ = Z
271 ; NewX = (Xl,Xh), NewY = (Yl,Yh), 272 ^(Z,(0,1),NewZ) 273 ).
274
276
278
279narrowing_op(lt, P, $(Z, X, Y), Out) :-
280 X = (Xl,Xh), Y = (Yl,Yh),
281 (-1 is cmpr(Xh,Yl) 282 -> ^(Z,(1,1),NewZ), P = p, Out = $(NewZ,X,Y) 283 ; (1 =\= cmpr(Yh,Xl) 284 -> ^(Z,(0,0),NewZ), P = p, Out = $(NewZ,X,Y) 285 ; lt_int_(Z,Xl,Xh,Yl,Yh,P,Out) 286 )
287 ).
288
289lt_int_((1,1),Xl,Xh,Yl,Yh,P,$((1,1),(Xl,NXh),(NYl,Yh))) :- !, 290 next_lt_(Yh,-1,YhD), 291 NXh is minr(Xh,YhD), 292 next_lt_(Xl,1,XlU), 293 NYl is maxr(XlU,Yl), 294 (non_empty(NXh,NYl) -> P=p ; true). 295lt_int_(Z,Xl,Xh,Yl,Yh,P,$(NewZ,NewX,NewY)) :- !,
296 (Z = (0,0)
297 -> lt_int_((1,1),Yl,Yh,Xl,Xh,P,$(_,NewY,NewX)), 298 NewZ = Z
299 ; NewX = (Xl,Xh), NewY = (Yl,Yh), 300 ^(Z,(0,1),NewZ) 301 ).
302
305next_lt_( 1.0Inf, _, 1.0Inf) :- !.
306next_lt_(-1.0Inf, _, -1.0Inf) :- !.
307next_lt_(V, -1, NV) :- NV is maxr(V-1,nexttoward(V,-1.0Inf)). 308next_lt_(V, 1, NV) :- NV is minr(V+1,nexttoward(V, 1.0Inf)).
309
311
313
314narrowing_op(in, P, $(Z, X, Y), $(NewZ, NewX, Y)):-
315 316 (^(X,Y,X1) 317 -> (Z = (1,1)
318 -> NewX = X1 319 ; NewX = X, 320 ^(Z,(0,1),NewZ) 321 )
322 ; ^(Z,(0,0),NewZ), 323 NewX = X, 324 P=p 325 ).
326
328
330
331narrowing_op(add, _, $((Zl,Zh), (Xl,Xh), (Yl,Yh)), $((NZl,NZh), (NXl,NXh), (NYl,NYh))) :-
332 NZl is maxr(Zl, roundtoward( Xl+Yl, to_negative)), 333 NZh is minr(Zh, roundtoward( Xh+Yh, to_positive)),
334 non_empty(NZl,NZh),
335 336 337 NXl is maxr(Xl, roundtoward(NZl+(-Yh), to_negative)), 338 NXh is minr(Xh, roundtoward(NZh+(-Yl), to_positive)),
339 non_empty(NXl,NXh),
340 NYl is maxr(Yl, roundtoward(NZl+(-NXh), to_negative)), 341 NYh is minr(Yh, roundtoward(NZh+(-NXl), to_positive)),
342 non_empty(NYl,NYh).
343
345
347
348narrowing_op(mul, P, $(Z,X,Y), $(NewZ, NewX, NewY)) :-
349 intCase(Cx,X),
350 intCase(Cy,Y),
351 multCase(Cx,Cy,X,Y,Z1), ^(Z,Z1,NewZ), 352 353 354 355 (int_contains(Z,Z1)
356 -> NewX = X, NewY = Y
357 ;
358 intCase(CNz,NewZ),
359 odivCase(CNz,Cx,NewZ,X,Y,Yp), 360 intCase(Cyp,Yp),
361 odivCase(CNz,Cyp,NewZ,Yp,X,NewX), 362 363 (Y == Yp, X \== NewX 364 -> intCase(CNx,NewX),
365 odivCase(CNz,CNx,NewZ,NewX,Y,NewY) 366 ; NewY = Yp,
367 ( ((zero_int(NewX), finite_int(NewY)) ; (zero_int(NewY), finite_int(NewX)))
368 -> P=p 369 ; true
370 )
371 )
372 )
372.
382
390multCase(p,p, (Xl,Xh), (Yl,Yh), (NZl,NZh)):-
391 NZl is roundtoward(Xl*Yl,to_negative),
392 NZh is roundtoward(Xh*Yh,to_positive).
393multCase(p,n, (Xl,Xh), (Yl,Yh), (NZl,NZh)):-
394 NZl is -roundtoward(Xh * -Yl,to_positive),
395 NZh is -roundtoward(Xl * -Yh,to_negative).
396multCase(n,p, (Xl,Xh), (Yl,Yh), (NZl,NZh)):-
397 NZl is -roundtoward(-Xl * Yh,to_positive),
398 NZh is -roundtoward(-Xh * Yl,to_negative).
399multCase(n,n, (Xl,Xh), (Yl,Yh), (NZl,NZh)):-
400 NZl is roundtoward(-Xh * -Yh,to_negative), 401 NZh is roundtoward(-Xl * -Yl,to_positive).
402
403multCase(p,s, (Xl,Xh), (Yl,Yh), (NZl,NZh)):-
404 NZl is -roundtoward(Xh * -Yl,to_positive),
405 NZh is roundtoward(Xh * Yh,to_positive).
406multCase(n,s, (Xl,Xh), (Yl,Yh), (NZl,NZh)):-
407 NZl is -roundtoward(-Xl * Yh,to_positive),
408 NZh is roundtoward(-Xl * -Yl,to_positive).
409multCase(s,p, (Xl,Xh), (Yl,Yh), (NZl,NZh)):-
410 NZl is -roundtoward(-Xl * Yh,to_positive),
411 NZh is roundtoward( Xh * Yh,to_positive).
412multCase(s,n, (Xl,Xh), (Yl,Yh), (NZl,NZh)):-
413 NZl is -roundtoward( Xh * -Yl,to_positive),
414 NZh is roundtoward(-Xl * -Yl,to_positive).
415
416multCase(s,s, (Xl,Xh), (Yl,Yh), (NZl,NZh)):-
417 NZl is minr(-roundtoward( Xl * -Yh,to_positive),-roundtoward(-Xh * Yl,to_positive)),
418 NZh is maxr( roundtoward(-Xl * -Yl,to_positive), roundtoward( Xh * Yh,to_positive)).
419
426
427odivCase(p,p, (Xl,Xh), (Yl,Yh), (Zl,Zh), (NZl,NZh)) :-
428 sign(Yl)+sign(Xl) > 0 429 -> NZl is maxr(Zl,roundtoward(Xl/Yh,to_negative)),
430 NZh is minr(Zh,roundtoward(Xh/max(0.0,Yl),to_positive)),
431 non_empty(NZl,NZh)
432 ; NZl = Zl, NZh = Zh.
433odivCase(p,n, (Xl,Xh), (Yl,Yh), (Zl,Zh), (NZl,NZh)) :-
434 sign(Xl)-sign(Yh) > 0 435 -> NZl is maxr(Zl,roundtoward(-Xh / -min(-0.0,Yh),to_negative)), 436 NZh is minr(Zh,roundtoward(-Xl / -Yl ,to_positive)),
437 non_empty(NZl,NZh)
438 ; NZl = Zl, NZh = Zh.
439odivCase(p,s, (Xl,Xh), (Yl,Yh), (Zl,Zh), (NZl,NZh)) :-
440 Xl > 0 441 -> ZIh is roundtoward(Xl/Yh,to_negative), 442 ZIl is roundtoward(Xl/Yl,to_positive), 443 ( 1 is cmpr(Zl,ZIl) -> NZl is maxr(Zl,ZIh) ; NZl = Zl), 444 (-1 is cmpr(Zh,ZIh) -> NZh is minr(Zh,ZIl) ; NZh = Zh), 445 non_empty(NZl,NZh)
446 ; NZl = Zl, NZh = Zh.
447
448odivCase(n,p, (Xl,Xh), (Yl,Yh), (Zl,Zh), (NZl,NZh)):-
449 sign(Yl)-sign(Xh) > 0 450 -> NZl is maxr(Zl,roundtoward(-Xl / -max(0.0,Yl),to_negative)), 451 NZh is minr(Zh,roundtoward(-Xh / -max(0.0,Yh),to_positive)),
452 non_empty(NZl,NZh)
453 ; NZl = Zl, NZh = Zh.
454odivCase(n,n, (Xl,Xh), (Yl,Yh), (Zl,Zh), (NZl,NZh)) :-
455 sign(Yh)+sign(Xh) < 0 456 -> NZl is maxr(Zl,roundtoward(Xh/Yl,to_negative)),
457 NZh is minr(Zh,roundtoward(Xl/min(-0.0,Yh),to_positive)), 458 non_empty(NZl,NZh)
459 ; NZl = Zl, NZh = Zh.
460odivCase(n,s, (Xl,Xh), (Yl,Yh), (Zl,Zh), (NZl,NZh)) :-
461 Xh < 0 462 -> ZIh is roundtoward( Xh / Yl,to_negative), 463 ZIl is roundtoward(-Xh / -Yh,to_positive), 464 ( 1 is cmpr(Zl,ZIh) -> NZl is maxr(Zl,ZIl) ; NZl = Zl), 465 (-1 is cmpr(Zh,ZIl) -> NZh is minr(Zh,ZIh) ; NZh = Zh), 466 non_empty(NZl,NZh)
467 ; NZl = Zl, NZh = Zh.
468
469odivCase(s,p, (Xl,Xh), (Yl,Yh), (Zl,Zh), (NZl,NZh)) :-
470 Yl > 0 471 -> NZl is maxr(Zl,roundtoward(-Xl / -Yl,to_negative)),
472 NZh is minr(Zh,roundtoward( Xh / Yl,to_positive)),
473 non_empty(NZl,NZh)
474 ; NZl = Zl, NZh = Zh.
475odivCase(s,n, (Xl,Xh), (Yl,Yh), (Zl,Zh), (NZl,NZh)) :-
476 Yh < 0 477 -> NZl is maxr(Zl,roundtoward(Xh/Yh,to_negative)),
478 NZh is minr(Zh,roundtoward(Xl/Yh,to_positive)),
479 non_empty(NZl,NZh)
480 ; NZl = Zl, NZh = Zh.
481
482odivCase(s,s, _, _, Z, Z). 483
485
487
488narrowing_op(min, _, $((Zl,Zh),(Xl,Xh),(Yl,Yh)), New) :-
489 Z1l is maxr(Zl,minr(Xl,Yl)), 490 Z1h is minr(Zh,minr(Xh,Yh)),
491 minimax((Zl,1.0Inf), (Z1l,Z1h),(Xl,Xh),(Yl,Yh), New).
492
493narrowing_op(max, _, $((Zl,Zh),(Xl,Xh),(Yl,Yh)), New) :-
494 Z1l is maxr(Zl,maxr(Xl,Yl)), 495 Z1h is minr(Zh,maxr(Xh,Yh)),
496 minimax((-1.0Inf,Zh), (Z1l,Z1h),(Xl,Xh),(Yl,Yh), New).
497
498minimax(_, Z1,X,Y, NewXYZ) :- 499 \+(^(Z1,X,_)), !, 500 NewXYZ = $(New, X, New),
501 ^(Y,Z1,New). 502
503minimax(_, Z1,X,Y, NewXYZ) :- 504 \+(^(Z1,Y,_)), !, 505 NewXYZ = $(New, New, Y),
506 ^(X,Z1,New). 507
508minimax(Zpartial, Z1,X,Y, $(Z1, NewX, NewY)) :- 509 ^(X,Zpartial,NewX), 510 ^(Y,Zpartial,NewY). 511
513
515
516narrowing_op(abs, _, $(Z,X), $(NewZ, NewX)) :-
517 intCase(Cx,X),
518 absCase(Cx,X,Z,NewZ), !,
519 non_empty(NewZ),
520 intersect_regions_(X,NewZ,NewX),
521 non_empty(NewX).
522
526intersect_regions_(Z,X,NewZ) :-
527 (^(Z,X,ZPos) -> true ; empty_interval(ZPos)), 528 (-(X,Z,ZNeg) -> true ; empty_interval(ZNeg)), 529 union_(ZPos,ZNeg,NewZ).
530
532-((Xl,Xh), (Zl,Zh), (NZl,NZh)) :-
533 NZl is maxr(Zl,-Xh), NZh is minr(Zh,-Xl),
534 non_empty(NZl,NZh).
535
539absCase(p, (Xl,Xh), (Zl,Zh), (NZl,NZh)) :- NZl is maxr(Zl,Xl), NZh is minr(Zh,Xh).
540absCase(n, (Xl,Xh), (Zl,Zh), (NZl,NZh)) :- NZl is maxr(Zl,-Xh), NZh is minr(Zh,-Xl).
541absCase(s, (Xl,Xh), (Zl,Zh), (NZl,NZh)) :- NZl is maxr(Zl,0), NZh is minr(Zh,maxr(-Xl,Xh)).
542
544
546
547narrowing_op(minus, _, $((Zl,Zh),(Xl,Xh)), $((NZl,NZh),(NXl,NXh))) :-
548 NZl is maxr(Zl,-Xh), NZh is minr(Zh,-Xl), 549 NXl is maxr(Xl,-NZh), NXh is minr(Xh,-NZl). 550
552
554
555narrowing_op(sqrt, _, $((Zl,Zh),(Xl,Xh)), $((NZl,NZh),(NXl,NXh))) :-
556 Xh>=0, Xl1 is maxr(0,Xl), 557 NZl is maxr(maxr(0,Zl),roundtoward(sqrt(Xl1),to_negative)),
558 NZh is minr(Zh,roundtoward(sqrt(Xh),to_positive)),
559 non_empty(NZl,NZh),
560 NXh is minr(Xh,roundtoward(NZh*NZh,to_positive)),
561 NXl is maxr(Xl,-NXh),
562 non_empty(NXl,NXh).
563
565
567
568narrowing_op(exp, _, $((Zl,Zh),(Xl,Xh)), $((NZl,NZh),(NXl,NXh))) :-
569 NZl is maxr(Zl,roundtoward(exp(Xl),to_negative)),
570 NZh is minr(Zh,roundtoward(exp(Xh),to_positive)),
571 non_empty(NZl,NZh),
572 NXl is maxr(Xl,roundtoward(log(NZl),to_negative)),
573 NXh is minr(Xh,roundtoward(log(NZh),to_positive)),
574 non_empty(NXl,NXh).
575
577
579
580narrowing_op(pow, P, $(Z,X,Y), $(NewZ,NewX,NewY)) :-
581 powr_(P, Z,X,Y, NewZ,NewX,NewY).
582
583powr_(p, Z,X,Y, NewZ,NewX,NewY) :- 584 Z = (Zl,Zh), X = (Xl,Xh), Y = (Yl,Yh),
585 ( equals_one(Xl), equals_one(Xh) -> 586 !, ^(Z,(1,1),NewZ), NewX = X, NewY = Y 587 ; equals_one(Zl), equals_one(Zh) -> 588 ((Xl =< -1,-1 =< Xh ; Xl =< 1,1 =< Xh)
589 -> fail 590 ; !, NewZ = Z, NewX = X, ^(Y,(0,0),NewY) 591 )
592 ; equals_zero(Yl), equals_zero(Yh) -> 593 !, ^(Z,(1,1),NewZ), NewX = X, NewY = Y 594 ).
595
596powr_(_, Z,X,(R,R), NewZ,NewX,NewY) :- rational(R,N,D), !, 597 N1 is N mod 2, D1 is D rem 2, 598 pt_powrCase(N1,D1,Z,X,R,NewZ), non_empty(NewZ),
599 Ri is 1/R,
600 pt_powrCase(D1,N1,X,NewZ,Ri,NewX), non_empty(NewX),
601 NewY = (R,R).
602
603powr_(_, Z,X,Y, NewZ,NewX,NewY) :- 604 intCase(C,X),
605 powr_intY_(C, Z,X,Y, NewZ,NewX,NewY).
606
607equals_zero(0).
608equals_zero(0.0).
609equals_zero(-0.0).
610
611equals_one(1).
612equals_one(1.0).
613
615pt_powrCase(N1,D1,Z,X,R,NewZ) :- R < 0, !, 616 Rp is -R,
617 universal_interval(UI),
618 intCase(Cz,Z),
619 odivCase(p,Cz,(1,1),Z,UI,Zi), 620 pt_powrCase(N1,D1,Zi,X,Rp,NZi),
621 intCase(CNzi,NZi),
622 odivCase(p,CNzi,(1,1),NZi,Z,NewZ). 623
624pt_powrCase(1,0,(Zl,Zh),(Xl,Xh),R,(NZl,NZh)) :- 625 626 Xh >=0, 627 Zl1 is maxr(0, roundtoward(Xl**R,to_negative)), 628 Zh1 is roundtoward(Xh**R,to_positive),
629 Zpl is maxr(Zl,Zl1), Zph is minr(Zh,Zh1), 630 Znl is maxr(Zl,-Zh1), Znh is minr(Zh,-Zl1), 631 ( 1 is cmpr(Znl,Znh) -> NZl is Zpl, NZh is Zph 632 ; 1 is cmpr(Zpl,Zph) -> NZl is Znl, NZh is Znh 633 ; NZl is minr(Zpl,Znl), NZh is maxr(Zph,Znh) 634 ).
635
636pt_powrCase(0,1,(Zl,Zh),(Xl,Xh),R,(NZl,NZh)) :- 637 638 ( Xh < 0 -> Xl1 is -Xh, Xh1 is -Xl 639 ;(Xl > 0 -> Xl1 = Xl, Xh1 = Xh 640 ; Xl1 = 0, Xh1 is maxr(-Xl,Xh) 641 )),
642 643 NZl is maxr(Zl, roundtoward(Xl1**R,to_negative)), 644 NZh is minr(Zh, roundtoward(Xh1**R,to_positive)).
645
646pt_powrCase(1,1,(Zl,Zh),(Xl,Xh),R,(NZl,NZh)) :- 647 648 NZl is maxr(Zl, roundtoward(Xl**R,to_negative)),
649 NZh is minr(Zh, roundtoward(Xh**R,to_positive)).
650
652powr_intY_(p, Z,X,Y, NewZ,NewX,NewY) :- 653 powr_prim_(Z,X,Y,NewZ), 654 universal_interval(UI),
655 intCase(Cy,Y),
656 odivCase(p,Cy,(1,1),Y,UI,Yi), 657 powr_prim_(X,NewZ,Yi,NewX), 658 ln(NewZ,Ynum), intCase(Cyn,Ynum),
659 ln(NewX,Yden), intCase(Cyd,Yden),
660 odivCase(Cyn,Cyd,Ynum,Yden,Y,NewY). 661
662powr_intY_(n, Z,X,Y, NewZ,NewX,NewY) :- 663 664 665 666 667 X = (Xl,Xh), X1l is -Xh, X1h is -Xl,
668 powr_intY_(p, Z,(X1l,X1h),Y, (_,Z1h),(X2l,X2h),NewY), 669 X3l is -X2h, X3h is -X2l, ^(X,(X3l,X3h),NewX), 670 Z1l is -Z1h, ^(Z,(Z1l,Z1h),NewZ). 671
672powr_intY_(s, Z,X,Y, NewZ,NewX,NewY):- 673 674 X = (Xl,Xh), Xfl is -Xl, 675 powr_intY_(p, Z,(0,Xfl),Y, (_,Znh),NXn,NYn), 676 powr_intY_(p, Z,(0,Xh), Y, (_,Zph),NXp,NYp), 677 678 NZl is -Znh, NZh is maxr(Znh,Zph), ^(Z,(NZl,NZh),NewZ),
679 union_(NXn,NXp,NX), ^(X,NX,NewX),
680 union_(NYn,NYp,NY), ^(Y,NY,NewY).
681
682powr_prim_((Zl,Zh), (Xl,Xh), (Yl,Yh), NewZ) :- 683 Zll is roundtoward(Xl**Yl,to_negative),
684 Zlh is roundtoward(Xl**Yh,to_positive),
685 Zhl is roundtoward(Xh**Yl,to_negative),
686 Zhh is roundtoward(Xh**Yh,to_positive),
687 NZl is maxr(Zl,minr(Zll, minr(Zlh, minr(Zhl, Zhh)))), 688 NZh is minr(Zh,maxr(Zll, maxr(Zlh, maxr(Zhl, Zhh)))), 689 (non_empty(NZl,NZh) -> NewZ = (NZl,NZh) ; NewZ = (Zl,Zh)). 690
691ln((Xl,Xh), (Zl,Zh)) :-
692 Zl is roundtoward(log(Xl),to_negative),
693 Zh is roundtoward(log(Xh),to_positive).
694
696
698
699narrowing_op(sin, _, $(Z,X), $(NewZ, NewX)) :-
700 sin_(X,S,Z,NewZ),
701 asin_(NewZ,S,X,NewX).
702
703sin_((Xl,Xh),(Sl,Sh),Z,NZ) :-
704 (Xl == Xh, abs(Xl) =:= 1.0Inf
705 -> Sl = -10, Sh = 10, 706 ^(Z,(-1.0,1.0),NZ)
707 ; Sl is floor(roundtoward(Xl/pi+0.5,to_positive)), 708 Sh is floor(roundtoward(Xh/pi+0.5,to_negative)), 709 ( Sh-Sl =< 2 710 -> to_float((Xl,Xh),FX), 711 sinCase_(FX,Sl,Sh,Z,(1,-1),NZ),
712 non_empty(NZ)
713 ; ^(Z,(-1.0,1.0),NZ)
714 )
715 ).
716
717sinCase_(X,Sl,Sh,Z,ZIn,NZ) :-
718 (Sl == Sh
719 -> sinSector_(Sl,X,Z,ZIn,NZ) 720 ; XSh is pi*(Sl+0.5), 721 X = (Xl,Xh),
722 sinSector_(Sl,(Xl,XSh),Z,ZIn,ZOut),
723 SNl is Sl+1,
724 sinCase_((XSh,Xh),SNl,Sh,Z,ZOut,NZ)
725 ).
726
727sinSector_(S,(Xl,Xh),(Zl,Zh),(ZlIn,ZhIn),(ZlOut,ZhOut)) :-
728 ( 0 is S mod 2 729 -> ZSl is roundtoward(sin(Xl), to_negative),
730 ZSh is roundtoward(sin(Xh), to_positive)
731 ; ZSl is roundtoward(sin(Xh), to_negative),
732 ZSh is roundtoward(sin(Xl), to_positive)
733 ),
734 ( ^((Zl,Zh),(ZSl,ZSh),(Z1l,Z1h)) 735 -> ZlOut is minr(ZlIn,Z1l), ZhOut is maxr(ZhIn,Z1h)
736 ; ZlOut = ZlIn, ZhOut = ZhIn
737 ).
738
739asin_(Z,S,X,NX) :-
740 ( Z = (-1.0,1.0)
741 -> NX = X 742 ; S = (Sl,Sh),
743 (Sl == Sh
744 -> asinSector_(Sl,Z,XS), 745 ^(X,XS,NX)
746 ; ( Sh-Sl =< 2 747 -> asinCaseLo_(Sl,Z,X,XSl),
748 asinCaseHi_(Sh,Z,X,XSh),
749 ^(X,(XSl,XSh),NX)
750 ; NX = X
751 )
752 )
753 ).
754
755asinCaseLo_(S,Z,X,NXl) :-
756 asinSector_(S,Z,XS),
757 ( ^(X,XS,(NXl,_))
758 -> true
759 ; X = (_,Xh), Xh >= pi*(S+0.5), 760 S1 is S+1,
761 asinCaseLo_(S1,Z,X,NXl)
762 ).
763
764asinCaseHi_(S,Z,X,NXh) :-
765 asinSector_(S,Z,XS),
766 ( ^(X,XS,(_,NXh))
767 -> true
768 ; X = (Xl,_), Xl =< pi*(S-0.5), 769 S1 is S-1,
770 asinCaseHi_(S1,Z,X,NXh)
771 ).
772
773asinSector_(S,(Zl,Zh),(XSl,XSh)) :-
774 Offs is S*pi,
775 bounded_number(Offl,Offh,Offs), 778 (0 is S mod 2
779 -> XSl is roundtoward(Offl+asin(Zl),to_negative), 780 XSh is roundtoward(Offh+asin(Zh),to_positive)
781 ; XSl is roundtoward(Offl-asin(Zh),to_negative), 782 XSh is roundtoward(Offh-asin(Zl),to_positive)
783 ).
784
786
788
789narrowing_op(cos, _, $(Z,X), $(NewZ, NewX)) :-
790 cos_(X,S,Z,NewZ),
791 acos_(NewZ,S,X,NewX).
792
793cos_((Xl,Xh),(Sl,Sh),Z,NZ) :-
794 (Xl == Xh, abs(Xl) =:= 1.0Inf
795 -> Sl = -10, Sh = 10, 796 ^(Z,(-1.0,1.0),NZ)
797 ; Sl is floor(roundtoward(Xl/pi,to_positive)), 798 Sh is floor(roundtoward(Xh/pi,to_negative)), 799 ( Sh-Sl =< 2 800 -> to_float((Xl,Xh),FX), 801 cosCase_(FX,Sl,Sh,Z,(1,-1),NZ),
802 non_empty(NZ)
803 ; ^(Z,(-1.0,1.0),NZ)
804 )
805 ).
806
807cosCase_(X,Sl,Sh,Z,ZIn,NZ) :-
808 ( Sl == Sh
809 -> cosSector_(Sl,X,Z,ZIn,NZ) 810 ; SNl is Sl+1, 811 XSh is pi*(Sl+1),
812 X = (Xl,Xh),
813 cosSector_(Sl,(Xl,XSh),Z,ZIn,ZOut),
814 cosCase_((XSh,Xh),SNl,Sh,Z,ZOut,NZ)
815 ).
816
817cosSector_(S,(Xl,Xh),(Zl,Zh),(ZlIn,ZhIn),(ZlOut,ZhOut)) :-
818 ( 1 is S mod 2 819 -> ZSl is roundtoward(cos(Xl), to_negative),
820 ZSh is roundtoward(cos(Xh), to_positive)
821 ; ZSl is roundtoward(cos(Xh), to_negative),
822 ZSh is roundtoward(cos(Xl), to_positive)
823 ),
824 ( ^((Zl,Zh),(ZSl,ZSh),(Z1l,Z1h)) 825 -> ZlOut is minr(ZlIn,Z1l), ZhOut is maxr(ZhIn,Z1h)
826 ; ZlOut = ZlIn, ZhOut = ZhIn
827 ).
828
829acos_(Z,S,X,NX) :-
830 ( Z = (-1.0,1.0)
831 -> NX = X 832 ; S = (Sl,Sh),
833 (Sl == Sh
834 -> acosSector_(Sl,Z,XS), 835 ^(X,XS,NX)
836 ; ( Sh-Sl =< 2 837 -> acosCaseLo_(Sl,Z,X,XSl),
838 acosCaseHi_(Sh,Z,X,XSh),
839 ^(X,(XSl,XSh),NX)
840 ; NX = X
841 )
842 )
843 ).
844
845acosCaseLo_(S,Z,X,NXl) :-
846 acosSector_(S,Z,XS),
847 ( ^(X,XS,(NXl,_))
848 -> true
849 ; S1 is S+1, 850 X = (_,Xh), Xh >= pi*S1,
851 acosCaseLo_(S1,Z,X,NXl)
852 ).
853
854acosCaseHi_(S,Z,X,NXh) :-
855 acosSector_(S,Z,XS),
856 ( ^(X,XS,(_,NXh))
857 -> true
858 ; X = (Xl,_), Xl =< pi*S, 859 S1 is S-1,
860 acosCaseHi_(S1,Z,X,NXh)
861 ).
862
863acosSector_(S,(Zl,Zh),(XSl,XSh)) :-
864 X1l is roundtoward(acos(Zh),to_negative),
865 X1h is roundtoward(acos(Zl),to_positive),
866 (1 is S mod 2
867 -> Offs is (S+1)*pi,
868 bounded_number(Offl,Offh,Offs), 869 XSl is roundtoward(Offl-X1h,to_negative), 870 XSh is roundtoward(Offh-X1l,to_positive)
871 ; Offs is S*pi,
872 bounded_number(Offl,Offh,Offs), 873 XSl is roundtoward(Offl+X1l,to_negative), 874 XSh is roundtoward(Offh+X1h,to_positive)
875 ).
876
878
880
881narrowing_op(tan, _, $(Z,X), $(NewZ, NewX)) :-
882 X = (Xl,Xh),
883 Sl is round(Xl/pi), 884 Sh is round(Xh/pi),
885 tanCase(Z,X,Sl,Sh,NewZ,NewX).
886
889tanCase(Z,(X,X),_,_,Z,(X,X)) :- 890 abs(X) =:= 1.0Inf, !.
891tanCase((Zl,Zh),(Xl,Xh),S,S,(NZl,NZh),NX) :- !, 892 Z1l is roundtoward(tan(Xl),to_negative),
893 Z1h is roundtoward(tan(Xh),to_positive),
894 ( non_empty(Z1l,Z1h)
895 -> ^((Zl,Zh),(Z1l,Z1h),(NZl,NZh)), 896 atan_((NZl,NZh),S,X1),
897 ^((Xl,Xh),X1,NX)
898 ; 899 ((Z1l =< Zh ; Z1h >= Zl) -> true), 900 NZl = Zl, NZh = Zh, NX = (Xl,Xh) 901 ).
902tanCase(Z,(Xl,Xh),Sl,Sh,(NZl,NZh),(NXl,NXh)) :- Sh-Sl =:= 1, 903 Sg is pi*(Sl+0.5), 904 bounded_number(XSl,XSh,Sg), 905 (tanCase(Z,(Xl,XSl),Sl,Sl,(NZ1l,NZ1h),(NXl,NX1h))
906 -> (tanCase(Z,(XSh,Xh),Sh,Sh,_NZ2,(_,NXh))
907 -> fail 908 ; NXh = NX1h, NZl = NZ1l, NZh = NZ1h 909 )
910 ; tanCase(Z,(XSh,Xh),Sh,Sh,(NZl,NZh),(NXl,NXh)) 911 ),
912 !.
913tanCase(Z,X,Sl,Sh,Z,NX) :- Sh-Sl =:= 2,
914 915 X = (Xl,Xh),
916 LB is rational(roundtoward(Xl/pi + 0.5, to_positive)), integer(LB),
917 UB is rational(roundtoward(Xh/pi + 0.5, to_negative)), integer(UB),
918 !,
919 S is (Sl+Sh)/2,
920 atan_(Z,S,X1), ^(X,X1,NX)
920.
921tanCase(Z,X,Sl,Sh,Z,X). 922
923atan_((Zl,Zh),S,(Xl,Xh)) :-
924 Offs is S*pi,
925 bounded_number(Offl,Offh,Offs), 926 Xl is Offl+roundtoward(atan(Zl),to_negative),
927 Xh is Offh+roundtoward(atan(Zh),to_positive).
928
930
932
933narrowing_op(not, P, $(Z,X), $(NewZ, NewX)) :-
934 notB_(X,Z,Z1,P), ^(Z,Z1,NewZ),
935 notB_(NewZ,X,X1,P), ^(X,X1,NewX).
936
937notB_((0,0), _, (1,1), p) :- !.
938notB_((1,1), _, (0,0), p) :- !.
939notB_( _, Z, NewZ, _) :- ^(Z,(0,1),NewZ).
940
942
944
945narrowing_op(and, P, $(Z,X,Y), $(NewZ, NewX, NewY)) :-
946 andB_rel_(Z,X,Y, NewZ, NewX, NewY, P).
947
948andB_rel_(Z,(1,1),(1,1), NewZ,(1,1),(1,1), p) :- !, ^(Z,(1,1),NewZ). 949andB_rel_(Z,(0,0),Y, NewZ,(0,0),Y, p) :- !, ^(Z,(0,0),NewZ), ^(Y,(0,1),NewY).
950andB_rel_(Z,X,(0,0), NewZ,X,(0,0), p) :- !, ^(Z,(0,0),NewZ), ^(X,(0,1),NewX).
951andB_rel_((1,1),X,Y, (1,1),NewX,NewY, p) :- !, ^(X,(1,1),NewX), ^(Y,(1,1),NewY).
952andB_rel_((0,0),X,(1,1), (0,0),NewX,(1,1), p) :- !, ^(X,(0,0),NewX).
953andB_rel_((0,0),(1,1),Y, (0,0),(1,1),NewY, p) :- !, ^(Y,(0,0),NewY).
954andB_rel_(Z,X,Y, NewZ,NewX,NewY, P) :- ^(Z,(0,1),NewZ), ^(X,(0,1),NewX), ^(Y,(0,1),NewY). 955
957
959
960narrowing_op(nand, P, $(Z,X,Y), $(NewZ, NewX, NewY)) :-
961 nandB_rel_(Z,X,Y, NewZ, NewX, NewY, P).
962
963nandB_rel_(Z,(1,1),(1,1), NewZ,(1,1),(1,1), p) :- !, ^(Z,(0,0),NewZ). 964nandB_rel_(Z,(0,0),Y, NewZ,(0,0),Y, p) :- !, ^(Z,(1,1),NewZ), ^(Y,(0,1),NewY).
965nandB_rel_(Z,X,(0,0), NewZ,X,(0,0), p) :- !, ^(Z,(1,1),NewZ), ^(X,(0,1),NewX).
966nandB_rel_((0,0),X,Y, (0,0),NewX,NewY, p) :- !, ^(X,(1,1),NewX), ^(Y,(1,1),NewY).
967nandB_rel_((1,1),X,(1,1), (1,1),NewX,(1,1), p) :- !, ^(X,(0,0),NewX).
968nandB_rel_((1,1),(1,1),Y, (1,1),(1,1),NewY, p) :- !, ^(Y,(0,0),NewY).
969nandB_rel_(Z,X,Y, NewZ,NewX,NewY, P) :- ^(Z,(0,1),NewZ), ^(X,(0,1),NewX), ^(Y,(0,1),NewY). 970
972
974
975narrowing_op(or, P, $(Z,X,Y), $(NewZ, NewX, NewY)) :-
976 orB_rel_(Z,X,Y, NewZ, NewX, NewY, P).
977
978orB_rel_(Z,(0,0),(0,0), NewZ,(0,0),(0,0), p) :- !, ^(Z,(0,0),NewZ). 979orB_rel_(Z,(1,1),Y, NewZ,(1,1),Y, p) :- !, ^(Z,(1,1),NewZ), ^(Y,(0,1),NewY).
980orB_rel_(Z,X,(1,1), NewZ,X,(1,1), p) :- !, ^(Z,(1,1),NewZ), ^(X,(0,1),NewX).
981orB_rel_((0,0),X,Y, (0,0),NewX,NewY, p) :- !, ^(X,(0,0),NewX), ^(Y,(0,0),NewY).
982orB_rel_((1,1),X,(0,0), (1,1),NewX,(0,0), p) :- !, ^(X,(1,1),NewX).
983orB_rel_((1,1),(0,0),Y, (1,1),(0,0),NewY, p) :- !, ^(Y,(1,1),NewY).
984orB_rel_(Z,X,Y, NewZ,NewX,NewY, P) :- ^(Z,(0,1),NewZ), ^(X,(0,1),NewX), ^(Y,(0,1),NewY). 985
987
989
990narrowing_op(nor, P, $(Z,X,Y), $(NewZ, NewX, NewY)) :-
991 norB_rel_(Z,X,Y, NewZ, NewX, NewY, P).
992
993norB_rel_(Z,(0,0),(0,0), NewZ,(0,0),(0,0), p) :- !, ^(Z,(1,1),NewZ). 994norB_rel_(Z,(1,1),Y, NewZ,(1,1),Y, p) :- !, ^(Z,(0,0),NewZ), ^(Y,(0,1),NewY).
995norB_rel_(Z,X,(1,1), NewZ,X,(1,1), p) :- !, ^(Z,(0,0),NewZ), ^(X,(0,1),NewX).
996norB_rel_((1,1),X,Y, (1,1),NewX,NewY, p) :- !, ^(X,(0,0),NewX), ^(Y,(0,0),NewY).
997norB_rel_((0,0),X,(0,0), (0,0),NewX,(0,0), p) :- !, ^(X,(1,1),NewX).
998norB_rel_((0,0),(0,0),Y, (0,0),(0,0),NewY, p) :- !, ^(Y,(1,1),NewY).
999norB_rel_(Z,X,Y, NewZ,NewX,NewY, P) :- ^(Z,(0,1),NewZ), ^(X,(0,1),NewX), ^(Y,(0,1),NewY). 1000
1002
1004
1005narrowing_op(xor, P, $(Z,X,Y), $(NewZ, NewX, NewY)) :-
1006 xorB_rel_(Z,X,Y, NewZ, NewX, NewY, P).
1007
1008xorB_rel_(Z,(B,B),(B,B), NewZ,(B,B),(B,B), p) :- !, ^(Z,(0,0),NewZ). 1009xorB_rel_(Z,(X,X),(Y,Y), NewZ,(X,X),(Y,Y), p) :- !, ^(Z,(1,1),NewZ).
1010xorB_rel_((B,B),X,(B,B), (B,B),NewX,(B,B), p) :- !, ^(X,(0,0),NewX).
1011xorB_rel_((Z,Z),X,(Y,Y), (Z,Z),NewX,(Y,Y), p) :- !, ^(X,(1,1),NewX).
1012xorB_rel_((B,B),(B,B),Y, (B,B),(B,B),NewY, p) :- !, ^(Y,(0,0),NewY).
1013xorB_rel_((Z,Z),(X,X),Y, (Z,Z),(X,X),NewY, p) :- !, ^(Y,(1,1),NewY).
1014xorB_rel_(Z,X,Y, NewZ,NewX,NewY, P) :- ^(Z,(0,1),NewZ), ^(X,(0,1),NewX), ^(Y,(0,1),NewY). 1015
1017
1019
1020narrowing_op(imB, P, $(Z,X,Y), $(NewZ, NewX, NewY)) :-
1021 imB_rel_(Z,X,Y, NewZ, NewX, NewY, P).
1022
1023imB_rel_(Z,(1,1),Y, New,(1,1),New, P) :- !, ^(Z,Y,New), (New=(B,B) -> P=p ; true). 1024imB_rel_(Z,(0,0),Y, NewZ,(0,0),Y, p) :- !, ^(Z,(1,1),NewZ), ^(Y,(0,1),NewY). 1025imB_rel_(Z,X,(0,0), NewZ,NewX,(0,0), P) :- !, notB_(X,Z,NewZ,P), notB_(NewZ,X,NewX,P). 1026imB_rel_(Z,X,(1,1), NewZ,X,(1,1), P) :- !, ^(Z,(1,1),NewZ). 1027imB_rel_((0,0),X,Y, (0,0),NewX,NewY, p) :- !, ^(X,(1,1),NewX), ^(Y,(0,0),NewY). 1028imB_rel_(Z,X,Y, NewZ,NewX,NewY, P) :- ^(Z,(0,1),NewZ), ^(X,(0,1),NewX), ^(Y,(0,1),NewY). 1029
1031
1032:- style_check(+singleton). 1033
1035
1036narrowing_op(user(Prim), P, InArgs, OutArgs) :-
1037 call_user_primitive(Prim, P, InArgs, OutArgs).