当Prolog在寻找解决方案的过程中遇到“选择点”(代码中它可以回来寻求更多可能解决方案的地方)时,它会显示该解决方案并提示您提供更多可能的解决方案。如果找不到更多内容,则显示“false”。这不是你的逻辑错误。这就是 Prolog 的工作方式。
删除选择点并不总是可取的。这取决于您的谓词目标是什么。使用剪切删除选择点的危险在于,选择点可能是通向有效替代解决方案的路径,而剪切会阻止您的程序找到这些解决方案。
让我们尝试使用答案中新建议的削减来更新程序:
| ?- count([[1,2,3],[4,1,5],[4,6,1]], 1, X).
X = 3
yes
| ?- count([[1,2,1,3],[4,1,5],[4,6,1]], 1, X).
X = 4
yes
| ?- count([[1,2,1,3],[4,1,5],[4,6,1],[1]], 1, X).
X = 5
到目前为止,一切都很好。这些看起来像是完整且正确的答案。我相信只要第一个参数完全绑定且没有变量,您的附加剪切(包括原始剪切)就会产生正确的答案。让我们尝试一个更有趣的查询:
2 ?- count([[A,2,B],[C,1,D]], 1, X).
A = B, B = C, C = D, D = 1,
X = 5.
3 ?-
谓词找到了一种解决方案。然而,不是还有更多吗?这个如何?
A = _ % something other than 1
B = C, C = D, D = 1,
X = 4.
这也是一个正确的解决方案,但谓词无法找到它。
另外,这个查询怎么样?
2 ?- count([[1,2,1,3],[4,1,5],[4,6,1],[1]], E, X).
E = 1,
X = 5.
3 ?-
同样,只找到一种解决方案。但不是还有更多吗?关于什么E = 4
and X = 2
?
如果我们从原始谓词中删除所有削减以尝试获得所有正确的解决方案,那么我们也会得到错误的解决方案:
2 ?- count([[1,2],[3,1,4],[1]], 1,X).
X = 3 ;
X = 2 ;
X = 2 ;
X = 1 ;
X = 2 ;
X = 1 ;
X = 1 ;
X = 0 ;
false.
2 ?- count([[1,2,1,3],[4,1,5],[4,6,1],[1]], E, X).
E = 1,
X = 5 ;
E = 1,
X = 4 ;
E = 1,
X = 3 ;
...
因此,如果需要更多的通用性,就需要构建更有效的解决方案。
count_occurrences_lol([], _, 0).
count_occurrences_lol([List|Lists], X, Count) :-
count_occurrences(List, X, C1), % Count occurrences in this list
count_occurrences_lol(Lists, X, C2), % Count occurrences in remaining sublists
Count is C1 + C2. % Total the counts
count_occurrences([], _, 0).
count_occurrences([X|Xs], X, Count) :-
count_occurrences(Xs, X, C1),
Count is C1 + 1.
count_occurrences([X1|Xs], X, Count) :-
dif(X1, X),
count_occurrences(Xs, X, Count).
现在我们得到以下信息:
3 ?- count_occurrences_lol([[1,2],[3,1,4],[1]], 1,X).
X = 3 ;
false.
正如预期的那样,只有一种解决方案。以及以下内容:
5 ?- count_occurrences_lol([[A,2,B],[C,1,3]], 1, X).
A = B, B = C, C = 1,
X = 4 ;
A = B, B = 1,
X = 3,
dif(C, 1) ;
A = C, C = 1,
X = 3,
dif(B, 1) ;
A = 1,
X = 2,
dif(B, 1),
dif(C, 1) ;
B = C, C = 1,
X = 3,
dif(A, 1) ;
B = 1,
X = 2,
dif(A, 1),
dif(C, 1) ;
C = 1,
X = 2,
dif(A, 1),
dif(B, 1) ;
X = 1,
dif(A, 1),
dif(B, 1),
dif(C, 1) ;
false.
3 ?- count_occurrences_lol([[1,2,1,3],[4,1,5],[4,6,1],[1]], E, X).
E = 1,
X = 5 ;
E = 2,
X = 1 ;
E = 3,
X = 1 ;
E = 4,
X = 2 ;
E = 5,
X = 1 ;
E = 6,
X = 1 ;
X = 0,
dif(E, 1),
dif(E, 1),
dif(E, 6),
dif(E, 4),
dif(E, 5),
dif(E, 1),
dif(E, 4),
dif(E, 3),
dif(E, 1),
dif(E, 2),
dif(E, 1).
4 ?-
正如预期的几种可能的解决方案。