Thursday, May 11, 2006

Lab 3 benim_lab_rules.py

from semantic import *
from parser.feature import *

sem = SemanticRuleSet()
identity = lambda x: x

### Rules ###

# Start rules
sem.add("Start -> S", lambda s: processSentence(s))
sem.add("Start -> Q[wh +]", lambda q: whQuestion(q))
sem.add("Start -> Q[wh -]", lambda q: ynQuestion(q))

# Declarative sentence
sem.add("S -> NP[wh -] VP", lambda np, vp: vp(np))

# Yes-no question
sem.add("Q[wh -] -> Do_Modal NP[wh -] VBAR[fin +]",
lambda dm, np, vbar: dm(vbar(np)))

# Where did ...
sem.add("Q[wh +] -> AdvP[wh +] Q[wh -]",
lambda advp, q:
q.addFeature(str(advp.getFeature("type").value()),
advp.getFeature("var").value()))

sem.add("Q[wh +] -> NP[wh +] VP",
lambda np, vp: vp(np))

sem.add("Q[wh +] -> NP[wh +] Q/NP",
lambda np, q: q(np))

sem.add("Q/NP -> Do_Modal NP VBAR[fin +]/NP",
lambda dm, np, vbar: lambda object: dm(vbar(np, object)))

sem.add("VBAR[fin +]/NP -> V2[tense -] NP/NP",
lambda v2, e: v2)

sem.add("VBAR[fin +]/NP -> V3[tense -] NP PP.dat/NP",
lambda v3, np, pp: lambda subj, beneficiary: v3(subj, beneficiary, np))

sem.add("VBAR[fin +]/NP -> V3[tense -] NP/NP PP.dat",
lambda v3, np, pp: lambda subj, patient: v3(subj, pp, patient))

sem.add("VBAR[fin +]/NP -> V3[tense -] NP/NP NP",
lambda v3, np1, np2: lambda subj, patient: v3(subj, np2, patient))

# NP
sem.add("NP[pro -, wh -] -> Name", identity)
sem.add("NP[pro -, wh -] -> Det AP* N", lambda det, apstar, n: n(det, apstar))
sem.add("NP[pro -, wh -] -> AP* N[mass +]", lambda apstar, nmass: nmass(apstar))

# AdvP[wh +]
#sem.add("NP[wh +] -> NP[pro +, wh +]", identity)
sem.add("AdvP[wh +] -> Adv[wh +]", identity)

# AP
sem.add("AP* -> AP* AP", lambda apstar, ap: C(ap, mod=apstar))
sem.add("AP* ->", lambda: StarCategory())
sem.add("AP -> A", identity)

# VP
sem.add("VP -> V+args", lambda v: lambda subj: v(subj))
sem.add("VP -> Do_Modal VBAR[fin +]",
lambda dm, vbar: lambda subj: dm(vbar(subj)))
sem.add("V+args -> Be[tense +] V.part[form V2]",
lambda be, vpart: lambda subj: be(vpart(Category.parse("Object"), subj)))
sem.add("V+args -> Be[tense +] V.part[form V2] PP.by",
lambda be, vpart, pp: lambda subj: be(vpart(pp, subj)))
sem.add("V+args -> V1[tense +]", lambda v1: lambda subj: v1(subj))
sem.add("V+args -> V1[tense +] PP", lambda v1, pp: lambda subj: pp(v1(subj)))
sem.add("VBAR[fin +] -> V1[tense -]", lambda v1: lambda subj: v1(subj))
sem.add("V+args -> V2[tense +] NP", lambda v2, np: lambda subj: v2(subj, np))
sem.add("V+args -> V2[tense +] NP[wh -] PP",
lambda v2, np, pp: lambda subj: pp(v2(subj, np)))
sem.add("VBAR[fin +] -> V2[tense -] NP[wh -]",
lambda v2, np: lambda subj: v2(subj, np))
sem.add("V+args -> V3[tense +] NP[wh -] PP.dat",
lambda v3, np, pp: lambda subj: v3(subj, pp, np))
sem.add("V+args -> V3[tense +] NP[wh -] NP[wh -]",
lambda v3, np1, np2: lambda subj: v3(subj, np1, np2))
sem.add("VBAR[fin +] -> V3[tense -] NP[wh -] PP.dat",
lambda v3, np, pp: lambda subj: v3(subj, pp, np))
sem.add("VBAR[fin +] -> V3[tense -] NP[wh -] NP[wh -]",
lambda v3, np1, np2: lambda subj: v3(subj, np1, np2))
sem.add("V+args -> V4[tense +] NP[wh -] PP[loc +]",
lambda v4, np, pp: lambda subj: v4(subj, np, pp))
sem.add("V+args -> V5[tense +] VBAR[fin -]",
lambda v5, vbar: lambda subj: v5(subj, vbar(subj)))
sem.add("V+args -> V6[tense +] NP[wh -] VBAR[fin -]",
lambda v6, np, vbar: lambda subj: v6(subj, np, vbar(np)))
sem.add("V+args -> V8[tense +] SBAR.that[fact -]",
lambda v8, sbar: lambda subj: v8(subj, sbar))
sem.add("V+args -> V9[tense +] SBAR.that[fact +]",
lambda v9, sbar: lambda subj: v9(subj, sbar))
sem.add("V+args -> V10[tense +] AP.pred",
lambda v10, ap: lambda subj: v10(subj, ap))
sem.add("V+args -> V11[tense +] Q_emb",
lambda v11, qemb: lambda subj: v11(subj, qemb))
sem.add("V+args -> V12[tense +] SBAR.for",
lambda v12, sbar: lambda subj: v12(subj, sbar))

# VBAR[fin -]
sem.add("VBAR[fin -] -> To VBAR[fin +]",
lambda to, vbar: lambda subj: vbar(subj))
# Q_emb
sem.add("Q_emb -> SBAR.comp[wh +]", identity)

# AP.pred
sem.add("AP.pred -> A.pred PP", lambda a, ppstar: a(ppstar))

# PP
sem.add("PP[loc ?x] -> P[loc ?x] NP[wh -]", lambda p, np: p(np))
sem.add("PP -> P NP", lambda p, np: p(np))
sem.add("PP.dat -> P.dat NP", lambda p, np: p(np))
sem.add("PP.by -> P.by NP", lambda p, np: p(np))

# SBAR.that
sem.add("SBAR.that -> That S", lambda that, s: s)

# SBAR.comp[wh +]
sem.add("SBAR.comp[wh +] -> Comp[wh +] S", lambda comp, s: s)

# SBAR.for
sem.add("SBAR.for -> For NP[wh -] VBAR[fin -]",
lambda for_, np, vbar: vbar(np))

