列表中的Prolog约束

列表中的Prolog约束,prolog,Prolog,我在prolog中遇到了一个问题,它要求对一个由四个元素组成的列表进行所有可能的排列(一个元素可以是1、2或X),但我必须在该列表中添加两个限制。它的最后一个元素不能是符号“X”,排列不能包含符号“1”超过2次。我不知道应该在哪里以及如何设置这些约束。有人能给我一些建议吗 domains elem=symbol list=elem* predicates elimin(elem,list,list) perm(list,list) clauses e

我在prolog中遇到了一个问题,它要求对一个由四个元素组成的列表进行所有可能的排列(一个元素可以是1、2或X),但我必须在该列表中添加两个限制。它的最后一个元素不能是符号“X”,排列不能包含符号“1”超过2次。我不知道应该在哪里以及如何设置这些约束。有人能给我一些建议吗

domains
    elem=symbol
    list=elem*

predicates
    elimin(elem,list,list)
    perm(list,list)


clauses
    elimin(H,T,[H|T]).
    elimin(H,[A|T],[A|X]):-
            elimin(H,T,X).
    perm([],[]).
    perm([H|T],X):-
        perm(T,T1),
        elimin(H,T1,X).
当前代码:

    domains
        elem=symbol
        list=elem*

    predicates
        valid(list)
        generate(list)
        count(list,elem,integer)
        member(symbol,list)
    clauses
        valid(S):- 
            generate(S),count(S,1,C),C<2.

        generate([A,B,C,D]) :-
            member(A,["1","2","X"]),
            member(B,["1","2","X"]),
            member(C,["1","2","X"]),
            member(D,["1","2"]).
    member(X,[X|_]).
    member(X,[_|T]):- member(X,T).      
    count([],_,0).
        count([H|T],X,C):- H<>X,
                count(T,X,C).
        count([H|T],X,C1):- H=X,
                count(T,X,C),
                C1=C+1.
域
元素=符号
列表=元素*
谓词
有效(列表)
生成(列表)
计数(列表、元素、整数)
成员(符号、列表)
条款
有效日期:

生成(S)、计数(S、1、C)、C从您的评论中可以看出,您的perm/2显然是无用的

显而易见的方法是将生成器与只接受有效序列的过滤器连接起来。 如果发电机避免将1置于最后位置,则程序计数/3就足够了。 生成器使用非确定性成员/2很容易编写

注意:保持常量小写(
x
而不是
x
)很方便

valid(S):-生成(S),计数(S,1,C),C<2。
生成([A,B,C,D]):-
成员(A、[1,2,x]),
成员(B,[1,2,x]),
成员(C[1,2,x]),
成员(D,[2,x])。

看看你是否可以自己写count/3…

如果你删除一个1,你就剩下3个元素要排列了?为这些条件编写测试,你会发现你已经编写了代码。第二个条件毫无意义。如果排列不能包含两次以上的“1”,则原始列表也不能。@SQB我更新了要求。我应该在该列表中找到的唯一值是1,2和X。因此可能存在类似[2,2,2,2]或[1,1,1,1]的解决方案。那么您就不需要寻找排列。
count([],X,0)。count([H | T],X,C):-H=X,C=C+1,count(T,X,C)
这样行吗?当
H\=X
时,您错过了“else”分支。然后计数将失败…并且无法重新分配到
C
。使用
C1是C+1
计数([],X,0)。计数([H | T],X,C):-H=X,C是C+1,计数(T,X,C)。count([H | T],X,C):-H\=X,count(T,X,C)。
好的,我想它现在应该可以工作了,对吧?应该是
count([H | T],X,C1):-H=X,count(T,X,C),C1是C+1。
尝试过,它说给出了“未声明的谓词或拼写错误”,将光标定位在
C1下的
C1是C+1
我用当前代码更新了帖子。
valid(S) :- generate(S), count(S,1,C), C < 2.

generate([A,B,C,D]) :-
    member(A,[1,2,x]),
    member(B,[1,2,x]),
    member(C,[1,2,x]),
    member(D,[2,x]).