我正在尝试创建一个带有两个向量/列表的谓词,并使用第一个作为过滤器。例如:
?- 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] .
这就是我得到的但是如果L2有true
作为第二个元素,false
作为第四个元素,我希望3
或5
等等。 0
被忽略,这就是“过滤”条件。
我从输入中得知的是,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).
我知道有更好的方法来完成这个功能,例如比较第一个元素和第二个元素的第一个元素,并用递归删除第一个元素,但我只是想知道为什么我没有得到true
或false
,或任何“返回”值。
有人可以帮助我吗?让它运转
新代码:
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).
预期行为的示例:
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,2,3,4开头的所有排列。 如果有人知道一个更好的方法来实现相同的,PLZ分享,但我已经得到了我需要的东西=)。
答案 0 :(得分: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
。
然后filter / 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] ;
...
答案 1 :(得分:2)
您的代码始终会将过滤列表的第一项测试为零。例如,查看第二个值时的情况:
filter([0,3,0,5,0,0,0,0], [1,2,3,4,5,6,7,8], 2).
此调用将执行以下统一:
# 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]的 second 元素是否为零;相反,你正在检查第一个。如果要在不更改其余代码的情况下修复它,则应该执行与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。如果谓词失败,Prolog确实打印false
并停止计算。但如果谓词成功,则有两种情况:
true
。true
。相反,它会打印变量值。此也计为true
。在你的情况下,Prolog实际上从你的谓词中“返回”true
- 除了因为你在查询中使用了变量,它打印了它们的值而不是打印true
。