package aima.core.logic.propositional.visitors; import aima.core.logic.propositional.parsing.AbstractPLVisitor; import aima.core.logic.propositional.parsing.ast.ComplexSentence; import aima.core.logic.propositional.parsing.ast.Connective; import aima.core.logic.propositional.parsing.ast.Sentence; /** * Artificial Intelligence A Modern Approach (3rd Edition): page 254.<br> * <br> * Move ~ inwards by repeated application of the following equivalences:<br> * ~(~α) ≡ α (double-negation elimination)<br> * ~(α & β) ≡ (~α | ~β) (De Morgan)<br> * ~(α | β) ≡ (~α & ~β) (De Morgan)<br> * * @author Ciaran O'Reilly * */ public class MoveNotInwards extends AbstractPLVisitor<Object> { /** * Move ~ inwards. * * @param sentence * a propositional logic sentence that has had it biconditionals * and implications removed. * @return an equivalent Sentence to the input with all negations moved * inwards. * @throws IllegalArgumentException * if a biconditional or implication is encountered in the * input. */ public static Sentence moveNotsInward(Sentence sentence) { Sentence result = null; MoveNotInwards moveNotsIn = new MoveNotInwards(); result = sentence.accept(moveNotsIn, null); return result; } @Override public Sentence visitUnarySentence(ComplexSentence s, Object arg) { Sentence result = null; Sentence negated = s.getSimplerSentence(0); if (negated.isPropositionSymbol()) { // Already moved in fully result = s; } else if (negated.isNotSentence()) { // ~(~α) ≡ α (double-negation elimination) Sentence alpha = negated.getSimplerSentence(0); result = alpha.accept(this, arg); } else if (negated.isAndSentence() || negated.isOrSentence()) { Sentence alpha = negated.getSimplerSentence(0); Sentence beta = negated.getSimplerSentence(1); // This ensures double-negation elimination happens Sentence notAlpha = (new ComplexSentence(Connective.NOT, alpha)) .accept(this, null); Sentence notBeta = (new ComplexSentence(Connective.NOT, beta)) .accept(this, null); if (negated.isAndSentence()) { // ~(α & β) ≡ (~α | ~β) (De Morgan) result = new ComplexSentence(Connective.OR, notAlpha, notBeta); } else { // ~(α | β) ≡ (~α & ~β) (De Morgan) result = new ComplexSentence(Connective.AND, notAlpha, notBeta); } } else { throw new IllegalArgumentException( "Biconditionals and Implications should not exist in input: " + s); } return result; } }