2013-11-17 4 views
4

Мне нужно написать программу, которая возвращает новый список из данного списка со следующими критериями. Если член списка отрицательный или 0, он должен и это значение 3 раза в новый список. Если член положителен, он должен добавить значение 2 раза для этого списка. Например:Prolog напечатать значение как результат вместо истинного

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.

ответ

3

Ваш код готовит значение R, как она идет вниз рекурсии цепь сверху-вниз, рассматривая значение, переданное в качестве первоначального списка. Вызов dt/2 с пустым списком производит желаемый результат:

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

Demo #1 - Обратите внимание на обратный порядок

Это, однако, необычный способ делать вещи в Прологе: как правило, 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

+0

Спасибо, ваш ответ показывает, что мне все еще нужно узнать кое-что в Прологе. – kuldarim

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] . 
Смежные вопросы