Пролог: замена двух половинок списка
Я пишу предикат в прологе, который разбит список с четным числом переменных на две половины и поменяет их местами. Например, [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).