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

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