Пролог: замена двух половинок списка

Я пишу предикат в прологе, который разбит список с четным числом переменных на две половины и поменяет их местами. Например, [a,b,c,d] -> [c,d,a,b].

append([], List, List).
append([Head|Tail], List, [Head|Rest]) :- 
   append(Tail, List, Rest).

divide(L, X, Y) :-
   append(X, Y, L),
   length(X, N),
   length(Y, N).

swap([], []).
swap([A], D) :-
   divide(A, B, C),
   append(C, B, D).

Я ожидал бы, что это сработает, разделив [A] на два меньших по размеру списка, затем сложив их вместе в обратном порядке, а затем назначив переменную "D" списку.

То, что я получаю, является "ложным", почему это не работает?
Я очень новичок в прологе, так что это может быть глупый / простой вопрос, спасибо!

1 ответ

Твой вопрос почему swap([a,b,c,d],[c,d,a,b]) выходит из строя. И вот настоящая причина:

? - swap ([_/ * a * /, _/ * b * /| _/ *, c, d * /], _/ * [c, d, a, b] * /).: - op (950, фу, *).
* (_).

своп ([], _/ * [] * /).
своп ([A], D):-
   * делить (A, B, C),
   * добавить (C, B, D).

Таким образом, не только ваш исходный запрос терпит неудачу, но даже это обобщение также терпит неудачу. Даже если вы спросите

?- swap([_,_|_],_).
false.

Вы просто получаете неудачу. Видеть это?

И вы можете спросить это и наоборот. С вышеупомянутым обобщением мы можем спросить:

?- swap(Xs, Ys).
   Xs = []
;  Xs = [_A].

Таким образом, ваш первый аргумент должен быть пустым списком или только одноэлементным списком. Вы, конечно, хотите описать также более длинные списки.

Может это поможет

:- use_module(library(lists), []).

 divide(L, X, Y) :-
 append(X, Y, L),
 length(X, N),
 length(Y, N).

 swap([], []).
 swap(L, D) :-
 divide(L, B, C),
 append(C, B, D).
Другие вопросы по тегам