2013-05-10 31 views
2

我试图做一个谓词,需要两个向量/列表,并使用第一个作为过滤器。例如:PROLOG列表过滤器谓词不是正确或错误

?- L1=[0,3,0,5,0,0,0,0],L2=[1,2,3,4,5,6,7,8],filter(L1,L2,1). 
    L1 = [0, 3, 0, 5, 0, 0, 0, 0], 
    L2 = [1, 2, 3, 4, 5, 6, 7, 8] . 

这就是我得到,但我想truefalse如果L2具有30 s的忽略第二个元素,5作为第四个元素,等等,这就是“过滤器“条件。 我从输入中得知,L1和L2总是长度= 8,只有L1有0 s。

我的代码是:

filter(_,_,9). 
filter([Y|T],V2,Row):- 
    Y=:=0, 
    NewRow is Row + 1, 
    filter([Y|T],V2,NewRow). 

filter([Y|T],V2,Row):- 
    Y=\=0, 
    nth(Row,[Y|T],X1), 
    nth(Row,V2,X2), 
    X1=:=X2, 
    NewRow is Row + 1, 
    filter([Y|T],V2,NewRow). 


nth(1,[X|_],X). 
nth(N,[_|T],R):- M is N-1, nth(M,T,R). 

我知道有第一的第一个元素进行比较,以第二的第n个这样的功能的更好的方法,例如,删除第一个使用递归的头但我只想知道为什么我没有得到truefalse或任何“返回”值。

有人可以帮助我?得到它的工作

新代码:

permutation([1,2,3,4,5,6,7,8],X),filter([1,2,3,4,0,0,0,0],X,1,R). 
X = R, R = [1, 2, 3, 4, 5, 6, 7, 8] ; 
X = R, R = [1, 2, 3, 4, 5, 6, 8, 7] ; 
X = R, R = [1, 2, 3, 4, 5, 7, 6, 8] ; 
X = R, R = [1, 2, 3, 4, 5, 7, 8, 6] . 

现在我可以得到所有以1开头的排列:预期行为的

filter([],R,_,R). 
filter([Y|T],V2,Row,R):- 
Y=:=0, 
NewRow is Row + 1, 
filter(T,V2,NewRow,R). 

filter([Y|T],V2,Row,R):- 
Y=\=0, 
nth(Row,V2,X2), 
Y=:=X2, 
NewRow is Row + 1, 
filter(T,V2,NewRow,R). 

例,2,3,4。 如果有人知道更好的方式来实现相同的PLZ份额,但我已经得到了我所需要的=)。

+0

谢谢谁接受了两个“我”的编辑(第二个是在时间上发生冲突,与我第一次的OP编辑)审查人员 - 的别人,耻辱你! – pnuts 2013-05-11 00:19:37

+0

我不明白发生了什么,但我添加了第n个谓词,但是它缺少一些文本,我添加了O.o,pnuts,你知道我的代码有什么问题吗? – 2013-05-11 00:32:16

+0

对不起,我只是在帮助翻译,我知道ZILCH关于PROLOG(而且对其他方面很少)!如果您想进一步编辑,请随时取得。 – pnuts 2013-05-11 00:34:37

回答

3

看起来可能是MAPLIST一个完美的任务/ 3

filter(L1, L2, _) :- 
    maplist(skip_or_match, L1, L2). 

skip_or_match(E1, E2) :- E1 == 0 ; E1 == E2. 

产生

?- permutation([1,2,3,4,5,6,7,8],X),filter([1,2,3,4,0,0,0,0],X,_). 
X = [1, 2, 3, 4, 5, 6, 7, 8] ; 
X = [1, 2, 3, 4, 5, 6, 8, 7] ; 
X = [1, 2, 3, 4, 5, 7, 6, 8] ; 
X = [1, 2, 3, 4, 5, 7, 8, 6] ; 
... 

我们可以做更多的有用,使用Prolog的设施 - 即使用anonymus variable表达don't care

然后过滤/ N是MAPLIST的一个简单的应用:

?- permutation([1,2,3,4,5,6,7,8],X),maplist(=,[1,2,3,4,_,_,_,_],X). 
X = [1, 2, 3, 4, 5, 6, 7, 8] ; 
X = [1, 2, 3, 4, 5, 6, 8, 7] ; 
X = [1, 2, 3, 4, 5, 7, 6, 8] ; 
X = [1, 2, 3, 4, 5, 7, 8, 6] ; 
... 
+0

Thx,我知道我忘记了一些东西,maplist做了我需要的正确方法 – 2013-05-11 14:52:26

2

您的代码总是测试过滤列表的第一项为零。例如,看一下情况,当你检查第二个值:

filter([0,3,0,5,0,0,0,0], [1,2,3,4,5,6,7,8], 2). 

此调用将执行以下unifications:

# first case: obvious fail… 
filter([0,3,0,5,0,0,0,0], [1,2,3,4,5,6,7,8], 2) =\= filter(_, _, 9). 

# second case: 
filter([0,3,0,5,0,0,0,0], [1,2,3,4,5,6,7,8], 2) = filter([Y|T],V2,Row). 
# unification succeeds with substitutions: 
    Y = 0 
    T = [3,0,5,0,0,0,0] 
    V2 = [1,2,3,4,5,6,7,8] 
    Row = 2 
# and what happens next? 
    Y =:= 0 # success! 

你可能想在这里检查是否元素[ Y | T]为零;相反,你正在检查第一个。如果你要修复它在不改变你的代码的其余部分,则应该进行比较,X1:

filter(V1,V2,Row):- 
    nth(Row, V1, X1), 
    X1 =:= 0, 
    NewRow is Row + 1, 
    filter(V1,V2,NewRow). 

filter(V1,V2,Row):- 
    nth(Row,V1,X1), 
    X1=\=0, 
    nth(Row,V2,X2), 
    X1=:=X2, 
    NewRow is Row + 1, 
    filter(V1,V2,NewRow). 

此外,还有,我认为你可能不会在序言越来越但一两件事。如果谓词失败,Prolog确实会打印false并停止计算。但是,如果谓词成功,则有两种情况:

  • 如果查询中没有变量,则Prolog将打印true
  • 如果查询中有任何变量,Prolog不打印true。相反,它会输出变量的值。这计为true

在你的情况的Prolog实际上是“返回” true从谓只是因为你已经在使用您的查询的变量,它打印自己的价值,而不是打印true的。

+0

嗨,刚刚解决它,我会添加代码和一个例子,但我其实想要比较检查V1的第一个元素是否为0,因为在那种情况下,我忽略它并继续比较下一个元素,我只关心那些元素!= 0 – 2013-05-11 01:42:17