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;
}
}