[Mulgara-svn] r1626 - in trunk/src/jar: content-rlog content-rlog/java/org/mulgara/content/rlog content-rlog/java/org/mulgara/krule/rlog content-rlog/java/org/mulgara/krule/rlog/ast content-rlog/java/org/mulgara/krule/rlog/ast/output content-rlog/java/org/mulgara/krule/rlog/parser content-rlog/javacc/org/mulgara/krule/rlog krule/java/org/mulgara/krule query/java/org/mulgara/query query/java/org/mulgara/query/rdf resolver resolver/java/org/mulgara/resolver resolver-prefix/java/org/mulgara/resolver/prefix resolver-relational/java/org/mulgara/resolver/relational rules/java/org/mulgara/rules store-stringpool-xa11/java/org/mulgara/store/stringpool/xa11 util/java/org/mulgara/util/functional web/java/org/mulgara/webquery
pag at mulgara.org
pag at mulgara.org
Tue Mar 24 18:42:51 UTC 2009
Author: pag
Date: 2009-03-24 11:42:49 -0700 (Tue, 24 Mar 2009)
New Revision: 1626
Added:
trunk/src/jar/content-rlog/java/org/mulgara/content/rlog/RlogStructure.java
trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/Program.java
trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CanonicalPredicate.java
trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CanonicalPredicateTest.java
trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CanonicalStatement.java
trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CheckRule.java
trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/VariableCanonicalizer.java
trunk/src/jar/krule/java/org/mulgara/krule/ConsistencyCheck.java
trunk/src/jar/query/java/org/mulgara/query/rdf/Krule.java
Modified:
trunk/src/jar/content-rlog/build.xml
trunk/src/jar/content-rlog/java/org/mulgara/content/rlog/RlogContentHandler.java
trunk/src/jar/content-rlog/java/org/mulgara/content/rlog/RlogStatements.java
trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/Rlog.java
trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Axiom.java
trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/BPredicate.java
trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/IntegerLiteral.java
trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/InvertedPredicate.java
trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/NullPredicate.java
trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Predicate.java
trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/PredicateLiteral.java
trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/PredicateParam.java
trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Rule.java
trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Statement.java
trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/StringLiteral.java
trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/TypeStatement.java
trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Variable.java
trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/output/AxiomGenerator.java
trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/output/RuleGenerator.java
trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/output/RuleWriter.java
trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/output/TripleGenerator.java
trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/parser/NSUtils.java
trunk/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParser.java
trunk/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParser.jj
trunk/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParserConstants.java
trunk/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParserTokenManager.java
trunk/src/jar/krule/java/org/mulgara/krule/KruleLoader.java
trunk/src/jar/krule/java/org/mulgara/krule/QueryStruct.java
trunk/src/jar/krule/java/org/mulgara/krule/Rule.java
trunk/src/jar/query/java/org/mulgara/query/ConstraintConjunction.java
trunk/src/jar/query/java/org/mulgara/query/ConstraintDisjunction.java
trunk/src/jar/query/java/org/mulgara/query/rdf/Mulgara.java
trunk/src/jar/resolver-prefix/java/org/mulgara/resolver/prefix/PrefixResolverFactory.java
trunk/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalResolverUnitTest.java
trunk/src/jar/resolver/build.xml
trunk/src/jar/resolver/java/org/mulgara/resolver/BuildRulesOperation.java
trunk/src/jar/resolver/java/org/mulgara/resolver/ExportOperation.java
trunk/src/jar/rules/java/org/mulgara/rules/DummyRuleLoader.java
trunk/src/jar/rules/java/org/mulgara/rules/RuleLoader.java
trunk/src/jar/rules/java/org/mulgara/rules/RuleLoaderFactory.java
trunk/src/jar/rules/java/org/mulgara/rules/RulesRef.java
trunk/src/jar/store-stringpool-xa11/java/org/mulgara/store/stringpool/xa11/XA11StringPoolLoadTest.java
trunk/src/jar/util/java/org/mulgara/util/functional/C.java
trunk/src/jar/util/java/org/mulgara/util/functional/Pair.java
trunk/src/jar/web/java/org/mulgara/webquery/QueryServlet.java
Log:
Merged in the consistency branch. Now Krule does consistency checking
Modified: trunk/src/jar/content-rlog/build.xml
===================================================================
--- trunk/src/jar/content-rlog/build.xml 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/content-rlog/build.xml 2009-03-24 18:42:49 UTC (rev 1626)
@@ -60,7 +60,7 @@
</target>
<target name="content-rlog-compile"
- depends="-content-rlog-prepare, gen-rlog-parser, resolver-spi-jar, resolver-file-jar, krule-jar"
+ depends="-content-rlog-prepare, gen-rlog-parser, resolver-spi-jar, resolver-file-jar"
description="Compiles all content-rlog related files included generated source code">
<javac destdir="${content-rlog.obj.dir}/classes" debug="on" deprecation="on" source="1.5" encoding="UTF-8">
<classpath refid="content-rlog-classpath"/>
Modified: trunk/src/jar/content-rlog/java/org/mulgara/content/rlog/RlogContentHandler.java
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/content/rlog/RlogContentHandler.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/content-rlog/java/org/mulgara/content/rlog/RlogContentHandler.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -18,6 +18,10 @@
package org.mulgara.content.rlog;
// Java 2 enterprise packages
+import java.io.BufferedWriter;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+
import javax.activation.MimeType;
import javax.activation.MimeTypeParseException;
@@ -94,6 +98,14 @@
*/
public void serialize(Statements statements, Content content, ResolverSession resolverSession)
throws ContentHandlerException, ModifiedException {
- throw new UnsupportedOperationException();
+ try {
+ Writer out = new BufferedWriter(new OutputStreamWriter(content.newOutputStream(), "utf-8"));
+ RlogStructure struct = new RlogStructure(resolverSession);
+ struct.load(statements);
+ struct.write(out);
+ out.close();
+ } catch (Exception e) {
+ throw new ContentHandlerException("Failed to serialize RLog to " + content.getURIString(), e);
+ }
}
}
Modified: trunk/src/jar/content-rlog/java/org/mulgara/content/rlog/RlogStatements.java
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/content/rlog/RlogStatements.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/content-rlog/java/org/mulgara/content/rlog/RlogStatements.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -54,7 +54,7 @@
/**
* Parses an {@link InputStream} into {@link Statements}.
* This parser uses memory and does not stream.
- *
+ *
* @created Feb 24, 2009
* @author Paul Gearon
* @copyright © 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
@@ -98,7 +98,7 @@
try {
InputStreamReader input = new InputStreamReader(content.newInputStream());
try {
- rlogParser = new Rlog(input);
+ rlogParser = new Rlog(input, content.getURI());
} finally {
input.close();
}
Copied: trunk/src/jar/content-rlog/java/org/mulgara/content/rlog/RlogStructure.java (from rev 1625, branches/consistency/src/jar/content-rlog/java/org/mulgara/content/rlog/RlogStructure.java)
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/content/rlog/RlogStructure.java (rev 0)
+++ trunk/src/jar/content-rlog/java/org/mulgara/content/rlog/RlogStructure.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -0,0 +1,853 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.content.rlog;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.mulgara.krule.rlog.parser.NSUtils;
+import org.mulgara.query.TuplesException;
+import org.mulgara.query.rdf.Krule;
+import org.mulgara.query.rdf.URIReferenceImpl;
+import org.mulgara.resolver.spi.GlobalizeException;
+import org.mulgara.resolver.spi.LocalizeException;
+import org.mulgara.resolver.spi.ResolverSession;
+import org.mulgara.resolver.spi.Statements;
+import org.mulgara.util.functional.Pair;
+
+import org.apache.log4j.Logger;
+import org.jrdf.graph.Literal;
+import org.jrdf.graph.Node;
+import org.jrdf.graph.URIReference;
+import org.jrdf.vocabulary.RDF;
+
+/**
+ * This class constructs an RLog structure out of a set of Statements.
+ *
+ * @created Mar 18, 2009
+ * @author Paul Gearon
+ * @copyright © 2009 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ */
+public class RlogStructure {
+
+ /** Logger. */
+ private static Logger logger = Logger.getLogger(RlogStructure.class.getName());
+
+ /** The rdf:type URI. */
+ private static final URIReference TYPE = new URIReferenceImpl(RDF.TYPE);
+
+ /** The rdf:value URI. */
+ private static final URIReference RDF_VALUE = new URIReferenceImpl(RDF.VALUE);
+
+ /** The rdf:Seq URI. */
+ private static final URIReference RDF_SEQ = new URIReferenceImpl(RDF.SEQ);
+
+ /** The domain for system graphs. */
+ private static final String SYS = "sys";
+
+ /** The session to use for localizing and globalizing. */
+ ResolverSession session;
+
+ /** The graph to store the statements in. */
+ Map<Node,Map<URIReference,Set<Node>>> graph = new HashMap<Node,Map<URIReference,Set<Node>>>();
+
+ /** Stores all the nodes of a particular type in a single set, one for each type. */
+ Map<Node,Set<Node>> nodesByType = new HashMap<Node,Set<Node>>();
+
+ /** Maps nodes to their type */
+ Map<Node,Node> typeByNode = new HashMap<Node,Node>();
+
+ /** Maps variables to their names */
+ Map<Node,String> nameByVar = new HashMap<Node,String>();
+
+ /** Maps namesto their variables */
+ Map<String,Node> varByName = new HashMap<String,Node>();
+
+ /** Maps all the in-use namespaces to their shorthand prefixes. */
+ Map<String,String> namespaces;
+
+ /** Default map of namespaces to their shorthand prefixes. */
+ Map<String,String> defaultNamespaces;
+
+ /** A generator for new namespace names. */
+ NamespaceGenerator namespaceGen = new NamespaceGenerator();
+
+ /** The current constraint context when writing a rule. */
+ Node currentRootConstraint = null;
+
+ /** A list of the rdf:_x IDs used for sequences. */
+ List<URIReference> listIds = new ArrayList<URIReference>();
+
+ /** The local node for the rdf:type URI. */
+ final long rdfType;
+
+
+ /**
+ * Constructs the structure, along with the session used to help build it.
+ * @param session The mechanism for convergins local nodes to global, and back.
+ * @throws LocalizeException If a global node could not be localized to a long.
+ */
+ public RlogStructure(ResolverSession session) throws LocalizeException {
+ this.session = session;
+ rdfType = session.localize(TYPE);
+ initNamespaces();
+ }
+
+
+ /**
+ * Initialized the namespaces with the registered domains.
+ */
+ private void initNamespaces() {
+ Map<String,String> ns = new HashMap<String,String>();
+ for (Map.Entry<String,String> e: NSUtils.getRegisteredDomains()) {
+ ns.put(e.getValue(), e.getKey());
+ }
+ defaultNamespaces = Collections.unmodifiableMap(ns);
+ namespaces = new HashMap<String,String>();
+ // add in sys: so it does not get mapped
+ namespaces.put(SYS + ":", SYS);
+ }
+
+
+ /**
+ * Build a structure in memory to represent the Krule data structure.
+ * @param statements The statements to load.
+ * @throws TuplesException If there was a problem accessing the statements.
+ * @throws GlobalizeException If there was a problem converting the statements to references.
+ */
+ public void load(Statements statements) throws TuplesException, GlobalizeException {
+ statements.beforeFirst();
+ while (statements.next()) {
+ long subject = statements.getSubject();
+ long predicate = statements.getPredicate();
+ long obj = statements.getObject();
+
+ if (predicate == rdfType) {
+ addType(subject, obj);
+ } else {
+ addToGraph(subject, predicate, obj);
+ }
+ }
+ nameVariables();
+ }
+
+
+ /**
+ * For every variable that was found, map it to its name.
+ */
+ void nameVariables() {
+ Set<Node> vars = nodesByType.get(Krule.VARIABLE);
+ if (vars == null) return;
+ for (Node v: vars) {
+ Node name = getPropertyValue(v, Krule.NAME);
+ if (!(name instanceof Literal)) throw new IllegalArgumentException("Bad Krule structure. Variable name is not a string.");
+ String sName = getValidVariableName((Literal)name);
+ nameByVar.put(v, sName);
+ varByName.put(sName, v);
+ }
+ }
+
+
+ /**
+ * Write a set of statements representing RLog to a given writer.
+ * @param writer The output to send the RLog to.
+ * @throws IOException If the data could not be converted or written out.
+ */
+ public void write(Writer writer) throws IOException {
+ if (writer == null) throw new IllegalArgumentException("Writer cannot be null.");
+
+ StringWriter out = new StringWriter();
+ writeAxioms(out);
+ writeChecks(out);
+ writeRules(out);
+ out.close();
+
+ writePrefixes(writer);
+ writer.append(out.getBuffer());
+ }
+
+
+ /**
+ * Sets the type for an object.
+ * @param s The subject to be typed.
+ * @param t The type of the subject.
+ * @throws GlobalizeException If the subject or type could not be globalized.
+ */
+ void addType(long s, long t) throws GlobalizeException {
+ Node subj = session.globalize(s);
+ Node type = session.globalize(t);
+ // map the type to the node
+ addValue(nodesByType, type, subj);
+ // map the node to its type
+ typeByNode.put(subj, type);
+ }
+
+
+ /**
+ * Add a triple to the graph.
+ * @param s The subject of the triple.
+ * @param p The predicate of the triple.
+ * @param o The object of the triple.
+ * @throws GlobalizeException If one of the elements of the triple could not be
+ * converted to a global node.
+ */
+ void addToGraph(long s, long p, long o) throws GlobalizeException {
+ Node subj = session.globalize(s);
+ URIReference pred = (URIReference)session.globalize(p);
+ Node obj = session.globalize(o);
+ addPropertyValue(graph, subj, pred, obj);
+ }
+
+
+ /**
+ * Writes all the axioms to the output as horn clauses.
+ * @param out The writer to send the RLog to.
+ * @throws IOException If there was an error writing to the output.
+ */
+ void writePrefixes(Writer out) throws IOException {
+ for (Map.Entry<String,String> ns: namespaces.entrySet()) {
+ String k = ns.getKey();
+ String v = ns.getValue() + ":";
+ if (v.equals(k)) continue;
+ out.append("@prefix ");
+ out.append(v);
+ out.append(" <");
+ out.append(k);
+ out.append("> .\n");
+ }
+ out.append("\n");
+ }
+
+
+ /**
+ * Writes all the axioms to the output as horn clauses.
+ * @param out The writer to send the RLog to.
+ * @throws IOException If there was an error writing to the output.
+ */
+ void writeAxioms(Writer out) throws IOException {
+ Set<Node> axioms = nodesByType.get(Krule.AXIOM);
+ if (axioms == null) return;
+ for (Node axiom: axioms) {
+ Map<URIReference,Set<Node>> properties = graph.get(axiom);
+ Node s = getSingle(properties, Krule.AXIOM_SUBJECT);
+ Node p = getSingle(properties, Krule.AXIOM_PREDICATE);
+ Node o = getSingle(properties, Krule.AXIOM_OBJECT);
+ out.append(toPredicate(s, p, o));
+ out.append(".\n");
+ }
+ out.append("\n");
+ }
+
+
+ /**
+ * Writes all the consistency checks to the output as horn clauses.
+ * @param out The writer to send the RLog to.
+ * @throws IOException If there was an error writing to the output.
+ */
+ void writeChecks(Writer out) throws IOException {
+ Set<Node> checks = nodesByType.get(Krule.CHECK);
+ if (checks == null) return;
+ for (Node check: checks) {
+ Map<URIReference,Set<Node>> properties = graph.get(check);
+ Node q = getSingle(properties, Krule.HAS_QUERY);
+ Node qType = typeByNode.get(q);
+ if (!qType.equals(Krule.QUERY)) {
+ throw new IllegalArgumentException("Bad Krule structure. Consistency check has a query that has a non-query type: " + qType);
+ }
+ out.append(":- ");
+ writeBody(out, q);
+ out.append(".\n");
+ }
+ out.append("\n");
+ }
+
+
+ /**
+ * Writes all the rules to the output as horn clauses.
+ * @param out The writer to send the RLog to.
+ * @throws IOException If there was an error writing to the output.
+ */
+ void writeRules(Writer out) throws IOException {
+ Set<Node> rules = nodesByType.get(Krule.RULE);
+ if (rules == null) return;
+ for (Node rule: rules) {
+ Node q = getPropertyValue(rule, Krule.HAS_QUERY);
+ Node qType = typeByNode.get(q);
+ if (!qType.equals(Krule.QUERY)) {
+ throw new IllegalArgumentException("Bad Krule structure. Consistency check has a query that has a non-query type: " + qType);
+ }
+ writeHead(out, q);
+ out.append(" :- ");
+ writeBody(out, q);
+ out.append(".\n");
+ }
+ out.append("\n");
+ }
+
+
+ /**
+ * Writes out the head of a query associated with a rule.
+ * @param out The writer output.
+ * @param query The node representing the query.
+ */
+ void writeHead(Writer out, Node query) throws IOException {
+ Node seq = getPropertyValue(query, Krule.SELECTION_VARS);
+ Node sType = typeByNode.get(seq);
+ if (!sType.equals(RDF_SEQ)) {
+ throw new IllegalArgumentException("Bad Krule structure. Query selection sequence is not a sequence type: " + sType);
+ }
+
+ // loop over multiple triples
+ int seqNr = 1;
+ Node s;
+ while (null != (s = getPropertyValue(seq, getListId(seqNr++)))) {
+ Node p = getPropertyValue(seq, getListId(seqNr++));
+ Node o = getPropertyValue(seq, getListId(seqNr++));
+ if (p == null || o == null) throw new IllegalArgumentException("Bad Krule structure. Query selection sequence is not set of triples. " + seqNr + " elements");
+ // separate triples with commas
+ if (seqNr > 4) out.append(", ");
+ out.append(toPredicate(s, p, o));
+ }
+ }
+
+
+ /**
+ * Writes out the body (WHERE clause) of a query associated with a rule.
+ * @param out The writer output.
+ * @param query The node representing the query.
+ */
+ void writeBody(Writer out, Node query) throws IOException {
+ Node constraint = getPropertyValue(query, Krule.HAS_WHERE_CLAUSE);
+ // remember the current context in case it is needed
+ currentRootConstraint = constraint;
+ writeConstraint(out, constraint, false);
+ }
+
+
+ /**
+ * Writes a general constraint type that may be inverted. This method is recursive.
+ * @param out The writer output.
+ * @param constraint The constraint to be written.
+ * Accepts conjunctions, differences, transitive and simple constraints.
+ * @param inv Indicates that the constraint is inverted.
+ * @throws IOException Due to a write error on the writer.
+ */
+ void writeConstraint(Writer out, Node constraint, boolean inv) throws IOException {
+ Node cType = typeByNode.get(constraint);
+ if (cType.equals(Krule.CONSTRAINT_CONJUNCTION)) {
+ writeConstraintConjunction(out, constraint, inv);
+ } else if (cType.equals(Krule.SIMPLE_CONSTRAINT)) {
+ writeConstraintSimple(out, constraint, inv);
+ } else if (cType.equals(Krule.DIFFERENCE)) {
+ writeConstraintDifference(out, constraint, inv);
+ } else if (cType.equals(Krule.TRANSITIVE_CONSTRAINT)) {
+ writeConstraintTransitive(out, constraint, inv);
+ } else {
+ throw new IllegalArgumentException("Bad Krule structure. Unsupported Constraint type: " + cType);
+ }
+ }
+
+
+ /**
+ * Writes the simple constraint type. This is just a triple.
+ * @param out The writer output.
+ * @param constraint The constraint to be written.
+ * @param inv Indicates that the constraint is inverted.
+ * @throws IOException Due to a write error on the writer.
+ */
+ void writeConstraintSimple(Writer out, Node constraint, boolean inv) throws IOException {
+ Node s = getPropertyValue(constraint, Krule.HAS_SUBJECT);
+ Node p = getPropertyValue(constraint, Krule.HAS_PREDICATE);
+ Node o = getPropertyValue(constraint, Krule.HAS_OBJECT);
+ // throw away the graph, as this is autodetected from the predicate in RLog parsing
+ if (s == null || p == null || o == null) {
+ throw new IllegalArgumentException("Bad Krule structure. Incomplete constraint.");
+ }
+ if (inv) out.append("~");
+ out.append(toPredicate(s, p, o));
+ }
+
+
+ /**
+ * Writes a constraint conjunction.
+ * @param out The writer output.
+ * @param constraint The constraint to be written.
+ * @param inv Indicates that the constraint is inverted.
+ * @throws IOException Due to a write error on the writer.
+ */
+ void writeConstraintConjunction(Writer out, Node constraint, boolean inv) throws IOException {
+ Map<URIReference,Set<Node>> constraintProps = graph.get(constraint);
+ if (constraintProps == null) throw new IllegalArgumentException("Bad Krule structure. Missing arguments for a conjunction.");
+ Set<Node> args = constraintProps.get(Krule.ARGUMENT);
+ // go through all the constraints, separating them with commas
+ boolean first = true;
+ for (Node c: args) {
+ if (first) first = false;
+ else out.append(", ");
+ writeConstraint(out, c, inv);
+ }
+ }
+
+
+ /**
+ * Writes a difference constraint.
+ * @param out The writer output.
+ * @param constraint The constraint to be written.
+ * @param inv Indicates that the constraint is inverted.
+ * @throws IOException Due to a write error on the writer.
+ */
+ void writeConstraintDifference(Writer out, Node constraint, boolean inv) throws IOException {
+ Node minuend = getPropertyValue(constraint, Krule.MINUEND);
+ Node subtrahend = getPropertyValue(constraint, Krule.SUBTRAHEND);
+ if (minuend == null) throw new IllegalArgumentException("Bad Krule structure. Missing minuend on a Difference.");
+ if (subtrahend == null) throw new IllegalArgumentException("Bad Krule structure. Missing subtrahend on a Difference.");
+ writeConstraint(out, minuend, inv);
+ out.append(", ");
+ writeConstraint(out, subtrahend, !inv);
+ }
+
+
+ /**
+ * Writes a transitive constraint.
+ * @param out The writer output.
+ * @param constraint The constraint to be written.
+ * @param inv Indicates that the constraint is inverted.
+ * @throws IOException Due to a write error on the writer.
+ */
+ void writeConstraintTransitive(Writer out, Node constraint, boolean inv) throws IOException {
+ Node arg = getPropertyValue(constraint, Krule.TRANSITIVE_ARGUMENT);
+ if (arg == null || !arg.equals(Krule.SIMPLE_CONSTRAINT)) {
+ throw new IllegalArgumentException("Bad Krule structure. Transitive constraints must operate on simple arguments.");
+ }
+ Node s = getPropertyValue(arg, Krule.HAS_SUBJECT);
+ Node p = getPropertyValue(arg, Krule.HAS_PREDICATE);
+ Node o = getPropertyValue(arg, Krule.HAS_OBJECT);
+ // throw away the graph, as this is autodetected from the predicate in RLog parsing
+ if (s == null || p == null || o == null) {
+ throw new IllegalArgumentException("Bad Krule structure. Incomplete constraint in transitive constraint.");
+ }
+
+ Node newVar = getUnusedVar();
+ out.append(toPredicate(s, p, newVar));
+ out.append(", ");
+ out.append(toPredicate(newVar, p, o));
+ }
+
+
+ /**
+ * Finds a variable that is not in use in the current constraint.
+ * @return A variable this is not being used in the current rule.
+ */
+ Node getUnusedVar() {
+ for (char v = 'A'; v <= 'Z'; v++) {
+ Node var = varByName.get(Character.toString(v));
+ if (var != null) return var;
+ }
+ // every variable is in use somewhere. Have to search the current rule.
+ Set<Node> currentVariables = getVariables(currentRootConstraint);
+ for (Node var: nameByVar.keySet()) {
+ if (!currentVariables.contains(var)) return var;
+ }
+ throw new IllegalStateException("Rule is too complex. It contains too many variables.");
+ }
+
+
+ /**
+ * Accumulates all of the variables under a given node.
+ * @param constraint The constraint node to find variables under.
+ * @return A Set of nodes which represent variables.
+ */
+ Set<Node> getVariables(Node constraint) {
+ Node type = typeByNode.get(constraint);
+ if (type.equals(Krule.SIMPLE_CONSTRAINT)) {
+ return getVariablesSimple(constraint);
+ } else if (type.equals(Krule.CONSTRAINT_CONJUNCTION)) {
+ return getVariablesConjunction(constraint);
+ } else if (type.equals(Krule.DIFFERENCE)) {
+ return getVariablesDifference(constraint);
+ } else if (type.equals(Krule.TRANSITIVE_CONSTRAINT)) {
+ return getVariablesTransitive(constraint);
+ } else {
+ throw new IllegalArgumentException("Bad Krule structure. Unsupported Constraint type: " + type);
+ }
+ }
+
+
+ /**
+ * Accumulates all of the variables in a simple constraint.
+ * @param constraint The constraint node to find variables under.
+ * @return A Set of nodes which represent variables.
+ */
+ Set<Node> getVariablesSimple(Node constraint) {
+ Node s = getPropertyValue(constraint, Krule.HAS_SUBJECT);
+ Node p = getPropertyValue(constraint, Krule.HAS_PREDICATE);
+ Node o = getPropertyValue(constraint, Krule.HAS_OBJECT);
+ if (s == null || p == null || o == null) {
+ throw new IllegalArgumentException("Bad Krule structure. Incomplete constraint.");
+ }
+ Set<Node> vars = new HashSet<Node>();
+ if (nameByVar.containsKey(s)) vars.add(s);
+ if (nameByVar.containsKey(p)) vars.add(p);
+ if (nameByVar.containsKey(o)) vars.add(o);
+ return vars;
+ }
+
+
+ /**
+ * Accumulates all of the variables in a conjunction.
+ * @param constraint The constraint node to find variables under.
+ * @return A Set of nodes which represent variables.
+ */
+ Set<Node> getVariablesConjunction(Node constraint) {
+ // Recursively get the variables from the arguments
+ Map<URIReference,Set<Node>> constraintProps = graph.get(constraint);
+ if (constraintProps == null) throw new IllegalArgumentException("Bad Krule structure. Missing arguments for a conjunction.");
+ Set<Node> args = constraintProps.get(Krule.ARGUMENT);
+ // accumulate the variables into the first result. This is not functional, but more efficient.
+ Set<Node> vars = null;
+ for (Node c: args) {
+ Set<Node> tmp = getVariables(c);
+ if (vars == null) vars = tmp;
+ else vars.addAll(tmp);
+ }
+ return vars;
+ }
+
+
+ /**
+ * Accumulates all of the variables in a difference.
+ * @param constraint The constraint node to find variables under.
+ * @return A Set of nodes which represent variables.
+ */
+ Set<Node> getVariablesDifference(Node constraint) {
+ // Recursively get the variables from the arguments
+ Node minuend = getPropertyValue(constraint, Krule.MINUEND);
+ Node subtrahend = getPropertyValue(constraint, Krule.SUBTRAHEND);
+ if (minuend == null) throw new IllegalArgumentException("Bad Krule structure. Missing minuend on a Difference.");
+ if (subtrahend == null) throw new IllegalArgumentException("Bad Krule structure. Missing subtrahend on a Difference.");
+ Set<Node> vars = getVariables(minuend);
+ vars.addAll(getVariables(subtrahend)); // not quite functional, but more efficient
+ return vars;
+ }
+
+
+ /**
+ * Accumulates all of the variables in a transitive constraint.
+ * @param constraint The constraint node to find variables under.
+ * @return A Set of nodes which represent variables.
+ */
+ Set<Node> getVariablesTransitive(Node constraint) {
+ // Recursively get the variables from the arguments
+ Node arg = getPropertyValue(constraint, Krule.TRANSITIVE_ARGUMENT);
+ if (arg == null || !arg.equals(Krule.SIMPLE_CONSTRAINT)) {
+ throw new IllegalArgumentException("Bad Krule structure. Transitive constraints must operate on simple arguments.");
+ }
+ return getVariables(arg);
+ }
+
+
+ /**
+ * Converts a triple to a string containing a DL predicate.
+ * @param s The subject of the triple.
+ * @param p The predicate of the triple.
+ * @param o The object of the triple.
+ * @return A string with the DL version of the predicate.
+ */
+ String toPredicate(Node s, Node p, Node o) {
+ if (isType(p)) return toTypePredicate(s, o);
+ return toBinaryPredicate(s, p, o);
+ }
+
+
+ /**
+ * Convert a subject and type into a Type predicate.
+ * @param s The subject to be typed.
+ * @param type The type of the subject.
+ * @return A string with the subject and type.
+ */
+ String toTypePredicate(Node s, Node type) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(toString(type));
+ sb.append("(");
+ sb.append(toString(s));
+ sb.append(")");
+ return sb.toString();
+ }
+
+
+ /**
+ * Convert a triple into a binary predicate.
+ * @param s The subject of the triple.
+ * @param p The predicate of the triple.
+ * @param o The object of the triple.
+ * @return A string with the DL version of the binary predicate.
+ */
+ String toBinaryPredicate(Node s, Node p, Node o) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(toString(p));
+ sb.append("(");
+ sb.append(toString(s));
+ sb.append(",");
+ sb.append(toString(o));
+ sb.append(")");
+ return sb.toString();
+ }
+
+
+ /**
+ * Gets the string representation of an object referenced by URIReference.
+ * @param n The node to get the value of.
+ * @return A string representation of the object.
+ */
+ String toString(Node n) {
+ Node refType = typeByNode.get(n); // Variable, URIReference or Literal
+ if (refType == null) throw new IllegalArgumentException("Bad Krule structure. No type for node: " + n);
+ if (!(refType instanceof URIReference)) throw new IllegalArgumentException("Bad Krule structure. Expected a reference for type, but got: " + refType);
+
+ // Get the referenced data
+ if (refType.equals(Krule.URI_REF)) {
+ // writing a URI
+ Node value = getPropertyValue(n, RDF_VALUE);
+ if (value == null || !(value instanceof URIReference)) throw new IllegalArgumentException("Bad Krule structure. URIReference came back with the wrong type: " + value + "(" + value.getClass().getName() + ")");
+ return namespaceString((URIReference)value);
+
+ } else if (refType.equals(Krule.VARIABLE)) {
+ return nameByVar.get(n);
+
+ } else if (refType.equals(Krule.LITERAL)) {
+ // writing a literal
+ Node value = getPropertyValue(n, RDF_VALUE);
+ if (!(value instanceof Literal)) throw new IllegalArgumentException("Bad Krule structure. Literal came back with the wrong type: " + value + "(" + value.getClass().getName() + ")");
+ return value.toString();
+
+ } else throw new IllegalArgumentException("Bad Krule structure. Output node is not a URI Reference, a variable, or a literal: " + refType);
+ }
+
+
+ /**
+ * Tests if a node is a reference to the rdf:type URI.
+ * @param n The node to check as a reference.
+ * @return <code>true</code> only if the node is a reference and it refers to rdf:type
+ */
+ boolean isType(Node n) {
+ Node refType = typeByNode.get(n); // Variable, URIReference or Literal
+ if (refType == null) throw new IllegalArgumentException("Bad Krule structure. No type for node: " + n);
+ if (!(refType instanceof URIReference)) throw new IllegalArgumentException("Bad Krule structure. Expected a reference for type, but got: " + refType);
+
+ // Get the referenced data
+ if (refType.equals(Krule.URI_REF)) {
+ // writing a URI
+ Node value = getPropertyValue(n, RDF_VALUE);
+ if (value == null || !(value instanceof URIReference)) throw new IllegalArgumentException("Bad Krule structure. URIReference came back with the wrong type: " + value + "(" + value.getClass().getName() + ")");
+ return value.equals(TYPE);
+ }
+ return false;
+ }
+
+
+ /**
+ * Get the namespace version of a URI.
+ * e.g. rdf:value instead of http://www.w3.org/1999/02/22-rdf-syntax-ns#value
+ * @param r The URI reference to convert to namespace form.
+ * @return The namespaced version of the URI.
+ */
+ String namespaceString(URIReference r) {
+ Pair<String,String> nsPair = addToNamespace(r);
+ String dom = nsPair.first();
+ String val = nsPair.second();
+
+ // Krule is the default namespace
+ if (dom.equals(Krule.KRULE)) return val;
+ return ((dom.endsWith(":")) ? dom : dom + ":") + val;
+ }
+
+
+ /**
+ * Scans nodes that are URIReferences, and adds them to the list of namespaces if not already there.
+ * @param r A node that may be a reference to be scanned.
+ */
+ void addToNamespace(Node n) {
+ if (!(n instanceof URIReference)) return;
+ addToNamespace((URIReference)n);
+ }
+
+
+ /**
+ * Scans a URIReference, and adds it to the list of namespaces if not already there.
+ * @param r The reference to be scanned.
+ * @return The domain abbreviation to use for this reference, and the value in the domain as a Pair.
+ */
+ Pair<String,String> addToNamespace(URIReference r) {
+ Pair<String,String> nsPair = splitUri(r.getURI());
+ String ns = nsPair.first();
+ String val = nsPair.second();
+ if (val.length() == 0) throw new IllegalArgumentException("Bad RLog data. URI needs a value in a domain to be serialized in RLog: " + r);
+
+ // determine the domain to use for this namespace
+ String dom = defaultNamespaces.get(ns);
+ if (dom == null) {
+ dom = namespaces.get(ns);
+ if (dom == null) {
+ namespaces.put(ns, dom = namespaceGen.newNamespace());
+ }
+ } else {
+ // domain is in the default list, add it to the in-use list
+ if (!namespaces.containsKey(ns)) namespaces.put(ns, dom);
+ }
+ return new Pair<String,String>(dom, val);
+ }
+
+
+ /**
+ * Gets the reference for a sequence member predicate.
+ * @param n The sequence index.
+ * @return The URI reference for <em>rdf:_n</em>.
+ */
+ URIReference getListId(int n) {
+ if (listIds.size() < n) {
+ for (int i = listIds.size() + 1; i <= n; i++) {
+ URI u = URI.create(RDF.BASE_URI + "_" + i);
+ listIds.add(new URIReferenceImpl(u));
+ }
+ }
+ return listIds.get(n - 1);
+ }
+
+
+ /**
+ * Convert a literal into a valid variable name. Variable names are a single upper case character.
+ * @param value The literal to convert.
+ * @return The validated, and converted name of the variable.
+ */
+ String getValidVariableName(Literal value) {
+ String var = ((Literal)value).getLexicalForm();
+ if (var.length() != 1) {
+ String v = var.substring(0, 1).toUpperCase();
+ logger.warn("Krule structure uses long variable names. Truncating: " + var + " -> " + v);
+ var = v;
+ }
+ if (!Character.isLetter(var.charAt(0))) throw new IllegalArgumentException("Bad Krule structure. Variable must be a letter: " + var);
+ if (!Character.isUpperCase(var.charAt(0))) {
+ logger.warn("Variable names must have upper case letters: " + var);
+ var = var.toUpperCase();
+ }
+ return var;
+ }
+
+
+ /**
+ * Gets the value of a property on an object.
+ * @param s The object in the graph.
+ * @param p The property being looked for.
+ * @return The value of the required property.
+ */
+ Node getPropertyValue(Node s, URIReference p) {
+ Map<URIReference,Set<Node>> values = graph.get(s);
+ if (values == null) throw new IllegalArgumentException("Bad Krule structure. Missing property <" + p + "> on object <" + s + ">");
+ return getSingle(values, p);
+ }
+
+
+ /**
+ * Map an object to a property value pair.
+ * @param subj The subject to set a property and value for.
+ * @param property The property for the subject.
+ * @param value The value for the subject's property.
+ */
+ static final void addPropertyValue(Map<Node,Map<URIReference,Set<Node>>> graph, Node subj, URIReference property, Node value) {
+ Map<URIReference,Set<Node>> propVal = graph.get(subj);
+ if (propVal == null) {
+ propVal = new HashMap<URIReference,Set<Node>>();
+ graph.put(subj, propVal);
+ }
+ addValue(propVal, property, value);
+ }
+
+
+ /**
+ * Map a property to a value.
+ * @param propertyValues The full set of properties and values for the current object.
+ * @param property The property to set on the current object.
+ * @param value The value to set the property to.
+ */
+ static final <T> void addValue(Map<T,Set<Node>> propertyValues, T property, Node value) {
+ Set<Node> values = propertyValues.get(property);
+ if (values == null) {
+ values = new HashSet<Node>();
+ propertyValues.put(property, values);
+ }
+ values.add(value);
+ }
+
+
+ /**
+ * Retrieves a single value from a multimap.
+ * @param <K> The type of the keys in the multimap.
+ * @param <V> The type of the values in the multimap.
+ * @param map The map to get the value from.
+ * @param key The key to find the value with.
+ * @return The single value found associated with the key, or null if not found.
+ * @throws IllegalArgumentException If the key maps to a set with more than one value.
+ */
+ static final <K,V> V getSingle(Map<K,Set<V>> map, K key) {
+ Set<V> vals = map.get(key);
+ if (vals == null || vals.size() == 0) return null;
+ if (vals.size() != 1) throw new IllegalArgumentException("Expecting singleton from a set of size: " + vals.size());
+ return vals.iterator().next();
+ }
+
+
+ /**
+ * Splits a URI into two sections. The second section contains the trailing identifier
+ * that includes only letters, digits and underscores. The first section is everything else.
+ * @param uri The URI to split.
+ * @return A pair of strings containing the two parts of the original URI.
+ */
+ static final Pair<String,String> splitUri(URI uri) {
+ String u = uri.toString();
+ for (int p = u.length() - 1; p >= 0; p--) {
+ char ch = u.charAt(p);
+ if (!Character.isLetterOrDigit(ch) && ch != '_' && ch != '-') {
+ p = p + 1;
+ return new Pair<String,String>(u.substring(0, p), u.substring(p));
+ }
+ }
+ return new Pair<String,String>("", u);
+ }
+
+
+ /**
+ * This class is a utility to generate new namespace names.
+ */
+ class NamespaceGenerator {
+ /** The namespace counter */
+ int n = 1;
+
+ /**
+ * Create a new name for a namespace.
+ * @return A new name.
+ */
+ String newNamespace() {
+ return "ns" + n++;
+ }
+ }
+}
Copied: trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/Program.java (from rev 1625, branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/Program.java)
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/Program.java (rev 0)
+++ trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/Program.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -0,0 +1,152 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.krule.rlog;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.mulgara.krule.rlog.ast.CanonicalStatement;
+import org.mulgara.krule.rlog.ast.Statement;
+
+/**
+ * Represents a complete program, including annotations.
+ * A program is mostly a list of statements, but can also include other elements
+ * such as "imports" of other programs.
+ *
+ * @created Mar 3, 2009
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class Program {
+
+ /** Logger. */
+ private static final Logger logger = Logger.getLogger(Program.class.getName());
+
+ /** All the statement that make up the program */
+ private List<Statement> statements;
+
+ /** The canonical forms of the statements that make up the program */
+ private List<CanonicalStatement> canonicalStatements;
+
+ /** The list of imports */
+ private List<URI> imports;
+
+ /**
+ * Constructs an empty program.
+ */
+ public Program() {
+ statements = new ArrayList<Statement>();
+ canonicalStatements = new ArrayList<CanonicalStatement>();
+ imports = new ArrayList<URI>();
+ }
+
+
+ /**
+ * Retrieve the statements from this program.
+ * @return A list of statements in the program.
+ */
+ public List<Statement> getStatements() {
+ return statements;
+ }
+
+
+ /**
+ * Merges the statements from another program into this one.
+ * Note that the parsing context of the foreign statements is maintained.
+ * @param p The foreign program to merge.
+ */
+ public void merge(Program p) {
+ logger.debug("Merging programs");
+ for (Statement s: p.getStatements()) add(s);
+ }
+
+
+ /**
+ * Adds a statement to this program. If the statement is already present it is skipped.
+ * @param s The statement to add.
+ */
+ public void add(Statement s) {
+ CanonicalStatement canonical = s.getCanonical();
+ if (!statementPresent(s, canonical)) {
+ statements.add(s);
+ canonicalStatements.add(canonical);
+ } else {
+ logger.debug("Not adding: " + s);
+ }
+ }
+
+
+ /**
+ * Adds an import directive to the program.
+ */
+ public void addImport(String imp) throws ParseException {
+ try {
+ URI u = new URI(imp);
+ imports.add(u);
+ } catch (URISyntaxException e) {
+ throw new ParseException("Bad URL in import");
+ }
+ }
+
+
+ /**
+ * Get all the import URIs for the document
+ * @return A List of URIs. These can be absolute or relative.
+ */
+ public List<URI> getImports() {
+ return imports;
+ }
+
+
+ /**
+ * Get an iterator for the statements in this program.
+ * @return A new iterator that returns statements.
+ */
+ public Iterator<Statement> stmtIterator() {
+ return statements.iterator();
+ }
+
+ /** @see java.lang.Object#toString() */
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ for (Statement s: statements) {
+ sb.append(s).append("\n");
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Tests if a statement is already present in the program.
+ * Attempts to canonicalize statements for comparison.
+ * @param stmt The statement to look for. Included for logging purposes.
+ * @param canonical The canonicalized form of the statement to look for.
+ * @return <code>true</code> if an equivalent statement is found, <code>false</code> otherwise.
+ */
+ private boolean statementPresent(Statement stmt, CanonicalStatement canonical) {
+ if (logger.isDebugEnabled()) logger.debug("Testing for presence of: " + stmt);
+ for (CanonicalStatement s: canonicalStatements) {
+ if (canonical.equals(s)) {
+ if (logger.isDebugEnabled()) logger.debug(canonical.toString() + " == " + s);
+ return true;
+ }
+ if (logger.isDebugEnabled()) logger.debug(canonical.toString() + " != " + s);
+ }
+ if (logger.isDebugEnabled()) logger.debug("New statement: " + stmt);
+ return false;
+ }
+}
Modified: trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/Rlog.java
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/Rlog.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/Rlog.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -17,6 +17,9 @@
package org.mulgara.krule.rlog;
import java.io.*;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
@@ -24,8 +27,8 @@
import java.util.Collection;
import java.util.Set;
+import org.apache.log4j.Logger;
import org.mulgara.krule.rlog.ast.*;
-import org.mulgara.krule.rlog.ast.output.KruleWriter;
import org.mulgara.krule.rlog.parser.TypeException;
import org.mulgara.krule.rlog.parser.URIParseException;
import org.mulgara.krule.rlog.rdf.MulgaraGraphs;
@@ -41,6 +44,9 @@
*/
public class Rlog implements Interpreter {
+ /** Logger. */
+ private static final Logger logger = Logger.getLogger(Rlog.class.getName());
+
/** The label used on all generated rules. */
private static String ruleLabel = "rule";
@@ -54,45 +60,6 @@
private List<Rule> rules;
/**
- * Parse input data into an AST and process.
- * @param args May contain a filename with the code to be parsed. All other parameters ignored.
- * @throws IOException If there was an error reading from the specified file, or standard in.
- * @throws beaver.Parser.Exception If there was a parsing exception.
- */
- public static void main(String[] args) throws IOException, ParseException {
- // get the input
- Reader intReader;
- if (args.length > 0) {
- File inFile = new File(args[0]);
- if (!inFile.exists() || !inFile.canRead()) {
- System.err.println("Unable to open file: " + inFile);
- return;
- }
- // borrow the filename for labelling rules
- intReader = new FileReader(inFile);
- String filename = inFile.getName();
- ruleLabel = filename.substring(0, filename.lastIndexOf('.'));
- } else {
- intReader = new InputStreamReader(System.in);
- }
- Reader input = new BufferedReader(intReader);
-
- try {
- // parse the input
- Rlog rlog = new Rlog(input);
- // emit to output
- new KruleWriter(rlog).emit(System.out);
- } catch (TypeException te) {
- System.err.println(te.getMessage());
- return;
- } catch (URIParseException e) {
- System.err.println(e.getMessage());
- return;
- }
-
- }
-
- /**
* Sets the label to use for each rule. The rule names are made up of this label
* plus an incremening number.
* @param label The text label to use on rules.
@@ -104,16 +71,15 @@
/**
* Create an rlog interpreter for building an AST from a stream Reader object.
* @param input The stream Reader.
+ * @param inputLocation The location the input comes from.
* @throws IOException There was an IO Exception on the input.
* @throws beaver.Parser.Exception There was a parser exception in the input data.
* @throws URIParseException If the rules contain illegal URIs.
*/
- public Rlog(Reader input) throws IOException, ParseException, TypeException, URIParseException {
- // parse the rlog into statements
- RlogParser parser = new RlogParser(input);
+ public Rlog(Reader input, URI inputLocation) throws IOException, ParseException, TypeException, URIParseException {
+ Program program = loadProgram(input, inputLocation);
+ statements = program.getStatements();
- statements = parser.statements();
-
// separate out the rules from the axioms
int ruleCount = 0;
rules = new ArrayList<Rule>();
@@ -130,7 +96,35 @@
calculateRuleDependencies();
}
+
/**
+ * Loads a program from an input Reader.
+ * @param input The Reader to get the program from.
+ * @param baseLocation The location context to load the program in. This is used for relative
+ * import declartations.
+ * @return The fully loaded program, including imports.
+ * @throws IOException Due to an IO error while loading the program.
+ * @throws ParseException If the program contains an error.
+ */
+ private Program loadProgram(Reader input, URI baseLocation) throws IOException, ParseException {
+ // parse the rlog into statements
+ RlogParser parser = new RlogParser(input);
+
+ try {
+ Program program = parser.getProgram();
+ loadImports(program, baseLocation);
+ return program;
+ } catch (ParseException e) {
+ logger.error("Error parsing program: " + e.getMessage());
+ throw e;
+ } catch (IOException e) {
+ logger.error("IO Error reading program: " + e.getMessage());
+ throw e;
+ }
+ }
+
+
+ /**
* Find all the variables in every rule.
* @return A complete collection of all the variables that were parsed.
*/
@@ -140,6 +134,7 @@
return vars;
}
+
/**
* Gets all the URIs referenced in the rules.
* @return All URIs in order of appearance within axioms, then rules.
@@ -153,6 +148,7 @@
return refs;
}
+
/**
* Get all the axioms appearing in the rule set.
* @return A list of axioms.
@@ -161,6 +157,7 @@
return Collections.unmodifiableList(axioms);
}
+
/**
* Get all the rules appearing in the rule set.
* @return A list of rules.
@@ -169,6 +166,7 @@
return Collections.unmodifiableList(rules);
}
+
/**
* Determine which rules are dependent on the result of which other rules,
* and set the rule objects accordingly.
@@ -182,4 +180,53 @@
}
}
+
+ /**
+ * Load all imports into the given program.
+ * @param prog The program to load its imports into.
+ * @param currentLocation A URI for the location of the program. Used for relative loads.
+ * @throws IOException If the import files cannot be read.
+ * @throws ParseException If an imported program has an error.
+ */
+ private void loadImports(Program prog, URI currentLocation) throws IOException, ParseException {
+ List<URI> imports = prog.getImports();
+ for (URI imp: imports) {
+ URL importLocation = makeAbsolute(currentLocation, imp);
+ if (logger.isDebugEnabled()) logger.debug("Importing " + importLocation);
+ Reader input = new InputStreamReader(importLocation.openStream());
+ Program impProgram;
+ try {
+ impProgram = loadProgram(input, currentLocation);
+ } catch (ParseException e) {
+ logger.error("Error in imported program <" + importLocation + ">");
+ throw e;
+ } finally {
+ input.close();
+ }
+ prog.merge(impProgram);
+ }
+ }
+
+
+ /**
+ * Calculate a URL from a given URI, relative to the current base location.
+ * @param base The base to calculate the final URL from. Must be a URL if <var>rel</var> is relative.
+ * @param rel The URL that is relative to the base. If absolute, then <var>base</var> is ignored.
+ * @return A new URL, which is <var>rel</var> if it is absolute, or a merge of <var>rel</var> and
+ * <var>base</var> if <var>rel</var> is relative.
+ * @throws IllegalArgumentException If <var>rel</var> is relative and <var>base</var> is not a URL,
+ * or if <var>rel</var> (or <var>base</var>+<var>rel</var>) is not a valid URL.
+ */
+ private URL makeAbsolute(URI base, URI rel) {
+ try {
+ if (!rel.isAbsolute()) {
+ if (base == null) throw new IllegalArgumentException("Relative URL used in import with no current location set");
+ return new URL(base.toURL(), rel.toString());
+ } else {
+ return rel.toURL();
+ }
+ } catch (MalformedURLException e) {
+ throw new IllegalArgumentException("Invalid URL for import of (" + rel + ")" + ": "+ e.getMessage());
+ }
+ }
}
Modified: trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Axiom.java
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Axiom.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Axiom.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -104,5 +104,15 @@
public RDFNode getObject() throws URIParseException {
return predicate.getObject();
}
+
+ @Override
+ public CanonicalStatement getCanonical() {
+ return new CanonicalStatement(predicate.getCanonical());
+ }
+
+ /** @see java.lang.Object#toString() */
+ public String toString() {
+ return predicate.toString() + ".";
+ }
}
Modified: trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/BPredicate.java
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/BPredicate.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/BPredicate.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -107,7 +107,7 @@
//inheritdoc
public String toString() {
- return "BPredicate: " + label + "(" + left + "," + right + ")";
+ return label.toString() + "(" + left + "," + right + ")";
}
//inheritdoc
@@ -132,5 +132,14 @@
graphAnnotation = MulgaraGraphs.getPredicateGraph(((URIReference)predicate).getURI());
}
}
+
+ /**
+ * Creates a canonical form for this predicate.
+ * @see org.mulgara.krule.rlog.ast.Predicate#getCanonical()
+ */
+ @Override
+ CanonicalPredicate getCanonical() {
+ return new CanonicalPredicate(left, (PredicateParam)label, right);
+ }
}
Copied: trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CanonicalPredicate.java (from rev 1625, branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CanonicalPredicate.java)
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CanonicalPredicate.java (rev 0)
+++ trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CanonicalPredicate.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -0,0 +1,197 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.krule.rlog.ast;
+
+/**
+ * Represents a canonicalization of a predicate.
+ *
+ * @created Mar 4, 2009
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class CanonicalPredicate implements Comparable<CanonicalPredicate> {
+
+ /** The number of elements for a binary predicate. */
+ private static final int BINARY_LENGTH = 3;
+
+ /** The number of elements for a unary predicate. */
+ private static final int UNARY_LENGTH = 2;
+
+ /** The number of elements for a null predicate. */
+ private static final int NULL_LENGTH = 0;
+
+ /** The different in ID between inverted predicates and the original predicate. */
+ private static final int INVERT_DIFF = 8;
+
+ /** The elements of the predicate */
+ private PredicateParam[] elements;
+
+ /** A flag to indicate that this predicate is inverted. */
+ private boolean invertFlag = false;
+
+ /** An ID used internally for comparisons between differing types. */
+ private int typeId;
+
+ /**
+ * Create a new canonicalized form for a null predicate.
+ */
+ CanonicalPredicate() {
+ elements = new PredicateParam[NULL_LENGTH];
+ typeId = elements.length;
+ }
+
+
+ /**
+ * Create a new canonicalized form for a binary predicate.
+ * @param s The subject of the predicate.
+ * @param p The value of the predicate.
+ * @param o The object of the predicate.
+ */
+ CanonicalPredicate(PredicateParam s, PredicateParam p, PredicateParam o) {
+ elements = new PredicateParam[BINARY_LENGTH];
+ elements[0] = s;
+ elements[1] = p;
+ elements[2] = o;
+ typeId = elements.length;
+ }
+
+
+ /**
+ * Create a new canonicalized form for a unary predicate.
+ * @param t The type of the predicate.
+ * @param v The value of the predicate.
+ */
+ CanonicalPredicate(PredicateParam t, PredicateParam v) {
+ elements = new PredicateParam[UNARY_LENGTH];
+ elements[0] = t;
+ elements[1] = v;
+ typeId = elements.length;
+ }
+
+
+ /**
+ * Changes this predicate to an inverted one.
+ */
+ public CanonicalPredicate invert() {
+ invertFlag = !invertFlag;
+ typeId += invertFlag ? INVERT_DIFF : -INVERT_DIFF;
+ return this;
+ }
+
+
+ /**
+ * Changes this predicate to an inverted one.
+ */
+ public boolean isInverted() {
+ return invertFlag;
+ }
+
+
+ /**
+ * Updates variables to a canonical form
+ * @param con The object with the update state for the variables.
+ */
+ public void renameVariables(VariableCanonicalizer con) {
+ for (int i = 0; i < elements.length; i++) {
+ if (elements[i] instanceof Variable) {
+ elements[i] = con.get((Variable)elements[i]);
+ }
+ }
+ }
+
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ StringBuilder s = new StringBuilder();
+ if (invertFlag) s.append("~");
+ switch (elements.length) {
+ case NULL_LENGTH:
+ s.append("<<null>>");
+ break;
+ case UNARY_LENGTH:
+ s.append(elements[0]);
+ s.append("(").append(elements[1]).append(")");
+ break;
+ case BINARY_LENGTH:
+ s.append(elements[1]);
+ s.append("(").append(elements[0]).append(", ");
+ s.append(elements[2]).append(")");
+ break;
+ default:
+ throw new IllegalStateException("Illegal predicate structure. Length = " + elements.length);
+ }
+ return s.toString();
+ }
+
+
+ /**
+ * Tests if this predicate equals another.
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object o) {
+ if (!(o instanceof CanonicalPredicate)) return false;
+ CanonicalPredicate cp = (CanonicalPredicate)o;
+ if (elements.length != cp.elements.length) return false;
+ for (int i = 0; i < elements.length; i++) {
+ if (!elements[i].equals(cp.elements[i])) return false;
+ }
+ return true;
+ }
+
+
+ /**
+ * Generate a repeatable hashcode for this predicate.
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ final int[] seed = new int[] { 7, 13, 17, 19 };
+ int result = 5;
+ for (int i = 0; i < elements.length; i++) result += seed[i] * elements[i].hashCode();
+ return result;
+ }
+
+
+ /**
+ * Compare this predicate to another.
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ public int compareTo(CanonicalPredicate cpred) {
+ if (typeId != cpred.typeId) return typeId - cpred.typeId;
+ return compareOnElt(0, cpred);
+ }
+
+
+ /**
+ * Compare this predicate, first on equivalent types, and then on type.
+ * Order by PredicateLiteral, StringLiteral, IntegerLiteral, Var.
+ * @param i The element being compared at this stage.
+ * @param cpred The other CanonicalPredicate to compare against.
+ * @return >0 if this object occurs after cpred, <0 if this object is before cpred,
+ * and 0 if this object is equal to cpred.
+ */
+ private int compareOnElt(int i, CanonicalPredicate cpred) {
+ assert i >= 0 && i < elements.length;
+ int typeDiff = elements[i].orderId() - cpred.elements[i].orderId();
+ // if the types are the same then compare
+ if (typeDiff == 0) {
+ int r = elements[i].compareTo(cpred.elements[i]);
+ // if the elements are equal, then move to the next element
+ return r == 0 && ++i < elements.length ? compareOnElt(i, cpred) : r;
+ }
+ return typeDiff;
+ }
+
+}
Copied: trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CanonicalPredicateTest.java (from rev 1625, branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CanonicalPredicateTest.java)
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CanonicalPredicateTest.java (rev 0)
+++ trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CanonicalPredicateTest.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -0,0 +1,179 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.krule.rlog.ast;
+
+import org.apache.log4j.Logger;
+import org.mulgara.krule.rlog.ParseContext;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ *
+ *
+ * @created Mar 10, 2009
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class CanonicalPredicateTest extends TestCase {
+
+ @SuppressWarnings("unused")
+ private static final Logger logger = Logger.getLogger(CanonicalPredicateTest.class.getName());
+
+ ParseContext context = new ParseContext();
+
+ /**
+ * Create the test
+ * @param name The name of the test.
+ */
+ public CanonicalPredicateTest(String name) {
+ super(name);
+ }
+
+
+ /**
+ * Hook from which the test runner can obtain a test suite.
+ *
+ * @return the test suite
+ */
+ public static Test suite() {
+ TestSuite suite = new TestSuite(CanonicalPredicateTest.class);
+ return suite;
+ }
+
+
+ /**
+ * This is a hook for initializing a test.
+ */
+ public void setup() {
+ }
+
+
+ /**
+ * Test that a predicate can be canonicalized.
+ *
+ * @throws Exception Due to any kind of internal failure.
+ */
+ public void testBinaryLiteral() throws Exception {
+ PredicateParam left = new BPredicateLiteral("foo", "bar", context);
+ PredicateParam right = new BPredicateLiteral("foo", "baz", context);
+ BPredicateLabel label = new BPredicateLiteral("foo", "pred", context);
+ Predicate p = new BPredicate(label, left, right, context);
+ CanonicalPredicate cp = p.getCanonical();
+ assertEquals("foo:pred(foo:bar, foo:baz)", cp.toString());
+ cp.invert();
+ assertEquals("~foo:pred(foo:bar, foo:baz)", cp.toString());
+ }
+
+ /**
+ * Test that a type predicate can be canonicalized.
+ *
+ * @throws Exception Due to any kind of internal failure.
+ */
+ public void testTypeLiteral() throws Exception {
+ PredicateParam left = new BPredicateLiteral("foo", "bar", context);
+ TypeLabel label = new TypeLiteral("foo", "Type", context);
+ Predicate p = new TypeStatement(label, left, context);
+ CanonicalPredicate cp = p.getCanonical();
+ assertEquals("foo:Type(foo:bar)", cp.toString());
+ cp.invert();
+ assertEquals("~foo:Type(foo:bar)", cp.toString());
+ }
+
+ /**
+ * Test that a binary predicate with variables can be canonicalized.
+ *
+ * @throws Exception Due to any kind of internal failure.
+ */
+ public void testBinaryVar() throws Exception {
+ PredicateParam left = new BPredicateLiteral("foo", "bar", context);
+ PredicateParam right = new Variable("X");
+ BPredicateLabel label = new BPredicateLiteral("foo", "pred", context);
+ Predicate p = new BPredicate(label, left, right, context);
+ CanonicalPredicate cp = p.getCanonical();
+ assertEquals("foo:pred(foo:bar, ?X)", cp.toString());
+ VariableCanonicalizer con = new VariableCanonicalizer();
+ cp.renameVariables(con);
+ assertEquals("foo:pred(foo:bar, ?V1)", cp.toString());
+
+ left = new Variable("A");
+ right = new Variable("B");
+ label = new Variable("C");
+ p = new BPredicate(label, left, right, context);
+ cp = p.getCanonical();
+ assertEquals("?C(?A, ?B)", cp.toString());
+ con = new VariableCanonicalizer();
+ cp.renameVariables(con);
+ assertEquals("?V2(?V1, ?V3)", cp.toString());
+ cp.renameVariables(con);
+ assertEquals("?V5(?V4, ?V6)", cp.toString());
+
+ cp = p.getCanonical();
+ cp.renameVariables(con);
+ assertEquals("?V2(?V1, ?V3)", cp.toString());
+ }
+
+ /**
+ * Test that a variable type predicate can be canonicalized.
+ *
+ * @throws Exception Due to any kind of internal failure.
+ */
+ public void testTypeVariable() throws Exception {
+ PredicateParam left = new BPredicateLiteral("foo", "bar", context);
+ TypeLabel label = new Variable("X");
+ Predicate p = new TypeStatement(label, left, context);
+ CanonicalPredicate cp = p.getCanonical();
+ assertEquals("?X(foo:bar)", cp.toString());
+ VariableCanonicalizer con = new VariableCanonicalizer();
+ cp.renameVariables(con);
+ assertEquals("?V1(foo:bar)", cp.toString());
+
+ left = new Variable("B");
+ label = new Variable("A");
+ p = new TypeStatement(label, left, context);
+ cp = p.getCanonical();
+ assertEquals("?A(?B)", cp.toString());
+ con = new VariableCanonicalizer();
+ cp.renameVariables(con);
+ assertEquals("?V1(?V2)", cp.toString());
+
+ cp.renameVariables(con);
+ assertEquals("?V3(?V4)", cp.toString());
+
+ cp = p.getCanonical();
+ cp.renameVariables(con);
+ assertEquals("?V1(?V2)", cp.toString());
+ }
+
+ /**
+ * Test that a variable type predicate can be equal.
+ *
+ * @throws Exception Due to any kind of internal failure.
+ */
+ public void testTypeEqual() throws Exception {
+ PredicateParam left = new BPredicateLiteral("foo", "bar", context);
+ TypeLabel label = new Variable("X");
+ Predicate p = new TypeStatement(label, left, context);
+ CanonicalPredicate cp = p.getCanonical();
+ VariableCanonicalizer con = new VariableCanonicalizer();
+ cp.renameVariables(con);
+ assertEquals("?V1(foo:bar)", cp.toString());
+
+ Predicate p2 = new TypeStatement(new Variable("V1"), left, context);
+ assertNotSame(p, p2);
+ assertEquals(cp, p2.getCanonical());
+ }
+
+}
Copied: trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CanonicalStatement.java (from rev 1625, branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CanonicalStatement.java)
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CanonicalStatement.java (rev 0)
+++ trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CanonicalStatement.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -0,0 +1,111 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.krule.rlog.ast;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Represents a canonicalized form of a statement. Used for comparing statements
+ * to check them for redundancy.
+ *
+ * @created Mar 12, 2009
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class CanonicalStatement {
+
+ /** A sorted list of predicates */
+ private List<CanonicalPredicate> body;
+
+ /** The head of the rule. May be empty. */
+ private CanonicalPredicate head;
+
+
+ /**
+ * Creates a canonical statement to represent an axiom.
+ * @param h The predicate in the axiom.
+ */
+ CanonicalStatement(CanonicalPredicate h) {
+ this(h, null);
+ }
+
+
+ /**
+ * Creates a canonical statement to represent a rule.
+ * @param h The predicate in the head of the rule.
+ * @param b The <em>sorted</em> predicates in the body of the rule.
+ */
+ CanonicalStatement(CanonicalPredicate h, List<CanonicalPredicate> b) {
+ if (b == null) body = Collections.emptyList();
+ else body = b;
+ head = h;
+ renameVariables();
+ }
+
+
+ /**
+ * Test is this statement is the same as another.
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object o) {
+ if (!(o instanceof CanonicalStatement)) return false;
+ CanonicalStatement s = (CanonicalStatement)o;
+ return equal(head, s.head) && body.equals(s.body);
+ }
+
+
+ /**
+ * Generates a hashcode which merges the hashcodes of the body and head.
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ int hhc = head.hashCode();
+ return (hhc >>> 16 | hhc << 16) ^ body.hashCode();
+ }
+
+
+ public String toString() {
+ StringBuilder s = new StringBuilder();
+ s.append(head);
+ s.append(" :- ");
+ for (int p = 0; p < body.size(); p++) {
+ if (p == 0) s.append(", ");
+ s.append(body.get(p));
+ }
+ s.append(".");
+ return s.toString();
+ }
+
+ /**
+ * Renames the variables into a canonical form.
+ */
+ private void renameVariables() {
+ VariableCanonicalizer vc = new VariableCanonicalizer();
+ for (CanonicalPredicate p: body) p.renameVariables(vc);
+ head.renameVariables(vc);
+ }
+
+
+ /**
+ * Performs an equality comparison for values that may be null.
+ * @param a The first object to be compared. May be null.
+ * @param b The second object to be compared. May be null.
+ * @return <code>true</code> if both a and b are null, or if they are equal.
+ * <code>false</code> otherwise.
+ */
+ private static final boolean equal(Object a, Object b) {
+ return a == null ? b == null : a.equals(b);
+ }
+}
Copied: trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CheckRule.java (from rev 1625, branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CheckRule.java)
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CheckRule.java (rev 0)
+++ trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CheckRule.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -0,0 +1,49 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.krule.rlog.ast;
+
+import java.util.List;
+
+import org.mulgara.krule.rlog.ParseContext;
+
+/**
+ * A headless rule, used for checking validity.
+ *
+ * @created Mar 3, 2009
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class CheckRule extends Rule {
+
+ /**
+ * @param body The body of the rule.
+ * @param context The parsing context for this rule.
+ */
+ public CheckRule(List<Predicate> body, ParseContext context) {
+ super(body, context);
+ }
+
+
+ /** @see java.lang.Object#toString() */
+ public String toString() {
+ StringBuilder sb = new StringBuilder(":- ");
+ for (int b = 0; b < body.size(); b++) {
+ if (b != 0) sb.append(", ");
+ sb.append(body.get(b));
+ }
+ sb.append(".");
+ return sb.toString();
+ }
+
+}
Modified: trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/IntegerLiteral.java
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/IntegerLiteral.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/IntegerLiteral.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -73,5 +73,26 @@
public RDFNode getRDFNode() {
return new Literal(value.toString(), RDF.XSD_LONG);
}
+
+
+ /**
+ * Order by PredicateLiteral, StringLiteral, IntegerLiteral, Var.
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ public int compareTo(PredicateParam o) {
+ if (o instanceof IntegerLiteral) return value.compareTo(((IntegerLiteral)o).value);
+ // Smaller than Variable, larger than everything else
+ return (o instanceof Variable) ? -1 : 1;
+ }
+
+
+ /**
+ * Defines the ordering that this class occurs in, compared to other PredicateParams
+ * @see org.mulgara.krule.rlog.ast.PredicateParam#orderId()
+ */
+ public int orderId() {
+ return INTEGER_LITERAL_ID;
+ }
+
}
Modified: trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/InvertedPredicate.java
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/InvertedPredicate.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/InvertedPredicate.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -91,5 +91,10 @@
return invertPredicate.getObject();
}
+ @Override
+ CanonicalPredicate getCanonical() {
+ return invertPredicate.getCanonical().invert();
+ }
+
}
Modified: trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/NullPredicate.java
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/NullPredicate.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/NullPredicate.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -90,5 +90,15 @@
throw new UnsupportedOperationException();
}
+ /** @see java.lang.Object#toString() */
+ public String toString() {
+ return "";
+ }
+
+ @Override
+ CanonicalPredicate getCanonical() {
+ return new CanonicalPredicate();
+ }
+
}
Modified: trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Predicate.java
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Predicate.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Predicate.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -172,6 +172,12 @@
}
/**
+ * Returns a canonical version of this predicate.
+ * @return A new canonical predicate, with canonicalized elements.
+ */
+ abstract CanonicalPredicate getCanonical();
+
+ /**
* Converts a Variable to a Var. Accepts multiple types.
* @param v The Variable to convert. This must be a Variable.
* @return a new Var that is equivalent to the v.
Modified: trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/PredicateLiteral.java
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/PredicateLiteral.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/PredicateLiteral.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -79,5 +79,28 @@
if (ref == null) throw new URIParseException(name);
return ref;
}
+
+ /**
+ * Order by PredicateLiteral, StringLiteral, IntegerLiteral, Var.
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ public int compareTo(PredicateParam o) {
+ // smaller than everything except other PredicateLiterals
+ return (o instanceof PredicateLiteral) ? name.compareTo(((PredicateLiteral)o).name) : -1;
+ }
+
+ /**
+ * Defines the ordering that this class occurs in, compared to other PredicateParams
+ * @see org.mulgara.krule.rlog.ast.PredicateParam#orderId()
+ */
+ public int orderId() {
+ return PREDICATE_LITERAL_ID;
+ }
+
+ /** @see java.lang.Object#toString() */
+ public String toString() {
+ return name;
+ }
+
}
Modified: trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/PredicateParam.java
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/PredicateParam.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/PredicateParam.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -26,9 +26,17 @@
* @copyright © 2007 <a href="mailto:pgearon at users.sourceforge.net">Topaz Project</a>
* @licence <a href="http://www.opensource.org/licenses/apache2.0.php">Apache License, Version 2.0</a>
*/
-public interface PredicateParam {
+public interface PredicateParam extends Comparable<PredicateParam> {
public void accept(TreeWalker walker);
public void print(int indent);
public RDFNode getRDFNode() throws URIParseException;
+ public int orderId();
+
+ // Identifiers for ordering subtypes
+ static final int PREDICATE_LITERAL_ID = 1;
+ static final int STRING_LITERAL_ID = 2;
+ static final int INTEGER_LITERAL_ID = 3;
+ static final int VARIABLE_ID = 4;
+
}
Modified: trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Rule.java
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Rule.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Rule.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -16,6 +16,7 @@
package org.mulgara.krule.rlog.ast;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
@@ -31,6 +32,7 @@
import org.mulgara.krule.rlog.rdf.RDFNode;
import org.mulgara.krule.rlog.rdf.URIReference;
import org.mulgara.krule.rlog.rdf.Var;
+import org.mulgara.util.functional.C;
/**
* Represents a rule statement.
@@ -56,7 +58,7 @@
/** The name of this rule. Used in RDF. */
private String name;
- public Rule(List<Predicate> body, ParseContext context) {
+ protected Rule(List<Predicate> body, ParseContext context) {
this(NullPredicate.NULL, body, context);
}
@@ -209,6 +211,28 @@
return triggers;
}
+ @Override
+ public CanonicalStatement getCanonical() {
+ List<CanonicalPredicate> list = new ArrayList<CanonicalPredicate>(body.size() + 1);
+ // reorder the predicates
+ for (Predicate p: body) C.ascendingInsert(list, p.getCanonical());
+ return new CanonicalStatement(head.getCanonical(), list);
+ }
+
+
+ /** @see java.lang.Object#toString() */
+ public String toString() {
+ StringBuilder sb = new StringBuilder(head.toString());
+ sb.append(" :- ");
+ for (int b = 0; b < body.size(); b++) {
+ if (b != 0) sb.append(", ");
+ sb.append(body.get(b));
+ }
+ sb.append(".");
+ return sb.toString();
+ }
+
+
/**
* Checks that all variables in the head are found in the body, and that every subtracted predicate
* contains at least one variable that appears in the standard matching predicates.
Modified: trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Statement.java
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Statement.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Statement.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -35,5 +35,11 @@
super(context);
}
+ /**
+ * Get a list of canonicalized predicates to represent the statement. The body of the
+ * statement must be sorted, but if a head exists then it must be at the end.
+ * @return A list containing the statement in canonical form.
+ */
+ public abstract CanonicalStatement getCanonical();
}
Modified: trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/StringLiteral.java
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/StringLiteral.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/StringLiteral.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -67,5 +67,24 @@
public RDFNode getRDFNode() {
return new Literal(value.toString());
}
+
+ /**
+ * Order by PredicateLiteral, StringLiteral, IntegerLiteral, Var.
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ public int compareTo(PredicateParam o) {
+ if (o instanceof StringLiteral) return value.compareTo(((StringLiteral)o).value);
+ // larger than PredicateLiteral, smaller than everything else
+ return (o instanceof PredicateLiteral) ? 1 : -1;
+ }
+
+ /**
+ * Defines the ordering that this class occurs in, compared to other PredicateParams
+ * @see org.mulgara.krule.rlog.ast.PredicateParam#orderId()
+ */
+ public int orderId() {
+ return STRING_LITERAL_ID;
+ }
+
}
Modified: trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/TypeStatement.java
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/TypeStatement.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/TypeStatement.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -97,7 +97,7 @@
// inheritdoc
public String toString() {
- return "TypeStatement: type(" + typeLabel + ") param(" + param + ")";
+ return typeLabel.toString() + "(" + param + ")";
}
//inheritdoc
@@ -113,7 +113,18 @@
return typeLabel.hashCode() * 37 + param.hashCode();
}
+
/**
+ * Creates a canonical form for this predicate.
+ * @see org.mulgara.krule.rlog.ast.Predicate#getCanonical()
+ */
+ @Override
+ CanonicalPredicate getCanonical() {
+ return new CanonicalPredicate((PredicateParam)typeLabel, param);
+ }
+
+
+ /**
* Search for the type in the special graphs, and annotate this predicate
* to any detected graphs.
*/
Modified: trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Variable.java
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Variable.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Variable.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -47,7 +47,7 @@
}
public String toString() {
- return "var(" + name + ")";
+ return "?" + name;
}
/** {@inheritDoc} */
@@ -66,5 +66,24 @@
return name.hashCode();
}
+
+ /**
+ * Order by PredicateLiteral, StringLiteral, IntegerLiteral, Var.
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ public int compareTo(PredicateParam o) {
+ // larger than everything except other variables
+ return (o instanceof Variable) ? name.compareTo(((Variable)o).name) : 1;
+ }
+
+
+ /**
+ * Defines the ordering that this class occurs in, compared to other PredicateParams
+ * @see org.mulgara.krule.rlog.ast.PredicateParam#orderId()
+ */
+ public int orderId() {
+ return VARIABLE_ID;
+ }
+
}
Copied: trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/VariableCanonicalizer.java (from rev 1625, branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/VariableCanonicalizer.java)
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/VariableCanonicalizer.java (rev 0)
+++ trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/VariableCanonicalizer.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -0,0 +1,47 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.krule.rlog.ast;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Maintains state for updating variables to a canonical form.
+ *
+ * @created Mar 4, 2009
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class VariableCanonicalizer {
+
+ /** Maintains the state of the variables that have already been mapped to new names. */
+ private Map<Variable,Variable> varMap = new HashMap<Variable,Variable>();
+
+ /** The index used to name variables. */
+ private int varIndex = 1;
+
+ /**
+ * Get the canonical variable that a variable is supposed to map to.
+ * @param old The old variable to be replaced.
+ * @return The new variable that the old variable is mapped to.
+ */
+ public Variable get(Variable old) {
+ Variable newVar = varMap.get(old);
+ if (newVar == null) {
+ newVar = new Variable("V" + varIndex++);
+ varMap.put(old, newVar);
+ }
+ return newVar;
+ }
+}
Modified: trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/output/AxiomGenerator.java
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/output/AxiomGenerator.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/output/AxiomGenerator.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -31,7 +31,7 @@
import java.util.Collection;
import java.util.List;
-import static org.mulgara.krule.KruleLoader.*;
+import static org.mulgara.query.rdf.Krule.*;
/**
* Writes variables to a list of triples.
Modified: trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/output/RuleGenerator.java
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/output/RuleGenerator.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/output/RuleGenerator.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -18,6 +18,7 @@
import org.jrdf.vocabulary.RDF;
import org.mulgara.krule.rlog.ParseException;
+import org.mulgara.krule.rlog.ast.CheckRule;
import org.mulgara.krule.rlog.ast.Predicate;
import org.mulgara.krule.rlog.ast.Rule;
import org.mulgara.krule.rlog.parser.URIParseException;
@@ -34,24 +35,28 @@
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
-import static org.mulgara.krule.KruleLoader.ARGUMENT;
-import static org.mulgara.krule.KruleLoader.CONSTRAINT_CONJUNCTION;
-import static org.mulgara.krule.KruleLoader.DIFFERENCE;
-import static org.mulgara.krule.KruleLoader.HAS_QUERY;
-import static org.mulgara.krule.KruleLoader.HAS_WHERE_CLAUSE;
-import static org.mulgara.krule.KruleLoader.HAS_SUBJECT;
-import static org.mulgara.krule.KruleLoader.HAS_PREDICATE;
-import static org.mulgara.krule.KruleLoader.HAS_OBJECT;
-import static org.mulgara.krule.KruleLoader.HAS_GRAPH;
-import static org.mulgara.krule.KruleLoader.NAME;
-import static org.mulgara.krule.KruleLoader.QUERY;
-import static org.mulgara.krule.KruleLoader.RULE;
-import static org.mulgara.krule.KruleLoader.SELECTION_VARS;
-import static org.mulgara.krule.KruleLoader.SIMPLE_CONSTRAINT;
-import static org.mulgara.krule.KruleLoader.TRIGGERS;
-import static org.mulgara.krule.KruleLoader.VARIABLE;
+import static org.mulgara.query.rdf.Krule.ARGUMENT;
+import static org.mulgara.query.rdf.Krule.CHECK;
+import static org.mulgara.query.rdf.Krule.CONSTRAINT_CONJUNCTION;
+import static org.mulgara.query.rdf.Krule.DIFFERENCE;
+import static org.mulgara.query.rdf.Krule.HAS_QUERY;
+import static org.mulgara.query.rdf.Krule.HAS_WHERE_CLAUSE;
+import static org.mulgara.query.rdf.Krule.HAS_SUBJECT;
+import static org.mulgara.query.rdf.Krule.HAS_PREDICATE;
+import static org.mulgara.query.rdf.Krule.HAS_OBJECT;
+import static org.mulgara.query.rdf.Krule.HAS_GRAPH;
+import static org.mulgara.query.rdf.Krule.MINUEND;
+import static org.mulgara.query.rdf.Krule.NAME;
+import static org.mulgara.query.rdf.Krule.QUERY;
+import static org.mulgara.query.rdf.Krule.RULE;
+import static org.mulgara.query.rdf.Krule.SELECTION_VARS;
+import static org.mulgara.query.rdf.Krule.SIMPLE_CONSTRAINT;
+import static org.mulgara.query.rdf.Krule.SUBTRAHEND;
+import static org.mulgara.query.rdf.Krule.TRIGGERS;
+import static org.mulgara.query.rdf.Krule.VARIABLE;
/**
* Writes rules to a list of triples.
@@ -71,6 +76,9 @@
/** The node for the krule:Rule type */
private final long kruleRule;
+ /** The node for the krule:Check type */
+ private final long kruleCheck;
+
/** The node for the krule:Query type */
private final long kruleQuery;
@@ -113,6 +121,12 @@
/** The node for the krule:argument predicate */
private final long kruleArgument;
+ /** The node for the krule:minuend predicate */
+ private final long kruleMinuend;
+
+ /** The node for the krule:subtrahend predicate */
+ private final long kruleSubtrahend;
+
/** The node for the krule:name predicate */
private final long kruleName;
@@ -129,6 +143,7 @@
this.rules = rules;
rdfSeq = resolverSession.localize(new URIReferenceImpl(RDF.SEQ));
kruleRule = resolverSession.localize(RULE);
+ kruleCheck = resolverSession.localize(CHECK);
kruleQuery = resolverSession.localize(QUERY);
kruleDifference = resolverSession.localize(DIFFERENCE);
kruleConjunction = resolverSession.localize(CONSTRAINT_CONJUNCTION);
@@ -143,6 +158,8 @@
kruleSelVars = resolverSession.localize(SELECTION_VARS);
kruleHasWhereClause = resolverSession.localize(HAS_WHERE_CLAUSE);
kruleArgument = resolverSession.localize(ARGUMENT);
+ kruleMinuend = resolverSession.localize(MINUEND);
+ kruleSubtrahend = resolverSession.localize(SUBTRAHEND);
kruleName = resolverSession.localize(NAME);
initSeqTo(3);
}
@@ -180,18 +197,24 @@
private List<long[]> emitRule(List<long[]> triples, Rule rule) throws NodePoolException, ParseException, LocalizeException, URISyntaxException, URIParseException {
long ruleNode = toKruleNode(rule.getName());
- // rule rdf:type kruleRule
- add(triples, ruleNode, rdfType, kruleRule);
+ if (rule instanceof CheckRule) {
+ // rule rdf:type kruleCheck
+ add(triples, ruleNode, rdfType, (rule instanceof CheckRule) ? kruleCheck : kruleRule);
+ } else {
+ // rule rdf:type kruleRule
+ add(triples, ruleNode, rdfType, kruleRule);
+ emitTriggers(triples, ruleNode, rule.getTriggers());
+ }
- emitTriggers(triples, ruleNode, rule.getTriggers());
-
// query rdf:type krule:Query
// rule krule:hasQuery query
long query = newBlankNode();
add(triples, query, rdfType, kruleQuery);
add(triples, ruleNode, kruleHasQuery, query);
- emitSelection(triples, query, rule.getHead());
+ if (rule instanceof CheckRule) emitSelection(triples, query, rule.getVariables());
+ else emitSelection(triples, query, rule.getHead());
+
emitWhereClause(triples, query, rule.getBody(), rule.getBodySubtractions());
return triples;
@@ -218,18 +241,47 @@
* @throws URISyntaxException If a selected URI is incorrectly formed.
*/
private void emitSelection(List<long[]> triples, long query, Predicate selection) throws URIParseException, LocalizeException, URISyntaxException {
+ emitSelection(triples, query, Collections.singletonList(selection));
+ }
+
+
+ /**
+ * Adds the head of a rule to the triples.
+ * @param triples The list of triples to append to.
+ * @param selection The list of predicates that makes up the head of a rule.
+ * @throws LocalizeException Unable to create a new blank node.
+ * @throws URISyntaxException If a selected URI is incorrectly formed.
+ */
+ private void emitSelection(List<long[]> triples, long query, List<Predicate> selection) throws URIParseException, LocalizeException, URISyntaxException {
+ List<RDFNode> sel = new ArrayList<RDFNode>();
+ for (Predicate p: selection) {
+ sel.add(p.getSubject());
+ sel.add(p.getPredicate());
+ sel.add(p.getObject());
+ }
+ emitSelection(triples, query, sel);
+ }
+
+
+ /**
+ * Adds the selection elements of a rule to the triples.
+ * @param triples The list of triples to append to.
+ * @param selection The selection that makes up the variables or the head of a rule.
+ * @throws LocalizeException Unable to create a new blank node.
+ * @throws URISyntaxException If a selected URI is incorrectly formed.
+ */
+ private void emitSelection(List<long[]> triples, long query, Collection<? extends RDFNode> selection) throws URIParseException, LocalizeException, URISyntaxException {
// seq rdf:type rdf:Seq
// query krule:selectionVariables seq
long seq = newBlankNode();
add(triples, seq, rdfType, rdfSeq);
add(triples, query, kruleSelVars, seq);
- // seq rdf:_1 getSubject()
- // seq rdf:_2 getPredicate()
- // seq rdf:_3 getObject()
- add(triples, seq, getSeq(1), toKruleNode(selection.getSubject().getRdfLabel()));
- add(triples, seq, getSeq(2), toKruleNode(selection.getPredicate().getRdfLabel()));
- add(triples, seq, getSeq(3), toKruleNode(selection.getObject().getRdfLabel()));
+ // seq rdf:_n selection(n) ...
+ int n = 1;
+ for (RDFNode s: selection) {
+ add(triples, seq, getSeq(n++), toKruleNode(s.getRdfLabel()));
+ }
}
@@ -262,21 +314,21 @@
* @throws URISyntaxException If one of the URIs in the constraint has an invalid syntax.
*/
private void emitSubtractions(List<long[]> triples, long diff, List<Predicate> body, List<Predicate> subs) throws URIParseException, LocalizeException, URISyntaxException {
- // constraintExpr rdf:type krule:Difference
+ // diff rdf:type krule:Difference
add(triples, diff, rdfType, kruleDifference);
long argument = newBlankNode();
- // diff krule:argument argument
- add(triples, diff, kruleArgument, argument);
+ // diff krule:minuend argument
+ add(triples, diff, kruleMinuend, argument);
int lastElt = subs.size() - 1;
if (lastElt == 0) emitConjunction(triples, argument, body);
else emitSubtractions(triples, argument, body, subs.subList(0, lastElt));
// last argument in subtraction
- // diff krule:argument argument
+ // diff krule:subtrahend argument
argument = newBlankNode();
- add(triples, diff, kruleArgument, argument);
+ add(triples, diff, kruleSubtrahend, argument);
emitSimpleConstraint(triples, argument, subs.get(lastElt));
}
Modified: trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/output/RuleWriter.java
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/output/RuleWriter.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/output/RuleWriter.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -16,12 +16,16 @@
package org.mulgara.krule.rlog.ast.output;
+import org.mulgara.krule.rlog.ast.CheckRule;
import org.mulgara.krule.rlog.ast.Predicate;
import org.mulgara.krule.rlog.ast.Rule;
import org.mulgara.krule.rlog.parser.URIParseException;
+import org.mulgara.krule.rlog.rdf.RDFNode;
import java.io.PrintStream;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
/**
@@ -58,11 +62,18 @@
* @param r The rule to print.
*/
private void emitRule(PrintStream out, Rule r) throws URIParseException {
- out.println(" <krule:Rule rdf:about=\"#" + r.getName() + "\">");
- emitTriggers(out, r.getTriggers());
+ if (r instanceof CheckRule) {
+ out.println(" <krule:ConsistencyCheck rdf:about=\"#" + r.getName() + "\">");
+ } else {
+ out.println(" <krule:Rule rdf:about=\"#" + r.getName() + "\">");
+ emitTriggers(out, r.getTriggers());
+ }
out.println(" <hasQuery>\n" +
" <Query>");
- emitSelection(out, r.getHead());
+
+ if (r instanceof CheckRule) emitSelection(out, r.getVariables());
+ else emitSelection(out, r.getHead());
+
emitWhereClause(out, r.getBody(), r.getBodySubtractions());
out.println(" </Query>\n" +
" </hasQuery>\n" +
@@ -86,15 +97,42 @@
* @param selection The selection that makes up the head of a rule.
*/
private void emitSelection(PrintStream out, Predicate selection) throws URIParseException {
+ emitSelection(out, Collections.singletonList(selection));
+ }
+
+
+ /**
+ * Prints the head for a rule to a PrintStream.
+ * @param out The PrintStream to send the selection to.
+ * @param selection The list of predicates that makes up the head of a rule.
+ */
+ private void emitSelection(PrintStream out, List<Predicate> selection) throws URIParseException {
+ List<RDFNode> sel = new ArrayList<RDFNode>();
+ for (Predicate p: selection) {
+ sel.add(p.getSubject());
+ sel.add(p.getPredicate());
+ sel.add(p.getObject());
+ }
+ emitSelection(out, sel);
+ }
+
+
+ /**
+ * Prints the selection values to a PrintStream.
+ * @param out The PrintStream to send the selection to.
+ * @param sel The elements to be selected.
+ */
+ private void emitSelection(PrintStream out, Collection<? extends RDFNode> sel) throws URIParseException {
out.println(" <selectionVariables>\n" +
- " <rdf:Seq>\n" +
- " <rdf:li rdf:resource=\"" + selection.getSubject().getRdfLabel() + "\"/>\n" +
- " <rdf:li rdf:resource=\"" + selection.getPredicate().getRdfLabel() + "\"/>\n" +
- " <rdf:li rdf:resource=\"" + selection.getObject().getRdfLabel() + "\"/>\n" +
- " </rdf:Seq>\n" +
+ " <rdf:Seq>");
+ for (RDFNode s: sel) {
+ out.println(" <rdf:li rdf:resource=\"" + s.getRdfLabel() + "\"/>");
+ }
+ out.println(" </rdf:Seq>\n" +
" </selectionVariables>");
}
+
/**
* Prints the body for a rule to a PrintStream.
* @param out The PrintStream to send the where clause to.
@@ -112,13 +150,13 @@
private void emitSubtractions(PrintStream out, List<Predicate> body, List<Predicate> subs, int indent) throws URIParseException {
int lastElt = subs.size() - 1;
out.println(sp(indent) + "<Difference>\n" +
- sp(indent + 1) + "<argument>");
+ sp(indent + 1) + "<minuend>");
if (lastElt == 0) emitConjunction(out, body, indent + 2);
else emitSubtractions(out, body, subs.subList(0, lastElt), indent + 2);
- out.println(sp(indent + 1) + "</argument>\n" +
- sp(indent + 1) + "<argument>");
+ out.println(sp(indent + 1) + "</minuend>\n" +
+ sp(indent + 1) + "<subtrahend>");
emitSimpleConstraint(out, subs.get(lastElt), indent + 2);
- out.println(sp(indent + 1) + "</argument>\n" +
+ out.println(sp(indent + 1) + "</subtrahend>\n" +
sp(indent) + "</Difference>");
}
Modified: trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/output/TripleGenerator.java
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/output/TripleGenerator.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/output/TripleGenerator.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -16,9 +16,9 @@
package org.mulgara.krule.rlog.ast.output;
-import static org.mulgara.krule.KruleLoader.KRULE;
-import static org.mulgara.krule.KruleLoader.LITERAL;
-import static org.mulgara.krule.KruleLoader.URI_REF;
+import static org.mulgara.query.rdf.Krule.KRULE;
+import static org.mulgara.query.rdf.Krule.LITERAL;
+import static org.mulgara.query.rdf.Krule.URI_REF;
import java.net.URI;
import java.net.URISyntaxException;
Modified: trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/parser/NSUtils.java
===================================================================
--- trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/parser/NSUtils.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/content-rlog/java/org/mulgara/krule/rlog/parser/NSUtils.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -18,8 +18,10 @@
import java.net.URI;
import java.net.URISyntaxException;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import java.util.Set;
import org.mulgara.krule.rlog.rdf.RDF;
@@ -130,4 +132,13 @@
public static String getRegisteredNamespace(String domain) {
return registeredDomains.get(domain);
}
+
+
+ /**
+ * Returns a list of entries in the registered domains.
+ * @return A Set of Map.Entries which map domain abbreviations to full namespaces.
+ */
+ public static Set<Map.Entry<String,String>> getRegisteredDomains() {
+ return Collections.unmodifiableSet(registeredDomains.entrySet());
+ }
}
Modified: trunk/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParser.java
===================================================================
--- trunk/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParser.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParser.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -3,13 +3,12 @@
import java.io.StringReader;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import org.mulgara.krule.rlog.ast.Axiom;
import org.mulgara.krule.rlog.ast.BPredicate;
import org.mulgara.krule.rlog.ast.BPredicateLiteral;
+import org.mulgara.krule.rlog.ast.CheckRule;
import org.mulgara.krule.rlog.ast.IntegerLiteral;
import org.mulgara.krule.rlog.ast.InvertedPredicate;
import org.mulgara.krule.rlog.ast.Predicate;
@@ -27,18 +26,30 @@
/** This context holds parse-specific domain mappings. */
private ParseContext context = new ParseContext();
+ /** The program being built by the parser. */
+ private Program program = null;
+
/**
* Parse an entire document into statements.
- * @param query The document as a string.
+ * @param doc The document as a string.
* @return A list of Statements parsed from the document.
* @throws ParseException Due to a syntactical or grammatical error in the query document.
*/
- public static List<Statement> parse(String query) throws ParseException {
- RlogParser parser = new RlogParser(new StringReader(query));
- return parser.statements();
+ public static Program parse(String doc) throws ParseException {
+ RlogParser parser = new RlogParser(new StringReader(doc));
+ return parser.program();
}
/**
+ * Retrieves the program that has been built up by this parser.
+ * @return The program built by this parser.
+ */
+ public Program getProgram() throws ParseException {
+ if (program == null) program = program();
+ return program;
+ }
+
+ /**
* Remove quotation marks from the front and back of a string.
* @param str The string to unquote.
* @return A string containing everything from <var>str</var> between the outermost quotes.
@@ -48,15 +59,16 @@
}
/* statements ::= (statement)+ */
- final public List<Statement> statements() throws ParseException {
- List<Statement> sList = new ArrayList<Statement>();
+ final public Program program() throws ParseException {
Statement s;
+ if (program == null) program = new Program();
label_1:
while (true) {
s = statement();
- if (s != null) sList.add(s);
+ if (s != null) program.add(s);
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case PREFIX:
+ case IMPORT:
case IMPLIED_BY:
case INVERT:
case IDENTIFIER:
@@ -70,7 +82,7 @@
break label_1;
}
}
- {if (true) return sList;}
+ {if (true) return program;}
throw new Error("Missing return statement in function");
}
@@ -79,6 +91,10 @@
String d, ns;
Statement s;
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case IMPORT:
+ importDecl();
+ {if (true) return null;}
+ break;
case PREFIX:
prefix();
{if (true) return null;}
@@ -135,7 +151,7 @@
jj_consume_token(IMPLIED_BY);
body = predicateList();
jj_consume_token(DOT);
- {if (true) return new Rule(body, context);}
+ {if (true) return new CheckRule(body, context);}
break;
case INVERT:
case IDENTIFIER:
@@ -385,6 +401,15 @@
context.registerDomain(d, ns);
}
+/* importDecl := IMPORT uri DOT */
+ final public void importDecl() throws ParseException {
+ String u;
+ jj_consume_token(IMPORT);
+ u = uri();
+ jj_consume_token(DOT);
+ program.addImport(u);
+ }
+
/* dom ::= DOMAIN */
final public String dom() throws ParseException {
Token d;
@@ -422,67 +447,6 @@
finally { jj_save(2, xla); }
}
- final private boolean jj_3R_17() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_20()) jj_scanpos = xsp;
- if (jj_scan_token(IDENTIFIER)) return true;
- if (jj_scan_token(LPAR)) return true;
- if (jj_3R_13()) return true;
- if (jj_scan_token(COMMA)) return true;
- if (jj_3R_21()) return true;
- if (jj_scan_token(RPAR)) return true;
- return false;
- }
-
- final private boolean jj_3_1() {
- if (jj_3R_3()) return true;
- return false;
- }
-
- final private boolean jj_3R_14() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_17()) {
- jj_scanpos = xsp;
- if (jj_3R_18()) return true;
- }
- return false;
- }
-
- final private boolean jj_3R_8() {
- if (jj_scan_token(VARIABLE)) return true;
- if (jj_scan_token(LPAR)) return true;
- if (jj_3R_13()) return true;
- if (jj_scan_token(RPAR)) return true;
- return false;
- }
-
- final private boolean jj_3R_26() {
- if (jj_scan_token(STRING_LITERAL)) return true;
- return false;
- }
-
- final private boolean jj_3R_25() {
- if (jj_scan_token(INTEGER_LITERAL)) return true;
- return false;
- }
-
- final private boolean jj_3R_24() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_25()) {
- jj_scanpos = xsp;
- if (jj_3R_26()) return true;
- }
- return false;
- }
-
- final private boolean jj_3R_12() {
- if (jj_3R_9()) return true;
- return false;
- }
-
final private boolean jj_3R_7() {
Token xsp;
xsp = jj_scanpos;
@@ -535,6 +499,11 @@
return false;
}
+ final private boolean jj_3R_9() {
+ if (jj_scan_token(DOMAIN)) return true;
+ return false;
+ }
+
final private boolean jj_3R_6() {
Token xsp;
xsp = jj_scanpos;
@@ -576,11 +545,6 @@
return false;
}
- final private boolean jj_3R_9() {
- if (jj_scan_token(DOMAIN)) return true;
- return false;
- }
-
final private boolean jj_3_3() {
Token xsp;
xsp = jj_scanpos;
@@ -623,6 +587,67 @@
return false;
}
+ final private boolean jj_3R_17() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_20()) jj_scanpos = xsp;
+ if (jj_scan_token(IDENTIFIER)) return true;
+ if (jj_scan_token(LPAR)) return true;
+ if (jj_3R_13()) return true;
+ if (jj_scan_token(COMMA)) return true;
+ if (jj_3R_21()) return true;
+ if (jj_scan_token(RPAR)) return true;
+ return false;
+ }
+
+ final private boolean jj_3_1() {
+ if (jj_3R_3()) return true;
+ return false;
+ }
+
+ final private boolean jj_3R_14() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_17()) {
+ jj_scanpos = xsp;
+ if (jj_3R_18()) return true;
+ }
+ return false;
+ }
+
+ final private boolean jj_3R_8() {
+ if (jj_scan_token(VARIABLE)) return true;
+ if (jj_scan_token(LPAR)) return true;
+ if (jj_3R_13()) return true;
+ if (jj_scan_token(RPAR)) return true;
+ return false;
+ }
+
+ final private boolean jj_3R_26() {
+ if (jj_scan_token(STRING_LITERAL)) return true;
+ return false;
+ }
+
+ final private boolean jj_3R_25() {
+ if (jj_scan_token(INTEGER_LITERAL)) return true;
+ return false;
+ }
+
+ final private boolean jj_3R_24() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_25()) {
+ jj_scanpos = xsp;
+ if (jj_3R_26()) return true;
+ }
+ return false;
+ }
+
+ final private boolean jj_3R_12() {
+ if (jj_3R_9()) return true;
+ return false;
+ }
+
public RlogParserTokenManager token_source;
SimpleCharStream jj_input_stream;
public Token token, jj_nt;
@@ -638,7 +663,7 @@
jj_la1_0();
}
private static void jj_la1_0() {
- jj_la1_0 = new int[] {0x5c06100,0x5c06000,0x5c06100,0x5c06000,0x4c04000,0x4000000,0x5800000,0x4000000,0x4c00000,0x4000000,0x4000000,0x5800000,0x7d00000,0x2100000,0x20000,};
+ jj_la1_0 = new int[] {0xb80c300,0xb80c000,0xb80c300,0xb80c000,0x9808000,0x8000000,0xb000000,0x8000000,0x9800000,0x8000000,0x8000000,0xb000000,0xfa00000,0x4200000,0x40000,};
}
final private JJCalls[] jj_2_rtns = new JJCalls[3];
private boolean jj_rescan = false;
@@ -815,8 +840,8 @@
public ParseException generateParseException() {
jj_expentries.removeAllElements();
- boolean[] la1tokens = new boolean[27];
- for (int i = 0; i < 27; i++) {
+ boolean[] la1tokens = new boolean[28];
+ for (int i = 0; i < 28; i++) {
la1tokens[i] = false;
}
if (jj_kind >= 0) {
@@ -832,7 +857,7 @@
}
}
}
- for (int i = 0; i < 27; i++) {
+ for (int i = 0; i < 28; i++) {
if (la1tokens[i]) {
jj_expentry = new int[1];
jj_expentry[0] = i;
Modified: trunk/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParser.jj
===================================================================
--- trunk/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParser.jj 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParser.jj 2009-03-24 18:42:49 UTC (rev 1626)
@@ -13,13 +13,12 @@
import java.io.StringReader;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import org.mulgara.krule.rlog.ast.Axiom;
import org.mulgara.krule.rlog.ast.BPredicate;
import org.mulgara.krule.rlog.ast.BPredicateLiteral;
+import org.mulgara.krule.rlog.ast.CheckRule;
import org.mulgara.krule.rlog.ast.IntegerLiteral;
import org.mulgara.krule.rlog.ast.InvertedPredicate;
import org.mulgara.krule.rlog.ast.Predicate;
@@ -37,18 +36,30 @@
/** This context holds parse-specific domain mappings. */
private ParseContext context = new ParseContext();
+ /** The program being built by the parser. */
+ private Program program = null;
+
/**
* Parse an entire document into statements.
- * @param query The document as a string.
+ * @param doc The document as a string.
* @return A list of Statements parsed from the document.
* @throws ParseException Due to a syntactical or grammatical error in the query document.
*/
- public static List<Statement> parse(String query) throws ParseException {
- RlogParser parser = new RlogParser(new StringReader(query));
- return parser.statements();
+ public static Program parse(String doc) throws ParseException {
+ RlogParser parser = new RlogParser(new StringReader(doc));
+ return parser.program();
}
/**
+ * Retrieves the program that has been built up by this parser.
+ * @return The program built by this parser.
+ */
+ public Program getProgram() throws ParseException {
+ if (program == null) program = program();
+ return program;
+ }
+
+ /**
* Remove quotation marks from the front and back of a string.
* @param str The string to unquote.
* @return A string containing everything from <var>str</var> between the outermost quotes.
@@ -67,9 +78,10 @@
<IN_COMMENT>
SPECIAL_TOKEN : { < COMMENT: (~["\r","\n"])* > : DEFAULT }
-TOKEN [IGNORE_CASE] :
+TOKEN :
{
< PREFIX : "@prefix" >
+ | < IMPORT : "@import" >
}
TOKEN :
@@ -118,11 +130,11 @@
/* statements ::= (statement)+ */
-List<Statement> statements() : {
- List<Statement> sList = new ArrayList<Statement>();
+Program program() : {
Statement s;
+ if (program == null) program = new Program();
} {
- (s=statement() { if (s != null) sList.add(s); } )+ { return sList; }
+ (s=statement() { if (s != null) program.add(s); } )+ { return program; }
}
@@ -131,7 +143,8 @@
String d, ns;
Statement s;
} {
- prefix() { return null; }
+ importDecl() { return null; }
+| prefix() { return null; }
| ( LOOKAHEAD(10) s=axiom() | s=rule() ) { return s; }
}
@@ -148,7 +161,7 @@
List<Predicate> body;
Predicate head;
} {
- <IMPLIED_BY> body=predicateList() <DOT> { return new Rule(body, context); }
+ <IMPLIED_BY> body=predicateList() <DOT> { return new CheckRule(body, context); }
| head=predicate() <IMPLIED_BY> body=predicateList() <DOT> { return new Rule(head, body, context); }
}
@@ -240,6 +253,14 @@
}
+/* importDecl := IMPORT uri DOT */
+void importDecl() : {
+ String u;
+} {
+ <IMPORT> u=uri() <DOT> { program.addImport(u); }
+}
+
+
/* dom ::= DOMAIN */
String dom() : {
Token d;
Modified: trunk/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParserConstants.java
===================================================================
--- trunk/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParserConstants.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParserConstants.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -6,24 +6,25 @@
int EOF = 0;
int COMMENT = 7;
int PREFIX = 8;
- int LOWER_CASE_LETTER = 9;
- int UPPER_CASE_LETTER = 10;
- int DIGIT = 11;
- int J_LETTER_DIGIT = 12;
- int IMPLIED_BY = 13;
- int INVERT = 14;
- int NEGATE = 15;
- int DOT = 16;
- int COMMA = 17;
- int LPAR = 18;
- int RPAR = 19;
- int STRING_LITERAL = 20;
- int URI = 21;
- int IDENTIFIER = 22;
- int VARIABLE = 23;
- int TYPE = 24;
- int INTEGER_LITERAL = 25;
- int DOMAIN = 26;
+ int IMPORT = 9;
+ int LOWER_CASE_LETTER = 10;
+ int UPPER_CASE_LETTER = 11;
+ int DIGIT = 12;
+ int J_LETTER_DIGIT = 13;
+ int IMPLIED_BY = 14;
+ int INVERT = 15;
+ int NEGATE = 16;
+ int DOT = 17;
+ int COMMA = 18;
+ int LPAR = 19;
+ int RPAR = 20;
+ int STRING_LITERAL = 21;
+ int URI = 22;
+ int IDENTIFIER = 23;
+ int VARIABLE = 24;
+ int TYPE = 25;
+ int INTEGER_LITERAL = 26;
+ int DOMAIN = 27;
int DEFAULT = 0;
int IN_COMMENT = 1;
@@ -38,6 +39,7 @@
"\"--\"",
"<COMMENT>",
"\"@prefix\"",
+ "\"@import\"",
"<LOWER_CASE_LETTER>",
"<UPPER_CASE_LETTER>",
"<DIGIT>",
Modified: trunk/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParserTokenManager.java
===================================================================
--- trunk/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParserTokenManager.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParserTokenManager.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -2,12 +2,11 @@
package org.mulgara.krule.rlog;
import java.io.StringReader;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import org.mulgara.krule.rlog.ast.Axiom;
import org.mulgara.krule.rlog.ast.BPredicate;
import org.mulgara.krule.rlog.ast.BPredicateLiteral;
+import org.mulgara.krule.rlog.ast.CheckRule;
import org.mulgara.krule.rlog.ast.IntegerLiteral;
import org.mulgara.krule.rlog.ast.InvertedPredicate;
import org.mulgara.krule.rlog.ast.Predicate;
@@ -24,53 +23,71 @@
{
public java.io.PrintStream debugStream = System.out;
public void setDebugStream(java.io.PrintStream ds) { debugStream = ds; }
+private final int jjStopStringLiteralDfa_0(int pos, long active0)
+{
+ switch (pos)
+ {
+ case 0:
+ if ((active0 & 0x4000L) != 0L)
+ {
+ jjmatchedKind = 27;
+ return -1;
+ }
+ return -1;
+ case 1:
+ if ((active0 & 0x4000L) != 0L)
+ {
+ if (jjmatchedPos == 0)
+ {
+ jjmatchedKind = 27;
+ jjmatchedPos = 0;
+ }
+ return -1;
+ }
+ return -1;
+ default :
+ return -1;
+ }
+}
+private final int jjStartNfa_0(int pos, long active0)
+{
+ return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0), pos + 1);
+}
private final int jjStopAtPos(int pos, int kind)
{
jjmatchedKind = kind;
jjmatchedPos = pos;
return pos + 1;
}
+private final int jjStartNfaWithStates_0(int pos, int kind, int state)
+{
+ jjmatchedKind = kind;
+ jjmatchedPos = pos;
+ try { curChar = input_stream.readChar(); }
+ catch(java.io.IOException e) { return pos + 1; }
+ return jjMoveNfa_0(state, pos + 1);
+}
private final int jjMoveStringLiteralDfa0_0()
{
switch(curChar)
{
- case 9:
- jjmatchedKind = 1;
- return jjMoveNfa_0(0, 0);
- case 10:
- jjmatchedKind = 2;
- return jjMoveNfa_0(0, 0);
- case 12:
- jjmatchedKind = 4;
- return jjMoveNfa_0(0, 0);
- case 13:
- jjmatchedKind = 3;
- return jjMoveNfa_0(0, 0);
- case 32:
- jjmatchedKind = 5;
- return jjMoveNfa_0(0, 0);
case 40:
- jjmatchedKind = 18;
- return jjMoveNfa_0(0, 0);
+ return jjStopAtPos(0, 19);
case 41:
- jjmatchedKind = 19;
- return jjMoveNfa_0(0, 0);
+ return jjStopAtPos(0, 20);
case 44:
- jjmatchedKind = 17;
- return jjMoveNfa_0(0, 0);
+ return jjStopAtPos(0, 18);
case 45:
- jjmatchedKind = 15;
+ jjmatchedKind = 16;
return jjMoveStringLiteralDfa1_0(0x40L);
case 46:
- jjmatchedKind = 16;
- return jjMoveNfa_0(0, 0);
+ return jjStopAtPos(0, 17);
case 58:
- return jjMoveStringLiteralDfa1_0(0x2000L);
+ return jjMoveStringLiteralDfa1_0(0x4000L);
case 64:
- return jjMoveStringLiteralDfa1_0(0x100L);
+ return jjMoveStringLiteralDfa1_0(0x300L);
case 126:
- jjmatchedKind = 14;
- return jjMoveNfa_0(0, 0);
+ return jjStopAtPos(0, 15);
default :
return jjMoveNfa_0(0, 0);
}
@@ -79,135 +96,129 @@
{
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) {
- return jjMoveNfa_0(0, 0);
+ jjStopStringLiteralDfa_0(0, active0);
+ return 1;
}
switch(curChar)
{
case 45:
if ((active0 & 0x40L) != 0L)
- {
- jjmatchedKind = 6;
- jjmatchedPos = 1;
- }
- else if ((active0 & 0x2000L) != 0L)
- {
- jjmatchedKind = 13;
- jjmatchedPos = 1;
- }
+ return jjStopAtPos(1, 6);
+ else if ((active0 & 0x4000L) != 0L)
+ return jjStopAtPos(1, 14);
break;
- case 80:
- return jjMoveStringLiteralDfa2_0(active0, 0x100L);
+ case 105:
+ return jjMoveStringLiteralDfa2_0(active0, 0x200L);
case 112:
return jjMoveStringLiteralDfa2_0(active0, 0x100L);
default :
break;
}
- return jjMoveNfa_0(0, 1);
+ return jjStartNfa_0(0, active0);
}
private final int jjMoveStringLiteralDfa2_0(long old0, long active0)
{
if (((active0 &= old0)) == 0L)
- return jjMoveNfa_0(0, 1);
+ return jjStartNfa_0(0, old0);
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) {
- return jjMoveNfa_0(0, 1);
+ jjStopStringLiteralDfa_0(1, active0);
+ return 2;
}
switch(curChar)
{
- case 82:
- return jjMoveStringLiteralDfa3_0(active0, 0x100L);
+ case 109:
+ return jjMoveStringLiteralDfa3_0(active0, 0x200L);
case 114:
return jjMoveStringLiteralDfa3_0(active0, 0x100L);
default :
break;
}
- return jjMoveNfa_0(0, 2);
+ return jjStartNfa_0(1, active0);
}
private final int jjMoveStringLiteralDfa3_0(long old0, long active0)
{
if (((active0 &= old0)) == 0L)
- return jjMoveNfa_0(0, 2);
+ return jjStartNfa_0(1, old0);
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) {
- return jjMoveNfa_0(0, 2);
+ jjStopStringLiteralDfa_0(2, active0);
+ return 3;
}
switch(curChar)
{
- case 69:
- return jjMoveStringLiteralDfa4_0(active0, 0x100L);
case 101:
return jjMoveStringLiteralDfa4_0(active0, 0x100L);
+ case 112:
+ return jjMoveStringLiteralDfa4_0(active0, 0x200L);
default :
break;
}
- return jjMoveNfa_0(0, 3);
+ return jjStartNfa_0(2, active0);
}
private final int jjMoveStringLiteralDfa4_0(long old0, long active0)
{
if (((active0 &= old0)) == 0L)
- return jjMoveNfa_0(0, 3);
+ return jjStartNfa_0(2, old0);
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) {
- return jjMoveNfa_0(0, 3);
+ jjStopStringLiteralDfa_0(3, active0);
+ return 4;
}
switch(curChar)
{
- case 70:
- return jjMoveStringLiteralDfa5_0(active0, 0x100L);
case 102:
return jjMoveStringLiteralDfa5_0(active0, 0x100L);
+ case 111:
+ return jjMoveStringLiteralDfa5_0(active0, 0x200L);
default :
break;
}
- return jjMoveNfa_0(0, 4);
+ return jjStartNfa_0(3, active0);
}
private final int jjMoveStringLiteralDfa5_0(long old0, long active0)
{
if (((active0 &= old0)) == 0L)
- return jjMoveNfa_0(0, 4);
+ return jjStartNfa_0(3, old0);
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) {
- return jjMoveNfa_0(0, 4);
+ jjStopStringLiteralDfa_0(4, active0);
+ return 5;
}
switch(curChar)
{
- case 73:
- return jjMoveStringLiteralDfa6_0(active0, 0x100L);
case 105:
return jjMoveStringLiteralDfa6_0(active0, 0x100L);
+ case 114:
+ return jjMoveStringLiteralDfa6_0(active0, 0x200L);
default :
break;
}
- return jjMoveNfa_0(0, 5);
+ return jjStartNfa_0(4, active0);
}
private final int jjMoveStringLiteralDfa6_0(long old0, long active0)
{
if (((active0 &= old0)) == 0L)
- return jjMoveNfa_0(0, 5);
+ return jjStartNfa_0(4, old0);
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) {
- return jjMoveNfa_0(0, 5);
+ jjStopStringLiteralDfa_0(5, active0);
+ return 6;
}
switch(curChar)
{
- case 88:
- if ((active0 & 0x100L) != 0L)
- {
- jjmatchedKind = 8;
- jjmatchedPos = 6;
- }
+ case 116:
+ if ((active0 & 0x200L) != 0L)
+ return jjStopAtPos(6, 9);
break;
case 120:
if ((active0 & 0x100L) != 0L)
- {
- jjmatchedKind = 8;
- jjmatchedPos = 6;
- }
+ return jjStopAtPos(6, 8);
break;
default :
break;
}
- return jjMoveNfa_0(0, 6);
+ return jjStartNfa_0(5, active0);
}
private final void jjCheckNAdd(int state)
{
@@ -247,13 +258,6 @@
};
private final int jjMoveNfa_0(int startState, int curPos)
{
- int strKind = jjmatchedKind;
- int strPos = jjmatchedPos;
- int seenUpto;
- input_stream.backup(seenUpto = curPos + 1);
- try { curChar = input_stream.readChar(); }
- catch(java.io.IOException e) { throw new Error("Internal Error"); }
- curPos = 0;
int[] nextStates;
int startsAt = 0;
jjnewStateCnt = 21;
@@ -274,19 +278,19 @@
case 0:
if ((0x3fe000000000000L & l) != 0L)
{
- if (kind > 25)
- kind = 25;
+ if (kind > 26)
+ kind = 26;
jjCheckNAdd(14);
}
else if (curChar == 58)
{
- if (kind > 26)
- kind = 26;
+ if (kind > 27)
+ kind = 27;
}
else if (curChar == 48)
{
- if (kind > 25)
- kind = 25;
+ if (kind > 26)
+ kind = 26;
}
else if (curChar == 60)
jjCheckNAddTwoStates(10, 11);
@@ -302,8 +306,8 @@
jjCheckNAddStates(0, 2);
break;
case 4:
- if (curChar == 34 && kind > 20)
- kind = 20;
+ if (curChar == 34 && kind > 21)
+ kind = 21;
break;
case 5:
if ((0xff000000000000L & l) != 0L)
@@ -330,43 +334,43 @@
jjCheckNAddTwoStates(10, 11);
break;
case 11:
- if (curChar == 62 && kind > 21)
- kind = 21;
+ if (curChar == 62 && kind > 22)
+ kind = 22;
break;
case 12:
- if (curChar == 48 && kind > 25)
- kind = 25;
+ if (curChar == 48 && kind > 26)
+ kind = 26;
break;
case 13:
if ((0x3fe000000000000L & l) == 0L)
break;
- if (kind > 25)
- kind = 25;
+ if (kind > 26)
+ kind = 26;
jjCheckNAdd(14);
break;
case 14:
if ((0x3ff000000000000L & l) == 0L)
break;
- if (kind > 25)
- kind = 25;
+ if (kind > 26)
+ kind = 26;
jjCheckNAdd(14);
break;
case 15:
- if (curChar == 58 && kind > 26)
- kind = 26;
+ if (curChar == 58 && kind > 27)
+ kind = 27;
break;
case 17:
if ((0x3ff000000000000L & l) == 0L)
break;
- if (kind > 22)
- kind = 22;
+ if (kind > 23)
+ kind = 23;
jjstateSet[jjnewStateCnt++] = 17;
break;
case 20:
if ((0x3ff000000000000L & l) == 0L)
break;
- if (kind > 24)
- kind = 24;
+ if (kind > 25)
+ kind = 25;
jjstateSet[jjnewStateCnt++] = 20;
break;
default : break;
@@ -383,14 +387,14 @@
case 0:
if ((0x7fffffeL & l) != 0L)
{
- if (kind > 23)
- kind = 23;
+ if (kind > 24)
+ kind = 24;
jjCheckNAdd(20);
}
else if ((0x7fffffe00000000L & l) != 0L)
{
- if (kind > 22)
- kind = 22;
+ if (kind > 23)
+ kind = 23;
jjCheckNAddStates(7, 9);
}
break;
@@ -412,15 +416,15 @@
case 16:
if ((0x7fffffe00000000L & l) == 0L)
break;
- if (kind > 22)
- kind = 22;
+ if (kind > 23)
+ kind = 23;
jjCheckNAddStates(7, 9);
break;
case 17:
if ((0x7fffffe87fffffeL & l) == 0L)
break;
- if (kind > 22)
- kind = 22;
+ if (kind > 23)
+ kind = 23;
jjCheckNAdd(17);
break;
case 18:
@@ -430,15 +434,15 @@
case 19:
if ((0x7fffffeL & l) == 0L)
break;
- if (kind > 23)
- kind = 23;
+ if (kind > 24)
+ kind = 24;
jjCheckNAdd(20);
break;
case 20:
if ((0x7fffffe87fffffeL & l) == 0L)
break;
- if (kind > 24)
- kind = 24;
+ if (kind > 25)
+ kind = 25;
jjCheckNAdd(20);
break;
default : break;
@@ -476,29 +480,10 @@
}
++curPos;
if ((i = jjnewStateCnt) == (startsAt = 21 - (jjnewStateCnt = startsAt)))
- break;
+ return curPos;
try { curChar = input_stream.readChar(); }
- catch(java.io.IOException e) { break; }
+ catch(java.io.IOException e) { return curPos; }
}
- if (jjmatchedPos > strPos)
- return curPos;
-
- int toRet = Math.max(curPos, seenUpto);
-
- if (curPos < toRet)
- for (i = toRet - Math.min(curPos, seenUpto); i-- > 0; )
- try { curChar = input_stream.readChar(); }
- catch(java.io.IOException e) { throw new Error("Internal Error : Please send a bug report."); }
-
- if (jjmatchedPos < strPos)
- {
- jjmatchedKind = strKind;
- jjmatchedPos = strPos;
- }
- else if (jjmatchedPos == strPos && jjmatchedKind > strKind)
- jjmatchedKind = strKind;
-
- return toRet;
}
private final int jjMoveStringLiteralDfa0_1()
{
@@ -599,19 +584,19 @@
}
}
public static final String[] jjstrLiteralImages = {
-"", null, null, null, null, null, null, null, null, null, null, null, null,
-"\72\55", "\176", "\55", "\56", "\54", "\50", "\51", null, null, null, null, null, null,
-null, };
+"", null, null, null, null, null, null, null, "\100\160\162\145\146\151\170",
+"\100\151\155\160\157\162\164", null, null, null, null, "\72\55", "\176", "\55", "\56", "\54", "\50", "\51",
+null, null, null, null, null, null, null, };
public static final String[] lexStateNames = {
"DEFAULT",
"IN_COMMENT",
};
public static final int[] jjnewLexState = {
-1, -1, -1, -1, -1, -1, 1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1,
+ -1, -1, -1,
};
static final long[] jjtoToken = {
- 0x7ffe101L,
+ 0xfffc301L,
};
static final long[] jjtoSkip = {
0xbeL,
@@ -726,6 +711,11 @@
switch(curLexState)
{
case 0:
+ try { input_stream.backup(0);
+ while (curChar <= 32 && (0x100003600L & (1L << curChar)) != 0L)
+ curChar = input_stream.BeginToken();
+ }
+ catch (java.io.IOException e1) { continue EOFLoop; }
jjmatchedKind = 0x7fffffff;
jjmatchedPos = 0;
curPos = jjMoveStringLiteralDfa0_0();
Copied: trunk/src/jar/krule/java/org/mulgara/krule/ConsistencyCheck.java (from rev 1625, branches/consistency/src/jar/krule/java/org/mulgara/krule/ConsistencyCheck.java)
===================================================================
--- trunk/src/jar/krule/java/org/mulgara/krule/ConsistencyCheck.java (rev 0)
+++ trunk/src/jar/krule/java/org/mulgara/krule/ConsistencyCheck.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -0,0 +1,139 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.krule;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+import org.mulgara.query.Answer;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.TuplesException;
+import org.mulgara.query.Variable;
+import org.mulgara.resolver.OperationContext;
+import org.mulgara.resolver.spi.Resolver;
+import org.mulgara.resolver.spi.ResolverException;
+import org.mulgara.resolver.spi.SystemResolver;
+
+/**
+ * A rule that generates no data, but instead checks that the data is consistent.
+ *
+ * @created Mar 18, 2009
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class ConsistencyCheck extends Rule {
+
+ /** Serialization ID */
+ private static final long serialVersionUID = 5514372363770138432L;
+
+ /** Logger. */
+ private static Logger logger = Logger.getLogger(ConsistencyCheck.class.getName());
+
+
+ /**
+ * Creates the consistency test as a rule.
+ * @param name The name of this rule.
+ */
+ public ConsistencyCheck(String name) {
+ super(name);
+ }
+
+
+ /**
+ * Adds a target for triggering. These are not legal for consistency checks.
+ * @param target The rule to be triggered when this rule is executed.
+ */
+ public void addTriggerTarget(Rule target) {
+ throw new IllegalStateException("Consistency checks cannot trigger other rules.");
+ }
+
+
+ /**
+ * Retrieves the list of subordinate rules.
+ * @return an immutable set of the subordinate rules.
+ */
+ public Set<Rule> getTriggerTargets() {
+ return Collections.emptySet();
+ }
+
+
+ /**
+ * Sets the query for this rule.
+ * @param queryStruct The query which retrieves data for this rule.
+ */
+ public void setQueryStruct(QueryStruct queryStruct) throws KruleStructureException {
+ this.query = queryStruct.extractQuery();
+ }
+
+
+ /**
+ * Runs this test.
+ * TODO: count the size of each individual constraint
+ *
+ * @param context The context to query against.
+ * @param resolver The resolver to add data with.
+ * @param sysResolver The resolver to localize data with.
+ */
+ public void execute(OperationContext context, Resolver resolver, SystemResolver sysResolver) throws QueryException, TuplesException, ResolverException {
+ // Tests the output of this rule
+ Answer answer = null;
+ logger.debug("Running consistency check: " + name);
+ try {
+ answer = context.doQuery(query);
+ } catch (Exception e) {
+ throw new QueryException("Unable to access data in rule.", e);
+ }
+ try {
+ // compare the size of the result data
+ long c = answer.getRowCount();
+ if (0 != c) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Failed consistency check: " + name);
+ logOutput(answer);
+ }
+ throw new QueryException("Consistency check failed for rule \"" + name + "\". Got " + c + " failure results.");
+ }
+ } finally {
+ answer.close();
+ }
+ }
+
+
+ /**
+ * Send the result of a query to the logger.
+ * @param ans The result of the query to log.
+ */
+ private void logOutput(Answer ans) {
+ try {
+ ans.beforeFirst();
+ Variable[] vars = ans.getVariables();
+ StringBuilder line = new StringBuilder();
+ for (Variable v: vars) line.append(v).append(" ");
+ logger.debug(line.toString());
+ line = new StringBuilder();
+ while (ans.next()) {
+ for (int c = 0; c < vars.length; c++) {
+ if (c != 0) line.append(", ");
+ line.append(ans.getObject(c));
+ }
+ line.append("\n");
+ }
+ logger.debug(line);
+ } catch (TuplesException e) {
+ logger.error("Error reading failure in consistency check.", e);
+ }
+ }
+
+}
Modified: trunk/src/jar/krule/java/org/mulgara/krule/KruleLoader.java
===================================================================
--- trunk/src/jar/krule/java/org/mulgara/krule/KruleLoader.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/krule/java/org/mulgara/krule/KruleLoader.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -24,16 +24,20 @@
// Third party packages
import org.apache.log4j.Logger;
import org.jrdf.graph.*;
+import org.jrdf.vocabulary.RDF;
// Locally written packages
-import org.mulgara.itql.*;
import org.mulgara.query.*;
import org.mulgara.query.rdf.LiteralImpl;
+import org.mulgara.query.rdf.Mulgara;
import org.mulgara.query.rdf.TripleImpl;
import org.mulgara.query.rdf.URIReferenceImpl;
import org.mulgara.resolver.OperationContext;
import org.mulgara.rules.*;
+import org.mulgara.util.functional.Pair;
+
import static org.mulgara.query.rdf.Mulgara.PREFIX_GRAPH;
+import static org.mulgara.query.rdf.Krule.*;
/**
* This object is used for parsing an RDF graph and building a rules structure
@@ -54,20 +58,17 @@
/** The database session for querying. */
private OperationContext operationContext;
- /** The interpreter for parsing queries. */
- private TqlInterpreter interpreter;
-
/** The rules. */
private RuleStructure rules;
- /** The URI of the model containing the rule data. */
- private URI ruleModel;
+ /** The Graph resource represented by ruleGraphUri. */
+ private final GraphResource ruleGraph;
- /** The URI of the model containing the base data. */
- private URI baseModel;
+ /** The URI of the graph containing the base data. */
+ private URI baseGraphUri;
- /** The URI of the model to receive the entailed data. */
- private URI destModel;
+ /** The URI of the graph to receive the entailed data. */
+ private URI destGraphUri;
/** A map of namespace names to the URIs. */
private Map<String,URI> aliases;
@@ -84,175 +85,30 @@
/** Map of Constraint nodes to the associated constraint object. */
private Map<Node,ConstraintExpression> constraintMap;
- /** URI for the Krule namespace. */
- public static final String KRULE = "http://mulgara.org/owl/krule/#";
+ /** RDF reference for rdf:type. */
+ public static final URIReferenceImpl RDF_TYPE = new URIReferenceImpl(RDF.TYPE);
- /** URI for a constraint subject. */
- private static final String HAS_SUBJECT_STR = KRULE + "hasSubject";
+ /** RDF reference for rdf:value. */
+ public static final URIReferenceImpl RDF_VALUE = new URIReferenceImpl(RDF.VALUE);
- /** URI for a constraint predicate. */
- private static final String HAS_PREDICATE_STR = KRULE + "hasPredicate";
+ /** A field used in queries to indicate no prior constraints on the answer. */
+ private static final UnconstrainedAnswer UNCONSTRAINED = new UnconstrainedAnswer();
- /** URI for a constraint object. */
- private static final String HAS_OBJECT_STR = KRULE + "hasObject";
-
- /** URI for a constraint model. */
- private static final String HAS_GRAPH_STR = KRULE + "hasModel";
-
- /** URI for a query property on rules. */
- private static final String HAS_QUERY_STR = KRULE + "hasQuery";
-
- /** URI for an axiom subject. */
- private static final String AXIOM_SUBJECT_STR = KRULE + "subject";
-
- /** URI for an axiom predicate. */
- private static final String AXIOM_PREDICATE_STR = KRULE + "predicate";
-
- /** URI for an axiom object. */
- private static final String AXIOM_OBJECT_STR = KRULE + "object";
-
- /** URI for rule triggering predicate. */
- private static final String TRIGGERS_STR = KRULE + "triggers";
-
- /** URI for selection variables in a query. */
- private static final String SELECTION_VARS_STR = KRULE + "selectionVariables";
-
- /** URI for constraints predicate in a query. */
- private static final String HAS_WHERE_CLAUSE_STR = KRULE + "hasWhereClause";
-
- /** URI for the argument property. */
- private static final String ARGUMENT_STR = KRULE + "argument";
-
- /** URI for the transitive constraint argument. */
- private static final String TRANSITIVE_ARGUMENT_STR = KRULE + "transitiveArgument";
-
- /** URI for the transitive constraint anchor argument. */
- private static final String ANCHOR_ARGUMENT_STR = KRULE + "anchorArgument";
-
- /** URI for the name argument. */
- private static final String NAME_STR = KRULE + "name";
-
- /** URI for the constraint conjunction type. */
- private static final String CONSTRAINT_CONJUNCTION_STR = KRULE + "ConstraintConjunction";
-
- /** URI for the constraint disjunction type. */
- private static final String CONSTRAINT_DISJUNCTION_STR = KRULE + "ConstraintDisjunction";
-
- /** URI for the simple constraint type. */
- private static final String SIMPLE_CONSTRAINT_STR = KRULE + "SimpleConstraint";
-
- /** URI for difference type. */
- private static final String DIFFERENCE_STR = KRULE + "Difference";
-
- /** URI for the Value type. */
- private static final String URI_REF_STR = KRULE + "URIReference";
-
- /** URI for the Variable type. */
- private static final String VARIABLE_STR = KRULE + "Variable";
-
- /** URI for the Variable type. */
- private static final String LITERAL_STR = KRULE + "Literal";
-
- /** URI for axiom type. */
- private static final String AXIOM_STR = KRULE + "Axiom";
-
- /** URI for rule type. */
- private static final String RULE_STR = KRULE + "Rule";
-
- /** URI for query type. */
- private static final String QUERY_STR = KRULE + "Query";
-
- /** RDF reference for constraint subject. */
- public static final URIReference HAS_SUBJECT = new URIReferenceImpl(URI.create(HAS_SUBJECT_STR));
-
- /** RDF reference for constraint predicate. */
- public static final URIReference HAS_PREDICATE = new URIReferenceImpl(URI.create(HAS_PREDICATE_STR));
-
- /** RDF reference for constraint object. */
- public static final URIReference HAS_OBJECT = new URIReferenceImpl(URI.create(HAS_OBJECT_STR));
-
- /** RDF reference for constraint model. */
- public static final URIReference HAS_GRAPH = new URIReferenceImpl(URI.create(HAS_GRAPH_STR));
-
- /** RDF reference for query property on rules. */
- public static final URIReference HAS_QUERY = new URIReferenceImpl(URI.create(HAS_QUERY_STR));
-
- /** RDF reference for axiom subject. */
- public static final URIReference AXIOM_SUBJECT = new URIReferenceImpl(URI.create(AXIOM_SUBJECT_STR));
-
- /** RDF reference for axiom predicate. */
- public static final URIReference AXIOM_PREDICATE = new URIReferenceImpl(URI.create(AXIOM_PREDICATE_STR));
-
- /** RDF reference for axiom object. */
- public static final URIReference AXIOM_OBJECT = new URIReferenceImpl(URI.create(AXIOM_OBJECT_STR));
-
- /** RDF reference for rule triggering predicate. */
- public static final URIReference TRIGGERS = new URIReferenceImpl(URI.create(TRIGGERS_STR));
-
- /** RDF reference for selection variables predicate. */
- public static final URIReference SELECTION_VARS = new URIReferenceImpl(URI.create(SELECTION_VARS_STR));
-
- /** RDF reference for hasWhereClause predicate. */
- public static final URIReference HAS_WHERE_CLAUSE = new URIReferenceImpl(URI.create(HAS_WHERE_CLAUSE_STR));
-
- /** RDF reference for the argument property. */
- public static final URIReference ARGUMENT = new URIReferenceImpl(URI.create(ARGUMENT_STR));
-
- /** RDF reference for the transitive constraint argument. */
- public static final URIReference TRANSITIVE_ARGUMENT = new URIReferenceImpl(URI.create(TRANSITIVE_ARGUMENT_STR));
-
- /** RDF reference for the transitive constraint anchor argument. */
- public static final URIReference ANCHOR_ARGUMENT = new URIReferenceImpl(URI.create(ANCHOR_ARGUMENT_STR));
-
- /** RDF reference for the name argument. */
- public static final URIReference NAME = new URIReferenceImpl(URI.create(NAME_STR));
-
- /** RDF reference for constraint conjunction class. */
- public static final URIReference CONSTRAINT_CONJUNCTION = new URIReferenceImpl(URI.create(CONSTRAINT_CONJUNCTION_STR));
-
- /** RDF reference for constraint disjunction class. */
- public static final URIReference CONSTRAINT_DISJUNCTION = new URIReferenceImpl(URI.create(CONSTRAINT_DISJUNCTION_STR));
-
- /** RDF reference for the simple constraint type. */
- public static final URIReference SIMPLE_CONSTRAINT = new URIReferenceImpl(URI.create(SIMPLE_CONSTRAINT_STR));
-
- /** RDF reference for the Difference type. */
- public static final URIReference DIFFERENCE = new URIReferenceImpl(URI.create(DIFFERENCE_STR));
-
- /** RDF reference for the Value type. */
- public static final URIReference URI_REF = new URIReferenceImpl(URI.create(URI_REF_STR));
-
- /** RDF reference for the Variable type. */
- public static final URIReference VARIABLE = new URIReferenceImpl(URI.create(VARIABLE_STR));
-
- /** RDF reference for the Literal type. */
- public static final URIReference LITERAL = new URIReferenceImpl(URI.create(LITERAL_STR));
-
- /** RDF reference for the Axiom type. */
- public static final URIReference AXIOM = new URIReferenceImpl(URI.create(AXIOM_STR));
-
- /** RDF reference for the Rule type. */
- public static final URIReference RULE = new URIReferenceImpl(URI.create(RULE_STR));
-
- /** RDF reference for the Query type. */
- public static final URIReference QUERY = new URIReferenceImpl(URI.create(QUERY_STR));
-
-
/**
* Principle constructor.
*
- * @param ruleModel The name of the model with the rules to run.
- * @param baseModel The name of the model with the base data.
- * @param destModel The name of the model which will receive the entailed data.
+ * @param ruleGraphUri The name of the graph with the rules to run.
+ * @param baseGraphUri The name of the graph with the base data.
+ * @param destGraphUri The name of the graph which will receive the entailed data.
*/
- KruleLoader(URI ruleModel, URI baseModel, URI destModel) {
- this.ruleModel = ruleModel;
- this.baseModel = baseModel;
- this.destModel = destModel;
+ KruleLoader(URI ruleGraphUri, URI baseGraphUri, URI destGraphUri) {
+ this.baseGraphUri = baseGraphUri;
+ this.destGraphUri = destGraphUri;
+ ruleGraph = new GraphResource(ruleGraphUri);
+
// set the query objects to null
operationContext = null;
- interpreter = null;
// initialize the aliases
newAliases();
@@ -279,16 +135,12 @@
* Reads the ruleModel in the database and constructs the rules from it.
*
* @param opContextParam The operationContext for querying on.
- * @param systemModel The system model.
* @return A new rule structure.
* @throws InitializerException There was a problem reading and creating the rules.
*/
- public Rules readRules(Object opContextParam, URI systemModel) throws InitializerException, RemoteException {
+ public Rules readRules(Object opContextParam) throws InitializerException, RemoteException {
this.operationContext = (OperationContext)opContextParam;
- // get a new interpreter
- interpreter = new TqlInterpreter(aliases);
-
rules = null;
try {
if (logger.isDebugEnabled()) logger.debug("Initializing for rule queries.");
@@ -298,7 +150,7 @@
if (logger.isDebugEnabled()) logger.debug("Querying for rules");
rules = findRules();
// set the target model
- rules.setTargetModel(destModel);
+ rules.setTargetModel(destGraphUri);
// find the triggers
loadTriggers();
@@ -363,14 +215,18 @@
* @throws QueryException When there is an exception finding the rules.
*/
private RuleStructure findRules() throws QueryException, TuplesException {
- Query query;
- try {
- // find all of the rules
- query = interpreter.parseQuery("select $rule from <" + ruleModel + "> where $rule <rdf:type> <krule:Rule> ;");
- } catch (Exception e) {
- throw new QueryException("Invalid query attempted while finding rules.", e);
- }
-
+ // select $rule from <ruleGraph> where $rule <rdf:type> <krule:Rule>
+ Variable ruleV = new Variable("rule");
+ Variable ruletypeV = new Variable("ruletype");
+ ConstraintExpression where = new ConstraintConjunction(
+ new ConstraintImpl(ruleV, RDF_TYPE, ruletypeV),
+ new ConstraintDisjunction(
+ new ConstraintIs(ruletypeV, RULE),
+ new ConstraintIs(ruletypeV, CHECK)
+ )
+ );
+ Query query = createQuery(where, ruleV, ruletypeV);
+
Answer ruleAnswer = query(query);
if (logger.isDebugEnabled()) logger.debug("Got response for rule query");
@@ -381,7 +237,11 @@
// create all the rules
while (ruleAnswer.next()) {
// create the rule and add it to the set
- rules.add(new Rule(ruleAnswer.getObject(0).toString()));
+ URIReference type = (URIReference)ruleAnswer.getObject(1);
+ String name = ruleAnswer.getObject(0).toString();
+ if (type.equals(RULE)) rules.add(new Rule(name));
+ else if (type.equals(CHECK)) rules.add(new ConsistencyCheck(name));
+ else throw new QueryException("Unexpected type for rule: " + name + "(" + type + ")");
}
} finally {
ruleAnswer.close();
@@ -399,12 +259,10 @@
* @throws InitializerException Data structures did not meet preconditions.
*/
private void loadTriggers() throws QueryException, TuplesException, InitializerException {
- Query query;
- try {
- query = interpreter.parseQuery("select $src $dest from <" + ruleModel + "> where $src <krule:triggers> $dest ;");
- } catch (Exception e) {
- throw new QueryException("Invalid query while finding triggers.", e);
- }
+ // select $src $dest from <ruleGraph> where $src <krule:triggers> $dest
+ Variable srcV = new Variable("src");
+ Variable destV = new Variable("dest");
+ Query query = createQuery(new ConstraintImpl(srcV, TRIGGERS, destV), srcV, destV);
Answer answer = query(query);
@@ -433,55 +291,66 @@
*/
private void loadQueries() throws TuplesException, QueryException, KruleStructureException, InitializerException {
if (logger.isDebugEnabled()) logger.debug("Loading Queries");
+
+ // create some of the loop-invariant resources
+ final URIReferenceImpl sysPrefix = new URIReferenceImpl(URI.create(PREFIX_GRAPH));
+ final URIReferenceImpl mulgaraPrefix = new URIReferenceImpl(Mulgara.PREFIX_URI);
+ final URIReferenceImpl seqPrefix = new URIReferenceImpl(URI.create(RDF.BASE_URI + "_"));
+
// go through the rules to set their queries
Iterator<Rule> ri = rules.getRuleIterator();
while (ri.hasNext()) {
Rule rule = ri.next();
+ // create a resource for this rule
+ URIReferenceImpl ruleRef = new URIReferenceImpl(URI.create(rule.getName()));
if (logger.isDebugEnabled()) logger.debug("Reading query for rule: " + rule.getName());
- Query query;
- try {
- // get the query data for this rule
- query = interpreter.parseQuery("select $pre $v $t from <" + ruleModel +
- "> where <" + rule.getName() + "> <krule:hasQuery> $q and $q <krule:selectionVariables> $vs and" +
- " $vs $pre $v and $pre <mulgara:prefix> <rdf:_> in <"+ PREFIX_GRAPH +
- "> and $v <rdf:type> $t ;");
- } catch (Exception e) {
- throw new QueryException("Invalid query while getting rule queries.", e);
- }
+ // select $pre $v $t from <ruleGraph>
+ // where <#ruleRef> <krule:hasQuery> $q and $q <krule:selectionVariables> $vs
+ // and $vs $pre $v and $pre <mulgara:prefix> <rdf:_> in <sys:prefix> and $v <rdf:type> $t
+ Variable qV = new Variable("q");
+ Variable vsV = new Variable("vs");
+ Variable preV = new Variable("pre");
+ Variable vV = new Variable("v");
+ Variable tV = new Variable("t");
+ ConstraintExpression where = new ConstraintConjunction(
+ new ConstraintImpl(ruleRef, HAS_QUERY, qV),
+ new ConstraintImpl(qV, SELECTION_VARS, vsV),
+ new ConstraintImpl(vsV, preV, vV),
+ new ConstraintImpl(preV, mulgaraPrefix, seqPrefix, sysPrefix),
+ new ConstraintImpl(vV, RDF_TYPE, tV)
+ );
+ Query query = createQuery(where, preV, vV, tV);
Answer answer = query(query);
// get the length of the sequence prefix
int prefixLength = ((URI)aliases.get("rdf")).toString().length() + 1;
// get the variables and values as elements with the appropriate type
- URIReference[] elements = new URIReference[3];
- URIReference[] types = new URIReference[3];
+ List<URIReference> elements = new ArrayList<URIReference>();
+ List<URIReference> types = new ArrayList<URIReference>();
try {
while (answer.next()) {
if (logger.isDebugEnabled()) logger.debug("Getting element from " + answer.getObject(0));
// work out the position of the element. Subject=0 Predicate=1 Object=2
int seqNr = Integer.parseInt(answer.getObject(0).toString().substring(prefixLength)) - 1;
if (logger.isDebugEnabled()) logger.debug("parsed: " + seqNr);
- if (seqNr > elements.length) {
- throw new KruleStructureException("Rule " + rule.getName() + " has too many insertion elements. Found sequence number: " + seqNr);
- }
// get the selection element and its type
- elements[seqNr] = (URIReference)answer.getObject(1);
- types[seqNr] = (URIReference)answer.getObject(2);
- if (logger.isDebugEnabled()) logger.debug("Nr: " + seqNr + ", v: " + elements[seqNr] + ", type: " + types[seqNr]);
+ setList(elements, seqNr, (URIReference)answer.getObject(1));
+ setList(types, seqNr, (URIReference)answer.getObject(2));
+ if (logger.isDebugEnabled()) logger.debug("Nr: " + seqNr + ", v: " + elements.get(seqNr) + ", type: " + types.get(seqNr));
}
} finally {
answer.close();
}
- for (int select = 0; select < elements.length; select++) {
- if (elements[select] == null || types[select] == null) {
+ for (int select = 0; select < elements.size(); select++) {
+ if (elements.get(select) == null || types.get(select) == null) {
// one element was set. Get a descriptive error message
StringBuffer errorMsg = new StringBuffer();
- for (int s = 0; s < elements.length; s++) {
- if (elements[s] == null) errorMsg.append(" <null>");
- else errorMsg.append(" ").append(elements[s]);
- if (types[s] == null) errorMsg.append("^^<null>");
- else errorMsg.append("^^<").append(types[s]).append(">");
+ for (int s = 0; s < elements.size(); s++) {
+ if (elements.get(s) == null) errorMsg.append(" <null>");
+ else errorMsg.append(" ").append(elements.get(s));
+ if (types.get(s) == null) errorMsg.append("^^<null>");
+ else errorMsg.append("^^<").append(types.get(s)).append(">");
}
throw new KruleStructureException("Rule " + rule.getName() + " does not have enough insertion elements. Got: " + errorMsg);
}
@@ -490,13 +359,15 @@
QueryStruct queryStruct = new QueryStruct(elements, types, aliases, uriReferences, varReferences, literalReferences);
// read in the WHERE reference
- try {
- // get the WHERE clause for this rule
- query = interpreter.parseQuery("select $w from <" + ruleModel +
- "> where <" + rule.getName() + "> <krule:hasQuery> $q and $q <krule:hasWhereClause> $w;");
- } catch (Exception e) {
- throw new QueryException("Invalid query reading WHERE clause for rule: " + rule.getName(), e);
- }
+
+ // select $w from <ruleGraph>
+ // where <#rule.getName()> <krule:hasQuery> $q and $q <krule:hasWhereClause> $w
+ Variable wV = new Variable("w");
+ where = new ConstraintConjunction(
+ new ConstraintImpl(ruleRef, HAS_QUERY, qV),
+ new ConstraintImpl(qV, HAS_WHERE_CLAUSE, wV)
+ );
+ query = createQuery(where, wV);
answer = query(query);
try {
@@ -518,7 +389,7 @@
if (logger.isDebugEnabled()) logger.debug("Setting models for the query");
// set the models
- queryStruct.setModelExpression(baseModel, destModel);
+ queryStruct.setModelExpression(baseGraphUri, destGraphUri);
if (logger.isDebugEnabled()) logger.debug("Setting query structure for the rule");
// create a new query and set it for the rule
@@ -539,15 +410,20 @@
private Set<org.jrdf.graph.Triple> findAxioms() throws TuplesException, QueryException, KruleStructureException, InitializerException {
if (logger.isDebugEnabled()) logger.debug("Loading Axioms");
- Query query;
- try {
- // get the query data for this rule
- query = interpreter.parseQuery("select $s $p $o from <" + ruleModel +
- "> where $axiom <rdf:type> <krule:Axiom> and $axiom <krule:subject> $s" +
- " and $axiom <krule:predicate> $p and $axiom <krule:object> $o;");
- } catch (Exception e) {
- throw new QueryException("Invalid query while finding axioms.", e);
- }
+ // select $s $p $o from <ruleGraph>
+ // where $axiom <rdf:type> <krule:Axiom> and $axiom <krule:subject> $s
+ // and $axiom <krule:predicate> $p and $axiom <krule:object> $o
+ Variable sV = new Variable("s");
+ Variable pV = new Variable("p");
+ Variable oV = new Variable("o");
+ Variable axiomV = new Variable("axiom");
+ ConstraintExpression where = new ConstraintConjunction(
+ new ConstraintImpl(axiomV, RDF_TYPE, AXIOM),
+ new ConstraintImpl(axiomV, AXIOM_SUBJECT, sV),
+ new ConstraintImpl(axiomV, AXIOM_PREDICATE, pV),
+ new ConstraintImpl(axiomV, AXIOM_OBJECT, oV)
+ );
+ Query query = createQuery(where, sV, pV, oV);
Answer answer = query(query);
// prepare the set of axioms
@@ -618,15 +494,15 @@
private void findUriReferences() throws TuplesException, QueryException, InitializerException {
if (logger.isDebugEnabled()) logger.debug("Querying for URI reference objects.");
- Query query;
- try {
- // find the URI references and the referred URIs.
- query = interpreter.parseQuery("select $ref $uri from <" +
- ruleModel + "> where $ref <rdf:type> <krule:URIReference> and $ref <rdf:value> $uri ;");
- } catch (Exception e) {
- throw new QueryException("Invalid query while looking for URI references.", e);
- }
-
+ // select $ref $uri from <ruleGraph>
+ // where $ref <rdf:type> <krule:URIReference> and $ref <rdf:value> $uri
+ Variable refV = new Variable("ref");
+ Variable uriV = new Variable("uri");
+ ConstraintExpression where = new ConstraintConjunction(
+ new ConstraintImpl(refV, RDF_TYPE, URI_REF),
+ new ConstraintImpl(refV, RDF_VALUE, uriV)
+ );
+ Query query = createQuery(where, refV, uriV);
Answer answer = query(query);
if (logger.isDebugEnabled()) logger.debug("Found all URI references.");
@@ -657,15 +533,17 @@
private void findVarReferences() throws TuplesException, QueryException, InitializerException {
if (logger.isDebugEnabled()) logger.debug("Querying for variable reference objects.");
- Query query;
- try {
- // find the URI references and the referred URIs.
- query = interpreter.parseQuery("select $ref $name from <" +
- ruleModel + "> where $ref <rdf:type> <krule:Variable> and $ref <krule:name> $name ;");
- } catch (Exception e) {
- throw new QueryException("Invalid query while finding variable references.", e);
- }
-
+ // find the URI references and the referred URIs.
+
+ // select $ref $name from <ruleGraph>
+ // where $ref <rdf:type> <krule:Variable> and $ref <krule:name> $name
+ Variable refV = new Variable("ref");
+ Variable nameV = new Variable("name");
+ ConstraintExpression where = new ConstraintConjunction(
+ new ConstraintImpl(refV, RDF_TYPE, VARIABLE),
+ new ConstraintImpl(refV, NAME, nameV)
+ );
+ Query query = createQuery(where, refV, nameV);
Answer answer = query(query);
if (logger.isDebugEnabled()) logger.debug("Found all variable references.");
@@ -677,7 +555,7 @@
URIReference ref = (URIReference)answer.getObject(0);
Literal name = (Literal)answer.getObject(1);
if (logger.isDebugEnabled()) logger.debug("Mapping <" + ref + "> to <" + name + ">");
- varReferences.put(ref, new Variable(name.toString()));
+ varReferences.put(ref, new Variable(name.getLexicalForm()));
}
} finally {
answer.close();
@@ -696,15 +574,15 @@
private void findLiteralReferences() throws TuplesException, QueryException, InitializerException {
if (logger.isDebugEnabled()) logger.debug("Querying for Literal objects.");
- Query query;
- try {
- // find the URI references and the referred URIs.
- query = interpreter.parseQuery("select $lit $str from <" +
- ruleModel + "> where $lit <rdf:type> <krule:Literal> and $lit <rdf:value> $str ;");
- } catch (Exception e) {
- throw new QueryException("Invalid query while looking for literal references.", e);
- }
-
+ // select $lit $str from <ruleGraph>
+ // where $lit <rdf:type> <krule:Literal> and $lit <rdf:value> $str
+ Variable litV = new Variable("lit");
+ Variable strV = new Variable("str");
+ ConstraintExpression where = new ConstraintConjunction(
+ new ConstraintImpl(litV, RDF_TYPE, LITERAL),
+ new ConstraintImpl(litV, RDF_VALUE, strV)
+ );
+ Query query = createQuery(where, litV, strV);
Answer answer = query(query);
if (logger.isDebugEnabled()) logger.debug("Found all Literals.");
@@ -735,16 +613,26 @@
private void loadSimpleConstraints() throws KruleStructureException, TuplesException, QueryException {
if (logger.isDebugEnabled()) logger.debug("Querying for Simple constraints.");
- Query query;
- try {
- // find the URI references and the referred URIs.
- query = interpreter.parseQuery("select $c $p $o from <" + ruleModel +
- "> where $c <rdf:type> <krule:SimpleConstraint> and $c $p $o and " +
- "($p <mulgara:is> <krule:hasSubject> or $p <mulgara:is> <krule:hasPredicate> or " +
- "$p <mulgara:is> <krule:hasObject> or $p <mulgara:is> <krule:hasModel>);");
- } catch (Exception e) {
- throw new QueryException("Invalid query while looking for simple constraints.", e);
- }
+ // select $c $p $o from <ruleGraph>
+ // where $c <rdf:type> <krule:SimpleConstraint> and $c $p $o
+ // and ($p <mulgara:is> <krule:hasSubject>
+ // or $p <mulgara:is> <krule:hasPredicate>
+ // or $p <mulgara:is> <krule:hasObject>
+ // or $p <mulgara:is> <krule:hasModel>)
+ Variable cV = new Variable("c");
+ Variable pV = new Variable("p");
+ Variable oV = new Variable("o");
+ ConstraintExpression where = new ConstraintConjunction(
+ new ConstraintImpl(cV, RDF_TYPE, SIMPLE_CONSTRAINT),
+ new ConstraintImpl(cV, pV, oV),
+ new ConstraintDisjunction(
+ new ConstraintIs(pV, HAS_SUBJECT),
+ new ConstraintIs(pV, HAS_PREDICATE),
+ new ConstraintIs(pV, HAS_OBJECT),
+ new ConstraintIs(pV, HAS_GRAPH)
+ )
+ );
+ Query query = createQuery(where, cV, pV, oV);
Answer answer = query(query);
if (logger.isDebugEnabled()) logger.debug("Found all simple constraints.");
@@ -802,23 +690,42 @@
// build constraints in place, recursively constructing child constraints until all are found
if (logger.isDebugEnabled()) logger.debug("Querying for Join constraints.");
- Query query;
- try {
- // find the URI references and the referred URIs.
- query = interpreter.parseQuery("select $constraint $constraint2 $type from <" + ruleModel +
- "> where $constraint <krule:argument> $constraint2 and $constraint <rdf:type> $type and " +
- "($type <mulgara:is> <krule:ConstraintConjunction> or $type <mulgara:is> <krule:ConstraintDisjunction>);");
- } catch (Exception e) {
- throw new QueryException("Invalid query while looking for join constraints.", e);
- }
+ // don't look for the type of the child constraints. krule:argument has range of Constraint.
+ // select $constraint $arg $constraint2 $type from <ruleGraph>
+ // where $constraint $arg $constraint2
+ // and $constraint <rdf:type> $type
+ // and ($type <mulgara:is> <krule:ConstraintConjunction>
+ // or $type <mulgara:is> <krule:ConstraintDisjunction>)
+ // and ($arg <mulgara:is> <krule:argument>
+ // or $arg <mulgara:is> <krule:minuend>
+ // or $arg <mulgara:is> <krule:subtrahend>)
+ Variable constraintV = new Variable("constraint");
+ Variable argV = new Variable("arg");
+ Variable constraint2V = new Variable("constraint2");
+ Variable typeV = new Variable("type");
+ ConstraintExpression where = new ConstraintConjunction(
+ new ConstraintImpl(constraintV, argV, constraint2V),
+ new ConstraintImpl(constraintV, RDF_TYPE, typeV),
+ new ConstraintDisjunction(
+ new ConstraintIs(typeV, CONSTRAINT_CONJUNCTION),
+ new ConstraintIs(typeV, CONSTRAINT_DISJUNCTION),
+ new ConstraintIs(typeV, DIFFERENCE)
+ ),
+ new ConstraintDisjunction(
+ new ConstraintIs(argV, ARGUMENT),
+ new ConstraintIs(argV, MINUEND),
+ new ConstraintIs(argV, SUBTRAHEND)
+ )
+ );
+ Query query = createQuery(where, constraintV, argV, constraint2V, typeV);
Answer answer = query(query);
if (logger.isDebugEnabled()) logger.debug("Found all join constraints.");
// accumulate all the constraint links and types
// create a map of join constraints to the constraints that they join
- Map<Node,Set<Node>> constraintLinks = new HashMap<Node,Set<Node>>();
+ Map<Node,Set<Pair<Node,Node>>> constraintLinks = new HashMap<Node,Set<Pair<Node,Node>>>();
// map the join constraints to the type of join
Map<Node,URIReference> joinTypes = new HashMap<Node,URIReference>();
@@ -827,13 +734,16 @@
// map each reference to the associated argument and type
while (answer.next()) {
Node constraintNode = (Node)answer.getObject(0);
- Node constraintNode2 = (Node)answer.getObject(1);
- URIReference type = (URIReference)answer.getObject(2);
- if (logger.isDebugEnabled()) logger.debug("constraint (" + type + ")<" + constraintNode + "> -> <" + constraintNode2 + ">");
- // map the constraint to its argument
- addLink(constraintLinks, constraintNode, constraintNode2);
+ URIReference arg = (URIReference)answer.getObject(1);
+ Node constraintNode2 = (Node)answer.getObject(2);
+ URIReference type = (URIReference)answer.getObject(3);
+ if (logger.isDebugEnabled()) logger.debug("constraint (" + type + ")<" + constraintNode + "> <" + arg + "><" + constraintNode2 + ">");
+ // map the constraint to its operand: constraintNode2
+ addLink(constraintLinks, constraintNode, new Pair<Node,Node>(arg, constraintNode2));
// map the type
- joinTypes.put(constraintNode, type);
+ URIReference storedType = joinTypes.get(constraintNode);
+ if (storedType == null) joinTypes.put(constraintNode, type);
+ else if (!storedType.equals(type)) throw new KruleStructureException("Varying types in constraint operations in the rule structure");
}
} finally {
answer.close();
@@ -841,19 +751,19 @@
if (logger.isDebugEnabled()) logger.debug("mapping join constraint RDF nodes to join constraint objects");
// collect all arguments together into constraints and map the node to the constraint
- for (Map.Entry<Node,Set<Node>> entry: constraintLinks.entrySet()) {
+ for (Map.Entry<Node,Set<Pair<Node,Node>>> entry: constraintLinks.entrySet()) {
// get the constraint node in question
Node constraintNode = entry.getKey();
// see if it maps to a constraint
if (constraintMap.get(constraintNode) == null) {
// the constraint does not exist
// get the argument nodes
- Set<Node> args = entry.getValue();
+ Set<Pair<Node,Node>> operands = entry.getValue();
// get the constraint's type
Node type = joinTypes.get(constraintNode);
- if (type == null) throw new KruleStructureException("No type (AND/OR) available on join constraint: " + constraintNode);
+ if (type == null) throw new KruleStructureException("No type (AND/OR/Minus) available on join constraint: " + constraintNode);
// convert the RDF nodes to constraints
- List<ConstraintExpression> constraintArgs = getConstraints(args, constraintLinks, joinTypes);
+ List<ConstraintExpression> constraintArgs = getConstraints(operands, constraintLinks, joinTypes);
ConstraintExpression joinConstraint = newJoinConstraint(type, constraintArgs);
if (logger.isDebugEnabled()) logger.debug("mapped " + constraintNode + " -> " + joinConstraint);
// build the join constraint, and map the node to it
@@ -877,16 +787,12 @@
private void loadHavingConstraints() throws KruleStructureException, TuplesException, QueryException {
if (logger.isDebugEnabled()) logger.debug("Querying for Having constraints.");
- Query query;
- try {
- // find the URI references and the referred URIs.
- query = interpreter.parseQuery("select $constraint from <" + ruleModel +
- "> where $rule <krule:hasHavingClause> $constraint;");
- } catch (Exception e) {
- throw new QueryException("Invalid query while searching on having clauses.", e);
- }
-
+ // select $constraint from <ruleGraph> where $rule <krule:hasHavingClause> $constraint
+ Variable ruleV = new Variable("rule");
+ Variable constraintV = new Variable("constraint");
+ Query query = createQuery(new ConstraintImpl(ruleV, HAS_HAVING_CLAUSE, constraintV), constraintV);
Answer answer = query(query);
+
if (logger.isDebugEnabled()) logger.debug("Found all having constraints.");
try {
@@ -907,15 +813,22 @@
private void loadTransitiveConstraints() throws KruleStructureException, TuplesException, QueryException {
if (logger.isDebugEnabled()) logger.debug("Querying for Transitive constraints.");
- Query query;
- try {
- // find the URI references and the referred URIs.
- query = interpreter.parseQuery("select $c $p $arg from <" + ruleModel +
- "> where $c <rdf:type> <krule:TransitiveConstraint> and $c $p $arg and " +
- "($p <mulgara:is> <krule:transitiveArgument> or $p <mulgara:is> <krule:anchorArgument>);");
- } catch (Exception e) {
- throw new QueryException("Invalid query while querying for transitive constraints.", e);
- }
+ // select $c $p $arg from <ruleGraph>
+ // where $c <rdf:type> <krule:TransitiveConstraint> and $c $p $arg
+ // and ($p <mulgara:is> <krule:transitiveArgument>
+ // or $p <mulgara:is> <krule:anchorArgument>)
+ Variable cV = new Variable("c");
+ Variable pV = new Variable("p");
+ Variable argV = new Variable("arg");
+ ConstraintExpression where = new ConstraintConjunction(
+ new ConstraintImpl(cV, RDF_TYPE, TRANSITIVE_CONSTRAINT),
+ new ConstraintImpl(cV, pV, argV),
+ new ConstraintDisjunction(
+ new ConstraintIs(pV, TRANSITIVE_ARGUMENT),
+ new ConstraintIs(pV, ANCHOR_ARGUMENT)
+ )
+ );
+ Query query = createQuery(where, cV, pV, argV);
Answer answer = query(query);
if (logger.isDebugEnabled()) logger.debug("Retrieved all transitive constraints.");
@@ -975,13 +888,13 @@
* to be created. The constraintLinks and typeMap arguments are for constructing new
* constraint objects.
*
- * @param constraints The set of constraint nodes to get the constraints for. Whenever possible,
- * the constraints come from constraintMap.
- * @param constraintLinks Linkage of join constraints to their arguments. Used to create a new constraint.
+ * @param constraints The set of constraint nodes and their usage to get the constraints for.
+ * Whenever possible, the constraints come from constraintMap.
+ * @param constraintLinks Linkage of join constraints to their arguments (and argument usage). Used to create a new constraint.
* @param typeMap Maps constraint nodes to their type. Used to create a new constraint.
* @throws KruleStructureException There was an error in the RDF data structure.
*/
- private List<ConstraintExpression> getConstraints(Set<Node> constraints, Map<Node,Set<Node>> constraintLinks, Map<Node,URIReference> typeMap) throws KruleStructureException {
+ private List<ConstraintExpression> getConstraints(Set<Pair<Node,Node>> constraints, Map<Node,Set<Pair<Node,Node>>> constraintLinks, Map<Node,URIReference> typeMap) throws KruleStructureException {
if (logger.isDebugEnabled()) logger.debug("converting nodes to constraint list: " + constraints);
// build the return list
@@ -992,21 +905,27 @@
return cList;
}
// go through the arguments
- for (Node cNode: constraints) {
+ for (Pair<Node,Node> constraintUsage: constraints) {
+ Node usage = constraintUsage.first(); // one of: argument/minuend/subtrahend
+ Node cNode = constraintUsage.second();
if (logger.isDebugEnabled()) logger.debug("converting: " + cNode);
// get the constraint expression object
ConstraintExpression constraintExpr = (ConstraintExpression)constraintMap.get(cNode);
if (constraintExpr == null) {
if (logger.isDebugEnabled()) logger.debug(cNode.toString() + " not yet mapped to constraint");
// constraint expression object does not yet exist, get its arguments
- Set<Node> constraintArgNodes = constraintLinks.get(cNode);
+ Set<Pair<Node,Node>> constraintArgNodes = constraintLinks.get(cNode);
// build the constraint expression - get the arguments as a list of constraints
List<ConstraintExpression> constraintArgs = getConstraints(constraintArgNodes, constraintLinks, typeMap);
constraintExpr = newJoinConstraint((Node)typeMap.get(cNode), constraintArgs);
}
// add the constraint argument to the list
- if (constraintExpr != null) cList.add(constraintExpr);
- else logger.warn("Missing constraint expression. Ignoring.");
+ if (constraintExpr != null) {
+ if (usage.equals(MINUEND)) setList(cList, 0, constraintExpr);
+ else if (usage.equals(SUBTRAHEND)) setList(cList, 1, constraintExpr);
+ else if (usage.equals(ARGUMENT)) cList.add(constraintExpr);
+ else throw new KruleStructureException("Unknown argument type for " + cNode + ": " + usage);
+ } else logger.warn("Missing constraint expression. Ignoring.");
}
return cList;
}
@@ -1028,8 +947,11 @@
return new ConstraintConjunction(args);
} else if (type.equals(CONSTRAINT_DISJUNCTION)) {
return new ConstraintDisjunction(args);
+ } else if (type.equals(DIFFERENCE)) {
+ if (args.size() != 2) throw new KruleStructureException("Difference constraints require 2 arguments: args=" + args);
+ return new ConstraintDifference(args.get(0), args.get(1));
}
- throw new KruleStructureException("Unknown join constraint type (not AND/OR): " + type);
+ throw new KruleStructureException("Unknown join constraint type (not AND/OR/Minus): " + type);
}
@@ -1085,29 +1007,64 @@
/**
- * Maps a node to another node, creating the entry if it does not exist yet.
+ * Maps a node to data about a nodee, creating the entry if it does not exist yet.
*
* @param map The mapping of nodes to tuples.
* @param node1 The node to map.
- * @param node2 The node to map it to.
+ * @param nodeData The node data to map it to.
*/
- private static void addLink(Map<Node,Set<Node>> map, Node node1, Node node2) {
+ private static void addLink(Map<Node,Set<Pair<Node,Node>>> map, Node node1, Pair<Node,Node> nodeData) {
// get the current set of properties
- Set<Node> links = map.get(node1);
+ Set<Pair<Node,Node>> links = map.get(node1);
// check that the set exists
if (links == null) {
// no, so create
- links = new HashSet<Node>();
- links.add(node2);
+ links = new HashSet<Pair<Node,Node>>();
+ links.add(nodeData);
// add to the map
map.put(node1, links);
} else {
// update the map to hold the new value
- links.add(node2);
+ links.add(nodeData);
}
}
+
/**
+ * Sets an element in a list, expanding the list if necessary.
+ * @param list The list to update.
+ * @param offset The offset to write to in the list.
+ * @param value The value to write to the list.
+ */
+ private static <T> void setList(List<T> list, int offset, T value) {
+ while (offset >= list.size()) list.add(null);
+ list.set(offset, value);
+ }
+
+
+ /**
+ * Utility method to create a query.
+ * @param constraintExpression The constraint expression making up the WHERE clause of the query.
+ * @param selection The variables to select in the query.
+ * @return The new query.
+ */
+ @SuppressWarnings("unchecked")
+ private Query createQuery(ConstraintExpression constraintExpression, Variable... selection) {
+ List<Variable> selectList = Arrays.asList(selection);
+ return new Query(
+ selectList, // SELECT
+ ruleGraph, // FROM
+ constraintExpression, // WHERE
+ null, // HAVING
+ (List<Order>)Collections.EMPTY_LIST, // ORDER BY
+ null, // LIMIT
+ 0, // OFFSET
+ UNCONSTRAINED // GIVEN
+ );
+ }
+
+
+ /**
* Local wrapper for querying on an OperationContext. Since {@link OperationContext#doQuery(Query)}
* throws an {@link Exception}, this is captured and wrapped in or cast to a {@link QueryException}.
* @param q The query to execute.
@@ -1116,7 +1073,8 @@
*/
private Answer query(Query q) throws QueryException {
try {
- return operationContext.doQuery(q);
+ if (operationContext != null) return operationContext.doQuery(q);
+ throw new IllegalStateException("No environment to query the database in");
} catch (Exception e) {
if (e instanceof QueryException) throw (QueryException)e;
throw new QueryException("Unable to execute query", e);
Modified: trunk/src/jar/krule/java/org/mulgara/krule/QueryStruct.java
===================================================================
--- trunk/src/jar/krule/java/org/mulgara/krule/QueryStruct.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/krule/java/org/mulgara/krule/QueryStruct.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -41,6 +41,7 @@
import org.mulgara.query.UnconstrainedAnswer;
import org.mulgara.query.Variable;
import org.mulgara.query.VariableFactory;
+import org.mulgara.query.rdf.Krule;
import org.mulgara.query.rdf.LiteralImpl;
import org.mulgara.query.rdf.URIReferenceImpl;
@@ -62,7 +63,7 @@
private static Logger logger = Logger.getLogger(QueryStruct.class.getName());
/** The selection list. */
- private ConstraintElement[] select = new ConstraintElement[3];
+ private ConstraintElement[] select;
/** List of elements which are variables, or ConstantValues. */
private List<SelectElement> variables;
@@ -80,8 +81,8 @@
/**
* Constructor. Converts string descriptions of the values and variables into the constraint elements.
*
- * @param vs The element nodes.
- * @param types The types of the elements, defined in the krule namespace.
+ * @param valueSelection The element nodes.
+ * @param selTypes The types of the elements, defined in the krule namespace.
* @param alias The aliases used in the query process.
* @param uriReferences A map of all krule:ref_* objects to the appropriate {@link org.jrdf.graph.URIReference}s.
* @param varReferences A map of all krule:var_* objects to the appropriate name.
@@ -89,42 +90,57 @@
* or the references are not found in the references map.
*/
public QueryStruct(
- URIReference[] vs, URIReference[] types, Map<String,URI> alias,
+ List<URIReference> valueSelection, List<URIReference> selTypes, Map<String,URI> alias,
Map<URIReference,URIReference> uriReferences, Map<URIReference,Variable> varReferences,
Map<Node,Literal> litReferences
) {
- if (vs.length != 3 && types.length != 3) {
+ if (valueSelection.size() <= 0 || selTypes.size() <= 0 || valueSelection.size() != selTypes.size()) {
throw new IllegalArgumentException("Wrong number of elements for a rule query");
}
+ URIReference[] vs = valueSelection.toArray(new URIReference[valueSelection.size()]);
+ URIReference[] types = selTypes.toArray(new URIReference[selTypes.size()]);
+
+ // If there is a non-multiple of 3 in the selection variables, then this is a check rule
+ // and we can only select variables in check rules
+ boolean varsOnly = vs.length % 3 != 0;
+
VariableFactory variableFactory = new VariableFactoryImpl();
// set up a list of variables
variables = new ArrayList<SelectElement>();
+ select = new ConstraintElement[vs.length];
// convert the parameters to usable objects
- for (int i = 0; i < 3; i++) {
+ for (int i = 0; i < vs.length; i++) {
URIReference element = vs[i];
// check the type
- if (types[i].equals(KruleLoader.URI_REF)) {
+ if (types[i].equals(Krule.URI_REF)) {
+ // check that this didn't have a non-multiple of 3 in the selection values
+ if (varsOnly) throw new IllegalArgumentException("Wrong number of elements for a rule query: " + vs.length);
+
// get the referred value from the map
select[i] = (URIReferenceImpl)uriReferences.get(element);
// assume that literals do not have the "Value" type inferred
variables.add(new ConstantValue(variableFactory.newVariable(), (URIReferenceImpl)select[i]));
- } else if (types[i].equals(KruleLoader.VARIABLE)) {
+ } else if (types[i].equals(Krule.VARIABLE)) {
// get the variable
select[i] = (Variable)varReferences.get(element);
variables.add((Variable)select[i]);
- } else if (types[i].equals(KruleLoader.LITERAL)) {
+ } else if (types[i].equals(Krule.LITERAL)) {
- if (i != 2) {
+ if (i % 3 != 2) {
throw new IllegalArgumentException("Selection literal in illegal position in query");
}
+
+ // check that this didn't have a non-multiple of 3 in the selection values
+ if (varsOnly) throw new IllegalArgumentException("Wrong number of elements for a rule query: " + vs.length);
+
// get the literal
select[i] = (LiteralImpl)litReferences.get(element);
variables.add(new ConstantValue(variableFactory.newVariable(), (LiteralImpl)select[i]));
@@ -143,6 +159,15 @@
/**
+ * Returns the number of elements to be returned from this query.
+ * @return The number of selection elements from the query.
+ */
+ public int elementCount() {
+ return select.length;
+ }
+
+
+ /**
* Retrieve the element <em>n</em>.
*
* @param n The element number to retrieve.
@@ -150,7 +175,7 @@
* @throws IndexOutOfBoundsException If n is larger than 3.
*/
public ConstraintElement getElement(int n) {
- assert n < 3;
+ assert n < select.length;
return select[n];
}
Modified: trunk/src/jar/krule/java/org/mulgara/krule/Rule.java
===================================================================
--- trunk/src/jar/krule/java/org/mulgara/krule/Rule.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/krule/java/org/mulgara/krule/Rule.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -51,13 +51,13 @@
private static Logger logger = Logger.getLogger(Rule.class.getName());
/** The name of this rule. */
- private String name;
+ protected String name;
/** The rules to be triggered when this rule generates statements.*/
private Set<Rule> triggerSet;
/** The query for this rule. This contains the information for the base model. */
- private Query query;
+ protected Query query;
/** The graph receiving the inferred data. */
private long targetGraph = UNINITIALIZED;
@@ -66,7 +66,7 @@
private long lastCount;
/** The structure containing this rule */
- private RuleStructure ruleStruct;
+ protected RuleStructure ruleStruct;
// TODO: Change this to a map of constraints to longs
@@ -112,11 +112,15 @@
/**
- * Sets the query for this rule.
+ * Sets the query for this rule. Must be a valid query for inserting data, meaning that it
+ * returns a multiple of 3 elements.
*
* @param queryStruct The query which retrieves data for this rule.
+ * @throws KruleStructureException If the query does not return a multiple of 3 elements.
*/
- public void setQueryStruct(QueryStruct queryStruct) {
+ public void setQueryStruct(QueryStruct queryStruct) throws KruleStructureException {
+ int e = queryStruct.elementCount();
+ if (e == 0 || e % 3 != 0) throw new KruleStructureException("Rule \"" + name + "\" attempting to generate the wrong number of elements (must be a multiple of 3): " + e);
this.query = queryStruct.extractQuery();
}
Modified: trunk/src/jar/query/java/org/mulgara/query/ConstraintConjunction.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/ConstraintConjunction.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/query/java/org/mulgara/query/ConstraintConjunction.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -93,6 +93,15 @@
/**
+ * Build a conjunction with a {@link Collection} of several children constraint expressions
+ * @param elements a {@link Collection} of {@link ConstraintExpression}s.
+ */
+ public ConstraintConjunction(ConstraintExpression... elements) {
+ super(Arrays.asList(elements));
+ }
+
+
+ /**
* Gets the Filtered attribute of the ConstraintConjunction object
*
* @return The Filtered value
Modified: trunk/src/jar/query/java/org/mulgara/query/ConstraintDisjunction.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/ConstraintDisjunction.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/query/java/org/mulgara/query/ConstraintDisjunction.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -82,6 +82,15 @@
}
/**
+ * Create a Disjunction (OR expression) between several constraint expressions.
+ *
+ * @param elements The expressions to perform a disjunction on.
+ */
+ public ConstraintDisjunction(ConstraintExpression... elements) {
+ super(Arrays.asList(elements));
+ }
+
+ /**
* Gets the Name attribute of the ConstraintDisjunction object
*
* @return The Name value
Copied: trunk/src/jar/query/java/org/mulgara/query/rdf/Krule.java (from rev 1625, branches/consistency/src/jar/query/java/org/mulgara/query/rdf/Krule.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/rdf/Krule.java (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/rdf/Krule.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2008 Fedora Commons, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.mulgara.query.rdf;
+
+import java.net.URI;
+
+/**
+ * URI constants for rules.
+ *
+ * @created Mar 23, 2009
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ */
+
+public class Krule {
+
+ /** URI for the Krule namespace. */
+ public static final String KRULE = "http://mulgara.org/owl/krule/#";
+
+ /** URI for a constraint subject. */
+ private static final String HAS_SUBJECT_STR = KRULE + "hasSubject";
+
+ /** URI for a constraint predicate. */
+ private static final String HAS_PREDICATE_STR = KRULE + "hasPredicate";
+
+ /** URI for a constraint object. */
+ private static final String HAS_OBJECT_STR = KRULE + "hasObject";
+
+ /** URI for a constraint model. */
+ private static final String HAS_GRAPH_STR = KRULE + "hasModel";
+
+ /** URI for a query property on rules. */
+ private static final String HAS_QUERY_STR = KRULE + "hasQuery";
+
+ /** URI for an axiom subject. */
+ private static final String AXIOM_SUBJECT_STR = KRULE + "subject";
+
+ /** URI for an axiom predicate. */
+ private static final String AXIOM_PREDICATE_STR = KRULE + "predicate";
+
+ /** URI for an axiom object. */
+ private static final String AXIOM_OBJECT_STR = KRULE + "object";
+
+ /** URI for rule triggering predicate. */
+ private static final String TRIGGERS_STR = KRULE + "triggers";
+
+ /** URI for selection variables in a query. */
+ private static final String SELECTION_VARS_STR = KRULE + "selectionVariables";
+
+ /** URI for constraints predicate in a query. */
+ private static final String HAS_WHERE_CLAUSE_STR = KRULE + "hasWhereClause";
+
+ /** URI for having constraints predicate in a query. */
+ private static final String HAS_HAVING_CLAUSE_STR = KRULE + "hasHavingClause";
+
+ /** URI for the argument property. */
+ private static final String ARGUMENT_STR = KRULE + "argument";
+
+ /** URI for the minuend property. */
+ private static final String MINUEND_STR = KRULE + "minuend";
+
+ /** URI for the subtrahend property. */
+ private static final String SUBTRAHEND_STR = KRULE + "subtrahend";
+
+ /** URI for the transitive constraint argument. */
+ private static final String TRANSITIVE_ARGUMENT_STR = KRULE + "transitiveArgument";
+
+ /** URI for the transitive constraint anchor argument. */
+ private static final String ANCHOR_ARGUMENT_STR = KRULE + "anchorArgument";
+
+ /** URI for the name argument. */
+ private static final String NAME_STR = KRULE + "name";
+
+ /** URI for the constraint conjunction type. */
+ private static final String CONSTRAINT_CONJUNCTION_STR = KRULE + "ConstraintConjunction";
+
+ /** URI for the constraint disjunction type. */
+ private static final String CONSTRAINT_DISJUNCTION_STR = KRULE + "ConstraintDisjunction";
+
+ /** URI for the simple constraint type. */
+ private static final String SIMPLE_CONSTRAINT_STR = KRULE + "SimpleConstraint";
+
+ /** URI for the transitive constraint type. */
+ private static final String TRANSITIVE_CONSTRAINT_STR = KRULE + "TransitiveConstraint";
+
+ /** URI for difference type. */
+ private static final String DIFFERENCE_STR = KRULE + "Difference";
+
+ /** URI for the Value type. */
+ private static final String URI_REF_STR = KRULE + "URIReference";
+
+ /** URI for the Variable type. */
+ private static final String VARIABLE_STR = KRULE + "Variable";
+
+ /** URI for the Variable type. */
+ private static final String LITERAL_STR = KRULE + "Literal";
+
+ /** URI for axiom type. */
+ private static final String AXIOM_STR = KRULE + "Axiom";
+
+ /** URI for rule type. */
+ private static final String RULE_STR = KRULE + "Rule";
+
+ /** URI for consistency check type. */
+ private static final String CHECK_STR = KRULE + "ConsistencyCheck";
+
+ /** URI for query type. */
+ private static final String QUERY_STR = KRULE + "Query";
+
+ /** RDF reference for constraint subject. */
+ public static final URIReferenceImpl HAS_SUBJECT = new URIReferenceImpl(URI.create(HAS_SUBJECT_STR));
+
+ /** RDF reference for constraint predicate. */
+ public static final URIReferenceImpl HAS_PREDICATE = new URIReferenceImpl(URI.create(HAS_PREDICATE_STR));
+
+ /** RDF reference for constraint object. */
+ public static final URIReferenceImpl HAS_OBJECT = new URIReferenceImpl(URI.create(HAS_OBJECT_STR));
+
+ /** RDF reference for constraint model. */
+ public static final URIReferenceImpl HAS_GRAPH = new URIReferenceImpl(URI.create(HAS_GRAPH_STR));
+
+ /** RDF reference for query property on rules. */
+ public static final URIReferenceImpl HAS_QUERY = new URIReferenceImpl(URI.create(HAS_QUERY_STR));
+
+ /** RDF reference for axiom subject. */
+ public static final URIReferenceImpl AXIOM_SUBJECT = new URIReferenceImpl(URI.create(AXIOM_SUBJECT_STR));
+
+ /** RDF reference for axiom predicate. */
+ public static final URIReferenceImpl AXIOM_PREDICATE = new URIReferenceImpl(URI.create(AXIOM_PREDICATE_STR));
+
+ /** RDF reference for axiom object. */
+ public static final URIReferenceImpl AXIOM_OBJECT = new URIReferenceImpl(URI.create(AXIOM_OBJECT_STR));
+
+ /** RDF reference for rule triggering predicate. */
+ public static final URIReferenceImpl TRIGGERS = new URIReferenceImpl(URI.create(TRIGGERS_STR));
+
+ /** RDF reference for selection variables predicate. */
+ public static final URIReferenceImpl SELECTION_VARS = new URIReferenceImpl(URI.create(SELECTION_VARS_STR));
+
+ /** RDF reference for hasWhereClause predicate. */
+ public static final URIReferenceImpl HAS_WHERE_CLAUSE = new URIReferenceImpl(URI.create(HAS_WHERE_CLAUSE_STR));
+
+ /** RDF reference for hasHavingClause predicate. */
+ public static final URIReferenceImpl HAS_HAVING_CLAUSE = new URIReferenceImpl(URI.create(HAS_HAVING_CLAUSE_STR));
+
+ /** RDF reference for the argument property. */
+ public static final URIReferenceImpl ARGUMENT = new URIReferenceImpl(URI.create(ARGUMENT_STR));
+
+ /** RDF reference for the minuend property. */
+ public static final URIReferenceImpl MINUEND = new URIReferenceImpl(URI.create(MINUEND_STR));
+
+ /** RDF reference for the subtrahend property. */
+ public static final URIReferenceImpl SUBTRAHEND = new URIReferenceImpl(URI.create(SUBTRAHEND_STR));
+
+ /** RDF reference for the transitive constraint argument. */
+ public static final URIReferenceImpl TRANSITIVE_ARGUMENT = new URIReferenceImpl(URI.create(TRANSITIVE_ARGUMENT_STR));
+
+ /** RDF reference for the transitive constraint anchor argument. */
+ public static final URIReferenceImpl ANCHOR_ARGUMENT = new URIReferenceImpl(URI.create(ANCHOR_ARGUMENT_STR));
+
+ /** RDF reference for the name argument. */
+ public static final URIReferenceImpl NAME = new URIReferenceImpl(URI.create(NAME_STR));
+
+ /** RDF reference for constraint conjunction class. */
+ public static final URIReferenceImpl CONSTRAINT_CONJUNCTION = new URIReferenceImpl(URI.create(CONSTRAINT_CONJUNCTION_STR));
+
+ /** RDF reference for constraint disjunction class. */
+ public static final URIReferenceImpl CONSTRAINT_DISJUNCTION = new URIReferenceImpl(URI.create(CONSTRAINT_DISJUNCTION_STR));
+
+ /** RDF reference for the simple constraint type. */
+ public static final URIReferenceImpl SIMPLE_CONSTRAINT = new URIReferenceImpl(URI.create(SIMPLE_CONSTRAINT_STR));
+
+ /** RDF reference for the transitive constraint type. */
+ public static final URIReferenceImpl TRANSITIVE_CONSTRAINT = new URIReferenceImpl(URI.create(TRANSITIVE_CONSTRAINT_STR));
+
+ /** RDF reference for the Difference type. */
+ public static final URIReferenceImpl DIFFERENCE = new URIReferenceImpl(URI.create(DIFFERENCE_STR));
+
+ /** RDF reference for the Value type. */
+ public static final URIReferenceImpl URI_REF = new URIReferenceImpl(URI.create(URI_REF_STR));
+
+ /** RDF reference for the Variable type. */
+ public static final URIReferenceImpl VARIABLE = new URIReferenceImpl(URI.create(VARIABLE_STR));
+
+ /** RDF reference for the Literal type. */
+ public static final URIReferenceImpl LITERAL = new URIReferenceImpl(URI.create(LITERAL_STR));
+
+ /** RDF reference for the Axiom type. */
+ public static final URIReferenceImpl AXIOM = new URIReferenceImpl(URI.create(AXIOM_STR));
+
+ /** RDF reference for the Rule type. */
+ public static final URIReferenceImpl RULE = new URIReferenceImpl(URI.create(RULE_STR));
+
+ /** RDF reference for the Consistency Check type. */
+ public static final URIReferenceImpl CHECK = new URIReferenceImpl(URI.create(CHECK_STR));
+
+ /** RDF reference for the Query type. */
+ public static final URIReferenceImpl QUERY = new URIReferenceImpl(URI.create(QUERY_STR));
+
+}
Modified: trunk/src/jar/query/java/org/mulgara/query/rdf/Mulgara.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/rdf/Mulgara.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/query/java/org/mulgara/query/rdf/Mulgara.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -27,6 +27,8 @@
package org.mulgara.query.rdf;
+import java.net.URI;
+
/**
* General constants.
*
@@ -57,4 +59,14 @@
/** An identifier for a XSD resolver graph */
public final static String XSD_GRAPH = "sys:xsd";
+
+ /** The URI for prefix graph types. */
+ public final static URI PREFIX_GRAPH_TYPE_URI = URI.create(NAMESPACE + "PrefixGraph");
+
+ /** The URI for prefixes. */
+ public final static URI PREFIX_URI = URI.create(NAMESPACE + "prefix");
+
+ /** The URI for prefixes. */
+ public final static URI IS_URI = URI.create(NAMESPACE + "is");
+
}
Modified: trunk/src/jar/resolver/build.xml
===================================================================
--- trunk/src/jar/resolver/build.xml 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/resolver/build.xml 2009-03-24 18:42:49 UTC (rev 1626)
@@ -33,6 +33,7 @@
<fileset file="${resolver-url.dist.dir}/${resolver-url.jar}"/>
<fileset file="${content-rdfxml.dist.dir}/${content-rdfxml.jar}"/>
<fileset file="${content-n3.dist.dir}/${content-n3.jar}"/>
+ <fileset file="${content-rlog.dist.dir}/${content-rlog.jar}"/>
<fileset file="${driver.dist.dir}/${driver.jar}"/>
</path>
@@ -82,7 +83,7 @@
<target name="resolver-compile"
depends="-resolver-prepare, resolver-spi-jar, rules-jar,
resolver-http-jar, resolver-file-jar, resolver-url-jar,
- resolver-jar-jar, content-rdfxml-jar, content-n3-jar,
+ resolver-jar-jar, content-rdfxml-jar, content-n3-jar, content-rlog-jar,
client-jrdf-jar, jrdf-jar, resolver-xsd-jar, driver-jar"
description="Compiles all resolver related files included generated
source code">
Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/BuildRulesOperation.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/BuildRulesOperation.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/BuildRulesOperation.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -81,7 +81,7 @@
if (ruleLoader == null) throw new org.mulgara.rules.InitializerException("No rule loader available");
// read in the rules
- Rules rules = ruleLoader.readRules(operationContext, metadata.getSystemModelURI());
+ Rules rules = ruleLoader.readRules(operationContext);
result = new RulesRefImpl(rules);
}
Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/ExportOperation.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/ExportOperation.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/ExportOperation.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -17,6 +17,7 @@
import java.util.Map;
import org.mulgara.content.rdfxml.writer.RDFXMLWriter;
+import org.mulgara.content.rlog.RlogStructure;
import org.mulgara.content.n3.N3Writer;
import org.mulgara.query.Constraint;
import org.mulgara.query.ConstraintImpl;
@@ -108,6 +109,10 @@
if (path != null && (path.endsWith(".n3") || path.endsWith(".nt") || path.endsWith(".ttl"))) {
N3Writer n3Writer = new N3Writer();
n3Writer.write(graphStatements, systemResolver, writer);
+ } else if (path != null && (path.endsWith(".rl") || path.endsWith(".dl") || path.endsWith(".rlog"))) {
+ RlogStructure struct = new RlogStructure(systemResolver);
+ struct.load(graphStatements);
+ struct.write(writer);
} else {
RDFXMLWriter rdfWriter = new RDFXMLWriter();
rdfWriter.write(graphStatements, systemResolver, writer, prefixes);
Modified: trunk/src/jar/resolver-prefix/java/org/mulgara/resolver/prefix/PrefixResolverFactory.java
===================================================================
--- trunk/src/jar/resolver-prefix/java/org/mulgara/resolver/prefix/PrefixResolverFactory.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/resolver-prefix/java/org/mulgara/resolver/prefix/PrefixResolverFactory.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -38,15 +38,9 @@
/** Logger. */
private static Logger logger = Logger.getLogger(PrefixResolverFactory.class.getName());
- /** The URI for the graphType. */
- private static final URI graphTypeURI = URI.create(Mulgara.NAMESPACE + "PrefixGraph");
-
/** The URI for the default graph. */
private static final URI DEFAULT_GRAPH = URI.create(Mulgara.PREFIX_GRAPH);
- /** The URI for prefixes. */
- private static final URI mulgaraPrefixURI = URI.create(Mulgara.NAMESPACE + "prefix");
-
/** The preallocated local node representing the prefix predicate. */
private long mulgaraPrefix;
@@ -66,7 +60,7 @@
}
// intialize the fields
- mulgaraPrefix = initializer.preallocate(new URIReferenceImpl(mulgaraPrefixURI));
+ mulgaraPrefix = initializer.preallocate(new URIReferenceImpl(Mulgara.PREFIX_URI));
// no need to claim the types supported by this resolver, as this is detected in the default graphs
}
@@ -116,14 +110,14 @@
boolean canWrite, ResolverSession resolverSession, Resolver systemResolver
) throws ResolverFactoryException {
if (logger.isDebugEnabled()) logger.debug("Creating new Prefix resolver");
- return new PrefixResolver(resolverSession, systemResolver, mulgaraPrefix, graphTypeURI);
+ return new PrefixResolver(resolverSession, systemResolver, mulgaraPrefix, Mulgara.PREFIX_GRAPH_TYPE_URI);
}
/**
* @return The default graph for this resolver.
*/
public Graph[] getDefaultGraphs() {
- return new Graph[] { new Graph(DEFAULT_GRAPH, graphTypeURI) };
+ return new Graph[] { new Graph(DEFAULT_GRAPH, Mulgara.PREFIX_GRAPH_TYPE_URI) };
}
/**
Modified: trunk/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalResolverUnitTest.java
===================================================================
--- trunk/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalResolverUnitTest.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalResolverUnitTest.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -43,11 +43,8 @@
// Java 2 standard packages
import java.io.File;
-import java.io.PrintWriter;
-import java.io.StringWriter;
import java.net.URI;
import java.net.URISyntaxException;
-import java.net.InetAddress;
import java.util.*;
import java.sql.*;
@@ -58,14 +55,9 @@
// Locally written packages
import org.mulgara.query.*;
-import org.mulgara.query.rdf.Mulgara;
import org.mulgara.query.rdf.URIReferenceImpl;
import org.mulgara.query.rdf.LiteralImpl;
import org.mulgara.server.Session;
-import org.mulgara.store.StoreException;
-import org.mulgara.store.nodepool.NodePool;
-import org.mulgara.store.stringpool.StringPool;
-import org.mulgara.store.tuples.AbstractTuples;
import org.mulgara.util.FileUtil;
import org.mulgara.util.TempDir;
@@ -109,9 +101,12 @@
}
}
+ /** create the temporary directory */
+ @SuppressWarnings("unused")
private static final File tmpDir = TempDir.getTempDir();
/** Logger. */
+ @SuppressWarnings("unused")
private static Logger logger =
Logger.getLogger(RelationalResolverUnitTest.class.getName());
@@ -225,9 +220,6 @@
String tempResolverFactoryClassName =
"org.mulgara.resolver.memory.MemoryResolverFactory";
- String ruleLoaderFactoryClassName =
- "org.mulgara.rules.RuleLoaderFactory";
-
// Create a database which keeps its system models on the Java heap
database = new Database(
databaseURI,
@@ -380,7 +372,7 @@
public void testBasicClassQuery() throws Exception {
Session session = database.newSession();
try {
- List selectList = Collections.singletonList(new Variable("s"));
+ List<Variable> selectList = Collections.singletonList(new Variable("s"));
Answer answer = session.query(new Query(
@@ -414,8 +406,8 @@
public void testBasicPropertyQuery() throws Exception {
Session session = database.newSession();
try {
- List selectList = Arrays.asList(new Variable[] { new Variable("s"), new Variable("fn") });
- List orderList = Arrays.asList(new Order[] {
+ List<Variable> selectList = Arrays.asList(new Variable[] { new Variable("s"), new Variable("fn") });
+ List<Order> orderList = Arrays.asList(new Order[] {
new Order(new Variable("s"), true),
new Order(new Variable("fn"), true)
});
@@ -458,8 +450,8 @@
public void testBoundPropertyQuery() throws Exception {
Session session = database.newSession();
try {
- List selectList = Arrays.asList(new Variable[] { new Variable("s") });
- List orderList = Arrays.asList(new Order[] {
+ List<Variable> selectList = Arrays.asList(new Variable[] { new Variable("s") });
+ List<Order> orderList = Arrays.asList(new Order[] {
new Order(new Variable("s"), true),
});
@@ -499,8 +491,8 @@
public void testBoundSubjectQuery() throws Exception {
Session session = database.newSession();
try {
- List selectList = Arrays.asList(new Variable[] { new Variable("o") });
- List orderList = Arrays.asList(new Order[] {
+ List<Variable> selectList = Arrays.asList(new Variable[] { new Variable("o") });
+ List<Order> orderList = Arrays.asList(new Order[] {
new Order(new Variable("o"), true),
});
@@ -540,8 +532,8 @@
public void testConjPropertyQuery() throws Exception {
Session session = database.newSession();
try {
- List selectList = Arrays.asList(new Variable[] { new Variable("s"), new Variable("fn") });
- List orderList = Arrays.asList(new Order[] {
+ List<Variable> selectList = Arrays.asList(new Variable[] { new Variable("s"), new Variable("fn") });
+ List<Order> orderList = Arrays.asList(new Order[] {
new Order(new Variable("s"), true),
new Order(new Variable("fn"), true)
});
@@ -590,7 +582,7 @@
public void testURIPatternQuery() throws Exception {
Session session = database.newSession();
try {
- List selectList = Collections.singletonList(new Variable("s"));
+ List<Variable> selectList = Collections.singletonList(new Variable("s"));
Answer answer = session.query(new Query(
@@ -624,8 +616,8 @@
public void testURIPatternPropertyQuery() throws Exception {
Session session = database.newSession();
try {
- List selectList = Arrays.asList(new Variable[] { new Variable("s"), new Variable("loc") });
- List orderList = Arrays.asList(new Order[] {
+ List<Variable> selectList = Arrays.asList(new Variable[] { new Variable("s"), new Variable("loc") });
+ List<Order> orderList = Arrays.asList(new Order[] {
new Order(new Variable("s"), true),
new Order(new Variable("loc"), true)
});
@@ -668,8 +660,8 @@
public void testBasicPredicateQuery() throws Exception {
Session session = database.newSession();
try {
- List selectList = Arrays.asList(new Variable[] { new Variable("s"), new Variable("p") });
- List orderList = Arrays.asList(new Order[] {
+ List<Variable> selectList = Arrays.asList(new Variable[] { new Variable("s"), new Variable("p") });
+ List<Order> orderList = Arrays.asList(new Order[] {
new Order(new Variable("s"), true),
new Order(new Variable("p"), true)
});
@@ -709,8 +701,8 @@
public void testBasicPredicateObjectQuery() throws Exception {
Session session = database.newSession();
try {
- List selectList = Arrays.asList(new Variable[] { new Variable("s"), new Variable("p"), new Variable("o") });
- List orderList = Arrays.asList(new Order[] {
+ List<Variable> selectList = Arrays.asList(new Variable[] { new Variable("s"), new Variable("p"), new Variable("o") });
+ List<Order> orderList = Arrays.asList(new Order[] {
new Order(new Variable("s"), true),
new Order(new Variable("p"), true),
new Order(new Variable("o"), true)
@@ -788,8 +780,8 @@
public void testCompoundPredicateVoidQuery() throws Exception {
Session session = database.newSession();
try {
- List selectList = Arrays.asList(new Variable[] { new Variable("s"), new Variable("p"), new Variable("q") });
- List orderList = Arrays.asList(new Order[] {
+ List<Variable> selectList = Arrays.asList(new Variable[] { new Variable("s"), new Variable("p"), new Variable("q") });
+ List<Order> orderList = Arrays.asList(new Order[] {
new Order(new Variable("s"), true),
new Order(new Variable("p"), true),
new Order(new Variable("q"), true)
@@ -833,8 +825,8 @@
public void testCompoundPredicateQuery() throws Exception {
Session session = database.newSession();
try {
- List selectList = Arrays.asList(new Variable[] { new Variable("s"), new Variable("p"), new Variable("q") });
- List orderList = Arrays.asList(new Order[] {
+ List<Variable> selectList = Arrays.asList(new Variable[] { new Variable("s"), new Variable("p"), new Variable("q") });
+ List<Order> orderList = Arrays.asList(new Order[] {
new Order(new Variable("s"), true),
new Order(new Variable("p"), true),
new Order(new Variable("q"), true)
@@ -882,8 +874,8 @@
public void testCompoundPredicateObjectQuery() throws Exception {
Session session = database.newSession();
try {
- List selectList = Arrays.asList(new Variable[] { new Variable("s"), new Variable("p"), new Variable("o") });
- List orderList = Arrays.asList(new Order[] {
+ List<Variable> selectList = Arrays.asList(new Variable[] { new Variable("s"), new Variable("p"), new Variable("o") });
+ List<Order> orderList = Arrays.asList(new Order[] {
new Order(new Variable("s"), true),
new Order(new Variable("p"), true),
new Order(new Variable("o"), true)
@@ -947,8 +939,8 @@
public void testBasicPatternPropertyQuery() throws Exception {
Session session = database.newSession();
try {
- List selectList = Arrays.asList(new Variable[] { new Variable("s"), new Variable("title") });
- List orderList = Arrays.asList(new Order[] {
+ List<Variable> selectList = Arrays.asList(new Variable[] { new Variable("s"), new Variable("title") });
+ List<Order> orderList = Arrays.asList(new Order[] {
new Order(new Variable("s"), true),
new Order(new Variable("title"), true)
});
@@ -994,8 +986,8 @@
public void testBoundPatternPropertyQuery() throws Exception {
Session session = database.newSession();
try {
- List selectList = Arrays.asList(new Variable[] { new Variable("s") });
- List orderList = Arrays.asList(new Order[] {
+ List<Variable> selectList = Arrays.asList(new Variable[] { new Variable("s") });
+ List<Order> orderList = Arrays.asList(new Order[] {
new Order(new Variable("s"), true),
});
@@ -1035,8 +1027,8 @@
public void testBoundPatternSubjectQuery() throws Exception {
Session session = database.newSession();
try {
- List selectList = Arrays.asList(new Variable[] { new Variable("o") });
- List orderList = Arrays.asList(new Order[] {
+ List<Variable> selectList = Arrays.asList(new Variable[] { new Variable("o") });
+ List<Order> orderList = Arrays.asList(new Order[] {
new Order(new Variable("o"), true),
});
@@ -1077,8 +1069,8 @@
public void testBasicReferWithJoinQuery() throws Exception {
Session session = database.newSession();
try {
- List selectList = Arrays.asList(new Variable[] { new Variable("name"), new Variable("abstract") });
- List orderList = Arrays.asList(new Order[] {
+ List<Variable> selectList = Arrays.asList(new Variable[] { new Variable("name"), new Variable("abstract") });
+ List<Order> orderList = Arrays.asList(new Order[] {
new Order(new Variable("name"), true),
new Order(new Variable("abstract"), true),
});
@@ -1137,12 +1129,12 @@
public void testBasicReferWithJoinQueryAndPropPattern() throws Exception {
Session session = database.newSession();
try {
- List selectList = Arrays.asList(new Variable[] {
+ List<Variable> selectList = Arrays.asList(new Variable[] {
new Variable("name"),
new Variable("abstract"),
new Variable("title"),
});
- List orderList = Arrays.asList(new Order[] {
+ List<Order> orderList = Arrays.asList(new Order[] {
new Order(new Variable("name"), true),
new Order(new Variable("abstract"), true),
new Order(new Variable("title"), true),
@@ -1209,11 +1201,11 @@
public void testBasicReferWithPropPattern() throws Exception {
Session session = database.newSession();
try {
- List selectList = Arrays.asList(new Variable[] {
+ List<Variable> selectList = Arrays.asList(new Variable[] {
new Variable("abstract"),
new Variable("title"),
});
- List orderList = Arrays.asList(new Order[] {
+ List<Order> orderList = Arrays.asList(new Order[] {
new Order(new Variable("abstract"), true),
new Order(new Variable("title"), true),
});
@@ -1264,8 +1256,8 @@
public void testObjectReferWithMNJoin() throws Exception {
Session session = database.newSession();
try {
- List selectList = Arrays.asList(new Variable[] { new Variable("title"), new Variable("author") });
- List orderList = Arrays.asList(new Order[] {
+ List<Variable> selectList = Arrays.asList(new Variable[] { new Variable("title"), new Variable("author") });
+ List<Order> orderList = Arrays.asList(new Order[] {
new Order(new Variable("title"), true),
new Order(new Variable("author"), true),
});
@@ -1327,8 +1319,8 @@
public void testObjectReferWithPK() throws Exception {
Session session = database.newSession();
try {
- List selectList = Arrays.asList(new Variable[] { new Variable("author"), new Variable("paper") });
- List orderList = Arrays.asList(new Order[] {
+ List<Variable> selectList = Arrays.asList(new Variable[] { new Variable("author"), new Variable("paper") });
+ List<Order> orderList = Arrays.asList(new Order[] {
new Order(new Variable("author"), true),
new Order(new Variable("paper"), true),
});
@@ -1382,8 +1374,8 @@
public void testBasicQueryWithAdditionalProperty() throws Exception {
Session session = database.newSession();
try {
- List selectList = Arrays.asList(new Variable[] { new Variable("title"), new Variable("seeAlso") });
- List orderList = Arrays.asList(new Order[] {
+ List<Variable> selectList = Arrays.asList(new Variable[] { new Variable("title"), new Variable("seeAlso") });
+ List<Order> orderList = Arrays.asList(new Order[] {
new Order(new Variable("title"), true),
new Order(new Variable("seeAlso"), true),
});
@@ -1451,8 +1443,8 @@
public void testDualDatabaseQuery() throws Exception {
Session session = database.newSession();
try {
- List selectList = Arrays.asList(new Variable[] { new Variable("s"), new Variable("loc") });
- List orderList = Arrays.asList(new Order[] {
+ List<Variable> selectList = Arrays.asList(new Variable[] { new Variable("s"), new Variable("loc") });
+ List<Order> orderList = Arrays.asList(new Order[] {
new Order(new Variable("s"), true),
new Order(new Variable("loc"), true)
});
Modified: trunk/src/jar/rules/java/org/mulgara/rules/DummyRuleLoader.java
===================================================================
--- trunk/src/jar/rules/java/org/mulgara/rules/DummyRuleLoader.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/rules/java/org/mulgara/rules/DummyRuleLoader.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -17,7 +17,6 @@
package org.mulgara.rules;
import java.net.URI;
-import java.rmi.RemoteException;
/**
* A dummy implementation of the rule loader.
@@ -36,7 +35,7 @@
*
* @return Nothing.
*/
- public Rules readRules(Object session, URI systemModel) throws InitializerException {
+ public Rules readRules(Object session) throws InitializerException {
throw new InitializerException("No rule loader available.");
}
Modified: trunk/src/jar/rules/java/org/mulgara/rules/RuleLoader.java
===================================================================
--- trunk/src/jar/rules/java/org/mulgara/rules/RuleLoader.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/rules/java/org/mulgara/rules/RuleLoader.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -16,7 +16,6 @@
package org.mulgara.rules;
-import java.net.URI;
import java.rmi.RemoteException;
/**
@@ -36,6 +35,6 @@
*
* @return A {@link org.mulgara.krule.RuleStructure} containing all the loaded rules.
*/
- public Rules readRules(Object session, URI systemModel) throws InitializerException, RemoteException;
+ public Rules readRules(Object session) throws InitializerException, RemoteException;
}
Modified: trunk/src/jar/rules/java/org/mulgara/rules/RuleLoaderFactory.java
===================================================================
--- trunk/src/jar/rules/java/org/mulgara/rules/RuleLoaderFactory.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/rules/java/org/mulgara/rules/RuleLoaderFactory.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -47,20 +47,15 @@
* @param target the destination for rule consequences.
* @return the constructed {@link RuleLoader}
*/
- public static RuleLoader newRuleLoader(String className, URI source, URI base, URI target)
- throws InitializerException
- {
- if (logger.isDebugEnabled()) {
- logger.debug("Creating rule loader " + className);
- }
+ public static RuleLoader newRuleLoader(String className, URI source, URI base, URI target) throws InitializerException {
+ if (logger.isDebugEnabled()) logger.debug("Creating rule loader " + className);
+
// Validate parameters
- if (className == null) {
- throw new IllegalArgumentException("Null 'className' parameter");
- }
+ if (className == null) throw new IllegalArgumentException("Null 'className' parameter");
try {
- Class ruleLoaderClass = Class.forName(className);
+ Class<?> ruleLoaderClass = Class.forName(className);
// Validate that the candidate supports the RuleLoader interface
if (!RuleLoader.class.isAssignableFrom(ruleLoaderClass)) {
@@ -80,8 +75,8 @@
newInstanceMethod.invoke(null, new Object[] { source, base, target });
return ruleLoader;
- }
- catch (Exception e) {
+
+ } catch (Exception e) {
logger.warn("Error generating rule loader factory", e);
throw new InitializerException("Unable to add rule loader factory", e);
}
Modified: trunk/src/jar/rules/java/org/mulgara/rules/RulesRef.java
===================================================================
--- trunk/src/jar/rules/java/org/mulgara/rules/RulesRef.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/rules/java/org/mulgara/rules/RulesRef.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -16,8 +16,6 @@
package org.mulgara.rules;
-import java.net.URI;
-import java.io.Serializable;
import java.rmi.Remote;
import java.rmi.RemoteException;
Modified: trunk/src/jar/store-stringpool-xa11/java/org/mulgara/store/stringpool/xa11/XA11StringPoolLoadTest.java
===================================================================
--- trunk/src/jar/store-stringpool-xa11/java/org/mulgara/store/stringpool/xa11/XA11StringPoolLoadTest.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/store-stringpool-xa11/java/org/mulgara/store/stringpool/xa11/XA11StringPoolLoadTest.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -29,7 +29,7 @@
import org.mulgara.util.TempDir;
/**
- * Test case for {@link XAStringPoolImpl}.
+ * Test case for {@link XA11StringPoolImpl}.
*
* @created 2008-08-20
*
Modified: trunk/src/jar/util/java/org/mulgara/util/functional/C.java
===================================================================
--- trunk/src/jar/util/java/org/mulgara/util/functional/C.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/util/java/org/mulgara/util/functional/C.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -20,6 +20,7 @@
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
+import java.util.ListIterator;
import java.util.NoSuchElementException;
/**
@@ -48,7 +49,7 @@
* @return A list whose elements are the result of applying op to each element of args.
* @throws E An exception that may be thrown from the {@link Fn1E#fn(Object)} method.
*/
- public static <T1,T2,E extends Exception> List<T2> map(Collection<T1> args, Fn1E<T1,T2,E> op) throws E {
+ public static final <T1,T2,E extends Exception> List<T2> map(Collection<T1> args, Fn1E<T1,T2,E> op) throws E {
List<T2> result = new LinkedList<T2>();
for (T1 a: args) result.add(op.fn(a));
return result;
@@ -57,7 +58,7 @@
/**
* The same method as {@link #map(Collection, Fn1E)} for arrays.
*/
- public static <T1,T2,E extends Exception> List<T2> map(T1[] args, Fn1E<T1,T2,E> op) throws E {
+ public static final <T1,T2,E extends Exception> List<T2> map(T1[] args, Fn1E<T1,T2,E> op) throws E {
List<T2> result = new ArrayList<T2>(args.length);
for (T1 a: args) result.add(op.fn(a));
return result;
@@ -76,14 +77,14 @@
* @param op The operation to apply to the elements of the input list.
* @return A list whose elements are the result of applying op to each element of args.
*/
- public static <T1,T2> List<T2> map(Collection<T1> args, Fn1<T1,T2> op) {
+ public static final <T1,T2> List<T2> map(Collection<T1> args, Fn1<T1,T2> op) {
return map(args, (Fn1E<T1,T2,RuntimeException>)op);
}
/**
* The same method as {@link #map(Collection, Fn1)} for arrays.
*/
- public static <T1,T2> List<T2> map(T1[] args, Fn1<T1,T2> op) {
+ public static final <T1,T2> List<T2> map(T1[] args, Fn1<T1,T2> op) {
List<T2> result = new ArrayList<T2>(args.length);
for (T1 a: args) result.add(op.fn(a));
return result;
@@ -100,7 +101,7 @@
* @return The first element in the list.
* @throws NoSuchElementException If the list is empty.
*/
- public static <T1> T1 head(LinkedList<T1> arg) throws NoSuchElementException {
+ public static final <T1> T1 head(LinkedList<T1> arg) throws NoSuchElementException {
return arg.getFirst();
}
@@ -111,7 +112,7 @@
* @return The first element in the list.
* @throws NoSuchElementException If the list is empty.
*/
- public static <T1> T1 head(List<T1> arg) throws NoSuchElementException {
+ public static final <T1> T1 head(List<T1> arg) throws NoSuchElementException {
if (arg instanceof LinkedList) return ((LinkedList<T1>)arg).getFirst();
if (arg.size() == 0) throw new NoSuchElementException("Empty list");
return arg.get(0);
@@ -123,7 +124,7 @@
* @param arg The list.
* @return The first element in the list, or <code>null</code> if the list is empty.
*/
- public static <T1> T1 headN(LinkedList<T1> arg) {
+ public static final <T1> T1 headN(LinkedList<T1> arg) {
return arg.isEmpty() ? null : arg.getFirst();
}
@@ -133,7 +134,7 @@
* @param arg The list.
* @return The first element in the list, or <code>null</code> if the list is empty.
*/
- public static <T1> T1 headN(List<T1> arg) {
+ public static final <T1> T1 headN(List<T1> arg) {
return arg.isEmpty() ? null : (arg instanceof LinkedList) ? ((LinkedList<T1>)arg).getFirst() : arg.get(0);
}
@@ -144,7 +145,7 @@
* @return The last element in the list.
* @throws NoSuchElementException If the list is empty.
*/
- public static <T1> T1 tail(LinkedList<T1> arg) throws NoSuchElementException {
+ public static final <T1> T1 tail(LinkedList<T1> arg) throws NoSuchElementException {
return arg.getLast();
}
@@ -155,7 +156,7 @@
* @return The last element in the list.
* @throws IndexOutOfBoundsException If the list is empty.
*/
- public static <T1> T1 tail(List<T1> arg) throws NoSuchElementException {
+ public static final <T1> T1 tail(List<T1> arg) throws NoSuchElementException {
if (arg instanceof LinkedList) return ((LinkedList<T1>)arg).getLast();
if (arg.size() == 0) throw new NoSuchElementException("Empty list");
return arg.get(arg.size() - 1);
@@ -167,7 +168,7 @@
* @param arg The list.
* @return The last element in the list, or <code>null</code> if the list is empty.
*/
- public static <T1> T1 tailN(LinkedList<T1> arg) {
+ public static final <T1> T1 tailN(LinkedList<T1> arg) {
return arg.isEmpty() ? null : arg.getLast();
}
@@ -177,7 +178,7 @@
* @param arg The list.
* @return The last element in the list, or <code>null</code> if the list is empty.
*/
- public static <T1> T1 tailN(List<T1> arg) {
+ public static final <T1> T1 tailN(List<T1> arg) {
return arg.isEmpty() ? null : arg.get(arg.size() - 1);
}
@@ -188,7 +189,7 @@
* @return The first element in the list.
* @throws NoSuchElementException If the list is empty.
*/
- public static <T1> T1 first(LinkedList<T1> arg) throws NoSuchElementException {
+ public static final <T1> T1 first(LinkedList<T1> arg) throws NoSuchElementException {
return arg.getFirst();
}
@@ -199,10 +200,63 @@
* @return The first element in the collection.
* @throws NoSuchElementException If the collection is empty.
*/
- public static <T1> T1 first(Collection<T1> arg) throws NoSuchElementException {
+ public static final <T1> T1 first(Collection<T1> arg) throws NoSuchElementException {
if (arg instanceof LinkedList) return ((LinkedList<T1>)arg).getFirst();
if (arg.isEmpty()) throw new NoSuchElementException("Empty Collection");
return arg.iterator().next();
}
+ /**
+ * Inserts an element into a list in ascending order.
+ * @param <T> The type of the element to be inserted. Must be comparable on itself.
+ * @param list The list to insert into. This must already be ordered.
+ * @param c The element to insert.
+ * @return The newly modified list with all elements in ascending.
+ */
+ public static final <T extends Comparable<T>> List<T> ascendingInsert(List<T> list, T c) {
+ return orderedInsert(list, c, true);
+ }
+
+ /**
+ * Inserts an element into an ordered list in descending order.
+ * @param <T> The type of the element to be inserted. Must be comparable on itself.
+ * @param list The list to insert into. This must already be ordered.
+ * @param c The element to insert.
+ * @return The newly modified list, with all elements in descending order.
+ */
+ public static final <T extends Comparable<T>> List<T> descendingInsert(List<T> list, T c) {
+ return orderedInsert(list, c, false);
+ }
+
+ /**
+ * Inserts an element into an ordered list in a given order.
+ * @param <T> The type of the element to be inserted. Must be comparable on itself.
+ * @param list The list to insert into. This must already be ordered in the same order as this insert.
+ * @param c The element to insert.
+ * @return The newly modified list, with all elements in order.
+ */
+ private static final <T extends Comparable<T>> List<T> orderedInsert(List<T> list, T c, boolean smaller) {
+ ListIterator<T> i = list.listIterator();
+ while (i.hasNext()) {
+ if (orderTest(c.compareTo(i.next()), smaller)) {
+ i.previous();
+ break;
+ }
+ }
+ i.add(c);
+ return list;
+ }
+
+ /**
+ * Tests if a comparison value indicates that smaller or larger values.
+ * @param value The value returned from a comparison.
+ * @param smaller When <code>true</code> this returns true for a comparison indicating a
+ * smaller value was first, otherwise it tests if the comparison indicates
+ * a larger value first.
+ * @return <code>true</code> when the value is in the same direction as the smaller flag indicates.
+ */
+ private static final boolean orderTest(int value, boolean smaller) {
+ return smaller ? value < 0 : value > 0;
+ }
+
}
Modified: trunk/src/jar/util/java/org/mulgara/util/functional/Pair.java
===================================================================
--- trunk/src/jar/util/java/org/mulgara/util/functional/Pair.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/util/java/org/mulgara/util/functional/Pair.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -46,4 +46,6 @@
public static <C1,C2> Pair<C1,C2> p(C1 c1, C2 c2) { return new Pair<C1,C2>(c1, c2); }
public Map<T1,T2> addTo(Map<T1,T2> map) { map.put(first, second); return map; }
+
+ public String toString() { return "{" + first + "," + second + "}"; }
}
Modified: trunk/src/jar/web/java/org/mulgara/webquery/QueryServlet.java
===================================================================
--- trunk/src/jar/web/java/org/mulgara/webquery/QueryServlet.java 2009-03-24 01:12:37 UTC (rev 1625)
+++ trunk/src/jar/web/java/org/mulgara/webquery/QueryServlet.java 2009-03-24 18:42:49 UTC (rev 1626)
@@ -417,7 +417,6 @@
throw new RequestException("Invalid URI for upload graph. " + e.getInput());
}
}
- System.err.println("No graphs in the parameter values");
// look in the mime data
if (mime != null) {
try {
More information about the Mulgara-svn
mailing list