cdc.applic.expressions.ast.visitors.IsDNF Maven / Gradle / Ivy
Show all versions of cdc-applic-expressions Show documentation
package cdc.applic.expressions.ast.visitors;
import cdc.applic.expressions.ast.AbstractBinaryNode;
import cdc.applic.expressions.ast.AbstractLeafNode;
import cdc.applic.expressions.ast.AbstractNaryNode;
import cdc.applic.expressions.ast.AbstractUnaryNode;
import cdc.applic.expressions.ast.AndNode;
import cdc.applic.expressions.ast.EquivalenceNode;
import cdc.applic.expressions.ast.ImplicationNode;
import cdc.applic.expressions.ast.NaryAndNode;
import cdc.applic.expressions.ast.NaryOrNode;
import cdc.applic.expressions.ast.Node;
import cdc.applic.expressions.ast.OrNode;
/**
* An analyzer that checks that an expression is in Disjunctive Normal Form.
*
* Simple expression like true or false are considered as DNF.
* Negative leaves are ignored.
*
* @author Damien Carbonne
*/
public final class IsDNF extends AbstractAnalyzer {
private boolean success = true;
/**
* Cumulated number of connectives (and, or operators).
*/
private int connectives = 0;
/**
* Cumulated number of negations (not operators).
*/
private int negations = 0;
public static boolean isDNF(Node node) {
final IsDNF analyzer = new IsDNF();
final Node n = ConvertToNary.execute(node, ConvertToNary.Variant.WHEN_NECESSARY);
n.accept(analyzer);
return analyzer.success;
}
@Override
public Void visitLeaf(AbstractLeafNode node) {
return null;
}
@Override
public Void visitUnary(AbstractUnaryNode node) {
negations++;
if (negations >= 2) {
success = false;
}
super.visitUnary(node);
negations--;
return null;
}
@Override
public Void visitBinary(AbstractBinaryNode node) {
if (negations > 0
|| node instanceof AndNode && connectives > 1
|| node instanceof OrNode && connectives > 0
|| node instanceof ImplicationNode
|| node instanceof EquivalenceNode) {
success = false;
}
connectives++;
super.visitBinary(node);
connectives--;
return null;
}
@Override
public Void visitNary(AbstractNaryNode node) {
if (negations > 0
|| node instanceof NaryAndNode && connectives > 1
|| node instanceof NaryOrNode && connectives > 0) {
success = false;
}
connectives++;
super.visitNary(node);
connectives--;
return null;
}
}