2012-04-19 73 views
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). 

感谢您的帮助!

回答

0

序列变量不能被'修改',因为你试图调用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). 
1

您的问题说明会谈。这是一个非常必要的程序性描述。试着首先关注关系应该描述的内容。其实,我还没有理解2的最小长度是多少。

考虑使用预定义的append/3length/2来代替您自己的定义。但实际上,在你的例子中都不需要。

您可能想要使用专用结构q(X,Y,S,P)代替列表[X,Y,S,P]

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

 
?- append([X,Y,S,P],Temp,Temp). 
Temp = [X, Y, S, P|Temp]. 

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

 
?- set_prolog_flag(occurs_check,error). 
true. 

?- append([X,Y,S,P],Temp,Temp). 
ERROR: lists:append/3: Cannot unify _G392 with [_G395,_G398,_G401,_G404|_G392]: would create an infinite tree 

目标=\=/2指算术不平等,你可能更喜欢dif/2代替。

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

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

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