prolog在一个命令上无限循环,为什么?

时间:2015-11-12 23:33:52

标签: prolog

我的波纹管功能是我想要完成的简化版本,但现在是:

%contains(array,searchElement,numberOfOccurances)
contains([],_,0).
contains([X1],Y,1) :- X1=Y.
contains([X1],Y,0) :- not(X1=Y).
contains([X1|X2],Y,Z) :- contains([X1],Y,Z1) ,contains(X2,Y,Z2),Z is Z1+Z2.

%call1(wrong):
contains([1,2,1,2,4],2,3).
%should return false, but loops infinitely

%call2(correct):
contains([1,2,1,2,4],2,2).
%returns true

%call3(correct):
contains([1,2,1,2,4],2,Z).
%returns Z=2

%line1 2 and 3 are correct and give no errors
%(when running 
%contains([],2,X/1/0) contains([2],2,X/1/0) contains([2],3,X/1/0);)
%, the problem is line 4

不幸的是,我陷入了无限循环,尝试过:

%altering line 4
contains([X1|X2],Y,Z1+Z2) :- contains([X1],Y,Z1) ,contains(X2,Y,Z2).
%results are:
%result1 false (correct, but just by chance)
%result2 false (wrong)
%result3 Z = 1+ (1+ (1+ (1+1))) -> clearly because string is appended and not calculated

如果还尝试用“is(Z,Z1 + Z2)”代替“Z is Z1 + Z2”但没有差异

编辑后

contains([],_,0):-write('query contains with empty array'), nl,read(_).
contains([X1],Y,1) :- write('query contains with 1 array for Z=1 X1='),write(X1), nl,read(_),X1=Y.
contains([X1],Y,0) :- write('query contains with 1 array for Z=0 X1='),write(X1), nl,read(_),not(X1=Y).
contains([X1|X2],Y,Z) :- write('query contains with 2 array X1='),write(X1),write(' X2='),write(X2), nl,read(_),contains([X1],Y,Z1) ,contains(X2,Y,Z2),Z is Z1+Z2. 
/* now i can see the loops that are being made
contains([11,12,13,14,15],11,2). %original
contains([11|[12,13,14,15]],11,2). %2=verify 11 + verify [12..15]
contains([11],11,1). %true
contains([12|[13,14,15]],11,1). %2=1+ verify 12 + verify [13..15]
contains([12],11,1). %false
contains([12],11,0). %true
contains([13|[14,15]],11,1). %2=1+0+ verify 13 + verify [14,15]
contains([13],11,1). %false
contains([13],11,0). %true
contains([14|[15]],11,1). %2=1+0+0+ verify 14 + verify [15]
contains([14],11,1). %false
contains([14],11,0). %true
contains([15],11,1). %false
contains([15],11,0). %true 
%now everything should stop and everything should return false!!!!
contains([15|[]],11,1). %wtf?
contains([15],11,1). %false
contains([15],11,0). %true 
contains([15|[]],11,1). %wtf?
contains([15],11,1). %false
contains([15],11,0). %true 
%and soo on

1 个答案:

答案 0 :(得分:0)

解决方案:

contains([X1|X2],Y,Z) :- contains([X1],Y,Z1) ,contains(X2,Y,Z2),Z is Z1+Z2.
%turn into
contains([X1|X2],Y,Z) :- not(X2=[]),contains([X1],Y,Z1) ,contains(X2,Y,Z2),Z is Z1+Z2.