:- op(500, yfx, @).
:- op(550, xfx, =>).
:- op(600, xfy, ^).

s(S) --> sn(SN), v(i, V), {reduz(SN@V, S)}.
s(V@N) --> n(p, N), v(i, V).

sn(SN) --> det(Det), n(c, N), {reduz(Det@N, SN)}.

det(P^Q^qualquer(X, P@X => Q@X)) --> [todo].

n(c, m) --> [menino].
n(p, p) --> [pedro].

v(i, d) --> [dormiu].

reduz((Argumento^Expressão)@Argumento, Expressão).
