[Mulgara-svn] r1598 - in branches/consistency/src/jar/content-rlog: java/org/mulgara/krule/rlog java/org/mulgara/krule/rlog/ast java/org/mulgara/krule/rlog/ast/output javacc/org/mulgara/krule/rlog

pag at mulgara.org pag at mulgara.org
Tue Mar 10 06:35:45 UTC 2009


Author: pag
Date: 2009-03-09 23:35:44 -0700 (Mon, 09 Mar 2009)
New Revision: 1598

Added:
   branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/Program.java
   branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CanonicalPredicate.java
   branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CheckRule.java
   branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/VariableCanonicalizer.java
Modified:
   branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/Rlog.java
   branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Axiom.java
   branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/BPredicate.java
   branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/IntegerLiteral.java
   branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/InvertedPredicate.java
   branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/NullPredicate.java
   branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Predicate.java
   branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/PredicateLiteral.java
   branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/PredicateParam.java
   branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Rule.java
   branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Statement.java
   branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/StringLiteral.java
   branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/TypeStatement.java
   branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Variable.java
   branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/output/RuleGenerator.java
   branches/consistency/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParser.java
   branches/consistency/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParser.jj
   branches/consistency/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParserTokenManager.java
Log:
Updated the parser to return a Program object that can be annotated, rather than just a list of statements. Also created a canonical form for statements, so that they can be compared, and duplicates can be removed

Added: branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/Program.java
===================================================================
--- branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/Program.java	                        (rev 0)
+++ branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/Program.java	2009-03-10 06:35:44 UTC (rev 1598)
@@ -0,0 +1,131 @@
+/*
+ * 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.URL;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.mulgara.krule.rlog.ast.CanonicalPredicate;
+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 &copy; 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<List<CanonicalPredicate>> canonicalStatements;
+
+  /** The list of imports */
+  private List<URL> imports;
+
+  /**
+   * Constructs an empty program.
+   */
+  public Program() {
+    statements = new ArrayList<Statement>();
+    canonicalStatements = new ArrayList<List<CanonicalPredicate>>();
+  }
+
+  /**
+   * 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) {
+    List<CanonicalPredicate> 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(URL imp) {
+    imports.add(imp);
+  }
+
+  /**
+   * 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, List<CanonicalPredicate> canonical) {
+    if (logger.isDebugEnabled()) logger.debug("Testing for presence of: " + stmt);
+    for (List<CanonicalPredicate> 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: branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/Rlog.java
===================================================================
--- branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/Rlog.java	2009-03-10 06:32:53 UTC (rev 1597)
+++ branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/Rlog.java	2009-03-10 06:35:44 UTC (rev 1598)
@@ -112,7 +112,8 @@
     // parse the rlog into statements
     RlogParser parser = new RlogParser(input);
 
-    statements = parser.statements();
+    Program program = parser.getProgram();
+    statements = program.getStatements();
 
     // separate out the rules from the axioms
     int ruleCount = 0;

Modified: branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Axiom.java
===================================================================
--- branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Axiom.java	2009-03-10 06:32:53 UTC (rev 1597)
+++ branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Axiom.java	2009-03-10 06:35:44 UTC (rev 1598)
@@ -16,6 +16,8 @@
 
 package org.mulgara.krule.rlog.ast;
 
+import java.util.Collections;
+import java.util.List;
 import java.util.Set;
 
 import org.mulgara.krule.rlog.ParseContext;
@@ -104,5 +106,15 @@
   public RDFNode getObject() throws URIParseException {
     return predicate.getObject();
   }
+
+  @Override
+  public List<CanonicalPredicate> getCanonical() {
+    return Collections.singletonList(predicate.getCanonical());
+  }
+
+  /** @see java.lang.Object#toString() */
+  public String toString() {
+    return predicate.toString() + ".";
+  }
 }
 

