有没有办法在Prolog中反转规则的逻辑?



我知道Prolog中的+符号代表";不可证明";,如果某个子句是可证明的,则其评估为false。

这让我思考了规则逻辑的可逆性,有没有一种方法可以反转使用与上面给出的+符号类似语法的规则逻辑?也就是说,这不需要你改变条款本身。

相反,我的意思是规则的逻辑是相反的。例如,如果规则是X > Y,则反过来返回结果X < Y

对于一个更复杂的例子,想象一下,我有一个子句:

passed(X, Y) :- mark(X, Y, Z), Z >= 40.
mark(john, maths, 50).
mark(paul, maths, 10).
mark(harry, maths, 78).

我可以推翻以下陈述吗:

?- passed(X, maths).
X = john
X = harry

所以我得到:

X = paul

否定是一个非常复杂的主题。。。Prolog提供了一种实用的方法,可以在其可以处理的受限域中对其某些功能进行建模。对于您的示例,使用充分实例化的参数来获得建设性的证明:

passed(X, Y) :- mark(X, Y, Z), Z >= 40.
mark(john, maths, 50).
mark(paul, maths, 10).
mark(harry, maths, 78).
?- mark(Student,_,_),+passed(Student,math).

可以表示为:

mark(john, maths, 50).
mark(paul, maths, 10).
mark(harry, maths, 78).
pass_mark(maths, 40).
% Passed is a Boolean, i.e. true or false
passed_subject_t(Person, Subject, Passed) :-
mark(Person, Subject, Score),
pass_mark(Subject, PassMark),
call_t(Score >= PassMark, Passed).
% Generic predicate
call_t(Goal, Bool) :-
% Don't use *-> because Goal might contain ";" alternatives
(   call(Goal)
->  Bool = true
;   Bool = false
).

swi-prolog中的结果:

?- findall(P, passed_subject_t(P, maths, true), Ps).
Ps = [john, harry].
?- findall(P, passed_subject_t(P, maths, false), Ps).
Ps = [paul].

在某些情况下,您可以,但不会是自动的。在这里,您可以使用clpfd"具体化";限制例如,对于SWI,在文档中,可以找到# Q谓词。

查询示例:

?- use_module(library(clpfd)).
true.
?- X #>= 40.
X in 40..sup.
?- # X #>= 40.
X in inf..39.

最新更新