% Prolog representation of a context-free grammar to enforce number agreement and build a parse tree
% This is slightly expanded code of Figures 12.9 in Section 12.6.5 of
% Poole and Mackworth, Artificial Intelligence: foundations of
% computational agents, Cambridge, 2010.
% Copyright (c) David Poole and Alan Mackworth 2010. This program
% is released under GPL, version 3 or later; see http://www.gnu.org/licenses/gpl.html
% a sentence is a noun phrase followed by a verb phrase.
sentence(T_0,T_2,Num,s(NP,VP)) :-
noun_phrase(T_0,T_1,Num,NP),
verb_phrase(T_1,T_2,Num,VP).
% a noun phrase is a determiner followed by modifiers followed
% by a noun followed by an optional prepositional phrase.
noun_phrase(T,T,_,nonp).
noun_phrase(T_0,T_4,Num,np(Det,Num,Mods,Noun,PP)) :-
det(T_0,T_1,Num,Det),
modifiers(T_1,T_2,Mods),
noun(T_2,T_3,Num,Noun),
pp(T_3,T_4,PP).
% a verb phrase is a verb followed by a noun phrase and an optional pp
verb_phrase(T_0,T_3,Num,vp(V,NP,PP)) :-
verb(T_0,T_1,Num,V),
noun_phrase(T_1, T_2, _, NP),
pp(T_2,T_3,PP).
% an optional prepositional phrase is either
% nothing or a preposition followed by a noun phrase
pp(T,T,nopp).
pp(T_0,T_2,pp(Prep,NP)) :-
preposition(T_0,T_1,Prep),
noun_phrase(T_1,T_2,_,NP).
% modifiers is a sequence of adjectives
modifiers(T,T,[]).
modifiers(T0,T2,[A|M]) :-
adjective(T0,T1,A),
modifiers(T1,T2,M).
% DICTIONARY
det([a|T],T,singular,indefinite).
det([some|T],T,plural,indefinite).
det([the|T],T,Num,definite).
adjective([nervous | T],T,nervous).
adjective([happy | T],T,happy).
noun([student|T],T,singular,student).
noun([students|T],T,plural,student).
noun([carrot|T],T,singular,carrot).
noun([carrots|T],T,plural,carrot).
verb([eats|T],T,singular,eat).
verb([eat|T],T,plural,eat).
preposition([with|T],T,with).
% sentence([a,nervous,student,eats,some,carrots],[],Num,Tree).
% sentence([a,nervous,student,with,some,happy,students,eats,some,carrots],[],Num,Tree).
% sentence([a,nervous,student,eats,some,carrots,with,some,happy,students],[],Num,Tree).