Prolog转换列表列表中的列表

时间:2017-04-29 23:48:17

标签: list prolog

我需要将元素列表转换为列表列表。 例如,如果我有列表[1,2,3,4],则输出必须是[[1],[2],[3],[4]],每个列表一个元素。

create([],_, _, _).
create([H|T], Aux, X, Result) :-
   append([H], Aux, X),
   Result = [X],
   create(T, X, _, Result).

我总是弄错......这甚至可能吗?

2 个答案:

答案 0 :(得分:2)

定义此关系的另一种可能性是使用DCG。在描述列表时,它们产生易于阅读的代码让我们坚持使用@false在评论中建议的单身名称:

singletons([]) -->        % the empty list
   [].                    % is empty
singletons([H|T]) -->     % the head of a nonempty list
   [[H]],                 % is a list on its own
   singletons(T).         % and so is the tail

您可以使用短语/ 2来直接查询:

   ?- phrase(singletons([1,2,3,4]),X).
X = [[1],[2],[3],[4]]

或者用短语/ 2作为单一目标写一个包装谓词:

singletons(L,Ls) :-
   phrase(singletons(L),Ls).

并查询:

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

谓词也相反:

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

以及最常见的查询:

   ?- singletons(L,Ls).
L = Ls = [] ? ;
L = [_A],
Ls = [[_A]] ? ;
L = [_A,_B],
Ls = [[_A],[_B]] ?
...

或者,您也可以定义一个简单的谓词,用于描述括号中任意元素与其自身之间的关系,然后使用库中的maplist / 3(apply)将其应用于列表的每个元素:

:- use_module(library(apply)).

embraced(X,[X]).

singletons(L,Ls) :-
   maplist(embraced,L,Ls).

此版本为上述查询产生相同的结果。但是,它更有效率。要看到这一点,请考虑以上查询:

   ?- singletons(L,[[1],[2],[3],[4]]).
L = [1,2,3,4]

您需要输入;以使Prolog搜索更多解决方案,然后失败(由no表示)。使用此版本时,没有剩余不必要的选择点,Prolog将确定性地继续查询。

答案 1 :(得分:1)

试试这个

create([],[]).

create([H|T],[[H]|T2]):- create(T,T2).

我试过

?- create([1,2,3,4],X).

,结果是

X = [[1], [2], [3], [4]].