Demo: computational semantics in NLTK
import nltk
import nltk.data
#######
# The following grammar shows how to do syntactic analysis
# with context-free grammar in NLTK.
# There is no semantics construction in this grammar.
gramstring = r"""
% start S
S -> NP VP
NP -> PN
VP -> IV
VP -> TV NP
PN -> 'Vincent'
PN -> 'Mia'
IV -> 'sleeps'
TV -> 'loves'
"""
grammar = nltk.grammar.CFG.fromstring(gramstring)
parser = nltk.parse.ChartParser(grammar)
inputs = ["Vincent sleeps", "Vincent loves Mia"]
for sent in inputs:
print("\nsentence:", sent, "\n")
trees = parser.parse(sent.split())
for tree in trees:
print(tree)
#######
# Now we add semantics. We do this in brackets after each nonterminal (constituent or POS label).
# The following grammar only has proper nouns, no other NPs,
# and represents Vincent as simply "vincent", of type e.
gramstring = r"""
% start S
S[SEM = <?vp(?np)>] -> NP[SEM=?np] VP[SEM=?vp]
NP[SEM=?pn] -> PN[SEM=?pn]
VP[SEM=?v] -> IV[SEM=?v]
VP[SEM=<?v(?np)>] -> TV[SEM=?v] NP[SEM=?np]
PN[SEM=<vincent>] -> 'Vincent'
PN[SEM=<mia>] -> 'Mia'
IV[SEM=<\x.sleep(x)>] -> 'sleeps'
TV[SEM=<\y x.love(x,y)>] -> 'loves'
"""
grammar = nltk.grammar.FeatureGrammar.fromstring(gramstring)
parser = nltk.parse.FeatureChartParser(grammar)
inputs = ["Vincent sleeps", "Vincent loves Mia"]
for sent in inputs:
print("\nsentence:", sent, "\n")
trees = parser.parse(sent.split())
for tree in trees:
print(tree)
#######
# The following grammar has noun phrases that are either
# proper nouns or Det N.
# Noun phrases are of type <<e, t>, t>
gramstring = r"""
% start S
S[SEM = <?np(?vp)>] -> NP[SEM=?np] VP[SEM=?vp]
NP[SEM=?pn] -> PN[SEM=?pn]
NP[SEM=<?det(?n)>] -> Det[SEM=?det] N[SEM=?n]
VP[SEM=?v] -> IV[SEM=?v]
VP[SEM=<?v(?np)>] -> TV[SEM=?v] NP[SEM=?np]
PN[SEM=<\P.P(vincent)>] -> 'Vincent'
PN[SEM=<\P.P(mia)>] -> 'Mia'
N[SEM=<\x.robber(x)>] -> 'robber'
Det[SEM=<\P Q.all x.(P(x) -> Q(x))>] -> 'every'
IV[SEM=<\x.sleep(x)>] -> 'sleeps'
TV[SEM=<\X x.X(\y.love(x,y))>] -> 'loves'
"""
grammar = nltk.grammar.FeatureGrammar.fromstring(gramstring)
parser = nltk.parse.FeatureChartParser(grammar)
inputs = ["Vincent sleeps", "Mia loves every robber"]
for sent in inputs:
print("\nsentence:", sent, "\n")
trees = parser.parse(sent.split())
for tree in trees:
print(tree)
################
# Blackburn and Bos
# chapter 2
# This grammar only does the syntax!
gramstring = """
% start S
S -> NP VP
VP -> VBAR[FIN=fin]
VP -> MOD VBAR[FIN=inf]
VP -> VP COORD VP
NP -> DET NBAR
NP -> PN
NP -> PRO
NP -> NP COORD NP
NBAR -> N
NBAR -> N PP
NBAR -> N RC
NBAR -> NBAR COORD NBAR
VBAR[FIN=?f] -> TV[FIN=?f] NP
VBAR[FIN=?f] -> IV[FIN=?f]
VBAR[FIN=?f] -> VBAR[FIN=?F] COORD VBAR[FIN=?f]
VBAR[FIN=fin] -> COP NP
VBAR[FIN=fin] -> COP NEG NP
N -> N COORD N
PP -> PREP NP
RC -> RELPRO VP
##################
COORD -> 'and'
COORD -> 'or'
COP -> 'is'
DET -> 'every'
DET -> 'a'
IV[FIN=fin] -> 'collapses'
IV[FIN=fin] -> 'dances'
IV[FIN=fin] -> 'snorts'
IV[FIN=inf] -> 'collapse'
IV[FIN=inf] -> 'dance'
IV[FIN=inf] -> 'snort'
N -> 'bar'
N -> 'boxer'
N -> 'criminal'
N -> 'owner'
N -> 'woman'
PN -> 'Vincent'
PN -> 'Mia'
PREP -> 'of'
PRO -> 'she'
PRO -> 'he'
MOD -> "doesn't"
NEG -> 'not'
RELPRO -> 'that'
TV[FIN=fin] -> 'kills'
TV[FIN=fin] -> 'knows'
TV[FIN=fin] -> 'loves'
TV[FIN=inf] -> 'kill'
TV[FIN=inf] -> 'know'
TV[FIN=inf] -> 'love'
"""
grammar = nltk.grammar.FeatureGrammar.fromstring(gramstring)
parser = nltk.parse.FeatureChartParser(grammar)
inputs = ["Mia knows every owner of a bar", "Vincent or Mia dances", "every boxer that kills a criminal loves a woman", "Vincent doesn't love a boxer or criminal that snorts", "she doesn't love a boxer or criminal that snorts and dances", "a boxer snorts", "he collapses", "Mia is a woman", "Vincent is not a boxer"]
print( "************ B&B chapter 2 *****")
for sent in inputs:
print("\nsentence:", sent, "\n")
trees = parser.parse(sent.split())
for tree in trees:
print(tree)