% Top-down DCG parser in Prolog
% progtdpar1.pl

s(L0, L) :- np(X, Y, L0, L1), vp(X, Y, L1, L).
np(X, Y, L0, L) :- pro(X, Y, L0, L).
np(3, X, L0, L) :- det(X, L0, L1), n(X, L1, L).
vp(X, Y, L0, L) :- vi(X, Y, L0, L).
vp(X, Y, L0, L) :- vbe(X, Y, L0, L1), adj(L1, L).

det(sing, [this|L], L).
det(plu,  [these|L], L).
det(X,    [the|L], L).

n(sing, [knight|L], L).
n(plu,  [knights|L], L).
n(X,    [sheep|L], L).

pro(1, sing, [i|L], L).
pro(1, plu,  [we|L], L).
pro(2, X,    [you|L], L).
pro(3, sing, [it|L], L).
pro(3, plu,  [they|L], L).

adj([tipsy|L], L).

vbe(1, sing, [am|L], L).
vbe(1, plu,  [are|L], L).
vbe(2, X,    [are|L], L).
vbe(3, plu,  [are|L], L).
vbe(3, sing, [is|L], L).

vi(X, Y,    [slept|L], L).
vi(1, X,    [sleep|L], L).
vi(2, X,    [sleep|L], L).
vi(3, plu,  [sleep|L], L).
vi(3, sing, [sleeps|L], L).