[Mulgara-svn] r1720 - in trunk: . src/jar src/jar/krule/java/org/mulgara/krule src/jar/query/java/org/mulgara/query/rdf src/jar/swrl src/jar/swrl/java src/jar/swrl/java/org src/jar/swrl/java/org/mulgara src/jar/swrl/java/org/mulgara/swrl

alexhall at mulgara.org alexhall at mulgara.org
Mon Jun 8 19:47:58 UTC 2009


Author: alexhall
Date: 2009-06-08 12:47:56 -0700 (Mon, 08 Jun 2009)
New Revision: 1720

Added:
   trunk/src/jar/query/java/org/mulgara/query/rdf/SWRL.java
   trunk/src/jar/swrl/
   trunk/src/jar/swrl/build.xml
   trunk/src/jar/swrl/java/
   trunk/src/jar/swrl/java/org/
   trunk/src/jar/swrl/java/org/mulgara/
   trunk/src/jar/swrl/java/org/mulgara/swrl/
   trunk/src/jar/swrl/java/org/mulgara/swrl/SWRLLoader.java
   trunk/src/jar/swrl/java/org/mulgara/swrl/SWRLStructureException.java
   trunk/src/jar/swrl/swrl-build.properties
Modified:
   trunk/.classpath
   trunk/build.xml
   trunk/src/jar/krule/java/org/mulgara/krule/QueryStruct.java
   trunk/src/jar/krule/java/org/mulgara/krule/RuleStructure.java
Log:
Initial implementation of a rule loader for SWRL rules.  This is only a basic parser with enough functionality to load and execute simple SWRL examples.  Future improvements include adding support for builtins; adding a test suite; and modifying the RuleLoader interface to allow for multiple rule loaders to be configured in the system.

Modified: trunk/.classpath
===================================================================
--- trunk/.classpath	2009-06-05 04:04:36 UTC (rev 1719)
+++ trunk/.classpath	2009-06-08 19:47:56 UTC (rev 1720)
@@ -50,6 +50,7 @@
 	<classpathentry kind="src" path="src/jar/store-stringpool-xa/java"/>
 	<classpathentry kind="src" path="src/jar/store-stringpool-xa11/java"/>
 	<classpathentry kind="src" path="src/jar/store-xa/java"/>
+	<classpathentry kind="src" path="src/jar/swrl/java"/>
 	<classpathentry kind="src" path="src/jar/tag/java"/>
 	<classpathentry kind="src" path="src/jar/tuples/java"/>
 	<classpathentry kind="src" path="src/jar/tuples-hybrid/java"/>

Modified: trunk/build.xml
===================================================================
--- trunk/build.xml	2009-06-05 04:04:36 UTC (rev 1719)
+++ trunk/build.xml	2009-06-08 19:47:56 UTC (rev 1720)
@@ -61,6 +61,7 @@
   <property file="${jar.src.dir}/store-stringpool-memory/store-stringpool-memory-build.properties"/>
   <property file="${jar.src.dir}/store-stringpool-xa/store-stringpool-xa-build.properties"/>
   <property file="${jar.src.dir}/store-stringpool-xa11/store-stringpool-xa11-build.properties"/>
+  <property file="${jar.src.dir}/swrl/swrl-build.properties"/>
   <property file="${jar.src.dir}/tag/tag-build.properties"/>
   <property file="${jar.src.dir}/tuples-hybrid/tuples-hybrid-build.properties"/>
   <property file="${jar.src.dir}/tuples/tuples-build.properties"/>
@@ -124,6 +125,7 @@
   <import file="${jar.src.dir}/store-stringpool-memory/build.xml"/>
   <import file="${jar.src.dir}/store-stringpool-xa/build.xml"/>
   <import file="${jar.src.dir}/store-stringpool-xa11/build.xml"/>
+  <import file="${jar.src.dir}/swrl/build.xml"/>
   <import file="${jar.src.dir}/tag/build.xml"/>
   <import file="${jar.src.dir}/tuples-hybrid/build.xml"/>
   <import file="${jar.src.dir}/tuples/build.xml"/>
@@ -306,7 +308,7 @@
                    server-rmi-dist, krule-dist,
                    store-stringpool-dist, store-stringpool-memory-dist,
                    store-stringpool-xa-dist,
-                   store-stringpool-xa11-dist, tag-dist,
+                   store-stringpool-xa11-dist, swrl-dist, tag-dist,
                    tuples-dist, tuples-hybrid-dist,
                    util-dist, util-xa-dist, web-dist"
           description="Creates the distribution base jars">
@@ -745,7 +747,7 @@
              server-jar, server-rmi-jar,
              krule-jar,
              store-stringpool-jar,
-             store-stringpool-memory-jar, store-stringpool-xa-jar, store-stringpool-xa11-jar,
+             store-stringpool-memory-jar, store-stringpool-xa-jar, store-stringpool-xa11-jar, swrl-jar,
              tuples-jar, tuples-hybrid-jar, util-jar, util-xa-jar, web-jar"
     unless="javadoc.uptodate"
     description="Creates the project javadoc">
@@ -784,6 +786,7 @@
                       org.mulgara.store.stringpool.xa.*,
                       org.mulgara.store.tuples.*,
                       org.mulgara.store.xa.*,
+                      org.mulgara.swrl.*,
                       org.mulgara.webquery.*,
                       org.mulgara.util,
                       org.mulgara.xml.*"
@@ -863,6 +866,7 @@
       <sourcepath path="${store-stringpool-memory.src.dir}/java"/>
       <sourcepath path="${store-stringpool-xa.src.dir}/java"/>
       <sourcepath path="${store-stringpool-xa11.src.dir}/java"/>
+      <sourcepath path="${swrl.src.dir}/java"/>
       <sourcepath path="${tuples.src.dir}/java"/>
       <sourcepath path="${tuples-hybrid.src.dir}/java"/>
       <sourcepath path="${util.src.dir}/java"/>
@@ -911,7 +915,7 @@
                    krule-javadoc,
                    store-stringpool-javadoc,
                    store-stringpool-memory-javadoc, store-stringpool-xa-javadoc,
-                   store-stringpool-xa11-javadoc,
+                   store-stringpool-xa11-javadoc, swrl-javadoc,
                    tag-javadoc, tuples-hybrid-javadoc, tuples-javadoc,
                    util-xa-javadoc, util-javadoc"
       unless="javadoc.uptodate"
@@ -1637,6 +1641,7 @@
              store-stringpool-memory-jar,
              store-stringpool-xa-jar,
              store-stringpool-xa11-jar,
+             swrl-jar,
              tuples-jar,
              tuples-hybrid-jar,
              util-jar,
@@ -1755,6 +1760,7 @@
       <zipfileset src="${bin.dir}/${dtd.jar}" excludes="META-INF/**"/>
       <zipfileset src="${bin.dir}/${jrdf.base.jar}" excludes="META-INF/**"/>
       <zipfileset src="${bin.dir}/${krule.jar}" excludes="META-INF/**"/>
+      <zipfileset src="${bin.dir}/${swrl.jar}" excludes="META-INF/**"/>
       <zipfileset src="${bin.dir}/${web.jar}" excludes="META-INF/**"/>
 
 
@@ -1830,6 +1836,7 @@
              store-stringpool-memory-jar,
              store-stringpool-xa-jar,
              store-stringpool-xa11-jar,
+             swrl-jar,
              tuples-jar,
              tuples-hybrid-jar,
              util-jar,
@@ -1893,6 +1900,7 @@
       <zipfileset src="${bin.dir}/${dtd.jar}" excludes="META-INF/**"/>
       <zipfileset src="${bin.dir}/${jrdf.base.jar}" excludes="META-INF/**"/>
       <zipfileset src="${bin.dir}/${krule.jar}" excludes="META-INF/**"/>
+      <zipfileset src="${bin.dir}/${swrl.jar}" excludes="META-INF/**"/>
       <zipfileset src="${bin.dir}/${web.jar}" excludes="META-INF/**"/>
 
 
@@ -1957,6 +1965,7 @@
              store-stringpool-memory-jar,
              store-stringpool-xa-jar,
              store-stringpool-xa11-jar,
+             swrl-jar,
              tuples-jar,
              tuples-hybrid-jar,
              util-jar,
@@ -2016,6 +2025,7 @@
       <zipfileset src="${bin.dir}/${dtd.jar}" excludes="**/*.xml, META-INF/**"/>
       <zipfileset src="${bin.dir}/${jrdf.base.jar}" excludes="**/*.xml, META-INF/**"/>
       <zipfileset src="${bin.dir}/${krule.jar}" excludes="**/*.xml, META-INF/**"/>
+      <zipfileset src="${bin.dir}/${swrl.jar}" excludes="**/*.xml, META-INF/**"/>
 
       <!-- Schemas -->
       <fileset dir="${src.dir}/jar/dtd" includes="DTD/**"/>
@@ -2086,6 +2096,7 @@
              store-stringpool-memory-jar,
              store-stringpool-xa-jar,
              store-stringpool-xa11-jar,
+             swrl-jar,
              tuples-jar,
              tuples-hybrid-jar,
              util-jar,
