/* An example is
   Mary gives the book.
     This consists of a NP (Mary) and a VP (gives the book)
   The boy that reads the book sits.
     This consists of a NP (The boy that reads the book) and
     a VP (sits) */
 

/* A sentence consists of a noun phrase and a verb phrase */
s(s(NP,VP)) --> np(Num,NP), vp(Num,VP).

/* A noun phrase consists of a proper noun or
  a determiner and a noun followed by a relative pronoun */
np(Num,np(PN)) --> pn(Num,PN).
np(Num,NP) -->
   d(Det),
   n(Num,N),
   rel(Num,Rel),
   {build_np(Det,N,Rel,NP)}. /* embedded Prolog goal */

/* Prolog rules to build a noun phrase from its parts */
build_np(Det,N,rel(nil),np(Det,N)).
build_np(Det,N,rel(RP,VP),np(Det,N,rel(RP,VP))).

/* A verb phrase consists of a transitive verb and a noun phrase
   or an intransitive verb */
vp(Num,vp(TV,NP)) -->
              tv(Num,TV), 
              np(_,NP).
vp(Num,vp(IV)) --> iv(Num,IV).

/* A relative pronoun phrase consists of the relative pronoun
   and a verb phrase */
rel(_Num,rel(nil)) --> [].
rel(Num,rel(RP,VP)) -->
             rpn(RP), vp(Num,VP).

/* Sample pronouns */
pn(sing,pn(PN)) --> [PN], {pn(PN,_X)}.
pn(plu,pn(PN)) --> [PN], {pn(_X,PN)}.
pn(mary,marys).
pn(henry,henrys).

/* Sample relative pronouns */
rpn(rpn(RPN)) --> [RPN], {rpn(RPN)}.
rpn(that).
rpn(which).
rpn(who).

/* Sample intransitive verbs */
iv(sing,iv(IV)) -->[IV], {iv(IV,_X)}.
iv(plu,iv(IV)) --> [IV], {iv(_X,IV)}.
iv(runs,run).
iv(sits,sit).

/* Sample determiners */
d(d(DET)) --> [DET], {d(DET)}.
d(a).
d(the).

/* Sample nouns */
n(sing,n(N)) --> [N], {n(N,_X)}.
n(plu,n(N)) --> [N], {n(_X,N)}.
n(book,books).
n(girl,girls).
n(boy,boys).

/* Sample transitive verbs */
tv(sing,tv(TV)) --> [TV], {tv(TV,_X)}.
tv(plu,tv(TV)) --> [TV], {tv(_X,TV)}.
tv(gives,give).
tv(reads,read).

:- ['read_line'].

parse :- write('Enter English input: '),
         read_line(Input),
         trim_period(Input,I),
         nl,
         s(Parse_form,I,[]),
         write(Parse_form), 
         nl, nl.

trim_period([.],[]).     
trim_period([X|R],[X|T]) :- trim_period(R,T).
