0

我是 Prolog 的新手,我被困在我正在尝试做的谓词上。它的目的是通过给定 P 的四边形列表 [X,Y,S,P] 进行递归,当四边形具有相同的 P 时,它将其存储在临时列表中。当它遇到一个新的 P 时,它会查看临时列表是否大于长度 2,如果是则将临时列表存储在输出列表中,如果小于 2 则删除四边形,然后再次开始递归新 P.
这是我的代码:

  deleteUP(_,[],[],[]).  
  deleteUP(P,[[X,Y,S,P]|Rest],Temp,Output):-
         !,  
         appends([X,Y,S,P],Temp,Temp),  
         deleteUP(P,[Rest],Temp,Output).  

 deleteUP(NextP,[[X,Y,S,P]|Rest],Temp,Output):-
       NextP =\= P,
       listlen(Temp,Z),
       Z > 1, !,
       appends(Temp,Output,Output),
       deleteUP(NextP,[_|Rest],Temp,Output).

 listlen([], 0).
 listlen([_|T],N) :- 
       listlen(T,N1), 
       N is N1 + 1.

 appends([],L,L).
 appends([H|T],L,[H|Result]):-
       appends(T,L,Result).  

谢谢你的帮助!

4

2 回答 2

1

您的问题描述谈到了存储、递归和启动。这是一个非常必要的、程序性的描述。尝试首先关注关系应该描述的内容。实际上,我仍然不明白 2 的最小长度是什么。

考虑使用预定义的append/3length/2代替您自己的定义。但实际上,您的示例中不需要两者。

您可能希望使用专用结构q(X,Y,S,P)来代替 list [X,Y,S,P]

目标appends([X,Y,S,P],Temp,Temp)表明您假设逻辑变量Temp可以像命令式语言中的变量一样使用。但这种情况并非如此。默认情况下,SWI 在这里创建了一个非常奇怪的结构,称为“无限树”。暂时忘记这个。

?-附加([X,Y,S,P],温度,温度)。
温度 = [X、Y、S、P|温度]。

SWI 中有一种安全的方法可以避免此类情况并自动检测(某些)此类错误。打开发生检查!

?- set_prolog_flag(occurs_check,error)。
真的。

?-附加([X,Y,S,P],温度,温度)。
错误:lists:append/3:无法将 _G392 与 [_G395,_G398,_G401,_G404|_G392] 统一:将创建无限树

目标=\=/2意味着算术不等式,您可能更喜欢dif/2

避免!- 在这种情况下不需要。

length(L, N), N > 1通常更好地表示为L = [_,_|_]

然而,主要问题是第三和第四个论点应该是什么。你真的需要先澄清这一点。

于 2012-04-19T14:27:09.967 回答
0

Prolog 变量不能被“修改”,因为您正在尝试调用 append:您需要一个新的变量来放置结果。请注意,此代码未经测试...

deleteUP(_,[],[],[]).

deleteUP(P,[[X,Y,S,P]|Rest],Temp,Output):-
         !,  
         appends([X,Y,S,P],Temp,Temp1),  
         deleteUP(P, Rest, Temp1,Output). % was deleteUP(P,[Rest],Temp,Output).  

deleteUP(NextP,[[X,Y,S,P]|Rest],Temp,Output1):-
       % NextP =\= P, should be useless given the test in clause above
       listlen(Temp,Z),
       Z > 1, !,  % else ?
       deleteUP(NextP,[_|Rest],Temp,Output),
       appends(Temp,Output,Output1).
于 2012-04-19T13:54:18.923 回答