package aima.core.logic.fol;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import aima.core.logic.fol.kb.data.Literal;
import aima.core.logic.fol.parsing.AbstractFOLVisitor;
import aima.core.logic.fol.parsing.ast.AtomicSentence;
import aima.core.logic.fol.parsing.ast.Function;
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.Variable;
/**
* @author Ravi Mohan
* @author Ciaran O'Reilly
*/
public class SubstVisitor extends AbstractFOLVisitor {
public SubstVisitor() {
}
/**
* Note: Refer to Artificial Intelligence A Modern Approach (3rd Edition):
* page 323.
*
* @param theta
* a substitution.
* @param sentence
* the substitution has been applied to.
* @return a new Sentence representing the result of applying the
* substitution theta to aSentence.
*
*/
public Sentence subst(Map<Variable, Term> theta, Sentence sentence) {
return (Sentence) sentence.accept(this, theta);
}
public Term subst(Map<Variable, Term> theta, Term aTerm) {
return (Term) aTerm.accept(this, theta);
}
public Function subst(Map<Variable, Term> theta, Function function) {
return (Function) function.accept(this, theta);
}
public Literal subst(Map<Variable, Term> theta, Literal literal) {
return literal.newInstance((AtomicSentence) literal
.getAtomicSentence().accept(this, theta));
}
@SuppressWarnings("unchecked")
@Override
public Object visitVariable(Variable variable, Object arg) {
Map<Variable, Term> substitution = (Map<Variable, Term>) arg;
if (substitution.containsKey(variable)) {
return substitution.get(variable).copy();
}
return variable.copy();
}
@SuppressWarnings("unchecked")
@Override
public Object visitQuantifiedSentence(QuantifiedSentence sentence,
Object arg) {
Map<Variable, Term> substitution = (Map<Variable, Term>) arg;
Sentence quantified = sentence.getQuantified();
Sentence quantifiedAfterSubs = (Sentence) quantified.accept(this, arg);
List<Variable> variables = new ArrayList<Variable>();
for (Variable v : sentence.getVariables()) {
Term st = substitution.get(v);
if (null != st) {
if (st instanceof Variable) {
// Only if it is a variable to I replace it, otherwise
// I drop it.
variables.add((Variable) st.copy());
}
} else {
// No substitution for the quantified variable, so
// keep it.
variables.add(v.copy());
}
}
// If not variables remaining on the quantifier, then drop it
if (variables.size() == 0) {
return quantifiedAfterSubs;
}
return new QuantifiedSentence(sentence.getQuantifier(), variables,
quantifiedAfterSubs);
}
}