2015-11-12 3 views
2

Моих ниже функций являются упрощенной версией того, что я хочу сделать, но здесь это:пролог бесконечно петляет по одной команде, почему?

%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 

если также пытался замен на "Z является Z1, Z2 +" с "не является (Z, 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 

ответ

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.