didoudiaz / gprolog

GNU Prolog
Other
106 stars 13 forks source link

Overflow with `(is)/2` #47

Closed notoria closed 1 year ago

notoria commented 1 year ago
$ ./bin/gprolog
GNU Prolog 1.6.0 (64 bits)
Compiled Jun 27 2023, 16:35:39 with gcc
Copyright (C) 1999-2023 Daniel Diaz

| ?- current_prolog_flag(max_integer, V), W is V + 1.

V = 1152921504606846975
W = -1152921504606846976

yes
| ?-
didoudiaz commented 1 year ago

gprolog does not (yet) detect integer under/overflow... (this is explained in the manual). Note that, succ/2 is a special-case (detection mainly added for call_nth/2 ! In the same spirit, it would be easy to add this detection for the specific case of incrementation (+ 1). But the general case, requires more work. I'm very busy at the University and have to prioritize my gprolog TODO list (contributors are welcome ;-)).

notoria commented 1 year ago

Related:

| ?- current_prolog_flag(min_integer, M), X is 1 >> M.

This query gets stuck (same with <<). Infinite loop maybe (between Pl_Fct_Fast_Shl and Pl_Fct_Fast_Shr)?

didoudiaz commented 1 year ago

Fixed. Note that I'm not really sure about which error to detect. If << and >> are to strength-reduced operations for multiplication and division by a power of 2, I suppose we want to detect overflows. However, they are very often used for bit-mask operations and it is desirable to have permissive operations in this context (is int_overflow still wanted ?).

notoria commented 1 year ago
| ?- X is (-1) >> 63.

X = -1

yes
| ?- X is (-1) >> 64.

X = 0 % unexpected

yes
| ?-

For arithmetic right shift, it should be -1.

For the left shift, it's multiplying by a power of 2, int_overflow is inevitable otherwise it will be necessary to reason about undefined behavior (C level or Prolog level).

didoudiaz commented 1 year ago

Fixed (assuming two'complement)