]> Repositorios git - scryer-prolog.git/commitdiff
ADDED: sign/1
authorMarkus Triska <[email protected]>
Thu, 5 May 2022 20:49:48 +0000 (22:49 +0200)
committerMarkus Triska <[email protected]>
Thu, 5 May 2022 20:51:49 +0000 (22:51 +0200)
src/lib/clpz.pl

index 2ed2cfbbe775451da475b7a66189674eade7e005..bb9ffcba08f0f3b69de30f8f272555523695da5e 100644 (file)
@@ -3,7 +3,7 @@
     Author:        Markus Triska
     E-mail:        [email protected]
     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))],
@@ -5482,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)
 
@@ -7694,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)].