package aima.core.logic.fol; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import aima.core.logic.fol.kb.data.Chain; import aima.core.logic.fol.kb.data.Clause; import aima.core.logic.fol.kb.data.Literal; import aima.core.logic.fol.parsing.FOLVisitor; import aima.core.logic.fol.parsing.ast.ConnectedSentence; import aima.core.logic.fol.parsing.ast.Constant; import aima.core.logic.fol.parsing.ast.Function; import aima.core.logic.fol.parsing.ast.NotSentence; import aima.core.logic.fol.parsing.ast.Predicate; import aima.core.logic.fol.parsing.ast.QuantifiedSentence; import aima.core.logic.fol.parsing.ast.Sentence; import aima.core.logic.fol.parsing.ast.Term; import aima.core.logic.fol.parsing.ast.TermEquality; import aima.core.logic.fol.parsing.ast.Variable; /** * @author Ciaran O'Reilly * */ public class StandardizeApartInPlace { // private static CollectAllVariables _collectAllVariables = new CollectAllVariables(); public static int standardizeApart(Chain c, int saIdx) { List<Variable> variables = new ArrayList<Variable>(); for (Literal l : c.getLiterals()) { collectAllVariables(l.getAtomicSentence(), variables); } return standardizeApart(variables, c, saIdx); } public static int standardizeApart(Clause c, int saIdx) { List<Variable> variables = new ArrayList<Variable>(); for (Literal l : c.getLiterals()) { collectAllVariables(l.getAtomicSentence(), variables); } return standardizeApart(variables, c, saIdx); } // // PRIVATE METHODS // private static int standardizeApart(List<Variable> variables, Object expr, int saIdx) { Map<String, Integer> indexicals = new HashMap<String, Integer>(); for (Variable v : variables) { if (!indexicals.containsKey(v.getIndexedValue())) { indexicals.put(v.getIndexedValue(), saIdx++); } } for (Variable v : variables) { Integer i = indexicals.get(v.getIndexedValue()); if (null == i) { throw new RuntimeException("ERROR: duplicate var=" + v + ", expr=" + expr); } else { v.setIndexical(i); } } return saIdx; } private static void collectAllVariables(Sentence s, List<Variable> vars) { s.accept(_collectAllVariables, vars); } } class CollectAllVariables implements FOLVisitor { public CollectAllVariables() { } @SuppressWarnings("unchecked") public Object visitVariable(Variable var, Object arg) { List<Variable> variables = (List<Variable>) arg; variables.add(var); return var; } @SuppressWarnings("unchecked") public Object visitQuantifiedSentence(QuantifiedSentence sentence, Object arg) { // Ensure I collect quantified variables too List<Variable> variables = (List<Variable>) arg; variables.addAll(sentence.getVariables()); sentence.getQuantified().accept(this, arg); return sentence; } public Object visitPredicate(Predicate predicate, Object arg) { for (Term t : predicate.getTerms()) { t.accept(this, arg); } return predicate; } public Object visitTermEquality(TermEquality equality, Object arg) { equality.getTerm1().accept(this, arg); equality.getTerm2().accept(this, arg); return equality; } public Object visitConstant(Constant constant, Object arg) { return constant; } public Object visitFunction(Function function, Object arg) { for (Term t : function.getTerms()) { t.accept(this, arg); } return function; } public Object visitNotSentence(NotSentence sentence, Object arg) { sentence.getNegated().accept(this, arg); return sentence; } public Object visitConnectedSentence(ConnectedSentence sentence, Object arg) { sentence.getFirst().accept(this, arg); sentence.getSecond().accept(this, arg); return sentence; } }