@@ -2189,6 +2200,7 @@
       <zipfileset src="${bin.dir}/${dtd.jar}" excludes="META-INF/**"/>
       <zipfileset src="${bin.dir}/${jrdf.base.jar}" excludes="META-INF/**"/>
       <zipfileset src="${bin.dir}/${krule.jar}" excludes="META-INF/**"/>
+      <zipfileset src="${bin.dir}/${swrl.jar}" excludes="META-INF/**"/>
       <zipfileset src="${bin.dir}/${web.jar}" excludes="META-INF/**"/>
 
 
@@ -2277,7 +2289,7 @@
   </target>
 
   <target name="utils-test"
-    depends="ant-task-test, dtd-test, krule-test, tag-test, util-test, util-xa-test"
+    depends="ant-task-test, dtd-test, krule-test, swrl-test, tag-test, util-test, util-xa-test"
     description="Runs miscellaneous utility tests">
   </target>
 

Modified: trunk/src/jar/krule/java/org/mulgara/krule/QueryStruct.java
===================================================================
--- trunk/src/jar/krule/java/org/mulgara/krule/QueryStruct.java	2009-06-05 04:04:36 UTC (rev 1719)
+++ trunk/src/jar/krule/java/org/mulgara/krule/QueryStruct.java	2009-06-08 19:47:56 UTC (rev 1720)
@@ -62,20 +62,17 @@
   /** Logger.  */
   private static Logger logger = Logger.getLogger(QueryStruct.class.getName());
 
-  /** The selection list. */
-  private ConstraintElement[] select;
-
   /** List of elements which are variables, or ConstantValues. */
-  private List<SelectElement> variables;
+  private List<SelectElement> variables = null;
 
   /** The graph expresison for the query. */
-  private GraphExpression graphs;
+  private GraphExpression graphs = null;
 
   /** The where clause of the query. */
-  private ConstraintExpression where;
+  private ConstraintExpression where = null;
 
   /** The having clause for the query. */
-  private ConstraintHaving having;
+  private ConstraintHaving having = null;
 
 
   /**
@@ -109,10 +106,10 @@
 
     // 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 < vs.length; i++) {
+      ConstraintElement select = null;
       URIReference element = vs[i];
       // check the type
       if (types[i].equals(Krule.URI_REF)) {
@@ -121,15 +118,15 @@
         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);
+        select = (URIReferenceImpl)uriReferences.get(element);
         // assume that literals do not have the "Value" type inferred
-        variables.add(new ConstantValue(variableFactory.newVariable(), (URIReferenceImpl)select[i]));
+        variables.add(new ConstantValue(variableFactory.newVariable(), (URIReferenceImpl)select));
 
       } else if (types[i].equals(Krule.VARIABLE)) {
 
         // get the variable
-        select[i] = (Variable)varReferences.get(element);
-        variables.add((Variable)select[i]);
+        select = (Variable)varReferences.get(element);
+        variables.add((Variable)select);
 
       } else if (types[i].equals(Krule.LITERAL)) {
         
@@ -141,20 +138,41 @@
         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]));
+        select = (LiteralImpl)litReferences.get(element);
+        variables.add(new ConstantValue(variableFactory.newVariable(), (LiteralImpl)select));
       } else {
         throw new IllegalArgumentException("Unknown selection type in rule query.");
       }
 
-      if (select[i] == null) {
+      if (select == null) {
         throw new IllegalArgumentException("Unable to resolve a reference for: " + element);
       }
     }
-
-    graphs = null;
-    having = null;
   }
+  
+  /**
+   * Construct a query structure with a known list of select elements.
+   * @param vars The select elements for this query.
+   */
+  public QueryStruct(List<SelectElement> vars) {
+    if (vars.size() <= 0) throw new IllegalArgumentException("Wrong number of elements for a rule query");
+    this.variables = new ArrayList<SelectElement>(vars);
+    
+    // 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 = variables.size() % 3 != 0;
+    
+    // Validate the select elements.
+    for (int i = 0; i < variables.size(); i++) {
+      SelectElement var = variables.get(i);
+      if (varsOnly && !(var instanceof Variable)) {
+        throw new IllegalArgumentException("Wrong number of elements for a rule query: " + variables.size());
+      }
+      if ((var instanceof ConstantValue) && (((ConstantValue)var).getValue() instanceof Literal) && i % 3 != 2) {
+        throw new IllegalArgumentException("Selection literal in illegal position in query");
+      }
+    }
+  }
 
 
   /**
@@ -162,24 +180,11 @@
    * @return The number of selection elements from the query.
    */
   public int elementCount() {
-    return select.length;
+    return variables.size();
   }
 
 
   /**
-   * Retrieve the element <em>n</em>.
-   *
-   * @param n The element number to retrieve.
-   * @return The <em>n</em>th element.
-   * @throws IndexOutOfBoundsException If n is larger than 3.
-   */
-  public ConstraintElement getElement(int n) {
-    assert n < select.length;
-    return select[n];
-  }
-
-
-  /**
    * Sets the where clause for the query.
    *
    * @param constraints The constraint expression defining the where clause.

Modified: trunk/src/jar/krule/java/org/mulgara/krule/RuleStructure.java
===================================================================
--- trunk/src/jar/krule/java/org/mulgara/krule/RuleStructure.java	2009-06-05 04:04:36 UTC (rev 1719)
+++ trunk/src/jar/krule/java/org/mulgara/krule/RuleStructure.java	2009-06-08 19:47:56 UTC (rev 1720)
@@ -135,6 +135,17 @@
   public void setAxioms(Set<org.jrdf.graph.Triple> axioms) {
     this.axioms = axioms;
   }
+  
+  
+  /**
+   * Adds a single axiom to these rules.
+   * 
+   * @param axiom A triple comprising an axiomatic statement.
+   */
+  public void addAxiom(org.jrdf.graph.Triple axiom) {
+    if (axioms == null) axioms = new HashSet<org.jrdf.graph.Triple>();
+    axioms.add(axiom);
+  }
 
 
   /**

Added: trunk/src/jar/query/java/org/mulgara/query/rdf/SWRL.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/rdf/SWRL.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/rdf/SWRL.java	2009-06-08 19:47:56 UTC (rev 1720)
@@ -0,0 +1,137 @@
+/*
+ * 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.query.rdf;
+
+import java.net.URI;
+
+/**
+ * URI constants for SWRL rules.
+ * 
+ * @created Jun 4, 2009
+ * @author Alex Hall
+ * @copyright &copy; 2009 <a href="http://www.revelytix.com">Revelytix, Inc.</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class SWRL {
+
+  /** URI for the SWRL namespace. */
+  public static final String SWRL = "http://www.w3.org/2003/11/swrl#";
+  
+  /** URI for a variable reference. */
+  public static final String VARIABLE_STR = SWRL + "Variable";
+  
+  /** URI for an implication (i.e. rule) */
+  public static final String IMP_STR = SWRL + "Imp";
+  
+  /** URI for a rule head. */
+  public static final String HEAD_STR = SWRL + "head";
+  
+  /** URI for a rule body. */
+  public static final String BODY_STR = SWRL + "body";
+  
+  /** URI for a class membership atom. */
+  public static final String CLASS_ATOM_STR = SWRL + "ClassAtom";
+  
+  /** URI for an individual-valued property atom. */
+  public static final String INDIVIDUAL_ATOM_STR = SWRL + "IndividualPropertyAtom";
+  
+  /** URI for a datatype-valued property atom. */
+  public static final String DATA_ATOM_STR = SWRL + "DatavaluedPropertyAtom";
+  
+  /** URI for an individual identity atom. */
+  public static final String SAME_INDIVIDUALS_ATOM_STR = SWRL + "SameIndividualsAtom";
+  
+  /** URI for an individual difference atom. */
+  public static final String DIFFERENT_INDIVIDUALS_ATOM_STR = SWRL + "DifferentIndividualsAtom";
+  
+  /** URI for a builtin atom. */
+  public static final String BUILTIN_ATOM_STR = SWRL + "BuiltinAtom";
+  
+  /** URI for a data range atom. */
+  public static final String DATA_RANGE_ATOM_STR = SWRL + "DataRangeAtom";
+  
+  /** URI for a class atom predicate. */
+  public static final String CLASS_PREDICATE_STR = SWRL + "classPredicate";
+  
+  /** URI for an individual or datatype property atom predicate. */
+  public static final String PROPERTY_PREDICATE_STR = SWRL + "propertyPredicate";
+  
+  /** URI for a builtin atom operator. */
+  public static final String BUILTIN_STR = SWRL + "builtin";
+  
+  /** URI for a data range atom predicate. */
+  public static final String DATA_RANGE_STR = SWRL + "dataRange";
+  
+  /** URI to identify the first argument to an atom. */
+  public static final String ARG_1_STR = SWRL + "argument1";
+  
+  /** URI to identify the second argument to an atom. */
+  public static final String ARG_2_STR = SWRL + "argument2";
+  
+  /** URI to identify the argument list for a builtin atom. */
+  public static final String ARGS_STR = SWRL + "arguments";
+  
+  /** URI reference for a variable reference. */
+  public static final URIReferenceImpl VARIABLE = new URIReferenceImpl(URI.create(VARIABLE_STR));
+  
+  /** URI reference for an implication (i.e. rule) */
+  public static final URIReferenceImpl IMP = new URIReferenceImpl(URI.create(IMP_STR));
+  
+  /** URI reference for a rule head. */
+  public static final URIReferenceImpl HEAD = new URIReferenceImpl(URI.create(HEAD_STR));
+  
+  /** URI reference for a rule body. */
+  public static final URIReferenceImpl BODY = new URIReferenceImpl(URI.create(BODY_STR));
+  
+  /** URI reference for a class membership atom. */
+  public static final URIReferenceImpl CLASS_ATOM = new URIReferenceImpl(URI.create(CLASS_ATOM_STR));
+  
+  /** URI reference for an individual-valued property atom. */
+  public static final URIReferenceImpl INDIVIDUAL_ATOM = new URIReferenceImpl(URI.create(INDIVIDUAL_ATOM_STR));
+  
+  /** URI reference for a datatype-valued property atom. */
+  public static final URIReferenceImpl DATA_ATOM = new URIReferenceImpl(URI.create(DATA_ATOM_STR));
+  
+  /** URI reference for an individual identity atom. */
+  public static final URIReferenceImpl SAME_INDIVIDUALS_ATOM = new URIReferenceImpl(URI.create(SAME_INDIVIDUALS_ATOM_STR));
+  
+  /** URI reference for an individual difference atom. */
+  public static final URIReferenceImpl DIFFERENT_INDIVIDUALS_ATOM = new URIReferenceImpl(URI.create(DIFFERENT_INDIVIDUALS_ATOM_STR));
+  
+  /** URI reference for a builtin atom. */
+  public static final URIReferenceImpl BUILTIN_ATOM = new URIReferenceImpl(URI.create(BUILTIN_ATOM_STR));
+  
+  /** URI reference for a data range atom. */
+  public static final URIReferenceImpl DATA_RANGE_ATOM = new URIReferenceImpl(URI.create(DATA_RANGE_ATOM_STR));
+  
+  /** URI reference for a class atom predicate. */
+  public static final URIReferenceImpl CLASS_PREDICATE = new URIReferenceImpl(URI.create(CLASS_PREDICATE_STR));
+  
+  /** URI reference for an individual or datatype property atom predicate. */
+  public static final URIReferenceImpl PROPERTY_PREDICATE = new URIReferenceImpl(URI.create(PROPERTY_PREDICATE_STR));
+  
+  /** URI reference for a builtin atom operator. */
+  public static final URIReferenceImpl BUILTIN = new URIReferenceImpl(URI.create(BUILTIN_STR));
+  
+  /** URI reference for a data range atom predicate. */
+  public static final URIReferenceImpl DATA_RANGE = new URIReferenceImpl(URI.create(DATA_RANGE_STR));
+  
+  /** URI reference to identify the first argument to an atom. */
+  public static final URIReferenceImpl ARG_1 = new URIReferenceImpl(URI.create(ARG_1_STR));
+  
+  /** URI reference to identify the second argument to an atom. */
+  public static final URIReferenceImpl ARG_2 = new URIReferenceImpl(URI.create(ARG_2_STR));
+  
+  /** URI reference to identify the argument list for a builtin atom. */
+  public static final URIReferenceImpl ARGS = new URIReferenceImpl(URI.create(ARGS_STR));
+  
+}

