Connor
Connor

Reputation: 1094

Is there a way to Reverse a Rule's logic in Prolog?

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

Answers (3)

brebs
brebs

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

user20301393
user20301393

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

CapelliC
CapelliC

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

Related Questions