我有一个可能包含多个值的变量X:X = 1; X = 4; X = 7 ......
这些值映射到包含x,y,z或w的列表。这些值/列表对中的每一个都被分成多个事实,所以我可以:
map(2,[x,y]).
map(3,[x]).
map(9,[y,w]).
我试图编写一个程序,给定X,我可以查找这些列表并计算有多少次出现的x,y,z或w。
这是我的尝试:
count(A,B,C,D,X) :- A = 0, B = 0, C = 0, D = 0,
check_list(X,x,A),
check_list(X,y,B),
check_list(X,z.C),
check_list(X,w,D).
check_list(X,Element,Counter) :-
map(X, List),
member(List, Element),
S is Counter + 1,
Counter = S.
我的程序背后的想法是我调用check_list来检查是否有一个成员包含x,y,z,w的每个可能的X值。如果有该成员,我将递增计数器。然后我希望A,B,C,D的值具有A = x的出现次数,B = y的出现次数等等。
答案 0 :(得分:2)
您正在使用Prolog变量错误。变量实例化后,变量不能更改值,除非Prolog回溯到实例化之前的选择点。例如,在count/5
的规则中,您将A
统一为零,然后您希望满足check_list(X,x,A)
会将A
绑定到x
的出现次数,但A
此时不是自由变量。
因此,您必须从第一条规则中删除A = 0, ..., D = 0
。
接下来,您需要一个可用于查找列表中元素出现次数的谓词。您可以使用findall/3
:
occurrences(X, List, N):- findall(_, member(X, List), O), length(O, N).
或者你可以自己写一下:
occurrences(_, [], 0).
occurrences(X, [X|Tail], N):-!, occurrences(X, Tail, N1), N is N1 + 1.
occurrences(X, [_|Tail], N):-occurrences(X, Tail, N).