从Prolog中的列表中删除头部

时间:2015-10-02 09:04:59

标签: list prolog

我试图编写一个谓词来从列表列表中的每个列表中删除头部,并将尾部添加到新列表中。结果列表应作为第二个参数返回。

这是尝试:

construct_new(S,New) :-
    New = [],
    new_situation(S,New).

new_situation([],_).
new_situation([H|T], New) :-
    chop(H, H1),
    new_situation(T, [H1|New]).

chop([_|T], T).

你会这样称呼:

construct_new([[x,x],[b,c],[d,e,f]],S).

但是,这只会产生输出true.

4 个答案:

答案 0 :(得分:3)

逐步执行

  1. 您的查询为construct_new(Input,Output),适用于某些实例Input列表。
  2. construct_new/2中的第一个语句将Output(a.k.a。New)与空列表统一起来。 返回的列表应该在哪里可供调用者使用?这两个论点现已统一。
  3. 您致电new_situation(Input,[])
  4. 您匹配第二个句子new_situation([H|T],[]),它以递归方式执行任务(步骤4,...),直到......
  5. 您到达new_situation([],_)成功会丢弃您构建的中间列表。
  6. 解决方案

    • 编写一个简单的递归谓词:

      new_situation([],[]).
      new_situation([[_|L]|T],[L|R]) :-
          new_situation(T,R).
      
    • 使用maplist

      construct_new(S,R) :-
          maplist(chop,S,R).
      

    备注

    正如其他答案和评论所指出的那样,你的谓词命名很差。 construct_new不是关系,而是行动,可以用来代表几乎任何东西。我倾向于喜欢chop,因为它清楚地传达了斩首的行为,但这不是一个适当的关系名称。 重复list_head_tail(L,H,T)是声明性的,并将变量与其角色相关联。使用maplist时,其他谓词(new_situation)甚至不需要存在......

    ...即使guillotine/3很诱人。

答案 1 :(得分:3)

这可以通过DCG完成:

owth(Lists, Tails) :-
    phrase(tails(Tails), Lists).

tails([]) --> [].
tails([T|Tails]) --> [[_|T]], tails(Tails).

产生这些查询:

| ?- owth([[x,x],[b,c],[d,e,f]], T).

T = [[x],[c],[e,f]] ? ;

no
| ?- owth(L, [[x],[c],[e,f]]).

L = [[_,x],[_,c],[_,e,f]]

yes

owth = 关闭他们的头!或者,如果使用其他方向,打开他们的头!

如果您还想捕捉头部,可以按如下方式进行增强:

owth(Lists, Heads, Tails) :-
    phrase(tails(Heads, Tails), Lists).

tails([], []) --> [].
tails([H|Hs], [T|Tails]) --> [[H|T]], tails(Hs, Tails).

答案 2 :(得分:2)

我们将 maplist/[3-4]与以下辅助谓词之一一起使用:

list_tail([_|Xs],Xs).

list_head_tail([X|Xs],X,Xs).

让我们运行一些查询!

?- maplist(list_head_tail,[[x,x],[b,c],[d,e,f]],Heads,Tails).
Heads = [x,b,d],
Tails = [[x],[c],[e,f]].

如果您对尾巴感兴趣,请将maplist/4list_head_tail/3一起使用...

?- maplist(list_head_tail,[[x,x],[b,c],[d,e,f]],_,Tails).
Tails = [[x],[c],[e,f]].

......或者更简单,maplist/3list_tail/2

一起
?- maplist(list_tail,[[x,x],[b,c],[d,e,f]],Tails).
Tails = [[x],[c],[e,f]].

答案 3 :(得分:1)

你也可以使用findall/3

稍微丑陋的单行
?- L = [[x,x],[b,c],[d,e,f]],
   findall(T, ( member(M, L), append([_], T, M) ), R).
R = [[x], [c], [e, f]].

(好的,技术上是一个双线程。无论哪种方式,你甚至不需要定义辅助谓词。)

但绝对更喜欢使用maplist的{​​{1}}解决方案,如above所示。

如果您手动执行地图列表扩展,并将您的chop命名为更好,那么您将获得:

chop/2

由于你可以在谓词的头部进行统一,你可以将其转换为:

lists_tails([], []).
lists_tails([X|Xs], [T|Ts]) :-
    list_tail(X, T),
    lists_tails(Xs, Ts).

但这与你在另一个答案中所拥有的相同。

练习:为什么我们不能说:

lists_tails([], []).
lists_tails([[_|T]|Xs], [T|Ts]) :-
    lists_tails(Xs, Ts).