# Do or Modal
sem.add("Do_Modal -> Do[tense +]", identity)
sem.add("Do_Modal -> Modal", identity)

# Empty slash rules
sem.add("NP/NP ->", lambda: None)
sem.add("PP.dat/NP -> P.dat NP/NP", lambda p, np: None)

### Lexicon ###

# Names
sem.addMatch("Name -> *", lambda name: C("Object", name=name))

sem.addLexicon("Name",
['Bob', 'Bill', 'Fido', 'Fred', 'icecream', 'Jane', 'John', 'Mary', 'Poirot', 'Rusty'])

# Common nouns
sem.addMatch("N[mass -] -> *", lambda word: lambda det, apstar: C("Object", type=word, definite=det, mod=apstar))
sem.addMatch("N[mass +] -> *", lambda word: lambda det, apstar: C("Object", type=word, definite=False, number='mass',
mod=apstar))

sem.addLexicon("N[mass -, number singular]",
['book', 'cadillac', 'car', 'case', 'city', 'communist', 'conference',
'corner', 'dog', 'eggplant', 'exam', 'fact', 'guy', 'kennel', 'letter',
'man', 'park', 'pencil', 'pot', 'room', 'table', 'tax', 'theory',
'tree', 'tune', 'volume', 'werewolf', 'woman'])
sem.addLexicon("N[mass -, number plural]",
['books', 'cats', 'cities', 'cows', 'drugs', 'friends', 'horses',
'keys', 'mets', 'redsox', 'teams', 'volumes', 'years'])
sem.addLexicon("N[mass +]", ['icecream'])
sem.add("Det -> 'the'", lambda word: True)
sem.add("Det -> 'this'", lambda word: True)
sem.add("Det -> 'a'", lambda word: False)
sem.add("Det -> 'an'", lambda word: False)

# wh-words
sem.addMatch("NP[pro +, wh +] -> *", lambda word: VariableValue(word))
sem.addLexicon("NP[pro +, wh +]", ['who', 'what'])
sem.add("Adv[wh +] -> 'where'", lambda word: C('Adverb', type='locative', var=VariableValue("where")))

def addVerb(form, root, past, present, ppart=None):
global sem
if ppart is None: ppart = past
(pos, proc) = form
sem.add(CFGProduction(pos.mix(C(None, tense=False)), root),
proc(root, False))
sem.add(CFGProduction(pos.mix(C(None, tense=True)), past),
proc(root, "past"))
sem.add(CFGProduction(pos.mix(C(None, tense=True)), present),
proc(root, "present"))
sem.add(CFGProduction(C("V.part", form=pos), ppart),
proc(root, "past-participle"))

v1form = (C("V1"),
lambda root, tense: lambda word: lambda agent: C("Event", action=root, agent=agent, tense=tense))

v2form = (C("V2"),
lambda root, tense: lambda word: lambda agent, patient: C("Event", action=root, agent=agent, patient=patient,
tense=tense))

v3form = (C("V3"),
lambda root, tense: lambda word: lambda agent, beneficiary, patient: C("Event", action=root, agent=agent, patient=patient,
beneficiary=beneficiary, tense=tense))

addVerb(v1form, 'come', 'came', 'comes', 'come')
addVerb(v1form, 'drive', 'drove', 'drives', 'driven')
addVerb(v1form, 'eat', 'ate', 'eats', 'eaten')
addVerb(v1form, 'return', 'returned', 'returns')
addVerb(v1form, 'sing', 'sang', 'sings', 'sung')
addVerb(v1form, 'sleep', 'slept', 'sleeps')
addVerb(v1form, 'talk', 'talked', 'talks')

addVerb(v2form, 'eat', 'ate', 'eats', 'eaten')
addVerb(v2form, 'buy', 'bought', 'buys')
addVerb(v2form, 'catch', 'caught', 'catches')
addVerb(v2form, 'chase', 'chased', 'chases')
addVerb(v2form, 'compute', 'computed', 'computes')
addVerb(v2form, 'drive', 'drove', 'drives', 'driven')
addVerb(v2form, 'find', 'found', 'finds')
addVerb(v2form, 'hate', 'hated', 'hates')
addVerb(v2form, 'keep', 'kept', 'keeps')
addVerb(v2form, 'kill', 'killed', 'kills')
addVerb(v2form, 'like', 'liked', 'likes')
addVerb(v2form, 'love', 'loved', 'loves')
addVerb(v2form, 'make', 'made', 'makes')
addVerb(v2form, 'pass', 'passed', 'passes')
addVerb(v2form, 'please', 'pleased', 'pleases')
addVerb(v2form, 'sing', 'sang', 'sings', 'sung')
addVerb(v2form, 'see', 'saw', 'sees', 'seen')
addVerb(v2form, 'support', 'supported', 'supports')
addVerb(v2form, 'surprise', 'surprised', 'surprises')
addVerb(v2form, 'visit', 'visited', 'visits')
addVerb(v2form, 'kiss', 'kissed', 'kisses')
addVerb(v3form, 'give', 'gave', 'gives', 'given')

sem.add("P[loc -] -> 'in'",
lambda word: lambda location: lambda frame: frame.addFeature("locative", C("Place", relation="in",
location=location)))

sem.add("P[loc -] -> 'under'",
lambda word: lambda location: lambda frame: frame.addFeature("locative", C(None, relation="under",
location=location)))

sem.add("P[loc +] -> 'on'",
lambda word: lambda location: C("locative", C(None, relation="on",
location=location)))

sem.add("P[loc -] -> 'of'",
lambda word: lambda source: lambda frame: frame.addFeature("source", source))

sem.add("P.dat -> 'to'",
lambda word: identity)

sem.add("P.by -> 'by'",
lambda word: identity)

# Adjectives
sem.addMatch("A -> *", lambda word: C(word))
sem.addLexicon("A", ['rabid', 'raw', 'smart', 'red', 'blue', 'green', 'yellow'])

sem.add("A.pred -> 'suspicious'", lambda word: lambda source: C("suspicious", source=source))

# Aux and Modal
sem.add("Do[tense +] -> 'did'",
lambda word: lambda verb_frame: verb_frame.addFeature("tense", "past"))

sem.add("Do[tense +] -> 'does'",
lambda word: lambda verb_frame: verb_frame.addFeature("tense", "present"))

sem.add("Be[tense +] -> 'is'",
lambda word: lambda verb_frame: verb_frame.addFeature("tense", "present"))

sem.add("Be[tense +] -> 'was'",
lambda word: lambda verb_frame: verb_frame.addFeature("tense", "past"))

