%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% An Implementation of G4ip for Terzo
% 	author: Christian.Urban@cl.cam.ac.uk 
% 
% some solvable sample queries:
%
% prove (nil |- p imp p).
% prove (nil |- (p imp p) imp (p imp p)).
% prove (nil |- ((((p imp q) imp p) imp p) imp q) imp q).
% prove (nil |- (a imp (b imp c)) imp ((a imp b) imp (a imp c))).
% prove (nil |- (a or (a imp b)) imp (((a imp b) imp a) imp a)).
%
% two non-solvable queries
%
% prove (nil |- a or (a imp false)).
% prove (nil |- ((a imp b) imp a) imp a).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

module G4ip.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% atomic formulae
kind form type.

type p form. 
type q form.
type a form.
type b form.
type c form.

type isatomic form -> o.

isatomic p.
isatomic q.
isatomic a.
isatomic b.
isatomic c.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% logical operators
type false  form.
type and    form -> form -> form.    
type or     form -> form -> form.       
type imp    form -> form -> form.
 
infixr and   9.
infixr or    9.
infixr imp   9.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% sequent constructor; sequents are of the form: (list |- formula) 
kind seq type.

type   |-  list form -> form -> seq. 
infixl |-   4.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% prove predicate; prints "solvable" if seq is provable, otherwise "no" 
type prove seq -> o.

prove (Gamma |- G) :- ( membNrest P Gamma Gamma',
                        left (P::Gamma' |- G) );
                        right   (Gamma  |- G).   

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% rightrules
type right seq -> o.

right (Gamma |- B and C) :- prove (Gamma |- B),          %% and-R   
                            prove (Gamma |- C).          

right (Gamma |- B imp C) :- prove (B::Gamma |- C).       %% imp-R

right (Gamma |- B or  C) :- prove (Gamma |- B);          %% or-R 
                            prove (Gamma |- C).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% leftrules
type left  seq -> o.

left (false :: Gamma |- G).                              %% false-L

left (A :: Gamma |- A)     :- isatomic A.                %% axiom 

left (B and C::Gamma |- G) :- prove (B::C::Gamma |- G).  %% and-L
 
left (B  or C::Gamma |- G) :- prove (B::Gamma |- G),     %% or-L 
                              prove (C::Gamma |- G).


left (A imp B::Gamma |- G) :-                            %% imp-L1
	isatomic A, ismember A Gamma, prove (B::Gamma |- G).

left ((B and C) imp D::Gamma |- G) :-                    %% imp-L2
	prove (B imp (C imp D)::Gamma |- G).

left ((B or  C) imp D::Gamma |- G) :-                    %% imp-L3
	prove (B imp D::C imp D::Gamma |- G).

left ((B imp C) imp D::Gamma |- G) :-                    %% imp-L4
	prove (C imp D::Gamma |- B imp C),	                              
	prove (D::Gamma |- G).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% returns a member and the remainder of a list
type membNrest     A -> list A -> list A -> o.

membNrest X (X::Rest) Rest.
membNrest X (Y::Tail) (Y::Rest) :- membNrest X Tail Rest.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% succeeds only once if A is element in the list 
type ismember     A -> list A -> o.

ismember X (X::Rest) :- !.
ismember X (Y::Tail) :- ismember X Tail.


