试图打破列表中列表的元素?

时间:2013-08-08 16:34:50

标签: prolog logic dcg

我正在尝试编写一个程序,其中包含以下内容:

?- g([2,3, [22,[3],9] ,4,[5],99],X).

X= [2,3,22,[3],9 ,4,5,99]

因此,它会搜索给定列表中的列表,并将其替换为不带括号[]的元素。

所以我写了这个程序:

第一个块只搜索列表中的第一个元素,即列表
如果没有这样的元素,则返回[there_is_no_list]

first_list_in_the_list([],[there_is_no_list]):-!.  
first_list_in_the_list([H|_],X):-is_list(H),X=H,!.  
first_list_in_the_list([_|T],X):-first_list_in_the_list(T,X).

第一个块完美地在prolog中工作。

第二个块只是在列表中搜索元素X,然后将列表拆分为两个列表,一个是X之前的所有元素的列表,第二个是X之后的元素。

splite_when_find_element([H|T],H,[],T):-!.  
splite_when_find_element([H|T],X,F,G):-
    splite_when_find_element(T,X,F1,G),append([H],F1,F).

它在Prolog中也可以正常工作。

并且第三个块被追加,并且它在一个新列表中将两个列表连接在一起。

append([],L,L).  
append([H|T],L,[H|U1]):- append(T,L,U1).

,最后一部分是:

gg(L,L):-first_list_in_the_list(L,[there_is_no_list]),!.    
gg(L,U):-first_list_in_the_list(L,X),
         splite_when_find_element(L,X,F,G),gg(G,R),append(F,X,E),
         append(E,R,U).

当我提供query [2,[3],5]时,我也会[2,[3],5],我真的不明白为什么会这样做。

3 个答案:

答案 0 :(得分:2)

一个简单的递归解决方案也可以。递归由输入列表的头部完成。在非平凡的情况下,当head是一个列表本身时,我们只是将其余的flattened列表附加到它。在下面的代码中,它在Rest中尚未展平append(H, Rest, Out),但在g(In, Rest)的递归调用之后将会展平% Base case, empty list. g([], []). % First recursive case: head is list. % Append remaining elements to it. g([H|In], Out):- append(H, Rest, Out), !, g(In, Rest). % Second recursive case: head is not list. % Will appear as-is in the output. g([H|In], [H|Out]):- g(In, Out). 。在追加调用后切断确保回溯不会考虑最后一种情况,即头部将按原样显示在输出中。

{{1}}

答案 1 :(得分:1)

也是DCG可以做的

lev, X --> [X], {is_list(X)}, lev.
lev, [X] --> [X], lev.
lev --> [].

试验:

?- phrase(lev,[a,[b,c,[d]],e],L).
L = [a, b, c, [d], e] .

答案 2 :(得分:0)

要展平嵌套列表的1个级别,请尝试以下操作:

flatten1( Xs , Ys ) :-        % to flatten a list
  flatten1( Xs , [] , Ys ) ,  % - invoke the worker predicate
  .                           %

flatten1( [] , T , R ) :-          % if we get to to the empty list
  reverse(T,R)                     % - just reverse the accumulator and we're done.
  .                                %
flatten1( [X|Xs] , T , R ) :-      % if the head of the list is unbound 
  var(X) ,                         % - check for being a var 
  ! ,                              % - cut (to eliminate problems on backtracking
  T1 = [X|T] ,                     % - prepend the head of the list to the accumulator
  flatten( Xs , T1 , R )           % - and recurse down
  .                                %
flatten1( [[]|Xs] , T , R ) :-     % if head of the list is an empty list, skip it
  flatten1( Xs , T , R )           % - ignore it and recurse down
  .                                %
flatten1( [[X|Ns]|Xs] , T , R ) :- % if head of the list is a non-empty list
  X1 = [Ns|Xs] ,                   % - prepend the tail of the sublist to the list
  T1 = [X|T] ,                     % - prepend the head of the sublist to the accumulator
  flatten( X1 , T1 , R )           % - and recurse down
  .                                %
flatten( [X|Xs] , T , R ) :-       % if the head of the list is something else (except an unbound variable)
  T1 = [X|T] ,                     % - prepend the list head to the accumulator and
  flatten( Xs , T1 , R )           % - recurse down
  .                                %