Prolog 试图打断列表中的列表元素?
我正试图编写一个程序,使以下内容:Prolog 试图打断列表中的列表元素?,prolog,logic,dcg,Prolog,Logic,Dcg,我正试图编写一个程序,使以下内容: ?- g([2,3, [22,[3],9] ,4,[5],99],X). X= [2,3,22,[3],9 ,4,5,99] 因此,它搜索给定列表中的列表,并将其替换为不带括号[]的元素 所以我写了这个程序: 第一个块只搜索列表中的第一个元素,即list 如果没有这样的元素,它将返回[没有列表] first_list_in_the_list([],[there_is_no_list]):-!. first_list_in_the_list([H|_],
?- g([2,3, [22,[3],9] ,4,[5],99],X).
X= [2,3,22,[3],9 ,4,5,99]
因此,它搜索给定列表中的列表,并将其替换为不带括号[]的元素
所以我写了这个程序:
第一个块只搜索列表中的第一个元素,即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,它将两个列表连接在一个新列表中
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).
当我给出一个
查询[2,3,5]
时,我也得到了[2,3,5]
,我真的不明白它为什么会这样做。要展平嵌套列表的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
. %
要展平嵌套列表的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
. %
一个简单的递归解决方案也会起作用。递归由输入列表的头部完成。在非平凡的情况下,当head本身是一个列表时,我们只需将展平列表的其余部分附加到它。在下面的代码中,它还没有在
append(H,Rest,Out)
中展平Rest
,但是在递归调用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).
一个简单的递归解决方案也会起作用。递归由输入列表的头部完成。在非平凡的情况下,当head本身是一个列表时,我们只需将展平列表的其余部分附加到它。在下面的代码中,它还没有在
append(H,Rest,Out)
中展平Rest
,但是在递归调用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).
DCG也可以
lev, X --> [X], {is_list(X)}, lev.
lev, [X] --> [X], lev.
lev --> [].
测试:
DCG也可以
lev, X --> [X], {is_list(X)}, lev.
lev, [X] --> [X], lev.
lev --> [].
测试:
您的示例的可能副本并没有删除所有子列表,但似乎只删除了中间的一个级别。例如,
[1,2,3,4,5,6]
变成了[1,2,3,4,5,6]
,如果我试着效仿你的例子。这就是你想要的吗?是的,没错。这就是我想要的,只有一个级别。示例的可能副本并不会删除所有子列表,但似乎只删除了中间的一个级别。例如,[1,2,3,4,5,6]
变成了[1,2,3,4,5,6]
,如果我试着效仿你的例子。这就是你想要的吗?是的,没错。这就是我想要的,只是一个层次。