сначала посмотрите на следующий пример:
?- fp(X,[b,a,b]).
false Хорошо, потому что второй аргумент должен быть отсортированным списком из двух элементов. (В моей программе я предполагаю, что a<b
)
?-fp(X,[a,b,b]).
X = [a, b, b] ;
X = [b, a, b] ;
X = [b, b, a] ;
false.
Да, это правильный результат.
Однако для
?-fp ([b,a,b], X)
X = [a,b,b].
Да, это ожидаемый результат.
Однако в случае
?-fp ([b,a,b], X)
X = [a,b,b];
Вот и зацикливается....
Есть ли способ справиться с этим циклом? Я долго думал, но безрезультатно. Можешь попробовать мне помочь?
fp(L, F) :-
fp(L, [], [], F).
fp([], AccA, AccB, F):-
append(AccA, AccB, F), !.
fp([a|L], AccA, AccB, F) :-
append([a|AccA], _, F),
fp(L, [a|AccA], AccB, F).
fp([b|L], AccA, AccB, F) :-
append(_, [b|AccB], F),
fp(L, AccA, [b|AccB], F).
trace
, чтобы посмотреть, что происходит? - person lurker   schedule 18.05.2016!
послеfp(L, AccA, [c|AccB], F).
, это не зацикливается, но дает неверный результат (не все возможности), когда первым аргументом являетсяX
. - person   schedule 18.05.2016X
иAccA
являются одноэлементными. Это намеренно? Кроме того, второе предложение кfp/4
вызываетfp([b|AccA], _, F)
(fp/3
), которого не существует. - person lurker   schedule 18.05.2016append(_, [b|AccB], F)
иappend([a|AccA], _, F)
напрашиваются на неприятности. Существует почти бесконечное количество решений для этих запросов, и (если вы посмотрите на свойtrace
) ваш код зацикливается, проверяя каждое из них, пытаясь найти другое решение. Вы хотите подумать о рефакторинге, чтобы избежать этих конкретных запросов. - person lurker   schedule 18.05.2016!/0
: это разрушает логический смысл вашей программы. Например, попробуйте с текущей версией запрос:?- fp(L, F).
. Вы получаете только единственное решение,F = L = []
. Очевидно, должно быть гораздо больше терминов, для которых выполняется это соотношение! - person mat   schedule 18.05.2016append
не так просто.. - person   schedule 18.05.2016append/3
очень удобен и всегда заманчив для использования. Однако иногда более подходящим является пользовательский предикат, который более точно делает то, что вам нужно, а иногда есть способ ограничить аргументы дляappend/3
, чтобы они были более ограниченными. Или, может быть, есть способ полностью переосмыслить проблему... - person lurker   schedule 18.05.2016