analisa(Expressão) :-
        categoria(Categoria),
        (   (Categoria = n; Categoria = v)
        ->  Regra =.. [Categoria, _, Sem]
        ;   Regra =.. [Categoria, Sem]
        ),
        phrase(Regra, Expressão, []),
        write(Categoria), write(':'), nl,
        apresenta(3, Sem).

categoria(s).
categoria(sn).
categoria(sv).
categoria(det).
categoria(n).
categoria(v).

apresenta(N, [X, Y]) :-
        tab(N),
        write(X),
        nl, nl,
        M is N + 5,
        apresenta_lista(M, Y).

apresenta_lista(_, []).
apresenta_lista(N, [X|Y]) :-
        apresenta(N, X),
        apresenta_lista(N, Y).

s([S, [SN_Comp, SV_Comp]]) --> sn(SN_Comp), sv(SV_Comp),
        {SN_Comp = [SN, _], SV_Comp = [SV, _], SN = SV^S}.

sn([N_Promov, [N_Comp]]) --> n(próprio, N_Comp),
        {N_Comp = [N, _], N_Promov = (N^P)^P}.
sn([SN, [Det_Comp, N_Comp]]) --> det(Det_Comp), n(comum, N_Comp),
        {Det_Comp = [Det, _], N_Comp = [N, _], Det = N^SN}.

sv(V) --> v(intransitivo, V).
sv([X^SV, [V_Comp, SN_Comp]]) --> v(transitivo, V_Comp), sn(SN_Comp),
        {SN_Comp = [(Y^V)^SV|_], V_Comp = [Y^X^V|_]}.

n(Tipo, [Denotação, []]) --> [Expressão],
        {n(Tipo, Expressão, Denotação)}.

n(comum, buraco, X^buraco(X)).
n(comum, menino, X^menino(X)).
n(próprio, pedro, pedro).

det([Denotação, []]) --> [Expressão], {det(Denotação, Expressão)}.

det((Arg^Func1)^(Arg^Func2)^qualquer(Arg, Func1, Func2), todo).
det((Arg^Func1)^(Arg^Func2)^algum(Arg, Func1, Func2), um).

v(Tipo, [Denotação, []]) --> [Expressão],
        {v(Tipo, Expressão, Denotação)}.

v(intransitivo, dormiu, X^dormir(X)).
v(transitivo, saltou, Y^X^saltar(X, Y)).