Added: trunk/src/jar/swrl/build.xml
===================================================================
--- trunk/src/jar/swrl/build.xml	                        (rev 0)
+++ trunk/src/jar/swrl/build.xml	2009-06-08 19:47:56 UTC (rev 1720)
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE project>
+
+<!-- =================================================================== -->
+<!--                       Project definition                            -->
+<!-- =================================================================== -->
+<project name="swrl" default="swrl.jar" basedir="../../..">
+
+  <!-- =================================================================== -->
+  <!--                      Property Definitions                           -->
+  <!-- =================================================================== -->
+
+  <!-- =================================================================== -->
+  <!--                              Imports                                -->
+  <!-- =================================================================== -->
+
+  <!-- =================================================================== -->
+  <!--                          Path Definitions                           -->
+  <!-- =================================================================== -->
+  <path id="swrl-classpath">
+
+    <path refid="common-classpath"/>
+
+    <pathelement path="${query.dist.dir}/${query.jar}"/>
+    <pathelement path="${driver.dist.dir}/${driver.jar}"/>
+    <pathelement path="${util.dist.dir}/${util.jar}"/>
+    <pathelement path="${querylang.dist.dir}/${querylang.jar}"/>
+    <pathelement path="${tuples.dist.dir}/${tuples.jar}"/>
+    <pathelement path="${resolver.dist.dir}/${resolver.jar}"/>
+    <pathelement path="${krule.dist.dir}/${krule.jar}"/>
+  </path>
+
+  <path id="swrl-test-classpath">
+
+    <path refid="swrl-classpath"/>
+
+    <fileset file="${swrl.dist.dir}/${swrl.jar}"/>
+  </path>
+
+  <target name="swrl-clean"
+          description="Removes all compile generated files for the swrl">
+
+    <tstamp/>
+
+    <delete dir="${swrl.obj.dir}"/>
+    <delete dir="${swrl.test.dir}"/>
+    <delete dir="${swrl.dist.dir}"/>
+  </target>
+
+  <target name="-swrl-prepare"
+          description="Creates all directories associated with the swrl's compilation"
+          depends="-prepare-build">
+
+    <mkdir dir="${swrl.obj.dir}"/>
+    <mkdir dir="${swrl.test.dir}"/>
+    <mkdir dir="${swrl.dist.dir}"/>
+    <mkdir dir="${swrl.obj.dir}/classes"/>
+  </target>
+
+  <target name="swrl-compile"
+          depends="-swrl-prepare, driver-jar, querylang-jar, tuples-jar, resolver-jar, krule-jar"
+          description="Compiles all swrl related files included generated source code">
+
+    <javac destdir="${swrl.obj.dir}/classes" debug="on"
+           deprecation="on" source="1.5">
+
+      <classpath refid="swrl-classpath"/>
+
+      <src path="${swrl.src.dir}/java"/>
+    </javac>
+  </target>
+
+  <target name="swrl-jar"
+    depends="swrl-compile, -swrl-jar-uptodate"
+    unless="swrl.jar.uptodate"
+    description="Builds the NodeType Resolver JAR">
+
+    <jar jarfile="${swrl.dist.dir}/${swrl.jar}">
+      <fileset dir="${swrl.obj.dir}/classes"/>
+    </jar>
+  </target>
+
+  <target name="-swrl-jar-uptodate">
+
+    <uptodate property="swrl.jar.uptodate"
+              targetfile="${swrl.dist.dir}/${swrl.jar}">
+      <srcfiles dir="${swrl.obj.dir}/classes" includes="**/*"/>
+    </uptodate>
+  </target>
+
+  <target name="swrl-dist"
+          depends="swrl-jar"
+          unless="swrl.uptodate"
+          description="Performs all tasks related to finalising this swrl and readying it for distribution">
+
+    <!-- All that's involved in the final version of the swrl library
+         is the jar so we don't need to do anything because the dependencies
+         take care of the work. -->
+  </target>
+
+  <target name="swrl-test"
+          depends="swrl-jar"
+          description="Carries out unit testing for this swrl">
+
+    <antcall target="component-test">
+
+      <param name="classpath.id" value="swrl-test-classpath"/>
+      <param name="dir" value="${swrl.src.dir}"/>
+      <param name="jar" value="${swrl.jar}"/>
+    </antcall>
+  </target>
+
+  <target name="swrl-javadoc"
+          depends="swrl-jar"
+          description="Creates the javadoc for this swrl">
+
+    <antcall target="javadoc">
+
+      <param name="javadoc.package" value="org.mulgara.swrl.*"/>
+      <param name="javadoc.classpath" value="swrl-classpath"/>
+      <param name="javadoc.sourcepath" value="${swrl.src.dir}/java"/>
+    </antcall>
+  </target>
+
+  <target name="swrl-help"
+          description="Displays the help information for this swrl">
+
+    <!-- This is similar to the main project's help except the information
+         is specific to this swrl -->
+
+    <echo message="Welcome to the build script for ${swrl.name}."/>
+    <echo message=""/>
+    <echo message="These targets can be invoked as follows:"/>
+    <echo message="  ./build.sh &lt;target&gt;"/>
+    <echo message=""/>
+
+    <java fork="false" classname="org.apache.tools.ant.Main"
+          newenvironment="false">
+
+      <jvmarg value="${arch.bits}"/>
+
+      <arg line="-buildfile ${swrl.src.dir}/build.xml -projecthelp"/>
+    </java>
+  </target>
+</project>

