Prolog在尾部插入列表中的数字

时间:2015-09-22 15:16:26

标签: list prolog dcg difference-lists

如何在prolog中构建一个接收数字和列表的谓词,我必须在尾部的列表中插入数字

我尝试在头列表中插入数字:html{ background:gray; } div{ width:200px; background:black; margin:0 auto; } h3{ color:white; } span{ position: absolute; margin-left: 8px; height: 28px; } 并且它有效,但我怎么能通过尾部来做呢?

4 个答案:

答案 0 :(得分:3)

只需使用append/3,就像这样:

?- append([a,b,c,d],[x],List).
List = [a,b,c,d,x].

答案 1 :(得分:2)

可以使用两部分递归规则在尾部插入:

  • 当列表为空时,将结果统一为包含项目的单元素列表
  • 当列表不为空时,将结果统一到头部,然后插入尾部尾部的结果。

英文描述比Prolog等同版本长得多:

ins_tail([], N, [N]).
ins_tail([H|T], N, [H|R]) :- ins_tail(T, N, R).

Demo.

答案 2 :(得分:1)

还没有人谈到difference lists

差异列表

差异列表用L-E表示,这对于由列表L构成的一对符号来说只是一个方便的符号,其最后一个构造单元的尾部有E

L = [ V1, ..., Vn | E]

空差异列表为E-EE为变量。只要您想要优化列表,就可以统一E。 例如,如果要添加元素X,可以按如下方式统一:

E = [X|F]

然后,L-F是新列表。同样,您可以在固定时间内附加列表。如果您将F统一为"正常"列表,特别是[],您关闭了您的开放式列表。在所有操作中,您通过L保留对整个列表的引用。当然,您仍然可以使用因果L符号在[W1, ..., Wm |L]-E前面添加元素。

您是否需要差异列表是另一个问题。如果在最后添加一个元素对你来说实际上是一个常见的操作,并且你正在操纵大型列表,那么它们就是相互影响。

明确的句子语法

DCG是在Prolog中编写语法规则的便捷方式。它们通常作为读取器宏实现,将-->形式转换为实际谓词。由于语法的目的是在解析期间构建结构(a.k.a。 productions ),因此实际谓词的转换涉及差异列表。因此,即使两个概念在理论上都是不相关的,差异列表通常也是DCG的构建材料。

维基百科上的示例以:

开头
 sentence --> noun_phrase, verb_phrase.

...被翻译为:

 sentence(S1,S3) :- noun_phrase(S1,S2), verb_phrase(S2,S3).

很多"管道"由语法提供(有点像monad)。正在构建的对象" sentence/2 S1 ,它是由谓词连接在一起的不同部分构建的。 S1 传递给noun_phrase,根据需要构建/扩展它,"返回" S2 ,可以看作"无论是什么扩展 S1 "。此值传递给verb_phrase,后者会更新它并提供 S3 ,a.k.a。无论是扩展 S2 S3 sentence的参数,因为它也是"无论是什么扩展 S1 ",根据我们的规则。 但是,这是Prolog,所以 S1 S2 S3 不一定是输入输出,它们在整个过程中统一,在此过程中也会发生回溯(您可以解析模糊的语法)。它们最终与列表统一。

当我们遇到箭头右侧的列表时,差异列表会发挥作用:

det --> [the].

以上规则翻译为:

det([the|X], X).

这意味着det/2将其第一个参数与尾部为X的开放式列表统一起来;其他规则将统一X。通常,您会找到与[]相关联的 epsilon 规则。

以上所有内容都是用宏来完成的,一个典型的错误是尝试在数据上调用一个辅助谓词,这会因为转换添加两个参数而失败(对helper(X)的调用实际上是对helper(X,V,W))。您必须将大括号{ ... }之间的实际实体括起来,以避免将谓词视为规则。

答案 3 :(得分:0)

这是另一个选择。

insert(N,[],[N]).
insert(N,[H|T],[H|Q]) :- conc([H|T],[N],[H|Q]).
conc([],L,L).
conc([H|T],L,[H|Q]) :- conc(T,L,Q).