14
15
55
181
187
188:- module(refres, [resolve_anaphors/2]). 189
191
192:- dynamic(variable_defined/3). 193
194:- dynamic(nesting_level/1). 195
196:- op( 400, xfx, :). 197:- op( 400, fy, -). 198:- op( 400, fy, ~). 199:- op( 600, xfy, v). 200:- op( 650, xfy, =>). 201
202:- use_module('../logger/error_logger', [add_error_message_once/4, add_warning_message_once/4]). 203:- use_module('../lexicon/lexicon_interface', [noun_pl/3]). 204
219
220resolve_anaphors(drs(ReferentsIn, ConditionsIn), DRSOut) :-
221 catch(call(resolve_anaphors1(drs(ReferentsIn, ConditionsIn), DRSOut)), CatchType, add_error_message_once(anaphor, '', CatchType, 'Send screenshot to APE developers.')).
222
223resolve_anaphors1(drs(ReferentsIn, ConditionsIn), drs(ReferentsOut, ConditionsOut)) :-
224 initialise_DRS_nesting_level,
225 226 enforce_order(ConditionsIn, ConditionsInUpdated, [], ConditionsAllOut, [], AntecedentsIn),
227 228 resolve_all_anaphors(drs(ReferentsIn, ConditionsInUpdated), ConditionsAllOut, AntecedentsIn, _AntecedentsOut, [], _ProperNamesOut, drs(ReferentsOut, ConditionsIntermediate)),
229 230 231 filter_conditions(ConditionsIntermediate, ConditionsOut),
232 233 cleanup.
234
235
252
253resolve_all_anaphors(drs(Referents, []), _ConditionsAllIn, AntecedentsIn, AntecedentsOut, ProperNames, ProperNames, drs(Referents, [])) :-
254 !,
255 (
256 var(AntecedentsOut)
257 ->
258 AntecedentsOut = AntecedentsIn
259 ;
260 true
261 ).
262
263resolve_all_anaphors(drs(ReferentsIn, [Condition|Conditions]), ConditionsAllIn, AntecedentsIn, AntecedentsOut, ProperNamesIn, ProperNamesOut, DRSOut) :-
264 (
265 266 Condition = _-_
267 ->
268 (
269 Condition = variable(_, _)-_
270 ->
271 272 define_new_variable(Condition, apposition),
273 DRSOut = drs(ReferentsOut, ConditionsOut)
274 ;
275 DRSOut = drs(ReferentsOut, [Condition|ConditionsOut])
276 ),
277 resolve_all_anaphors(drs(ReferentsIn, Conditions), ConditionsAllIn, AntecedentsIn, AntecedentsOut, ProperNamesIn, ProperNamesOut, drs(ReferentsOut, ConditionsOut))
278 ;
279 280 Condition = antecedent(_, _, _, _, _, _, _, _, _)
281 ->
282 283 insert_antecedent(Condition, AntecedentsIn, AntecedentsIM),
284 285 resolve_all_anaphors(drs(ReferentsIn, Conditions), ConditionsAllIn, AntecedentsIM, AntecedentsOut, ProperNamesIn, ProperNamesOut, DRSOut)
286 ;
287 288 Condition = anaphor(_, AnaphorID1, _, _, _, _, _, _, _, _, _)
289 ->
290 (
291 292 append(Front, [anaphor(Anaphortype2, AnaphorID2, AnaphorReferent2, AnaphorConditions2, AnaphorGenus2, AnaphorNumerus2, AnaphorPerson2, SentenceID2, TokenID2, Tokens2, Subject2)|Rest], Conditions),
293 AnaphorID2 < AnaphorID1
294 ->
295 296 append(Front,[anaphor(Anaphortype2, AnaphorID2, AnaphorReferent2, AnaphorConditions2, AnaphorGenus2, AnaphorNumerus2, AnaphorPerson2, SentenceID2, TokenID2, Tokens2, Subject2), Condition|Rest], PermutedConditions),
297 resolve_all_anaphors(drs(ReferentsIn, PermutedConditions), ConditionsAllIn, AntecedentsIn, AntecedentsOut, ProperNamesIn, ProperNamesOut, DRSOut)
298 ;
299 300 resolve_one_anaphor(drs(ReferentsIn, Conditions), ConditionsAllIn, ConditionsAllOut, Condition, AntecedentsIn, AntecedentsIntermediate, ProperNamesIn, ProperNamesIM, drs(ReferentsIM, ConditionsIM)),
301 302 resolve_all_anaphors(drs(ReferentsIM, ConditionsIM), ConditionsAllOut, AntecedentsIntermediate, AntecedentsOut, ProperNamesIM, ProperNamesOut, DRSOut)
303 )
304 ;
305 306 is_list(Condition)
307 ->
308 DRSOut = drs(ReferentsOut, [ConditionListOut|ConditionsOut]),
309 resolve_all_anaphors(drs(ReferentsIn, Condition), ConditionsAllIn, AntecedentsIn, AntecedentsTemp, ProperNamesIn, ProperNamesTemp, drs(ReferentsTemp, ConditionListOut)),
310 resolve_all_anaphors(drs(ReferentsTemp, Conditions), ConditionsAllIn, AntecedentsTemp, AntecedentsOut, ProperNamesTemp, ProperNamesOut, drs(ReferentsOut, ConditionsOut))
311 ;
312 313 (
314 315 Condition = - drs(ReferentsNIn, ConditionsNIn)
316 ;
317 318 Condition = ~ drs(ReferentsNIn, ConditionsNIn)
319 ;
320 321 Condition = can(drs(ReferentsNIn, ConditionsNIn))
322 ;
323 324 Condition = must(drs(ReferentsNIn, ConditionsNIn))
325 ;
326 327 Condition = should(drs(ReferentsNIn, ConditionsNIn))
328 ;
329 330 Condition = may(drs(ReferentsNIn, ConditionsNIn))
331 ;
332 333 Condition = question(drs(ReferentsNIn, ConditionsNIn))
334 ;
335 336 Condition = command(drs(ReferentsNIn, ConditionsNIn))
337 ;
338 339 Condition = _ : drs(ReferentsNIn, ConditionsNIn)
340 )
341 ->
342 functor(Condition, Operator, _),
343 arg(1, Condition, Label),
344 increase_DRS_nesting_level,
345 346 enforce_order(ConditionsNIn, ConditionsNInUpdated, ConditionsAllIn, ConditionsAllOut, AntecedentsIn, AntecedentsInUpdated),
347 348 resolve_all_anaphors(drs(ReferentsNIn, ConditionsNInUpdated), ConditionsAllOut, AntecedentsInUpdated, AntecedentsInUpdated, ProperNamesIn, ProperNamesIM, drs(ReferentsIntermediate, ConditionsIntermediate1)),
349 350 decrease_DRS_nesting_level,
351 add_proper_name_antecedents(ProperNamesIn, ProperNamesIM, AntecedentsIn, AntecedentsInPlusProperNames),
352 resolve_all_anaphors(drs(ReferentsIn, Conditions), ConditionsAllIn, AntecedentsInPlusProperNames, AntecedentsOut, ProperNamesIM, ProperNamesOut, drs(ReferentsOut, ConditionsOut)),
353 354 355 filter_conditions(ConditionsIntermediate1, ConditionsIntermediate2),
356 357 build_drs(Operator, Label, drs(ReferentsIntermediate, ConditionsIntermediate2), NewDRS),
358 DRSOut = drs(ReferentsOut, [NewDRS|ConditionsOut])
359 ;
360 361 Condition = drs(Referents1In, Conditions1In) => drs(Referents2In, Conditions2In)
362 ->
363 increase_DRS_nesting_level,
364 365 enforce_order(Conditions1In, Conditions1InUpdated, ConditionsAllIn, ConditionsAllIM1, AntecedentsIn, AntecedentsIM1),
366 367 append(ConditionsAllIM1, Conditions2In, ConditionsAllPlusConsequence),
368 resolve_all_anaphors(drs(Referents1In, Conditions1InUpdated), ConditionsAllPlusConsequence, AntecedentsIM1, AntecedentsIM2, ProperNamesIn, ProperNamesIM1, drs(Referents1Out, Conditions1Intermediate)),
369 enforce_order(Conditions2In, Conditions2InUpdated, ConditionsAllIM1, ConditionsAllIM2, AntecedentsIM2, AntecedentsIM3),
370 resolve_all_anaphors(drs(Referents2In, Conditions2InUpdated), ConditionsAllIM2, AntecedentsIM3, _AntecedentsOut, ProperNamesIM1, ProperNamesIM2, drs(Referents2Out, Conditions2Intermediate1)),
371 372 decrease_DRS_nesting_level,
373 add_proper_name_antecedents(ProperNamesIn, ProperNamesIM2, AntecedentsIn, AntecedentsInPlusProperNames),
374 resolve_all_anaphors(drs(ReferentsIn, Conditions), ConditionsAllIn, AntecedentsInPlusProperNames, AntecedentsOut, ProperNamesIM2, ProperNamesOut, drs(ReferentsOut, ConditionsOut)),
375 376 377 filter_conditions(Conditions1Intermediate, Conditions1Out),
378 filter_conditions(Conditions2Intermediate1, Conditions2Intermediate2),
379 380 subtract_conditions(Conditions2Intermediate2, Conditions1Out, Conditions2Out),
381 382 DRSOut = drs(ReferentsOut, [drs(Referents1Out, Conditions1Out) => drs(Referents2Out, Conditions2Out)|ConditionsOut])
383 ;
384 385 386 387 Condition = drs(Referents1In, Conditions1In) v DisjunctRestIn
388 ->
389 increase_DRS_nesting_level,
390 391 enforce_order(Conditions1In, Conditions1InUpdated, ConditionsAllIn, ConditionsAllIM, AntecedentsIn, AntecedentsInUpdated),
392 393 resolve_all_anaphors(drs(Referents1In, Conditions1InUpdated), ConditionsAllIM, AntecedentsInUpdated, AntecedentsIM, ProperNamesIn, ProperNamesIM1, drs(Referents1Out, Conditions1Intermediate)),
394 395 DisjunctRestIn = drs(_ReferentsDisjunctRestIn, ConditionsDisjunctRestIn),
396 enforce_order(ConditionsDisjunctRestIn, _ConditionsDisjunctRestInUpdated, ConditionsAllIM, ConditionsAllOut, AntecedentsIM, AntecedentsIMUpdated),
397 resolve_all_anaphors(DisjunctRestIn, ConditionsAllOut, AntecedentsIMUpdated, _AntecedentsOut, ProperNamesIM1, ProperNamesIM2, drs(ReferentsRestOut, ConditionsRestIntermediate)),
398 399 decrease_DRS_nesting_level,
400 add_proper_name_antecedents(ProperNamesIn, ProperNamesIM2, AntecedentsIn, AntecedentsInPlusProperNames),
401 resolve_all_anaphors(drs(ReferentsIn, Conditions), ConditionsAllIn, AntecedentsInPlusProperNames, AntecedentsOut, ProperNamesIM2, ProperNamesOut, drs(ReferentsOut, ConditionsOut)),
402 403 404 filter_conditions(Conditions1Intermediate, Conditions1Out),
405 filter_conditions(ConditionsRestIntermediate, ConditionsRestOut),
406 407 DRSOut = drs(ReferentsOut, [drs(Referents1Out, Conditions1Out) v drs(ReferentsRestOut, ConditionsRestOut)|ConditionsOut])
408 ).
409
410
424
425resolve_one_anaphor(drs(ReferentsIn, ConditionsIn), ConditionsAllIn, ConditionsAllOut, Anaphor, AntecedentsIn, AntecedentsOut, ProperNamesIn, ProperNamesOut, drs(ReferentsOut, ConditionsOut)) :-
426 (
427 428 Anaphor = anaphor(nonreflexive_pronoun, AnaphorID, AnaphorReferent, AnaphorConditions, AnaphorGenus, AnaphorNumerus, AnaphorPerson, AnaphorSID, AnaphorTID, AnaphorTokens, SentenceSubject)
429 ->
430 (
431 432 433 434 member(antecedent(AntecedentID, AntecedentReferent, _AntecedentConditions, AnaphorGenus, AnaphorNumerus, AnaphorPerson, AntecedentSID, AntecedentTID, AntecedentTokens), AntecedentsIn),
435 AnaphorID > AntecedentID,
436 SentenceSubject \== subj(AntecedentReferent)
437 ->
438 delete_all_occurrences_of_one_discourse_referent(ReferentsIn, AnaphorReferent, ReferentsOut),
439 (
440 441 (AnaphorTokens = 'he' ; AnaphorTokens = 'she' ; AnaphorTokens = 'he/she' ; AnaphorTokens = 'it' ; AnaphorTokens = 'they')
442 ->
443 ConditionsOut = [antecedent(AnaphorID, AnaphorReferent, AnaphorConditions, AnaphorGenus, AnaphorNumerus, AnaphorPerson, AnaphorSID, AnaphorTID, AnaphorTokens)|ConditionsIn]
444 ;
445 446 ConditionsOut = ConditionsIn
447 ),
448 ConditionsAllOut = ConditionsAllIn,
449 AnaphorReferent = AntecedentReferent,
450 AntecedentsOut = AntecedentsIn,
451 ProperNamesOut = ProperNamesIn
452 ;
453 454 455 ReferentsOut = ReferentsIn,
456 ConditionsOut = ConditionsIn,
457 ConditionsAllOut = ConditionsAllIn,
458 ProperNamesOut = ProperNamesIn,
459 AntecedentsOut = AntecedentsIn,
460 atom_concat('Unresolved anaphor: ', AnaphorTokens, ErrorText),
461 add_error_message_once(anaphor, AnaphorSID-AnaphorTID, ErrorText, 'Identify correct accessible antecedent.')
462 )
463 ;
464 465 Anaphor = anaphor(definite_noun_phrase, AnaphorID, AnaphorReferent, AnaphorConditions, AnaphorGenus, AnaphorNumerus, AnaphorPerson, AnaphorSID, AnaphorTID, AnaphorTokens, SentenceSubject)
466 ->
467 468 (
469 member(variable(VariableReferent, VariableName)-AnaphorSID/_, AnaphorConditions),
470 VariableReferent == AnaphorReferent
471 ->
472 (
473 474 variable_defined(VariableName, DRSNestingLevel, bare),
475 nesting_level(CurrentNestingLevel),
476 CurrentNestingLevel >= DRSNestingLevel
477 ->
478 atom_concat('Redefined variable: ', VariableName, ErrorText),
479 add_error_message_once(anaphor, AnaphorSID - AnaphorTID, ErrorText, 'Assign unique variables.')
480 ;
481 true
482 )
483 ;
484 true
485 ),
486 (
487 488 489 490 member(antecedent(AntecedentID, AntecedentReferent, AntecedentConditions, AnaphorGenus, _AntecedentNumerus, AnaphorPerson, AntecedentSID, AntecedentTID, AntecedentTokens), AntecedentsIn),
491 AnaphorID > AntecedentID,
492 493 AnaphorTokens = AntecedentTokens,
494 495 \+ (member(relation(ReferentX, of, ReferentY)-AntecedentSID/_, AntecedentConditions), ReferentX == AntecedentReferent, ReferentY == AnaphorReferent),
496 497 (
498 member(variable(ReferentZ, _X1)-AntecedentSID/_, AntecedentConditions)
499 ->
500 ReferentZ == AntecedentReferent
501 ;
502 true
503 ),
504 505 \+ \+ (
506 507 Antecedent = antecedent(AntecedentID, AntecedentReferent, AntecedentConditions, AnaphorGenus, AntecedentNumerus, AnaphorPerson, AntecedentSID, AntecedentTID, AntecedentTokens),
508 copy_term(Antecedent, CopiedAntecedent),
509 510 numbervars(CopiedAntecedent, 1, _),
511 512 CopiedAntecedent = antecedent(_, CopiedAntecedentReferent, CopiedAntecedentConditions, _, _, _, _, _, _),
513 AnaphorReferent = CopiedAntecedentReferent,
514 515 match_elements(AnaphorConditions, CopiedAntecedentConditions)
516 )
517 ->
518 519 520 521 (
522 \+ \+ member(relation(AnaphorReferent, of, Owner1)-AnaphorSID/_, AnaphorConditions),
523 \+ (member(object(Owner2, _, _, _, _, _)-AnaphorSID/_, AnaphorConditions), Owner1 == Owner2)
524 ->
525 select(relation(_SomeObject, of, _Owner)-AnaphorSID/_, AnaphorConditions, RestAnaphorConditions)
526 ;
527 RestAnaphorConditions = AnaphorConditions
528 ),
529 530 term_variables(RestAnaphorConditions, AnaphorReferents),
531 delete_all_occurrences_of_all_discourse_referents(ReferentsIn, AnaphorReferents, ReferentsOut),
532 533 eliminate_spurious_antecedents(AntecedentsIn, AnaphorID, AnaphorConditions, AntecedentsOut),
534 ConditionsOut = ConditionsIn,
535 ConditionsAllOut = ConditionsAllIn,
536 AnaphorReferent = AntecedentReferent,
537 ProperNamesOut = ProperNamesIn
538 ;
539 540 541 542 member(antecedent(AntecedentID, AntecedentReferent, AntecedentConditions, AnaphorGenus, _AntecedentNumerus, AnaphorPerson, AntecedentSID, AntecedentTID, AntecedentTokens), AntecedentsIn),
543 AnaphorID > AntecedentID,
544 545 AnaphorTokens = AntecedentTokens,
546 547 \+ \+ (
548 549 Antecedent = antecedent(AntecedentID, AntecedentReferent, AntecedentConditions, AnaphorGenus, AntecedentNumerus, AnaphorPerson, AntecedentSID, AntecedentTID, AntecedentTokens),
550 copy_term((Antecedent, ConditionsAllIn), (CopiedAntecedent, CopiedConditionsAllIn)),
551 552 numbervars((CopiedAntecedent, CopiedConditionsAllIn), 1, _),
553 554 CopiedAntecedent = antecedent(_, CopiedAntecedentReferent, CopiedAntecedentConditions, _, _, _, _, _, _),
555 AnaphorReferent = CopiedAntecedentReferent,
556 557 once(append(Front, [object(AnaphorReferent, AnaphorTokens, Quant, Unit, Op, Count)-AnaphorSID/TID|Tail], AnaphorConditions)),
558 once(append(Front, Tail, RemainingAnaphorConditions)),
559 MainAnaphorCondition = object(AnaphorReferent, AnaphorTokens, Quant, Unit, Op, Count)-AnaphorSID/TID,
560 561 match_elements([MainAnaphorCondition], AntecedentConditions),
562 563 append(CopiedAntecedentConditions, CopiedConditionsAllIn, CopiedAntecedentConditionsAndCopiedConditionsAllIn),
564 match_elements(RemainingAnaphorConditions, CopiedAntecedentConditionsAndCopiedConditionsAllIn)
565 )
566 ->
567 term_variables(AnaphorConditions, AnaphorReferents),
568 delete_all_occurrences_of_all_discourse_referents(ReferentsIn, AnaphorReferents, ReferentsOut),
569 570 eliminate_spurious_antecedents(AntecedentsIn, AnaphorID, AnaphorConditions, AntecedentsOut),
571 ConditionsOut = ConditionsIn,
572 ConditionsAllOut = ConditionsAllIn,
573 AnaphorReferent = AntecedentReferent,
574 ProperNamesOut = ProperNamesIn
575 ;
576 577 578 ReferentsOut = ReferentsIn,
579 ProperNamesOut = ProperNamesIn,
580 AntecedentsOut = AntecedentsIn,
581 582 delete_all_occurrences_of_all_elements(AnaphorConditions, [variable(_, _)-_], AnaphorConditionsWithoutVariables),
583 append(AnaphorConditionsWithoutVariables, ConditionsIn, ConditionsIM),
584 585 586 ConditionsOut = [antecedent(AnaphorID, AnaphorReferent, AnaphorConditions, AnaphorGenus, AnaphorNumerus, AnaphorPerson, AnaphorSID, AnaphorTID, AnaphorTokens)|ConditionsIM],
587 588 append(AnaphorConditions, ConditionsAllIn, ConditionsAllOut),
589 590 (
591 592 \+ \+ member(object(AnaphorReferent, AnaphorTokens, countable, na, _Op, AnaphorCount)-AnaphorSID/_, AnaphorConditions)
593 ->
594 (
595 596 AnaphorCount = 1
597 ->
598 AnaphorNoun = AnaphorTokens
599 ;
600 601 602 lexicon_interface:noun_pl(AnaphorNoun, AnaphorTokens, _Gender)
603 ->
604 true
605 ;
606 607 AnaphorNoun = AnaphorTokens
608 ),
609 concat_atom(['The definite noun phrase ''the ', AnaphorNoun, ''' does not have an antecedent and thus is not interpreted as anaphoric reference, but as a new indefinite noun phrase.'], ErrorText1),
610 concat_atom(['If the definite noun phrase ''the ', AnaphorNoun, ''' should be an anaphoric reference then you must introduce an appropriate antecedent.'], ErrorText2),
611 add_warning_message_once(anaphor, AnaphorSID-AnaphorTID, ErrorText1, ErrorText2)
612 ;
613 614 member(object(AnaphorReferent, AnaphorTokens, mass, na, na, na)-AnaphorSID/_, AnaphorConditions)
615 ->
616 concat_atom(['The definite noun phrase ''the ', AnaphorTokens, ''' does not have an antecedent and thus is not interpreted as anaphoric reference, but as a new indefinite noun phrase.'], ErrorText1),
617 concat_atom(['If the definite noun phrase ''the ', AnaphorTokens, ''' should be an anaphoric reference then you must introduce an appropriate antecedent.'], ErrorText2),
618 add_warning_message_once(anaphor, AnaphorSID-AnaphorTID, ErrorText1, ErrorText2)
619 )
620 )
621 ;
622 623 Anaphor = anaphor(variable, AnaphorID, AnaphorReferent, AnaphorConditions, _AnaphorGenus, AnaphorNumerus, AnaphorPerson, AnaphorSID, AnaphorTID, AnaphorTokens, SentenceSubject)
624 ->
625 (
626 627 628 member(antecedent(AntecedentID, AntecedentReferent, AntecedentConditions, _AntecedentGenus, AnaphorNumerus, AnaphorPerson, AntecedentSID, AntecedentTID, AntecedentTokens), AntecedentsIn),
629 AnaphorID > AntecedentID,
630 631 AntecedentConditions = [variable(AntecedentReferent, AntecedentVariable)-_AntecedentIndex],
632 AnaphorConditions = [variable(AnaphorReferent, AnaphorVariable)-_AnaphorIndex],
633 AntecedentVariable == AnaphorVariable
634 ->
635 delete_all_occurrences_of_one_discourse_referent(ReferentsIn, AnaphorReferent, ReferentsOut),
636 ConditionsOut = ConditionsIn,
637 ConditionsAllOut = ConditionsAllIn,
638 AntecedentsOut = AntecedentsIn,
639 AnaphorReferent = AntecedentReferent,
640 ProperNamesOut = ProperNamesIn
641 ;
642 643 644 645 AnaphorConditions = [Variable],
646 define_new_variable(Variable, bare),
647 648 ConditionsOut = [antecedent(AnaphorID, AnaphorReferent, AnaphorConditions, _AnaphorGenus, AnaphorNumerus, AnaphorPerson, AnaphorSID, AnaphorTID, AnaphorTokens),
649 object(AnaphorReferent,something,dom,na,na,na)-AnaphorSID/AnaphorTID|ConditionsIn],
650 ReferentsOut = ReferentsIn,
651 ConditionsAllOut = ConditionsAllIn,
652 AntecedentsOut = AntecedentsIn,
653 ProperNamesOut = ProperNamesIn
654 )
655 ;
656 657 Anaphor = anaphor(proper_name, AnaphorID, AnaphorReferent, AnaphorConditions, AnaphorGenus, AnaphorNumerus, AnaphorPerson, AnaphorSID, AnaphorTID, AnaphorTokens, SentenceSubject)
658 ->
659 (
660 661 662 member(proper_name(_ID, AnaphorReferent, AnaphorConditions, AnaphorGenus, AnaphorNumerus, AnaphorPerson, _SID, _TID, AnaphorTokens), ProperNamesIn)
663 ->
664 ReferentsOut = ReferentsIn,
665 ConditionsOut = ConditionsIn,
666 ConditionsAllOut = ConditionsAllIn,
667 AntecedentsOut = AntecedentsIn,
668 ProperNamesOut = ProperNamesIn
669 ;
670 671 ReferentsOut = ReferentsIn,
672 673 ConditionsOut = [antecedent(AnaphorID, AnaphorReferent, AnaphorConditions, AnaphorGenus, AnaphorNumerus, AnaphorPerson, AnaphorSID, AnaphorTID, AnaphorTokens)|ConditionsIn],
674 ConditionsAllOut = ConditionsAllIn,
675 AntecedentsOut = AntecedentsIn,
676 677 ProperNamesOut = [proper_name(AnaphorID, AnaphorReferent, AnaphorConditions, AnaphorGenus, AnaphorNumerus, AnaphorPerson, AnaphorSID, AnaphorTID, AnaphorTokens)|ProperNamesIn]
678 )
679 ;
680 681 Anaphor = anaphor(_UnrecognizedAnaphorType, AnaphorID, AnaphorReferent, AnaphorConditions, AnaphorGenus, AnaphorNumerus, AnaphorPerson, AnaphorSID, AnaphorTID, AnaphorTokens, SentenceSubject)
682 ->
683 684 ReferentsOut = ReferentsIn,
685 ConditionsOut = [unresolved(Anaphor)|ConditionsIn],
686 ConditionsAllOut = ConditionsAllIn,
687 AntecedentsOut = AntecedentsIn,
688 ProperNamesOut = ProperNamesIn,
689 add_error_message_once(anaphor, AnaphorSID-AnaphorTID, 'Unrecognised anaphor.', 'Send screenshot to APE developers.')
690 ).
691
692
706
707add_proper_name_antecedents(ProperNamesThisLevel, ProperNamesNestedLevel, AntecedentsThisLevelIn, AntecedentsThisLevelOut) :-
708 709 delete_all_occurrences_of_all_elements(ProperNamesNestedLevel, ProperNamesThisLevel, NewProperNames),
710 (
711 712 NewProperNames = []
713 ->
714 AntecedentsThisLevelOut = AntecedentsThisLevelIn
715 ;
716 717 prepend_proper_name_antecedents(NewProperNames, AntecedentsThisLevelIn, AntecedentsThisLevelIntermediate1),
718 sort(AntecedentsThisLevelIntermediate1, AntecedentsThisLevelIntermediate2),
719 reverse(AntecedentsThisLevelIntermediate2, AntecedentsThisLevelOut)
720 ).
721
722prepend_proper_name_antecedents([], Antecedents, Antecedents).
723
724prepend_proper_name_antecedents([proper_name(ID, Referent, Conditions, Genus, Numerus, Person, SID, TID, Tokens)|MoreProperNames], Antecedents, NewAntecedents) :-
725 prepend_proper_name_antecedents(MoreProperNames, [antecedent(ID, Referent, Conditions, Genus, Numerus, Person, SID, TID, Tokens)|Antecedents], NewAntecedents).
726
727
736
737build_drs(Operator, Label, DRS, NewDRS) :-
738 (
739 var(Label)
740 ->
741 NewDRS =.. [Operator, Label, DRS]
742 ;
743 744 NewDRS =.. [Operator, DRS]
745 ).
746
747
756
757check_for_redefined_variables([]).
758
759check_for_redefined_variables([_Antecedent]).
760
762check_for_redefined_variables([divider_between_DRS_nesting_levels|Antecedents]) :-
763 check_for_redefined_variables(Antecedents).
764
765check_for_redefined_variables([Antecedent|Antecedents]) :-
766 Antecedent = antecedent(AntecedentID1, AntecedentReferent1, AntecedentConditions1, _AnaphorGenus1, _AntecedentNumerus1, _AntecedentPerson1, AntecedentSID1, AntecedentTID1, _AntecedentTokens1),
767 (
768 769 select(variable(Referent1, VariableName)-AntecedentSID1/_, AntecedentConditions1, [_|_]),
770 Referent1 == AntecedentReferent1,
771 member(antecedent(AntecedentID2, AntecedentReferent2, AntecedentConditions2, _AnaphorGenus2, _AntecedentNumerus2, _AntecedentPerson2, AntecedentSID2, _AntecedentTID2, _AntecedentTokens2), Antecedents),
772 AntecedentID2 < AntecedentID1,
773 select(variable(Referent2, VariableName)-AntecedentSID2/_, AntecedentConditions2, [_|_]),
774 Referent2 == AntecedentReferent2
775 ->
776 atom_concat('Redefined variable: ', VariableName, ErrorText),
777 add_error_message_once(anaphor, AntecedentSID1 - AntecedentTID1, ErrorText, 'Assign unique variables.')
778 ;
779 780 true
781 ),
782 783 check_for_redefined_variables(Antecedents).
784
785
791
792cleanup :-
793 retractall(variable_defined(_, _, _)).
794
795
806
807define_new_variable(variable(_Referent, VariableName)-SentenceIndex/TokenIndex, VariableType) :-
808 nesting_level(CurrentNestingLevel),
809 (
810 811 variable_defined(VariableName, DRSNestingLevel, _VariableType),
812 CurrentNestingLevel >= DRSNestingLevel
813 ->
814 atom_concat('Redefined variable: ', VariableName, ErrorText),
815 add_error_message_once(anaphor, SentenceIndex-TokenIndex, ErrorText, 'Assign unique variables.')
816 ;
817 true
818 ),
819 assert(variable_defined(VariableName, CurrentNestingLevel, VariableType)).
820
821
835
836delete_all_occurrences_of_all_elements(ListIn, [], ListIn) :-
837 !.
838
839delete_all_occurrences_of_all_elements(ListIn, [ElementToDelete|ElementsToDelete], ListOut) :-
840 delete_all(ListIn, ElementToDelete, ListIM),
841 !,
842 delete_all_occurrences_of_all_elements(ListIM, ElementsToDelete, ListOut).
843
844
845delete_all([X|Xs],Z,Ys) :-
846 \+ \+ (X = Z),
847 delete_all(Xs,Z,Ys).
848
849delete_all([X|Xs],Z,[X|Ys]) :-
850 \+ \+ (X \= Z),
851 delete_all(Xs,Z,Ys).
852
853delete_all([],_X,[]).
854
867
868delete_all_occurrences_of_all_discourse_referents(Referents, [], Referents) :-
869 !.
870
871delete_all_occurrences_of_all_discourse_referents(ReferentsIn, [ReferentToDelete|ReferentsToDelete], ReferentsOut) :-
872 delete_all_occurrences_of_one_discourse_referent(ReferentsIn, ReferentToDelete, ReferentsIM),
873 delete_all_occurrences_of_all_discourse_referents(ReferentsIM, ReferentsToDelete, ReferentsOut).
874
875
876delete_all_occurrences_of_one_discourse_referent([], _ReferentToDelete, []).
877
878delete_all_occurrences_of_one_discourse_referent([Referent|Referents], ReferentToDelete, ReferentsOut) :-
879 (
880 Referent == ReferentToDelete
881 ->
882 delete_all_occurrences_of_one_discourse_referent(Referents, ReferentToDelete, ReferentsOut)
883 ;
884 delete_all_occurrences_of_one_discourse_referent(Referents, ReferentToDelete, ReferentsRest),
885 ReferentsOut = [Referent|ReferentsRest]
886 ).
887
898
899eliminate_spurious_antecedents(AntecedentsIn, AnaphorID, AnaphorConditions, AntecedentsOut) :-
900 (
901 member(antecedent(AntecedentID, AntecedentReferent, AntecedentConditions, AntecedentGenus, AntecedentNumerus, AntecedentPerson, AntecedentSID, AntecedentTID, AntecedentTokens), AntecedentsIn),
902 AnaphorID < AntecedentID,
903 \+ AntecedentConditions = [],
904 \+ \+ (numbervars((AnaphorConditions, AntecedentConditions), 1, _), forall(member(Condition, AntecedentConditions), member(Condition, AnaphorConditions)))
905 ->
906 delete(AntecedentsIn, antecedent(AntecedentID, AntecedentReferent, AntecedentConditions, AntecedentGenus, AntecedentNumerus, AntecedentPerson, AntecedentSID, AntecedentTID, AntecedentTokens), AntecedentsIntermediate),
907 eliminate_spurious_antecedents(AntecedentsIntermediate, AnaphorID, AnaphorConditions, AntecedentsOut)
908 ;
909 AntecedentsOut = AntecedentsIn
910 ).
911
917
918initialise_DRS_nesting_level :-
919 retractall(nesting_level(_)),
920 assert(nesting_level(1)).
921
922
923increase_DRS_nesting_level :-
924 retract(nesting_level(CurrentNestingLevel)),
925 NewNestingLevel is CurrentNestingLevel + 1,
926 assert(nesting_level(NewNestingLevel)).
927
928
929decrease_DRS_nesting_level :-
930 retract(nesting_level(CurrentNestingLevel)),
931 NewNestingLevel is CurrentNestingLevel - 1,
932 assert(nesting_level(NewNestingLevel)),
933 retractall(variable_defined(_VariableName, CurrentNestingLevel, _VariableType)).
934
935
946
947enforce_order(ConditionsIn, ConditionsOut, ConditionsAllIn, ConditionsAllOut, AntecedentsIn, AntecedentsOut) :-
948 949 remove_and_collect_antecedents(ConditionsIn, [], AllAntecedents, [], ConditionsRest),
950 951 sort(AllAntecedents, AllAntecedentsSorted),
952 reverse(AllAntecedentsSorted, AllAntecedentsSortedReversed),
953 (
954 AntecedentsIn = []
955 ->
956 AntecedentsOut = AllAntecedentsSortedReversed
957 ;
958 959 append(AllAntecedentsSortedReversed, [divider_between_DRS_nesting_levels|AntecedentsIn], AntecedentsOut)
960 ),
961 check_for_redefined_variables(AntecedentsOut),
962 963 reverse(ConditionsRest, ConditionsOut),
964 965 append(ConditionsOut, ConditionsAllIn, ConditionsAllOut).
966
967
968remove_and_collect_antecedents([], Antecedents, Antecedents, ConditionsOut, ConditionsOut).
969
970remove_and_collect_antecedents([ConditionIn|ConditionsIn], AntecedentsSofar, Antecedents, ConditionsOutSofor, ConditionsOut) :-
971 (
972 ConditionIn = antecedent(_ID, _Referent, _Conditions, _Genus, _Numerus, _Person, _SentenceID, _TokenID, _Tokens)
973 ->
974 transform_allquantified_nouns(ConditionIn, TransformedConditionIn),
975 remove_and_collect_antecedents(ConditionsIn, [TransformedConditionIn|AntecedentsSofar], Antecedents, ConditionsOutSofor, ConditionsOut)
976 ;
977 978 is_list(ConditionIn)
979 ->
980 981 remove_and_collect_antecedents(ConditionIn, [], NewAntecedents, [], NewConditions),
982 append(NewAntecedents, AntecedentsSofar, NewAntecedentsSofar),
983 remove_and_collect_antecedents(ConditionsIn, NewAntecedentsSofar, Antecedents, [NewConditions|ConditionsOutSofor], ConditionsOut)
984 ;
985 remove_and_collect_antecedents(ConditionsIn, AntecedentsSofar, Antecedents, [ConditionIn|ConditionsOutSofor], ConditionsOut)
986 ).
987
988
989transform_allquantified_nouns(Condition, TransformedCondition) :-
990 991 992 993 (
994 Condition = antecedent(AntecedentID, AntecedentReferent, AntecedentConditions, AntecedentGenus, '$num'(SP, '$pl'), AntecedentPerson, AntecedentSID, AntecedentTID, AntecedentTokens),
995 select(object(Referent, Lemma, countable, na, eq, 1)-AntecedentSID/_, AntecedentConditions, RestAntecedentConditions),
996 Referent == AntecedentReferent
997 ->
998 NewAntecedentConditions = [object(Referent, Lemma, countable, na, geq, 2)-AntecedentSID/_|RestAntecedentConditions],
999 TransformedCondition = antecedent(AntecedentID, AntecedentReferent, NewAntecedentConditions, AntecedentGenus, '$num'(SP, '$pl'), AntecedentPerson, AntecedentSID, AntecedentTID, AntecedentTokens)
1000 ;
1001 TransformedCondition = Condition
1002 ).
1003
1004
1013
1014filter_conditions(ConditionsIn, ConditionsOut) :-
1015 1016 remove_duplicate_conditions(ConditionsIn, ConditionsWithoutDuplicates),
1017 1018 noun_phrase_conjunction_refers_to_itself(ConditionsWithoutDuplicates),
1019 1020 reverse(ConditionsWithoutDuplicates, ConditionsOut).
1021
1022
1023remove_duplicate_conditions(Conditions, ConditionsWithoutDuplicates) :-
1024 remove_duplicate_conditions(Conditions, [], ConditionsWithoutDuplicates).
1025
1026remove_duplicate_conditions([], ConditionsWithoutDuplicates, ConditionsWithoutDuplicates).
1027
1028remove_duplicate_conditions([Condition|RestConditions], Singles, ConditionsWithoutDuplicates) :-
1029 (
1030 1031 Condition = ConditionProper - _/_,
1032 member(DuplicateSimpleCondition, RestConditions),
1033 DuplicateSimpleCondition = DuplicateSimpleConditionProper - _/_,
1034 ConditionProper == DuplicateSimpleConditionProper
1035 ->
1036 remove_duplicate_conditions(RestConditions, Singles, ConditionsWithoutDuplicates)
1037 ;
1038 1039 member(DuplicateComplexCondition, RestConditions),
1040 Condition == DuplicateComplexCondition
1041 ->
1042 remove_duplicate_conditions(RestConditions, Singles, ConditionsWithoutDuplicates)
1043 ;
1044 1045 remove_duplicate_conditions(RestConditions, [Condition|Singles], ConditionsWithoutDuplicates)
1046 ).
1047
1048
1049noun_phrase_conjunction_refers_to_itself(Conditions) :-
1050 (
1051 1052 select(object(Whole,na,countable,na,eq,N)-Sentence/'', Conditions, RestConditions)
1053 ->
1054 1055 1056 findall(1, (subterm(has_part(Whole1,_Part)-Sentence/'', RestConditions), Whole1 == Whole), Branches),
1057 (
1058 1059 length(Branches, N)
1060 ->
1061 true
1062 ;
1063 1064 add_error_message_once(anaphor, Sentence - '', 'Noun phrase conjunction refers anaphorically to itself.', 'Remove anaphoric references from noun phrase conjunction.')
1065 ),
1066 noun_phrase_conjunction_refers_to_itself(RestConditions)
1067 ;
1068 1069 true
1070 ).
1071
1072
1080
1081insert_antecedent(Antecedent, AntecedentsIn, AntecedentsOut) :-
1082 (
1083 1084 member(divider_between_DRS_nesting_levels, AntecedentsIn)
1085 ->
1086 append(Front, [divider_between_DRS_nesting_levels|Tail], AntecedentsIn),
1087 insert_antecedent1(Antecedent, Front, FrontOut),
1088 append(FrontOut, [divider_between_DRS_nesting_levels|Tail], AntecedentsOut)
1089 ;
1090 1091 insert_antecedent1(Antecedent, AntecedentsIn, AntecedentsOut)
1092 ),
1093 check_for_redefined_variables(AntecedentsOut).
1094
1095
1096insert_antecedent1(Antecedent, [], [Antecedent]) :-
1097 !.
1098
1099insert_antecedent1(antecedent(ID1, R1, C1, G1, N1, P1, SID1, TID1, T1), [antecedent(ID2, R2, C2, G2, N2, P2, SID2, TID2, T2)|Antecedents], [antecedent(ID2, R2, C2, G2, N2, P2, SID2, TID2, T2)|AntecedentsIM]) :-
1100 ID1 < ID2,
1101 !,
1102 insert_antecedent1(antecedent(ID1, R1, C1, G1, N1, P1, SID1, TID1, T1), Antecedents, AntecedentsIM).
1103
1104insert_antecedent1(antecedent(ID1, R1, C1, G1, N1, P1, SID1, TID1, T1),[antecedent(ID2, R2, C2, G2, N2, P2, SID2, TID2, T2)|Antecedents], [antecedent(ID1, R1, C1, G1, N1, P1, SID1, TID1, T1), antecedent(ID2, R2, C2, G2, N2, P2, SID2, TID2, T2)|Antecedents]) :-
1105 ID1 >= ID2.
1106
1107
1120
1121match_elements([], _Set).
1122
1123match_elements([Element|Elements], Set) :-
1124 (
1125 1126 Element = object(R1, Noun, countable, na, eq, 1) - _Index1
1127 ->
1128 (
1129 1130 member(object(R2, Noun, countable, na, _Op, 1) - _Index2, Set),
1131 R1 = R2
1132 ;
1133 1134 member(object(R2, Noun, mass, _Unit, _Op, _Count) - _Index2, Set),
1135 R1 = R2
1136 )
1137 ;
1138 1139 Element = object(R1, Noun, countable, na, geq, 2) - _Index1
1140 ->
1141 (
1142 1143 member(object(R2, Noun, countable, na, _Op, N2) - _Index2, Set),
1144 N2 >= 2,
1145 R1 = R2
1146 ;
1147 1148 member(object(R2, Noun, countable, Unit, _Op, _Count) - _Index2, Set),
1149 \+ Unit = na,
1150 R1 = R2
1151 )
1152 ;
1153 1154 Element = modifier_pp(Arg11, Arg12, Arg13) - _Index1
1155 ->
1156 member(modifier_pp(Arg21, Arg22, Arg23) - _Index2, Set),
1157 1158 Arg11 = Arg21,
1159 Arg12 = Arg22,
1160 Arg13 = Arg23
1161 ;
1162 1163 Element = has_part(Whole1, Part1) - _Index1
1164 ->
1165 member(has_part(Whole2, Part2) - _Index2, Set),
1166 1167 Whole1 = Whole2,
1168 Part1 = Part2
1169 ;
1170 1171 Element = Condition1 - _Index1
1172 ->
1173 member(Condition2 - _Index2, Set),
1174 Condition1 = Condition2
1175 ;
1176 1177 Element = antecedent(_, _, _ ,_, _, _, _, _)
1178 ->
1179 true
1180 ;
1181 1182 Element = anaphor(_, _, _ ,_, _, _, _, _, _, _)
1183 ->
1184 true
1185 ;
1186 1187 is_list(Element)
1188 ->
1189 member(List, Set),
1190 is_list(List),
1191 match_elements(Element, List),
1192 match_elements(List, Element)
1193 ;
1194 1195 Element = drs(_Referents1, Conditions1)
1196 ->
1197 member(drs(_Referents2, Conditions2), Set),
1198 match_elements(Conditions1, Conditions2),
1199 match_elements(Conditions2, Conditions1)
1200 ;
1201 1202 Element = - drs(_Referents1, Conditions1)
1203 ->
1204 member(- drs(_Referents2, Conditions2), Set),
1205 match_elements(Conditions1, Conditions2),
1206 match_elements(Conditions2, Conditions1)
1207 ;
1208 1209 Element = ~ drs(_Referents1, Conditions1)
1210 ->
1211 member(~ drs(_Referents2, Conditions2), Set),
1212 match_elements(Conditions1, Conditions2),
1213 match_elements(Conditions2, Conditions1)
1214 ;
1215 1216 Element = can(drs(_Referents1, Conditions1))
1217 ->
1218 member(can(drs(_Referents2, Conditions2)), Set),
1219 match_elements(Conditions1, Conditions2),
1220 match_elements(Conditions2, Conditions1)
1221 ;
1222 1223 Element = must(drs(_Referents1, Conditions1))
1224 ->
1225 member(must(drs(_Referents2, Conditions2)), Set),
1226 match_elements(Conditions1, Conditions2),
1227 match_elements(Conditions2, Conditions1)
1228 ;
1229 1230 Element = should(drs(_Referents1, Conditions1))
1231 ->
1232 member(should(drs(_Referents2, Conditions2)), Set),
1233 match_elements(Conditions1, Conditions2),
1234 match_elements(Conditions2, Conditions1)
1235 ;
1236 1237 Element = may(drs(_Referents1, Conditions1))
1238 ->
1239 member(may(drs(_Referents2, Conditions2)), Set),
1240 match_elements(Conditions1, Conditions2),
1241 match_elements(Conditions2, Conditions1)
1242 ;
1243 Element = question(drs(_Referents1, Conditions1))
1244 ->
1245 member(question(drs(_Referents2, Conditions2)), Set),
1246 match_elements(Conditions1, Conditions2),
1247 match_elements(Conditions2, Conditions1)
1248 ;
1249 Element = command(drs(_Referents1, Conditions1))
1250 ->
1251 member(command(drs(_Referents2, Conditions2)), Set),
1252 match_elements(Conditions1, Conditions2),
1253 match_elements(Conditions2, Conditions1)
1254 ;
1255 1256 Element = _ : drs(_Referents1, Conditions1)
1257 ->
1258 member( _ :(drs(_Referents2, Conditions2)), Set),
1259 match_elements(Conditions1, Conditions2),
1260 match_elements(Conditions2, Conditions1)
1261 ;
1262 1263 Element = drs(_ReferentsP1, ConditionsP1) => drs(_ReferentsC1, ConditionsC1)
1264 ->
1265 member(drs(_ReferentsP2, ConditionsP2) => drs(_ReferentsC2, ConditionsC2), Set),
1266 match_elements(ConditionsP1, ConditionsP2),
1267 match_elements(ConditionsP2, ConditionsP1),
1268 match_elements(ConditionsC1, ConditionsC2),
1269 match_elements(ConditionsC2, ConditionsC1)
1270 ;
1271 1272 1273 Element = drs(_ReferentsD1, ConditionsD1) v DisjunctsRest1
1274 ->
1275 member(drs(_ReferentsD2, ConditionsD2) v DisjunctsRest2, Set),
1276 1277 match_element_against_disjunction(drs(_ReferentsD1, ConditionsD1), drs(_ReferentsD2, ConditionsD2) v DisjunctsRest2),
1278 1279 (
1280 1281 \+ DisjunctsRest1 = drs([], [_ v _])
1282 ->
1283 match_element_against_disjunction(DisjunctsRest1, drs(_ReferentsD2, ConditionsD2) v DisjunctsRest2)
1284 ;
1285 1286 DisjunctsRest1 = drs([], [DisjunctsRest11 v DisjunctsRest12])
1287 ->
1288 match_elements([DisjunctsRest11 v DisjunctsRest12], [drs(_ReferentsD2, ConditionsD2) v DisjunctsRest2])
1289 )
1290 ),
1291 match_elements(Elements, Set).
1292
1293
1294match_element_against_disjunction(drs(_ReferentsD1, ConditionsD1), drs(_ReferentsD2, ConditionsD2) v DisjunctsRest2) :-
1295 1296 (
1297 1298 match_elements(ConditionsD1, ConditionsD2)
1299 ->
1300 true
1301 ;
1302 1303 1304 \+ DisjunctsRest2 = drs([], [_ v _])
1305 ->
1306 match_elements([drs(_ReferentsD1, ConditionsD1)], [DisjunctsRest2])
1307 ;
1308 1309 1310 DisjunctsRest2 = drs([], [DisjunctsRest21 v DisjunctsRest22])
1311 ->
1312 match_element_against_disjunction(drs(_ReferentsD1, ConditionsD1), DisjunctsRest21 v DisjunctsRest22)
1313 ).
1314
1315
1323
1324subterm(Term, Term) :-
1325 nonvar(Term).
1326
1327subterm(Sub,Term):-
1328 nonvar(Term),
1329 functor(Term,_F,N),
1330 N > 0,
1331 subterm(N,Sub,Term).
1332
1333
1334subterm(N,Sub,Term):-
1335 arg(N,Term,Arg),
1336 subterm(Sub,Arg).
1337
1338subterm(N,Sub,Term):-
1339 N>1,
1340 N1 is N-1,
1341 subterm(N1,Sub,Term).
1342
1352
1353subtract_conditions(Difference, [], Difference).
1354
1355subtract_conditions(Conditions1, [Condition2|Conditions2], Difference) :-
1356 (
1357 Condition2 = Condition2C - _,
1358 Condition2C \= formula(_, _, _),
1359 select(Condition - _, Conditions1, RestConditions1),
1360 Condition == Condition2C
1361 ->
1362 subtract_conditions(RestConditions1, Conditions2, Difference)
1363 ;
1364 subtract_conditions(Conditions1, Conditions2, Difference)
1365 ).
1366
1367