为什么Prolog与包含更多元素的元组匹配(X,Xs)?一个例子:
test2((X, Xs)) :- write(X), nl, test2(Xs).
test2((X)) :- write(X), nl.
test :-
read(W),
test2(W).
?- test.
|: a, b(c), d(e(f)), g.
a
b(c)
d(e(f))
g
yes
实际上这是我想要实现的,但似乎是可疑的。有没有其他方法可以将术语连词视为Prolog中的列表?
答案 0 :(得分:2)
,/2
运算符的元组 term 构造在PROLOG中通常是右关联的(通常称为序列),因此您输入{{ 1}}实际上可能是术语a, b(c), d(e(f)), g
。事实证明,您的谓词(a, (b(c), (d(e(f)), g)))
打印了您的问题中显示的内容,第一次调用test2/1
,test2/1
匹配X
的第一个句子, a
匹配Xs
,然后匹配(b(c), (d(e(f)), g))
匹配的X
和匹配b(c)
的{{1}},依此类推。
如果您真的想处理被解释为连词的列表,您可以使用以下内容:
Xs
输入(d(e(f)), g)
上的 ....这里的列表结构通常与使用test2([X|Xs]) :- write(X), nl, test2(Xs).
test2([]).
构造的元组略有不同(因为,至少在SWI-PROLOG中,这种结构是用于处理用[a, b(c), d(e(f)), g]
构造的术语的语法糖,大致相同因为你用,/2
构造序列或元组术语。这样,如果您允许列表术语在代码中被解释为连词,则可以获得列表术语支持的好处。另一种方法是声明并使用您的自己的(可能是中缀运算符)进行连接,例如./2
,您可以将其声明为:
,/2
然后你可以将你的联盟构建为&/2
并从那里适当地处理它,准确地知道:- op(500, yfx, &). % conjunction constructor
- 你的意思 -
有关详细信息,请参阅SWI-PROLOG中op/3
的手册页 - 如果您没有使用SWI,我认为在您使用的PROLOG实现中应该有类似的谓词 - 如果值得的话这是盐: - )
编辑:要将使用a & b(c) & d(e(f)) & g
构建的元组术语转换为列表,您可以使用以下内容:
&/2
答案 1 :(得分:0)
嗯... a, b(c), d(e(f)), g
表示a
和(b(c)
和(d(e(f))
和g
)),以及列表[1,2,3]
是只是一个[1 | [2 | [3 | []]]]
。即如果你把这个联结转到一个列表,你会得到相同的test2([X|Xs]):-...
,但区别在于联合带有关于如何组合这两个目标的信息(也可能有分离(X; Xs)
)。您可以通过(a, b(c)), (d(e(f)), g)
您使用简单的递归类型。在其他语言中,列表也是递归类型,但它们通常假装是数组(具有良好索引的大型元组)。
可能你应该使用:
test2((X, Y)):- test2(X), nl, test2(Y).
test2((X; Y)). % TODO: handle disjunction
test2(X) :- write(X), nl.