1% This file is part of the Attempto Parsing Engine (APE). 2% Copyright 2008-2013, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch). 3% 4% The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it 5% under the terms of the GNU Lesser General Public License as published by the Free Software 6% Foundation, either version 3 of the License, or (at your option) any later version. 7% 8% The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT 9% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 10% PURPOSE. See the GNU Lesser General Public License for more details. 11% 12% You should have received a copy of the GNU Lesser General Public License along with the Attempto 13% Parsing Engine (APE). If not, see http://www.gnu.org/licenses/. 14 15:- module(drs_to_coreace, [ 16 drs_to_coreace/2, 17 bigdrs_to_coreace/2 18 ]).
67:- use_module(morphgen, [ 68 clear_vars/0, 69 add_var/1, 70 remove_singletons/2, 71 listlist_listatom/2, 72 surface_noun/4, 73 surface_verb/3, 74 surface_property/3, 75 surface_property/6, 76 surface_adverb/3, 77 surface_quotedstring/2, 78 get_di_marker/4 79 ]). 80 81:- use_module(drs_utils, [ 82 get_toplevel_object_referents/2 83 ]). 84 85:- use_module(drs_to_drslist, [ 86 drs_to_drslist/2 87 ]). 88 89/* 90:- debug(verbose). 91:- debug(that). 92:- debug(toplevel). 93:- debug(npcoord). 94*/ 95 96% Operators used in the DRS 97:- op(400, fy, -). 98:- op(400, fy, ~). 99:- op(500, xfx, =>). 100:- op(500, xfx, v). 101:- op(500, xfx, '--'). 102 103 104:- dynamic is_rep/1, ref2conds/4. 105 106 107% @tbd rename 108bigdrs_to_coreace(Drs, AceList) :- 109 drs_to_drslist(Drs, DrsList), 110 drslist_to_coreace(DrsList, AceList). 111 112 113drslist_to_coreace([], []). 114 115drslist_to_coreace([Drs | DrsList], [Ace | AceList]) :- 116 drs_to_coreace(Drs, Ace), 117 drslist_to_coreace(DrsList, AceList).
Empty DRS -> [] Unsupported DRS -> [] Supported DRS -> [sentence1, sentence2, ..., sentenceN], where sentence is an atom
131drs_to_coreace(drs([], []), []) :- !. 132 133drs_to_coreace(DRS, AceSentenceList) :- 134 retractall(is_rep(_)), 135 clear_vars, 136 % BUG: why do we need the next line? 137 assert(is_rep(nil)), 138 139 % Make a copy to preserve the variables in the caller. 140 copy_term(DRS, DRSCopy), 141 142 DRSCopy = drs(Dom, ConditionList), 143 144 get_toplevel_object_referents(ConditionList, toplevel(ToplevelReferentList, UnsortedSubjectList, UnsortedObjectList, NamedList)), 145 numbervars(DRSCopy, 0, _), 146 147 drs_to_coreace_nvar_wrapper(drs(Dom, ConditionList), [ToplevelReferentList, UnsortedSubjectList, UnsortedObjectList, NamedList], Result), 148 !, 149 post_process(Result, AceSentenceList), 150 !. 151 152drs_to_coreace(_Drs, []). 153% TODO: Throw an exception 154%drs_to_coreace(Drs, _) :- 155% throw(error('Not implemented', context(drs_to_coreace/2, Drs))).
161drs_to_coreace_nvar_wrapper(Drs, List, Result) :-
162 retractall(ref2conds(_, _, _, _)),
163 reset_counter(box_counter),
164 make_boxid(BoxId),
165 catch(drs_to_coreace_nvar(Drs, BoxId, List, []--_, Result), _, fail).
172post_process -->
173 remove_singletons,
174 find_sentencelist,
175 listlist_listatom.
186drs_to_coreace_nvar(Drs, BoxId, [ToplevelReferentList, UnsortedSubjectList, UnsortedObjectList, NamedList], RI--RO, Result1) :-
187
188 debug(toplevel, "toplevel referents:
189 ToplevelReferentList: ~W
190 UnsortedSubjectList: ~W
191 UnsortedObjectList: ~W
192 NamedList: ~W~n",
193 [ToplevelReferentList, [numbervars(true)], UnsortedSubjectList, [numbervars(true)], UnsortedObjectList, [numbervars(true)], NamedList, [numbervars(true)]]),
194
195 % We assert the DRS conditions.
196 % The DRS itself is not used anymore below.
197 make_ref2conds(Drs, BoxId),
198
199 % The next line means, that we use the `there is' construction
200 % only if needed. If there is a verb that calls a noun
201 % then the noun will not be verbalized by `there is'.
202 findall(Referent, use_there_is(Referent), ThereIsReferents),
203
204 debug(verbose, "ThereIsReferents: ~W~n", [ThereIsReferents, [numbervars(true)]]),
205
206 % Remove syntactic objects because we do not want to use 'there is' with objects.
207 % E.g. There is a cat. John hates the cat. --> John hates a cat.
208 subtract(ToplevelReferentList, UnsortedObjectList, List1),
209
210 % Add syntactic subjects because we want to use 'there is' with subjects.
211 % E.g. A cat sees John. --> There is a cat X1. The cat X1 sees John.
212 append(List1, UnsortedSubjectList, List2),
213
214 % Remove named-objects to avoid e.g. "There is John.", regardless
215 % of whether `John' is later used as a subject or as an object.
216 subtract(List2, NamedList, UnnamedList2),
217
218 % Remove duplicates
219 list_to_set(UnnamedList2, InitialReferents),
220
221 debug(verbose, "InitialReferents: ~w~n", [InitialReferents]),
222
223 append(InitialReferents, ThereIsReferents, List3),
224 list_to_set(List3, Refs),
225 referents_to_orderedreferents(Refs, OrderedRefs),
226
227 debug(verbose, "input to call_referents_to_acetexts/2: ~W~n", [OrderedRefs, [numbervars(true)]]),
228
229 call_referents_to_acetexts(OrderedRefs, RI--RO, Result1).
@tbd The 3rd point needs rethinking.
@param Refs is a list of discourse referents @param OrderedRefs is the list ordered
247referents_to_orderedreferents(Refs, OrderedRefs) :-
248 findall((SentenceId, BoxCounter, N)-Referent, (
249 member(Referent, Refs),
250 ref2conds(Referent, Conditions, id(BoxCounter, _, _), SentenceId),
251 get_orderer(Conditions, N)
252 ), List1),
253 debug(verbose, "Keys : ~W~n", [List1, [numbervars(true)]]),
254 keysort(List1, List2),
255 debug(verbose, "Keys (sorted) : ~W~n", [List2, [numbervars(true)]]),
256 findall(Referent, member(_Key-Referent, List2), OrderedRefs).
It is false that a dog barks and that there is a man.
is paraphrased as:
It is false that there is a man and that a dog barks.
284get_orderer(Conditions, N) :- 285 memberchk(predicate(_, _, '$VAR'(N)), Conditions), 286 !. 287 288get_orderer(Conditions, N) :- 289 memberchk(predicate(_, _, '$VAR'(N1), '$VAR'(N2)), Conditions), 290 !, 291 N is N1 + N2. 292 293get_orderer(Conditions, N) :- 294 memberchk(predicate(_, _, '$VAR'(N1), '$VAR'(N2), '$VAR'(N3)), Conditions), 295 !, 296 N is N1 + N2 + N3. 297 298get_orderer(Conditions, N) :- 299 memberchk(object('$VAR'(N1), _, _, _, _, _), Conditions), 300 N is (-1 * (1 / (N1 + 1))), 301 !. 302 303get_orderer(_Conditions, 0).
311find_sentencelist([], []). 312 313find_sentencelist(TokenList, [Sentence | SentenceList]) :- 314 find_sentence(TokenList, Sentence, RestTokenList), 315 find_sentencelist(RestTokenList, SentenceList).
324find_sentence(['.' | RestTokenList], [], RestTokenList) :- !. 325 326find_sentence([Token | RestTokenList], [Token | RestSentence], RestTokenList2) :- 327 find_sentence(RestTokenList, RestSentence, RestTokenList2).
Referent is toplevel if:
The 3rd clause was added to correctly paraphrase: There is a man who does not sleep. John sees the man.
@param Referent is a discourse referent
346use_there_is(Referent) :- 347 ref2conds(Referent, [Condition | ConditionList], BoxId, _SentenceId), 348 \+ is_called(Referent, [Condition | ConditionList], BoxId, _). 349 350% Handles the case: There is a man who does not sleep. John sees the man. 351use_there_is(Referent) :- 352 toplevel_id(ToplevelId), 353 % Referent is top-level 354 ref2conds(Referent, [Condition | ConditionList], ToplevelId, _SId1), 355 % Referent is called by a top-level referent. 356 is_called(Referent, [Condition | ConditionList], ToplevelId, SId2), 357 % Referent is called from an embedded box. 358 is_called(Referent, [Condition | ConditionList], BoxId, SId3), 359 \+ toplevel_id(BoxId), 360 % The embedded box is introduced before the other caller (in terms of the sentence Id). 361 SId3 < SId2.
368toplevel_id(id(0, top, [])).
380is_called(Referent, _, BoxId, SentenceId) :-
381 ref2conds(Referent2, ConditionList, BoxId, SentenceId),
382 Referent \= Referent2,
383 member(Condition, ConditionList),
384 Condition \= formula(_, _, _),
385 arg(Num, Condition, Referent),
386 Num > 1.
395call_referents_to_acetexts(RefList, RI--RO, Result) :-
396 (
397 referents_to_acetexts(RefList, RI--RO, ACETexts)
398 ->
399 flatten(ACETexts, Result)
400 ;
401 Result = []
402 ).
411referents_to_acetexts([], RI--RI, '.'). 412 413referents_to_acetexts([Referent | ReferentsTail], RI--RO, [Text | TextTail]) :- 414 debug(verbose, "used referents: ~W~n", [RI, [numbervars(true)]]), 415 referent_text(Referent, top, RI--RTmp, Text, _), 416 debug(verbose, "top referent: ~W; text: ~W; used referents: ~W~n", [Referent, [numbervars(true)], Text, [numbervars(true)], RTmp, [numbervars(true)]]), 417 !, 418 referents_to_acetexts(ReferentsTail, RTmp--RO, TextTail).
429referent_text(Referent, RI--RO, Text, Features) :- 430 referent_text(Referent, deep, RI--RO, Text, Features). 431 432 433referent_text(named(Name), _, RI--RI, NameText, f(SgPl, _)) :- 434 surface_noun(pn, Name, SgPl, NameText), 435 !. 436 437% Recursively call drs_to_coreace_nvar on the embedded DRS. 438referent_text(Referent, deep, RI--RO, [that | SentenceListCoord], _) :- 439 ref2conds(Referent, [Referent:drs(Dom, CondList)], _BoxId, _SentenceId), 440 debug(that, "THAT: drs: ~W~n", [drs(Dom, CondList), [numbervars(true)]]), 441 retractall(ref2conds(_, _, _, _)), 442 reset_counter(box_counter), 443 make_boxid(NewBoxId), 444 drs_to_coreace_nvar(drs(Dom, CondList), NewBoxId, [[], [], [], []], RI--RO, Result), 445 debug(that, "THAT: result: ~q~n", [Result]), 446 find_sentencelist(Result, [_Ignore_BUG | SentenceList]), 447 debug(that, "THAT: sentence(s): ~W~n", [SentenceList, [numbervars(true)]]), 448 sentencelist_sentencelistcoord(SentenceList, SentenceListCoord). 449 450referent_text(formula(Expr1, Eq, Expr2), top, RI--RO, [BoxMarker, Expr1Text, Eq, Expr2Text], _) :- 451 !, 452 expr_exprpp(Expr1, RI--RTmp, Expr1Text), 453 expr_exprpp(Expr2, RTmp--RO, Expr2Text), 454 ref2conds(formula(Expr1, Eq, Expr2), _, BoxId, _SentenceId), 455 get_box_prefix(BoxId, BoxMarker). 456 457% Support for query pronouns: 'who' and 'what'. 458% Note: 'how' and 'which' are not covered by this rule. 459% Note: the question mark is added later. 460% Note: we only support top-level query-conditions. 461% Note: this rule generates "there is who?" and never "there are who?" 462referent_text(Referent, TopDeep, RI--[Referent | RI], [ThereIs, QueryWord], _Features) :- 463 toplevel_id(ToplevelId), 464 ref2conds(Referent, [Query], ToplevelId, _SentenceId), 465 query(Referent, Query, _, QueryWord), 466 get_box_prefix(ToplevelId, BoxPrefix), 467 get_thereis(TopDeep, sg, BoxPrefix, ThereIs), 468 \+ memberchk(Referent, RI). 469 470referent_text(Referent, TopDeep, RI--RO, Text, Features) :- 471 get_type(Referent, Type, BoxId), 472 get_box_prefix(BoxId, BoxPrefix), 473 debug(that, 'referent_text: ~W ~W ~w ~w~n', [Referent, [numbervars(true)], Type, [numbervars(true)], BoxId, BoxPrefix]), 474 !, 475 conds_text(Type, BoxPrefix, TopDeep, RI--RO, Text, Features), 476 debug(verbose, "referent_text_out: ~W; used referents: ~W~n", [Text, [numbervars(true)], RO, [numbervars(true)]]). 477 478referent_text(Expression, deep, RI--RO, ExpressionText, f(sg, _)) :- 479 expr_exprpp(Expression, RI--RO, ExpressionText).
492get_type(Referent, Type, BoxId) :-
493 ref2conds(Referent, Conditions, BoxId, _SentenceId),
494 conditions_type(Conditions, Type).
508conditions_type(Conditions, noun(Mains, parts(Parts), owners(Owners), adjectives(Adjectives))) :- 509 member(Condition, Conditions), 510 functor(Condition, object, _), 511 !, 512 conditions_nountype(Conditions, Mains, Parts, Owners, Adjectives). 513 514conditions_type(Conditions, verb(Predicates, adverbs(Adverbs), pps(PPs))) :- 515 member(Condition, Conditions), 516 is_predicate(Condition), 517 !, 518 conditions_verbtype(Conditions, Predicates, Adverbs, PPs). 519 520conditions_type(Conditions, Conditions).
531conditions_nountype([], [], [], [], []). 532 533conditions_nountype([H | T], Mains, [Part | Parts], Owners, Adjectives) :- 534 H = has_part(_, Part), 535 !, 536 conditions_nountype(T, Mains, Parts, Owners, Adjectives). 537 538conditions_nountype([H | T], Mains, Parts, [H | Owners], Adjectives) :- 539 functor(H, relation, _), 540 !, 541 conditions_nountype(T, Mains, Parts, Owners, Adjectives). 542 543conditions_nountype([H | T], Mains, Parts, Owners, [H | Adjectives]) :- 544 functor(H, Functor, _), 545 ( 546 Functor = property 547 ; 548 Functor = query 549 ), 550 !, 551 conditions_nountype(T, Mains, Parts, Owners, Adjectives). 552 553% BUG: Here we convert those atoms that are in fact numbers (e.g. '5') into actual numbers (e.g. 5). 554% APE does not generate such "atom numbers", but other DRS generators might. 555conditions_nountype( 556 [object(Referent, Value, Quantisation, Unit, Operator, Count) | T], 557 [object(Referent, Value, Quantisation, Unit, Operator, NCount) | Mains], Parts, Owners, Adjectives 558 ) :- 559 atom(Count), Count \= na, 560 !, 561 atom_number(Count, NCount), 562 conditions_nountype(T, Mains, Parts, Owners, Adjectives). 563 564% Fall back: other conditions go to Mains. 565conditions_nountype([H | T], [H | Mains], Parts, Owners, Adjectives) :- 566 conditions_nountype(T, Mains, Parts, Owners, Adjectives).
576conditions_verbtype([], [], [], []). 577 578conditions_verbtype([H | T], Predicates, [H | Adverbs], PPs) :- 579 functor(H, Functor, _), 580 ( 581 Functor = modifier_adv 582 ; 583 Functor = query 584 ), 585 !, 586 conditions_verbtype(T, Predicates, Adverbs, PPs). 587 588conditions_verbtype([H | T], Predicates, Adverbs, [H | PPs]) :- 589 functor(H, Functor, _), 590 ( 591 Functor = modifier_pp 592 ), 593 !, 594 conditions_verbtype(T, Predicates, Adverbs, PPs). 595 596% Fall back: other conditions go to Predicates. 597conditions_verbtype([H | T], [H | Predicates], Adverbs, PPs) :- 598 conditions_verbtype(T, Predicates, Adverbs, PPs).
611counter(Name, N) :-
612 catch(
613 (nb_getval(Name, N0), succ(N0, N), nb_setval(Name, N)),
614 _,
615 (N = 1, nb_setval(Name, N))
616 ).
625reset_counter(Name) :-
626 nb_setval(Name, 0).
635make_ref2conds(drs(Dom, Conds), BoxId) :-
636 assert_referents(Dom, Conds, BoxId),
637 process_conds(Conds, BoxId).
ref2conds/4
containing
information about the shared Referent, the conditions that share the Referent,
and the DRS-box ID.
Finally processes separately the remaining conditions: in case the remaining
conditions have the form formula/3 then they are asserted as they are.
In case the remaining conditions are complex conditions then they are just ignored.
Otherwise (e.g. in case of relation/3) a failure is triggered.
flatten/3 is used to remove the DRS embedded lists
659assert_referents([], Conditions, BoxId) :- 660 assert_rest(Conditions, BoxId). 661 662assert_referents([Referent | ReferentsTail], Conditions, BoxId) :- 663 flatten(Conditions, FlatConditions), 664 mypartition(Referent, FlatConditions, Included, Excluded, Id), 665 assert(ref2conds(Referent, Included, BoxId, Id)), 666 assert_referents(ReferentsTail, Excluded, BoxId). 667 668 669first_argument_is_referent(Referent, Condition) :- 670 Condition \= formula(_, _, _), 671 arg(1, Condition, Referent).
677mypartition(_Referent, [], [], [], _). 678 679mypartition(Referent, [Condition-STId | Conditions], [Condition | Included], Excluded, SId) :- 680 first_argument_is_referent(Referent, Condition), 681 !, 682 get_sentence_id(STId, SId), 683 mypartition(Referent, Conditions, Included, Excluded, SId). 684 685mypartition(Referent, [ConditionWithId | Conditions], Included, [ConditionWithId | Excluded], SId) :- 686 mypartition(Referent, Conditions, Included, Excluded, SId).
692assert_rest([], _). 693 694assert_rest([formula(Expr1, Eq, Expr2)-STId | CondList], BoxId) :- 695 get_sentence_id(STId, SId), 696 assert(ref2conds(formula(Expr1, Eq, Expr2), [formula(Expr1, Eq, Expr2)], BoxId, SId)), 697 assert_rest(CondList, BoxId). 698 699assert_rest([relation(_, _, _)-_ | _CondList], _BoxId) :- 700 !, 701 fail. 702 703assert_rest([has_part(_, _)-_ | _CondList], _BoxId) :- 704 !, 705 fail. 706 707assert_rest([_Cond | CondList], BoxId) :- 708 assert_rest(CondList, BoxId).
The conditions are first sorted to make sure that less complex conditions (e.g. negations) are verbalized before more complex ones (e.g. implications).
722process_conds(Cs, BoxId) :- 723 sort(Cs, CsSorted), 724 process_conds_loop(CsSorted, BoxId). 725 726 727process_conds_loop([], _). 728 729process_conds_loop([C | Cs], BoxId) :- 730 walk_cond(C, BoxId), 731 process_conds_loop(Cs, BoxId).
739walk_cond(_-_, _). % ignoring simple conditions 740 741walk_cond([C | Cs], _BoxId) :- 742 include(is_complex_or_predicate, [C | Cs], Predicates), 743 length(Predicates, Len), 744 Len > 1, 745 !, 746 throw(error('Predicate group is too complex', context(walk/2, Predicates))). 747 748walk_cond([C | Cs], BoxId) :- 749 !, 750 process_conds([C | Cs], BoxId). 751 752walk_cond(question(drs(QDom, QConds)), BoxId) :- 753 !, 754 memberchk(query(_, _)-_, QConds), 755 assert_referents(QDom, QConds, BoxId), 756 process_conds(QConds, BoxId). 757 758walk_cond(Label:drs(Dom, Conds), BoxId) :- 759 !, 760 assert(ref2conds(Label, [Label:drs(Dom, Conds)], BoxId, 'BUG')). 761 762% BUG: handling of relation/3 alone in the then-box 763% IN: A dog of every man who waits barks. 764% OUT: A dog that every man who waits OF-RELATION barks. 765% BUG: UniqueRef should actually be a numbervard variable 766walk_cond(drs(Dom1, Conds) => drs([], [relation(Owned, of, Owner)-STId]), ParentBoxId) :- 767 !, 768 make_boxid(if, ParentBoxId, BoxId1), 769 assert_referents(Dom1, Conds, BoxId1), 770 process_conds(Conds, BoxId1), 771 make_boxid(then, ParentBoxId, BoxId2), 772 counter(ref, UniqueRef), 773 assert_referents([UniqueRef], [predicate(UniqueRef, 'OF-RELATION', Owner, Owned)-STId], BoxId2). 774 775walk_cond(drs(Dom1, Conds1) => drs(Dom2, Conds2), ParentBoxId) :- 776 make_boxid(if, ParentBoxId, BoxId1), 777 assert_referents(Dom1, Conds1, BoxId1), 778 process_conds(Conds1, BoxId1), 779 make_boxid(then, ParentBoxId, BoxId2), 780 assert_referents(Dom2, Conds2, BoxId2), 781 process_conds(Conds2, BoxId2). 782 783% Every disjunction has two DRSs. If the first DRS 784% is complex (e.g. implication, negation, ...) then the conditions 785% of the second DRS cannot share discourse referents with it. 786% This property allows us to safely change the order the DRSs providing 787% a more readable paraphrase and/or avoiding scope problems, 788% e.g. naively paraphrasing 789% {Every man eats} or John drinks. 790% as 791% If there is a man X1 then {the man X1 eats or John drinks}. 792% 793% @tbd We could relax the requirement that a complex condition 794% must contain a single condition that embeds a DRS. Instead we should 795% simply require that the OR boxes do not share variables that are 796% not declared on a higher level. Unfortunately at this stage we have 797% already numbervared the variables which makes this check difficult to implement. 798% So we currently only check that the variables-list is empty in the 1st DRS 799% but non-empty in the 2nd. 800walk_cond(drs([], Conds1) v Drs2, BoxId) :- 801 Drs2 = drs([_|_], _), 802 !, 803 walk_cond(Drs2 v drs([], Conds1), BoxId). 804 805walk_cond(drs(Dom1, Conds1) v drs(Dom2, Conds2), ParentBoxId) :- 806 make_boxid(or1, ParentBoxId, BoxId1), 807 assert_referents(Dom1, Conds1, BoxId1), 808 process_conds(Conds1, BoxId1), 809 make_boxid(or2, ParentBoxId, BoxId2), 810 assert_referents(Dom2, Conds2, BoxId2), 811 process_conds(Conds2, BoxId2). 812 813walk_cond(Cond, ParentBoxId) :- 814 parse_unary(Cond, Type, Dom, Conds), 815 !, 816 make_boxid(Type, ParentBoxId, BoxId), 817 assert_referents(Dom, Conds, BoxId), 818 process_conds(Conds, BoxId). 819 820 821% @tbd document 822make_boxid(ToplevelId) :- 823 toplevel_id(ToplevelId). 824make_boxid(Type, ParentBoxId, id(Id, Type, ParentBoxId)) :- 825 counter(box_counter, Id).
In case no Referent from a given box has been verbalized, then the current Referent is the first one and we initiate the box. Then we check the outer box to come up for the name of the box (and do this recursively).
841% Not the first Referent in the top-box to be verbalized. 842get_box_prefix(ToplevelId, ['.']) :- 843 toplevel_id(ToplevelId), 844 is_rep(0), 845 !. 846 847% First Referent in the top-box to be verbalized. 848get_box_prefix(ToplevelId, []) :- 849 toplevel_id(ToplevelId), 850 assert(is_rep(0)), 851 !. 852 853% Not the first Referent in the OR1-box to be verbalized. 854% Given that the OR1 V OR2 is in the NOT-box. 855% Ex?: It is false that there is a cat and that there is a mouse or that there is a dog. 856get_box_prefix(id(Id, or1, id(_, Marker, _)), [and, that]) :- 857 is_unary_modifier(Marker), 858 is_rep(Id), 859 !. 860 861% Not the first Referent in the NOT-box to be verbalized. 862get_box_prefix(id(Id, Marker, _), [and, that]) :- 863 is_unary_modifier(Marker), 864 is_rep(Id), 865 !. 866 867% BUG: ??? 868% Not the first Referent in the any box to be verbalized. 869get_box_prefix(id(Id, _, _), [and]) :- 870 is_rep(Id), 871 !. 872 873% The first Referent in the THEN-box to be verbalized. 874get_box_prefix(id(Id, then, _), [then]) :- 875 assert(is_rep(Id)), 876 !. 877 878% The first Referent in the OR2-box to be verbalized. 879% Given that the OR1 V OR2 is in the NOT-box. 880% BUG: do we have to worry about any higher-level NOT-boxes 881% or is checking just for the parent NOT-box OK? 882% Ex: It is false that there is a cat or that there is a dog. 883get_box_prefix(id(Id, or2, id(_, Marker, _)), [or, that]) :- 884 is_unary_modifier(Marker), 885 assert(is_rep(Id)), 886 !. 887 888% The first Referent in the OR1-box. 889% The parent is the NOT-box. 890% The parent has already a Referent. 891% @tbd Examples 892get_box_prefix(id(Id, or1, id(ParentId, Marker, _)), [',', and, that]) :- 893 is_unary_modifier(Marker), 894 is_rep(ParentId), 895 assert(is_rep(Id)), 896 !. 897 898% The first Referent in the OR1-box. 899% The parent is not the NOT-box and is not the top-box. 900% The parent has already a Referent. 901get_box_prefix(id(Id, or1, id(ParentId, _, _)), [',', and]) :- 902 ParentId \= 0, 903 is_rep(ParentId), 904 assert(is_rep(Id)), 905 !. 906 907% The first Referent in the OR2-box to be verbalized. 908% Given that the parent is not a NOT-box. 909get_box_prefix(id(Id, or2, _), [or]) :- 910 assert(is_rep(Id)), 911 !. 912 913% The general case. The first Referent to be verbalized in either: 914% IF-box, OR1-box, NOT-box. 915get_box_prefix(id(Id, BoxMarker, OuterBoxId), [OuterBoxPrefix | BoxPrefix]) :- 916 assert(is_rep(Id)), 917 get_box_name(BoxMarker, BoxPrefix), 918 get_box_prefix(OuterBoxId, OuterBoxPrefix).
925is_unary_modifier(not). 926is_unary_modifier(naf). 927is_unary_modifier(can). 928is_unary_modifier(must). 929is_unary_modifier(should). 930is_unary_modifier(may).
940get_box_name(if, [if]). 941%%get_box_name(then, [then]). 942get_box_name(or1, []). 943%%get_box_name(or2, [or]). 944get_box_name(not, [it, is, false, that]). 945get_box_name(naf, [it, is, not, provable, that]). 946get_box_name(can, [it, is, possible, that]). 947get_box_name(must, [it, is, necessary, that]). 948get_box_name(should, [it, is, recommended, that]). 949get_box_name(may, [it, is, admissible, that]).
Note: some objects can have an owner, but in this case max 1 owner. ProperName objects cannot have an owner.
967% Old somebody and something are referred to by a variable only. 968conds_text(noun([object(A, somebody, countable, na, eq, 1)], parts([]), owners([]), adjectives([])), _, deep, RI--RI, [A], f(sg, _)) :- 969 memberchk(A, RI), 970 add_var(A), 971 !. 972 973conds_text(noun([object(A, something, dom, na, na, na)], parts([]), owners([]), adjectives([])), _, deep, RI--RI, [A], f(sg, _)) :- 974 memberchk(A, RI), 975 add_var(A), 976 !. 977 978 979% New somebody and something (with 'there is') 980conds_text(noun([object(A, somebody, countable, na, eq, 1)], parts([]), owners([]), adjectives([])), 981BoxPrefix, top, RI--[A | RI], [BoxPrefix, there, is, somebody, A], f(sg, _)) :- 982 \+ memberchk(A, RI), 983 add_var(A), 984 !. 985 986conds_text(noun([object(A, something, dom, na, na, na)], parts([]), owners([]), adjectives([])), 987BoxPrefix, top, RI--[A | RI], [BoxPrefix, there, is, something, A], f(sg, _)) :- 988 \+ memberchk(A, RI), 989 add_var(A), 990 !. 991 992% New somebody and something. 993conds_text(noun([object(A, somebody, countable, na, eq, 1)], parts([]), owners([]), adjectives([])), _, deep, RI--[A | RI], [somebody, A], f(sg, _)) :- 994 \+ memberchk(A, RI), 995 add_var(A), 996 !. 997 998conds_text(noun([object(A, something, dom, na, na, na)], parts([]), owners([]), adjectives([])), _, deep, RI--[A | RI], [something, A], f(sg, _)) :- 999 \+ memberchk(A, RI), 1000 add_var(A), 1001 !. 1002 1003 1004% NP conjunction. This is the only case where parts/1 has a non-empty list as an argument 1005% Old plural object, refer to it by 'they' (and 'them'). E.g. 1006% John and Mary wait. They talk. 1007% John and Mary wait. Bill sees them. 1008% * John and Mary wait. John and Mary talk. (this is not supported by refres) 1009% 1010% BUG: `them' is not supported 1011conds_text(noun([object(A, na, countable, _, _, _)], parts([_ | _]), _Owner, _Adjectives), _BoxPrefix, deep, RI--RI, [they], f(pl, subj)) :- 1012 memberchk(A, RI), 1013 !. 1014 1015conds_text(noun([object(A, na, countable, _, _, _)], parts([_ | _]), _Owner, _Adjectives), _BoxPrefix, deep, RI--RI, [them], f(pl, obj)) :- 1016 memberchk(A, RI), 1017 !. 1018 1019% NP conjunction. 1020% Note that we require that parts/1 has a non-empty list as an argument and that the number of 1021% arguments matches the number specified in the object-condition (QNum). 1022% In the DRSs generated by APE, this is not always the case. Consider DRSs where the 1023% has_part/2 condition is embedded into negation, such as the ones generated from: 1024% There are less than 3 men and less than 3 women. 1025% Less than 3 men and John wait. 1026conds_text(noun([object(A, na, countable, _, eq, QNum)], parts(ListOfObjects), _Owner, _Adjectives), BoxPrefix, TopDeep, RI--RO, [Prefix, ListOfObjectsText], f(pl, _)) :- 1027 !, 1028 debug(npcoord, 'npcoord: QNum: ~w; ListOfObjects: ~w~n', [QNum, ListOfObjects]), 1029 length(ListOfObjects, QNum), 1030 surface_det(A, RI, pl, TopDeep, BoxPrefix, countable, dummy, dummy, Prefix), 1031 objects_to_text(ListOfObjects, [A | RI]--RO, ListOfObjectsText), 1032 debug(verbose, 'top:~w prefix:~w result:~w~n', [TopDeep, BoxPrefix, Prefix]). 1033 1034% Plural `which' 1035% Example: which men wait? 1036% Example: there are which men of John? 1037% `how many' (+ plural noun) 1038% Example: how many men wait? 1039% Example: there are how many men of John? 1040conds_text(noun([object(A, Agent, countable, na, geq, 2)], parts([]), Owner, adjectives([Query])), 1041BoxPrefix, TopDeep, RI--RO, [ThereIs, QueryWord, AgentText, OwnerText], f(pl, _)) :- 1042 query(A, Query, pl, QueryWord), 1043 !, 1044 \+ memberchk(A, RI), 1045 toplevel_id(ToplevelId), 1046 ref2conds(A, _, ToplevelId, _SentenceId), 1047 get_thereis(TopDeep, pl, BoxPrefix, ThereIs), 1048 surface_noun(cn, Agent, pl, AgentText), 1049 verbalize_owners(A, RI--RO, Owner, OwnerText). 1050 1051% BUG: temporary handling of "less than" and "at most" 1052conds_text(noun([object(_, _, countable, na, na, na)], parts([]), _, adjectives(_)), _, _, _, _, _) :- 1053 !, 1054 fail. 1055 1056conds_text(noun([object(A, Agent, countable, na, Comp, Number)], parts([]), Owner, adjectives(Adjectives)), 1057 BoxPrefix, TopDeep, RI--RO, [SurfaceDeterminer, AdjectivesText, AgentText, A, OwnerText], f(pl, _)) :- 1058 (Number = 0 ; Number > 1), 1059 surface_det(A, RI, pl, TopDeep, BoxPrefix, countable, Comp, Number, SurfaceDeterminer), 1060 surface_noun(cn, Agent, pl, AgentText), 1061 conds_to_andlist(adjective_to_text, Adjectives, AdjectivesText), 1062 verbalize_owners(A, RI--RO, Owner, OwnerText), 1063 add_var(A). 1064 1065 1066% Singular and mass nouns 1067% 1068% 1. Indefinite pronouns (somebody, something) can have owners but not properties. 1069% 1070% Everything of John is red. 1071% If there is something B of John then B is red. 1072% 1073% Note that this wouldn't work with quoted strings since they cannot have attached variables: 1074% 1075% Everything "Go!" of John is red. -> If there is something "Go!" of John then ??? is red. 1076% 1077% (Fortunately we don't support quoted strings in apposition anymore.) 1078% 1079% 2. Regular nouns 1080% 3. BUG: measurement nouns 1081 1082% If there is somebody of John then ... 1083conds_text(noun([object(A, Value, _, _, _, _)], parts([]), Owner, _Adjectives), BoxPrefix, top, 1084 RI--RO, [BoxPrefix, there, is, Value, A, OwnerText], f(sg, _)) :- 1085 (Value = somebody ; Value = something), 1086 verbalize_owners(A, RI--RO, Owner, OwnerText), 1087 add_var(A). 1088 1089 1090% somebody of John waits ... 1091conds_text(noun([object(A, Value, _, _, _, _)], parts([]), Owner, _Adjectives), _BoxPrefix, deep, 1092 RI--RO, [Name, A, OwnerText], f(sg, _)) :- 1093 (Value = somebody ; Value = something), 1094 ( 1095 memberchk(A, RI) 1096 -> 1097 Name = [] 1098 ; 1099 Name = Value 1100 ), 1101 verbalize_owners(A, RI--RO, Owner, OwnerText), 1102 add_var(A). 1103 1104 1105% Singular `which' 1106% (Note that `which' is not possible with mass nouns, qeneralized quantifiers, 1107% and indefinite pronouns.) 1108% Which man waits? 1109% There is which man of John? 1110conds_text(noun([object(A, Agent, countable, na, eq, 1)], parts([]), Owner, adjectives([Query])), 1111BoxPrefix, TopDeep, RI--RO, [ThereIs, QueryWord, AgentText, OwnerText], f(sg, _)) :- 1112 query(A, Query, sg, QueryWord), 1113 !, 1114 \+ memberchk(A, RI), 1115 toplevel_id(ToplevelId), 1116 ref2conds(A, _, ToplevelId, _SentenceId), 1117 get_thereis(TopDeep, sg, BoxPrefix, ThereIs), 1118 surface_noun(cn, Agent, sg, AgentText), 1119 verbalize_owners(A, RI--RO, Owner, OwnerText). 1120 1121 1122% 'how much' (+ mass noun) 1123% Example: John eats how much food? 1124conds_text(noun([object(A, Agent, mass, na, na, na)], parts([]), Owner, adjectives([Query])), 1125BoxPrefix, TopDeep, RI--RO, [ThereIs, QueryWord, AgentText, OwnerText], f(sg, _)) :- 1126 query(A, Query, mass, QueryWord), 1127 !, 1128 \+ memberchk(A, RI), 1129 toplevel_id(ToplevelId), 1130 ref2conds(A, _, ToplevelId, _SentenceId), 1131 get_thereis(TopDeep, sg, BoxPrefix, ThereIs), 1132 surface_noun(cn, Agent, mass, AgentText), 1133 verbalize_owners(A, RI--RO, Owner, OwnerText). 1134 1135 1136% Countable: a man 1137conds_text(noun([object(A, Agent, countable, na, eq, 1)], parts([]), Owner, adjectives(Adjectives)), 1138 BoxPrefix, TopDeep, RI--RO, [SurfaceDeterminer, AdjectivesText, AgentText, A, OwnerText], f(sg, _)) :- 1139 surface_noun(cn, Agent, sg, AgentText), 1140 conds_to_andlist(adjective_to_text, Adjectives, AdjectivesText), 1141 surface_det(A, RI, sg, TopDeep, BoxPrefix, countable, _, _, SurfaceDeterminer), 1142 verbalize_owners(A, RI--RO, Owner, OwnerText), 1143 add_var(A). 1144 1145 1146% Countable: At least 1 man 1147conds_text(noun([object(A, Value, countable, na, Eq, 1)], parts([]), Owner, adjectives(Adjectives)), 1148 BoxPrefix, TopDeep, RI--RO, [SurfaceDeterminer, AdjectivesText, AgentText, A, OwnerText], f(sg, _)) :- 1149 Eq \= eq, 1150 surface_noun(cn, Value, sg, AgentText), 1151 conds_to_andlist(adjective_to_text, Adjectives, AdjectivesText), 1152 surface_det(A, RI, sg, TopDeep, BoxPrefix, countable, Eq, 1, SurfaceDeterminer), 1153 verbalize_owners(A, RI--RO, Owner, OwnerText), 1154 add_var(A). 1155 1156 1157% Mass: some rice 1158conds_text(noun([object(A, Agent, mass, na, na, na)], parts([]), Owner, adjectives(Adjectives)), 1159BoxPrefix, TopDeep, RI--RO, [SurfaceDeterminer, AdjectivesText, AgentText, A, OwnerText], f(sg, _)) :- 1160 surface_noun(cn, Agent, mass, AgentText), 1161 conds_to_andlist(adjective_to_text, Adjectives, AdjectivesText), 1162 surface_det(A, RI, sg, TopDeep, BoxPrefix, mass, _, _, SurfaceDeterminer), 1163 verbalize_owners(A, RI--RO, Owner, OwnerText), 1164 add_var(A). 1165 1166% Measurement constructs, e.g. 1167% More than 3 kg of white rice rots. 1168% 2 kg of water boils. The water is warm. 1169% 2 kg of apples are ripe. The apples rot. 1170conds_text(noun([object(A, Agent, Quant, Unit, QType, QNum)], parts([]), Owner, adjectives(Adjectives)), 1171BoxPrefix, TopDeep, RI--RO, [ThereIs, Specifier, AdjectivesText, AgentText, A, OwnerText], f(SgPl, _)) :- 1172 (Unit \= na), 1173 ( 1174 Quant = countable 1175 -> 1176 SgPl = pl 1177 ; 1178 SgPl = sg 1179 ), 1180 ( 1181 memberchk(A, RI) 1182 -> 1183 ThereIs = [], 1184 surface_determiner(old, _, _, Specifier), 1185 RO = RI, 1186 OwnerText = [] 1187 ; 1188 get_thereis(TopDeep, SgPl, BoxPrefix, ThereIs), 1189 surface_determiner(new, QType, QNum, Q), 1190 Specifier = [Q, Unit, of], 1191 verbalize_owners(A, RI--RO, Owner, OwnerText) 1192 ), 1193 conds_to_andlist(adjective_to_text, Adjectives, AdjectivesText), 1194 surface_noun(cn, Agent, SgPl, AgentText), 1195 add_var(A). 1196 1197 1198% Intransitive verbs with (adverb | pp)* attachment. 1199conds_text(verb([predicate(_, Predicate, Argument)], adverbs(Adverbs), pps(PPs)), Box, _, 1200 RI--RO, [Box, ArgumentText, PredicateText, AdverbsText, PPsText], _) :- 1201 referent_text(Argument, RI--RTmp, ArgumentText, f(SgPl, subj)), 1202 surface_verb(SgPl, Predicate, PredicateText), 1203 conds_to_andlist(adverb_to_text, Adverbs, AdverbsText), 1204 pps_to_text(PPs, RTmp--RO, PPsText). 1205 1206% Transitive verbs with (adverb | pp)* attachment. 1207% BUG: Comment is currently not returned. 1208conds_text(verb([predicate(_, Predicate, Argument1, Argument2)], adverbs(Adverbs), pps(PPs)), Box, _, 1209 RI--RO, [Box, Argument1Text, PredicateText, Argument2Text, AdverbsText, PPsText], _) :- 1210 debug(verbose, "transitive verb: referents in: ~W~n", [RI, [numbervars(true)]]), 1211 referent_text(Argument1, RI--RTmp1, Argument1Text, f(SgPl, subj)), 1212 surface_verb(SgPl, Predicate, PredicateText), 1213 referent_text(Argument2, RTmp1--RTmp2, Argument2Text, f(_, obj)), 1214 conds_to_andlist(adverb_to_text, Adverbs, AdverbsText), 1215 pps_to_text(PPs, RTmp2--RO, PPsText), 1216 make_comment(PredicateText, PPsText, _Comment). 1217 1218% Ditransitive verbs with (adverb | pp)* attachment. 1219% Note: the order of calling referent_text/4 is important as assert/1 is performed by this call. 1220% Test it with "A man gives a dog the dog.", in the paraphrase the order of indef-NP and def-NP must be correct. 1221% 1222conds_text(verb([predicate(_, Lemma, Argument1, Argument2, Argument3)], adverbs(Adverbs), pps(PPs)), Box, _, 1223 RI--RO, DiText, _) :- 1224 referent_text(Argument1, RI--RTmp1, Argument1Text, f(SgPl, subj)), 1225 get_di_marker(SgPl, Lemma, SurfaceForm, DiMarker), 1226 di_text(DiMarker, RTmp1--RTmp2, Box, Argument1Text, SurfaceForm, Argument2, Argument3, AdverbsText, PPsText, DiText), 1227 conds_to_andlist(adverb_to_text, Adverbs, AdverbsText), 1228 pps_to_text(PPs, RTmp2--RO, PPsText). 1229 1230 1231% Properties as copula arguments. 1232% Must have at least 1 element. 1233conds_text([FirstProperty | RestProperties], _, _, RI--RO, [PropertiesText], _) :- 1234 properties_to_text([FirstProperty | RestProperties], RI--RO, PropertiesText).
1242di_text('', RI--RO, Box, Argument1Text, PredicateText, Argument2, Argument3, AdverbsText, PPsText, [Box, Argument1Text, PredicateText, Argument3Text, Argument2Text, AdverbsText, PPsText]) :- 1243 !, 1244 referent_text(Argument3, RI--RTmp, Argument3Text, f(_, obj)), 1245 referent_text(Argument2, RTmp--RO, Argument2Text, f(_, obj)). 1246 1247di_text(Marker, RI--RO, Box, Argument1Text, PredicateText, Argument2, Argument3, AdverbsText, PPsText, [Box, Argument1Text, PredicateText, Argument2Text, Marker, Argument3Text, AdverbsText, PPsText]) :- 1248 referent_text(Argument2, RI--RTmp, Argument2Text, f(_, obj)), 1249 referent_text(Argument3, RTmp--RO, Argument3Text, f(_, obj)).
1264verbalize_owners(Ref, RI--RI, owners([]), []) :- 1265 memberchk(Ref, RI), 1266 !. 1267 1268verbalize_owners(Ref, RI--[Ref | RI], owners([]), []) :- 1269 !. 1270 1271verbalize_owners(Ref, RI--RI, owners([_]), []) :- 1272 memberchk(Ref, RI), 1273 !. 1274 1275verbalize_owners(Ref, RI--RO, owners([relation(_, of, OwnerReferent)]), [of, OwnerText]) :- 1276 referent_text(OwnerReferent, [Ref | RI]--RO, OwnerText, _Features).
1289conds_to_andlist(_, [], []). 1290 1291conds_to_andlist(Cond_To_Text, [Cond], [Text]) :- 1292 !, 1293 call(Cond_To_Text, Cond, Text). 1294 1295conds_to_andlist(Cond_To_Text, [Cond | Conds], [Text, 'and' | Texts]) :- 1296 call(Cond_To_Text, Cond, Text), 1297 conds_to_andlist(Cond_To_Text, Conds, Texts).
1305adjective_to_text(property(_, Property, Comparison), PropertyText) :-
1306 surface_property(Property, Comparison, PropertyText).
1318adverb_to_text(modifier_adv(_, Adverb, Comparison), AdverbText) :- 1319 !, 1320 surface_adverb(Adverb, Comparison, AdverbText). 1321 1322adverb_to_text(Query, QueryWord) :- 1323 query(Referent, Query, _, QueryWord), 1324 toplevel_id(ToplevelId), 1325 ref2conds(Referent, _, ToplevelId, _SentenceId).
1333pps_to_text([], RI--RI, []). 1334 1335pps_to_text([modifier_pp(_, Prep, Modifier) | PPs], RI--RO, [Prep, ModifierText | PPsText]) :- 1336 referent_text(Modifier, RI--RTmp, ModifierText, _Features), 1337 pps_to_text(PPs, RTmp--RO, PPsText).
1345properties_to_text([], RI--RI, []). 1346 1347properties_to_text([property(_, Property, Comparison)], RI--RI, PropertyText) :- 1348 !, 1349 surface_property(Property, Comparison, PropertyText). 1350 1351properties_to_text([property(_, Property, Comparison, Argument)], RI--RO, [PropertyText, ArgumentText]) :- 1352 !, 1353 surface_property(Property, Comparison, PropertyText), 1354 referent_text(Argument, RI--RO, ArgumentText, _Features). 1355 1356properties_to_text([property(_Ref1, Adjective, Ref2, Comparison, ComparisonTarget, Ref3)], RI--RO, PropertyText) :- 1357 !, 1358 referent_text(Ref2, RI--RTmp, Ref2Text, _), 1359 referent_text(Ref3, RTmp--RO, Ref3Text, _), 1360 surface_property(Adjective, Comparison, ComparisonTarget, Ref2Text, Ref3Text, PropertyText). 1361 1362properties_to_text([property(_, Property, Comparison) | Properties], RI--RO, [PropertyText, 'and' | PropertiesText]) :- 1363 !, 1364 surface_property(Property, Comparison, PropertyText), 1365 properties_to_text(Properties, RI--RO, PropertiesText).
1375objects_to_text([Agent], RI--RO, [AgentText]) :- 1376 referent_text(Agent, RI--RO, AgentText, _Features). 1377 1378objects_to_text([Agent | Agents], RI--RO, [AgentText, 'and' | AgentsText]) :- 1379 referent_text(Agent, RI--RTmp, AgentText, _Features), 1380 objects_to_text(Agents, RTmp--RO, AgentsText).
1396surface_det(Referent, RI, SgPl, TopDeep, BoxPrefix, NounType, Comp, Number, Result) :- 1397 ( 1398 memberchk(Referent, RI) 1399 -> 1400 OldNew = old 1401 ; 1402 OldNew = new 1403 ), 1404 surface_det_x(SgPl, TopDeep, BoxPrefix, NounType, OldNew, Comp, Number, Result). 1405 1406 1407surface_det_x(sg, top, BoxPrefix, countable, new, eq, 1, [BoxPrefix, there, is, a]). 1408 1409surface_det_x(sg, top, BoxPrefix, mass, new, na, na, [BoxPrefix, there, is, some]). 1410 1411surface_det_x(sg, deep, _, countable, new, eq, 1, [a]) :- !. 1412surface_det_x(sg, deep, _, mass, new, na, na, [some]). 1413surface_det_x(sg, deep, _, mass, old, _, _, [the]). 1414 1415 1416% There are John and Mary. 1417surface_det_x(pl, top, BoxPrefix, _, _, dummy, dummy, [BoxPrefix, there, are]) :- !. 1418 1419% John and Mary wait. 1420surface_det_x(pl, deep, _, _, _, dummy, dummy, []) :- !. 1421 1422 1423surface_det_x(sg, top, BoxPrefix, countable, Det, Comp, Number, [BoxPrefix, there, is, SurfaceDeterminer]) :- 1424 surface_determiner(Det, Comp, Number, SurfaceDeterminer). 1425 1426surface_det_x(sg, deep, _, countable, Det, Comp, Number, SurfaceDeterminer) :- 1427 surface_determiner(Det, Comp, Number, SurfaceDeterminer). 1428 1429 1430surface_det_x(pl, top, BoxPrefix, _, Det, Comp, Number, [BoxPrefix, there, are, SurfaceDeterminer]) :- 1431 surface_determiner(Det, Comp, Number, SurfaceDeterminer). 1432 1433surface_det_x(pl, deep, _, _, Det, Comp, Number, SurfaceDeterminer) :- 1434 surface_determiner(Det, Comp, Number, SurfaceDeterminer).
1444surface_determiner(old, _, _, the). 1445 1446surface_determiner(new, eq, Number, [Number]). 1447 1448surface_determiner(new, geq, Number, [at, least, Number]). 1449 1450surface_determiner(new, leq, Number, [at, most, Number]). 1451 1452surface_determiner(new, greater, Number, [more, than, Number]). 1453 1454surface_determiner(new, less, Number, [less, than, Number]). 1455 1456surface_determiner(new, exactly, Number, [exactly, Number]). 1457 1458surface_determiner(new, na, na, []).
1468get_thereis(top, sg, BoxPrefix, [BoxPrefix, there, is]). 1469get_thereis(top, pl, BoxPrefix, [BoxPrefix, there, are]). 1470get_thereis(deep, _, _, []).
1479make_comment(_, [], []). 1480make_comment(PredicateText, [H | Tail], ['/*', 'Did you know that in ACE prepositional phrases always modify the verb? I.e.', PredicateText, [H | Tail], '*/']).
1488expr_exprpp(string(String), RI--RI, StringText) :- 1489 !, 1490 atomic(String), % the content of string/1 is either an atom or a number 1491 surface_quotedstring(String, StringText). 1492 1493expr_exprpp(int(Number), RI--RI, NumberText) :- 1494 !, 1495 integer(Number), 1496 with_output_to(atom(NumberText), format("~w", [Number])). 1497 1498expr_exprpp(real(Number), RI--RI, NumberText) :- 1499 !, 1500 float(Number), 1501 with_output_to(atom(NumberText), format("~w", [Number])). 1502 1503expr_exprpp(int(Number, Unit), RI--RI, [NumberText, Unit]) :- 1504 !, 1505 integer(Number), 1506 with_output_to(atom(NumberText), format("~w", [Number])). 1507 1508expr_exprpp(real(Number, Unit), RI--RI, [NumberText, Unit]) :- 1509 !, 1510 float(Number), 1511 with_output_to(atom(NumberText), format("~w", [Number])). 1512 1513expr_exprpp(named(Name), RI--RI, NameText) :- 1514 surface_noun(pn, Name, _, NameText), 1515 !. 1516 1517% Note: it's ok to call findall where RI--RI because sets cannot introduce new referents 1518expr_exprpp(set(Set), RI--RI, ['{', CommaSetText, '}']) :- 1519 !, 1520 findall(ElText, (member(El, Set), expr_exprpp(El, RI--RI, ElText)), SetText), 1521 list_commalist(SetText, CommaSetText). 1522 1523% Note: it's ok to call findall where RI--RI because lists cannot introduce new referents 1524expr_exprpp(list(List), RI--RI, ['[', CommaListText, ']']) :- 1525 !, 1526 findall(ElText, (member(El, List), expr_exprpp(El, RI--RI, ElText)), ListText), 1527 list_commalist(ListText, CommaListText). 1528 1529expr_exprpp(expr(Op, Expr1, Expr2), RI--RO, ['(', Expr1Text, Op, Expr2Text, ')']) :- 1530 !, 1531 expr_exprpp(Expr1, RI--RTmp, Expr1Text), 1532 expr_exprpp(Expr2, RTmp--RO, Expr2Text). 1533 1534expr_exprpp(Referent, RI--RO, Variable) :- 1535 get_type(Referent, Type, BoxId), 1536 get_box_prefix(BoxId, BoxPrefix), 1537 conds_text(Type, BoxPrefix, deep, RI--RO, Text, _), 1538 flatten(Text, FlatText), 1539 last(FlatText, Variable), 1540 debug(verbose, "NP in expr: ~w ~w~n", [Text, Variable]).
1548list_commalist([], []). 1549list_commalist([X], [X]). 1550list_commalist([X1, X2 | Tail], [X1, ',' | Text]) :- 1551 list_commalist([X2 | Tail], Text).
1558sentencelist_sentencelistcoord([Sentence], [Sentence]). 1559sentencelist_sentencelistcoord([Sentence1, Sentence2 | SentenceList], [Sentence1, [and, that] | SentenceListCoord]) :- 1560 sentencelist_sentencelistcoord([Sentence2 | SentenceList], SentenceListCoord).
1571get_sentence_id(SId/_TId, SId) :- !. 1572get_sentence_id(SId, SId).
1578is_complex_or_predicate([_ | _]) :- 1579 !. 1580is_complex_or_predicate(Condition) :- 1581 is_predicate(Condition), 1582 !. 1583is_complex_or_predicate(Condition) :- 1584 embeds_drs(Condition).
1591is_predicate(Condition-_) :- 1592 !, 1593 functor(Condition, predicate, _). 1594 1595is_predicate(Condition) :- 1596 functor(Condition, predicate, _).
1608embeds_drs(_Label:drs(_, _)). 1609embeds_drs(=>(_, _)). 1610embeds_drs(v(_, _)). 1611embeds_drs(-(_)). 1612embeds_drs(~(_)). 1613embeds_drs(can(_)). 1614embeds_drs(must(_)). 1615embeds_drs(should(_)). 1616embeds_drs(may(_)). 1617 1618 1619% is_complex_drs(+Drs:drs) 1620% 1621% @bug Currently not used 1622% 1623% DRS is complex iff 1624% at least one of its conditions embeds a DRS. 1625% 1626/* 1627is_complex_drs(drs(_, Cs)) :- 1628 member(C, Cs), 1629 embeds_drs(C), 1630 !. 1631*/ 1632 1633is_complex_drs(drs(_, [Cond])) :- 1634 embeds_drs(Cond).
1639parse_unary(-(drs(Dom, Conds)), not, Dom, Conds). 1640parse_unary(~(drs(Dom, Conds)), naf, Dom, Conds). 1641parse_unary(can(drs(Dom, Conds)), can, Dom, Conds). 1642parse_unary(must(drs(Dom, Conds)), must, Dom, Conds). 1643parse_unary(should(drs(Dom, Conds)), should, Dom, Conds). 1644parse_unary(may(drs(Dom, Conds)), may, Dom, Conds).
1650query(X, query(X, QLemma), SgPl, qp(QPhrase)) :- 1651 query_(QLemma, SgPl, QPhrase), 1652 !. 1653 1654query_(which, sg, [which]). 1655query_(which, pl, [which]). 1656query_(howm, pl, [how, many]). 1657query_(howm, mass, [how, much]). 1658query_(Word, _, [Word])
DRS to Core ACE verbalizer
Translates an Attempto DRS into the Core ACE fragment of Attempto Controlled English (ACE).
The setup: we have DRS-boxes and discourse referents, such that
Each referent lives-in exactly 1 box. For each box at least 1 referent lives-in it. Each referent has a unique ID and maps-to a set of conditions. Each box has a unique ID and has a name (if, then, '', or, `it is false that', etc.)
The task: verbalize each discourse referent, i.e. the conditions of each discourse referent. And do it in the context of
The order is important. It is set by referents_to_orderedreferents/2.
For the developer: to see the internals, use:
*/