Added: trunk/src/jar/swrl/java/org/mulgara/swrl/SWRLLoader.java
===================================================================
--- trunk/src/jar/swrl/java/org/mulgara/swrl/SWRLLoader.java	                        (rev 0)
+++ trunk/src/jar/swrl/java/org/mulgara/swrl/SWRLLoader.java	2009-06-08 19:47:56 UTC (rev 1720)
@@ -0,0 +1,916 @@
+/*
+ * 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.swrl;
+
+import java.net.URI;
+import java.rmi.RemoteException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+import org.jrdf.graph.BlankNode;
+import org.jrdf.graph.Literal;
+import org.jrdf.graph.Node;
+import org.jrdf.graph.ObjectNode;
+import org.jrdf.graph.PredicateNode;
+import org.jrdf.graph.SubjectNode;
+import org.jrdf.graph.Triple;
+import org.jrdf.graph.URIReference;
+import org.jrdf.vocabulary.OWL;
+import org.jrdf.vocabulary.RDF;
+import org.mulgara.itql.VariableFactoryImpl;
+import org.mulgara.krule.ConsistencyCheck;
+import org.mulgara.krule.KruleStructureException;
+import org.mulgara.krule.QueryStruct;
+import org.mulgara.krule.Rule;
+import org.mulgara.krule.RuleStructure;
+import org.mulgara.query.Answer;
+import org.mulgara.query.ConstantValue;
+import org.mulgara.query.ConstraintConjunction;
+import org.mulgara.query.ConstraintDisjunction;
+import org.mulgara.query.ConstraintElement;
+import org.mulgara.query.ConstraintExpression;
+import org.mulgara.query.ConstraintFilter;
+import org.mulgara.query.ConstraintImpl;
+import org.mulgara.query.ConstraintIs;
+import org.mulgara.query.ConstraintOperation;
+import org.mulgara.query.GraphExpression;
+import org.mulgara.query.GraphResource;
+import org.mulgara.query.Order;
+import org.mulgara.query.Query;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.SelectElement;
+import org.mulgara.query.SingleTransitiveConstraint;
+import org.mulgara.query.TuplesException;
+import org.mulgara.query.UnconstrainedAnswer;
+import org.mulgara.query.Value;
+import org.mulgara.query.Variable;
+import org.mulgara.query.VariableFactory;
+import org.mulgara.query.filter.And;
+import org.mulgara.query.filter.Equals;
+import org.mulgara.query.filter.Filter;
+import org.mulgara.query.filter.RDFTerm;
+import org.mulgara.query.filter.value.DataTypeFn;
+import org.mulgara.query.filter.value.IRI;
+import org.mulgara.query.filter.value.TypedLiteral;
+import org.mulgara.query.filter.value.Var;
+import org.mulgara.query.rdf.LiteralImpl;
+import org.mulgara.query.rdf.SWRL;
+import org.mulgara.query.rdf.TripleImpl;
+import org.mulgara.query.rdf.URIReferenceImpl;
+import org.mulgara.query.rdf.VariableNodeImpl;
+import org.mulgara.resolver.OperationContext;
+import org.mulgara.rules.InitializerException;
+import org.mulgara.rules.RuleLoader;
+import org.mulgara.rules.Rules;
+import org.mulgara.util.functional.Pair;
+
+/**
+ * Implementation of a rule loader which parses rule definitions from an RDF
+ * graph according to the SWRL schema.
+ * 
+ * @created Jun 4, 2009
+ * @author Alex Hall
+ * @copyright &copy; 2009 <a href="http://www.revelytix.com">Revelytix, Inc.</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class SWRLLoader implements RuleLoader {
+  
+  private static final Logger logger = Logger.getLogger(SWRLLoader.class.getName());
+  
+  /** A field used in queries to indicate no prior constraints on the answer. */
+  private static final UnconstrainedAnswer UNCONSTRAINED = new UnconstrainedAnswer();
+
+  /** RDF reference for rdf:type. */
+  public static final URIReferenceImpl RDF_TYPE = new URIReferenceImpl(RDF.TYPE);
+  
+  /** The graph from which rule definitions are being read. */
+  private final GraphResource ruleGraph;
+  /** The graph expression containing the base statements. */
+  private final GraphExpression baseGraph;
+  /** The graph where entailed statements will be inserted. */
+  private final URI destGraph;
+  
+  /** The database session for querying. */
+  private OperationContext operationContext;
+  
+  /** Factory for creating unique variables in the rule queries. */
+  private VariableFactory varFactory = new VariableFactoryImpl();
+
+  /**
+   * Factory method.
+   * @param ruleGraph The graph URI that contains the SWRL rule definitions. 
+   * @param baseGraph The graph expression that contains the base statements.
+   * @param destGraph The graph URI that will receive the entailed statements.
+   * @return The rule loader which will process the rule definitions.
+   */
+  public static RuleLoader newInstance(URI ruleGraph, GraphExpression baseGraph, URI destGraph) {
+    return new SWRLLoader(ruleGraph, baseGraph, destGraph);
+  }
+  
+  /**
+   * Initialize the rule loader with the rule, base, and destination graphs.
+   * @param ruleGraph The graph containing the rules to load.
+   * @param baseGraph The graph expression containing the base statements.
+   * @param destGraph The destination graph for entailed statements.
+   */
+  SWRLLoader(URI ruleGraph, GraphExpression baseGraph, URI destGraph) {
+    this.ruleGraph = new GraphResource(ruleGraph);
+    this.baseGraph = baseGraph;
+    this.destGraph = destGraph;
+  }
+  
+  /* (non-Javadoc)
+   * @see org.mulgara.rules.RuleLoader#readRules(java.lang.Object)
+   */
+  @Override
+  public Rules readRules(Object session) throws InitializerException, RemoteException {
+    this.operationContext = (OperationContext)session;
+    
+    RuleStructure rules = new RuleStructure();
+    rules.setTargetModel(destGraph);
+    
+    try {
+      Map<URIReference,Variable> vars = findVariables();
+      if (logger.isDebugEnabled()) logger.debug("Found variables: " + vars);
+      
+      List<Node> ruleNodes = findRules();
+      if (logger.isDebugEnabled()) logger.debug("Found rules: " + ruleNodes);
+      
+      Map<Node,Pair<URI,ConstraintImpl>> constraintAtoms = new HashMap<Node,Pair<URI,ConstraintImpl>>();
+      Map<Node,Pair<URI,Filter>> filterAtoms = new HashMap<Node,Pair<URI,Filter>>();
+      findAtoms(constraintAtoms, filterAtoms, vars);
+      if (logger.isDebugEnabled()) {
+        logger.debug("Found constraint atoms: " + constraintAtoms);
+        logger.debug("Found filter atoms: " + filterAtoms);
+      }
+      
+      for (Node ruleNode : ruleNodes) {
+        buildRule(ruleNode, rules, constraintAtoms, filterAtoms);
+      }
+      
+      processTriggers(rules);
+    } catch (TuplesException te) {
+      logger.error("Exception while accessing rule data.", te);
+      throw new InitializerException("Problem accessing rule data", te);
+    } catch (QueryException qe) {
+      logger.error("Exception while reading rules.", qe);
+      throw new InitializerException("Problem reading rules", qe);
+    } catch (SWRLStructureException se) {
+      logger.error("Error in rule RDF data:" + se.getMessage(), se);
+      throw new InitializerException("Problem in rules RDF", se);
+    }
+    
+    return rules;
+  }
+
+  /**
+   * Find all variable declarations in the rule graph.  Variable references are
+   * identified using an <tt>rdf:type</tt> of <tt>swrl:Variable</tt>.
+   * @return A mapping of variable URI reference to a variable object which will
+   *         represent that reference in all subsequent queries.
+   */
+  private Map<URIReference,Variable> findVariables() throws QueryException, TuplesException {
+    // select $var from <ruleGraph> where $var <rdf:type> <swrl:Variable>
+    Variable varV = new Variable("var");
+    ConstraintExpression where = new ConstraintImpl(varV, RDF_TYPE, SWRL.VARIABLE);
+    Query query = createQuery(where, varV);
+    if (logger.isDebugEnabled()) logger.debug("Variable query: " + query);
+    Answer answer = doQuery(query);
+    
+    Map<URIReference,Variable> variables = new HashMap<URIReference,Variable>();
+    
+    try {
+      answer.beforeFirst();
+      while (answer.next()) {
+        Object obj = answer.getObject(varV.getName());
+        if (logger.isDebugEnabled()) logger.debug("Found variable: " + obj);
+        if (obj instanceof URIReference) {
+          Variable var = varFactory.newVariable();
+          variables.put((URIReference)obj, var);
+        }
+      }
+    } finally {
+      answer.close();
+    }
+    
+    return variables;
+  }
+  
+  /**
+   * Find all resources in the rule graph that represent SWRL rules (a.k.a. implications).
+   * A rule is identified by an <tt>rdf:type</tt> of <tt>swrl:Imp</tt>.
+   * @return A list of RDF nodes that represent rule resources.
+   */
+  private List<Node> findRules() throws QueryException, TuplesException {
+    // select $rule from <ruleGraph> where $rule <rdf:type> <swrl:Imp>
+    Variable ruleVar = new Variable("rule");
+    ConstraintExpression where = new ConstraintImpl(ruleVar, RDF_TYPE, SWRL.IMP);
+    Query query = createQuery(where, ruleVar);
+    if (logger.isDebugEnabled()) logger.debug("Rule query: " + query);
+    Answer answer = doQuery(query);
+    
+    List<Node> rules = new ArrayList<Node>();
+    try {
+      answer.beforeFirst();
+      while (answer.next()) {
+        rules.add((Node)answer.getObject(ruleVar.getName()));
+      }
+    } finally {
+      answer.close();
+    }
+    
+    return rules;
+  }
+  
+  /**
+   * Finds all SWRL atoms in the rule graph, and convert them into query triple patterns
+   * or filters as appropriate.  The triple patterns and filters are inserted into the supplied
+   * maps, and variable mappings are performed when the patterns and filters are constructed.
+   * @param constraintAtoms This object will be populated with SWRL atoms that convert to RDF
+   *        triple patterns. The mapping is from the atom's RDF node to a [atom type URI, triple pattern] pair.
+   * @param filterAtoms This object will be populated with SWRL atoms that convert to SPARQL
+   *        filters. The mapping is from the atom's RDF node to a [atom type URI, filter] pair.
+   * @param varMap A map of variable URI references to variable objects to use when constructing
+   *        triple patterns and filters.
+   */
+  private void findAtoms(Map<Node,Pair<URI,ConstraintImpl>> constraintAtoms, Map<Node,Pair<URI,Filter>> filterAtoms, Map<URIReference,Variable> varMap)
+      throws QueryException, TuplesException, SWRLStructureException {
+    findClassAtoms(constraintAtoms, varMap);
+    findIndividualAtoms(constraintAtoms, varMap);
+    findDataAtoms(constraintAtoms, varMap);
+    findIdentityAtoms(constraintAtoms, varMap);
+    findDataRangeAtoms(filterAtoms, varMap);
+    findBuiltinAtoms(filterAtoms, varMap);
+  }
+  
+  /**
+   * Find all atoms in the rule graph of type <tt>swrl:ClassAtom</tt> and insert the resulting
+   * triple patterns into the supplied map.  Note that only named classes are supported.
+   * A class atom has the form:
+   * <pre>
+   * _:x rdf:type swrl:ClassAtom .
+   * _:x swrl:classPredicate ex:MyClass .
+   * _:x swrl:argument1 rule:varX .
+   * </pre>
+   * and will be translated into the triple pattern: <tt>[$varX rdf:type ex:MyClass]</tt>
+   * @param constraintAtoms The map into which the triple patterns are inserted.
+   * @param varMap The variable reference map which is used to construct the triple patterns.
+   */
+  private void findClassAtoms(Map<Node,Pair<URI,ConstraintImpl>> constraintAtoms, Map<URIReference,Variable> varMap)
+      throws QueryException, TuplesException, SWRLStructureException {
+    // select $atom $class $arg from <ruleGraph>
+    // where $atom <rdf:type> <swrl:ClassAtom> and $atom <swrl:classPredicate> $class and $atom <swrl:argument1> $arg
+    Variable atomVar = new Variable("atom");
+    Variable classVar = new Variable("class");
+    Variable argVar = new Variable("arg");
+    ConstraintExpression where = new ConstraintConjunction(
+        new ConstraintImpl(atomVar, RDF_TYPE, SWRL.CLASS_ATOM),
+        new ConstraintImpl(atomVar, SWRL.CLASS_PREDICATE, classVar),
+        new ConstraintImpl(atomVar, SWRL.ARG_1, argVar)
+    );
+    
+    Query query = createQuery(where, atomVar, classVar, argVar);
+    Answer answer = doQuery(query);
+    
+    try {
+      answer.beforeFirst();
+      while (answer.next()) {
+        Node atom = (Node)answer.getObject(atomVar.getName());
+        Object classObj = answer.getObject(classVar.getName());
+        checkClass(classObj, URIReference.class, "Only named classes may be used with class atoms.");
+        Object argObj = answer.getObject(argVar.getName());
+        checkClass(argObj, URIReference.class, "Argument of a class atom may only be a URI or variable reference");
+        constraintAtoms.put(atom, new Pair<URI,ConstraintImpl>(SWRL.CLASS_ATOM.getURI(),
+            toConstraint((URIReference)argObj, RDF_TYPE, (URIReference)classObj, varMap)));
+      }
+    } finally {
+      answer.close();
+    }
+  }
+  
+  /**
+   * Find all atoms in the rule graph of type <tt>swrl:IndividualPropertyAtom</tt> and insert
+   * the resulting triple patterns into the supplied map.  An individual property atom has the form:
+   * <pre>
+   * _:x rdf:type swrl:IndividualPropertyAtom .
+   * _:x swrl:propertyPredicate ex:myObjectProperty .
+   * _:x swrl:argument1 ex:myIndividual .
+   * _:x swrl:argument2 rule:varX .
+   * </pre>
+   * and will be translated to the triple pattern: <tt>[ex:myIndividual ex:myObjectProperty $varX]</tt>.
+   * @param constraintAtoms The map into which the triple patterns are inserted.
+   * @param varMap The variable reference map which is used to construct the triple patterns.
+   */
+  private void findIndividualAtoms(Map<Node,Pair<URI,ConstraintImpl>> constraintAtoms, Map<URIReference,Variable> varMap)
+      throws QueryException, TuplesException, SWRLStructureException {
+    // select $atom $property $arg1 $arg2 from <ruleGraph>
+    // where $atom <rdf:type> <swrl:IndividualPropertyAtom> and $atom <swrl:propertyPredicate> $property
+    //   and $atom <swrl:argument1> $arg1 and $atom <swrl:argument2> $arg2;
+    Variable atomVar = new Variable("atom");
+    Variable propertyVar = new Variable("property");
+    Variable arg1Var = new Variable("arg1");
+    Variable arg2Var = new Variable("arg2");
+    ConstraintExpression where = new ConstraintConjunction(
+        new ConstraintImpl(atomVar, RDF_TYPE, SWRL.INDIVIDUAL_ATOM),
+        new ConstraintImpl(atomVar, SWRL.PROPERTY_PREDICATE, propertyVar),
+        new ConstraintImpl(atomVar, SWRL.ARG_1, arg1Var),
+        new ConstraintImpl(atomVar, SWRL.ARG_2, arg2Var)
+    );
+    
+    Query query = createQuery(where, atomVar, propertyVar, arg1Var, arg2Var);
+    Answer answer = doQuery(query);
+    
+    try {
+      answer.beforeFirst();
+      while (answer.next()) {
+        Node atom = (Node)answer.getObject(atomVar.getName());
+        Object subjectObj = answer.getObject(arg1Var.getName());
+        checkClass(subjectObj, URIReference.class, "Subject of an individual property atom must be a URI or variable reference");
+        Object propertyObj = answer.getObject(propertyVar.getName());
+        checkClass(propertyObj, URIReference.class, "Predicate of an individual property atom must be a URI");
+        Node object = (Node)answer.getObject(arg2Var.getName());
+        constraintAtoms.put(atom, new Pair<URI,ConstraintImpl>(SWRL.INDIVIDUAL_ATOM.getURI(),
+            toConstraint((URIReference)subjectObj, (URIReference)propertyObj, object, varMap)));
+      }
+    } finally {
+      answer.close();
+    }
+  }
+  
+  /**
+   * Find all atoms in the rule graph of type <tt>swrl:DatavaluedPropertyAtom</tt> and insert
+   * the resulting triple patterns into the supplied map.  An individual property atom has the form:
+   * <pre>
+   * _:x rdf:type swrl:DatavaluedPropertyAtom .
+   * _:x swrl:propertyPredicate ex:myDataProperty .
+   * _:x swrl:argument1 ex:myIndividual .
+   * _:x swrl:argument2 rule:varX .
+   * </pre>
+   * and will be translated to the triple pattern: <tt>[ex:myIndividual ex:myDataProperty $varX]</tt>.
+   * @param constraintAtoms The map into which the triple patterns are inserted.
+   * @param varMap The variable reference map which is used to construct the triple patterns.
+   */
+  private void findDataAtoms(Map<Node,Pair<URI,ConstraintImpl>> constraintAtoms, Map<URIReference,Variable> varMap)
+      throws QueryException, TuplesException, SWRLStructureException {
+    // select $atom $property $arg1 $arg2 from <ruleGraph>
+    // where $atom <rdf:type> <swrl:DatavaluedPropertyAtom> and $atom <swrl:propertyPredicate> $property
+    //   and $atom <swrl:argument1> $arg1 and $atom <swrl:argument2> $arg2;
+    Variable atomVar = new Variable("atom");
+    Variable propertyVar = new Variable("property");
+    Variable arg1Var = new Variable("arg1");
+    Variable arg2Var = new Variable("arg2");
+    ConstraintExpression where = new ConstraintConjunction(
+        new ConstraintImpl(atomVar, RDF_TYPE, SWRL.DATA_ATOM),
+        new ConstraintImpl(atomVar, SWRL.PROPERTY_PREDICATE, propertyVar),
+        new ConstraintImpl(atomVar, SWRL.ARG_1, arg1Var),
+        new ConstraintImpl(atomVar, SWRL.ARG_2, arg2Var)
+    );
+    
+    Query query = createQuery(where, atomVar, propertyVar, arg1Var, arg2Var);
+    Answer answer = doQuery(query);
+    
+    try {
+      answer.beforeFirst();
+      while (answer.next()) {
+        Node atom = (Node)answer.getObject(atomVar.getName());
+        Object subjectObj = answer.getObject(arg1Var.getName());
+        checkClass(subjectObj, URIReference.class, "Subject of a data-valued property atom must be a URI or variable reference");
+        Object propertyObj = answer.getObject(propertyVar.getName());
+        checkClass(propertyObj, URIReference.class, "Predicate of a data-valued property atom must be a URI");
+        Node object = (Node)answer.getObject(arg2Var.getName());
+        constraintAtoms.put(atom, new Pair<URI,ConstraintImpl>(SWRL.DATA_ATOM.getURI(),
+            toConstraint((URIReference)subjectObj, (URIReference)propertyObj, object, varMap)));
+      }
+    } finally {
+      answer.close();
+    }
+  }
+  
+  /**
+   * Find all identity atoms in the rule graph (i.e. atoms of type <tt>swrl:SameIndividualsAtom</tt>
+   * and <tt>swrl:DifferentIndividualsAtom</tt>) an insert the resulting triple patterns into
+   * the supplied map.  Identity atoms take the following form:
+   * <pre>
+   * _:x rdf:type swrl:SameIndividualsAtom .
+   * _:x swrl:argument1 ex:individualA .
+   * _:x swrl:argument2 rule:varX .
+   * 
+   * _:y rdf:type swrl:DifferentIndividualsAtom .
+   * _:x swrl:argument1 ex:individualB .
+   * _:x swrl:argument2 rule:varY .
+   * </pre>
+   * and are translated into the triple patterns: <tt>[ex:individualA owl:sameAs $varX]</tt>
+   * and <tt>[ex:individualB owl:differentFrom $varY]</tt>.
+   * @param constraintAtoms The map into which the triple patterns are inserted.
+   * @param varMap The variable reference map which is used to construct the triple patterns.
+   */
+  private void findIdentityAtoms(Map<Node,Pair<URI,ConstraintImpl>> constraintAtoms, Map<URIReference,Variable> varMap)
+      throws QueryException, TuplesException, SWRLStructureException {
+    // select $atom $type $arg1 $arg2 from <ruleGraph>
+    // where $atom <rdf:type> $type and $atom <swrl:argument1> $arg1 and $atom <swrl:argument2> $arg2
+    //   and ($type <mulgara:is> <swrl:SameIndividualsAtom> or $type <mulgara:is> <swrl:DifferentIndividualsAtom>)
+    Variable atomVar = new Variable("atom");
+    Variable typeVar = new Variable("type");
+    Variable arg1Var = new Variable("arg1");
+    Variable arg2Var = new Variable("arg2");
+    ConstraintExpression where = new ConstraintConjunction(
+        new ConstraintImpl(atomVar, RDF_TYPE, typeVar),
+        new ConstraintImpl(atomVar, SWRL.ARG_1, arg1Var),
+        new ConstraintImpl(atomVar, SWRL.ARG_2, arg2Var),
+        new ConstraintDisjunction(
+            new ConstraintIs(typeVar, SWRL.SAME_INDIVIDUALS_ATOM),
+            new ConstraintIs(typeVar, SWRL.DIFFERENT_INDIVIDUALS_ATOM))
+    );
+    
+    Query query = createQuery(where, atomVar, typeVar, arg1Var, arg2Var);
+    Answer answer = doQuery(query);
+    
+    try {
+      answer.beforeFirst();
+      while (answer.next()) {
+        Node atom = (Node)answer.getObject(atomVar.getName());
+        URIReference type = (URIReference)answer.getObject(typeVar.getName());
+        Object arg1Obj = answer.getObject(arg1Var.getName());
+        checkClass(arg1Obj, URIReference.class, "Arguments to identity atoms must be URI or variable references");
+        Object arg2Obj = answer.getObject(arg2Var.getName());
+        checkClass(arg2Obj, URIReference.class, "Arguments to identity atoms must be URI or variable references");
+        
+        URIReference pred = null;
+        if (SWRL.SAME_INDIVIDUALS_ATOM.equals(type)) {
+          pred = new URIReferenceImpl(OWL.SAME_AS);
+        } else if (SWRL.DIFFERENT_INDIVIDUALS_ATOM.equals(type)) {
+          pred = new URIReferenceImpl(OWL.DIFFERENT_FROM);
+        } else {
+          throw new IllegalStateException("Unexpected type result for identiy atom: " + type);
+        }
+        
+        constraintAtoms.put(atom, new Pair<URI,ConstraintImpl>(type.getURI(),
+            toConstraint((URIReference)arg1Obj, pred, (URIReference)arg2Obj, varMap)));
+      }
+    } finally {
+      answer.close();
+    }
+  }
+  
+  /**
+   * Find all atoms in the rule graph of type <tt>swrl:DataRangeAtom</tt> and insert the
+   * resulting filters into the supplied map.  Note that only named datatypes are supported.
+   * A data range atom has the form:
+   * <pre>
+   * _:x rdf:type swrl:DataRangeAtom .
+   * _:x swrl:dataRange xsd:integer .
+   * _:x swrl:argument1 rule:varX .
+   * </pre>
+   * and is mapped to the SPARQL filter clause: <tt>FILTER( datatype(?varX) = xsd:integer )</tt>.
+   * @param filterAtoms The map into which the filters are inserted.
+   * @param varMap The variable reference map which is used to construct the triple patterns.
+   */
+  private void findDataRangeAtoms(Map<Node,Pair<URI,Filter>> filterAtoms, Map<URIReference,Variable> varMap)
+      throws QueryException, TuplesException, SWRLStructureException {
+    // select $atom $range $arg from <ruleGraph>
+    // where $atom <rdf:type> <swrl:DataRangeAtom> and $atom <swrl:dataRange> $range and $atom <swrl:argument1> $arg
+    Variable atomVar = new Variable("atom");
+    Variable rangeVar = new Variable("range");
+    Variable argVar = new Variable("arg");
+    ConstraintExpression where = new ConstraintConjunction(
+        new ConstraintImpl(atomVar, RDF_TYPE, SWRL.DATA_RANGE_ATOM),
+        new ConstraintImpl(atomVar, SWRL.DATA_RANGE, rangeVar),
+        new ConstraintImpl(atomVar, SWRL.ARG_1, argVar)
+    );
+    
+    Query query = createQuery(where, atomVar, rangeVar, argVar);
+    Answer answer = doQuery(query);
+    
+    try {
+      answer.beforeFirst();
+      while (answer.next()) {
+        Node atom = (Node)answer.getObject(atomVar.getName());
+        Object rangeObj = answer.getObject(rangeVar.getName());
+        checkClass(rangeObj, URIReference.class, "Data range atom must specify a named datatype or variable reference");
+        Node arg = (Node)answer.getObject(argVar.getName());
+        Filter filter = new Equals(toRdfTerm((URIReference)rangeObj, varMap), new DataTypeFn(toRdfTerm(arg, varMap)));
+        filterAtoms.put(atom, new Pair<URI,Filter>(SWRL.DATA_RANGE_ATOM.getURI(), filter));
+      }
+    } finally {
+      answer.close();
+    }
+  }
+  
+  /**
+   * Find all atoms in the rule graph of type <tt>swrl:BuiltinAtom</tt> and insert the
+   * resulting filters into the supplied map.  Currently unimplemented.
+   * @param filterAtoms The map into which the filters are inserted.
+   * @param varMap The variable reference map which is used to construct the triple patterns.
+   */
+  private void findBuiltinAtoms(Map<Node,Pair<URI,Filter>> filterAtoms, Map<URIReference,Variable> varMap)
+      throws QueryException, TuplesException, SWRLStructureException {
+    // TODO Implement me.
+  }
+  
+  /**
+   * Builds the rule identified by the given RDF node, and inserts it into the supplied
+   * rule structure.  Rules handled by this method may be ordinary rules, consistency checks,
+   * or axioms, depending on the number of atoms in the body and head of the SWRL implication.
+   * @param ruleNode The RDF node that identifies the rule description to build.
+   * @param rules The rule structure to hold the new rule.
+   * @param constraintAtoms A pre-loaded map containing all triple-pattern atoms in the rule graph.
+   * @param filterAtoms A pre-loaded map containing all filter atoms in the rule graph.
+   */
+  private void buildRule(Node ruleNode, RuleStructure rules,
+      Map<Node,Pair<URI,ConstraintImpl>> constraintAtoms, Map<Node,Pair<URI,Filter>> filterAtoms)
+      throws QueryException, TuplesException, SWRLStructureException {
+    if (logger.isDebugEnabled()) logger.debug("Building structure for rule: " + ruleNode);
+    
+    Set<Node> bodyAtoms = getListMembers(ruleNode, SWRL.BODY);
+    if (logger.isDebugEnabled()) logger.debug("Found body atoms: " + bodyAtoms);
+    
+    Set<Node> headAtoms = getListMembers(ruleNode, SWRL.HEAD);
+    if (logger.isDebugEnabled()) logger.debug("Found head atoms: " + headAtoms);
+    
+    if (bodyAtoms.isEmpty() && headAtoms.isEmpty()) throw new SWRLStructureException("Rule must have at least one atom: " + ruleNode);
+    
+    if (bodyAtoms.isEmpty()) {
+      // Empty body means it's an axiom
+      for (Node headAtom : headAtoms) {
+        rules.addAxiom(toAxiom(getHeadAtom(headAtom, constraintAtoms, filterAtoms)));
+      }
+    } else {
+      // Either a regular rule or a consistency check; both have queries.
+      ConstraintExpression whereClause = buildWhereClause(bodyAtoms, constraintAtoms, filterAtoms);
+      Rule rule = null;
+      List<SelectElement> selectVars = null;
+      
+      if (headAtoms.isEmpty()) {
+        rule = new ConsistencyCheck(ruleNode.toString());
+        selectVars = new ArrayList<SelectElement>(whereClause.getVariables());
+      } else {
+        rule = new Rule(ruleNode.toString());
+        selectVars = getSelectElements(headAtoms, constraintAtoms, filterAtoms);
+      }
+      
+      QueryStruct queryStruct = new QueryStruct(selectVars);
+      queryStruct.setWhereClause(whereClause);
+      queryStruct.setGraphExpression(baseGraph, destGraph);
+      try {
+        rule.setQueryStruct(queryStruct);
+      } catch (KruleStructureException e) {
+        throw new SWRLStructureException("Illegal query structure", e);
+      }
+      rules.add(rule);
+    }
+  }
+  
+  /**
+   * Gets the triple pattern identified by the given atom node, or throws an exception if
+   * the given atom does not map to a triple pattern.
+   * @param node The RDF node representing an atom appearing in a rule head.
+   * @param constraintAtoms All triple-pattern atoms in the rule graph.
+   * @param filterAtoms All filter atoms in the rule graph.
+   * @return The triple pattern mapped to the given RDF node.
+   * @throws SWRLStructureException if the RDF node does not represent a triple pattern atom.
+   */
+  private ConstraintImpl getHeadAtom(Node node, Map<Node,Pair<URI,ConstraintImpl>> constraintAtoms,
+      Map<Node,Pair<URI,Filter>> filterAtoms) throws SWRLStructureException {
+    if (constraintAtoms.containsKey(node)) {
+      return constraintAtoms.get(node).second();
+    } else if (filterAtoms.containsKey(node)) {
+      throw new SWRLStructureException("Atoms in rule head must map to triple patterns; found: " + filterAtoms.get(node).first());
+    } else {
+      throw new SWRLStructureException("Unable to map entry in rule head to an atom: " + node);
+    }
+  }
+  
+  /**
+   * Converts a query triple pattern to an axiomatic statement.
+   * @param pattern A query triple pattern.
+   * @return The equivalent axiomatic statement.
+   * @throws SWRLStructureException if any position in the triple pattern contains a variable.
+   */
+  private Triple toAxiom(ConstraintImpl pattern) throws SWRLStructureException {
+    ConstraintElement c = pattern.getElement(0);
+    if (c instanceof Variable) throw new SWRLStructureException("Axioms may not contain variables.");
+    SubjectNode s = (SubjectNode)c;
+    c = pattern.getElement(1);
+    if (c instanceof Variable) throw new SWRLStructureException("Axioms may not contain variables.");
+    PredicateNode p = (PredicateNode)c;
+    c = pattern.getElement(2);
+    if (c instanceof Variable) throw new SWRLStructureException("Axioms may not contain variables.");
+    ObjectNode o = (ObjectNode)c;
+    return new TripleImpl(s, p, o);
+  }
+  
+  /**
+   * Builds the where clause for a query given a collection of atoms in a rule body.
+   * The atoms from the rule body may map to triple patterns or filters, but at least one
+   * atom must map to a triple pattern.
+   * @param bodyAtoms A collection of RDF nodes that are atoms in the body of a SWRL implication.
+   * @param constraintAtoms All triple-pattern atoms in the rule graph.
+   * @param filterAtoms All filter atoms in the rule graph.
+   * @return The where clause for a query that represents the rule body.
+   */
+  private ConstraintExpression buildWhereClause(Set<Node> bodyAtoms, Map<Node,Pair<URI,ConstraintImpl>> constraintAtoms,
+      Map<Node,Pair<URI,Filter>> filterAtoms) throws SWRLStructureException {
+    List<ConstraintExpression> triplePatterns = new ArrayList<ConstraintExpression>();
+    List<Filter> filters = new ArrayList<Filter>();
+    
+    for (Node bodyAtom : bodyAtoms) {
+      if (constraintAtoms.containsKey(bodyAtom)) {
+        triplePatterns.add(constraintAtoms.get(bodyAtom).second());
+      } else if (filterAtoms.containsKey(bodyAtom)) {
+        filters.add(filterAtoms.get(bodyAtom).second());
+      } else {
+        throw new SWRLStructureException("Unable to map entry in rule head to an atom: " + bodyAtom);
+      }
+    }
+    
+    if (triplePatterns.isEmpty()) {
+      throw new SWRLStructureException("Rule body must contain at least one triple pattern.");
+    }
+    
+    ConstraintExpression whereClause = new ConstraintConjunction(triplePatterns);
+    if (!filters.isEmpty()) {
+      Filter filter = (filters.size() == 1) ? filters.get(0) : new And(filters.toArray(new Filter[filters.size()]));
+      whereClause = new ConstraintFilter(whereClause, filter);
+    }
+    return whereClause;
+  }
+  
+  /**
+   * Construct a list of select elements that are specified by triple patterns in
+   * the head of a SWRL rule.  The select elements may be either variables or constant values.
+   * @param headNodes A collection of RDF nodes that comprise the atoms in the head of a SWRL rule.
+   * @param constraintAtoms All triple-pattern atoms in the rule graph.
+   * @param filterAtoms All filter atoms in the rule graph.
+   * @return The list of elements that represent statements to be entailed by the rule.
+   */
+  private List<SelectElement> getSelectElements(Set<Node> headNodes, Map<Node,Pair<URI,ConstraintImpl>> constraintAtoms,
+      Map<Node,Pair<URI,Filter>> filterAtoms) throws SWRLStructureException {
+    List<SelectElement> selectElements = new ArrayList<SelectElement>();
+    for (Node headNode : headNodes) {
+      ConstraintImpl pattern = getHeadAtom(headNode, constraintAtoms, filterAtoms);
+      for (int i = 0; i < 3; i++) {
+        ConstraintElement e = pattern.getElement(i);
+        selectElements.add(e instanceof Variable ? (Variable)e : new ConstantValue(varFactory.newVariable(), (Value)e));
+      }
+    }
+    return selectElements;
+  }
+  
+  /**
+   * Utility method to get all members of the RDF list whose head is the object of
+   * an RDF statement with the given subject and predicate.
+   * @param subject The subject of a statement which identifies the list.
+   * @param predicate The predicate of a statement which identifies the list.
+   * @return A collection of RDF nodes which comprise the given list.
+   */
+  private Set<Node> getListMembers(Node subject, URIReferenceImpl predicate) throws QueryException, TuplesException {
+    // select $value from <ruleGraph>
+    // where <parent> <predicate> $head
+    //   and (trans($head <rdf:rest> $node) or $head <rdf:rest> $node)
+    //   and ($head <rdf:first> $value or $node <rdf:first> $value)
+    Variable valueVar = new Variable("value");
+    Variable headVar = new Variable("head");
+    Variable nodeVar = new Variable("node");
+    URIReferenceImpl rdfRest = new URIReferenceImpl(RDF.REST);
+    URIReferenceImpl rdfFirst = new URIReferenceImpl(RDF.FIRST);
+    ConstraintExpression where = new ConstraintConjunction(
+        new ConstraintImpl(toElement(subject), predicate, headVar),
+        new ConstraintDisjunction(
+            new SingleTransitiveConstraint(new ConstraintImpl(headVar, rdfRest, nodeVar)),
+            new ConstraintImpl(headVar, rdfRest, nodeVar)),
+        new ConstraintDisjunction(
+            new ConstraintImpl(headVar, rdfFirst, valueVar),
+            new ConstraintImpl(nodeVar, rdfFirst, valueVar))
+    );
+    
+    Query query = createQuery(where, valueVar);
+    Answer answer = doQuery(query);
+    Set<Node> values = new HashSet<Node>();
+    try {
+      answer.beforeFirst();
+      while (answer.next()) values.add((Node)answer.getObject(valueVar.getName()));
+    } finally {
+      answer.close();
+    }
+    return values;
+  }
+  
+  /**
+   * Detect and add all trigger dependencies between rules to the given rule structure.
+   * @param rules The rule structure for which to process triggers.
+   */
+  private void processTriggers(RuleStructure rules) {
+    for (Iterator<Rule> it1 = rules.getRuleIterator(); it1.hasNext(); ) {
+      Rule trigger = it1.next();
+      for (Iterator<Rule> it2 = rules.getRuleIterator(); it2.hasNext(); ) {
+        Rule potentialTarget = it2.next();
+        if (triggersRule(trigger, potentialTarget)) trigger.addTriggerTarget(potentialTarget);
+      }
+    }
+  }
+  
+  /**
+   * Determine if a rule triggers a potential terget.
+   * @param trigger The rule which may potentially trigger another rule.
+   * @param potentialTarget The potential target of the rule.
+   * @return <tt>true</tt> iff the given rule has a head atom which matches one of
+   *         the body atoms of the potential target.
+   */
+  private boolean triggersRule(Rule trigger, Rule potentialTarget) {
+    // Consistency checks never trigger other rules (they throw exceptions instead).
+    if (trigger instanceof ConsistencyCheck) return false;
+    
+    List<SelectElement> products = trigger.getQuery().getVariableList();
+    if (products.size() % 3 != 0) throw new IllegalStateException("Invalid number of select elements for rule query: " + trigger.getQuery());
+    
+    for (int index = 0; index < products.size(); index += 3) {
+      List<SelectElement> triggerProduct = products.subList(index, index + 3);
+      if (matchesExpression(triggerProduct, potentialTarget.getQuery().getConstraintExpression())) return true;
+    }
+    
+    return false;
+  }
+  
+  /**
+   * Determine whether the head atom represented by the product list matches any part of
+   * the given constraint expression.
+   * @param product A triple pattern appearing as the product of a rule.
+   * @param expr The body of a potential target rule.
+   * @return <tt>true</tt> iff the triple pattern matches any part of the potential target.
+   */
+  private boolean matchesExpression(List<SelectElement> product, ConstraintExpression expr) {
+    assert product.size() == 3;
+    // Only triple patterns, conjunctions, and filters are created by the rule loader; ignore other
+    // constraint types.
+    if (expr instanceof ConstraintImpl) return matchesPattern(product, (ConstraintImpl)expr);
+    else if (expr instanceof ConstraintOperation) {
+      // An operation matches if any of the operands matches.
+      boolean matches = false;
+      for (ConstraintExpression operand : ((ConstraintOperation)expr).getElements()) {
+        matches = matches || matchesExpression(product, operand);
+      }
+      return matches;
+    } else if (expr instanceof ConstraintFilter) {
+      // Only the unfiltered part of a constraint can trigger a match (filters restrict the results from the unfiltered part).
+      return matchesExpression(product, ((ConstraintFilter)expr).getUnfilteredConstraint());
+    }
+    return false;
+  }
+  
+  /**
+   * Determine whether a triple product in the head of one rule matches the triple pattern
+   * in the body of another rule.
+   * @param product A triple product.
+   * @param pattern A triple pattern.
+   * @return <tt>true</tt> if the product and pattern match at every position.  A match is
+   *         defined as both constants with the same value, or both variables (regardless of
+   *         variable name).
+   */
+  private boolean matchesPattern(List<SelectElement> product, ConstraintImpl pattern) {
+    assert product.size() == 3;
+    for (int i = 0; i < product.size(); i++) {
+      SelectElement productTerm = product.get(i);
+      if ((productTerm instanceof ConstantValue) && !(((ConstantValue)productTerm).getValue().equals(pattern.getElement(i)))) return false;
+    }
+    return true;
+  }
+    
+  /**
+   * 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.
+   * @return The Answer to the query.
+   * @throws QueryException If the query fails.
+   */
+  private Answer doQuery(Query q) throws QueryException {
+    try {
+      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);
+    }
+  }
+  
+  /**
+   * Converts an RDF node into an RDF term used in a filter.  Variable mappings from the
+   * rule graph are applied as part of this conversion.
+   * @param node A node from an RDF graph.
+   * @param varMap The variable mappings defined by the rule graph.
+   * @return The corresponding RDF term.
+   */
+  private RDFTerm toRdfTerm(Node node, Map<URIReference,Variable> varMap) throws QueryException, SWRLStructureException {
+    if (varMap.containsKey(node)) return new Var(varMap.get(node).getName());
+    if (node instanceof URIReference) return new IRI(((URIReference)node).getURI());
+    if (node instanceof Literal) {
+      Literal l = (Literal)node;
+      return TypedLiteral.newLiteral(l.getLexicalForm(), l.getDatatypeURI(), l.getLanguage());
+    }
+    throw new SWRLStructureException("RDF term in an atom must be a URI, literal, or variable reference");
+  }
+  
+  /**
+   * Constructs a query triple pattern from a subject, predicate, and object RDF node.
+   * Variable mappings from the rule graph are applied as part of this operation.
+   * @param s The subject URI reference.
+   * @param p The predicate URI reference.
+   * @param o The object node.
+   * @param varMap The variable mappings defined by the rule graph.
+   * @return The corresponding triple pattern.
+   */
+  private ConstraintImpl toConstraint(URIReference s, URIReference p, Node o, Map<URIReference,Variable> varMap) throws SWRLStructureException {
+    ConstraintElement subject = varMap.containsKey(s) ? varMap.get(s): (s instanceof URIReferenceImpl ? (URIReferenceImpl)s : new URIReferenceImpl(s.getURI()));
+    ConstraintElement predicate = varMap.containsKey(p) ? varMap.get(p): (p instanceof URIReferenceImpl ? (URIReferenceImpl)p : new URIReferenceImpl(p.getURI()));
+    ConstraintElement object = null;
+    if (o instanceof URIReference) {
+      URIReference oUri = (URIReference)o;
+      object = varMap.containsKey(oUri) ? varMap.get(oUri) : (oUri instanceof URIReferenceImpl ? (URIReferenceImpl)oUri : new URIReferenceImpl(oUri.getURI()));
+    } else if (o instanceof Literal) {
+      object = toLiteralElement((Literal)o);
+    } else {
+      throw new SWRLStructureException("Object of a triple pattern must be a URI, literal, or variable reference; found: " + o);
+    }
+    return new ConstraintImpl(subject, predicate, object);
+  }
+  
+  /**
+   * Converts a JRDF node to a query constraint element.
+   * @param node The JRDF node.
+   * @return The query constraint element.
+   */
+  private ConstraintElement toElement(Node node) {
+    if (node instanceof ConstraintElement) return (ConstraintElement)node;
+    if (node instanceof URIReference) {
+      return new URIReferenceImpl(((URIReference)node).getURI());
+    } else if (node instanceof Literal) {
+      return toLiteralElement((Literal)node);
+    } else if (node instanceof BlankNode) {
+      return new VariableNodeImpl(((BlankNode)node).getID());
+    }
+    throw new IllegalArgumentException("Unable to convert to constraint element: " + node);
+  }
+  
+  /**
+   * Converts a JRDF literal node to a query constraint element.
+   * @param lit The JRDF literal node.
+   * @return The query constraint element.
+   */
+  private LiteralImpl toLiteralElement(Literal lit) {
+    if (lit instanceof LiteralImpl) return (LiteralImpl)lit;
+    else if (lit.getDatatypeURI() != null) return new LiteralImpl(lit.getLexicalForm(), lit.getDatatypeURI());
+    else if (lit.getLanguage() != null && lit.getLanguage().length() > 0) return new LiteralImpl(lit.getLexicalForm(), lit.getLanguage());
+    else return new LiteralImpl(lit.getLexicalForm());
+  }
+  
+  /**
+   * Utility method to do type checking on an object extracted from query results.
+   * @param <T> The expected class.
+   * @param obj The object that was extracted from a query answer.
+   * @param expected The expected class of the object.
+   * @param msg The message to use when throwing an exception if the class doesn't match.
+   * @throws SWRLStructureException if the actual class of the object doesn't match the expected class.
+   */
+  private <T> void checkClass(Object obj, Class<T> expected, String msg) throws SWRLStructureException {
+    if (!expected.isAssignableFrom(obj.getClass())) {
+      throw new SWRLStructureException(msg);
+    }
+  }
+}

