/* Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. Contact: SYSTAP, LLC DBA Blazegraph 2501 Calvert ST NW #106 Washington, DC 20008 licenses@blazegraph.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * Created on Jun 23, 2008 */ package com.bigdata.relation.rule; import java.util.Iterator; import java.util.Set; import com.bigdata.bop.IBindingSet; import com.bigdata.bop.IConstraint; import com.bigdata.bop.IPredicate; import com.bigdata.bop.IVariable; import com.bigdata.relation.IRelation; import com.bigdata.relation.rule.eval.ActionEnum; import com.bigdata.relation.rule.eval.IJoinNexus; import com.bigdata.relation.rule.eval.IRuleTaskFactory; /** * Conjunctive query of N {@link IPredicate}s with optional {@link IConstraint}s. * * @author <a href="mailto:thompsonbry@users.sourceforge.net">Bryan Thompson</a> * @version $Id$ * * @param E * The generic type of the [E]lements materialized by the head of the * rule. This should be the same as the generic type of the * {@link IRelation} that can be materialized from the * {@link String} associated with the {@link IPredicate} that * is the head of the rule. */ public interface IRule<E> extends IStep { /** * The #of distinct variables declared by the rule. */ public int getVariableCount(); /** * The variables declared by the rule in no particular order. */ public Iterator<IVariable> getVariables(); /** * The #of distinct required variables declared by the rule. */ public int getRequiredVariableCount(); /** * The required variables declared by the rule in no particular order. */ public Iterator<IVariable> getRequiredVariables(); /** * The head of the rule -or- <code>null</code> iff there is no head for * this rule. Note that rules that are executed as queries DO NOT need to * specify a head. However, rules that will be executed as mutation * operations (insert or delete) MUST specify the head as it determines the * {@link IRelation} on which the rule will write. * * @see ActionEnum */ public IPredicate getHead(); /** * The #of {@link IPredicate}s in the body (aka tail) of the rule. */ public int getTailCount(); /** * Iterator visits the {@link IPredicate}s in the body (ala tail) of the * rule. */ public Iterator<IPredicate> getTail(); /** * Return the predicate at the given index from the tail of the rule. * * @param index * The index. * * @return The predicate at that index. * * @throws IndexOutOfBoundsException */ public IPredicate getTail(int index); /** * The #of constraints on the legal states for bindings of the variables * declared by rule. */ public int getConstraintCount(); /** * The optional constraints. */ public Iterator<IConstraint> getConstraints(); /** * Return the constraint at the given index. * * @param index * The index. * * @return The constraint. * * @throws IndexOutOfBoundsException */ public IConstraint getConstraint(int index); /** * The name of the rule. */ public String getName(); /** * Externalizes the rule displaying variable names and constants. */ public String toString(); /** * Externalizes the rule displaying variable names, their bindings, and * constants. * * @param bindingSet * When non-<code>null</code>, the current variable bindings * will be displayed. Otherwise, the names of variables will be * displayed rather than their bindings. */ public String toString(IBindingSet bindingSet); /** * Specialize a rule - the name of the new rule will be derived from the * name of the old rule with an appended single quote to indicate that it is * a derived variant. * * @param bindingSet * Bindings for zero or more free variables in this rule. The * rule will be rewritten such that the variable is replaced by * the binding throughout the rule. An attempt to bind a variable * not declared by the rule will be ignored. * @param constraints * An array of additional constraints to be imposed on the rule * (optional). * * @return The specialized rule. * * @throws IllegalArgumentException * if <i>bindingSet</i> is <code>null</code>. */ public IRule<E> specialize(IBindingSet bindingSet, IConstraint[] constraints); /** * Specialize a rule by binding zero or more variables and adding zero or * more constraints. * * @param bindingSet * Bindings for zero or more free variables in this rule. The * rule will be rewritten such that the variable is replaced by * the binding throughout the rule. An attempt to bind a variable * not declared by the rule will be ignored. * @param constraints * An array of additional constraints to be imposed on the rule * (optional). * * @return The specialized rule. * * @exception IllegalArgumentException * if <i>name</i> is <code>null</code>. * @exception IllegalArgumentException * if <i>bindingSet</i> is <code>null</code>. */ public IRule<E> specialize(String name, IBindingSet bindingSet, IConstraint[] constraints); /** * Returns any variables that were bound to constants when an {@link IRule} * was {@link #specialize(String, IBindingSet, IConstraint[]) specialized}. * <p> * Note: {@link IJoinNexus#newBindingSet(IRule)} MUST apply the constants * before returning the bindings to the caller. * * @return The bound constants. */ public IBindingSet getConstants(); /** * Return the variables in common for two {@link IPredicate}s. * * @param index1 * The index of a predicate in the {@link #tail}. * * @param index2 * The index of a different predicate in the {@link #tail}. * * @return The variables in common -or- <code>null</code> iff there are no * variables in common. * * @throws IllegalArgumentException * if the two predicate indices are the same. * @throws IndexOutOfBoundsException * if either index is out of bounds. */ public Set<IVariable<?>> getSharedVars(int index1, int index2); /** * Return true iff the selected predicate is fully bound. * * @param index * The index of a predicate declared the {@link #getTail() tail} * of the {@link IRule}. * @param bindingSet * The variable bindings. * * @return True iff it is fully bound (a mixture of constants and/or bound * variables). * * @throws IndexOutOfBoundsException * if the <i>index</i> is out of bounds. * @throws IllegalArgumentException * if <i>bindingSet</i> is <code>null</code>. */ public boolean isFullyBound(int index, IBindingSet bindingSet); /** * If the rule is fully bound for the given bindings. * * @param bindingSet * The bindings. * * @return true if there are no unbound variables in the rule given those * bindings. */ public boolean isFullyBound(IBindingSet bindingSet); /** * The #of arguments in the selected predicate that are variables (vs * constants) with the given the bindings. * * @param index * The index of a predicate declared the {@link #getTail() tail} * of the {@link IRule}. * @param bindingSet * The bindings under which the variable count will be obtained * (any variables in the predicate that are bound in the binding * set will be treated as constants for the purposes of this * method). */ public int getVariableCount(int index,IBindingSet bindingSet); /** * Return <code>true</code> unless the {@link IBindingSet} violates a * {@link IConstraint} declared for this {@link Rule}. * * @param bindingSet * The binding set. * * @return <code>true</code> unless a constraint is violated by the * bindings. */ public boolean isConsistent(IBindingSet bindingSet); /** * Return <code>true</code> iff the rule declares this variable. * * @param var * Some variable. * * @return True if the rule declares that variable. * * @throws IllegalArgumentException * if <i>var</i> is <code>null</code>. */ public boolean isDeclared(IVariable var); /* * Behavior override. */ /** * An optional {@link IRuleTaskFactory} that will be used in place of the * default {@link IRuleTaskFactory} to evaluate this rule (optional) * * @return <code>null</code> unless custom evaluation is desired. */ public IRuleTaskFactory getTaskFactory(); }