当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 和 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 ?-
预期的几种可能的解决方案。