Prolog 暗示否定谓词
我如何在 PROLOG 中编写以下规则: if P then not Q
我知道您可以轻松地编写 if P then Q 像 q(X) 这样的谓词:- p(X)
,但是如何否定 q/1
谓词呢?我不想用其他语义(例如 non_q/1
)定义新谓词。
How can I write the following rule in PROLOG: if P then not Q
I understand that you can easily write if P then Q the predicates like q(X) :- p(X)
, but how can you negate the q/1
predicate? I don't want to define new predicates with other semantics like non_q/1
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
子句“if P then not Q”在逻辑上等价于否定子句“not P OR not Q”。因此,它是一个没有正文字的 Horn 子句,并且作为 SLD 定理证明和Horn 子句可以在 Prolog 编程中表示为目标子句或“查询”:
让我们稍后再回到这个想法。
但目标条款可能不是您想要的那种表示形式。构成 Prolog“知识库”的事实和规则是确定子句,即每个 Horn 子句都恰好有一个正文字。 “If P then not Q”没有正字面量,因此在这个意义上它不能被表示(作为定语子句)。
上面显示的目标子句“询问”P 和 Q 是否都可以被证明。 Prolog 提供了“否定即失败”的概念,因此“询问”“not P OR not Q”是否成立的更自然的方式是:
如果 P 或 Q 失败,我们就会成功,如果两者都成功,我们就会失败。
然而,如果您的目的是断言知识库中的某些内容是否定,Prolog 自然不支持这一点。根据您的应用程序,可能有一种合理的方法来解决 Prolog 语法并完成所需的任务(总是有一种不合理的方法来做到这一点,正如您使用 non_q 谓词所暗示的那样) 。
The clause "if P then not Q" is logically equivalent to the negative clause "not P OR not Q". As such it is a Horn clause without a positive literal, and as an application of the correspondence of SLD theorem proving and Horn clauses, can be represented in Prolog programming as a goal clause or "query":
Let's come back to this idea in a minute.
But the goal clause is perhaps not the sort of representation you have in mind. The facts and rules that constitute a Prolog "knowledgebase" are definite clauses, i.e. Horn clauses each with exactly one positive literal. "If P then not Q" has no positive literal, so in this sense it cannot be represented (as a definite clause).
The goal clause shown above "asks" if P and Q can both be proven. Prolog provides a notion of "negation as failure", so a more natural way to "ask" whether "not P OR not Q" holds would be:
Then we would get success if either P or Q fails, and failure if both succeed.
However if your purpose is to assert the negation something in the knowledgebase, Prolog doesn't naturally support this. Depending on your application, there may be a reasonable way to work around the Prolog syntax and accomplish what is needed (there's always an unreasonable way to do it, as you've hinted as with a non_q predicate).
你听说过 Prolog 中的 cut 吗?
无论如何,我对Prolog标准不太了解,但是在SWI-Prolog中,符号
\+
表示否定。我知道它不必在每个 Prolog 解释器中都起作用。您可以使用 Prolog 的 cut 来进行谓词否定。谓词定义如下:
表示Goal 无法被证明,而不是Goal 是假的。
也许这个 Prolog &剪切链接将会很有用。
Have you ever heard about cut in Prolog?
Anyway I don't know much about Prolog standard, but in SWI-Prolog the symbol
\+
means negation. I know it don't have to work in every Prolog's interpreter.You can make the predicate negation with Prolog's cut. The predicate is defined like:
It means that Goal can't be proven, not the Goal is false.
Maybe this Prolog & Cut link will be useful.
“...if P then not Q” 可以通过
->
if-then 控制流谓词来表示(例如,GNU) ,以及\+
否定(或“不可证明”) ) 操作员(例如,GNU),如下所示:请注意,通常
\+
将实现所谓的 negation-as-failure;即,子目标/表达式\+ Q
将成功,当且仅当Q
不能。请注意,\+
下的Q
求值不会影响执行时表达式Q
中存在的任何变量的绑定。例如,考虑:
鉴于这些事实,以下内容成立:
按照您可能想要的方式(就“规则”而言)实现类似于
\+ q(X) :- p(X)
的东西是正如您所描述的,这并不简单,但潜在的黑客行为是:此定义仅反映
q(X)
对于所有X
失败的意图,其中p(X)
成功当且仅当它被断言在q(X)
的任何其他子句之前,但可能并不理想。"...if P then not Q" can be represented via the
->
if-then control-flow predicate (e.g., GNU) , along with the\+
negation (or 'not-provable') operator (e.g., GNU), as follows:Note that, typically,
\+
will implement what is known as negation-as-failure; i.e., the subgoal/expression\+ Q
will succeed iffQ
cannot. Note that the evaluation ofQ
under\+
will not affect the bindings of any variables present in the expressionQ
at execution.For example, consider:
Given these facts, the following hold:
Implementing something akin to
\+ q(X) :- p(X)
as you might want (in terms of a 'rule') isn't straightforward, as you describe, however a potential hack is:This definition will only reflect the intention that
q(X)
is to fail for allX
wherep(X)
succeeds iff it is asserted before any other clauses ofq(X)
, but may not be ideal.您可以使用最少的逻辑来定义负头。用最少的逻辑
~A可以看成A-> ff。因此,以下内容
可以被视为:
现在,如果我们采用以下恒等式 (A -> (B -> C)) = (A & B -> C),我们
看到上面相当于:
现在有一个问题,我们如何提出否定查询?有一个
使用与否定不同的最小逻辑的方式
失败。这个想法是,通过暂时将 A 添加到 prolog 程序 G 来回答以下形式的查询
,然后
尝试求解 B,即执行以下操作:
现在让我们转向 Prolog 表示法,我们将证明 p 和 p -> 。 〜q
通过执行(最小逻辑)Prolog 程序暗示 ~q。这
prolog 程序是:
查询是:
我们首先需要定义新的连接词 (-:)/2。快速解决方案
如下:
在这里您可以看到 SWI Prolog 中这种最小逻辑否定的实现:
最好的问候
参考:
统一证明作为逻辑编程的基础 (1989)
作者:戴尔·米勒、戈帕兰·纳达图尔、弗兰克·普芬宁、安德烈·塞德罗夫
You can use minimal logic to define a negative head. In minimal logic
~A can be viewed as A -> ff. Thus the following
Can be viewed as:
Now if we take the following identity (A -> (B -> C)) = (A & B -> C), we
see that the above is equivalent to:
There is now one problem, how can we ask negative queries? There is one
way to make use of minimal logic which is different from negation as
failure. The idea is that a query of the form:
is answered by temporarily adding A to the prolog program G, and then
trying to solve B, i.e. doing the following:
Now lets turn to Prolog notation, we will show that p, and p -> ~q
implies ~q by executing a (minimal logic) Prolog program. The
prolog program is:
And the query is:
We first need to define the new connective (-:)/2. A quick solution
is as follows:
Here you see a realisation of this minimal logic negation in SWI Prolog:
Best Regards
Reference:
Uniform Proofs as a Foundation for Logic Programming (1989)
by Dale Miller, Gopalan Nadathur, Frank Pfenning, Andre Scedrov