我试图在列表L中找到X的出现次数 例如: -
occurrences(a, [b, a, b, c, a, d, a], N ).
N =3
我的代码无效。这是我的代码。
occ(K,L,N) :- N1=0, occ1(K,L,N1,N).
occ1(K,[],N1,N) :- N=N1.
occ1(K,L,N1,N) :-
L=[X|L1],
( K=X -> N1 is N1+1, occ1(K,L1,N1,N) ; occ1(K,L1,N1,N) ).
有人能告诉我代码中有什么问题。
答案 0 :(得分:2)
虽然@Kay给出的答案在修复错误方面是现实的,但它完全绕过了一个更大的问题:occ1/4
的代码逻辑上不纯。
这对你来说可能不是很重要, 但使用不纯的代码有几个负面后果:
为了表明在按照建议@Kay“修复”后代码中存在这些问题,让我们考虑“已更正”的代码和一些查询。首先,这是更正后的代码:
occ(K,L,N) :- N1=0, occ1(K,L,N1,N).
occ1(_,[],N1,N) :- N=N1.
occ1(K,L,N1,N) :-
L=[X|L1],
( K=X -> N2 is N1+1, occ1(K,L1,N2,N) ; occ1(K,L1,N1,N) ).
以下是您在问题中提供的查询:
?- occ(a,[b,a,b,c,a,d,a],N).
N = 3 ;
false.
好!如果我们以不同的方式编写查询怎么办?
?- A=a,B=b,C=c,D=d, occ(a,[B,A,B,C,A,D,A],N).
A = a, B = b, C = c, D = d, N = 3 ;
false.
好!如果我们重新排序目标怎么办?逻辑连接应该是可交换的......
?- occ(a,[B,A,B,C,A,D,A],N), A=a,B=b,C=c,D=d.
false.
失败! 似乎 occ1/4
没问题,但现在我们得到了一个逻辑上不健全的答案。
使用逻辑纯代码可以避免这种情况: 查看我在my answer中向相关问题“Prolog - count repititions in list (sic)”提供的纯色和单调代码。
答案 1 :(得分:1)
问题是
N1 is N1+1
变量不能被覆盖"在Prolog。您只需要一个新变量,例如
N2 is N1+1, occ1(K,L1,N2,N)
问题"我们可以替换特定的列表元素吗?如果是,语法是什么?":
您只能构建新列表:
replace(_, _, [], []).
replace(Old, New, [H0|T0], [H1|T1]) :-
(H0 = Old -> H1 = New; H1 = H0),
replace(Old, New, T0, T1).