sem.add("Modal -> 'can'",
lambda word: lambda verb_frame: verb_frame.addFeature("mood", "can").addFeature("tense", "present"))

sem.add("To -> 'to'", lambda word: lambda: None)
sem.add("That -> 'that'", lambda word: lambda: None)
sem.add("Comp[wh +] -> 'whether'", lambda word: lambda: None)
sem.add("NP[wh -, pro +] -> 'somebody'", lambda word: C("Object"))

### Sentence processing ###

def processSentence(data):
sem.learned.add(data)
return "Okay."

def ynQuestion(data):
if sem.learned.match(data) is not None: return "Yes."
else: return "No."

def whQuestion(data):
vars = sem.learned.matchVar(data)
if vars is None: return "I don't know."
else:
if len(vars.keys()) == 1:
return translate(vars.values()[0])
else:
return translate(sem.learned.match(data))

def translate(data):
if data.symbol() == "Object":
name = data.getFeature("name").value()
definite = data.getFeature("definite").value()
plural = data.getFeature("plural").value()
type = data.getFeature("type").value()
mod = translateModifier(data.getFeature("mod").value())
desc = "%s%s" % (mod, type)
if name != Category.null():
return name
elif type != Category.null():
if definite: return "the %s" % desc
else:
if plural: return "some %s" % desc
else: return "a %s" % desc
else: return "something"
elif data.symbol() == "Place":
relation = data.getFeature("relation").value()
location = translate(data.getFeature("location").value())
return "%s %s" % (relation, location)
else: return repr(data)

def translateModifier(data):
if data == Category.null(): return ""
else: return "%s%s " % (translateModifier(data.getFeature("mod").value()), data.symbol())

Batch Results for Lab 3

