Вы можете написать предикат вхождения/5, который будет истинным, если второй и третий аргументы встречаются одинаково часто в списке, который является первым аргументом. 4-й и 5-й аргументы являются соответствующими счетчиками. Тогда предикат вхождения/1 является предикатом вызова:
occurrences(List) :-
occurrences(List,a,b,0,0).
occurrences([],_A,_B,N,N).
occurrences([A|Xs],A,B,N0,M) :-
N1 is N0+1,
occurrences(Xs,A,B,N1,M).
occurrences([B|Xs],A,B,N,M0) :-
M1 is M0+1,
occurrences(Xs,A,B,N,M1).
occurrences([X|Xs],A,B,N,M) :-
dif(A,X),
dif(B,X),
occurrences(Xs,A,B,N,M).
Вы начинаете со счетчиков в 0, и в зависимости от того, равен ли заголовок списка A
или B
, соответствующий счетчик увеличивается или счетчик не увеличивается, если заголовок отличается от обоих. Теперь давайте посмотрим на результаты для ваших примеров:
?- occurrences([a,a,b,b]).
true ;
false.
?- occurrences([a,a,a,b,b]).
false.
Однако я думаю, что предикат вхождения / 3, который позволяет вам указать два элемента, был бы более полезным:
occurrences(List,A,B) :-
dif(A,B),
occurrences(List,A,B,0,0).
Тогда ваши примеры запросов будут выглядеть так:
?- occurrences([a,a,b,b],a,b).
true ;
false.
?- occurrences([a,a,a,b,b],a,b).
false.
Вы также можете спросить, какие элементы встречаются одинаково часто:
?- occurrences([a,a,b,b,c,c,d],X,Y).
X = a,
Y = b ;
X = a,
Y = c ;
X = b,
Y = a ;
X = c,
Y = a ;
X = b,
Y = c ;
X = c,
Y = b ;
dif(X, d),
dif(X, c),
dif(X, c),
dif(X, b),
dif(X, b),
dif(X, a),
dif(X, a),
dif(X, Y),
dif(Y, d),
dif(Y, c),
dif(Y, c),
dif(Y, b),
dif(Y, b),
dif(Y, a),
dif(Y, a).
Последнее решение соответствует двум элементам, которые вообще не встречаются в списке, так как оба они встречаются одинаково часто, а именно 0 раз. Если вы хотите использовать предикат в другом направлении, то есть спросить, какие существуют списки, в которых два заданных элемента появляются одинаково часто, вы должны указать цель, ограничивающую длину списка во время предиката. вызов, например:
?- length(L,_),occurrences(L,a,b).
L = [] ;
L = [_G150],
dif(_G150, b),
dif(_G150, a) ;
L = [a, b] ;
L = [b, a] ;
L = [_G116, _G119],
dif(_G116, b),
dif(_G116, a),
dif(_G119, b),
dif(_G119, a) ;
L = [a, b, _G162],
dif(_G162, b),
dif(_G162, a) ;
L = [a, _G159, b],
dif(_G159, b),
dif(_G159, a) ;
L = [b, a, _G162],
dif(_G162, b),
dif(_G162, a) ;
.
.
.
person
tas
schedule
14.11.2017
a
иb
? - person false   schedule 15.11.2017[a,b,a,b]
? - person lurker   schedule 15.11.2017