001 package aima.logic.fol; 002 003 import java.util.ArrayList; 004 import java.util.HashMap; 005 import java.util.HashSet; 006 import java.util.List; 007 import java.util.Map; 008 import java.util.Set; 009 010 import aima.logic.fol.inference.proof.ProofStepRenaming; 011 import aima.logic.fol.kb.data.Chain; 012 import aima.logic.fol.kb.data.Clause; 013 import aima.logic.fol.kb.data.Literal; 014 import aima.logic.fol.parsing.ast.AtomicSentence; 015 import aima.logic.fol.parsing.ast.Sentence; 016 import aima.logic.fol.parsing.ast.Term; 017 import aima.logic.fol.parsing.ast.Variable; 018 019 /** 020 * @author Ciaran O'Reilly 021 * 022 */ 023 public class StandardizeApart { 024 private VariableCollector variableCollector = null; 025 private SubstVisitor substVisitor = null; 026 027 public StandardizeApart() { 028 variableCollector = new VariableCollector(); 029 substVisitor = new SubstVisitor(); 030 } 031 032 public StandardizeApart(VariableCollector variableCollector, 033 SubstVisitor substVisitor) { 034 this.variableCollector = variableCollector; 035 this.substVisitor = substVisitor; 036 } 037 038 // Note: see page 277. 039 public StandardizeApartResult standardizeApart(Sentence aSentence, 040 StandardizeApartIndexical standardizeApartIndexical) { 041 Set<Variable> toRename = variableCollector 042 .collectAllVariables(aSentence); 043 Map<Variable, Term> renameSubstitution = new HashMap<Variable, Term>(); 044 Map<Variable, Term> reverseSubstitution = new HashMap<Variable, Term>(); 045 046 for (Variable var : toRename) { 047 Variable v = null; 048 do { 049 v = new Variable(standardizeApartIndexical.getPrefix() 050 + standardizeApartIndexical.getNextIndex()); 051 // Ensure the new variable name is not already 052 // accidentally used in the sentence 053 } while (toRename.contains(v)); 054 055 renameSubstitution.put(var, v); 056 reverseSubstitution.put(v, var); 057 } 058 059 Sentence standardized = substVisitor.subst(renameSubstitution, 060 aSentence); 061 062 return new StandardizeApartResult(aSentence, standardized, 063 renameSubstitution, reverseSubstitution); 064 } 065 066 public Clause standardizeApart(Clause clause, 067 StandardizeApartIndexical standardizeApartIndexical) { 068 069 Set<Variable> toRename = variableCollector.collectAllVariables(clause); 070 Map<Variable, Term> renameSubstitution = new HashMap<Variable, Term>(); 071 072 for (Variable var : toRename) { 073 Variable v = null; 074 do { 075 v = new Variable(standardizeApartIndexical.getPrefix() 076 + standardizeApartIndexical.getNextIndex()); 077 // Ensure the new variable name is not already 078 // accidentally used in the sentence 079 } while (toRename.contains(v)); 080 081 renameSubstitution.put(var, v); 082 } 083 084 if (renameSubstitution.size() > 0) { 085 List<Literal> literals = new ArrayList<Literal>(); 086 087 for (Literal l : clause.getLiterals()) { 088 literals.add(substVisitor.subst(renameSubstitution, l)); 089 } 090 Clause renamed = new Clause(literals); 091 renamed.setProofStep(new ProofStepRenaming(renamed, 092 clause.getProofStep())); 093 return renamed; 094 } 095 096 return clause; 097 } 098 099 public Chain standardizeApart(Chain chain, 100 StandardizeApartIndexical standardizeApartIndexical) { 101 102 Set<Variable> toRename = variableCollector.collectAllVariables(chain); 103 Map<Variable, Term> renameSubstitution = new HashMap<Variable, Term>(); 104 105 for (Variable var : toRename) { 106 Variable v = null; 107 do { 108 v = new Variable(standardizeApartIndexical.getPrefix() 109 + standardizeApartIndexical.getNextIndex()); 110 // Ensure the new variable name is not already 111 // accidentally used in the sentence 112 } while (toRename.contains(v)); 113 114 renameSubstitution.put(var, v); 115 } 116 117 if (renameSubstitution.size() > 0) { 118 List<Literal> lits = new ArrayList<Literal>(); 119 120 for (Literal l : chain.getLiterals()) { 121 AtomicSentence atom = (AtomicSentence) substVisitor.subst( 122 renameSubstitution, l.getAtomicSentence()); 123 lits.add(l.newInstance(atom)); 124 } 125 126 Chain renamed = new Chain(lits); 127 128 renamed.setProofStep(new ProofStepRenaming(renamed, 129 chain.getProofStep())); 130 131 return renamed; 132 } 133 134 return chain; 135 } 136 137 public Map<Variable, Term> standardizeApart(List<Literal> l1Literals, 138 List<Literal> l2Literals, 139 StandardizeApartIndexical standardizeApartIndexical) { 140 Set<Variable> toRename = new HashSet<Variable>(); 141 142 for (Literal pl : l1Literals) { 143 toRename.addAll(variableCollector.collectAllVariables(pl 144 .getAtomicSentence())); 145 } 146 for (Literal nl : l2Literals) { 147 toRename.addAll(variableCollector.collectAllVariables(nl 148 .getAtomicSentence())); 149 } 150 151 Map<Variable, Term> renameSubstitution = new HashMap<Variable, Term>(); 152 153 for (Variable var : toRename) { 154 Variable v = null; 155 do { 156 v = new Variable(standardizeApartIndexical.getPrefix() 157 + standardizeApartIndexical.getNextIndex()); 158 // Ensure the new variable name is not already 159 // accidentally used in the sentence 160 } while (toRename.contains(v)); 161 162 renameSubstitution.put(var, v); 163 } 164 165 List<Literal> posLits = new ArrayList<Literal>(); 166 List<Literal> negLits = new ArrayList<Literal>(); 167 168 for (Literal pl : l1Literals) { 169 posLits.add(substVisitor.subst(renameSubstitution, pl)); 170 } 171 for (Literal nl : l2Literals) { 172 negLits.add(substVisitor.subst(renameSubstitution, nl)); 173 } 174 175 l1Literals.clear(); 176 l1Literals.addAll(posLits); 177 l2Literals.clear(); 178 l2Literals.addAll(negLits); 179 180 return renameSubstitution; 181 } 182 }