2017-01-05 2 views
2

Я пытаюсь повернуть список в прологе рекурсивно, но он не работает должным образом.Повернуть список в прологе рекурсивно

Код:

rot([],[]). 
rot([H|T1], [T2|H]):-rot(T1,T2). 

Выход:

?- rot([1,2,3], V). 
V = [[[[]|3]|2]|1] 

Ожидаемый результат:

?- rot([1,2,3], V). 
V = [3,2,1] 

Может кто-нибудь объяснить мне, почему мой код не работает?

ответ

4

Поскольку Prolog нетипизирован, вы действительно можете написать что-то вроде [List|Element], но если вы хотите, чтобы список имел смысл, единственный способ построить списки - это как [Element|List]. Так что [T2|H] не имеет никакого смысла. В этом случае T2 должен быть элементом, а H - списком (или пустым списком []).

Вам нужно будет определить два предиката:

  • главный предикат (rot/2), который просто выталкивает голову из заданного списка и вызывает рекурсивный предикат; и
  • рекурсивный предикат (здесь rot/3), который просто передает все элементы данного списка и испускает исходную голову как хвост.

вместе это работает, как:

%main predicate rot/2 
rot([],[]). 
rot([H|T1],T2) :- 
    rot(T1,H,T2). 

%recursive predicate rot/3 
rot([],Last,[Last]). 
rot([H|T1],Last,[H|T2]) :- 
    rot(T1,Last,T2). 
3

Ваш код не работает, поскольку в выражении типа [H|T], H является элементом списка, а T - это хвост списка - также список. Например:

?- [H|T] = [1,2,3]. 
H = 1, 
T = [2, 3]. 

Так что происходит, когда вы переключаете это вокруг?

?- [H|T] = [1,2,3], X = [T|H]. 
H = 1, 
T = [2, 3], 
X = [[2, 3]|1]. 

Уточнить возникшую проблему?

2

Проблема с вторым пунктом. Что я делаю, чтобы повернуть хвост первого списка внутри L1 и затем вызвать append с L1 и первым элементом и присвоить результат L (второй аргумент)

my-append([], L, L). 
my-append([H|T], L, [H|R]) :- my-append(T, L, R). 

rot([], []). 
rot([H|T], L) :- rot(T, L1), my-append(L1, H, L). 
+0

Вы определяющие положения вида '- (my, append ([], L, L)). – mat

Смежные вопросы