Recursion 序言:映射到列表的ID号
我有一个变量X,它可能包含多个值:X=1;X=4;X=7 这些值映射到包含x、y、z或w的列表。这些值/列表对中的每一个都被拆分为多个事实,因此我可以:Recursion 序言:映射到列表的ID号,recursion,prolog,counter,Recursion,Prolog,Counter,我有一个变量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)
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的出现次数,等等。您使用的Prolog变量是错误的。变量实例化后不能更改其值,除非Prolog回溯到实例化之前的选择点。例如,在
count/5
规则中,将A
统一为零,然后期望满足检查列表(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).