Added: trunk/src/jar/swrl/java/org/mulgara/swrl/SWRLStructureException.java
===================================================================
--- trunk/src/jar/swrl/java/org/mulgara/swrl/SWRLStructureException.java	                        (rev 0)
+++ trunk/src/jar/swrl/java/org/mulgara/swrl/SWRLStructureException.java	2009-06-08 19:47:56 UTC (rev 1720)
@@ -0,0 +1,42 @@
+/*
+ * 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.swrl;
+
+/**
+ * Exception to indicate an error in the structure of an RDF graph describing
+ * a collection of SWRL rules.
+ * 
+ * @created Jun 5, 2009
+ * @author Alex Hall
+ * @copyright &copy; 2009 <a href="http://www.revelytix.com">Revelytix, Inc.</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class SWRLStructureException extends Exception {
+
+  private static final long serialVersionUID = -8536158307400743724L;
+
+  /**
+   * @param message The exception message.
+   */
+  public SWRLStructureException(String message) {
+    super(message);
+  }
+
+  /**
+   * @param message The exception message.
+   * @param cause The exception cause.
+   */
+  public SWRLStructureException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+}

Added: trunk/src/jar/swrl/swrl-build.properties
===================================================================
--- trunk/src/jar/swrl/swrl-build.properties	                        (rev 0)
+++ trunk/src/jar/swrl/swrl-build.properties	2009-06-08 19:47:56 UTC (rev 1720)
@@ -0,0 +1,17 @@
+#
+# Properties used by the SWRL module
+#
+# $Id: krule-build.properties,v 1.1 2005/06/26 12:41:14 pgearon Exp $
+#
+
+# Module Name
+swrl.name          = SWRL
+
+# General module properties
+swrl.conf.dir      = ${conf.dir}
+swrl.src.dir       = ${jar.src.dir}/swrl
+swrl.obj.dir       = ${jar.obj.dir}/swrl
+swrl.dist.dir      = ${bin.dir}
+swrl.test.dir      = ${test.dir}/swrl
+swrl.jxtest.dir    = ${jxtest.dir}/swrl
+swrl.jar           = swrl-base-${mulgara-version}.jar




More information about the Mulgara-svn mailing list