aima.core.logic.fol.inference.Demodulation Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aima-core Show documentation
Show all versions of aima-core Show documentation
AIMA-Java Core Algorithms from the book Artificial Intelligence a Modern Approach 3rd Ed.
package aima.core.logic.fol.inference;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import aima.core.logic.fol.inference.proof.ProofStepClauseDemodulation;
import aima.core.logic.fol.kb.data.Clause;
import aima.core.logic.fol.kb.data.Literal;
import aima.core.logic.fol.parsing.ast.AtomicSentence;
import aima.core.logic.fol.parsing.ast.Term;
import aima.core.logic.fol.parsing.ast.TermEquality;
import aima.core.logic.fol.parsing.ast.Variable;
/**
* Artificial Intelligence A Modern Approach (3rd Edition): page 354.
*
* Demodulation: For any terms x, y, and z, where z appears somewhere in literal
* mi and where UNIFY(x,z) = θ:
*
*
* x=y, m1 OR ... OR mn[z]
* ------------------------------------------------------------
* SUB(SUBST(θ,x), SUBST(θ,y), m1 OR ... OR mn)
*
*
* where SUBST is the usual substitution of a binding list, and SUB(x,y,m) means
* to replace x with y everywhere that x occurs within m.
*
* Some additional restrictions/clarifications highlighted in:
* Demodulation Restrictions
* 1. Unit Equations Only.
* 2. Variables substituted in Equation Only.
*
* @author Ciaran O'Reilly
*
*/
public class Demodulation extends AbstractModulation {
public Demodulation() {
}
public Clause apply(TermEquality assertion, Clause clExpression) {
Clause altClExpression = null;
for (Literal l1 : clExpression.getLiterals()) {
AtomicSentence altExpression = apply(assertion,
l1.getAtomicSentence());
if (null != altExpression) {
// I have an alternative, create a new clause
// with the alternative and return
List newLits = new ArrayList();
for (Literal l2 : clExpression.getLiterals()) {
if (l1.equals(l2)) {
newLits.add(l1.newInstance(altExpression));
} else {
newLits.add(l2);
}
}
// Only apply demodulation at most once on
// each call.
altClExpression = new Clause(newLits);
altClExpression.setProofStep(new ProofStepClauseDemodulation(
altClExpression, clExpression, assertion));
if (clExpression.isImmutable()) {
altClExpression.setImmutable();
}
if (!clExpression.isStandardizedApartCheckRequired()) {
altClExpression.setStandardizedApartCheckNotRequired();
}
break;
}
}
return altClExpression;
}
public AtomicSentence apply(TermEquality assertion,
AtomicSentence expression) {
AtomicSentence altExpression = null;
IdentifyCandidateMatchingTerm icm = getMatchingSubstitution(
assertion.getTerm1(), expression);
if (null != icm) {
Term replaceWith = substVisitor.subst(
icm.getMatchingSubstitution(), assertion.getTerm2());
// Want to ignore reflexivity axiom situation, i.e. x = x
if (!icm.getMatchingTerm().equals(replaceWith)) {
ReplaceMatchingTerm rmt = new ReplaceMatchingTerm();
// Only apply demodulation at most once on each call.
altExpression = rmt.replace(expression, icm.getMatchingTerm(),
replaceWith);
}
}
return altExpression;
}
//
// PROTECTED METHODS
//
@Override
protected boolean isValidMatch(Term toMatch,
Set toMatchVariables, Term possibleMatch,
Map substitution) {
// Demodulation only allows substitution in the equation only,
// if the substitution contains variables not in the toMatch
// side of the equation (i.e. left hand side), then
// it is not a legal demodulation match.
// Note: see:
// http://logic.stanford.edu/classes/cs157/2008/lectures/lecture15.pdf
// slide 23 for an example.
if (toMatchVariables.containsAll(substitution.keySet())) {
return true;
}
return false;
}
}