Reputation: 1094
I understand that the \+
symbol in Prolog stands for "not provable", which evaluates to false if some clause is provable.
This got me thinking about the reversibility of a Rule's logic, is there a way to reverse a rules logic that uses similar syntax to the \+
symbol given above? i.e. that doesn't require you changing the clause itself.
By reverse I mean the rule's logic is inverted. For example, if the rule is X > Y
, then the reverse returns the outcome X < Y
.
For a more complex example, imagine, instead, I had the clause:
passed(X, Y) :- mark(X, Y, Z), Z >= 40.
mark(john, maths, 50).
mark(paul, maths, 10).
mark(harry, maths, 78).
Could I reverse the following statement:
?- passed(X, maths).
X = john
X = harry
So that I get:
X = paul
Upvotes: 1
Views: 267
Reputation: 4456
Could represent as:
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
).
Results in 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].
Upvotes: 1
Reputation: 1
In some cases, you can but it won't be automatic.
Here, you could use a clpfd "reified" constraint.
For example, for SWI, in the docs, one can find #\ Q
predicate.
Example queries:
?- use_module(library(clpfd)).
true.
?- X #>= 40.
X in 40..sup.
?- #\ X #>= 40.
X in inf..39.
Upvotes: 0
Reputation: 60034
Negation is a really complex topic... Prolog offers a practical way to model some of its features in the restricted domain it can handle. For your example, use sufficiently instantiated arguments to get a constructive proof:
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).
Upvotes: 1