2015-04-27 4 views
2

мне нужно написать предикат partition/2 таким образом, что partition(L, P) удовлетворяется, когда конкатенация каждого списка в список списков P так же, как список L. Список списков P может содержать произвольное количество списков.В список списков, Append все списки вместе в один список

Пример запросов:

? - partition ([1 ,2 ,3] , P). 
P = [[1] , [2] , [3]]; 
P = [[1] , [2 , 3]]; 
P = [[1 , 2] , [3]]; 
P = [[1 , 2 , 3]]; 
no 
? - partition (L , [[1] ,[2] ,[3 ,4 ,5]]). 
L = [1 , 2 , 3 , 4 , 5]; 
no 

Я попытался конкатенации списков в P вместе, то проверять, если она равна L. Это то, что у меня есть, но это не работает. Он бесконечно петляет для любого P, который содержит более 1 списка.

partition([], []). ;; Partition of empty list is the empty list 
partition(L, [L]). ;; Base case where if P contains 1 element (list), L is equal to this list. 
partition(L, [X|[Y1|Y2]]) :- 
    append(X, Y1, XY1), 
    partition(L, [XY1|Y2]). ;; Append each list in P to the list after it, repeating until one list is created. X is the head of the list, Y1 is the second element, and Y2 is the rest of the list. 

Любая помощь приветствуется.

ответ

3

Сложная часть этого заключается в использовании append/3 способом, который универсально завершается.

Давайте код list_sublists/2 (несколько более декларативный имя, чем partition):

list_sublists([],[]). 
list_sublists([X|Xs],[[Y|Ys]|Yss]) :- 
    append([Y|Ys],Xs0,[X|Xs]), 
    list_sublists(Xs0,Yss). 

Рассмотрим задачу append([Y|Ys],Xs0,[X|Xs]) во втором предложении: она заканчивается повсеместно, когда либо [Y|Ys] или [X|Xs] (или оба)/ограничена в длина.

Теперь давайте выполним запросы вы дали:

?- list_sublists([1,2,3],Pss). 
Pss = [[1],[2],[3]] ; 
Pss = [[1],[2,3]] ; 
Pss = [[1,2],[3]] ; 
Pss = [[1,2,3]]  ; 
false. 

?- list_sublists(Ls,[[1],[2],[3,4,5]]). 
Ls = [1,2,3,4,5]. 
1

Я пытался минимально исправить код: он заканчивает тем, что к чему-то очень похожее (одинаковое, на самом деле), чтобы @repeat ответ (+1), конечно

partition([], []). % Partition of empty list is the empty list 
%partition(L, [L]). % Base case where if P contains 1 element (list), L is equal to this list. 
% Append each list in P to the list after it, repeating until one list is created. X is the head of the list, Y1 is the second element, and Y2 is the rest of the list. 
partition(L, [[X|Xs]|Zs]) :- 
    append([X|Xs], Ys, L), 
    partition(Ys, Zs). 

Я бы сказал, что трюк это заставляет первый аргумент Append/3 иметь длину> 0, совершенное придав ему образец [X|Xs] вместо просто Xs

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