Prolog打印值作为结果而不是true

时间:2013-11-17 12:26:08

标签: printing prolog

我需要编写一个程序,它使用以下条件从给定列表返回一个新列表。 如果列表成员为负数或0,则该值应为新列表的3倍。如果成员是肯定的,它应该为该列表增加2倍的值。 例如:

goal: dt([-3,2,0],R).
R = [-3,-3,-3,2,2,0,0,0].

我编写了以下代码,它对我来说很好,但它返回true而不是R = [some_values]

我的代码:

dt([],R):- write(R). % end print new list
dt([X|Tail],R):- X =< 0, addNegavite(Tail,X,R). % add 3 negatives or 0
dt([X|Tail],R):- X > 0, addPositive(Tail,X,R). % add 2 positives
addNegavite(Tail,X,R):- append([X,X,X],R,Z), dt(Tail, Z).
addPositive(Tail,X,R):- append([X,X],R,Z), dt(Tail, Z).

也许有人知道如何打印R = []而不是true

2 个答案:

答案 0 :(得分:3)

为什么在你的条款中打电话给write

最好不要在你的条款中产生副作用:

dt([], []).
dt([N|NS], [N,N,N|MS]) :-
    N =< 0,
    dt(NS, MS).
dt([N|NS], [N,N|MS]) :-
   N > 0,
   dt(NS, MS).

这将有效:

?- dt([-3,2,0], R).
R = [-3, -3, -3, 2, 2, 0, 0, 0] .

在子句中不调用带副作用的函数的另一个好处是反过来也可以:

?- dt(R, [-3, -3, -3, 2, 2, 0, 0, 0]).
R = [-3, 2, 0] .

您可以在条款之外调用write

?- dt([-3,2,0], R), write(R).
[-3,-3,-3,2,2,0,0,0]
R = [-3, -3, -3, 2, 2, 0, 0, 0] .

答案 1 :(得分:3)

您的代码准备R的值,因为它从顶部到底部递归到递归链,将传入的值视为初始列表。使用空列表调用dt/2会产生所需的输出:

:- dt([-3,2,0],[]).

Demo #1 - 请注意相反的顺序

然而,这是在Prolog中执行操作的一种不寻常的方式:通常,R是您的返回值,以相反的方式生成,当基本案例服务于“空列表”情况时,其余的规则从空列表中得出结果:

dt([],[]). % Base case: empty list produces an empty list
dt([X|Like],R):- X =< 0, addNegavite(Like,X,R).
dt([X|Like],R):- X > 0, addPositive(Like,X,R).
% The two remaining rules do the tail first, then append:
addNegavite(Like,X,R):- dt(Like, Z), append([X,X,X], Z,  R).
addPositive(Like,X,R):- dt(Like, Z), append([X,X], Z, R).

Demo #2