All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cdc.applic.expressions.ast.visitors.DistributeOrOverAnd Maven / Gradle / Ivy

The newest version!
package cdc.applic.expressions.ast.visitors;

import cdc.applic.expressions.ast.AbstractBinaryNode;
import cdc.applic.expressions.ast.AbstractNaryNode;
import cdc.applic.expressions.ast.AndNode;
import cdc.applic.expressions.ast.EquivalenceNode;
import cdc.applic.expressions.ast.ImplicationNode;
import cdc.applic.expressions.ast.Node;
import cdc.applic.expressions.ast.OrNode;
import cdc.applic.expressions.ast.XorNode;

/**
 * Utility class used to recursively apply distributivity of or (∨) over and (∧)
 * by applying these rewriting rules:
 * 
    *
  • α ∨ (β ∧ γ) ≡ (α ∨ β) ∧ (α ∨ γ) *
  • (β ∧ γ) ∨ α ≡ (β ∨ α) ∧ (γ ∨ α) *
* * Warning: This must be called: *
    *
  • after nary nodes have been removed, *
  • after equivalence nodes (↔) have been removed, *
  • after xor nodes (↮) have been removed, *
  • after implication nodes (→) have been removed, *
  • and after not nodes (¬) have been moved inwards. *
* * Note: This is an adaptation of AIMA Java implementation. * * @author Damien Carbonne */ public final class DistributeOrOverAnd extends AbstractConverter { private static final DistributeOrOverAnd CONVERTER = new DistributeOrOverAnd(); private DistributeOrOverAnd() { } public static Node execute(Node node) { return node.accept(CONVERTER); } @Override public Node visitBinary(AbstractBinaryNode node) { final Node result; if (node instanceof OrNode) { final Node s1 = node.getAlpha().accept(this); final Node s2 = node.getBeta().accept(this); if (s1 instanceof AndNode || s2 instanceof AndNode) { final Node alpha; final AbstractBinaryNode betaAndGamma; if (s2 instanceof AndNode) { // alpha | (beta & gamma) alpha = s1; betaAndGamma = (AbstractBinaryNode) s2; } else { // (beta & gamma) | alpha alpha = s2; betaAndGamma = (AbstractBinaryNode) s1; } final Node beta = betaAndGamma.getAlpha(); final Node gamma = betaAndGamma.getBeta(); if (s2 instanceof AndNode) { // (alpha | beta) & (alpha | gamma) final Node alphaOrBeta = (new OrNode(alpha, beta)).accept(this); final Node alphaOrGamma = (new OrNode(alpha, gamma)).accept(this); result = new AndNode(alphaOrBeta, alphaOrGamma); } else { // (beta | alpha) & (gamma | alpha) final Node betaOrAlpha = (new OrNode(beta, alpha)).accept(this); final Node gammaOrAlpha = (new OrNode(gamma, alpha)).accept(this); result = new AndNode(betaOrAlpha, gammaOrAlpha); } } else { result = new OrNode(s1, s2); } } else { if (node instanceof EquivalenceNode || node instanceof ImplicationNode || node instanceof XorNode) { throw new IllegalArgumentException("Equivalence, Xor and Implication nodes must be removed before calling " + getClass().getCanonicalName()); } result = super.visitBinary(node); } return result; } @Override public Node visitNary(AbstractNaryNode node) { throw new IllegalArgumentException("Nary nodes must be removed before calling " + getClass().getCanonicalName()); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy