cdc.applic.expressions.ast.visitors.DistributeOrOverAnd 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.
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