Hello.
> John gave Mary Fido
Processing the edge queue...
|[--] . . .| Name -> 'John'
|. [--] . .| V3[tense +] -> 'gave'
|. . [--] .| Name -> 'Mary'
|. . . [--]| Name -> 'Fido'
|> . . . .| Start -> . S
|> . . . .| Start -> . Q[wh +]
|> . . . .| Start -> . Q[wh -]
|> . . . .| S -> . NP[wh -] VP
|> . . . .| Q[wh +] -> . NP[wh +] Q/NP
|> . . . .| Q[wh +] -> . NP[wh +] VP
|> . . . .| Q[wh +] -> . AdvP[wh +] Q[wh -]
|> . . . .| Q[wh -] -> . Do_Modal NP[wh -] VBAR[fin +]
|> . . . .| NP[pro -, wh -] -> . AP* N[mass +]
|> . . . .| NP[pro -, wh -] -> . Det AP* N
|> . . . .| NP[pro -, wh -] -> . Name
|> . . . .| AdvP[wh +] -> . Adv[wh +]
|> . . . .| Do_Modal -> . Modal
|> . . . .| Do_Modal -> . Do[tense +]
|# . . . .| AP* ->
|> . . . .| AP* -> . AP* AP
|[--] . . .| NP[pro -, wh -] -> Name
|> . . . .| NP[pro -, wh -] -> AP* . N[mass +]
|> . . . .| AP* -> AP* . AP
|[--> . . .| S -> NP[wh -] . VP
|> . . . .| AP -> . A
|. > . . .| VP -> . Do_Modal VBAR[fin +]
|. > . . .| VP -> . V+args
|. > . . .| Do_Modal -> . Modal
|. > . . .| Do_Modal -> . Do[tense +]
|. > . . .| V+args -> . V12[tense +] SBAR.for
|. > . . .| V+args -> . V11[tense +] Q_emb
|. > . . .| V+args -> . V10[tense +] AP.pred
|. > . . .| V+args -> . V9[tense +] SBAR.that[fact +]
|. > . . .| V+args -> . V8[tense +] SBAR.that[fact -]
|. > . . .| V+args -> . V6[tense +] NP[wh -] VBAR[fin -]
|. > . . .| V+args -> . V5[tense +] VBAR[fin -]
|. > . . .| V+args -> . V4[tense +] NP[wh -] PP[loc +]
|. > . . .| V+args -> . V3[tense +] NP[wh -] NP[wh -]
|. > . . .| V+args -> . V3[tense +] NP[wh -] PP.dat
|. > . . .| V+args -> . V2[tense +] NP[wh -] PP
|. > . . .| V+args -> . V2[tense +] NP
|. > . . .| V+args -> . V1[tense +] PP
|. > . . .| V+args -> . V1[tense +]
|. > . . .| V+args -> . Be[tense +] V.part[form V2] PP.by
|. > . . .| V+args -> . Be[tense +] V.part[form V2]
|. [--> . .| V+args -> V3[tense +] . NP[wh -] NP[wh -]
|. [--> . .| V+args -> V3[tense +] . NP[wh -] PP.dat
|. . > . .| NP[pro -, wh -] -> . AP* N[mass +]
|. . > . .| NP[pro -, wh -] -> . Det AP* N
|. . > . .| NP[pro -, wh -] -> . Name
|. . # . .| AP* ->
|. . > . .| AP* -> . AP* AP
|. . [--] .| NP[pro -, wh -] -> Name
|. . > . .| NP[pro -, wh -] -> AP* . N[mass +]
|. . > . .| AP* -> AP* . AP
|. [-----> .| V+args -> V3[tense +] NP[wh -] . NP[wh -]
|. [-----> .| V+args -> V3[tense +] NP[wh -] . PP.dat
|. . > . .| AP -> . A
|. . . > .| NP[pro -, wh -] -> . AP* N[mass +]
|. . . > .| NP[pro -, wh -] -> . Det AP* N
|. . . > .| NP[pro -, wh -] -> . Name
|. . . > .| PP.dat -> . P.dat NP
|. . . # .| AP* ->
|. . . > .| AP* -> . AP* AP
|. . . [--]| NP[pro -, wh -] -> Name
|. . . > .| NP[pro -, wh -] -> AP* . N[mass +]
|. . . > .| AP* -> AP* . AP
|. [--------]| V+args -> V3[tense +] NP[wh -] NP[wh -]
|. . . > .| AP -> . A
|. [--------]| VP -> V+args
|[===========]| S -> NP[wh -] VP
|[===========]| Start -> S

Found 1 parses with 76 edges
>> Evaluating: Start -> S
Text: John gave Mary Fido
Expression: (lambda s: processSentence(s))

>> Evaluating: S -> NP[pro -, wh -] VP
Text: John gave Mary Fido
Expression: (lambda np, vp: vp(np))

>> Evaluating: NP[pro -, wh -] -> Name
Text: John
Expression: (lambda x: x)

>> Evaluating: Name -> 'John'
Text: John
Expression: (lambda name: C('Object', name=name))

<< Evaluated: Name -> 'John'
Text: John
Value: Object[name John]

<< Evaluated: NP[pro -, wh -] -> Name
Text: John
Value: Object[name John]

>> Evaluating: VP -> V+args
Text: gave Mary Fido
Expression: (lambda v: (lambda subj: v(subj)))

>> Evaluating: V+args -> V3[tense +] NP[pro -, wh -] NP[pro -, wh -]
Text: gave Mary Fido
Expression: (lambda v3, np1, np2: (lambda subj: v3(subj, np1, np2)))

>> Evaluating: V3[tense +] -> 'gave'
Text: gave
Expression: (lambda word: (lambda agent, beneficiary, patient: C('Event', action='give', agent=agent, patient=patient, beneficiary=beneficiary, tense='past')))

<< Evaluated: V3[tense +] -> 'gave'
Text: gave
Value: (lambda agent, beneficiary, patient: C('Event', action='give', agent=agent, patient=patient, beneficiary=beneficiary, tense='past'))

>> Evaluating: NP[pro -, wh -] -> Name
Text: Mary
Expression: (lambda x: x)

>> Evaluating: Name -> 'Mary'
Text: Mary
Expression: (lambda name: C('Object', name=name))

<< Evaluated: Name -> 'Mary'
Text: Mary
Value: Object[name Mary]

<< Evaluated: NP[pro -, wh -] -> Name
Text: Mary
Value: Object[name Mary]

>> Evaluating: NP[pro -, wh -] -> Name
Text: Fido
Expression: (lambda x: x)

>> Evaluating: Name -> 'Fido'
Text: Fido
Expression: (lambda name: C('Object', name=name))

<< Evaluated: Name -> 'Fido'
Text: Fido
Value: Object[name Fido]

<< Evaluated: NP[pro -, wh -] -> Name
Text: Fido
Value: Object[name Fido]

<< Evaluated: V+args -> V3[tense +] NP[pro -, wh -] NP[pro -, wh -]
Text: gave Mary Fido
Value: (lambda subj: (lambda agent, beneficiary, patient: C('Event', action='give', agent=agent, patient=patient, beneficiary=beneficiary, tense='past'))@(subj, Object[name Mary], Object[name Fido]))

<< Evaluated: VP -> V+args
Text: gave Mary Fido
Value: (lambda subj: (lambda subj: (lambda agent, beneficiary, patient: C('Event', action='give', agent=agent, patient=patient, beneficiary=beneficiary, tense='past'))@(subj, Object[name Mary], Object[name Fido]))@(subj))

<< Evaluated: S -> NP[pro -, wh -] VP
Text: John gave Mary Fido
Value: Event[action give, agent Object[name John], beneficiary Object[name Mary], patient Object[name Fido], tense past]

<< Evaluated: Start -> S
Text: John gave Mary Fido
Value: 'Okay.'

Okay.


----------

> John did give Mary Fido
Processing the edge queue...
|[--] . . . .| Name -> 'John'
|. [--] . . .| Do[tense +] -> 'did'
|. . [--] . .| V3[tense -] -> 'give'
|. . . [--] .| Name -> 'Mary'
|. . . . [--]| Name -> 'Fido'
|> . . . . .| Start -> . S
|> . . . . .| Start -> . Q[wh +]
|> . . . . .| Start -> . Q[wh -]
|> . . . . .| S -> . NP[wh -] VP
|> . . . . .| Q[wh +] -> . NP[wh +] Q/NP
|> . . . . .| Q[wh +] -> . NP[wh +] VP
|> . . . . .| Q[wh +] -> . AdvP[wh +] Q[wh -]
|> . . . . .| Q[wh -] -> . Do_Modal NP[wh -] VBAR[fin +]
|> . . . . .| NP[pro -, wh -] -> . AP* N[mass +]
|> . . . . .| NP[pro -, wh -] -> . Det AP* N
|> . . . . .| NP[pro -, wh -] -> . Name
|> . . . . .| AdvP[wh +] -> . Adv[wh +]
|> . . . . .| Do_Modal -> . Modal
|> . . . . .| Do_Modal -> . Do[tense +]
|# . . . . .| AP* ->
|> . . . . .| AP* -> . AP* AP
|[--] . . . .| NP[pro -, wh -] -> Name
|> . . . . .| NP[pro -, wh -] -> AP* . N[mass +]
|> . . . . .| AP* -> AP* . AP
|[--> . . . .| S -> NP[wh -] . VP
|> . . . . .| AP -> . A
|. > . . . .| VP -> . Do_Modal VBAR[fin +]
|. > . . . .| VP -> . V+args
|. > . . . .| Do_Modal -> . Modal
|. > . . . .| Do_Modal -> . Do[tense +]
|. > . . . .| V+args -> . V12[tense +] SBAR.for
|. > . . . .| V+args -> . V11[tense +] Q_emb
|. > . . . .| V+args -> . V10[tense +] AP.pred
|. > . . . .| V+args -> . V9[tense +] SBAR.that[fact +]
|. > . . . .| V+args -> . V8[tense +] SBAR.that[fact -]
|. > . . . .| V+args -> . V6[tense +] NP[wh -] VBAR[fin -]
|. > . . . .| V+args -> . V5[tense +] VBAR[fin -]
|. > . . . .| V+args -> . V4[tense +] NP[wh -] PP[loc +]
|. > . . . .| V+args -> . V3[tense +] NP[wh -] NP[wh -]
|. > . . . .| V+args -> . V3[tense +] NP[wh -] PP.dat
|. > . . . .| V+args -> . V2[tense +] NP[wh -] PP
|. > . . . .| V+args -> . V2[tense +] NP
|. > . . . .| V+args -> . V1[tense +] PP
|. > . . . .| V+args -> . V1[tense +]
|. > . . . .| V+args -> . Be[tense +] V.part[form V2] PP.by
|. > . . . .| V+args -> . Be[tense +] V.part[form V2]
|. [--] . . .| Do_Modal -> Do[tense +]
|. [--> . . .| VP -> Do_Modal . VBAR[fin +]
|. . > . . .| VBAR[fin +] -> . V3[tense -] NP[wh -] NP[wh -]
|. . > . . .| VBAR[fin +] -> . V3[tense -] NP[wh -] PP.dat
|. . > . . .| VBAR[fin +] -> . V2[tense -] NP[wh -]
|. . > . . .| VBAR[fin +] -> . V1[tense -]
|. . [--> . .| VBAR[fin +] -> V3[tense -] . NP[wh -] NP[wh -]
|. . [--> . .| VBAR[fin +] -> V3[tense -] . NP[wh -] PP.dat
|. . . > . .| NP[pro -, wh -] -> . AP* N[mass +]
|. . . > . .| NP[pro -, wh -] -> . Det AP* N
|. . . > . .| NP[pro -, wh -] -> . Name
|. . . # . .| AP* ->
|. . . > . .| AP* -> . AP* AP
|. . . [--] .| NP[pro -, wh -] -> Name
|. . . > . .| NP[pro -, wh -] -> AP* . N[mass +]
|. . . > . .| AP* -> AP* . AP
|. . [-----> .| VBAR[fin +] -> V3[tense -] NP[wh -] . PP.dat
|. . [-----> .| VBAR[fin +] -> V3[tense -] NP[wh -] . NP[wh -]
|. . . > . .| AP -> . A
|. . . . > .| PP.dat -> . P.dat NP
|. . . . > .| NP[pro -, wh -] -> . AP* N[mass +]
|. . . . > .| NP[pro -, wh -] -> . Det AP* N
|. . . . > .| NP[pro -, wh -] -> . Name
|. . . . # .| AP* ->
|. . . . > .| AP* -> . AP* AP
|. . . . [--]| NP[pro -, wh -] -> Name
|. . . . > .| NP[pro -, wh -] -> AP* . N[mass +]
|. . . . > .| AP* -> AP* . AP
|. . [--------]| VBAR[fin +] -> V3[tense -] NP[wh -] NP[wh -]
|. . . . > .| AP -> . A
|. [-----------]| VP -> Do_Modal VBAR[fin +]
|[==============]| S -> NP[wh -] VP
|[==============]| Start -> S

Found 1 parses with 84 edges
>> Evaluating: Start -> S
Text: John did give Mary Fido
Expression: (lambda s: processSentence(s))

>> Evaluating: S -> NP[pro -, wh -] VP
Text: John did give Mary Fido
Expression: (lambda np, vp: vp(np))

>> Evaluating: NP[pro -, wh -] -> Name
Text: John
Expression: (lambda x: x)

>> Evaluating: Name -> 'John'
Text: John
Expression: (lambda name: C('Object', name=name))

<< Evaluated: Name -> 'John'
Text: John
Value: Object[name John]

<< Evaluated: NP[pro -, wh -] -> Name
Text: John
Value: Object[name John]

>> Evaluating: VP -> Do_Modal VBAR[fin +]
Text: did give Mary Fido
Expression: (lambda dm, vbar: (lambda subj: dm(vbar(subj))))

>> Evaluating: Do_Modal -> Do[tense +]
Text: did
Expression: (lambda x: x)

>> Evaluating: Do[tense +] -> 'did'
Text: did
Expression: (lambda word: (lambda verb_frame: verb_frame.addFeature('tense', 'past')))

<< Evaluated: Do[tense +] -> 'did'
Text: did
Value: (lambda verb_frame: verb_frame.addFeature('tense', 'past'))

<< Evaluated: Do_Modal -> Do[tense +]
Text: did
Value: (lambda verb_frame: verb_frame.addFeature('tense', 'past'))

>> Evaluating: VBAR[fin +] -> V3[tense -] NP[pro -, wh -] NP[pro -, wh -]
Text: give Mary Fido
Expression: (lambda v3, np1, np2: (lambda subj: v3(subj, np1, np2)))

>> Evaluating: V3[tense -] -> 'give'
Text: give
Expression: (lambda word: (lambda agent, beneficiary, patient: C('Event', action='give', agent=agent, patient=patient, beneficiary=beneficiary, tense=False)))

<< Evaluated: V3[tense -] -> 'give'
Text: give
Value: (lambda agent, beneficiary, patient: C('Event', action='give', agent=agent, patient=patient, beneficiary=beneficiary, tense=False))

>> Evaluating: NP[pro -, wh -] -> Name
Text: Mary
Expression: (lambda x: x)

>> Evaluating: Name -> 'Mary'
Text: Mary
Expression: (lambda name: C('Object', name=name))

<< Evaluated: Name -> 'Mary'
Text: Mary
Value: Object[name Mary]

<< Evaluated: NP[pro -, wh -] -> Name
Text: Mary
Value: Object[name Mary]

>> Evaluating: NP[pro -, wh -] -> Name
Text: Fido
Expression: (lambda x: x)

>> Evaluating: Name -> 'Fido'
Text: Fido
Expression: (lambda name: C('Object', name=name))

<< Evaluated: Name -> 'Fido'
Text: Fido
Value: Object[name Fido]

<< Evaluated: NP[pro -, wh -] -> Name
Text: Fido
Value: Object[name Fido]

<< Evaluated: VBAR[fin +] -> V3[tense -] NP[pro -, wh -] NP[pro -, wh -]
Text: give Mary Fido
Value: (lambda subj: (lambda agent, beneficiary, patient: C('Event', action='give', agent=agent, patient=patient, beneficiary=beneficiary, tense=False))@(subj, Object[name Mary], Object[name Fido]))

<< Evaluated: VP -> Do_Modal VBAR[fin +]
Text: did give Mary Fido
Value: (lambda subj: (lambda verb_frame: verb_frame.addFeature('tense', 'past'))@((lambda subj: (lambda agent, beneficiary, patient: C('Event', action='give', agent=agent, patient=patient, beneficiary=beneficiary, tense=False))@(subj, Object[name Mary], Object[name Fido]))@(subj)))

<< Evaluated: S -> NP[pro -, wh -] VP
Text: John did give Mary Fido
Value: Event[action give, agent Object[name John], beneficiary Object[name Mary], patient Object[name Fido], tense past]

<< Evaluated: Start -> S
Text: John did give Mary Fido
Value: 'Okay.'

Okay.
-----

> Did John give Mary Fido
Processing the edge queue...
|[--] . . . .| Do[tense +] -> 'Did'
|. [--] . . .| Name -> 'John'
|. . [--] . .| V3[tense -] -> 'give'
|. . . [--] .| Name -> 'Mary'
|. . . . [--]| Name -> 'Fido'
|> . . . . .| Start -> . S
|> . . . . .| Start -> . Q[wh +]
|> . . . . .| Start -> . Q[wh -]
|> . . . . .| S -> . NP[wh -] VP
|> . . . . .| Q[wh +] -> . NP[wh +] Q/NP
|> . . . . .| Q[wh +] -> . NP[wh +] VP
|> . . . . .| Q[wh +] -> . AdvP[wh +] Q[wh -]
|> . . . . .| Q[wh -] -> . Do_Modal NP[wh -] VBAR[fin +]
|> . . . . .| NP[pro -, wh -] -> . AP* N[mass +]
|> . . . . .| NP[pro -, wh -] -> . Det AP* N
|> . . . . .| NP[pro -, wh -] -> . Name
|> . . . . .| AdvP[wh +] -> . Adv[wh +]
|> . . . . .| Do_Modal -> . Modal
|> . . . . .| Do_Modal -> . Do[tense +]
|# . . . . .| AP* ->
|> . . . . .| AP* -> . AP* AP
|[--] . . . .| Do_Modal -> Do[tense +]
|> . . . . .| NP[pro -, wh -] -> AP* . N[mass +]
|> . . . . .| AP* -> AP* . AP
|[--> . . . .| Q[wh -] -> Do_Modal . NP[wh -] VBAR[fin +]
|> . . . . .| AP -> . A
|. > . . . .| NP[pro -, wh -] -> . AP* N[mass +]
|. > . . . .| NP[pro -, wh -] -> . Det AP* N
|. > . . . .| NP[pro -, wh -] -> . Name
|. # . . . .| AP* ->
|. > . . . .| AP* -> . AP* AP
|. [--] . . .| NP[pro -, wh -] -> Name
|. > . . . .| NP[pro -, wh -] -> AP* . N[mass +]
|. > . . . .| AP* -> AP* . AP
|[-----> . . .| Q[wh -] -> Do_Modal NP[wh -] . VBAR[fin +]
|. > . . . .| AP -> . A
|. . > . . .| VBAR[fin +] -> . V3[tense -] NP[wh -] NP[wh -]
|. . > . . .| VBAR[fin +] -> . V3[tense -] NP[wh -] PP.dat
|. . > . . .| VBAR[fin +] -> . V2[tense -] NP[wh -]
|. . > . . .| VBAR[fin +] -> . V1[tense -]
|. . [--> . .| VBAR[fin +] -> V3[tense -] . NP[wh -] NP[wh -]
|. . [--> . .| VBAR[fin +] -> V3[tense -] . NP[wh -] PP.dat
|. . . > . .| NP[pro -, wh -] -> . AP* N[mass +]
|. . . > . .| NP[pro -, wh -] -> . Det AP* N
|. . . > . .| NP[pro -, wh -] -> . Name
|. . . # . .| AP* ->
|. . . > . .| AP* -> . AP* AP
|. . . [--] .| NP[pro -, wh -] -> Name
|. . . > . .| NP[pro -, wh -] -> AP* . N[mass +]
|. . . > . .| AP* -> AP* . AP
|. . [-----> .| VBAR[fin +] -> V3[tense -] NP[wh -] . PP.dat
|. . [-----> .| VBAR[fin +] -> V3[tense -] NP[wh -] . NP[wh -]
|. . . > . .| AP -> . A
|. . . . > .| PP.dat -> . P.dat NP
|. . . . > .| NP[pro -, wh -] -> . AP* N[mass +]
|. . . . > .| NP[pro -, wh -] -> . Det AP* N
|. . . . > .| NP[pro -, wh -] -> . Name
|. . . . # .| AP* ->
|. . . . > .| AP* -> . AP* AP
|. . . . [--]| NP[pro -, wh -] -> Name
|. . . . > .| NP[pro -, wh -] -> AP* . N[mass +]
|. . . . > .| AP* -> AP* . AP
|. . [--------]| VBAR[fin +] -> V3[tense -] NP[wh -] NP[wh -]
|. . . . > .| AP -> . A
|[==============]| Q[wh -] -> Do_Modal NP[wh -] VBAR[fin +]
|[==============]| Start -> Q[wh -]

Found 1 parses with 71 edges
>> Evaluating: Start -> Q[wh -]
Text: Did John give Mary Fido
Expression: (lambda q: ynQuestion(q))

>> Evaluating: Q[wh -] -> Do_Modal NP[pro -, wh -] VBAR[fin +]
Text: Did John give Mary Fido
Expression: (lambda dm, np, vbar: dm(vbar(np)))

>> Evaluating: Do_Modal -> Do[tense +]
Text: Did
Expression: (lambda x: x)

>> Evaluating: Do[tense +] -> 'Did'
Text: Did
Expression: (lambda word: (lambda verb_frame: verb_frame.addFeature('tense', 'past')))

<< Evaluated: Do[tense +] -> 'Did'
Text: Did
Value: (lambda verb_frame: verb_frame.addFeature('tense', 'past'))

<< Evaluated: Do_Modal -> Do[tense +]
Text: Did
Value: (lambda verb_frame: verb_frame.addFeature('tense', 'past'))

>> Evaluating: NP[pro -, wh -] -> Name
Text: John
Expression: (lambda x: x)

>> Evaluating: Name -> 'John'
Text: John
Expression: (lambda name: C('Object', name=name))

<< Evaluated: Name -> 'John'
Text: John
Value: Object[name John]

<< Evaluated: NP[pro -, wh -] -> Name
Text: John
Value: Object[name John]

>> Evaluating: VBAR[fin +] -> V3[tense -] NP[pro -, wh -] NP[pro -, wh -]
Text: give Mary Fido
Expression: (lambda v3, np1, np2: (lambda subj: v3(subj, np1, np2)))

>> Evaluating: V3[tense -] -> 'give'
Text: give
Expression: (lambda word: (lambda agent, beneficiary, patient: C('Event', action='give', agent=agent, patient=patient, beneficiary=beneficiary, tense=False)))

<< Evaluated: V3[tense -] -> 'give'
Text: give
Value: (lambda agent, beneficiary, patient: C('Event', action='give', agent=agent, patient=patient, beneficiary=beneficiary, tense=False))

>> Evaluating: NP[pro -, wh -] -> Name
Text: Mary
Expression: (lambda x: x)

>> Evaluating: Name -> 'Mary'
Text: Mary
Expression: (lambda name: C('Object', name=name))

<< Evaluated: Name -> 'Mary'
Text: Mary
Value: Object[name Mary]

<< Evaluated: NP[pro -, wh -] -> Name
Text: Mary
Value: Object[name Mary]

>> Evaluating: NP[pro -, wh -] -> Name
Text: Fido
Expression: (lambda x: x)

>> Evaluating: Name -> 'Fido'
Text: Fido
Expression: (lambda name: C('Object', name=name))

<< Evaluated: Name -> 'Fido'
Text: Fido
Value: Object[name Fido]

<< Evaluated: NP[pro -, wh -] -> Name
Text: Fido
Value: Object[name Fido]

<< Evaluated: VBAR[fin +] -> V3[tense -] NP[pro -, wh -] NP[pro -, wh -]
Text: give Mary Fido
Value: (lambda subj: (lambda agent, beneficiary, patient: C('Event', action='give', agent=agent, patient=patient, beneficiary=beneficiary, tense=False))@(subj, Object[name Mary], Object[name Fido]))

<< Evaluated: Q[wh -] -> Do_Modal NP[pro -, wh -] VBAR[fin +]
Text: Did John give Mary Fido
Value: Event[action give, agent Object[name John], beneficiary Object[name Mary], patient Object[name Fido], tense past]

<< Evaluated: Start -> Q[wh -]
Text: Did John give Mary Fido
Value: 'Yes.'

Yes.

--------

> What did John give Mary
Processing the edge queue...
|[--] . . . .| NP[pro +, wh +] -> 'What'
|. [--] . . .| Do[tense +] -> 'did'
|. . [--] . .| Name -> 'John'
|. . . [--] .| V3[tense -] -> 'give'
|. . . . [--]| Name -> 'Mary'
|> . . . . .| Start -> . S
|> . . . . .| Start -> . Q[wh +]
|> . . . . .| Start -> . Q[wh -]
|> . . . . .| S -> . NP[wh -] VP
|> . . . . .| Q[wh +] -> . NP[wh +] Q/NP
|> . . . . .| Q[wh +] -> . NP[wh +] VP
|> . . . . .| Q[wh +] -> . AdvP[wh +] Q[wh -]
|> . . . . .| Q[wh -] -> . Do_Modal NP[wh -] VBAR[fin +]
|> . . . . .| NP[pro -, wh -] -> . AP* N[mass +]
|> . . . . .| NP[pro -, wh -] -> . Det AP* N
|> . . . . .| NP[pro -, wh -] -> . Name
|[--> . . . .| Q[wh +] -> NP[wh +] . Q/NP
|[--> . . . .| Q[wh +] -> NP[wh +] . VP
|> . . . . .| AdvP[wh +] -> . Adv[wh +]
|> . . . . .| Do_Modal -> . Modal
|> . . . . .| Do_Modal -> . Do[tense +]
|# . . . . .| AP* ->
|> . . . . .| AP* -> . AP* AP
|. > . . . .| Q/NP -> . Do_Modal NP VBAR[fin +]/NP
|. > . . . .| VP -> . Do_Modal VBAR[fin +]
|. > . . . .| VP -> . V+args
|> . . . . .| NP[pro -, wh -] -> AP* . N[mass +]
|> . . . . .| AP* -> AP* . AP
|. > . . . .| Do_Modal -> . Modal
|. > . . . .| Do_Modal -> . Do[tense +]
|. > . . . .| V+args -> . V12[tense +] SBAR.for
|. > . . . .| V+args -> . V11[tense +] Q_emb
|. > . . . .| V+args -> . V10[tense +] AP.pred
|. > . . . .| V+args -> . V9[tense +] SBAR.that[fact +]
|. > . . . .| V+args -> . V8[tense +] SBAR.that[fact -]
|. > . . . .| V+args -> . V6[tense +] NP[wh -] VBAR[fin -]
|. > . . . .| V+args -> . V5[tense +] VBAR[fin -]
|. > . . . .| V+args -> . V4[tense +] NP[wh -] PP[loc +]
|. > . . . .| V+args -> . V3[tense +] NP[wh -] NP[wh -]
|. > . . . .| V+args -> . V3[tense +] NP[wh -] PP.dat
|. > . . . .| V+args -> . V2[tense +] NP[wh -] PP
|. > . . . .| V+args -> . V2[tense +] NP
|. > . . . .| V+args -> . V1[tense +] PP
|. > . . . .| V+args -> . V1[tense +]
|. > . . . .| V+args -> . Be[tense +] V.part[form V2] PP.by
|. > . . . .| V+args -> . Be[tense +] V.part[form V2]
|> . . . . .| AP -> . A
|. [--] . . .| Do_Modal -> Do[tense +]
|. [--> . . .| VP -> Do_Modal . VBAR[fin +]
|. [--> . . .| Q/NP -> Do_Modal . NP VBAR[fin +]/NP
|. . > . . .| VBAR[fin +] -> . V3[tense -] NP[wh -] NP[wh -]
|. . > . . .| VBAR[fin +] -> . V3[tense -] NP[wh -] PP.dat
|. . > . . .| VBAR[fin +] -> . V2[tense -] NP[wh -]
|. . > . . .| VBAR[fin +] -> . V1[tense -]
|. . > . . .| NP[pro -, wh -] -> . AP* N[mass +]
|. . > . . .| NP[pro -, wh -] -> . Det AP* N
|. . > . . .| NP[pro -, wh -] -> . Name
|. . # . . .| AP* ->
|. . > . . .| AP* -> . AP* AP
|. . [--] . .| NP[pro -, wh -] -> Name
|. . > . . .| NP[pro -, wh -] -> AP* . N[mass +]
|. . > . . .| AP* -> AP* . AP
|. [-----> . .| Q/NP -> Do_Modal NP . VBAR[fin +]/NP
|. . > . . .| AP -> . A
|. . . > . .| VBAR[fin +]/NP -> . V3[tense -] NP/NP NP
|. . . > . .| VBAR[fin +]/NP -> . V3[tense -] NP/NP PP.dat
|. . . > . .| VBAR[fin +]/NP -> . V3[tense -] NP PP.dat/NP
|. . . > . .| VBAR[fin +]/NP -> . V2[tense -] NP/NP
|. . . [--> .| VBAR[fin +]/NP -> V3[tense -] . NP/NP NP
|. . . [--> .| VBAR[fin +]/NP -> V3[tense -] . NP/NP PP.dat
|. . . [--> .| VBAR[fin +]/NP -> V3[tense -] . NP PP.dat/NP
|. . . . # .| NP/NP ->
|. . . . > .| NP[pro -, wh -] -> . AP* N[mass +]
|. . . . > .| NP[pro -, wh -] -> . Det AP* N
|. . . . > .| NP[pro -, wh -] -> . Name
|. . . [--> .| VBAR[fin +]/NP -> V3[tense -] NP/NP . PP.dat
|. . . [--> .| VBAR[fin +]/NP -> V3[tense -] NP/NP . NP
|. . . . # .| AP* ->
|. . . . > .| AP* -> . AP* AP
|. . . . [--]| NP[pro -, wh -] -> Name
|. . . . > .| PP.dat -> . P.dat NP
|. . . . > .| NP[pro -, wh -] -> AP* . N[mass +]
|. . . . > .| AP* -> AP* . AP
|. . . [-----]| VBAR[fin +]/NP -> V3[tense -] NP/NP NP
|. . . [----->| VBAR[fin +]/NP -> V3[tense -] NP . PP.dat/NP
|. . . . > .| AP -> . A
|. [-----------]| Q/NP -> Do_Modal NP VBAR[fin +]/NP
|. . . . . >| PP.dat/NP -> . P.dat NP/NP
|[==============]| Q[wh +] -> NP[wh +] Q/NP
|[==============]| Start -> Q[wh +]

Found 1 parses with 95 edges
>> Evaluating: Start -> Q[wh +]
Text: What did John give - Mary
Expression: (lambda q: whQuestion(q))

>> Evaluating: Q[wh +] -> NP[pro +, wh +] Q/NP
Text: What did John give - Mary
Expression: (lambda np, q: q(np))

>> Evaluating: NP[pro +, wh +] -> 'What'
Text: What
Expression: (lambda word: VariableValue(word))

<< Evaluated: NP[pro +, wh +] -> 'What'
Text: What
Value: ?What

>> Evaluating: Q/NP -> Do_Modal NP[pro -, wh -] VBAR[fin +]/NP
Text: did John give - Mary
Expression: (lambda dm, np, vbar: (lambda object: dm(vbar(np, object))))

>> Evaluating: Do_Modal -> Do[tense +]
Text: did
Expression: (lambda x: x)

>> Evaluating: Do[tense +] -> 'did'
Text: did
Expression: (lambda word: (lambda verb_frame: verb_frame.addFeature('tense', 'past')))

<< Evaluated: Do[tense +] -> 'did'
Text: did
Value: (lambda verb_frame: verb_frame.addFeature('tense', 'past'))

<< Evaluated: Do_Modal -> Do[tense +]
Text: did
Value: (lambda verb_frame: verb_frame.addFeature('tense', 'past'))

>> Evaluating: NP[pro -, wh -] -> Name
Text: John
Expression: (lambda x: x)

>> Evaluating: Name -> 'John'
Text: John
Expression: (lambda name: C('Object', name=name))

<< Evaluated: Name -> 'John'
Text: John
Value: Object[name John]

<< Evaluated: NP[pro -, wh -] -> Name
Text: John
Value: Object[name John]

>> Evaluating: VBAR[fin +]/NP -> V3[tense -] NP/NP NP[pro -, wh -]
Text: give - Mary
Expression: (lambda v3, np1, np2: (lambda subj, patient: v3(subj, np2, patient)))

>> Evaluating: V3[tense -] -> 'give'
Text: give
Expression: (lambda word: (lambda agent, beneficiary, patient: C('Event', action='give', agent=agent, patient=patient, beneficiary=beneficiary, tense=False)))

<< Evaluated: V3[tense -] -> 'give'
Text: give
Value: (lambda agent, beneficiary, patient: C('Event', action='give', agent=agent, patient=patient, beneficiary=beneficiary, tense=False))

>> Evaluating: NP/NP -> -
Text: -
Expression: (lambda : None)

<< Evaluated: NP/NP -> -
Text: -
Value: None

>> Evaluating: NP[pro -, wh -] -> Name
Text: Mary
Expression: (lambda x: x)

>> Evaluating: Name -> 'Mary'
Text: Mary
Expression: (lambda name: C('Object', name=name))

<< Evaluated: Name -> 'Mary'
Text: Mary
Value: Object[name Mary]

<< Evaluated: NP[pro -, wh -] -> Name
Text: Mary
Value: Object[name Mary]

<< Evaluated: VBAR[fin +]/NP -> V3[tense -] NP/NP NP[pro -, wh -]
Text: give - Mary
Value: (lambda subj, patient: (lambda agent, beneficiary, patient: C('Event', action='give', agent=agent, patient=patient, beneficiary=beneficiary, tense=False))@(subj, Object[name Mary], patient))

<< Evaluated: Q/NP -> Do_Modal NP[pro -, wh -] VBAR[fin +]/NP
Text: did John give - Mary
Value: (lambda object: (lambda verb_frame: verb_frame.addFeature('tense', 'past'))@((lambda subj, patient: (lambda agent, beneficiary, patient: C('Event', action='give', agent=agent, patient=patient, beneficiary=beneficiary, tense=False))@(subj, Object[name Mary], patient))@(Object[name John], object)))

<< Evaluated: Q[wh +] -> NP[pro +, wh +] Q/NP
Text: What did John give - Mary
Value: Event[action give, agent Object[name John], beneficiary Object[name Mary], patient ?What, tense past]

<< Evaluated: Start -> Q[wh +]
Text: What did John give - Mary
Value: Fido

Fido

Lab 3

3.1
These two rules let the system handle Wh-questions

This rule lets the system handle questions with "hidden" beneficiary e.g. "Who did John give Fido to (Mary)"

sem.add("VBAR[fin +]/NP -> V3[tense -] NP PP.dat/NP",
lambda v3, np, pp: lambda subj, beneficiary: v3(subj, beneficiary, np))

This rule lets the system handle questions with "hidden" object e.g. "What did John give (Fido) to Mary?"

sem.add("VBAR[fin +]/NP -> V3[tense -] NP/NP PP.dat",
lambda v3, np, pp: lambda subj, patient: v3(subj, pp, patient))


3.2
I added this rule, which let verbs such as give take two NP arguments.
In lambda calculus form they were given different variable names to avoid confusion (np1, np2)

sem.add("V+args -> V3[tense +] NP[wh -] NP[wh -]",
lambda v3, np1, np2: lambda subj: v3(subj, np1, np2))

3.3
I added the rule below which let a "tense-less" VP take two NP arguments
I did the same renaming of variable names as was done for question 2
sem.add("VBAR[fin +] -> V3[tense -] NP[wh -] NP[wh -]",
lambda v3, np1, np2: lambda subj: v3(subj, np1, np2))

Sentences such as "Did John give Mary Fido " works without any additional rules because
sem.add("Q[wh -] -> Do_Modal NP[wh -] VBAR[fin +]",
lambda dm, np, vbar: dm(vbar(np)))
uses the same VBAR rule to construct "tense-less" VPs. The ordering of constituents of VBAR is the same in y/n questions as it is in declarative sentences

3.4
I added this rule

sem.add("VBAR[fin +]/NP -> V3[tense -] NP/NP NP",
lambda v3, np1, np2: lambda subj, patient: v3(subj, np2, patient))

Why don't we need to add two rules again? Because we do not need to cover the "Who did John give Fido" in the same vein (Fido can be the beneficiary according to the above rule) as "Who did John give Fido to?


in fact this seems to be an ambiguous case, we can either understand "Who did John give Fido to" or "Who did John give to Fido"

Extensibility
Each time we add a declarative sentence we need to add other rules to handle y-n questions
For each gap we might have in a sentence we need additional rules so it is hard to say the system is very easy to extend