Suppose I want to represent integers like so: integer:Sign:[FirstDigit,SecondDigit,...]
. For instance, 42 would be represented as integer:positive:[4,2]
.
I need a predicate that generates the value of the integer based on this representation and vice versa.
Here is what I came up with:
integer_value_('integer':Sign:[H],E) :-
H in 0..9,
(
Sign = 'positive',
E #= H
;
Sign = 'negative',
E #= -H
).
integer_value_('integer':Sign:[H,I|T],E) :-
H in 0..9,
length([I|T],L),
(
Sign = 'positive',
E #= F + H * 10^L
;
Sign = 'negative',
E #= F - H * 10^L
),
integer_value_('integer':Sign:[I|T],F).
This works as expected. However, it has the unfortunate property of accepting things like integer:positive:[0,1]
, that is, leading zeroes at the beginning of the list. This is especially problematic when I enumerate all possible integers using integer_value_(I,J), label([J]).
: the ones with leading zeroes also show up.
I then attempted to correct this by using integer_value_
only for all but the first digit, and using integer_value
for the first one (keeping in mind that we need to accomodate for 0 being represented with a list containing only 0):
integer_value('integer':Sign:[H],E) :-
abs(E) #< 10,
abs(E) #> -1,
integer_value_('integer':Sign:[H],E).
integer_value('integer':Sign:[H,I|T],E) :-
H in 1..9,
length([I|T],L),
(
Sign = 'positive',
E #= F + H * 10^L
;
Sign = 'negative',
E #= F - H * 10^L
),
integer_value_('integer':Sign:[I|T],F).
However now it does not behave properly. For example, integer_value(I,-19).
returns I = integer:negative:[1, 9]
, but if we ask for another answer Prolog goes into an infinite loop for reasons I don't understand (it should say false, or already know there are no other answers).
This problem does not occur with the "opposite" query integer_value(integer:negative:[1,9],Z).
which returns Z = 19
and then false, nor does it occur when both arguments are Variables (it enumerates numbers properly, with no leading zeroes), which is surprising to me.
Any idea what that infinite loop occurs, and if there's an easy way to fix it?
'
for all atoms that do not need such quotes, likepositive
,negative
,integer
etc. You can simply write all these atoms down directly, such asSign = positive
,Sign = negative
andinteger:Sign:[I|T]
. – Cheek