Modified: branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/BPredicate.java
===================================================================
--- branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/BPredicate.java	2009-03-10 06:32:53 UTC (rev 1597)
+++ branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/BPredicate.java	2009-03-10 06:35:44 UTC (rev 1598)
@@ -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);
+  }
 }
 

Added: branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CanonicalPredicate.java
===================================================================
--- branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CanonicalPredicate.java	                        (rev 0)
+++ branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CanonicalPredicate.java	2009-03-10 06:35:44 UTC (rev 1598)
@@ -0,0 +1,181 @@
+/*
+ * 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.Arrays;
+
+/**
+ * Represents a canonicalization of a predicate.
+ *
+ * @created Mar 4, 2009
+ * @author Paul Gearon
+ * @copyright &copy; 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() {
+    return (invertFlag ? "~" : "") + Arrays.asList(elements).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 &gt;0 if this object occurs after cpred, &lt;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;
+  }
+
+}

Added: branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CheckRule.java
===================================================================
--- branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CheckRule.java	                        (rev 0)
+++ branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/CheckRule.java	2009-03-10 06:35:44 UTC (rev 1598)
@@ -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 &copy; 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: branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/IntegerLiteral.java
===================================================================
--- branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/IntegerLiteral.java	2009-03-10 06:32:53 UTC (rev 1597)
+++ branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/IntegerLiteral.java	2009-03-10 06:35:44 UTC (rev 1598)
@@ -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: branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/InvertedPredicate.java
===================================================================
--- branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/InvertedPredicate.java	2009-03-10 06:32:53 UTC (rev 1597)
+++ branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/InvertedPredicate.java	2009-03-10 06:35:44 UTC (rev 1598)
@@ -91,5 +91,10 @@
     return invertPredicate.getObject();
   }
 
+  @Override
+  CanonicalPredicate getCanonical() {
+    return invertPredicate.getCanonical().invert();
+  }
+
 }
 

Modified: branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/NullPredicate.java
===================================================================
--- branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/NullPredicate.java	2009-03-10 06:32:53 UTC (rev 1597)
+++ branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/NullPredicate.java	2009-03-10 06:35:44 UTC (rev 1598)
@@ -90,5 +90,15 @@
     throw new UnsupportedOperationException();
   }
 
+  /** @see java.lang.Object#toString() */
+  public String toString() {
+    return "";
+  }
+
+  @Override
+  CanonicalPredicate getCanonical() {
+    return new CanonicalPredicate();
+  }
+
 }
 

Modified: branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Predicate.java
===================================================================
--- branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Predicate.java	2009-03-10 06:32:53 UTC (rev 1597)
+++ branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Predicate.java	2009-03-10 06:35:44 UTC (rev 1598)
@@ -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: branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/PredicateLiteral.java
===================================================================
--- branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/PredicateLiteral.java	2009-03-10 06:32:53 UTC (rev 1597)
+++ branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/PredicateLiteral.java	2009-03-10 06:35:44 UTC (rev 1598)
@@ -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: branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/PredicateParam.java
===================================================================
--- branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/PredicateParam.java	2009-03-10 06:32:53 UTC (rev 1597)
+++ branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/PredicateParam.java	2009-03-10 06:35:44 UTC (rev 1598)
@@ -26,9 +26,17 @@
  * @copyright &copy; 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: branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Rule.java
===================================================================
--- branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Rule.java	2009-03-10 06:32:53 UTC (rev 1597)
+++ branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Rule.java	2009-03-10 06:35:44 UTC (rev 1598)
@@ -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,32 @@
     return triggers;
   }
 
