scryer-prolog
scryer-prolog copied to clipboard
clpz: popcount/1 and (^)/2 crash
?- X is -1^ -1.
X = -1. % expected
?- X#=popcount(-1).
X = 64. % not sure if this is OK
?- X#=popcount(-1^ -1).
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src/machine/system_calls.rs:6834:51
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
This X = 64.
still looks strange to me.
#999 still an issue? #998 popcount controversy; research participants :-) think it should be a domain error. Hint: In the Lisp spirit, the popcount of a negative integer is the number of 0 bits in 2's complement. So X = 64 is wrong.
@flexoron: Ad domain_error
: In general, a domain error may be produced by a built-in predicate like popcount/2
, but not by arithmetic evaluation alone. Thus SWI's
?- catch(X is popcount(-1),error(E,_), true).
E = domain_error(not_less_than_zero, -1), unexpected. % SWI
E = evaluation_error(undefined). % 7.9.2 h, 7.12.2 g, 9.1.2. % expected, if considered to be an error
is highly problematic. It could be either evaluation_error(undefined)
or à la rigueur some newly invented exceptional value (9.1.2) , if an error should be the outcome (I have no real opinion on it).
((The reason that I encountered this issue is just because I tried to test clpz
systematically, taking the manual (and not knowing anything about the meaning of all these functors). After all, some of the issues that hinder exhaustive testing have been fixed recently, before there was too much leaking.))
?- X #= popcount(Y).
clpz:(X#=popcount(Y)), unexpected. % current Scryer result
X#=popcount(Y), unexpected. % more compact formulation
X in 0..sup, Y in 0..sup, X #= popcount(Y) % hypothetically desirable, if popcount(-1) is undefined
| % alternate outcome
X in 0..sup, Y in inf..sup, X #= popcount(Y). % in case of LISP-ish meaning
I see your point. If hypothetically desirable then:
?- X #= popcount(Y) , A #= X/Y.
X in 0..sup, Y in 0..sup, A in diverr..0..supinf ?
Not clear what you mean, but 0 is excluded for division, no matter which:
?- A #= X/Y.
clpz:(A*Y#=X), clpz:(Y in inf.. -1\/1..sup).
?- A #= X//Y.
clpz:(X//Y#=A), clpz:(Y in inf.. -1\/1..sup).
?- A #= X div Y.
clpz:(_A+_B#=X), clpz:(_A//Y#=A), clpz:(X mod Y#=_B), clpz:(Y in inf.. -1\/1..sup).
x = 0/0. x * 0 = 0. x = (0..sup).
Anyway.
What I mean: Is X and Y (the result) available
?- X #= popcount(Y) , A #= X*Y.
X in 0..sup, Y in 0..sup, A in 0..sup % Is this possible?
My opinion: Problem is tricky but the outcome shouldn't be an error.
For example:
Define popcount such that it counts the sign-bit inverted (bit set? count 0s, not set? count 1s)
Just for the record, the oldest clpfd
library of SICStus I can get hold of right now:
[ulrich@a9 lib]$ /usr/local/lib/sicstus3.8.4_2/bin/sicstus
SICStus 3.8.4 (x86-linux-glibc2.1): Sun Jul 23 14:25:19 CEST 2000
Licensed to complang.tuwien.ac.at
...
| ?- asserta(clpfd:full_answer).
yes
| ?- A #= X/Y.
clpfd:'x/y=z'(X,Y,A) ? ;
no
| ?- A #= X/Y, Y = 0.
no
| ?- A #= X//Y.
{DOMAIN ERROR: _71#=_68//_69 - arg 0: expected constraint, found _71#=_68//_69}
| ?- A #= X div Y.
{SYNTAX ERROR: in line 28 (within 28-29)}
** operator expected after expression **
?- A #= X
** here **
div Y .
whereas today it's:
| ?- A #= X/Y.
X//Y#=A,
X in inf..sup,
Y in(inf.. -1)\/(1..sup),
A in inf..sup ?
yes
| ?- A #= X//Y.
X//Y#=A,
X in inf..sup,
Y in(inf.. -1)\/(1..sup),
A in inf..sup ? ;
no
| ?- A #= X div Y.
X div Y#=A,
X in inf..sup,
Y in(inf.. -1)\/(1..sup),
A in inf..sup ? ;
no
| ?-
At least convergence on a certain level.
I think the rug library returns an Option
Currently:
?- X#=popcount(-1^ -1).
thread 'main' panicked at 'assertion failed: sign == Sign::Positive', /home/ulrich/.cargo/git/checkouts/dashu-b0ac188b86787091/f934219/integer/src/repr.rs:148:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Right now:
?- X=popcount(-1 ^ -1).
X = popcount(-1^ -1).
?-
Which i assume is related to #2146.
@razetime: Please note the missing #
:
?- X#=popcount(-1 ^ -1).
X = 0.