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

cdc.applic.expressions.ast.visitors.DistributeAndOverOr 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 and (∧) over or (∨)
 * 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 DistributeAndOverOr extends AbstractConverter { private static final DistributeAndOverOr CONVERTER = new DistributeAndOverOr(); private DistributeAndOverOr() { } public static Node execute(Node node) { return node.accept(CONVERTER); } @Override public Node visitBinary(AbstractBinaryNode node) { final Node result; if (node instanceof AndNode) { final Node s1 = node.getAlpha().accept(this); final Node s2 = node.getBeta().accept(this); if (s1 instanceof OrNode || s2 instanceof OrNode) { final Node alpha; final AbstractBinaryNode betaAndGamma; if (s2 instanceof OrNode) { // 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 OrNode) { // (alpha & beta) | (alpha & gamma) final Node alphaAndBeta = (new AndNode(alpha, beta)).accept(this); final Node alphaAndGamma = (new AndNode(alpha, gamma)).accept(this); result = new OrNode(alphaAndBeta, alphaAndGamma); } else { // (beta & alpha) | (gamma & alpha) final Node betaAndAlpha = (new AndNode(beta, alpha)).accept(this); final Node gammaAndAlpha = (new AndNode(gamma, alpha)).accept(this); result = new OrNode(betaAndAlpha, gammaAndAlpha); } } else { result = new AndNode(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