% This file is part of the Attempto Parsing Engine (APE). % Copyright 2008-2013, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch). % % The Attempto Parsing Engine (APE) is free software: you can redistribute it and/or modify it % under the terms of the GNU Lesser General Public License as published by the Free Software % Foundation, either version 3 of the License, or (at your option) any later version. % % The Attempto Parsing Engine (APE) is distributed in the hope that it will be useful, but WITHOUT % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR % PURPOSE. See the GNU Lesser General Public License for more details. % % You should have received a copy of the GNU Lesser General Public License along with the Attempto % Parsing Engine (APE). If not, see http://www.gnu.org/licenses/. :- module(drs_to_ruleml, [ drs_to_ruleml/2 ]). /** Attempto DRS to RuleML/folog converter This module converts the Attempto DRS into RuleML/folog as specified by David Hirtle in his thesis. @author Kaarel Kaljurand @author Tobias Kuhn @version 2012-08-23 @see http://www.ruleml.org/translator/ @bug Test RuleML validity. @bug Test correspondence to Hirtle's specification. E.g. DRSs resulting from query sentences are currently incorrectly supported. (Note that Hirtle just rejects such DRSs.) @bug Support ACE 5/5.5/6 extensions (e.g. RuleML supports NAF). */ % The following operators are used in the DRS. :- op(400, fx, -). :- op(500, xfx, =>). :- op(500, xfx, v). %% drs_to_ruleml(+Drs:drs, -RuleML:functor) is det. % % Turn the DRS into RuleML/folog (in SWI Prolog's internal XML format) % as specified in David Hirtle's thesis. drs_to_ruleml( DRS, element('RuleML', [], [ element('Assert', [], Elements) ]) ) :- existdrs_els(DRS, Elements). %% conds_and(+Conds:list, -Element:functor) is det. % % Converts a list of DRS conditions into a RuleML and-element. conds_and(Conds, ElementsOut) :- conds_elements(Conds, Elements), conds_and_x(Elements, ElementsOut). conds_and_x([Element], Element) :- !. conds_and_x(Elements, element('And', [], Elements)). %% conds_elements(+Conds:list, -Elements:list) is det. % % Converts a list of DRS conditions into RuleML elements. conds_elements([], []). conds_elements([Cond | Tail], [SCond | STail]) :- cond_element(Cond, SCond), conds_elements(Tail, STail). %% cond_element(+Condition:functor, -Element:functor) is det. % % Converts a DRS condition into a RuleML element. % % As the structure of the DRS doesn't match exactly to the structure % of the RuleML element (as specified by Hirtle), % we have to do some ugly appending. cond_element(drs(Dom1, Conds1) => DRS2, element('Forall', [], SubElements0) ) :- args_els(Dom1, VarElements1), conds_and(Conds1, Element1), existdrs_els(DRS2, SubElements2), append([Element1], SubElements2, SubElements1), append(VarElements1, [element('Implies', [], SubElements1)], SubElements0). cond_element(DRS1 v DRS2, element('Or', [], SubElements0) ) :- existdrs_els(DRS1, SubElements1), existdrs_els(DRS2, SubElements2), append(SubElements1, SubElements2, SubElements0). cond_element(-DRS, element('Neg', [], SubElements)) :- existdrs_els(DRS, SubElements). cond_element(Conds, Element) :- is_list(Conds), conds_and(Conds, Element). cond_element(Condition-_, element('Atom', [], [element('Rel', [], [Functor]) | Els])) :- Condition =.. [Functor | Args], args_els(Args, Els). %% args_els(+List:list, -Elements:list) is det. % % Converts the arguments of a DRS condition into RuleML elements. % % Note that all terms (e.g. variables and numbers) must be converted into atoms % to be compatible with the way how SWI represents XML % documents internally. args_els([], []). args_els([H | T], [element('Var', [], [HH]) | ElsTail]) :- var(H), !, term_to_atom(H, HH), args_els(T, ElsTail). args_els([H | T], [element('Data', [], [HH]) | ElsTail]) :- number(H), !, term_to_atom(H, HH), % alternatively: atom_number(HH, H) args_els(T, ElsTail). args_els([H | T], [element('Ind', [], [H]) | ElsTail]) :- args_els(T, ElsTail). %% existdrs_els(+Drs:drs, -Elements:list) is det. % % Converts an existential DRS box into RuleML elements. existdrs_els(drs([],Conds), [Element]) :- !, conds_and(Conds, Element). existdrs_els(drs(Dom,Conds), [element('Exists', [], Elements)]) :- args_els(Dom, DomElements), conds_and(Conds, Element), append(DomElements, [Element], Elements). %% to_xml(+Elements:list, -Xml:atom) is det. % % @param Elements is a list of XML elements % @param Xml is an XML document as an atom % % @deprecated use SWI's xml_write/3 instead % % Converts SWI Prolog's XML represenation into an XML atom. % Something like xml_write/3 but very simple. to_xml([], ''). to_xml([element(Name, _, Elements) | T], Xml) :- to_xml(Elements, ElXml), to_xml(T, TXml), format(atom(Xml), '<~w>~w~n~w', [Name, ElXml, Name, TXml]). to_xml([Text | T], Xml) :- atom(Text), to_xml(T, TXml), format(atom(Xml), '~w~w', [Text, TXml]).