cdc.applic.expressions.ast.visitors.DistributeAndOverOr Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cdc-applic-expressions Show documentation
Show all versions of cdc-applic-expressions Show documentation
Applicabilities Expressions.
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