package warnings; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Stack; import parser.ASTvar; import parser.SparcTranslatorTreeConstants; public class PrologRule { ArrayList<PrologRuleAtom> bodyAtoms; public PrologRule() { bodyAtoms = new ArrayList<PrologRuleAtom>(); } public void addRelAtom(Term term1, Term term2, Relation rel, boolean isArithmetic) { bodyAtoms.add(new PrologRuleRelAtom(term1, term2, rel, isArithmetic)); } public void addNonRelAtom(String atomName, Term term, boolean negated) { bodyAtoms.add(new PrologRuleNonRelAtom(atomName, term, negated)); } public void addRangeAtom(Term term, long lowest, long highest) { bodyAtoms.add(new PrologRuleRangeAtom(term, lowest, highest)); } public void addLabelingAtom(HashSet<String> arithmeticVariables) { bodyAtoms.add(new PrologRuleLabelingAtom(arithmeticVariables)); } public void addVarRangeAtom(HashSet<String> arithmeticVariables) { bodyAtoms.add(new PrologRuleVarRangeAtom(arithmeticVariables)); } public void addIsAtom(String variableName, Term term) { bodyAtoms.add(new PrologRuleIsAtom(variableName, term)); } public String toString() { StringBuilder ruleStr = new StringBuilder(); ruleStr.append(getHeadAtom()); ArrayList<String> atomStrings = new ArrayList<String>(bodyAtoms.size()); for (PrologRuleAtom atom : bodyAtoms) { atomStrings.add(atom.toString()); } if (bodyAtoms.size() != 0) { ruleStr.append(" :- "); if (bodyAtoms.size() != 0) { ruleStr.append(StringListUtils.getSeparatedList(atomStrings, ",")); } } ruleStr.append("."); ruleStr.append(System.getProperty("line.separator")); return ruleStr.toString(); } public String getHeadAtom() { return "p"; } /** * Replace all arithmetic atoms occuring in non-relation atoms * by new variables and add "is" statements to the body * @return the set of the variables which were introduced during the process */ public HashSet<String> fetchArithmeticsIntoIsAtoms() { HashSet<String> newVariables=new HashSet<String>(); HashSet<String> usedVariables = new HashSet<String>(); for (PrologRuleAtom atom : bodyAtoms) { usedVariables.addAll(atom.getVariables()); } UniqueNameGenerator ugen = new UniqueNameGenerator(); ugen.addUsedNames(usedVariables); ArrayList<PrologRuleAtom> isAtoms = new ArrayList<PrologRuleAtom>(); HashMap<String, String> termToVariable = new HashMap<String, String>(); for (PrologRuleAtom atom : bodyAtoms) { if (atom.type == PrologRuleAtomType.nonrel) { String argumentString = ((PrologRuleNonRelAtom) atom).argument .toString(); if (argumentString.indexOf('-') != -1 || argumentString.indexOf('+') != -1 || argumentString.indexOf('*') != -1 || argumentString.indexOf('/') != -1) { String varName; if (!termToVariable.containsKey(argumentString)) { varName = ugen.generateNewName(); newVariables.add(varName); termToVariable.put(argumentString, varName); isAtoms.add(new PrologRuleIsAtom(varName, ((PrologRuleNonRelAtom) atom).argument)); } else { varName = termToVariable.get(argumentString); } ASTvar var = new ASTvar(SparcTranslatorTreeConstants.JJTVAR); var.image = varName; ((PrologRuleNonRelAtom) atom).argument = new Term(var); } } } for(PrologRuleAtom isAtom:isAtoms) { this.bodyAtoms.add(isAtom); } return newVariables; } public void reorderBodyAtoms() { ArrayList<PrologRuleAtom> orderedBodyAtoms = new ArrayList<PrologRuleAtom>( bodyAtoms.size()); boolean connected[][] = new boolean[bodyAtoms.size()][bodyAtoms.size()]; for (int i = 0; i < bodyAtoms.size(); i++) { for (int j = 0; j < bodyAtoms.size(); j++) { if (i == j) continue; if (!Collections.disjoint(bodyAtoms.get(i).getVariables(), bodyAtoms.get(j).getVariables())) { connected[i][j] = true; connected[j][i] = true; } } } boolean[] was = new boolean[bodyAtoms.size()]; for (int i = 0; i < bodyAtoms.size(); i++) { if (was[i] == true) continue; Stack<Integer> stack = new Stack<Integer>(); stack.push(i); while (!stack.isEmpty()) { int peek = stack.peek(); was[peek] = true; stack.pop(); orderedBodyAtoms.add(bodyAtoms.get(peek)); for (int j = 0; j < bodyAtoms.size(); j++) { if (!was[j] && connected[i][j]) { stack.push(j); } } } } bodyAtoms = orderedBodyAtoms; } }