package translating; import java.util.ArrayList; import java.util.HashSet; import parser.ASTaggregateElement; import parser.ASTarithmeticTerm; import parser.ASTatom; import parser.ASTchoice_element; import parser.ASTprogramRule; import parser.ASTterm; import parser.ASTvar; import parser.SimpleNode; import parser.SparcTranslatorTreeConstants; /** * This class fetches arithmetic expressions from atoms' arguments to fix * well-known DLV issue with arithmetics expressions For each arithmetic * expression new variable is created, and arithmetic term is assigned to the * variable. Atom representing this new assignment is moved to the body of * corresponding rule Example: p(X+1). becomes p(Y):-Y=X+1. The list of such * atoms is returned by functions fetch(Global|Local) variables */ public class ExpressionFetcher { HashSet<String> usedVariableNames; // mapping from creating variables to arithmetic expressions found in atoms ExpressionSplitter exprSplitter; /** * @param a * set variables used in rule they will not be used for new * variable names */ public ExpressionFetcher(HashSet<String> set) { this.usedVariableNames = set; exprSplitter=new ExpressionSplitter(set); } /** * @param program * rule where atoms will be searched * @return atoms of the form var_name = [arithmetic expression], where * [arithmetic_expression] goes over all possible regular expression * from the rule */ public ArrayList<ASTatom> fetchGlobalExpressions(ASTprogramRule rule) { return fetchExpressions(rule, true); } /** * @param aggregate * element to be explored * @return list of atoms of the form var_name = [arithmetic expression], * where [arithmetic_expression] goes over all possible regular * expression from the aggregate element */ public ArrayList<ASTatom> fetchLocalExpressions(ASTaggregateElement elem) { return fetchExpressions(elem, false); } /** * @param choice * rule element where arithmetic atoms will be searched. * @return list of atoms of the form var_name = [arithmetic expression], * where [arithmetic_expression] goes over all possible regular * expression from the choice rule element */ public ArrayList<ASTatom> fetchLocalExpressions(ASTchoice_element elem) { return fetchExpressions(elem, false); } /** * Fetch expressions from given AST node and return a list of found * expression. * * @param n * node to be explored * @param ignoreLocals * if the parameter is true, choice rules and aggregates are * @return list of atoms which were built */ private ArrayList<ASTatom> fetchExpressions(SimpleNode n, boolean ignoreLocals) { // ignore choice rules and aggregates in case ignore locals was set to // true ArrayList<ASTatom> result = new ArrayList<ASTatom>(); if (ignoreLocals && (n.getId() == SparcTranslatorTreeConstants.JJTAGGREGATE || n .getId() == SparcTranslatorTreeConstants.JJTCHOICE_RULE)) { return result; } if (n.getId() == SparcTranslatorTreeConstants.JJTARITHMETICTERM) { // we are only interested in arithmetic terms which are not // supported by DLV ,i.e, it those with operation signs if (n.toString().indexOf('-') != -1 || n.toString().indexOf('+') != -1 || n.toString().indexOf('*') != -1 || n.toString().indexOf('/') != -1) { ASTterm newTerm=exprSplitter.split((ASTarithmeticTerm)n,result); ASTvar newVar=new ASTvar(SparcTranslatorTreeConstants.JJTVAR); newVar.image=newTerm.toString(); n.jjtAddChild(newVar, 0); } } for (int i = 0; i < n.jjtGetNumChildren(); i++) { result.addAll(fetchExpressions((SimpleNode) (n.jjtGetChild(i)), ignoreLocals)); } return result; } }