Prolog - 为什么变量不受约束?

时间:2012-12-26 15:02:23

标签: list prolog

我已经定义了一个目标lowerpartition / 3如下:

lowerpartition(X,P,Z) :- var(Z),!,lowerpartition(X,P,[]).
lowerpartition([],_,_).
lowerpartition([X|Xs],P,Z) :- X=<P, lowerpartition(Xs,P,[X|Z]).
lowerpartition([X|Xs],P,Z) :- X>P, lowerpartition(Xs,P,Z).

当我打电话

lowerpartition([1,2,3,4,5],3,X).

我希望X绑定到列表[3,2,1],但Prolog只返回false。我做错了什么?

3 个答案:

答案 0 :(得分:5)

您似乎正在将基于累加器的方法与基于堆栈的方法混合使用。 你的第一个条款:

lowerpartition(X,P,Z) :- var(Z),!,lowerpartition(X,P,[]).

将保留Z未实例化,在检查它是变量之后不会使用它,因此它将不会被统一...

试试这个:

lowerpartition([], _, []).
lowerpartition([X|Xs], P, [X|Zs]):-
  X =< P, lowerpartition(Xs, P, Zs).
lowerpartition([X|Xs], P, Zs):-
  X > P, lowerpartition(Xs, P, Zs).

答案 1 :(得分:3)

因为您在第一个子句中使用了prolog不能统一的谓词。

lowerpartition(X,P,Z) :- var(Z),
                         !,
                         lowerpartition(X,P,[]). % here is what prolog cant unify 

对代码进行一点修改:

lowerpartition(X,P,Z) :- var(Z),lowerpartition_1(X,P,Z),!. % note the position of cut aswell

lowerpartition_1([],_,[]).
lowerpartition_1([X|Xs],P,[X|Z]) :- X=<P, lowerpartition_1(Xs,P,Z).
lowerpartition_1([X|Xs],P,Z) :- X>P, lowerpartition_1(Xs,P,Z).

希望这有帮助。

答案 2 :(得分:2)

这里是一个基于DCG的解决方案:我的简单测试返回与gusbro解决方案相同的结果。

lowerpartition(P), [X] --> [X], {X=<P}, lowerpartition(P), !.
lowerpartition(P) --> [X], {X>P}, lowerpartition(P).
lowerpartition(_) --> [].

这是如何调用它:

?- phrase(lowerpartition(3), [1,2,3,4,5,3,2,6,7], X).
X = [1, 2, 3, 3, 2].

但如果您使用带有lrary(apply)的Prolog,那么

lowerpartition(Xs, P, Rs) :- exclude(compare(<, P), Xs, Rs).

返回与上面相同的结果