假设我想像这样表示整数:integer:Sign:[FirstDigit,SecondDigit,...]
. 例如,42 将表示为integer:positive:[4,2]
。
我需要一个基于此表示生成整数值的谓词,反之亦然。
这是我想出的:
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).
这按预期工作。但是,它具有接受诸如 之类的东西的不幸属性integer:positive:[0,1]
,即在列表开头的前导零。当我使用 : 枚举所有可能的整数时,这尤其成问题integer_value_(I,J), label([J]).
:带有前导零的整数也会出现。
然后我尝试通过integer_value_
仅使用除第一个数字以外的所有数字并使用integer_value
第一个数字来纠正此问题(请记住,我们需要使用仅包含 0 的列表来表示 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).
但是现在它的行为不正常。例如,integer_value(I,-19).
返回I = integer:negative:[1, 9]
,但如果我们要求另一个答案,Prolog 会因为我不明白的原因进入无限循环(它应该说错误,或者已经知道没有其他答案)。
这个问题不会发生在integer_value(integer:negative:[1,9],Z).
返回Z = 19
然后为假的“相反”查询中,当两个参数都是变量时也不会发生(它正确枚举数字,没有前导零),这让我感到惊讶。
知道无限循环发生了什么,是否有一种简单的方法可以解决它?