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

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

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

verbphrase(Tokens, ivp(Verb), Rest):-
    verb(Tokens, Verb, Rest).

verbphrase(Tokens, tvp(Verb, NP), Rest):-
    verb(Tokens, Verb, More),
    nounphrase(More, NP, Rest).

verbphrase(Tokens, ttvp(Verb, NP_indirect_obj, NP_direct_obj), Rest):-
    verb(Tokens, Verb, More),
    nounphrase(More, NP_indirect_obj, More2),
    nounphrase(More2, NP_direct_obj, Rest).

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

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

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

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

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

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

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

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

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

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

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

