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