在Prolog中匹配元组 [英] Matching tuples in Prolog

查看:103
本文介绍了在Prolog中匹配元组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么Prolog与包含更多元素的元组匹配(X,Xs)?一个例子:

Why does Prolog match (X, Xs) with a tuple containing more elements? An example:

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中,还有其他方法可以将术语连词视为列表吗?

Actually this is what I want to achieve but it seems suspicious. Is there any other way to treat a conjunction of terms as a list in Prolog?

推荐答案

元组 term 构造在PROLOG中通常是右关联的(通常称为序列) ),因此您输入的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)Xs匹配(d(e(f)), g),依此类推.

Tuple term construction with the ,/2 operator is generally right-associative in PROLOG (typically referred to as a sequence), so your input of a, b(c), d(e(f)), g might well actually be the term (a, (b(c), (d(e(f)), g))). This is evidenced by the fact that your predicate test2/1 printed what is shown in your question, where on the first invocation of the first clause of test2/1, X matched a and Xs matched (b(c), (d(e(f)), g)), then on the second invocation X matched b(c) and Xs matched (d(e(f)), g), and so on.

如果您真的想处理解释为连词的列表,则可以使用以下内容:

If you really wanted to deal with a list of terms interpreted as a conjunction, you could have used the following:

test2([X|Xs]) :- write(X), nl, test2(Xs).                                    
test2([]).

输入[a, b(c), d(e(f)), g]上的

....通常,这里的列表结构与用,/2构造的元组的解释有些不同(至少在SWI-PROLOG中,这样的结构是语法糖,用于处理用./2构造的术语,与您使用的方法几乎相同).用,/2构造序列或元组项).这样,如果您可以允许列表项在代码中被解释为连词,那么您将获得支持列表项的好处.另一种选择是声明并使用您的 own (也许是infix运算符)进行连接,例如&/2,您可以将其声明为:

...on input [a, b(c), d(e(f)), g]. The list structure here is generally interpreted a little differently from tuples constructed with ,/2 (as, at least in SWI-PROLOG, such structures are syntactic sugar for dealing with terms constructed with ./2 in much the same way as you'd construct sequences or tuple terms with ,/2). This way, you get the benefits of the support of list terms, if you can allow list terms to be interpreted as conjunctions in your code. Another alternative is to declare and use your own (perhaps infix operator) for conjunction, such as &/2, which you could declare as:

:- op(500, yfx, &). % conjunction constructor

然后可以将连接词构造为a & b(c) & d(e(f)) & g并从那里适当地处理它,确切地知道&/2-合取是什么意思.

You could then construct your conjunct as a & b(c) & d(e(f)) & g and deal with it appropriately from there, knowing exactly what you mean by &/2 - conjunction.

请参见手册页中的 op/3 SWI-PROLOG以获得更多详细信息-如果您不使用SWI,那么我想您所使用的任何PROLOG实现中都应该有一个类似的谓词-如果值得,那就加盐:-)

See the manual page for op/3 in SWI-PROLOG for more details - if you're not using SWI, I presume there should be a similar predicate in whatever PROLOG implementation your'e using -- if it's worth it's salt :-)

编辑:要将使用,/2构造的元组项转换为列表,可以使用以下内容:

To convert a tuple term constructed using ,/2 to a list, you could use something like the following:

conjunct_to_list((A,B), L) :-
  !,
  conjunct_to_list(A, L0),
  conjunct_to_list(B, L1),
  append(L0, L1, L).
conjunct_to_list(A, [A]).

这篇关于在Prolog中匹配元组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