+  @Override
+  public List<CanonicalPredicate> getCanonical() {
+    List<CanonicalPredicate> list = new ArrayList<CanonicalPredicate>(body.size() + 1);
+    // reorder the predicates
+    for (Predicate p: body) C.ascendingInsert(list, p.getCanonical());
+    list.add(head.getCanonical());
+    // rename the variables
+    VariableCanonicalizer vc = new VariableCanonicalizer();
+    for (CanonicalPredicate p: list) p.renameVariables(vc);
+    return 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: branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Statement.java
===================================================================
--- branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Statement.java	2009-03-10 06:32:53 UTC (rev 1597)
+++ branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Statement.java	2009-03-10 06:35:44 UTC (rev 1598)
@@ -16,6 +16,8 @@
 
 package org.mulgara.krule.rlog.ast;
 
+import java.util.List;
+
 import org.mulgara.krule.rlog.ParseContext;
 
 /**
@@ -35,5 +37,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 List<CanonicalPredicate> getCanonical();
 }
 

Modified: branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/StringLiteral.java
===================================================================
--- branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/StringLiteral.java	2009-03-10 06:32:53 UTC (rev 1597)
+++ branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/StringLiteral.java	2009-03-10 06:35:44 UTC (rev 1598)
@@ -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: branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/TypeStatement.java
===================================================================
--- branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/TypeStatement.java	2009-03-10 06:32:53 UTC (rev 1597)
+++ branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/TypeStatement.java	2009-03-10 06:35:44 UTC (rev 1598)
@@ -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: branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Variable.java
===================================================================
--- branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Variable.java	2009-03-10 06:32:53 UTC (rev 1597)
+++ branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/Variable.java	2009-03-10 06:35:44 UTC (rev 1598)
@@ -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;
+  }
+
 }
 

Added: branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/VariableCanonicalizer.java
===================================================================
--- branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/VariableCanonicalizer.java	                        (rev 0)
+++ branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/VariableCanonicalizer.java	2009-03-10 06:35:44 UTC (rev 1598)
@@ -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 &copy; 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: branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/output/RuleGenerator.java
===================================================================
--- branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/output/RuleGenerator.java	2009-03-10 06:32:53 UTC (rev 1597)
+++ branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/ast/output/RuleGenerator.java	2009-03-10 06:35:44 UTC (rev 1598)
@@ -420,7 +420,7 @@
     String seqBase = RDF.BASE_URI.toString() + "_";
     for (int i = cachedSeq.size() + 1; i <= largest; i++) {
       URI s = URI.create(seqBase + i);
-      cachedSeq.add(resolverSession.lookup(new URIReferenceImpl(s)));
+      cachedSeq.add(resolverSession.localize(new URIReferenceImpl(s)));
     }
   }
 

Modified: branches/consistency/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParser.java
===================================================================
--- branches/consistency/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParser.java	2009-03-10 06:32:53 UTC (rev 1597)
+++ branches/consistency/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParser.java	2009-03-10 06:35:44 UTC (rev 1598)
@@ -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,13 +59,13 @@
   }
 
 /* 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 IMPLIED_BY:
@@ -70,7 +81,7 @@
         break label_1;
       }
     }
-                                                       {if (true) return sList;}
+                                                         {if (true) return program;}
     throw new Error("Missing return statement in function");
   }
 
@@ -135,7 +146,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:
@@ -422,42 +433,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;
@@ -623,6 +598,42 @@
     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;
+  }
+
   public RlogParserTokenManager token_source;
   SimpleCharStream jj_input_stream;
   public Token token, jj_nt;

Modified: branches/consistency/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParser.jj
===================================================================
--- branches/consistency/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParser.jj	2009-03-10 06:32:53 UTC (rev 1597)
+++ branches/consistency/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParser.jj	2009-03-10 06:35:44 UTC (rev 1598)
@@ -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.
@@ -118,11 +129,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; }
 }
 
 
@@ -148,7 +159,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); }
 }
 

Modified: branches/consistency/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParserTokenManager.java
===================================================================
--- branches/consistency/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParserTokenManager.java	2009-03-10 06:32:53 UTC (rev 1597)
+++ branches/consistency/src/jar/content-rlog/javacc/org/mulgara/krule/rlog/RlogParserTokenManager.java	2009-03-10 06:35:44 UTC (rev 1598)
@@ -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;




More information about the Mulgara-svn mailing list