我开始学习Prolog。该程序试图获取给定元素的所有出现:
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
答案 0 :(得分:5)
除了其他人写的内容外,请考虑使用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
不同,则出现列表为空。
答案 1 :(得分:1)
你已经被鲁本斯告知过你的错误。我只是添加一个样式注释:通常在Prolog中,首选直接在头部参数中编码模式:
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].
编辑 @false破坏了一个令人讨厌的错误:这里使用if / then / else构造进行修正
occurences(_, [], []).
occurences(X, [Y|T], Os) :-
( X = Y
-> Os = [X|R]
; Os = R
),
occurences(X,T,R).
答案 2 :(得分:0)
考虑:
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.