如何在prolog中构建一个接收数字和列表的谓词,我必须在尾部的列表中插入数字
我尝试在头列表中插入数字:html{
background:gray;
}
div{
width:200px;
background:black;
margin:0 auto;
}
h3{
color:white;
}
span{
position: absolute;
margin-left: 8px;
height: 28px;
}
并且它有效,但我怎么能通过尾部来做呢?
答案 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).
答案 2 :(得分:1)
还没有人谈到difference lists。
差异列表用L-E
表示,这对于由列表L
构成的一对符号来说只是一个方便的符号,其最后一个构造单元的尾部有E
:
L = [ V1, ..., Vn | E]
空差异列表为E-E
,E
为变量。只要您想要优化列表,就可以统一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).