需要帮助在 Prolog 中编写列表

Need help programming a list in Prolog

我需要帮助在 Prolog 中编写一个程序,如果列表有 n 个 [a, c] 和 m 个 b,则 returns 为真。但它必须是这样的顺序:a,b,c 如果列表中有字母 a,b,c。列表中a和c的个数必须相同,b的个数可以任意。示例:[] 为真,[b] 为真,[a,b,c] 为真,[a,c] 为真,[a,b,b,b,b,c] 为真,[a, a,b,c,c] 为真。但是 [b,c] 是假的,[a,b] 是假的,[a,a,b,c] 是假的。

这是我尝试做的,我有 n 个 a 和 m 个 b,但我只需要让列表以 n 个 c(与 a 相同)结尾:

langageAB([b]).

langageAB([b | S]):-
    langageAB(S).

langage8([]).

langage8([a,b]).

langage8([a | S]):-
    langage8(S).

langage8([a |S]):-
    langageAB(S).

更高效的答案:

abc_list3(ABCs) :-
    length(ABCs, ABCsLen),
    MaxAsLen is ABCsLen div 2,
    between(0, MaxAsLen, AsLen),
    % Same length for as and cs
    length(As, AsLen),
    length(Cs, AsLen),
    BsLen is ABCsLen - (AsLen * 2),
    length(Bs, BsLen),
    % Length of As, Bs and Cs has already been defined
    append([As, Bs, Cs], ABCs),
    % Contents of the 3 segments
    maplist(=(a), As),
    maplist(=(b), Bs),
    maplist(=(c), Cs).

swi-prolog 中的结果:

?- time(findnsols(13, L, abc_list3(L), Ls)).
% 554 inferences, 0.000 CPU in 0.000 seconds (100% CPU, 1735654 Lips)
Ls = [[],[b],[b,b],[a,c],[b,b,b],[a,b,c],[b,b,b,b],[a,b,b,c],[a,a,c,c],[b,b,b,b,b],[a,b,b,b,c],[a,a,b,c,c],[b,b,b,b,b,b]]

原始的、性能较差的答案:

abc_list2(ABCs) :-
    % Start at length 0, if ABCs is uninstantiated
    length(ABCs, _ABCsLen),
    append([As, Bs, Cs], ABCs),
    % Same length for as and cs
    length(As, AsLen),
    length(Cs, AsLen),
    % Contents of the 3 segments
    maplist(=(a), As),
    maplist(=(b), Bs),
    maplist(=(c), Cs).

swi-prolog 中的结果:

?- time(findnsols(13, L, abc_list2(L), Ls)).
% 982 inferences, 0.001 CPU in 0.001 seconds (100% CPU, 1957806 Lips)
Ls = [[], [b], [b, b], [a, c], [b, b, b], [a, b, c], [b, b, b, b], [a, b, b, c], [a, a, c, c], [b, b, b, b, b], [a, b, b, b, c], [a, a, b, c, c], [b, b, b, b, b, b]]

性能比较:

?- time(findnsols(5000, _, abc_list3(_), _)).
% 1,542,075 inferences, 0.125 CPU in 0.124 seconds (101% CPU, 12337474 Lips)

?- time(findnsols(5000, _, abc_list2(_), _)).
% 37,702,800 inferences, 4.226 CPU in 4.191 seconds (101% CPU, 8921614 Lips)