在Prolog中匹配元组

时间:2010-05-23 22:32:59

标签: list prolog tuples

为什么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中的列表?

2 个答案:

答案 0 :(得分:2)

使用,/2运算符的元组 term 构造在PROLOG中通常是右关联的(通常称为序列),因此您输入{{ 1}}实际上可能是术语a, b(c), d(e(f)), g。事实证明,您的谓词(a, (b(c), (d(e(f)), g)))打印了您的问题中显示的内容,第一次调用test2/1test2/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.