Merge pull request #1461 from triska/clpz_sign

ADDED: sign/1
This commit is contained in:
Mark Thom
2022-05-05 17:24:54 -06:00
committed by GitHub

View File

@@ -3,7 +3,7 @@
Author: Markus Triska
E-mail: triska@metalevel.at
WWW: https://www.metalevel.at
Copyright (C): 2016-2021 Markus Triska
Copyright (C): 2016-2022 Markus Triska
This library provides CLP():
@@ -390,6 +390,7 @@ In total, the arithmetic constraints are:
| Expr `mod` Expr | Modulo induced by floored division |
| Expr `rem` Expr | Modulo induced by truncated division |
| abs(Expr) | Absolute value |
| sign(Expr) | Sign (-1, 0, 1) of Expr |
| Expr // Expr | Truncated integer division |
| Expr div Expr | Floored integer division |
@@ -2564,6 +2565,7 @@ parse_clpz(E, R,
m(A//B) => [g(B #\= 0), p(ptzdiv(A, B, R))],
m(A div B) => [g(?(R) #= (A - (A mod B)) // B)],
m(A^B) => [p(pexp(A, B, R))],
m(sign(A)) => [g(R in -1..1), p(psign(A, R))],
% bitwise operations
m(\A) => [p(pfunction(\, A, R))],
m(msb(A)) => [p(pfunction(msb, A, R))],
@@ -5134,7 +5136,6 @@ run_propagator(pmodz(X,Y,Z), MState) -->
domain_remove_smaller_than(ZD3, ZMin, ZD5) },
fd_put(Z, ZD5, ZPs)
% queue_goal(Z in ZMin..ZMax)
%/* This doesn't work very well.
; { fd_get(Y, _, _, n(YU), _), YU > 0 } ->
{ fd_get(Z, ZD1, ZPs),
ZMax is YU - 1,
@@ -5147,7 +5148,6 @@ run_propagator(pmodz(X,Y,Z), MState) -->
domain_remove_smaller_than(ZD1, ZMin, ZD3) },
fd_put(Z, ZD3, ZPs)
% queue_goal(Z #> YL)
% * /
; true
)
)
@@ -5484,6 +5484,21 @@ run_propagator(pexp(X,Y,Z), MState) -->
; true
).
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% % Y = sign(X)
run_propagator(psign(X,Y), MState) -->
( nonvar(X) -> kill(MState), queue_goal(Y is sign(X))
; Y == -1 -> kill(MState), queue_goal(X #< 0)
; Y == 0 -> kill(MState), queue_goal(X = 0)
; Y == 1 -> kill(MState), queue_goal(X #> 0)
; { fd_get(X, _, XL, XU, _) },
( { XL = n(L), L > 0 } -> kill(MState), queue_goal(Y = 1)
; { XU = n(U), U < 0 } -> kill(MState), queue_goal(Y = -1)
; true
)
).
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% % Y = popcount(X)
@@ -7696,6 +7711,7 @@ attribute_goal_(ptzdiv(X,Y,Z)) --> [?(X) // ?(Y) #= ?(Z)].
attribute_goal_(pdiv(X,Y,Z)) --> [?(X) div ?(Y) #= ?(Z)].
attribute_goal_(prdiv(X,Y,Z)) --> [?(X) / ?(Y) #= ?(Z)].
attribute_goal_(pexp(X,Y,Z)) --> [?(X) ^ ?(Y) #= ?(Z)].
attribute_goal_(psign(X,Y)) --> [?(Y) #= sign(?(X))].
attribute_goal_(pabs(X,Y)) --> [?(Y) #= abs(?(X))].
attribute_goal_(pmod(X,M,K)) --> [?(X) mod ?(M) #= ?(K)].
attribute_goal_(prem(X,Y,Z)) --> [?(X) rem ?(Y) #= ?(Z)].