cdc.applic.pclauses.PClause Maven / Gradle / Ivy
package cdc.applic.pclauses;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import cdc.applic.expressions.Expression;
import cdc.applic.expressions.ast.AbstractPropertyNode;
import cdc.applic.expressions.ast.FalseNode;
import cdc.applic.expressions.ast.Node;
import cdc.applic.expressions.ast.NotEqualNode;
import cdc.applic.expressions.ast.NotInNode;
import cdc.applic.expressions.ast.NotNode;
import cdc.applic.expressions.ast.RefNode;
import cdc.applic.expressions.ast.TrueNode;
import cdc.applic.expressions.literals.Name;
public abstract class PClause {
protected final List nodes;
private final byte cache;
private static final byte USE_NEGATION = 0x1;
private static final byte USE_REF = 0x2;
private static final byte IS_CANONICAL = 0x4;
private static final byte USE_FALSE = 0x8;
private static final byte USE_TRUE = 0x10;
protected PClause(List nodes) {
this.nodes = Collections.unmodifiableList(nodes);
this.cache = computeCache(nodes);
}
private static byte computeCache(List nodes) {
byte cache = 0;
boolean isCanonical = true;
Set props = null;
Set refs = null;
for (final Node node : nodes) {
if (node instanceof AbstractPropertyNode) {
final AbstractPropertyNode pnode = (AbstractPropertyNode) node;
if (pnode instanceof NotEqualNode || node instanceof NotInNode) {
cache |= USE_NEGATION;
}
if (props == null) {
props = new HashSet<>();
props.add(pnode.getName());
} else if (props.contains(pnode.getName())) {
isCanonical = false;
} else {
props.add(pnode.getName());
}
} else if (node instanceof RefNode) {
cache |= USE_REF;
final RefNode rnode = (RefNode) node;
if (refs == null) {
refs = new HashSet<>();
refs.add(rnode.getName());
} else if (refs.contains(rnode.getName())) {
isCanonical = false;
} else {
refs.add(rnode.getName());
}
} else if (node instanceof NotNode) {
cache |= USE_NEGATION;
cache |= USE_REF;
final RefNode rnode = (RefNode) ((NotNode) node).getAlpha();
if (refs == null) {
refs = new HashSet<>();
refs.add(rnode.getName());
} else if (refs.contains(rnode.getName())) {
isCanonical = false;
} else {
refs.add(rnode.getName());
}
} else if (node instanceof FalseNode) {
cache |= USE_FALSE;
isCanonical = false;
} else if (node instanceof TrueNode) {
cache |= USE_TRUE;
isCanonical = false;
} else {
throw new IllegalArgumentException("Unexpected node " + node);
}
}
if (isCanonical) {
cache |= IS_CANONICAL;
}
return cache;
}
public abstract Connective getConnective();
public abstract Node toNode();
public final List getNodes() {
return nodes;
}
public final Expression toExpression() {
return toNode().toExpression();
}
public final boolean isCanonical() {
return (cache & IS_CANONICAL) != 0;
}
public final boolean useNegation() {
return (cache & USE_NEGATION) != 0;
}
public final boolean useRef() {
return (cache & USE_REF) != 0;
}
public final boolean useFalse() {
return (cache & USE_FALSE) != 0;
}
public final boolean useTrue() {
return (cache & USE_TRUE) != 0;
}
public static PClause of(Connective connective,
List nodes) {
if (connective == Connective.AND) {
return PAndClause.of(nodes);
} else {
return POrClause.of(nodes);
}
}
public static PClause of(Connective connective,
Node... nodes) {
if (connective == Connective.AND) {
return PAndClause.of(nodes);
} else {
return POrClause.of(nodes);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy