\']\n\t ].\n\n').
clause_source_code(component(message_body, en-A, B, C, message_body1), 'realizer-grammar.mug', '\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \n%%% Language-independent elements %%%%%%%%%%%%%%%%%%%\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \n \ncomponent(message_body, en-_, Mode, FD, message_body1) :-\n\tFD === [ scope: [user_intention/email/body],\n\t\t user_intention: [ email:\t[\n\t\t\t\t\t body: T1]],\n\t\t Mode: [realized:1,\n\t\t\ttext: T1]].\t\t').
clause_source_code(component(subject, en-A, B, C, subject1), 'realizer-grammar.mug', '\t\t\t\n\n\ncomponent(subject, en-_, Mode, FD, subject1) :-\n\tFD === [ scope: [user_intention/email/to],\n\t\t user_intention: [ email:\t[\n\t\t\t\t\t subject: T1]],\n \t Mode: [realized:1,\n\t\t\t text: T1]].\t\t').
clause_source_code(component(list, A, B, C, list_1phone), 'realizer-grammar.mug', '\t\t\t\n\n/*\n\nThe list algorithm warrants some detailed explanation:\n\nThe input is a list of FDs (ListFD), given in attribute list. Each\nelement of the ListFD is unified with a template that reads the first\nelement of the \'salient\' list. This element FieldName contains the\nattribute (KB property) that identifies the most salient information\nabout the object, which is usually used to identify the objects. For\ncontacts, this would be the name. For emails, this would be the\nsubject and the sender/recipient. In the same template, we unify a\npair FieldName:SalientItemIdentifier. Because FieldName is\ninstantiated late (read out of \'salient\'), we need to delay the\nunification of this pair.\n\nAs soon FieldName is instantiated, the pair is unified with the FD and\nSalientItemIdentifier is instantiated. It will usually contain a\nstring or another kind of object.\n\nFor each element from the original list, we create a new list with a\nscreen_dynamic/voice attribute and an object attribute. The type of\nSalientItemIdentifier is read using the typeof operator. (Usually it\nwill simply return the value of the type attribute of\nSalientItemIdentifier, or \'predefined\' in case it\'s just an atom like\nfor email subjects). The type is directly used in the \'cat\' attribute\n(for screen_dynamic or voice), which triggers the resulting FD to the expanded.\n\nFor predefined objects, we have defined a MUG component. Similarly,\nMUG components need to be defined for other types that can occur here.\n\nThe foreach function automatically applies the unifier to the resulting\nlist. Therefore, we can simply read out the screen_dynamic:text attribute\nand insert it in a template that generates a radio button.\n\nFor voice, we insert \' or \' inbetween the objects. Therefore, we have\nto treat the first object in the list differently -- after all, we don\'t\nwant to get a string like "or peter ustinov or keith jarrett" out\nof the component.\n\n\n */\n\ncomponent(list, _, Mode, FD, list_1phone) :-\n(Mode=screen_dynamic),\ndevice_model(screen_size, phone), % no radio buttons for the phone\n\t\t \n\t\t\t\t% Algorithm:\n\t\t\t\t% given: A list of objects, a task/field context description\n\t\t\t\t% For each object, show:\n\t\t\t\t% Value of the most salient (designated in type description) field\n\t\t\t\t% list of values: all entries of the object that could fill the task/field context description\n\t\n\tFD === [ \n\t\t list: ListFD, \n\t\t Mode:[cat:list,\n\t\t \t realized:1,\n\t\t\t text: concat([\'\', concat(foreach(foreach(unifyEach(ListFD, [Mode:[realized:1|_]]), \n\t\t\t\t\t\t\t [ salient:[FieldName|_],\n\t\t\t\t\t\t\t\tFieldName:SalientItemIdentifier|_],\n\t\t\t\t\t\t\t [ Mode:[cat:typeof(SalientItemIdentifier)|_],\n\t\t\t\t\t\t\t\tobject:SalientItemIdentifier |_]\n\t\t\t\t\t\t\t ), \n\t\t\t\t\t\t [ Mode:[text:Text|_]|_], \n\t\t\t\t\t\t template(\'
\']\n\t\t\t\t )\n\t\t\t] \n\t ].\n\n').
clause_source_code(component(list, A, B, C, list_1), 'realizer-grammar.mug', '\n\n\ncomponent(list, _, Mode, FD, list_1) :-\n(Mode=screen_dynamic),\ndevice_model(screen_size, pda), % no radio buttons for the phone\n\t\t \n\t\t\t\t% Algorithm:\n\t\t\t\t% given: A list of objects, a task/field context description\n\t\t\t\t% For each object, show:\n\t\t\t\t% Value of the most salient (designated in type description) field\n\t\t\t\t% list of values: all entries of the object that could fill the task/field context description\n\t\n\tFD === [ \n\t\t list: ListFD, \n\t\t Mode:[cat:list,\n\t\t \t realized:1,\n\t\t\t text: concat([concat(foreach(foreach(unifyEach(ListFD, [Mode:[realized:1|_]]), \n\t\t\t\t\t\t\t [ salient:[FieldName|_],\n\t\t\t\t\t\t\t\tFieldName:SalientItemIdentifier|_],\n\t\t\t\t\t\t\t [ Mode:[cat:typeof(SalientItemIdentifier)|_],\n\t\t\t\t\t\t\t\tobject:SalientItemIdentifier |_]\n\t\t\t\t\t\t\t ), \n\t\t\t\t\t\t [ Mode:[text:Text|_]|_], \n\t\t\t\t\t\t template(\' ~w\',[Text])\n\t\t\t\t\t\t )\n\t\t\t\t\t ), \n\t\t\t\t \'
\']\n\t\t\t\t )\n\t\t\t] \n\t ].\n\t').
clause_source_code(component(list, A, B, C, list_1b), 'realizer-grammar.mug', '\t \ncomponent(list, _, Mode, FD, list_1b) :-\n\n\t(Mode=voice),\n\n\tFD === [ \n\t\t list: [FirstOfListFD|RemainderOfList], \n\t\t Mode:[ \tcat:list,\n\t\t \t realized:1,\n\t\t\t\ttext: \n\t\t concat([concat(foreach(foreach(unifyEach([FirstOfListFD], [Mode:[realized:1|_]]),\n\t\t\t\t\t\t [ salient:[FieldName|_],\n\t\t\t\t\t\t\t\tFieldName:ItemIdentifier\n\t\t\t\t\t\t |_], \n\t\t\t\t\t\t [ Mode:[cat:typeof(ItemIdentifier)|_], \n\t\t\t\t\t\t\tobject:ItemIdentifier|_]\n\t\t\t\t\t\t ), \n\t\t\t\t\t [Mode:[text:Text|_]|_], \n\t\t\t\t\t Text\n\t\t\t\t\t )),\n\t\t\t concat(foreach(foreach(unifyEach(RemainderOfList, [Mode:[realized:1|_]]),\n\t\t\t\t\t\t [ salient:[FieldName1|_],\n\t\t\t\t\t\t\t\tFieldName1:ItemIdentifier1\n\t\t\t\t\t\t |_], \n\t\t\t\t\t\t [ Mode:[cat:typeof(ItemIdentifier1)|_], \n\t\t\t\t\t\t\tobject:ItemIdentifier1|_]\n\t\t\t\t\t\t ), \n\t\t\t\t\t [Mode:[text:Text1|_]|_], \n\t\t\t\t\t concat([\' or \',Text1,\' \'])\n\t\t\t\t\t ))\n\t\t\t ])\n\t\t ]\n\t ].\n\n').
clause_source_code(component(list, A, screen_dynamic, B, list_2), 'realizer-grammar.mug', '\ncomponent(list, _, screen_dynamic, FD, list_2) :-\n\n/* Display the whole item, instead of just the salient elements */\n/* This displays it as a list of radio buttons */\n\t\t\t\t% Algorithm:\n\t\t\t\t% given: A list of objects, a task/field context description\n\t\t\t\t% For each object, show:\n\t\t\t\t% Value of the most salient (designated in type description) field\n\t\t\t\t% list of values: all entries of the object that could fill the task/field context description\n\tMode=screen_dynamic,\ndevice_model(screen_size, pda), % no radio buttons for the phone\n\n\tDisplayFD === [type: Type,\n\t\t Mode:[cat: Type,\n\t\t\t prefix:\'\']\n\t\t ],\n\n\tDisplayFD2 === [type: Type2,\n\t\t\tMode:[cat: Type2,\n\t\t\t prefix:\'\']\n\t\t ],\n\tTemplateFD === [Mode: [text: T1]],\n\tOutTemplateFD === template(\' ~w\',[T1]),\n\t\n\tFD === [ \n\t\t list: [FirstOfListFD|RemainderOfListFD],\n\t\t % If this is a list, for each item in the list,\n\t\t % get the cat of the item type\n\t\t % For each of these augmented items, unify it with the templatefd to\n\t\t % create the output fd\n\t\t % then concatenate them all together.\n\t\t Mode:[ cat:list,\n\t\t \t realized:1,\n\t\t\t\t text:\n\t\t\t\tconcat([concat(foreach(multiply(\n\t\t\t\t\t\t\t unifyEach([FirstOfListFD], [Mode:[realized:1]]),\n\t\t\t\t\t\t\t DisplayFD\n\t\t\t\t\t\t\t ),\n\t\t\t\t\t\t TemplateFD,\n\t\t\t\t\t\t OutTemplateFD\n\t\t\t\t\t\t \n\t\t\t\t\t\t )),\n\t\t\t\t concat(foreach(multiply(\n\t\t\t\t\t\t\t unifyEach(RemainderOfListFD, [Mode:[realized:1]]),\n\t\t\t\t\t\t\t DisplayFD2\n\t\t\t\t\t\t\t ),\n\t\t\t\t\t\t [Mode: [text: T2]],\n\t\t\t\t\t\t template(\' ~w\',[T2])\n\t\t\t\t\t\t \n\t\t\t\t\t\t ))])\n\t\t\t\t]].\n\n').
clause_source_code(component(list, A, B, C, list_2_voice), 'realizer-grammar.mug', '\n\ncomponent(list, _, Mode, FD, list_2_voice) :-\n/* Display the whole item, instead of just the salient elements */\n\t\t\t\t% Algorithm:\n\t\t\t\t% given: A list of objects, a task/field context description\n\t\t\t\t% For each object, show:\n\t\t\t\t% Value of the most salient (designated in type description) field\n\t\t\t\t% list of values: all entries of the object that could fill the task/field context description\n\tMode=voice,\n\t\n\tDisplayFD === [type: Type,\n\t\t Mode:[cat: Type,\n\t\t\t prefix:\'\']\n\t\t ],\n\n\tDisplayFD2 === [type: Type2,\n\t\t\tMode:[cat: Type2,\n\t\t\t prefix:\'\']\n\t\t ],\n\tTemplateFD === [Mode: [text: T1]],\n\tOutTemplateFD === T1,\n\t\n\tFD === [ \n\t\t list: [FirstOfListFD|RemainderOfListFD],\n\t\t % If this is a list, for each item in the list,\n\t\t % get the cat of the item type\n\t\t % For each of these augmented items, unify it with the templatefd to\n\t\t % create the output fd\n\t\t % then concatenate them all together.\n\t\t voice:[cat:list,\n\t\t \t realized:1,\n\t\t\t\t text:\n\t\t\t\tconcat([concat(foreach(multiply(\n\t\t\t\t\t\t\t \t unifyEach([FirstOfListFD], [Mode:[realized:1]]),\n\t\t\t\t\t\t\t DisplayFD\n\t\t\t\t\t\t\t ),\n\t\t\t\t\t\t TemplateFD,\n\t\t\t\t\t\t OutTemplateFD\n\t\t\t\t\t\t \n\t\t\t\t\t\t )),\n\t\t\t\t concat(foreach(multiply(\n\t\t\t\t\t\t\t unifyEach(RemainderOfListFD, [Mode:[realized:1]]),\n\t\t\t\t\t\t\t DisplayFD2\n\t\t\t\t\t\t\t ),\n\t\t\t\t\t\t [Mode: [text: T2]],\n\t\t\t\t\t\t concat([\' or \', T2, \' \'])\n\t\t\t\t\t\t \n\t\t\t\t\t\t ))])\n\t\t\t\t]].\n\n').
clause_source_code(component(disambiguate, A, B, C, disambiguate_1), 'realizer-grammar.mug', '\n\n\n\n% output the long version stuff via voice and on screen_dynamic\n\n/* disambiguate\n\nThis calls up a MUG component for the ActionType specified (such as\nfillfield, addtolist). The resulting structure is contained in the\nfullstring attribute (Target variable), so the template \'disambiguate\'\n(see template components below) can read it and insert it in its\ntemplate.\n\nThe structure of this is somewhat awkward, we might want to simplify\nthese things.\n\n \n */\n\ncomponent(disambiguate, _, Mode, FD, disambiguate_1) :- \n\tFD === [\n\t\t\n \t\ttype: CommonType, \n \t\tquantity:Card, \n \t\taction:Target=[\n \t\t\t\n\t\t\ttype: ActionType,\n\t\t\tMode: [\tcat: ActionType\n\t\t\t \n\t\t\t\t]\n\t\t ],\n \t \tMode:[ \t \tcat:disambiguate, \t\t \t\t\t\n\t\t\t\tfullstring:[\t\n\t\t\t\t\t\t\n\t\t\t\t\t\ttemplate: disambiguate,\n\t\t\t\t\t\tdeterminer:Card,\n\t\t\t\t\t\tfield_vp:Target,\n\t\t\t\t\t\ttype_np:CommonType,\n\t\t\t\t\t\t\n\t\t\t\t\t\ttext:Text, \n\t\t\t\t\t\tMode:[\tcat:template_mod,\n\t\t\t\t\t\t\tprefix: \'\',\n\t\t\t\t\t\t\ttext:Text]],\n\t\t\t\ttext:Text,\n\t\t\t\trealized:1\n\t\t ]\n\t ].\n\n').
clause_source_code(component(submit, A, voice, B, submit_1), 'realizer-grammar.mug', '\n\n\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n%%% Mode-specific Code Generation Level %%%%%%%%%%%%%%%%%%%%%%%%\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n\n\n%%%%% HTML/VXML PRODUCING LEVEL %%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n%% SCREEN_DYNAMIC %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n/* Creating various html components. */\n % the submit component is currently not used\ncomponent(submit, _, voice, FD, submit_1) :- \n\tFD === [ \n\t\t voice:[text:\' \', \n\t\t\trealized:0] \n\t ].\n\n').
clause_source_code(component(submit, A, screen_dynamic, B, submit_2), 'realizer-grammar.mug', '\ncomponent(submit, _, screen_dynamic, FD, submit_2) :-\n\tdevice_model(screen_size, pda),\nFD === [\n \t\tscreen_dynamic:[cat:submit,\n \t\trealized:1,\n\t\t text: \' \' ]].\n\n').
clause_source_code(component(submit, A, screen_dynamic, B, submit_3), 'realizer-grammar.mug', '\n\ncomponent(submit, _, screen_dynamic, FD, submit_3) :-\n\tdevice_model(screen_size, phone),\n\tFD === [ \n\t\t \n\t\t screen_dynamic:[\ttext:\'\', \n\t\t realized:1,\n\t\t\t\t\t\trealized:0\n\t\t\t\t\t]\n\t ].\n\t').
clause_source_code(component(empty, A, B, C, empty_1), 'realizer-grammar.mug', '\t \n\t \n\ncomponent(empty, _, Mode, FD, empty_1) :-\n\tFD === [\n\t\tMode:[\tcat:empty, text:\' \'] ].\n\n').
clause_source_code(component(optional_string, A, screen_dynamic, B, optional_string_1), 'realizer-grammar.mug', '\n\n\ncomponent(optional_string, _, screen_dynamic, FD, optional_string_1) :-\n\tFD === [\t\tstring: String, \n\t\t\t\tscreen_dynamic:[\n\t\t\t\t\tprefix:P,\n\t\t\t\t\trealized:1,\n\t\t\t\t\t\t text:template(\'~w~w\', [P,String]) ]],\n\tgiven(String),\n\tgiven(P).\n\n').
clause_source_code(component(optional_string, en-A, voice, B, optional_string_2), 'realizer-grammar.mug', '\n\t\t\t\t%Note: for now, we are not using VXML, so voice strings are output to html\n\ncomponent(optional_string, en-_, voice, FD, optional_string_2) :-\n\tFD === [\t\tstring:String, \n\t\t\t\tvoice:[\n\t\t\t\t prefix:P,\n\t\t\t\t realized:1,\n\t\t\t\t text:template(\'~w~w\', [P,String]) ]],\n\tgiven(String),\n\tgiven(P).\n\n').
clause_source_code(component(optional_string, A, B, C, optional_string_n), 'realizer-grammar.mug', '\n\t\t\t\t% null realization\ncomponent(optional_string, _, Mode, FD, optional_string_n) :-\n\tFD === [\t\t \n\t\t\t\t Mode:[ \trealized:0,\n\t\t\t\t\t\ttext: \'\']].\n\n').
clause_source_code(component(objlist, A, screen_dynamic, B, objlist_1), 'realizer-grammar.mug', '\n\ncomponent(objlist, _, screen_dynamic, FD, objlist_1) :-\n\tFD === [elements:Elem ], \n\tStart = \'\',\n\tListStart = \'
', html:'upper html', deeper:[html:'this should only be seen when recurse=lim or full', deeper:[html:'this is deepest (only full!)'|B]|C]|D]),
grammar_constraint(fd_collect(text, A, recurse_full, E)),
grammar_constraint(fd_collect(html, A, recurse_limited, F)),
grammar_constraint(fd_collect(deeper:html, A, recurse_limited, G)),
grammar_constraint(fd_collect(deeper:html, A, recurse_full, H)),
grammar_constraint(nonvar(E)),
grammar_constraint(nonvar(F)),
grammar_constraint(nonvar(G)),
grammar_constraint(nonvar(H)),
E=['
Peter Ustinov
'],
F=['upper html'],
G=['this should only be seen when recurse=lim or full'],
H=['this should only be seen when recurse=lim or full', 'this is deepest (only full!)'].
mug_engine_declare(stepbystepeval).
mug_engine_test(stepbystepeval) :-
unif(A, [source:'here ', deep:[source:'i come'|B]|C]),
D=multiply([A], [addtl:tag|E]),
F=collect(source, G),
unif(H, [orig:A, list:eval(concat, [F], I, J), prep:G|K]),
unif(G, D),
grammar_constraint(wrapeval(H, L)),
grammar_constraint(applyOperators(L)),
grammar_constraint(fd_read_value(L, list, none, M)),
M='here i come'.
mug_engine_declare(linkCenters).
mug_engine_test(linkCenters) :-
unif(A, [type:askconfirmation, initiative:implicit, experience:novice, error:none, action:[type:task, objectid:44, task:[type:send_email, contexttype:email, email:[type:email, objectid:10, salient:[subject, to], to:[type:contact, objectid:9, firstname:'Mick', lastname:'Cody', realize:1|B], from:[type:emailaddress, objectid:8, adr:'reitter@mle.ie'|C], subject:[type:text, content:'Irish weather'|D], body:[type:text, content:'G\'day mates. Happy New Year Everybody! -Dave'|E]|F]|G]|H]|I]),
unif(J, [type:askconfirmation, initiative:implicit, experience:novice, error:none, action:[type:task, objectid:44, task:[type:send_email, contexttype:email, email:[type:email, objectid:10, salient:[subject, to], to:[type:contact, objectid:9, firstname:'Mick', lastname:'Cody', realize:1|K], from:[type:emailaddress, objectid:8, adr:'reitter@mle.ie'|L], subject:[type:text, content:'Irish weather'|M], body:[type:text, content:'G\'day mates. Happy New Year Everybody! -Dave'|N]|O]|P]|Q]|R]),
grammar_constraint(linkCenters([], A, S, T)),
grammar_constraint(linkCenters(T, J, U, V)),
grammar_constraint(fd_read_value(S, action:task:email:from:centering:previous:cb, unknown, none)),
grammar_constraint(fd_read_value(S, action:task:email:centering:current:cf, unknown, unknown)),
grammar_constraint(fd_bind_value(S, action:task:email:centering:utterance, W)),
grammar_constraint(fd_bind_value(S, action:task:email:centering:utterance, X)),
grammar_constraint(W==X),
grammar_constraint(fd_bind_value(S, action:task:email:to:centering:current, Y)),
grammar_constraint(fd_bind_value(U, action:task:email:to:centering:previous, Z)),
grammar_constraint(Y==Z),
grammar_constraint(fd_bind_value(S, action:task:email:centering:current, A1)),
grammar_constraint(fd_bind_value(U, action:task:email:centering:previous, B1)),
grammar_constraint(A1==B1),
grammar_constraint(fd_read_value(U, action:task:email:to:centering:current:cf, unknown, unknown)),
grammar_constraint(fd_bind_value(U, action:task:email:to:centering:utterance, C1)),
grammar_constraint(fd_bind_value(U, action:task:email:centering:utterance, D1)),
grammar_constraint(\+W==C1),
grammar_constraint(C1==D1).
ex(mugtest8, A) :-
unif(A, [type:askconfirmation, initiative:implicit, experience:novice, error:none, action:[type:task, scope:[task/email], task:[type:send_email, contexttype:email, email:[png:[gend:neut, num:sing|B], objectid:10, centering:[current:[cp:1, cb:1|C], previous:[cp:0, form:null|D], utterance:[cb:10, cp:10|E]|F], type:email, objectid:10, salient:[subject, to], to:[type:contact, objectid:9, firstname:'Mick', lastname:'Cody', png:[gend:masc, num:sing|G], centering:[current:[cb:0|H], previous:[cp:0, form:null|I]|J]|K], cc:[type:contact, firstname:'Erin', lastname:'Panttaja', png:[gend:fem, num:sing|L], centering:[current:[cp:0, cb:0|M], previous:[cp:0|N]|O]|P], from:[type:emailaddress, objectid:8, adr:'reitter@mle.ie', png:[gend:masc, num:sing|Q], centering:[current:[cp:0, cb:0|R], previous:[cp:0|S]|T]|U], subject:[type:text, content:'Aussie weather'|V], body:[type:text, content:'G\'day mates. Happy New Year Everybody! -Dave'|W]|X]|Y]|Z]|A1]).
ex(mugtest9, A) :-
unif(A, [type:askconfirmation, initiative:implicit, experience:novice, error:none, action:[type:task, scope:[task/email], task:[type:send_email, contexttype:email, email:[png:[gend:neut, num:sing|B], centering:[current:[cp:1, cb:1|C], previous:[cp:1, form:pronoun|D], utterance:[cb:10, cp:10|E]|F], type:email, objectid:10, salient:[subject, to], to:[type:contact, objectid:9, firstname:'Mick', lastname:'Cody', png:[gend:masc, num:sing|G], centering:[current:[cp:0, cb:0|H], previous:[cp:1, form:pronoun|I]|J]|K], cc:[type:contact, firstname:'Erin', lastname:'Panttaja', png:[gend:fem, num:sing|L], centering:[current:[cp:0, cb:0|M], previous:[cp:0|N]|O]|P], from:[type:emailaddress, objectid:8, adr:'reitter@mle.ie', png:[gend:masc, num:sing|Q], centering:[current:[cp:0, cb:0|R], previous:[cp:0|S]|T]|U], subject:[type:text, content:'Aussie weather'|V], body:[type:text, content:'G\'day mates. Happy New Year Everybody! -Dave'|W]|X]|Y]|Z]|A1]).
ex(mugtest10, A) :-
unif(A, [type:askconfirmation, initiative:implicit, experience:novice, error:none, action:[type:task, scope:[task/email], task:[type:send_email, contexttype:email, email:[png:[gend:neut, num:sing|B], centering:[previous:[cp:0, form:full|C]|D], type:email, objectid:10, salient:[subject, to], to:[type:contact, objectid:9, firstname:'Mick', lastname:'Cody', png:[gend:masc, num:sing|E], centering:[previous:[cp:0, form:definite|F]|G]|H], cc:[type:contact, firstname:'Erin', lastname:'Panttaja', png:[gend:fem, num:sing|I], centering:[previous:[cp:0|J]|K]|L], from:[type:emailaddress, objectid:8, adr:'reitter@mle.ie', png:[gend:masc, num:sing|M], centering:[previous:[cp:0|N]|O]|P], subject:[type:text, content:'Aussie weather'|Q], body:[type:text, content:'G\'day mates. Happy New Year Everybody! -Dave'|R]|S]|T]|U]|V]).
ex(mugtest11, A) :-
unif(A, [type:pick, initiative:implicit, experience:novice, error:none, cardinality:one, action:[type:fillfield, task:[type:send_email, contexttype:email, email:[type:email, to:[type:contact, firstname:'Mick', lastname:'Cody', gend:masc|B], cc:[type:contact, firstname:'Erin', lastname:'Panttaja', gend:fem|C], from:[type:emailaddress, adr:'reitter@mle.ie'|D]|E]|F], scope:[user_intention/email/bcc], user_intention:[list:[[type:contact, firstname:'Jenna', lastname:'Templeton', gend:fem|G], [type:contact, firstname:'Jenna', lastname:'Elfman', gend:fem|H], [type:contact, firstname:'Jenna', lastname:'Bruce', gend:fem|I]]|J]|K]|L]).
ex(mugtest12, A) :-
unif(A, [type:pick, initiative:implicit, experience:novice, error:none, cardinality:one, action:[type:fillfield, task:[type:send_email, contexttype:email, email:[type:email|B]|C], scope:[user_intention/email/bcc], user_intention:[list:[[type:contact, firstname:'Jenna', lastname:'Templeton', gend:fem|D], [type:emailaddress, adr:'reitter@mle.ie'|E], [type:contact, firstname:'Jenna', lastname:'Elfman', gend:fem|F]]|G]|H]|I]).
ex(paper1, A) :-
unif(A, [type:askconfirmation, initiative:implicit, experience:novice, error:none, action:[type:task, task:[type:send_email, contexttype:email, email:[type:email, to:[type:contact, firstname:'Fred', lastname:'Cummins', realize:1|B], cc:[type:contact, firstname:'Erin', lastname:'Panttaja', realize:1|C], from:[type:emailaddress, adr:'reitter@mle.ie'|D], subject:[type:text, content:'Aussie weather'|E], body:[type:text, content:'G\'day mates. Happy New Year Everybody! -Dave'|F]|G]|H], scope:[task/email]|I]|J]).
ex(paper2, A) :-
unif(A, [type:askconfirmation, initiative:implicit, experience:novice, error:none, action:[type:task, task:[type:send_email, contexttype:email, email:[type:email, to:[type:contact, firstname:'Fred', lastname:'Cummins', realize:1|B], cc:[type:contact, firstname:'Erin', lastname:'Panttaja', realize:1|C], from:[type:emailaddress, adr:'reitter@mle.ie'|D], subject:[type:text, content:'Aussie weather'|E], body:[type:text, content:'G\'day mates. The summer is really nice down under, warm and sunny. Are you enjoying the Irish rain? Happy New Year Everybody! -Dave'|F]|G]|H]|I]|J]).
ex(erin1, A) :-
unif(A, [type:pick, cardinality:one, action:[type:addtolist, task:[type:send_email|B], scope:[task/email/to], user_intention:[list:[[type:contact, firstname:'Peter', lastname:'Ustinov'|C], [type:emailaddress, adr:'peter@yahoo.com'|D]]|E]|F]|G]).
mug-workbench/_workbench.conf.pl 0000644 0000767 0000024 00000000646 10410111247 016757 0 ustar dr staff 0000000 0000000 % MUG Workbench Configuration. This file is auto-generated.
:- dynamic(workbench_config/1).
:- retractall(workbench_config(_)).
workbench_config(filter('no score', 0, [score])).
workbench_config(filter(generation, '1', [text, screen_static, screen_dynamic, voice, cat])).
workbench_config(filter('only type', '1', [type])).
workbench_config(filter(scoring, 0, [score, utility, overall, reading, realize, realized])).
mug-workbench/all 0000755 0000767 0000024 00000000067 10127046041 014054 0 ustar dr staff 0000000 0000000 yap -s 18000 -h 20000 -t 18000 -l all_api_yap.pl
mug-workbench/all_api_yap.pl 0000644 0000767 0000024 00000001555 10127046041 016170 0 ustar dr staff 0000000 0000000 % realizer_api_gpl
:- yap_flag(language,sicstus).
:- yap_flag(informational_messages,on).
:- ensure_loaded('compat_yap.pl').
:- ensure_loaded('lists.pl').
:- ensure_loaded('realizer-api.pl').
:- ensure_loaded('realizer.pl').
:- ensure_loaded('debug.pl').
:- ensure_loaded('ff-tools-opt.pl').
:- ensure_loaded('punif.pl').
:- ensure_loaded('score.pl').
:- ensure_loaded('tools.pl').
:- ensure_loaded('uni.pl').
:- ensure_loaded('unif.pl').
:- ensure_loaded('kb_engine.pl').
:- ensure_loaded('database.pl').
:- ensure_loaded('tools.pl').
% grammars
:- ensure_loaded('_realizer-grammar.pl').
:- ensure_loaded('_centering-grammar.pl').
% :- ensure_loaded('_realizer-autoconv.pl').
:- ensure_loaded('_realizer-tests.pl').
:- ensure_loaded('dm.pl').
:- ensure_loaded('fusion.pl').
% socket-based API
:- ensure_loaded('sockets_api.pl').
:- server(all, 'localhost'). mug-workbench/._all_dev_swi.pl 0000400 0000767 0000000 00000000122 10145243607 016400 0 ustar dr wheel 0000000 0000000 Mac OS X 2 R TEXT mug-workbench/all_dev_swi.pl 0000644 0000767 0000024 00000000352 10145243607 016207 0 ustar dr staff 0000000 0000000 % realizer_api_gpl
:- load_files(['siteconfig.pl', 'realizer-dev.pl', 'realizer.pl'], [silent(true)]).
:- ensure_loaded('dm.pl').
:- ensure_loaded('fusion.pl').
% socket-based API
:- ensure_loaded('sockets_api.pl').
mug-workbench/ao-tests.mug 0000644 0000767 0000024 00000000411 10127046041 015620 0 ustar dr staff 0000000 0000000 % -*-Prolog-*-
/*
These are unit tests for parts of the Fission MUG engine.
Author: David Reitter, reitter@mle.media.mit.edu
Copyright 2003, Media Lab Europe Ltd.
CONFIDENTIAL.
Last Change: $Id: ao-tests.mug,v 1.5 2004/02/16 16:59:49 dr Exp $
*/
% deleted mug-workbench/basic-grammar.mug 0000644 0000767 0000024 00000004307 10155176636 016615 0 ustar dr staff 0000000 0000000 % -*-Prolog-*-
/*
This grammar components demonstrate the MUG principles
It should not interfere with the other grammars or examples.
*/
grammar_info('Basic sample grammar and test case','David Reitter').
output_mode(screen).
output_mode(voice).
/* test case */
ex(basic1, FD) :-
FD === [
type: give_explanation,
action: none,
theme: [ type: gui_button,
label: 'Save',
png: [gend: neut, num: sing],
function: [ type:save,
scope: document
]
]
].
/* root component for all modes */
component(multimodal, _, Mode, FD, demo_multimodal_1) :-
FD === [
tree:[
Mode:[ cat:DialogueAct,
text:A],
type:DialogueAct
],
Mode:[ cat:multimodal,
text:A]
].
/* Dialogue Act component */
component(give_explanation, _, Mode, FD, give_explanation) :-
FD === [
theme: Theme = [ function: Function ],
theme_refexp: [ sem: Theme,
Mode: [ cat:refexp,
prefix: '',
realized:1,
function:normal,
case:nom,
text: Subject
]
],
pred: [
function: Function,
Mode: [ cat:describe_function,
form: 'vp\\np',
text: Predicate
]
],
Mode:[ cat: give_explanation,
realized: 1,
text: concat([capitalize(Subject), ' ', Predicate, '.'])
]
].
/* canned text: description of some program function.
must realize a verbal phrase
*/
component(describe_function, _, Mode, FD, describe_function_1) :-
FD === [
function: [ type: save,
scope: document
],
Mode:[ cat:describe_function,
form: 'vp\\np',
text: concat(['saves your document to disk'])
]
].
/* realizes a GUI element */
component(gui_button, _, Mode, FD, gui_button_1) :-
FD === [
label: Label,
Mode:[ cat:gui_button,
realized:1,
text: concat(['the ', Label, ' button'])
]
].
/* lexical element, bneeded by refexp component */
component(objtype, en-_, Mode, FD, demo_objtype_1) :-
FD ===
[
objecttype: gui_button,
Mode: [text: 'button']
].
mug-workbench/benchmark.pl 0000644 0000767 0000024 00000002574 10127046041 015652 0 ustar dr staff 0000000 0000000
run_benchmark :-
time(run_tests('benchmark.out')).
run_tests(File) :-
abolish(benchmark_result/2),
choose(maximum_number_of_results, [50,200,500]),
choose(search_algorithm, [depthfirst, bestfirst]),
choose(bounded_search, [on,off]),
choose(iterative_deepening, [on, off]),
choose(scoring_heuristic, [admissible, practical]),
choose(experimental_beam_search, [off]),
\+ (experimental_beam_search(on), bounded_search(off)),
\+ (iterative_deepening(on), bounded_search(off)),
get_siteconfig(Conf),
writeln(Conf),
run_tests2(Res),
assertz(bechmark_result(Conf, Res)),
fail.
run_tests(File) :-
tell(File),
print_results,
told.
print_results :-
bechmark_result(Conf, Res),
nl,
write('\t'),
foreach((Ex, Time), Res,
format('~w \t ', [Ex])),
nl,
format('~w \t ', [Conf]),
foreach((Ex, Time), Res,
format('~w \t', [ Time])),
nl,
fail.
print_results.
choose(Pred, List) :-
member(V, List),
abolish(Pred/1),
PredA =.. [Pred,V],
assertz(PredA).
run_tests2(TL) :-
findall((Ex, Time),
(
member(Ex,
[demo1, demo2, demo3, demo4, demo5, demo6,demo7,demo8]
%[demo1, demo8]
), write(Ex),nl, time((\+ \+ fist(Ex)),Time) , write(time:Time),nl), TL),
foreach((Ex, Time), TL,
format('~w \t ~w \n', [Ex, Time])).
time(Goal, CPUT) :-
statistics(cputime,CPU),
call(Goal),
statistics(cputime,CPU2),
CPUT is CPU2-CPU.
mug-workbench/cache_mfug.pl 0000644 0000767 0000024 00000001665 10127046041 016001 0 ustar dr staff 0000000 0000000 % grammar cache
%
% doesn't make sense to include this in uni(), because
% there is a Cat preselection anyways.
% Experiments show that unificatino doesn't fail anyways!!
%
:- dynamic cache_mfug/4.
:- index(cache_mfug(1,1,1,1)).
index_mfug_unifications(OutFile) :-
retractall(cache_mfug(_,_,_,_)),
tell(OutFile),
index_mfug_unifications1,
told.
index_mfug_unifications1 :-
output_modes(Modes),
member(M1, Modes), component(_Cat1, L, M1, FD1, UniqueID1),
member(M2, Modes), component(_Cat2, L, M2, FD2, UniqueID2),
(M1/UniqueID1) \== (M2/UniqueID2), % don't try to unify the same rule twice
unify(FD1, FD2), % should unify
if(cache_mfug(UniqueID1,M1,UniqueID2,M2),
true,
(assertz(cache_mfug(UniqueID1,M1,UniqueID2,M2)),
writeq(cache_mfug(UniqueID1,M1,UniqueID2,M2)), write('.'), nl)
),
fail.
index_mfug_unifications1.
:- index_mfug_unifications('_realizer-cache.pl'),
ensure_loaded('_realizer-cache.pl').
mug-workbench/._centering-grammar.mug 0000400 0000767 0000000 00000000122 10176167171 017674 0 ustar dr wheel 0000000 0000000 Mac OS X 2 R TEXT mug-workbench/centering-grammar.mug 0000644 0000767 0000024 00000025400 10176167171 017504 0 ustar dr staff 0000000 0000000 /*
Authors: Eva Maguire, David Reitter
Components required for the generation of referring expressions
Refexp instantiates a surface realization depending on whether
the same object has been mentioned in the previous sentence,
and whether various centering conditions are fulfilled.
*/
grammar_info('MUG Centering Grammar for Referring Expressions','Eva Maguire, David Reitter').
/* because CF setting not implemented, we cannot do deictics / highlighed
stuff
component(refexp, en-_, Mode, FD, Utterance, refexp_full_focused_screen) :-
Mode\=voice,
Utterance === [utterance: [cb:ThisObjectID]],
FD === [sem:[ type: ObjectType,
objectid: ThisObjectID,
png:[num:sing],
centering:[
current:[form: full,
cp:1,
cf:1], % this element is definitely top of CF
previous:[cp:0, form: null]
],
Mode:[cat: ObjectType,
realized:1,
text: SurfaceForm
]
],
Mode:[text: concat(['',P,' ',SurfaceForm, '']),
prefix: P,
function: normal,
realized: 1
]
],
given(ObjectType).
*/
component(refexp, en-_, Mode, FD, Utterance, refexp_full) :-
FD === [sem:[ type: ObjectType,
png:[num:sing],
centering:[
current:[form: full,
cb:0],
previous:[cp:0, form: null]
],
Mode:[cat: ObjectType,
realized:1,
text: SurfaceForm
]
],
Mode:[text: concat([P,' ',SurfaceForm]),
prefix: P,
function: normal,
realized: 1
]
]
, given(ObjectType).
% Full, Possessive
component(refexp, en-_, Mode, FD, refexp_full_poss) :-
FD === [sem:[ type: ObjectType,
png:[num:sing],
centering:[
current:[form: full ],
previous:[cp:0, form: null]
],
Mode:[cat: ObjectType,
realized:1,
text: SurfaceForm
]
],
Mode:[text: concat([P,' ',SurfaceForm, '`s']),
prefix: P,
function: poss,
realized: 1
]
].
%em
%If an object was referred to in a non-sentence intial position in the last expression then it may be referred to using a definite referring expression.
component(refexp, en-_, Mode, FD, refexp_definite) :-
FD === [
sem:[ type: ObjectType,
png:[num:sing],
centering:[ current:[form: definite ],
previous:[cp:0, form:PreviousForm]
],
Mode:[ cat: objtype,
text: TypeText
],
objecttype:ObjectType
],
Mode:[text: template('~w the ~w', [P,TypeText]),
prefix: P,
function: normal,
realized: 1]
],
% not pronoun
( PreviousForm=null; PreviousForm=full; PreviousForm=deictic )
,
given(ObjectType).
/*
component(refexp, en-_, Mode, FD, Utterance, refexp_definite_in_focus_scr) :-
(Mode=screen_dynamic; Mode=screen),
Utterance === [utterance: [cb:ThisObjectID]],
FD === [
sem:[ type: ObjectType,
objectid: ThisObjectID,
png:[num:sing],
centering:[ current:[form: definite,
cb:1],
previous:[cp:0, form:PreviousForm]
],
Mode:[ cat: objtype,
text: TypeText
],
objecttype:ObjectType
],
Mode:[text: template('~w the ~w', [P,TypeText]),
prefix: P,
function: normal,
realized: 1]
],
% not pronoun
( PreviousForm=null; PreviousForm=full; PreviousForm=deictic )
,
given(ObjectType).
*/
%em
%If an object was referred to in the last utterance it may be pronominalised according to its semantics.
%If an object was a pronoun in the last utterance it is excluded from begin referred to by any referring expression other than a pronoun.
component(refexp, en-_, Mode, FD, refexp_pronoun/Function/Word) :-
FD === [
sem:[ type:ObjectType,
png:PNG,
centering:[current:[form:pronoun ],
previous:[form:PreviousForm]
]
],
Mode:[text: template('~w ~w',[P, Word]),
realized: 1,
function: Function,
case:Case,
prefix: P
]
],
given(ObjectType),
/* first pronominalization rule
at least one of the following conditions must hold:
- the currently pronominalized concept did not appear in U(i-1),
- the CB of the current utterance is realized as pronoun
This excludes the case that is forbidden by the rule:
- this element occurred in Cf (u-1), but CB(U) is not realized as pronoun
*/
% ( WasInCF = 0 ; FormOfCurrentCB = pronoun ),
/* it MUST have been realized somehow in the previous utterance */
% not null
( PreviousForm=pronoun; PreviousForm=full; PreviousForm=deictic;PreviousForm=definite ),
/* cheap lexicon access */
pronoun(PNG, Function, Case, Word).
pronoun(PNG, normal, _, 'it') :- PNG === [gend: neut, num: sing].
pronoun(PNG, normal, nom, 'she') :- PNG === [gend: fem, num: sing].
pronoun(PNG, normal, acc, 'her') :- PNG === [gend: fem, num: sing].
pronoun(PNG, normal, nom, 'he') :- PNG === [gend: masc, num: sing].
pronoun(PNG, normal, acc, 'him') :- PNG === [gend: masc, num: sing].
pronoun(PNG, normal, nom, 'they') :- PNG === [num: plural].
pronoun(PNG, normal, acc, 'them') :- PNG === [num: plural].
pronoun(PNG, poss, _, 'its') :- PNG === [gend: neut, num: sing].
pronoun(PNG, poss, _, 'her') :- PNG === [gend: fem, num: sing].
pronoun(PNG, poss, _, 'his') :- PNG === [gend: masc, num: sing].
pronoun(PNG, poss, _, 'their') :- PNG === [num: plural].
%em
%If the screen mode refers to the cb it can use a definite.
%this email/this contact etc. Note that the object must be the cb.
%if underspecified the cb will be instantiated as one.
component(refexp, en-_, Mode, FD, refexp_empty) :-
FD === [
sem:[ type:ObjectType,
centering:[current:[cf: 0,
cb: 0]
]
],
Mode:[text: '',
realized: 0
]
],
given(ObjectType).
% dr
% if underspecified, we don't realize at all.
component(refexp, en-_, Mode, FD, refexp_unspecified) :-
FD === [
sem:[ type:ObjectType,
centering:[current:[cf: 0,
cb: 0]
]
],
Mode:[text: '',
realized: 0 % must be zero, in case it's a complement!
]
],
notgiven(ObjectType),
freeze(ObjectType, fail). % may not be instantiated at a later point in time!
/* these are all the centering transitions */
/* not in use --
the problem is that the cb cannot be determined until it is clear which
or the referring expressions are going to be realized in the utterance.
only one of these - the one that is the highest ranking one in Cf(U i-1) -
will receive 'cb' status.
*/
/*
component(centering_transition, en-_, Mode, FD, continue_cb) :-
FD === [
current:[cb:CBCP, cp:CBCP, form:CBF],
previous:[cb:CBPrev],
utterance:[
cb_form:CBF,
transition:continue]
],
(CBCP = CBPrev ; CBPrev = none ),
CBCP = 1.
component(centering_transition, en-_, Mode, FD, continue_noncb) :-
FD === [
current:[cb:CBCP, cp:CBCP],
previous:[cb:CBPrev],
utterance:[
transition:continue]
],
(CBCP = CBPrev ; CBPrev = none ),
(CBCP = 0; CBCP = none).
component(centering_transition, en-_, Mode, FD, retain_cb/CBPrev/ZeroOrNone) :-
FD === [
current:[cb:1, cp:ZeroOrNone, form:CBF],
previous:[cb:CBPrev],
utterance:[
cb_form:CBF,
transition:retain]
],
(CBPrev = 1 ; CBPrev = none ).
% (ZeroOrNone = 0; ZeroOrNone = none). % to be realized as constrained when possible
component(centering_transition, en-_, Mode, FD, retain_nocb/CBPrev) :-
FD === [
current:[cb:0], % cp is unknown
previous:[cb:CBPrev],
utterance:[
transition:retain]
],
(CBPrev = 1 ; CBPrev = none ).
component(centering_transition, en-_, Mode, FD, retain_none_cb) :-
FD === [
current:[cb:none, cp:NotNone], % cp is unknown
previous:[cb:none], % previously, must be none
utterance:[
transition:retain]
].
% (NotNone = 0; NotNone = 1).
% NotNone to be implemented when constraints are available. otherwise it will only
% generate ambiguous structures or stuff that is pruned lateron.
*/
/* retain, smooth-shift, rough-shift are still missing! */
/* this
*/
/*
component(refexp, en-_, voice, FD, Utterance, refexp_deictic_voice) :-
Utterance === [utterance: [cb:ThisObjectID]],
FD === [
sem: [ png: [num: sing],
objectid: ThisObjectID,
centering: [ current:[
cb:CB,
cp:CP
]
],
type:ObjectType
],
typetext: [
objecttype: ObjectType,
voice: [cat: objtype,
text: TypeText
]
],
voice:[ form:deictic,
prefix:Pre,
realized: 1,
text: template('~w this! ~w', [Pre, TypeText])
],
screen:[ form:full,
realized: 1,
highlighted:1
]
],
% deictics must be either on top of the current CF (deictic)
% on in the CB (discourse-deictic)
when(ground((CB,CF)), ((CB=1;CP=1), !)).
*/
/*
Nota bene:
The CF setting (after grammar application)
has not been implemented yet.
Sorry! dr 09/2004
See my MSc thesis for a definition of the
algorithm that would need to be implemented.
*/
/* no deictics from screen to voice
comm_component(refexp, en-_, screen, FD, Utterance, refexp_deictic_screen) :-
Utterance === [utterance: [cb:ThisObjectID]],
FD === [
sem:[png: [num: sing],
objectid:ThisObjectID,
centering:[ current:[cb:1,
highlighted:1],
utterance:[cb:ThisObjectID]
],
type:ObjectType
],
typetext: [
objecttype: ObjectType,
screen: [cat: objtype,
text: TypeText
]
],
screen:[form:deictic,
prefix:Pre,
realized: 1,
text: template('~w this ~w', [Pre, TypeText])]
].
*/
/* more stuff that is shared between grammars */
% object types
% this translates a single object type (from the knowledge base)
% to a natural language noun
component(objtype, en-_, Mode, FD, objtype_1) :-
(
KBType/Text = email/'e-mail';
KBType/Text = appointment/'appointment';
KBType/Text = document/'document';
KBType/Text = 'contact'/contact;
KBType/Text = 'person'/person
),
FD ===
[
objecttype: KBType,
Mode: [text: Text]
].
mug-workbench/centering.pl 0000644 0000767 0000024 00000020436 10127046041 015673 0 ustar dr staff 0000000 0000000 /*
Centering instantiation
These predicates establish links between the centering information
of each object instance in an utterance, and then between
the utterances -- acording to transitions.
At the end of the process, the transitions should be
decided and the centering information instantiated.
- unfinished -
current issue:
weird cyclism in term, probably bug in replaceSemEntities
Author: David Reitter
$Log: centering.pl,v $
Revision 1.3 2004/06/27 17:46:15 dr
merge with dmdev branch
Revision 1.2.2.2 2004/05/25 14:01:34 dr
get_proptype fix
Revision 1.2.2.1 2004/05/21 20:44:33 dr
removed singleton warning
Revision 1.2 2004/04/02 23:56:47 dr
merged dev branch
Revision 1.1.2.11 2004/04/02 19:12:39 dr
no error message any more when scope attribute and similar stuff is preprocessed
Revision 1.1.2.10 2004/03/31 23:47:04 dr
can determine cb, various improvements
Revision 1.1.2.9 2004/03/31 19:30:30 dr
work on centering. socnet grammar generates the odd pronoun every now and then!
Revision 1.1.2.8 2004/03/31 08:08:35 dr
centering, fixes -- took CB planning out again
Revision 1.1.2.7 2004/03/30 21:52:57 dr
work_on_centering
Revision 1.1.2.6 2004/03/24 01:48:39 dr
new centering architecture implemented: single utterances are realized directly starting with 'multimodal', a discourse is realized with 'discourse'.
Text planning has essentially a separate grammar. The entry point for this is the 'plan' component, which takes discourse semantics in a 'sem' attribute and has a 'plan' attriibute as outcome.
Revision 1.1.2.5 2004/03/23 14:44:13 dr
centering
Revision 1.1.2.4 2004/03/23 01:40:00 dr
dev
Revision 1.1.2.3 2004/03/19 13:28:30 dr
one bugfix in sbt
Revision 1.1.2.2 2004/03/19 13:23:48 dr
one bugfix in sbt (display, used in pfd/1 pretty-printing), which generated cyclic terms when outputting to screen. Also optimization
Revision 1.1.2.1 2004/03/18 21:10:44 dr
first version, still buggy
*/
:- ensure_loaded(tools).
:- ensure_loaded(display).
:- ensure_loaded(debug).
:- use_module('kb_engine', [ get_proptype/3 ]).
% test case
tc :-
ex(demo1, Ex),
linkCenters([Ex], [ExL]),
pfd(ExL).
/*
linkCenters
This takes a list of the entities in the previous utterance
(empty if first utterance), the current utterance FD (U2)
and instantiates an utterance FD with linked entities and
a list of entities in U2.
*/
linkCenters(U1Entities, U2, U2Linked, U2Entities) :-
% find all semantic entities and replace them
replaceSemEntities([x:U2], [x:U2Linked], [], [], ListToLink, ListLinked),
% link all the centers
linkCentersOneUtterance(ListToLink, _, U1Entities, [], U2Entities, ListLinked).
findFocus(FD) :-
replaceSemEntities([x:FD], [x:_], [], [], ToLink, _),
determineCB(ToLink).
%replaceSemEntities(FD, FDNew, ToLink, Linked, ToLink2, Linked2)
% finds all sem. entities in the FD and binds them with a variable
% in ToLink2. Creates a new FD (FDNew) that has the same
% structures, but variables in place of all semantic entities,
% which are listed in Linked2. For each variable in ToLink2, there
% is a variable in Linked2, and FD/FDNew are isomorph (?) via
% the pairs from ToLink2 and Linked2.
replaceSemEntities(FD, FD, ToLink, Linked, ToLink, Linked) :-
(var(FD); atom(FD); integer(FD)), !.
replaceSemEntities([F|R], [F2|R2], ToLink, Linked, ToLink4, Linked4) :- !,
(nonvar(F)
-> (F= A:V;F=V), !,
(true
->
(
replaceSemEntities(V, VR, ToLink2, Linked2, ToLink3, Linked3),
(is_fd(V)
->
fd_read_value(V, type, _, Type),
(is_no_centering_object(Type)
-> V2 = V,
ToLink2 = ToLink,
Linked2 = Linked
; ToLink2 = [VR|ToLink],
Linked2 = [V2|Linked]
)
;
V2 = V,
ToLink2 = ToLink,
Linked2 = Linked
),
F2 = A:V2
)
;
F2=F,
ToLink3 = ToLink,
Linked3 = Linked
)
; F2 = F,
ToLink3 = ToLink,
Linked3 = Linked
),
replaceSemEntities(R, R2, ToLink3, Linked3,ToLink4, Linked4).
% everything else
% for example paths like 'task/email'
replaceSemEntities(FD, FD, ToLink, Linked, ToLink, Linked).
is_no_centering_object(Type) :-
var(Type), !.
% a non-centering object has no 'centering' property
is_no_centering_object(Type) :-
\+ get_proptype(Type, centering, _).
linkCentersOneUtterance([], _, _, Store, Store, []).
linkCentersOneUtterance([F|R], UttCentFD, InstancesPriorUtt, ObjectStorage, StoreAcc, [FNew|RNew]) :-
% instantiate centering prev / current and link them somehow
% the current center has
% fd_bind_value(F, sem, Sem),
% nonvar(Sem),
fd_bind_value(F, objectid, ID),
(var(ID) ->
gensym(obj, ID); true),
% try to find old centering information
% read first matching element in list
(memberchk(ID-_-SemPrev, ObjectStorage)
->
% object was realized previously in this utterance
% read the previous realization info
unif(SemPrev,
[centering:[current:PreviousCentering|_]|_])
;
(memberchk(ID-_-SemPrev, InstancesPriorUtt)
->
% Object was mentioned in previous utt
unif(SemPrev,
[centering:[current:PreviousCentering|_]|_])
;
% Object was not mentioned in previous utt
PreviousCentering = [ cp:0, cb:none, cf:0, form:null |_ ]
)
),
!,
% does this instantiation have centering information?
fd_read_value(F, centering, _, Cent),
(var(Cent)
-> % no, good
F=FNew
; % yes, we need to copy then
copy_term(F, FNew1),
remove_attributes(FNew1, FNew, [centering])
),
% target is FNew
% all FDs share the same utterance structure
unif(FNew, [centering:[previous:PreviousCentering, utterance: UttCentFD|_]|_]),
linkCentersOneUtterance(R, UttCentFD, InstancesPriorUtt, [ID-_-FNew|ObjectStorage], StoreAcc, RNew).
/*
% find out the discourse status
DR: this has to be done with the PREVIOUS utterance, not the current one
we cant do thuis here anyways
discourse old depends on whether it was mentioned and had a form != null somewhere
this can't be done unification wise
only after generation of utterance
that means
1. generate plan (order sentences)
2. linkCenters
3. for each utterance
a) instantiate discourse status depending on previous instantiations
b) generate
c) determine centering transition for utterance
d) optimize via b) and c)
e) determine focus set for U
f) determine cp for U
henschels algorithm defines 'focus set':
everything in U that is discourse_old plus subject
focus attribute:
1 if in focus set
0 if not
pronoun realization if centering:previous:focus:1
strong parallelism: ignore for now.
% read first matching element in list
(memberchk(ID-_-SemPrev2, AllInstances)
->
% object was realized previously in an earlier utterance
% read the previous realization info
fd_read_value(SemPrev2, centering:current:form, 0, Form),
(Form == null
-> Status = discourse_old
; Status = discourse_new
)
; Status = discourse_new
),
*/
/*
the item realized in Ui that has the lowest 'previous:cf' value
greater than zero gets to be the CB
*/
/* at the end, we know that the assumed CB is the actual CB,
so we can bind the value to 1 */
determineCB(L) :-
determineCB(L, 999999, _, _).
% end of recursion, no CB has been found
determineCB([], 999999, _, none) :-!.
% end of recursion, CB was found
determineCB([], _, 1, 0).
/* this won't work because we don't know what exactly is going to be
realized, and what is going to be empty.
therefore, we cannot decide what the CB is going to be! */
determineCB([_ID-_-F|R], CFValue, CBValue, NonCBValue) :-
% unrealized stuff -> null
fd_bind_value(F, centering:current:form, CurrForm),
(var(CurrForm) -> CurrForm=null; true),
fd_read_value(F, centering:previous:cf, 0, PrevCFValue),
((PrevCFValue>0, PrevCFValue (/* found a new CB */
/* bind previously assumed CB to 0 */
CBValue = NonCBValue,
/* the NewCBValue is not instantiated,
but we assume that F is the new CB */
fd_bind_value(F, centering:current:cb, NewCBValue),
NewCFValue = PrevCFValue
)
; (
/* this is not a new CB,
keep the currently assumed CB */
NewCBValue = CBValue,
NewCFValue = CFValue,
/* not the CB */
fd_bind_value(F, centering:current:cb, NonCBValue)
)
),
determineCB(R, NewCFValue, NewCBValue, NonCBValue).
mug-workbench/._CHANGELOG 0000400 0000767 0000000 00000000122 10410110012 014737 0 ustar dr wheel 0000000 0000000 Mac OS X 2 R EMAx mug-workbench/CHANGELOG 0000644 0000767 0000024 00000015217 10410110012 014554 0 ustar dr staff 0000000 0000000 MUG System Fission - Changelog
David Reitter, dreitter at inf.ed.ac.uk
** This file describes overall changes in Fission
** Refer to the CVS logs of source files for more detailed information.
*****************
1.2
A fix to make it compatible with latest (>=5.5) versions of SWI Prolog.
*****************
1.1
small bugs in documentation (./fi instead of ./mug)
took out deictics from big grammar
better warning message if template arguments are bad
assumes default scoring for unknown (new) modes
simple-grammar now has output_mode/1 specification
robust against multiple output_mode declarations
updated one author's e-mail addresses
implemented benchmarking in benchmark.pl
*****************
1.0 - release
*****************
03 June 2004
- many improvements to the workbench. Use of CSS.
- unit tests available from workbench
- SWI-Prolog >=5.3.8 required
- better unification algorithm. demo2 gives additional results now.
- much more documentation, source code refactored and tidied up
- dialogue manager included (incomplete)
- best first search (and best-only search) provided. change setting in fission.pl
*****************
10 Feb 2004
Over the past couple of days, Fission saw massive changes to its internal ongoings.
These contribute to two main achievements:
- Speed and memory optimizations
- Scoring consolidation, improvements
- Error checking
********************************************************************************************
Speed:
********************************************************************************************
- the code responsible for storing intermediate results ready to be used by the
workbench has changed. (SWI specific.) It is now twice as fast, and uses half
the memory. Running the maximum of 100 examples should be manageable again.
- the central unifier was completely rewritten in order to allow for some
optimizations such as minimum remaining values optimization.
The optimization itself could not speed up the process (we're working on it...),
however, the rewrite brought about a 50 percent speed improvement for the
MUG application code (try fist/1 instead of fisd/1). This is evident in YAP as
well, and across several big examples.
Search techniques such as A* search (or at least Branch&Bound) are very hard
to realize in Prolog. Given their known memory requirements, combined with
Prolog's bad performance when copying large terms, it is unclear whether
A*search would really improve things.
- The scoring improvement (see below) speeds up the process further.
Data:
teested with SWI, development (debugging environment), fisd command
and YAP, production environment , fist command
tested on Feb7, 04 CVS main trunk release, Powerbook:
SWI fisd, demo1, 64 variants, 12.34 CPU time, effectively 37.46 seconds (memory swapping)
SWI fisd, ex2, 9 variants, 1.64 CPU in 2.09 seconds
YAP fist, demo1, 2050ms
YAP fist, ex2, 440ms
performance with new revision, Powerbook:
SWI fisd, demo1, 64 variants, 2.94 CPU time, effectively 4.98 seconds
SWI fisd, ex2, 9 variants 1.03 CPU in 1.58 seconds
YAP fist, demo1, 580ms
YAP fist, ex2, 290ms
tested on Feb8, 04 CVS main trunk release, Franka:
YAP fist, demo1, 719ms
YAP fist, ex2, 164ms
performance with new revision (with MRV opt.), Franka:
YAP fist, demo1, 203ms
YAP fist, ex2, 104ms
********************************************************************************************
SCORING:
********************************************************************************************
- The utility score is now computed in two steps: before applying the MUG, an
arithmetic expression is calculated (score:utility:X in the FDs). This way,
we can be sure that every semantic entity is only scored once.
- The scoring model functions for redundant information was improved
- The scoring model has now device coefficients phi (see HLT paper)
- Reading cost on screen is lower than before
********************************************************************************************
ERROR CHECKING
********************************************************************************************
- less screen output when we start ./fi
- syntax errors in the code are marked red
- MUG and KB warnings are yellow now
- the KB serves as a type hierarchy for the FDs.
FDs are not fully typed, but when equipped with a type attribute, they will be checked
against the types defined in the KB. Attributes should be declared and typed in the KB.
Undeclared attributes in typed FDs, values with non-matching types or FDs with non-existing
types will lead to a complaint of the structure checking algorithm (warning only).
FDs in the input and the MUG are checked like this.
This feature is experimental.
Warnings should never break the process. They can be resolved
over time.
********************************************************************************************
UNIT TESTS
********************************************************************************************
- some unit tests produce output
- most unit tests produce "malformed request".
I investigated this and found that the "scope" attribute always (983 cases)
is a prolog term like user_intention/email/bcc instead of a list containing
the scope elements, such as [user_intention/email/bcc]. In 19 cases of several
elements, it is given as a string, i.e. "task/email/to,task/email/cc,task/email/bcc"
Giving a prolog string doesn't really make sense. In 5 cases, the syntax was
scope: "task/email/to,task/email/cc,task/email/bcc,task/email/priority,task/email/body]",
This bugs seem to result from a problem with the excel2mug script and the excel spreadsheets.
My last revision of this left some irregularities.
The output of fission was "malformed request" (as no MUG generation path could be found),
which was correct for these cases.
- assuming that we wanted to keep lists in the scope attribute instead of terms (i think we
talked about this), I changed the excel2mug script accordingly and regenerated the
auto test cases.
- the sockets interface now outputs the request / session ID with its answer, which comes
in handy when you want to trace a problem. Well, the IDs in the
unit tests were 23784 all the time... so I changed that as well in
the excel2mug program.
- Some unit tests still don't work, and for the ones i have taken a look at, this is
not because of technical problems with the engine, but rather missing components in the
MUG or the like:
changelist (see example confirm1) is not an action type in the MUG
inform (see ex inform1) is not yet a task (dialogue act) type in the MUG
To DO:
- scoring, complementarity / redundancy bias, model explicitly
mug-workbench/._compat_gnu.pl 0000400 0000767 0000000 00000000122 10410107133 016230 0 ustar dr wheel 0000000 0000000 Mac OS X 2 R EMAx mug-workbench/compat_gnu.pl 0000644 0000767 0000024 00000014321 10410107133 016040 0 ustar dr staff 0000000 0000000 /*
GNU Prolog compatibility layer
This implements many essential predicates found in SWI Prolog
and many other Prolog implementations that aren't available in GNU Prolog.
Generally, these predicates behave as expected; in exceptional circumstances (i.e. errors/argument instantiation which throw an exception),these predicates may silently fail.
In an implementation that is ready to be compiled (and that's what's GNU Prolog good at), these bugs should have been
eliminated.
Time-complexity and optimization issues may be differ between SWI/GNU. In general, SWI will be much faster at things like flag/3, as we simply use the assert/retract mechanism.
Additionally, you need to include lists.pl from the SWI distribution.
Some predicates cannot be used in their original form:
Use eval_arith/2 instead of is/2 to enable custom functions in GNU/YAP.
Author: David Reitter, reitter at media.mit.edu
-- stealing and copying stuff from various sources, in particular from Jan Wielemaker's SWI Prolog.
Version: $Id: compat_gnu.pl,v 1.6 2004/06/27 17:46:15 dr Exp $
(C) 2003 Media Lab Europe Ltd.
Licensed under the GNU public license.
See end for licensing information.
*/
prolog_verbosity(_).
not(Goal) :- \+ Goal.
% is_list taken from the SWI manual
is_list(X) :-
var(X), !,
fail.
is_list([]).
is_list([_|T]) :-
is_list(T).
succ(I,J) :-
nonvar(I),
I>=0,
J is I+1.
succ(I,J) :-
nonvar(J),
I is J-1,
I>=0.
sformat(String, Templ, Args) :-
open_output_atom_stream(Stream),
format(Stream, Templ, Args),
close_output_atom_stream(Stream, String).
% SWI-Strings are represented as codes-lists in GNU
string_to_atom(Atom, Atom) :-
atom(Atom), !.
string_to_atom(String, Atom) :-
atom_codes(Atom, String).
string(S) :- is_codes(S).
is_codes(X) :-
var(X), !,
fail.
is_codes([]).
is_codes([N|T]) :-
integer(N),
N>0,
N<256,
is_codes(T).
% evaluation
:- dynamic(register_arithmetic/1).
arithmetic_function(Functor/Arity) :-
%print(register_arithmetic(Functor/Arity)),nl,
retractall(register_arithmetic(Functor/Arity)),
assertz(register_arithmetic(Functor/Arity)).
eval_arith(Term, Result) :-
Term =.. [F|Args],
eval_arith2(Args, Args2),
((length(Args2,L),
register_arithmetic(F/L),
append(Args2, [Result], Args3),
ATermN =.. [F|Args3],
ATermN, !)
;
(ATerm =.. [F|Args2],
Result is ATerm % try internal eval routine
)), !.
eval_arith2([], []).
eval_arith2([Term|Rest], [TermResult|RestResult]) :-
eval_arith(Term, TermResult),
eval_arith2(Rest, RestResult).
% rewrite atom into lower case
downcase_atom(Atom, AtomLower) :-
atom_chars(Atom, Chars),
downcase_codes(Chars, CharsLower),
atom_chars(AtomLower, CharsLower).
downcase_codes([],[]).
downcase_codes([F|R], [FL|RL]) :-
lower_upper(FL,F),
downcase_codes(R,RL).
% For all possible Bindings in Cond, Action can be proven.
forall(Cond, Action) :-
Cond,
(Action -> fail
; (!, fail)).
forall(_,_).
flag(Sym, Old, NewExp) :-
g_read(Sym, Old),
nonvar(NewExp) ->
New is NewExp, % evaluate
g_assign(Sym, New)
;
g_read(Sym, New).
% between(Min, Max, X)
% X is a value between Min and Max
% usually used to generate all possible values [Min..Max]
between(Min, Max, _) :-
(var(Min);var(Max)),
write('ERROR: between/3: Arguments are not sufficiently instantiated').
between(Min, Max, X) :-
nonvar(X),
X >= Min,
X =< Max.
between(Min, Max, Min) :-
nonvar(Min),
nonvar(Max),
Min =< Max.
between(Min, Max, X) :-
nonvar(Min),
nonvar(Max),
Min