Программа, чтобы найти каждый список X в Прологе
Я начинаю изучать Пролог. Эта программа пытается получить все вхождения данного элемента:
occurences(_, [], Res):- Res is [].
occurences(X, [X|T], Res):-
occurences(X,T,TMP),
Res is [X,TMP].
occurences(X, [_|T], Res):- occurences(X,T,Res).
Но вот ошибка:
?- occurences(a,[a,b,c,a],Res).
ERROR: is/2: Arithmetic: `[]/0' is not a function
^ Exception: (11) _G525 is [] ? creep
Exception: (10) occurences(a, [], _G524) ? creep
Exception: (9) occurences(a, [a], _G524) ? creep
Exception: (8) occurences(a, [c, a], _G524) ? creep
Exception: (7) occurences(a, [b, c, a], _G524) ? creep
Exception: (6) occurences(a, [a, b, c, a], _G400) ? creep
3 ответа
В дополнение к тому, что написали другие, рассмотрите возможность использования ограничения dif/2:
occurrences(_, [], []).
occurrences(X, [X|Ls], [X|Rest]) :-
occurrences(X, Ls, Rest).
occurrences(X, [L|Ls], Rest) :-
dif(X, L),
occurrences(X, Ls, Rest).
Теперь вы можете использовать предикат во всех направлениях, например:
?- occurrences(X, [a,a,b], Os).
X = a,
Os = [a, a] ;
X = b,
Os = [b] ;
Os = [],
dif(X, b),
dif(X, a),
dif(X, a) ;
false.
Последнее решение означает, что список вхождений пуст, если X отличается от обоих a
а также b
,
Рубенс уже проинформировал вас о вашей ошибке. Я просто добавлю примечание по стилю: часто в Прологе предпочтительно напрямую кодировать шаблон в аргументах head:
occurences(_, [], []).
occurences(X, [X|T], [X|TMP]) :-
occurences(X,T,TMP), !.
occurences(X, [_|T], Res) :-
occurences(X,T,Res).
Я исправил второй пункт "вывод" из [X,TMP]
в [X|TMP]
и обратите внимание на сокращение: без него процедура дает больше результатов, чем требуется:
?- occurences(a,[a,b,c,a],Res).
Res = [a, a] ;
Res = [a] ;
Res = [a] ;
Res = [] ;
false.
с разрезом:
?- occurences(a,[a,b,c,a],Res).
Res = [a, a].
edit @false испортил неприятную ошибку: здесь исправление, используя конструкцию if/then/else
occurences(_, [], []).
occurences(X, [Y|T], Os) :-
( X = Y
-> Os = [X|R]
; Os = R
),
occurences(X,T,R).
Рассматривать:
occurrences(_, [], []) :- !.
occurrences(X, [Y|L], R) :-
X \== Y, !,
occurrences(X, L, R).
occurrences(X, [Y|L], [Y|R]) :-
occurrences(X, L, R).
Тестирование:
?- occurrences(a,[a,b,a,c],O).
O = [a, a].
?- occurrences(a,[a,X,a,c],O).
O = [a, a].
?- occurrences(a,[a,X,a,c],[a]).
false.
?- occurrences(a,[a,X,a,c],[a,a]).
true.