这是一种解决方案:
split([],[]).
split([Head|Tail],[[Head]|Split]) :-
split(Tail,Split).
split([Head|Tail],[[Head|List]|Split]) :-
split(Tail,[List|Split]).
例如:
?- split([1,2,3,4],Lists), split(Recover,Lists).
Lists = [[1], [2], [3], [4]],
Recover = [1, 2, 3, 4] ;
Lists = [[1], [2], [3, 4]],
Recover = [1, 2, 3, 4] ;
Lists = [[1], [2, 3], [4]],
Recover = [1, 2, 3, 4] ;
Lists = [[1], [2, 3, 4]],
Recover = [1, 2, 3, 4] ;
Lists = [[1, 2], [3], [4]],
Recover = [1, 2, 3, 4] ;
Lists = [[1, 2], [3, 4]],
Recover = [1, 2, 3, 4] ;
Lists = [[1, 2, 3], [4]],
Recover = [1, 2, 3, 4] ;
Lists = [[1, 2, 3, 4]],
Recover = [1, 2, 3, 4] ;
false.
此解决方案基于以下观察。我将扁平化列表称为输入列表,将未扁平化列表称为输出列表。在递归情况下,输入列表具有[H|T] 的形式,split(T,R) 假设成功。需要考虑三种情况。
- 如果
R = [],我们可以开始构造一个新列表,其最后一个元素是H。
- 如果
R = [_|_],我们可以开始构造一个新列表,其最后一个元素是H。
- 如果
R = [L|_],我们可以通过将H 附加到L 来继续构造L。
在每种情况下,我们都会获得有效的输出列表。前两种情况由split/2的第二个子句实现(R = []或R = [_|_]无所谓),第三个由第三个子句实现。