B-Prolog:
3 mod 2=1
3 mod-2=1
-3 mod 2= -1
-3 mod-2= -1
3 rem 2=1
3 rem-2=1
-3 rem 2= -1
-3 rem-2= -1
SWI:
3 mod 2=1
3 mod-2=1
-3 mod 2= -1
-3 mod-2= -1
3 rem 2=0.5
3 rem-2= -0.5
-3 rem 2= -0.5
-3 rem-2=0.5
It seems that there is no difference betwen rem and mod in B-Prolog. Any
suggestions on what is compliant with the standard?
Cheers,
Neng-Fa
I think this is a pretty old version of SWI-Prolog:
?- A is 3 rem 2.
A = 1.
Ulrich also pointed out that the implementation of mod/2 is broken for
negative values also in the latest version. I haven't studied the
details of his remarks and the standard yet.
Cheers --- Jan
I don't know which implementation is correct. I'd like to know if anybody
who created the standard knows about the difference between mod and rem.
Cheers,
Neng-Fa
To the best of my knowledge, the standard isn't terribly clear about that,
apart from requiring that // and rem go together such that
X =:= (X rem Y) + (X // Y) * Y.
without being specific about negative arguments, also for mod.
A few years ago I cleaned this up in ECLiPSe, following recommendations
by Richard O'Keefe. These go beyond the standard, but seem sensible and
consistent with many other languages:
X // Y division with truncated result
X rem Y remainder corresponding to //, in range -(Y-1)..Y-1
X div Y division with floored result (not in ISO)
X mod Y remainder corresponding to div, in range 0..Y-1
Such that X =:= (X rem Y) + (X // Y) * Y
and X =:= (X mod Y) + (X div Y) * Y.
This yields:
1 is 3 rem 2
1 is 3 rem -2
-1 is -3 rem 2
-1 is -3 rem -2
1 is 3 // 2
-1 is 3 // -2
-1 is -3 // 2
1 is -3 // -2
1 is 3 mod 2
-1 is 3 mod -2
1 is -3 mod 2
-1 is -3 mod -2
1 is 3 div 2
-2 is 3 div -2
-2 is -3 div 2
1 is -3 div -2
Cheers,
Joachim
I disagree. The rules given in Section 9.1.3 of ISO/IEC 13211-1 seem
unambiguous to me, namely if Y=\=0 then:
mod(X,Y) = X-((X div Y)*Y)
rem(X,Y) = X-((X // Y)*Y)
where:
> X // Y division with truncated result
> X div Y division with floored result
This is consistent with:
> X mod Y remainder corresponding to div, in range 0..Y-1 if Y>0
or range Y+1..0 if Y<0
> X rem Y remainder corresponding to //, in range -(Y-1)..Y-1 if Y>0
or range Y+1..-(Y+1) if Y<0
> Such that X =:= (X rem Y) + (X // Y) * Y
> and X =:= (X mod Y) + (X div Y) * Y.
ISO, ECLiPSe and SICStus agree on this issue (div is not an evaluable
functor in SICStus, nor is it mentioned by ISO, as Joachim points
out).
--Mats
Thanks to a patch by Ulrich that I found in my mailbos this morning,
SWI-Prolog now also agrees. Just out of curiosity, I think I only
used mod/2 with positive integers (nominator non-negative). Rem has
been broken totally for many years and mod has been broken for
negative integers until this morning. It was only Ulrich, adding more
ISO compliancy tests who finally found these issues.
What are the common usecases for rem/2 and mod/2 with negative
arguments?
Cheers --- Jan
There is a helpful article on modulus and remainder here:
http://mindprod.com/jgloss/modulus.html
This relates to Java and its truncated (same as most hardware?)
division. The difference between modulus and remainder on negative
values as explained there, would seem to me to be the most obvious
differentiation between the intended behavior of mod and rem in
Prolog. That is, rem should be a fast remainder from a truncated
hardware division, and mod needs some sign adjusting afterwards to be
more mathematically correct. rem and mod should only differ when
negative operands are involved.
Rupert
Thanks. At least that clarifies the rational. Doesn't really encourage
me to use any of this with negative operants as long as I can easily avoid
that :-)
--- Jan
> I disagree. The rules given in Section 9.1.3 of ISO/IEC 13211-1 seem
> unambiguous to me, namely if Y=\=0 then:
>
> mod(X,Y) = X-((X div Y)*Y)
> rem(X,Y) = X-((X // Y)*Y)
>
> where:
>
>> X // Y division with truncated result
>> X div Y division with floored result
Thanks for your clarification. I couldn't find these definitions in the
standard (the red-covered book). Now I hope more Prolog systems will be
consistent on these two functions.
Cheers,
Neng-Fa
> I couldn't find these definitions in the
>standard (the red-covered book). Now I hope more Prolog systems will be
>consistent on these two functions.
You may want examine the material accompanied with the compliance
tests conducted by Peter Szabo and Peter Szeredi in the course of
making SICStus compliant.
http://www.inf.bme.hu/~pts/stdprolog/
Maybe this test could be repeated? For one, SWI has improved quite a lot.
Also, the tests have been repeated for SICStus 4 beta. It would be even
nicer to announce those tests in advance.