使用谓词检查 X 是否在列表中恰好出现四次的问题

问题描述 投票:0回答:1

我正在尝试编写一个谓词

fourExactly(X, List)
,它检查变量
X
是否在
List
中出现了四次。如果是这种情况,谓词应该为 true,如果不是,则谓词应该为 false。这是我当前的实现:

fourExactly(X, List) :-
    count_occurrences(X, List, 4).
% Base case: An empty list has zero occurrences of any element.
count_occurrences(_, [], 0).
% Recursive case: If the head of the list is X, increment the count.
count_occurrences(H, [H|T], Count) :-
    count_occurrences(H, T, RestCount),
    Count is RestCount + 1.
% Recursive case: If the head of the list is not X, do not increment the count.
count_occurrences(H, [_|T], Count) :-
    count_occurrences(H, T, Count).

如果

X
中的
List
少于四个(假),并且恰好有四个(真),我当前的实现可以正常工作。如果超过四个,它将停止正常运行,输出如下所示:

?- fourExactly(n, [n, n, n, n, n, a]).
Yes (0.00s cpu, solution 1, maybe more)
Yes (0.00s cpu, solution 2, maybe more)
Yes (0.00s cpu, solution 3, maybe more)
Yes (0.00s cpu, solution 4, maybe more)
Yes (0.00s cpu, solution 5, maybe more)
No (0.00s cpu)

我认为这与 Prolog 的后链有关,但我不知道如何解决它。我将不胜感激任何帮助。

提前感谢您的帮助

prolog swi-prolog
1个回答
0
投票

使用

dif
,从零开始计数,并防止计数超过最大值(如果指定了最大值):

select_eq_count(L, E, C) :- 
    % Start counting at 0
    select_eq_count_(L, E, 0, C).

% End of list, so unify the count
select_eq_count_([], _, C, C).
select_eq_count_([H|T], E, U, C) :-
    % Different
    dif(H, E),
    select_eq_count_(T, E, U, C).
select_eq_count_([E|T], E, U, C) :-
    % The head of the list is equal to the element
    % Prevent exceeding the count if specified
    (   nonvar(C)
    % Comparing Count to Upto
    ->  C > U
    ;   true
    ),
    U1 is U + 1,
    select_eq_count_(T, E, U1, C).

这是非常普遍的,例如无需指定计数:

?- length(L, 2), select_eq_count(L, E, C).
L = [_A, _B],
C = 0,
dif(_A, E),
dif(_B, E) ;
L = [_A, E],
C = 1,
dif(_A, E) ;
L = [E, _A],
C = 1,
dif(_A, E) ;
L = [E, E],
C = 2.

...然后可以数到 4,例如:

?- length(L, 5), select_eq_count(L, E, 4).
L = [_A, E, E, E, E],
dif(_A, E) ;
L = [E, _A, E, E, E],
dif(_A, E) ;
L = [E, E, _A, E, E],
dif(_A, E) ;
L = [E, E, E, _A, E],
dif(_A, E) ;
L = [E, E, E, E, _A],
dif(_A, E) ;
false.
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.