我知道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.