%A simple grammar for English

s 	--> np,vp.
s	--> s,[and],s.
np	--> det,noun.
vp	--> verb,np.

det	--> [the].
det	--> [a].

noun	--> [musician].
noun	--> [violin]|[piano].
noun	--> [baker].
noun	--> [bread].

verb	--> [plays].
verb	--> [makes].






%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Arithmetics

exp     --> num.
exp     --> ['-'],num.
exp     --> ['('], exp, [')'].
exp     --> exp, op, exp.
num     --> dig.
num     --> dig,num.
dig     --> [1].
op      --> ['+'].






%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


% Context

s 		--> np(Number),vp(Number).
s		--> s,[and],s.
np(Number)	--> det(Number),noun(Number).
vp(Number)	--> verb(Number),np(_).

det(singular)		--> [the].
det(plural)		--> [the].
det(singular)	--> [a].
det(no_det)	--> [].

noun(singular)	--> [musician].
noun(plural)	--> [musicians].
noun(singular)	--> [violin].
noun(singular)	--> [baker].
noun(plural)	--> [bakers].
noun(singular)	--> [bread].
noun(plural)	--> [bread].

noun(no_det)	--> [money].

verb(singular)	--> [plays].
verb(plural)	--> [play].
verb(singular)	--> [makes].
verb(plural)	--> [make].

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% More complex grammar for English

r(X) :- s(X,[a,baker,makes,money],[]),p(X).
r1 :- trans(K,L,[]),p(K).
r2 :- trans(D,[bakers,make,a,bread,and,a,musician,plays,on,the,violin],[]),
	p(D).
r3 :- trans(X,[a,musician,plays,on,the,violin],[]),p(X).
r4(X) :- trans(X,[a,musician,plays|L],[]).

%%%%%%%%%

% Pretty print of a structure

p(S) :- pps(S,1).
pps([],_).
pps(X,I)	:- atomic(X), nl, tab(I), write(X).
pps([H|T],I) 	:- pps(H,I), (T==[] ; pps(T,I)).
pps(X,I) 	:- 
		X=..[H|T], nl, tab(I), write(H), write('('),
	  	K is I+3, pps(T,K),
	  	tab(1), write(')'),!.

%%%%%%%%%

% English grammar


trans( s(np(D,NP), vp(V,NP1)) )	--> np(Number,D,NP),vp(Number,V,NP1),
					{write('s->np,vp')}.


s(np(D,NP), vp(V,NP1)) 		--> np(Number,D,NP),vp(Number,V,NP1),
					{write('s->np,vp')}.
trans( ss( s(NP1,VP1),and, s(NP2,VP2) ) )	
				--> s(NP1,VP1),[and],s(NP2,VP2).

np(Number,det(DET),noun(N))	--> det(Number,DET),noun(Number,N).
np(Number,prep(PR),det(DET),noun(N))	
				--> 
				prep(PR),det(Number,DET),noun(Number,N),
				{allowed(PR,DET,N)}.

vp(Number,verb(V), np(D,NP))	--> verb(Number,V),np(Number1,D,NP),
				{NP=noun(N), allowed(V,N)}.
vp(Number,verb(V), np(PR,D,N))	--> verb(Number,V),np(Number1,PR,D,N).

det(singular,the)	--> [the].
det(plural  ,the)	--> [the].
det(singular,a)		--> [a].
det(no_det,' ')		--> [].

prep(X)			--> [X],{member(X,[on,in,at])}.

noun(singular,musician)	-->[musician].
noun(plural,musicians)	-->[musicians].

noun(singular,violin)	--> [violin].
noun(singular,baker)	--> [baker].
noun(plural,bakers)	--> [bakers].
noun(no_det,bakers)	--> [bakers].
noun(singular,bread)	--> [bread].
noun(plural,bread)	--> [bread].

noun(no_det,money)	--> [money].

verb(singular,plays)	--> [plays].
verb(plural,play)	--> [play].
verb(singular,makes)	--> [makes].
verb(plural,make)	--> [make].
verb(no_det,make)	--> [make].

%% Context - semantics

on_the(instruments).
on_the(place).
instruments(violin,guitar,synthesizer).
place(table).

allowed(play,What)	:- 
			member(What,[violin,guitar,synthesizer]).
allowed(plays,What)	:- 
			member(What,[violin,guitar,synthesizer]).
allowed(on,the,What)	:- 
			on_the(Subject),
			current_predicate(Subject/Arity),
			functor(Instr,Subject,Arity),
			Instr,
			Instr=..[_|List],
			member(What,List).

%allowed(Determ,Noun)	:- Determ='the',
%			   member(Noun,List).
