top_s --> s(fin,nogap,nogap).

s(Vform,G0,G) --> n(2,G0,G1), v(2,Vform,G1,G).

n(2,G,G) --> proper_noun.
n(2,G,G) --> det, n(1).
n(1) --> n(1), s(fin,gap,nogap).
n(1) --> n(0).

n(2,gap,nogap) --> [].

v(2,Vform,G0,G) --> v(1,Vform,G0,G).

v(1,Vform,G,G) --> v(intrans,Vform).
v(1,Vform,G0,G) --> v(trans,Vform), n(2,G0,G).
v(1,Vform,G0,G) --> v(obj_equi,Vform), n(2,G0,G1), v(2,inf,G1,G).
v(1,Vform,G0,G) --> v(scomp,Vform),[that],s(fin,G0,G).
v(1,inf,G0,G) --> v(to,inf), v(2,bse,G0,G).

v(intrans,bse) --> [run].         v(intrans,fin) --> [runs].
v(trans,bse) --> [chase].         v(trans,fin) --> [chases].
v(obj_equi,bse) --> [persuade].   v(obj_equi,fin) --> [persuades].
v(scomp,bse) --> [believe].       v(scomp,fin) --> [believes].
v(to,inf) --> [to].

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

n(0) --> [cat].             n(0) --> [dog].

proper_noun --> [fido].     proper_noun --> [tigger].

test1 :-
  top_s([the,dog,fido,chases,persuades,a,cat,to,chase,tigger],[]).
test2 :-
  top_s([a,dog,chases,the,cat,fido,persuades,to,run],[]).
test3 :-
  top_s([tigger,chases,the,dog,fido,believes,that,a,cat,chases],[]).
