如何在这样的序言中编写程序

How to code a program in prolog based like this

我正在尝试在 prolog 中编写一个程序,该程序仅使用字母 {a,b,c} 并采用 l 个 a、m 个 b 和 n 个 c。但必须是a,b,c的顺序。示例:[a,b,c] 为真,[a,a,b,b,c] 为真,[a,b] 为真,[a] 为真,[b] 为真,[c] 为真,[a,c] 为真,[b,c] 为真,[a,a,a,b,b] 为真。但是 [b,a,c] 是假的,[c,b] 也是假的,[b,b,b,c,c,c,a] 也是如此。因为顺序错了。 这是我尝试做的,但它并不完全符合我的要求:

langageAB([b]).

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

langageAC([c]).

langageAC([c | S]):-
    langageAC(S).

langage7([a, b, c]).

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

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

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

langage7([b | S]):-
    langageAC(S).

您可以首先定义一个谓词来创建一个 差异列表 ,其中包含零个或多个等于 X 的元素。使用这种数据结构,新元素的连接可以在常数时间内完成。在下面的定义中,差异列表由谓词langage_x/3.

的第二个和第三个参数组成的对表示
langage_x(_, S, S).
langage_x(X, [X|S], T) :-
    langage_x(X, S, T).

示例:

?- langage_x(a, A, B).
A = B ;
A = [a|B] ;
A = [a, a|B] ;
A = [a, a, a|B] .

?- langage_x(a, A, []).
A = [] ;
A = [a] ;
A = [a, a] ;
A = [a, a, a] .

注意,如果A = [a,a,a|B],例如,那么差异列表A-B代表列表[a,a,a]。此外,变量 B 的实例化会自动扩展表示的列表(或关闭它,如果 B 是用 [] 实例化的)。

之后,你可以定义谓词langage7/1如下:

langage7(A) :-
    langage_x(a, A, B),
    langage_x(b, B, C),
    langage_x(c, C, []). % this last goal closes the list!

要检查一个序列是否属于该语言,你可以问:

?- langage7([a,a,b,c,c,c]).
true .

?- langage7([a,a,c,c]).
true .

?- langage7([a,b,a,c,c]).
false.

要生成该语言的所有序列,你可以问:

?- length(L, _), langage7(L).
L = [] ;
L = [c] ;
L = [b] ;
L = [a] ;
L = [c, c] ;
L = [b, c] ;
L = [b, b] ;
L = [a, c] ;
L = [a, b] ;
L = [a, a] ;
L = [c, c, c] ;
...