:- op(1200,xfx,'--->').


:- multifile (--->)/2, word/2.


parse(Phrase) -->
   leaf(SubPhrase), lc(SubPhrase,Phrase).


leaf(Cat) --> [Word], {word(Word,Cat)}.

leaf(Phrase) -->  {Phrase ---> []}.


lc(Phrase,Phrase) -->  [].

lc(SubPhrase,SuperPhrase) -->
   {rule(SubPhrase, Phrase, Rest)},
   parse_rest(Rest),
   lc(Phrase,SuperPhrase).

rule(SubPhrase, Phrase, Rest) :-
    nonterminal(SubPhrase),
    (Phrase ---> Body),
    get_lc(Body, Constraints, SubPhrase, Rest),
    call(Constraints).


parse_rest(Phrase) -->  
   {(Phrase \== (_,_)),
    (Phrase \== {_}),
    (Phrase \== [])},
   parse(Phrase).

parse_rest({Goals}) --> {call(Goals)}.

parse_rest([]) --> [].

parse_rest((Phrase,Phrases)) -->
   parse_rest(Phrase),
   parse_rest(Phrases).


nonterminal(Phrase) :-
   \+ \+ ((_Head ---> Body), get_lc(Body, _, Phrase, _)).

get_lc(({Constraints},LC,Rest), Constraints, LC, Rest).
get_lc(({Constraints},LC), Constraints, LC, []).
get_lc((LC, Rest), true, LC, Rest) :- (LC \== {_}).
get_lc(LC, true, LC, []) :- (LC \== (_,_)).

