我通常会写这样一个声明作为两个条款,如下:
x :- y.
y :- x.
在Prolog中,是否有任何简洁的方式来编写类似&#34的声明;如果x然后是y,反之亦然"?
换句话说,当且仅当y"是否可以写" x作为单一陈述?
答案 0 :(得分:6)
你说你通常会写“p,当且仅当q”(我将在下面写 q< => q )
p :- q.
q :- p.
但这只有在
时才正确在这种情况下,代码并没有真正说出任何有趣的内容,只有p和q是等价的,但是没有说明它们是真还是假。
如果涉及变量,请说
p(X) :- q(X).
q(X) :- p(X).
然后意思是
forall X: p(X) <= q(X) and forall X': q(X') <= p(X')
与
相同forall X,X': p(X) <= q(X) and q(X') <= p(X')
当你真正想说的是
时forall X: p(X) <= q(X) and q(X) <= p(X)
另一方面,只要您对谓词只有一个单子句,那么单独该子句就可以读作“if if only only”。例如
p(X,Y) :- q(X,Z).
装置
forall X,Y exists Z: p(X,Y) <=> q(X,Z)
如果在其他地方定义了q / 2,那么这是一个明智的事情。这样你就可以定义别名,投影等。
你没有给出任何问题的背景知识,但是一旦考虑了变量,就可以问“在什么情况下p&lt; =&gt; q?”,其中p和q是任意定义的。那你想写点像
p_iff_q(X) :- p(X) <=> q(X).
,在简单的Prolog中,你必须重写为像
这样的东西p_iff_q(X) :- p(X),q(X) ; \+p(X),\+q(X).
答案 1 :(得分:4)
据我所知,不在swi-prolog中。
另一方面,您可以编写一个小的重写谓词,使用以下小程序自动重写您的程序理论:
:- dynamic([system:term_expansion/2]).
:- op(900, xfx, user:(:::)).
system:term_expansion(:::(H,T),[H :- T, T :- H]) :-
callable(H),
callable(T).
然后你可以简单地使用
x ::: y.
当然,您可以指定除:::
之外的其他运算符,只需相应地替换运算符定义(op/3
)和term_expansion/2
。
另一方面,只有在你打电话之前解决了头部和身体,这不会产生无限循环。否则,转换的程序将无限循环。 Prolog不是一个真正的逻辑引擎,它只是逻辑编程:用逻辑语法指定程序,而不是表达逻辑理论。
答案 2 :(得分:1)
可以表示&#34; if-and-only-if&#34; Prolog中的规则使用Constraint Handling Rules。
例如,在SWI-Prolog中:
:- use_module(library(chr)).
:- chr_constraint class/2,species/2,animal/1,mammal/1,bird/1.
%X can be a member of only one species
species(X,X1),species(X,X2) <=> X1 = X2.
%X can be a member of only one class
class(X,X1),class(X,X2) <=> X1 = X2.
%X is a bird if and only if X is an animal and a pelican or a pigeon
bird(X) <=> animal(X),class(X,bird),(species(X,pelican);species(X,pigeon)).
%X is a mammal if and only if X is an animal
mammal(X) <=> animal(X),class(X,mammal),(species(X,cat);species(X,dog);species(X,bear)).