001 /* 002 * Created on Sep 20, 2004 003 * 004 */ 005 package aima.logic.fol; 006 007 import java.util.ArrayList; 008 import java.util.List; 009 import java.util.Map; 010 011 import aima.logic.fol.kb.data.Literal; 012 import aima.logic.fol.parsing.AbstractFOLVisitor; 013 import aima.logic.fol.parsing.ast.AtomicSentence; 014 import aima.logic.fol.parsing.ast.Function; 015 import aima.logic.fol.parsing.ast.QuantifiedSentence; 016 import aima.logic.fol.parsing.ast.Sentence; 017 import aima.logic.fol.parsing.ast.Term; 018 import aima.logic.fol.parsing.ast.Variable; 019 020 /** 021 * @author Ravi Mohan 022 * @author Ciaran O'Reilly 023 */ 024 public class SubstVisitor extends AbstractFOLVisitor { 025 026 public SubstVisitor() { 027 } 028 029 /** 030 * Note: Refer to Artificial Intelligence A Modern Approach (2nd Edition): 031 * page 273. 032 * 033 * @param theta 034 * a substitution. 035 * @param aSentence 036 * the substitution has been applied to. 037 * @return a new Sentence representing the result of applying the 038 * substitution theta to aSentence. 039 * 040 */ 041 public Sentence subst(Map<Variable, Term> theta, Sentence aSentence) { 042 return (Sentence) aSentence.accept(this, theta); 043 } 044 045 public Term subst(Map<Variable, Term> theta, Term aTerm) { 046 return (Term) aTerm.accept(this, theta); 047 } 048 049 public Function subst(Map<Variable, Term> theta, Function aFunction) { 050 return (Function) aFunction.accept(this, theta); 051 } 052 053 public Literal subst(Map<Variable, Term> theta, Literal aLiteral) { 054 return aLiteral.newInstance( 055 (AtomicSentence) aLiteral.getAtomicSentence().accept(this, 056 theta)); 057 } 058 059 @SuppressWarnings("unchecked") 060 @Override 061 public Object visitVariable(Variable variable, Object arg) { 062 Map<Variable, Term> substitution = (Map<Variable, Term>) arg; 063 if (substitution.containsKey(variable)) { 064 return substitution.get(variable).copy(); 065 } 066 return variable.copy(); 067 } 068 069 @SuppressWarnings("unchecked") 070 @Override 071 public Object visitQuantifiedSentence(QuantifiedSentence sentence, 072 Object arg) { 073 074 Map<Variable, Term> substitution = (Map<Variable, Term>) arg; 075 076 Sentence quantified = sentence.getQuantified(); 077 Sentence quantifiedAfterSubs = (Sentence) quantified.accept(this, arg); 078 079 List<Variable> variables = new ArrayList<Variable>(); 080 for (Variable v : sentence.getVariables()) { 081 Term st = substitution.get(v); 082 if (null != st) { 083 if (st instanceof Variable) { 084 // Only if it is a variable to I replace it, otherwise 085 // I drop it. 086 variables.add((Variable) st.copy()); 087 } 088 } else { 089 // No substitution for the quantified variable, so 090 // keep it. 091 variables.add(v.copy()); 092 } 093 } 094 095 // If not variables remaining on the quantifier, then drop it 096 if (variables.size() == 0) { 097 return quantifiedAfterSubs; 098 } 099 100 return new QuantifiedSentence(sentence.getQuantifier(), variables, 101 quantifiedAfterSubs); 102 } 103 }