sentence(Tokens, Rest, s(NP, VP), Wff) :-
    nounphrase(Tokens, More, NP, Term),
    verbphrase(More, Rest, VP, Term, Wff).

nounphrase(Tokens, Rest, np(Det, N), Term) :-
    determiner(Tokens, More, Det, Ignored),
    noun(More, Rest, N, Term).

nounphrase(Tokens, Rest, np(N), Term) :-
    propernoun(Tokens, Rest, N, Term).

verbphrase(Tokens, Rest, ivp(Verb), Term, [Predicate,Term]) :-
    verb(Tokens, Rest, Verb, Predicate).

verbphrase(Tokens, Rest, tvp(Verb, NP), Term1, [Predicate,Term1,Term2]) :-
    verb(Tokens, More, Verb, Predicate),
    nounphrase(More, Rest, NP, Term2).

verbphrase(Tokens, Rest, ttvp(Verb, NP_indirect_obj, NP_direct_obj), Term1, [Predicate,Term1,Term2,Term3]) :-
    verb(Tokens, More, Verb, Predicate),
    nounphrase(More, More2, NP_indirect_obj, Term3),
    nounphrase(More2, Rest, NP_direct_obj, Term2).

determiner([the | Rest], Rest, det(the), null).

determiner([a | Rest], Rest, det(a), null).

noun([man | Rest], Rest, n(man), adam). 

noun([apple | Rest], Rest, n(apple), apple).

noun([snake | Rest], Rest, n(snake), satan).

verb([eats | Rest], Rest, v(eats), eat). 

verb([loves | Rest], Rest, v(loves), love). 

verb([sleeps | Rest], Rest, v(sleeps), sleep).

verb([gives | Rest], Rest, v(gives), give).

propernoun([eve | Rest], Rest, n(eve), eve). 

propernoun([adam | Rest], Rest, n(adam), adam). 
