/* file logic.pl */

/* A silly program to demonstrate the use of operators in Prolog.
Logical connectives and, or, if and ~ (negation) are defined as
operators and given the same semantics as their Prolog counterparts.

A small procedure play/0 is provided to allow the answers 'true' and 'false'
to be supplied.

To run the program, type 'play.' and then input a propositional calculus expression,
followed by a full stop and carriage return.

e.g. 

| ?- play.
> |: p and q.
true
> p and r.
false
> r and r.
false
> q and r.
false
> q or r.
true
> p implies q.
true
> p implies q and r.
false
> p implies q or r.
true
> stop.
goodbye


Type 'stop.' to finish. */

% Operator definitions

:- op(1000, xfy, or).

:- op(900, xfy, and).

:- op(800, fy, ~).

:- op(1100, xfy, implies).

% Allow Prolog to simply fail if given an unknown predicate

%:- prolog_flag(unknown, _, fail).
:- set_prolog_flag(unknown, fail).

% Definitions of connectives
~X :- \+ X.
and(X, Y):-  X, Y.
or(X, Y):- X;Y.

% This one is cunning, 'X implies Y' is defined with the semantics of 
% (~X) or Y -- which has the same truth conditions
implies(X, Y):- \+ X ; Y.



% p and q are true.
p.
q.

% Top level. Write a prompt and accept input. Then evaluate input.
play:-
   write('> '),
   read(X),
   evaluate(X).
   
% If X is 'stop', then output 'goodbye' and terminate.
evaluate(X):-
   X = stop,
   write(goodbye), nl.

% If X succeeds, write 'true' and continue.   
evaluate(X):-
   X,
   write(true), nl,
   play.

% Otherwise, output 'false' and continue.   
evaluate(_):-
   write(false), nl,
   play.
   
:-play.