Package nltk :: Package sem :: Module drt
[hide private]
[frames] | no frames]

Source Code for Module nltk.sem.drt

  1  # Natural Language Toolkit: Discourse Representation Theory (DRT)  
  2  # 
  3  # Author: Dan Garrette <[email protected]> 
  4  # 
  5  # URL: <http://nltk.org> 
  6  # For license information, see LICENSE.TXT 
  7   
  8  from nltk.internals import Counter 
  9  from nltk.sem import logic 
 10  from nltk.sem.logic import Variable, unique_variable 
 11  import drt_resolve_anaphora as RA 
 12   
 13  from Tkinter import Canvas 
 14  from Tkinter import Tk 
 15  from tkFont import Font 
 16  from nltk.draw import in_idle 
 17   
18 -class AbstractDrs(object):
19 """ 20 This is the base abstract abstract DRT Expression from which every DRT 21 Expression extends. 22 """
23 - def __call__(self, other, *additional):
24 accum = self.applyto(other) 25 for a in additional: 26 accum = accum(a) 27 return accum
28
29 - def applyto(self, other):
30 return DrtApplicationExpression(self, other)
31
32 - def __neg__(self):
33 return DrtNegatedExpression(self)
34
35 - def negate(self):
36 return -self
37
38 - def __and__(self, other):
39 raise NotImplementedError()
40
41 - def __or__(self, other):
42 assert isinstance(other, AbstractDrs) 43 return DrtOrExpression(self, other)
44
45 - def __gt__(self, other):
46 assert isinstance(other, AbstractDrs) 47 return DrtImpExpression(self, other)
48
49 - def __lt__(self, other):
50 assert isinstance(other, AbstractDrs) 51 return DrtIffExpression(self, other)
52
53 - def tp_equals(self, other, prover_name='tableau'):
54 """Pass the expression (self <-> other) to the theorem prover. 55 If the prover says it is valid, then the self and other are equal.""" 56 assert isinstance(other, AbstractDrs) 57 58 from nltk.inference import inference 59 f1 = self.simplify().toFol(); 60 f2 = other.simplify().toFol(); 61 return f1.tp_equals(f2, prover_name)
62
63 - def __add__(self, other):
64 return ConcatenationDRS(self, other)
65
66 - def is_pronoun_function(self):
67 """ Is self of the form "PRO(x)"? """ 68 return isinstance(self, DrtApplicationExpression) and \ 69 isinstance(self.function, DrtVariableExpression) and \ 70 self.function.variable.name == Tokens.PRONOUN and \ 71 isinstance(self.argument, DrtIndividualVariableExpression)
72
73 - def get_EqualityExpression(self):
75
76 - def make_VariableExpression(self, variable):
77 if logic.is_indvar(variable.name): 78 return DrtIndividualVariableExpression(variable) 79 else: 80 return DrtVariableExpression(variable)
81
82 - def draw(self):
83 DrsDrawer(self).draw()
84
85 -class DRS(AbstractDrs, logic.Expression, RA.DRS):
86 """A Discourse Representation Structure."""
87 - def __init__(self, refs, conds):
88 """ 89 @param refs: C{list} of C{DrtVariableExpression} for the discourse referents 90 @param conds: C{list} of C{Expression} for the conditions 91 """ 92 self.refs = refs 93 self.conds = conds
94
95 - def replace(self, variable, expression, replace_bound=False):
96 """Replace all instances of variable v with expression E in self, 97 where v is free in self.""" 98 try: 99 #if a bound variable is the thing being replaced 100 i = self.refs.index(variable) 101 if not replace_bound: 102 return self 103 else: 104 return DRS(self.refs[:i]+[expression.variable]+self.refs[i+1:], 105 [cond.replace(variable, expression, True) for cond in self.conds]) 106 except ValueError: 107 #variable not bound by this DRS 108 109 # any bound variable that appears in the expression must 110 # be alpha converted to avoid a conflict 111 for ref in (set(self.refs) & expression.free()): 112 newvar = unique_variable() 113 newvarex = DrtIndividualVariableExpression(newvar) 114 i = self.refs.index(ref) 115 self = DRS(self.refs[:i]+[newvar]+self.refs[i+1:], 116 [cond.replace(ref, newvarex, True) 117 for cond in self.conds]) 118 119 #replace in the conditions 120 return DRS(self.refs, 121 [cond.replace(variable, expression, replace_bound) 122 for cond in self.conds])
123
124 - def variables(self):
125 """ 126 @see: logic.Expression.variables() 127 """ 128 conds_free = set() 129 for cond in self.conds: 130 conds_free |= cond.variables() 131 return conds_free - set(self.refs)
132
133 - def free(self, indvar_only=True):
134 """ 135 @see: logic.Expression.free() 136 """ 137 conds_free = set() 138 for cond in self.conds: 139 conds_free |= cond.free(indvar_only) 140 return conds_free - set(self.refs)
141
142 - def get_refs(self):
143 return self.refs
144
145 - def simplify(self):
146 return DRS(self.refs, [cond.simplify() for cond in self.conds])
147
148 - def toFol(self):
149 accum = self.conds[-1].toFol() 150 for cond in self.conds[::-1][1:]: 151 accum = logic.AndExpression(cond.toFol(), accum) 152 for ref in self.refs[::-1]: 153 accum = logic.ExistsExpression(ref, accum) 154 return accum
155
156 - def __eq__(self, other):
157 r"""Defines equality modulo alphabetic variance. 158 If we are comparing \x.M and \y.N, then check equality of M and N[x/y].""" 159 if self.__class__ == other.__class__: 160 if len(self.refs) == len(other.refs): 161 converted_other = other 162 for (r1, r2) in zip(self.refs, converted_other.refs): 163 varex = self.make_VariableExpression(r1) 164 converted_other = converted_other.replace(r2, varex, True) 165 return self.conds == converted_other.conds 166 return False
167
168 - def str(self, syntax=logic.Tokens.NEW_NLTK):
169 return Tokens.DRS + '([' + ','.join([str(ref) for ref in self.refs]) + \ 170 '],[' + ', '.join([cond.str(syntax) for cond in self.conds]) + '])'
171
172 -class DrtVariableExpression(AbstractDrs, logic.VariableExpression, 173 RA.VariableExpression):
174 - def toFol(self):
175 return self
176
177 - def get_refs(self):
178 return []
179
180 -class DrtIndividualVariableExpression(DrtVariableExpression, 181 logic.IndividualVariableExpression, 182 RA.VariableExpression):
183 - def toFol(self):
184 return self
185
186 - def get_refs(self):
187 return []
188
189 -class DrtNegatedExpression(AbstractDrs, logic.NegatedExpression, 190 RA.NegatedExpression):
191 - def toFol(self):
192 return logic.NegatedExpression(self.term.toFol())
193
194 -class DrtLambdaExpression(AbstractDrs, logic.LambdaExpression, 195 RA.LambdaExpression):
196 - def toFol(self):
197 return logic.LambdaExpression(self.variable, self.term.toFol())
198
199 -class DrtOrExpression(AbstractDrs, logic.ImpExpression):
200 - def toFol(self):
201 return logic.OrExpression(self.first.toFol(), self.second.toFol())
202
203 -class DrtImpExpression(AbstractDrs, logic.ImpExpression, RA.ImpExpression):
204 - def get_refs(self):
205 return []
206
207 - def toFol(self):
208 first_drs = self.first 209 second_drs = self.second 210 211 accum = first_drs.conds[-1].toFol() 212 for cond in first_drs.conds[::-1][1:]: 213 accum = logic.AndExpression(cond.toFol(), accum) 214 215 accum = logic.ImpExpression(accum, second_drs.toFol()) 216 217 for ref in first_drs.refs[::-1]: 218 accum = logic.AllExpression(ref, accum) 219 220 return accum
221
222 -class DrtIffExpression(AbstractDrs, logic.IffExpression, RA.IffExpression):
223 - def toFol(self):
224 return logic.IffExpression(self.first.toFol(), self.second.toFol())
225
226 -class DrtEqualityExpression(AbstractDrs, logic.EqualityExpression, RA.EqualityExpression):
227 - def toFol(self):
228 return logic.EqualityExpression(self.first.toFol(), self.second.toFol())
229
230 -class ConcatenationDRS(AbstractDrs, logic.BooleanExpression, RA.ConcatenationDRS):
231 """DRS of the form '(DRS + DRS)'"""
232 - def replace(self, variable, expression, replace_bound=False):
233 """Replace all instances of variable v with expression E in self, 234 where v is free in self.""" 235 first = self.first 236 second = self.second 237 238 # If variable is bound by both first and second 239 if isinstance(first, DRS) and isinstance(second, DRS) and \ 240 variable in (set(first.get_refs()) & set(second.get_refs())): 241 first = first.replace(variable, expression, True) 242 second = second.replace(variable, expression, True) 243 244 # If variable is bound by first 245 elif isinstance(first, DRS) and variable in first.refs: 246 if replace_bound: 247 first = first.replace(variable, expression, replace_bound) 248 second = second.replace(variable, expression, replace_bound) 249 250 # If variable is bound by second 251 elif isinstance(second, DRS) and variable in second.refs: 252 if replace_bound: 253 first = first.replace(variable, expression, replace_bound) 254 second = second.replace(variable, expression, replace_bound) 255 256 else: 257 # alpha convert every ref that is free in 'expression' 258 for ref in (set(self.get_refs()) & expression.free()): 259 v = DrtIndividualVariableExpression(unique_variable()) 260 first = first.replace(ref, v, True) 261 second = second.replace(ref, v, True) 262 263 first = first.replace(variable, expression, replace_bound) 264 second = second.replace(variable, expression, replace_bound) 265 266 return self.__class__(first, second)
267
268 - def get_refs(self):
269 return self.first.get_refs() + self.second.get_refs()
270
271 - def simplify(self):
272 first = self.first.simplify() 273 second = self.second.simplify() 274 275 if isinstance(first, DRS) and isinstance(second, DRS): 276 # For any ref that is in both 'first' and 'second' 277 for ref in (set(first.refs) & set(second.refs)): 278 # alpha convert the ref in 'second' to prevent collision 279 newvar = DrtIndividualVariableExpression(unique_variable()) 280 second = second.replace(ref, newvar, True) 281 282 return DRS(first.refs + second.refs, first.conds + second.conds) 283 else: 284 return self.__class__(first,second)
285
286 - def getOp(self, syntax=logic.Tokens.NEW_NLTK):
287 return Tokens.DRS_CONC
288
289 - def __eq__(self, other):
290 r"""Defines equality modulo alphabetic variance. 291 If we are comparing \x.M and \y.N, then check equality of M and N[x/y].""" 292 if self.__class__ == other.__class__: 293 self_refs = self.get_refs() 294 other_refs = other.get_refs() 295 if len(self_refs) == len(other_refs): 296 converted_other = other 297 for (r1,r2) in zip(self_refs, other_refs): 298 varex = self.make_VariableExpression(r1) 299 converted_other = converted_other.replace(r2, varex, True) 300 return self.first == converted_other.first and \ 301 self.second == converted_other.second 302 return False
303
304 - def toFol(self):
305 return logic.AndExpression(self.first.toFol(), self.second.toFol())
306
307 -class DrtApplicationExpression(AbstractDrs, logic.ApplicationExpression, RA.ApplicationExpression):
308 - def toFol(self):
309 return logic.ApplicationExpression(self.function.toFol(), 310 self.argument.toFol())
311
312 - def get_refs(self):
313 return []
314
315 -class DrsDrawer:
316 BUFFER = 3 317
318 - def __init__(self, drs, size_canvas=True, canvas=None):
319 """ 320 @param drs: C{AbstractDrs}, The DRS to be drawn 321 @param size_canvas: C{boolean}, True if the canvas size should be the exact size of the DRS 322 @param canvas: C{Canvas} The canvas on which to draw the DRS. If none is given, create a new canvas. 323 """ 324 self.syntax = logic.Tokens.NEW_NLTK 325 326 master = None 327 if not canvas: 328 master = Tk() 329 master.title("DRT") 330 331 font = Font(family='helvetica', size=12) 332 333 if size_canvas: 334 canvas = Canvas(master, width=0, height=0) 335 canvas.font = font 336 self.canvas = canvas 337 (right, bottom) = self._visit(drs, self.BUFFER, self.BUFFER) 338 canvas = Canvas(master, width=max(right, 100), height=bottom)#, bg='white') 339 else: 340 canvas = Canvas(master, width=300, height=300) 341 342 canvas.pack() 343 canvas.font = font 344 345 self.canvas = canvas 346 self.drs = drs 347 self.master = master
348
349 - def _get_text_height(self):
350 """Get the height of a line of text""" 351 return self.canvas.font.metrics("linespace")
352
353 - def draw(self, x=BUFFER, y=BUFFER):
354 """Draw the DRS""" 355 self._handle(self.drs, self._draw_command, x, y) 356 357 if self.master and not in_idle(): 358 self.master.mainloop() 359 else: 360 return self._visit(self.drs, x, y)
361
362 - def _visit(self, expression, x, y):
363 """ 364 Return the bottom-rightmost point without actually drawing the item 365 366 @param expression: the item to visit 367 @param x: the top of the current drawing area 368 @param y: the left side of the current drawing area 369 @return: the bottom-rightmost point 370 """ 371 return self._handle(expression, self._visit_command, x, y)
372
373 - def _draw_command(self, item, x, y):
374 """ 375 Draw the given item at the given location 376 377 @param item: the item to draw 378 @param x: the top of the current drawing area 379 @param y: the left side of the current drawing area 380 @return: the bottom-rightmost point 381 """ 382 if isinstance(item, str): 383 self.canvas.create_text(x, y, anchor='nw', font=self.canvas.font, text=item) 384 elif isinstance(item, tuple): 385 # item is the lower-right of a box 386 (right, bottom) = item 387 self.canvas.create_rectangle(x, y, right, bottom) 388 horiz_line_y = y + self._get_text_height() + (self.BUFFER * 2) #the line separating refs from conds 389 self.canvas.create_line(x, horiz_line_y, right, horiz_line_y) 390 391 return self._visit_command(item, x, y)
392
393 - def _visit_command(self, item, x, y):
394 """ 395 Return the bottom-rightmost point without actually drawing the item 396 397 @param item: the item to visit 398 @param x: the top of the current drawing area 399 @param y: the left side of the current drawing area 400 @return: the bottom-rightmost point 401 """ 402 if isinstance(item, str): 403 return (x + self.canvas.font.measure(item), y + self._get_text_height()) 404 elif isinstance(item, tuple): 405 return item
406
407 - def _handle(self, expression, command, x=0, y=0):
408 """ 409 @param expression: the expression to handle 410 @param command: the function to apply, either _draw_command or _visit_command 411 @param x: the top of the current drawing area 412 @param y: the left side of the current drawing area 413 @return: the bottom-rightmost point 414 """ 415 if command == self._visit_command: 416 #if we don't need to draw the item, then we can use the cached values 417 try: 418 #attempt to retrieve cached values 419 right = expression._drawing_width + x 420 bottom = expression._drawing_height + y 421 return (right, bottom) 422 except AttributeError: 423 #the values have not been cached yet, so compute them 424 pass 425 426 if isinstance(expression, DrtVariableExpression): 427 factory = self._handle_VariableExpression 428 elif isinstance(expression, DRS): 429 factory = self._handle_DRS 430 elif isinstance(expression, DrtNegatedExpression): 431 factory = self._handle_NegatedExpression 432 elif isinstance(expression, DrtLambdaExpression): 433 factory = self._handle_LambdaExpression 434 elif isinstance(expression, logic.BooleanExpression): 435 factory = self._handle_BooleanExpression 436 elif isinstance(expression, DrtApplicationExpression): 437 factory = self._handle_ApplicationExpression 438 elif isinstance(expression, RA.PossibleAntecedents): 439 factory = self._handle_VariableExpression 440 else: 441 raise Exception, expression.__class__.__name__ 442 443 (right, bottom) = factory(expression, command, x, y) 444 445 #cache the values 446 expression._drawing_width = right - x 447 expression._drawing_height = bottom - y 448 449 return (right, bottom)
450
451 - def _handle_VariableExpression(self, expression, command, x, y):
452 return command(expression.str(self.syntax), x, y)
453
454 - def _handle_NegatedExpression(self, expression, command, x, y):
455 # Find the width of the negation symbol 456 right = self._visit_command(Tokens.NOT[self.syntax], x, y)[0] 457 458 # Handle term 459 (right, bottom) = self._handle(expression.term, command, right, y) 460 461 # Handle variables now that we know the y-coordinate 462 command(Tokens.NOT[self.syntax], x, self._get_centered_top(y, bottom - y, self._get_text_height())) 463 464 return (right, bottom)
465
466 - def _handle_DRS(self, expression, command, x, y):
467 left = x + self.BUFFER #indent the left side 468 bottom = y + self.BUFFER #indent the top 469 470 # Handle Discourse Referents 471 if expression.refs: 472 refs = ' '.join([str(ref) for ref in expression.refs]) 473 else: 474 refs = ' ' 475 (max_right, bottom) = command(refs, left, bottom) 476 bottom += (self.BUFFER * 2) 477 478 # Handle Conditions 479 if expression.conds: 480 for cond in expression.conds: 481 (right, bottom) = self._handle(cond, command, left, bottom) 482 max_right = max(max_right, right) 483 bottom += self.BUFFER 484 else: 485 bottom += self._get_text_height() + self.BUFFER 486 487 # Handle Box 488 max_right += self.BUFFER 489 return command((max_right, bottom), x, y)
490
491 - def _handle_ApplicationExpression(self, expression, command, x, y):
492 function, args = expression.uncurry() 493 if not isinstance(function, DrtVariableExpression): 494 #It's not a predicate expression ("P(x,y)"), so leave arguments curried 495 function = expression.function 496 args = [expression.argument] 497 498 # Get the max bottom of any element on the line 499 function_bottom = self._visit(function, x, y)[1] 500 max_bottom = max([function_bottom] + [self._visit(arg, x, y)[1] for arg in args]) 501 502 line_height = max_bottom - y 503 504 # Handle 'function' 505 function_drawing_top = self._get_centered_top(y, line_height, function._drawing_height) 506 right = self._handle(function, command, x, function_drawing_top)[0] 507 508 # Handle open paren 509 centred_string_top = self._get_centered_top(y, line_height, self._get_text_height()) 510 right = command(Tokens.OPEN, right, centred_string_top)[0] 511 512 # Handle each arg 513 for (i,arg) in enumerate(args): 514 arg_drawing_top = self._get_centered_top(y, line_height, arg._drawing_height) 515 right = self._handle(arg, command, right, arg_drawing_top)[0] 516 517 if i+1 < len(args): 518 #since it's not the last arg, add a comma 519 right = command(Tokens.COMMA + ' ', right, centred_string_top)[0] 520 521 # Handle close paren 522 right = command(Tokens.CLOSE, right, centred_string_top)[0] 523 524 return (right, max_bottom)
525
526 - def _handle_LambdaExpression(self, expression, command, x, y):
527 # Find the width of the lambda symbol and abstracted variables 528 variables = Tokens.LAMBDA[self.syntax] + str(expression.variable) + Tokens.DOT[self.syntax] 529 right = self._visit_command(variables, x, y)[0] 530 531 # Handle term 532 (right, bottom) = self._handle(expression.term, command, right, y) 533 534 # Handle variables now that we know the y-coordinate 535 command(variables, x, self._get_centered_top(y, bottom - y, self._get_text_height())) 536 537 return (right, bottom)
538
539 - def _handle_BooleanExpression(self, expression, command, x, y):
540 # Get the full height of the line, based on the operands 541 first_height = self._visit(expression.first, 0, 0)[1] 542 second_height = self._visit(expression.second, 0, 0)[1] 543 line_height = max(first_height, second_height) 544 545 # Handle open paren 546 centred_string_top = self._get_centered_top(y, line_height, self._get_text_height()) 547 right = command(Tokens.OPEN, x, centred_string_top)[0] 548 549 # Handle the first operand 550 first_height = expression.first._drawing_height 551 (right, first_bottom) = self._handle(expression.first, command, right, self._get_centered_top(y, line_height, first_height)) 552 553 # Handle the operator 554 right = command(' %s ' % expression.getOp(self.syntax), right, centred_string_top)[0] 555 556 # Handle the second operand 557 second_height = expression.second._drawing_height 558 (right, second_bottom) = self._handle(expression.second, command, right, self._get_centered_top(y, line_height, second_height)) 559 560 # Handle close paren 561 right = command(Tokens.CLOSE, right, centred_string_top)[0] 562 563 return (right, max(first_bottom, second_bottom))
564
565 - def _get_centered_top(self, top, full_height, item_height):
566 """Get the y-coordinate of the point that a figure should start at if 567 its height is 'item_height' and it needs to be centered in an area that 568 starts at 'top' and is 'full_height' tall.""" 569 return top + (full_height - item_height) / 2
570 571
572 -class Tokens(logic.Tokens):
573 DRS = 'DRS' 574 DRS_CONC = '+' 575 PRONOUN = 'PRO' 576 OPEN_BRACKET = '[' 577 CLOSE_BRACKET = ']' 578 579 PUNCT = [DRS_CONC, OPEN_BRACKET, CLOSE_BRACKET] 580 581 SYMBOLS = logic.Tokens.SYMBOLS + PUNCT 582 583 TOKENS = logic.Tokens.TOKENS + [DRS] + PUNCT
584
585 -class DrtParser(logic.LogicParser):
586 """A lambda calculus expression parser.""" 587
588 - def __init__(self):
590
591 - def get_all_symbols(self):
592 """This method exists to be overridden""" 593 return Tokens.SYMBOLS
594
595 - def isvariable(self, tok):
596 return tok not in Tokens.TOKENS
597
598 - def handle(self, tok):
599 """This method is intended to be overridden for logics that 600 use different operators or expressions""" 601 if tok in Tokens.NOT: 602 return self.handle_negation() 603 604 elif tok in Tokens.LAMBDA: 605 return self.handle_lambda(tok) 606 607 elif tok == Tokens.OPEN: 608 return self.handle_open(tok) 609 610 elif tok.upper() == Tokens.DRS: 611 return self.handle_DRS() 612 613 elif self.isvariable(tok): 614 return self.handle_variable(tok)
615
616 - def make_NegatedExpression(self, expression):
617 return DrtNegatedExpression(expression)
618
619 - def handle_DRS(self):
620 # a DRS 621 self.assertToken(self.token(), Tokens.OPEN) 622 self.assertToken(self.token(), Tokens.OPEN_BRACKET) 623 refs = [] 624 while self.token(0) != Tokens.CLOSE_BRACKET: 625 # Support expressions like: DRS([x y],C) == DRS([x,y],C) 626 if self.token(0) == Tokens.COMMA: 627 self.token() # swallow the comma 628 else: 629 refs.append(logic.Variable(self.token())) 630 self.token() # swallow the CLOSE_BRACKET token 631 self.assertToken(self.token(), Tokens.COMMA) 632 self.assertToken(self.token(), Tokens.OPEN_BRACKET) 633 conds = [] 634 while self.token(0) != Tokens.CLOSE_BRACKET: 635 # Support expressions like: DRS([x y],C) == DRS([x, y],C) 636 if self.token(0) == Tokens.COMMA: 637 self.token() # swallow the comma 638 else: 639 conds.append(self.parse_Expression()) 640 self.token() # swallow the CLOSE_BRACKET token 641 self.assertToken(self.token(), Tokens.CLOSE) 642 return DRS(refs, conds)
643
644 - def make_EqualityExpression(self, first, second):
645 """This method serves as a hook for other logic parsers that 646 have different equality expression classes""" 647 return DrtEqualityExpression(first, second)
648
650 """This method serves as a hook for other logic parsers that 651 have different boolean operators""" 652 factory = None 653 op = self.token(0) 654 if op == Tokens.DRS_CONC: 655 factory = ConcatenationDRS 656 elif op in Tokens.OR: 657 factory = DrtOrExpression 658 elif op in Tokens.IMP: 659 factory = DrtImpExpression 660 elif op in Tokens.IFF: 661 factory = DrtIffExpression 662 return factory
663
664 - def make_ApplicationExpression(self, function, argument):
665 return DrtApplicationExpression(function, argument)
666
667 - def make_VariableExpression(self, name):
672
673 - def make_LambdaExpression(self, variables, term):
674 return DrtLambdaExpression(variables, term)
675
676 -def demo():
677 n = Tokens.NEW_NLTK 678 print '='*20 + 'TEST PARSE' + '='*20 679 parser = DrtParser() 680 print parser.parse(r'DRS([x,y],[sees(x,y)])') 681 print parser.parse(r'DRS([x],[man(x), walks(x)])') 682 print parser.parse(r'\x.\y.DRS([],[sees(x,y)])') 683 print parser.parse(r'\x.DRS([],[walks(x)])(john)') 684 print parser.parse(r'(DRS([x],[walks(x)]) + DRS([y],[runs(y)]))') 685 print parser.parse(r'(DRS([],[walks(x)]) -> DRS([],[runs(x)]))') 686 print parser.parse(r'DRS([x],[PRO(x), sees(John,x)])') 687 print parser.parse(r'DRS([x],[man(x), -DRS([],[walks(x)])])') 688 print parser.parse(r'DRS([],[(DRS([x],[man(x)]) -> DRS([],[walks(x)]))])') 689 690 print '='*20 + 'Test toFol()' + '='*20 691 print parser.parse(r'DRS([x,y],[sees(x,y)])').toFol() 692 693 694 print '='*20 + 'Test alpha conversion and lambda expression equality' + '='*20 695 e1 = parser.parse(r'\x.drs([],[P(x)])') 696 print e1 697 e2 = e1.alpha_convert(DrtVariableExpression('z')) 698 print e2 699 print e1 == e2 700 701 print '='*20 + 'Test resolve_anaphora()' + '='*20 702 print parser.parse(r'DRS([x,y,z],[dog(x), cat(y), walks(z), PRO(z)])').resolve_anaphora() 703 print parser.parse(r'DRS([],[(DRS([x],[dog(x)]) -> DRS([y],[walks(y), PRO(y)]))])').resolve_anaphora() 704 print parser.parse(r'(DRS([x,y],[]) + DRS([],[PRO(x)]))').resolve_anaphora() 705 print parser.parse(r'DRS([x],[walks(x), PRO(x)])').resolve_anaphora() 706 707 print '='*20 + 'Test tp_equals()' + '='*20 708 a = parser.parse(r'DRS([x],[man(x), walks(x)])') 709 b = parser.parse(r'DRS([x],[walks(x), man(x)])') 710 print a.tp_equals(b)
711 712
713 -def test_draw():
714 expressions = [ 715 r'x', 716 r'DRS([],[])', 717 r'DRS([x],[])', 718 r'DRS([x],[man(x)])', 719 720 r'drs([x,y],[sees(x,y)])', 721 r'drs([x],[man(x), walks(x)])', 722 r'\x.drs([],[man(x), walks(x)])', 723 r'\x y.drs([],[sees(x,y)])', 724 r'drs([],[(drs([],[walks(x)]) + drs([],[runs(x)]))])', 725 726 r'drs([x],[man(x), -drs([],[walks(x)])])', 727 r'drs([],[(drs([x],[man(x)]) -> drs([],[walks(x)]))])' 728 ] 729 730 for e in expressions: 731 d = DrtParser().parse(e) 732 d.draw()
733 734 if __name__ == '__main__': 735 demo() 736