% This file is part of AceRules. % Copyright 2008-2012, Tobias Kuhn, http://www.tkuhn.ch % % AceRules 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. % % AceRules 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 AceRules. If % not, see http://www.gnu.org/licenses/. :- module(simple_rules, [ simple_rules/2 % +Rules, -SimpleRules ]). :- use_module(op_defs). :- use_module(list_utils). :- use_module(logger). /** Simple rules This module generates a simple and concise rule representation on the basis of the internal rule representation of AceRules. The simple rules are not completely equivalent to the internal representation: * "Something", "everybody", etc. are represented in the same way as nouns. That means that they do not unify with other objects (as they do in the internal format). * maybe more... @author Tobias Kuhn @version 2008-11-24 */ %% simple_rules(+Rules, -SimpleRules) % % Transforms the rules in internal format into the simple rule format. simple_rules(Rules, SimpleRules) :- retractall(var_data(_,_)), copy_term(Rules, RulesCopy), % just to be sure... simple_rules_x(RulesCopy, RulesTemp), transform_data_values(RulesTemp, SimpleRules). simple_rules_x([], []) :- !. simple_rules_x([(_Label, Head, [])|RestIn], RestOut) :- transform_list([Head], []), !, simple_rules_x(RestIn, RestOut). simple_rules_x([(Label, Head, Body)|RestIn], [(Label, HeadT, BodyT)|RestOut]) :- transform_list([Head], [HeadT]), transform_list(Body, BodyT), !, simple_rules_x(RestIn, RestOut). simple_rules_x([Rule|RestIn], [Rule|RestOut]) :- simple_rules_x(RestIn, RestOut). %% transform_list(+ListIn, -ListOut) % % Transforms a list of conditions into the simple rule format. transform_list([], []). transform_list([-Pred|RestIn], [-PredT|RestOut]) :- !, transform_list([Pred], [PredT]), transform_list(RestIn, RestOut). transform_list([~Pred|RestIn], [~PredT|RestOut]) :- !, transform_list([Pred], [PredT]), transform_list(RestIn, RestOut). transform_list([can([Pred])|RestIn], [can(PredT)|RestOut]) :- !, transform_list([Pred], [PredT]), transform_list(RestIn, RestOut). transform_list([can(ListIn)|RestIn], [can(ListOut)|RestOut]) :- !, transform_list(ListIn, ListOut), transform_list(RestIn, RestOut). transform_list([must([Pred])|RestIn], [must(PredT)|RestOut]) :- !, transform_list([Pred], [PredT]), transform_list(RestIn, RestOut). transform_list([must(ListIn)|RestIn], [must(ListOut)|RestOut]) :- !, transform_list(ListIn, ListOut), transform_list(RestIn, RestOut). transform_list([group([Pred])|RestIn], [PredT|RestOut]) :- !, transform_list([Pred], [PredT]), transform_list(RestIn, RestOut). transform_list([group(Group)|RestIn], [group(GroupT)|RestOut]) :- !, transform_list(Group, GroupT), transform_list(RestIn, RestOut). transform_list([object(R, Noun, _, _, _, _)|RestIn], [PredOut|RestOut]) :- is_var_or_skolem(Noun), !, transform_ref(R, RT), PredOut =.. [something, RT], transform_list(RestIn, RestOut). transform_list([object(_, na, _, _, _, _)|RestIn], RestOut) :- % group objects !, transform_list(RestIn, RestOut). transform_list([object(_, _, named, _, _, _)|RestIn], RestOut) :- !, transform_list(RestIn, RestOut). transform_list([object(R, Value, data, _, _, _)|RestIn], RestOut) :- var(R), !, R = Value, transform_list(RestIn, RestOut). transform_list([object(R, Value, data, _, _, _)|RestIn], RestOut) :- !, transform_ref(R, RT), assert_var_data(RT, Value), transform_list(RestIn, RestOut). transform_list([object(R, Noun, _, _, _, _)|RestIn], [PredOut|RestOut]) :- !, transform_ref(R, RT), PredOut =.. [Noun, RT], transform_list(RestIn, RestOut). transform_list([property(R, Adj, _D)|RestIn], [PredOut|RestOut]) :- !, transform_ref(R, RT), PredOut =.. [Adj, RT], transform_list(RestIn, RestOut). transform_list([property(A, Adj, _D, B)|RestIn], [PredOut|RestOut]) :- !, transform_ref(A, AT), transform_ref(B, BT), PredOut =.. [Adj, AT, BT], transform_list(RestIn, RestOut). transform_list([property(A, Adj, B, _D, _T, C)|RestIn], [PredOut|RestOut]) :- !, transform_ref(A, AT), transform_ref(B, BT), transform_ref(C, CT), PredOut =.. [Adj, AT, BT, CT], transform_list(RestIn, RestOut). transform_list([of_relation(object(A,Noun,_,_,_,_),B)|RestIn], [PredOut|RestOut]) :- !, transform_ref(A, AT), transform_ref(B, BT), PredOut = of(Noun, AT, BT), transform_list(RestIn, RestOut). transform_list([pred_mod(Verb, A, Mods)|RestIn], [PredOut|RestOut]) :- !, transform_ref(A, AT), transform_mods(Mods, ModsT), PredOut =.. [Verb, AT, ModsT], transform_list(RestIn, RestOut). transform_list([pred_mod(Verb, A, B, Mods)|RestIn], [PredOut|RestOut]) :- !, transform_ref(A, AT), transform_ref(B, BT), transform_mods(Mods, ModsT), PredOut =.. [Verb, AT, BT, ModsT], transform_list(RestIn, RestOut). transform_list([pred_mod(Verb, A, B, C, Mods)|RestIn], [PredOut|RestOut]) :- !, transform_ref(A, AT), transform_ref(B, BT), transform_ref(C, CT), transform_mods(Mods, ModsT), PredOut =.. [Verb, AT, BT, CT, ModsT], transform_list(RestIn, RestOut). transform_list([be_adj(A, Adj, _, Mods)|RestIn], [PredOut|RestOut]) :- !, transform_ref(A, AT), transform_mods(Mods, ModsT), PredOut =.. [Adj, AT, ModsT], transform_list(RestIn, RestOut). transform_list([has_part(G, P)|RestIn], [PredOut|RestOut]) :- !, transform_ref(G, GT), transform_ref(P, PT), PredOut = has_part(GT, PT), transform_list(RestIn, RestOut). transform_list([Pred|RestIn], [Pred|RestOut]) :- transform_list(RestIn, RestOut). %% transform_mods(+Modifiers, -Desc, -Refs) % % Transforms a list of modifiers into a description and the list % of referents (for the PPs). The description is a list of atoms % that contains the names of the modifiers separated by underscores. transform_mods(ModsIn, ModsOut) :- transform_mods_x(ModsIn, ModsTemp), reverse(ModsTemp, ModsOut). transform_mods_x([], []). transform_mods_x([modifier_adv(Adv, _D)|Mods], [Adv|RestOut]) :- !, transform_mods_x(Mods, RestOut). transform_mods_x([modifier_pp(Prep, R)|Mods], [PrepTerm|RestOut]) :- transform_ref(R, RT), PrepTerm =.. [Prep, RT], transform_mods_x(Mods, RestOut). %% transform_ref(+RefIn, -RefOut) % % Transforms a (possibly skolemized) discourse referent into a % shorter form. Concretely, these transformations are done: % % == % X => X % v('John') => 'John' % v(3) => v(3) % gv(5) => gv(5) % == transform_ref(V, VT) :- var(V), !, VT = V. transform_ref(v(A), A) :- atom(A), !. transform_ref(R, R). %% is_var_or_skolem(+Term) % % Succeeds if the term is a variable or a skolemized variable. is_var_or_skolem(V) :- var(V), !. is_var_or_skolem(v(_)). is_var_or_skolem(gv(_)). :- dynamic(var_data/2). assert_var_data(Var, _) :- var_data(Var, _), !, log('simple-rules.UnificationError'), throw(error('simple-rules.UnificationError', 'Unification failed for simple rules generation.')). assert_var_data(Var, Data) :- assert(var_data(Var, Data)). %% transform_data_values(+TermIn, -TermOut) transform_data_values(Var, Var) :- var(Var), !. transform_data_values(TermIn, Data) :- var_data(TermIn, Data), !. transform_data_values([], []) :- !. transform_data_values([H1|T1], [H2|T2]) :- !, transform_data_values(H1, H2), transform_data_values(T1, T2). transform_data_values(Term, Term) :- Term =.. [Term], !. transform_data_values(Term1, Term2) :- !, Term1 =.. List1, transform_data_values(List1, List2), Term2 =.. List2.