"""
Temporal extension of presuppdrt
"""
__author__ = "Peter Makarov, Alex Kislev, Emma Li"
__version__ = "1.0"
__date__ = "Tue, 24 Aug 2010"
#import presuppdrt as drt
from . import presuppdrt as drt
from nltk.sem.logic import Variable
from .presuppdrt import DrsDrawer
from .presuppdrt import AnaphoraResolutionException
from .presuppdrt import DrtApplicationExpression
from .presuppdrt import DrtTimeVariableExpression
from .presuppdrt import DRS
from .presuppdrt import DrtExpression
from .presuppdrt import DrtVariableExpression
from .presuppdrt import DrtStateVariableExpression
from .presuppdrt import Binding
from .presuppdrt import DrtEventVariableExpression
from .presuppdrt import VariableReplacer
from .presuppdrt import ConditionReplacer
from .presuppdrt import ConditionRemover
from .presuppdrt import DrtEqualityExpression
from .presuppdrt import DrtConstantExpression
from .presuppdrt import unique_variable
from .presuppdrt import DrtNegatedExpression
from .presuppdrt import is_statevar
from .presuppdrt import is_eventvar
from .presuppdrt import is_timevar
from .presuppdrt import is_uttervar
from .presuppdrt import DrtAbstractVariableExpression
from .presuppdrt import DrtUtterVariableExpression
from .presuppdrt import DrtIndividualVariableExpression
from .presuppdrt import DefiniteDescriptionDRS
from .presuppdrt import DrtEventualityApplicationExpression
from .presuppdrt import DrtLambdaExpression
from .presuppdrt import DrtBooleanExpression
from .presuppdrt import DrtConcatenation
from .presuppdrt import DrtImpExpression
from .presuppdrt import DrtOrExpression
from .presuppdrt import DrtFeatureConstantExpression
[docs]class DrtTokens(drt.DrtTokens):
NEWINFO_DRS = 'NEWINFO'
LOCATION_TIME = 'LOCPRO'
UTTER_TIME = 'UTTER'
REFER_TIME = 'REFER'
PERF = 'PERF'
UTTER = "UTTER"
REFER = "REFER"
OVERLAP = "overlap"
EARLIER = "earlier"
INCLUDE = "include"
ABUT = "abut"
END = "end"
TEMP_CONDS = [OVERLAP, EARLIER, INCLUDE]
PAST = "PAST"
PRES = "PRES"
FUT = "FUT"
TENSE = [PAST, PRES, FUT]
# ???
OLD_NLTK = 0
NLTK = 1
PROVER9 = 2
[docs]class DrtTimeApplicationExpression(DrtApplicationExpression):
pass
[docs]class LocationTimeResolutionException(Exception):
pass
[docs]class DrtLocationTimeApplicationExpression(DrtTimeApplicationExpression):
"""LOCPRO(t) condition from a non-finite verb. Gets resolved
to the closest location time referent introduced by a finite auxiliary. """
def readings(self, trail=[]):
utter_time_search = False
for drs in (ancestor for ancestor in reversed(trail) if isinstance(ancestor, DRS)):
search_list = drs.refs
if self.argument.variable in drs.refs:
search_list = drs.refs[:drs.refs.index(self.argument.variable)]
for ref in reversed(search_list):
refex = DrtVariableExpression(ref)
if isinstance(refex, DrtUtterVariableExpression):
#In case there is no location time referent that has not yet been used
#to relate some eventuality to utterance time, use utterance time as location time
return [Binding([(trail[-1], VariableReplacer(self.argument.variable, refex))])], True
elif not utter_time_search and isinstance(refex, DrtTimeVariableExpression) and \
not (refex == self.argument):
if any(isinstance(c, DrtApplicationExpression) and isinstance(c.function, DrtApplicationExpression) and \
c.function.argument == refex and (c.function.function.variable.name == DrtTokens.OVERLAP or \
c.function.function.variable.name == DrtTokens.INCLUDE) for c in drs.conds):
utter_time_search = True
else:
#Returns first suitable antecedent expression
return [Binding([(trail[-1], VariableReplacer(self.argument.variable, refex))])], True
raise LocationTimeResolutionException("Variable '%s' does not "
"resolve to anything." % self.argument)
[docs]class DrtFindUtterTimeExpression(DrtApplicationExpression):
"""Type of application expression looking to equate its argument with utterance time"""
def readings(self, trail=[]):
for ancestor in trail:
for ref in ancestor.get_refs():
refex = DrtVariableExpression(ref)
if isinstance(refex, DrtUtterVariableExpression):
return [Binding([(trail[-1], VariableReplacer(self.argument.variable, refex))])], True
raise UtteranceTimeTimeResolutionException("Variable '%s' does not "
"resolve to anything." % self.argument)
[docs]class UtteranceTimeTimeResolutionException(Exception):
pass
[docs]class DrtFindEventualityExpression(DrtApplicationExpression):
"""Comprises reference point REFER condition and aspectual PERF condition.
DRS-condition REFER(e) or REFER(s) returns a temporal condition that
relates given eventuality and some previous event or state. In the simplified
version of the reference point selection algorithm, the condition picks out the
most recent event and, depending on the type of its argument, returns either an
earlier(e*,e) or include(s,e*), where e* is the reference point and e/s is the given
eventuality. In case there is no event in the previous discourse, the most recent
state is taken as the reference point and overlap(s*,s) or include(s*,e) is introduced
depending on the type of the given eventuality.
PERF(e) locates the most recent state referent s and resolves to a condition abut(e,s).
PERF(s) locates the most recent state referent s* and resolves to a condition abut(e*,s*),
e* = end(s) and adds a new event referent e*. Note that end(.) is an operator on states
that returns events."""
def readings(self, trail=[]):
state_reference_point = None
index = trail[-1].conds.index(self)
#state reference point in case there are no previous events
for drs in (ancestor for ancestor in reversed(trail) if isinstance(ancestor, DRS)):
search_list = drs.refs
if drs is trail[-1]:
#Described eventuality in the object's referents?
#Take r
# efs' list up to described eventuality
search_list = drs.refs[:drs.refs.index(self.argument.variable)]
for ref in reversed(search_list):
#search for the most recent reference
refex = DrtVariableExpression(ref)
if isinstance(refex, DrtEventVariableExpression) and \
not (refex == self.argument) and not self.function.variable.name == DrtTokens.PERF:
if isinstance(self.argument, DrtEventVariableExpression):
#In case given eventuality is an event, return earlier
return [Binding([(trail[-1], ConditionReplacer(index,
[self._combine(DrtTokens.EARLIER, refex, self.argument)]))])], False
elif isinstance(self.argument, DrtStateVariableExpression):
#In case given eventuality is a state, return include
return [Binding([(trail[-1], ConditionReplacer(index,
[self._combine(DrtTokens.INCLUDE, self.argument, refex)]))])], False
elif not state_reference_point and \
isinstance(refex, DrtStateVariableExpression) and \
not (refex == self.argument):
#In case no event is found, locate the most recent state
state_reference_point = refex
if state_reference_point:
if self.function.variable.name == DrtTokens.PERF:
#in case we are dealing with PERF
if isinstance(self.argument, DrtEventVariableExpression):
#Reference point is a state and described eventuality an event,
#return event abuts on state
return [Binding([(trail[-1], ConditionReplacer(index,
[self._combine(DrtTokens.ABUT, self.argument, state_reference_point)]))])], False
elif isinstance(self.argument, DrtStateVariableExpression):
#Reference point is a state and described eventuality a state,
#then add an event referent to the ancestor's refs list and two conditions
#that that event is the end of eventuality and
#that event abuts on ref.state. Function object needed.
termination_point = unique_variable(Variable("e"))
conds = [DrtEqualityExpression(DrtEventVariableExpression(termination_point), DrtApplicationExpression(self.make_ConstantExpression(DrtTokens.END), self.argument)),
self._combine(DrtTokens.ABUT, DrtEventVariableExpression(termination_point), state_reference_point)]
return [Binding([(trail[-1], DrtFindEventualityExpression.ConditionReplacer(index, conds, termination_point))])], False
elif isinstance(self.argument, DrtStateVariableExpression):
#Reference point is a state and given eventuality is also a state,
#return overlap
return [Binding([(trail[-1], ConditionReplacer(index,
[self._combine(DrtTokens.OVERLAP, state_reference_point, self.argument)]))])], False
elif isinstance(self.argument, DrtEventVariableExpression):
#Reference point is a state and given eventuality is an event,
#return include
return [Binding([(trail[-1], ConditionReplacer(index,
[self._combine(DrtTokens.INCLUDE, state_reference_point, self.argument)]))])], False
else:
#no suitable reference found
return [Binding([(trail[-1], ConditionRemover(index))])], False
def make_ConstantExpression(self, name):
return DrtConstantExpression(Variable(name))
def _combine(self, cond, arg1, arg2):
"""Combines two arguments into a DrtEventualityApplicationExpression
that has another DrtEventualityApplicationExpression as its functor"""
return DrtEventualityApplicationExpression(DrtEventualityApplicationExpression(self.make_ConstantExpression(cond), arg1), arg2)
[docs]class NewInfoDRS(DRS):
pass
[docs]class PresuppositionDRS(drt.PresuppositionDRS):
def collect_event_data(self, cond, event_data_map, event_strings_map, individuals=None):
if isinstance(cond.function, DrtApplicationExpression) and \
not isinstance(cond.function, DrtTimeApplicationExpression) and \
isinstance(cond.argument, DrtIndividualVariableExpression) and \
not isinstance(cond.argument, DrtTimeVariableExpression):
event_data_map.setdefault(cond.argument.variable, []).append((cond.function.argument, cond.function.function.variable.name))
elif cond.__class__ == DrtEventualityApplicationExpression and \
(isinstance(cond.argument, DrtEventVariableExpression) or \
isinstance(cond.argument, DrtStateVariableExpression)) and \
not isinstance(cond.function, DrtApplicationExpression):
assert cond.argument not in event_strings_map
event_strings_map[cond.argument] = cond.function.variable.name
# The rest are nouns and attributive adjectives
elif individuals is not None and cond.__class__ == DrtApplicationExpression and \
not isinstance(cond.function, DrtApplicationExpression):
individuals.setdefault(cond.argument.variable, []).append(cond)
[docs]class DefiniteDescriptionDRS(drt.DefiniteDescriptionDRS):
def _get_free(self):
free = self.free(True)
temporal_conditions = []
# If there are free variables that stem from conditions like 'overlap', earlier', 'include',
# those conditions will be moved to the local DRS
for cond in self.conds:
if isinstance(cond, DrtTimeApplicationExpression) and isinstance(cond.function, DrtTimeApplicationExpression):
assert cond.function.function.variable.name in DrtTokens.TEMP_CONDS
for expression in [cond.argument, cond.function.argument]:
expression_variable = expression.variable
if expression_variable in free and isinstance(expression, DrtUtterVariableExpression):
free.remove(expression_variable)
if isinstance(cond, DrtEventualityApplicationExpression) and \
isinstance(cond.function, DrtEventualityApplicationExpression):
assert cond.function.function.variable.name in DrtTokens.TEMP_CONDS
for expression_variable in [cond.argument.variable, cond.function.argument.variable]:
if expression_variable in free:
free.remove(expression_variable)
temporal_conditions.append(cond)
self.conds.remove(cond)
return free, temporal_conditions
[docs]class DrtParser(drt.DrtParser):
"""DrtParser producing conditions and referents for temporal logic"""
[docs] def handle_PresuppositionDRS(self, tok, context):
"""Parse all the Presuppositon DRSs"""
if tok == DrtTokens.DEFINITE_DESCRIPTION_DRS:
self.assertNextToken(DrtTokens.OPEN)
drs = self.handle_DRS(tok, context)
return DefiniteDescriptionDRS(drs.refs, drs.conds)
else:
return drt.DrtParser.handle_PresuppositionDRS(self, tok, context)
def handle_DRS(self, tok, context):
drs = drt.DrtParser.handle_DRS(self, tok, context)
location_time = None
for cond in drs.conds:
if isinstance(cond, DrtFindEventualityExpression):
#PERF(.) gives rise to a DrtFindEventualityExpression;
#in case it is among the DRS-conditions, the eventuality carried by
#this DRS does not give rise to a REFER(.) condition
return DRS(drs.refs, drs.conds)
if not location_time and isinstance(cond, DrtLocationTimeApplicationExpression):
location_time = cond.argument
for ref in drs.refs:
#Change DRS: introduce REFER(s/e) condition, add INCLUDE/OVERLAP
#conditions to verbs (triggered by LOCPRO) and given some trigger
#from DrtTokens.TENSE put UTTER(.) condition and,for PAST and FUT,
#earlier(.,.) condition w.r.t. to some new discourse
#referent bound to utterance time.
if is_statevar(ref.name):
#Adds REFER(s) condition.
if location_time:
#Relates location time and eventuality
drs.conds.append(DrtTimeApplicationExpression(DrtTimeApplicationExpression(self.make_ConstantExpression(DrtTokens.OVERLAP), location_time), DrtStateVariableExpression(ref)))
drs.conds.append(DrtFindEventualityExpression(self.make_ConstantExpression(DrtTokens.REFER), DrtVariableExpression(ref)))
if is_eventvar(ref.name):
#Adds REFER(e) condition.
if location_time:
#Relates location time and eventuality
drs.conds.append(DrtTimeApplicationExpression(DrtTimeApplicationExpression(self.make_ConstantExpression(DrtTokens.INCLUDE), location_time), DrtStateVariableExpression(ref)))
drs.conds.append(DrtFindEventualityExpression(self.make_ConstantExpression(DrtTokens.REFER), DrtVariableExpression(ref)))
if is_timevar(ref.name) and not is_uttervar(ref.name):
#Relates location time with utterance time
tense_cond = [c for c in drs.conds if isinstance(c, DrtApplicationExpression) and \
isinstance(c.function, DrtConstantExpression) and \
c.function.variable.name in DrtTokens.TENSE and DrtVariableExpression(ref) == c.argument]
if not tense_cond == []:
if tense_cond[0].function.variable.name == DrtTokens.PRES:
#Put UTTER(t) instead
#drs.conds.remove(drs.conds.index(tense_cond[0]))
drs.conds[drs.conds.index(tense_cond[0])] = DrtFindUtterTimeExpression(self.make_ConstantExpression(DrtTokens.UTTER), DrtTimeVariableExpression(ref))
else:
#Put new discourse referent and bind it to utterance time
#by UTTER(.) and also add earlier(.,.) condition
utter_time = unique_variable(ref)
drs.refs.insert(0, utter_time)
drs.conds[drs.conds.index(tense_cond[0])] = DrtFindUtterTimeExpression(self.make_ConstantExpression(DrtTokens.UTTER), DrtTimeVariableExpression(utter_time))
if tense_cond[0].function.variable.name == DrtTokens.PAST:
drs.conds.append(DrtTimeApplicationExpression(DrtTimeApplicationExpression(self.make_ConstantExpression(DrtTokens.EARLIER), DrtTimeVariableExpression(ref)), DrtTimeVariableExpression(utter_time)))
else:
drs.conds.append(DrtTimeApplicationExpression(DrtTimeApplicationExpression(self.make_ConstantExpression(DrtTokens.EARLIER), DrtTimeVariableExpression(utter_time)), DrtTimeVariableExpression(ref)))
return DRS(drs.refs, drs.conds)
def make_VariableExpression(self, name):
return DrtVariableExpression(Variable(name))
def make_ApplicationExpression(self, function, argument):
if isinstance(function, DrtAbstractVariableExpression) and \
function.variable.name == DrtTokens.LOCATION_TIME and \
isinstance(argument, DrtTimeVariableExpression):
return DrtLocationTimeApplicationExpression(function, argument)
elif isinstance(function, DrtAbstractVariableExpression) and \
function.variable.name == DrtTokens.PERF:
return DrtFindEventualityExpression(function, argument)
elif isinstance(argument, DrtStateVariableExpression) or \
isinstance(argument, DrtEventVariableExpression):
return DrtEventualityApplicationExpression(function, argument)
elif isinstance(argument, DrtTimeVariableExpression):
return DrtTimeApplicationExpression(function, argument)
else:
return DrtApplicationExpression(function, argument)