From 1371b59e44a20bf0345adde8901a667c388b4812 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Euzenat?= <Jerome.Euzenat@inria.fr>
Date: Wed, 6 Oct 2010 07:10:00 +0000
Subject: [PATCH] - implemented universal and existential quantification in
 EDOAL

---
 examples/omwg/total.xml                       | 44 ++++++++++
 html/edoal.html                               | 11 ++-
 html/relnotes.html                            |  4 +-
 .../impl/edoal/ClassDomainRestriction.java    | 16 ++++
 .../impl/edoal/ClassTypeRestriction.java      | 17 ++++
 .../impl/renderer/RDFRendererVisitor.java     | 85 +++----------------
 .../exmo/align/parser/RDFParser.java          | 19 +++--
 .../exmo/align/parser/SyntaxElement.java      |  2 +
 8 files changed, 112 insertions(+), 86 deletions(-)

diff --git a/examples/omwg/total.xml b/examples/omwg/total.xml
index 257f259d..6f484f37 100644
--- a/examples/omwg/total.xml
+++ b/examples/omwg/total.xml
@@ -200,6 +200,50 @@
 	<relation>SubsumedBy</relation>
       </Cell>
     </map>
+    <!-- test the quantifiers -->
+    <map>
+      <Cell rdf:about="MappingRule_class_quant">
+	<entity1>
+	  <edoal:Class>
+	    <edoal:or rdf:parseType="Collection">
+	      <edoal:Class rdf:about="&wine;Vin"/>
+	      <edoal:AttributeDomainRestriction> 
+		<edoal:onAttribute>
+		  <edoal:Relation>
+		    <edoal:compose rdf:parseType="Collection">
+		      <edoal:Relation rdf:about="&wine;hasTerroir"/>
+		      <edoal:Relation rdf:about="&proton;locatedIn"/>
+		    </edoal:compose>
+		  </edoal:Relation>
+		</edoal:onAttribute>
+  		<edoal:all><edoal:Class rdf:about="&wine;FrenchRegion"/></edoal:all>
+	      </edoal:AttributeDomainRestriction>	  
+	    </edoal:or>
+	  </edoal:Class>
+	</entity1>
+	<entity2> 
+	  <edoal:Class>
+	    <edoal:and rdf:parseType="Collection">
+	      <edoal:Class rdf:about="&vin;Vin"/>
+	      <edoal:AttributeDomainRestriction> 
+		<edoal:onAttribute>
+		  <edoal:Relation>
+		    <edoal:compose rdf:parseType="Collection">
+		      <edoal:Relation rdf:about="&vin;hasTerroir"/>
+		      <edoal:Relation rdf:about="&proton;locatedIn"/>
+		    </edoal:compose>
+		  </edoal:Relation>
+		</edoal:onAttribute>
+		<edoal:comparator rdf:resource="&xsd;equals"/>
+  		<edoal:exists><edoal:Class rdf:about="&wine;FrenchRegion"/></edoal:exists>
+	      </edoal:AttributeDomainRestriction>	  
+	    </edoal:and>
+	  </edoal:Class>
+        </entity2>
+	<measure rdf:datatype='&xsd;float'>1.</measure>
+	<relation>SubsumedBy</relation>
+      </Cell>
+    </map>
     <!-- a bit more test on values -->
     <map>
       <Cell rdf:about="MappingRule_class_values">
diff --git a/html/edoal.html b/html/edoal.html
index 477d993f..0070072c 100644
--- a/html/edoal.html
+++ b/html/edoal.html
@@ -140,7 +140,8 @@ A class can be defined using its URI or a restriction. Restrictions are defined
 <u>classexpr</u> ::= &lt;Class rdf:about=" <u>URI</u> "/>
             | &lt;Class> <u>classconst</u> &lt;/Class>
             | &lt;AttributeOccurenceRestriction> <u>onatt</u> <u>comp</u> <u>INTEGER</u> &lt;/AttributeOccurenceRestriction>
-            | &lt;AttributeDomainRestriction> <u>onatt</u> (&lt;class><u>classexpr</u>&lt;/class>|<u>datatype</u>) &lt;/AttributeDomainRestriction>
+            | &lt;AttributeDomainRestriction> <u>onatt</u> <u>classrest</u> &lt;/AttributeDomainRestriction>
+            | &lt;AttributeTypeRestriction> <u>onatt</u> <u>typerest</u> &lt;/AttributeTypeRestriction>
             | &lt;AttributeValueRestriction> <u>onatt</u> <u>comp</u> (&lt;value><u>instexpr</u>&lt;/value>|<u>val</u>) &lt;/AttributeValueRestriction>
 
 <u>classconst</u> ::= &lt;and rdf:parseType="Collection"> <u>classexpr</u>+&lt;/and>
@@ -160,7 +161,9 @@ A class can be defined using its URI or a restriction. Restrictions are defined
 
 <u>val</u> ::= &lt;value> <u>value</u> &lt;/value> 
 
-<u>datatype</u> ::= &lt;type> <u>value</u> &lt;/type> 
+<u>typerest</u> ::= <!--&lt;all> <u>type</u> &lt;/all> | &lt;exists> <u>type</u> &lt;/exists> | -->&lt;type> <u>type</u> &lt;/type>
+
+<u>classrest</u> ::= &lt;all> <u>classexpr</u> &lt;/all> | &lt;exists> <u>classexpr</u> &lt;/exists> | &lt;class> <u>classexpre</u> &lt;/class>
 
 <u>comp</u> ::= &lt;comparator rdf:resource=" <u>URI</u> "/>
 
@@ -201,8 +204,8 @@ Property values can be transformed by applying a <i>Transformation</i> function.
 <div class="fragment"><pre>
 <u>propexpr</u> ::= &lt;Property rdf:about=" <u>URI</u> "/> 
            | &lt;Property> <u>propconst</u>+ &lt;/Property> 
-           | &lt;PropertyDomainRestriction> &lt;class> <u>classexpr</u> &lt;/class> &lt;/PropertyDomainRestrict 
-           | &lt;PropertyTypeRestriction> <u>datatype</u> &lt;/PropertyTypeRestriction> 
+           | &lt;PropertyDomainRestriction> &lt;class> <u>classexpr</u> &lt;/class> &lt;/PropertyDomainRestriction> 
+           | &lt;PropertyTypeRestriction> <u>typerest</u> &lt;/PropertyTypeRestriction> 
            | &lt;PropertyValueRestriction> <u>comp</u> <u>val</u> &lt;/PropertyValueRestriction><!--
            | <u>transf</u>-->
 
diff --git a/html/relnotes.html b/html/relnotes.html
index 03a706ee..f90a3178 100644
--- a/html/relnotes.html
+++ b/html/relnotes.html
@@ -78,8 +78,8 @@ The development of 4 versions continue.
 <li>Implemented online evaluation and diff (server)</li>
 <li>Added the possibility to drop a number of correspondences in <tt>ONetworkWeakener</tt> (util)</li>
 <li>Added a google chart API display of plots <tt>GenPlot -t html</tt> (util)</li>
-<li><tt>edoal:or</tt>, <tt>edoal:and</tt> and <tt>edoal:compose</tt>
-  can be empty (edoal)</li>
+<li><tt>edoal:or</tt>, <tt>edoal:and</tt> and <tt>edoal:compose</tt> can be empty (edoal)</li>
+<li>Added universal (<tt>all</tt>) and existantial (<tt>exists</tt>) quantification of domains in edoal (edoal)</li>
 <li>Upgraded to <span style="color: green">Pellet 2.1</span> (but
   Pellet is not anymore distributed <a href="lib.html">due to license restrictions</a>)</li>
 <li>Upgraded to <span style="color: green">OntoSim 2.1</span> (lib)</li>
diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/ClassDomainRestriction.java b/src/fr/inrialpes/exmo/align/impl/edoal/ClassDomainRestriction.java
index 1ed5f92d..689c9082 100644
--- a/src/fr/inrialpes/exmo/align/impl/edoal/ClassDomainRestriction.java
+++ b/src/fr/inrialpes/exmo/align/impl/edoal/ClassDomainRestriction.java
@@ -25,17 +25,29 @@ package fr.inrialpes.exmo.align.impl.edoal;
 public class ClassDomainRestriction extends ClassRestriction implements Cloneable {
 
     ClassExpression domain = null;
+    boolean universal = true;
 
     /**
      * Constructs a typeCondition with the given restriction.
      * 
      * @param p
      *            the PathExpression to which the restriction applies
+     * @param pred
+     * wether the constraint is universal (true) or existential (false)
      * @param cl
      *            the ClassExpression restricting the domain
      * @throws NullPointerException
      *             if the restriction is null
      */
+    public ClassDomainRestriction(final PathExpression p,
+				  final boolean pred,
+				  final ClassExpression cl) {
+	super(p);
+	// Check that this is a property
+	universal = pred;
+	domain = cl;
+    }
+
     public ClassDomainRestriction(final PathExpression p,
 				final ClassExpression cl) {
 	super(p);
@@ -51,4 +63,8 @@ public class ClassDomainRestriction extends ClassRestriction implements Cloneabl
 	domain = cl;
     }
 
+    public boolean isUniversal() {
+	return universal;
+    }
+
 }
diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/ClassTypeRestriction.java b/src/fr/inrialpes/exmo/align/impl/edoal/ClassTypeRestriction.java
index b8159167..cfe1009e 100644
--- a/src/fr/inrialpes/exmo/align/impl/edoal/ClassTypeRestriction.java
+++ b/src/fr/inrialpes/exmo/align/impl/edoal/ClassTypeRestriction.java
@@ -41,17 +41,31 @@ package fr.inrialpes.exmo.align.impl.edoal;
 public class ClassTypeRestriction extends ClassRestriction implements Cloneable {
 
     Datatype type = null;
+    boolean universal = true;
 
     /**
      * Constructs a ClassTypeRestriction with the given restriction.
      * 
      * @param p
      *            the restricted PathExpression
+     * @param pred
+     * wether the constraint is universal (true) or existential (false)
      * @param t
      *            the Datatype to which this path is restricted
      * @throws NullPointerException
      *             if the restriction is null
+     * NOTE: Currently the predicate is not visible in the syntax which only
+     * authorises type (so universal)
      */
+    public ClassTypeRestriction(final PathExpression p,
+				  final boolean pred,
+				final Datatype t) {
+	super(p);
+	// Check that this is a property
+	universal = pred;
+	type = t;
+    }
+
     public ClassTypeRestriction(final PathExpression p,
 				final Datatype t) {
 	super(p);
@@ -67,4 +81,7 @@ public class ClassTypeRestriction extends ClassRestriction implements Cloneable
 	type = t;
     }
 
+    public boolean isUniversal() {
+	return universal;
+    }
 }
diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/RDFRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/RDFRendererVisitor.java
index 00081ac8..be2ae828 100644
--- a/src/fr/inrialpes/exmo/align/impl/renderer/RDFRendererVisitor.java
+++ b/src/fr/inrialpes/exmo/align/impl/renderer/RDFRendererVisitor.java
@@ -89,9 +89,8 @@ import fr.inrialpes.exmo.align.impl.edoal.EDOALCell;
  * @version $Id$
  */
 
-public class RDFRendererVisitor implements AlignmentVisitor {
+public class RDFRendererVisitor extends IndentedRendererVisitor implements AlignmentVisitor {
 
-    PrintWriter writer = null;
     Alignment alignment = null;
     Cell cell = null;
     Hashtable<String,String> nslist = null;
@@ -99,28 +98,11 @@ public class RDFRendererVisitor implements AlignmentVisitor {
 
     private static Namespace DEF = Namespace.ALIGNMENT;
     
-    private String INDENT = "  ";
-
-    private String NL = "";
-
-    /** String for the pretty linebreak. **/
-    private String linePrefix = "";
-
-    private int prefixCount = 0;
-
     private boolean isPattern = false;
 	
     public RDFRendererVisitor( PrintWriter writer ){
-	NL = System.getProperty("line.separator");
-	this.writer = writer;
-    }
-
-    public void setIndentString( String ind ) {
-	INDENT = ind;
-    }
-
-    public void setNewLineString( String nl) { 
-	NL = nl;
+	super( writer );
+	//NL = System.getProperty("line.separator");
     }
 
     public void init( Properties p ) {
@@ -454,7 +436,7 @@ public class RDFRendererVisitor implements AlignmentVisitor {
 	writer.print(NL);
 	decreaseIndent();
 	indentedOutput("</"+SyntaxElement.ONPROPERTY.print(DEF)+">"+NL);
-	visit( c.getType() );
+	visit( c.getType() ); // Directly -> to be changed for rendering all/exists
 	decreaseIndent();
 	writer.print(NL);
 	indentedOutput("</"+SyntaxElement.TYPE_COND.print(DEF)+">");
@@ -472,12 +454,20 @@ public class RDFRendererVisitor implements AlignmentVisitor {
 	writer.print(NL);
 	decreaseIndent();
 	indentedOutput("</"+SyntaxElement.ONPROPERTY.print(DEF)+">"+NL);
-	indentedOutput("<"+SyntaxElement.TOCLASS.print(DEF)+">"+NL);
+	if ( c.isUniversal() ) {
+	    indentedOutput("<"+SyntaxElement.ALL.print(DEF)+">"+NL);
+	} else {
+	    indentedOutput("<"+SyntaxElement.EXISTS.print(DEF)+">"+NL);
+	}
 	increaseIndent();
 	visit( c.getDomain() );
 	writer.print(NL);
 	decreaseIndent();
-	indentedOutput("</"+SyntaxElement.TOCLASS.print(DEF)+">"+NL);
+	if ( c.isUniversal() ) {
+	    indentedOutput("</"+SyntaxElement.ALL.print(DEF)+">"+NL);
+	} else {
+	    indentedOutput("</"+SyntaxElement.EXISTS.print(DEF)+">"+NL);
+	}
 	decreaseIndent();
 	indentedOutput("</"+SyntaxElement.DOMAIN_RESTRICTION.print(DEF)+">");
     }
@@ -774,51 +764,4 @@ public class RDFRendererVisitor implements AlignmentVisitor {
 	writer.print("</"+SyntaxElement.DATATYPE.print(DEF)+">");
     }
 	
-    // ===================================================================
-    // pretty printing management
-    // JE: I THINK THAT THIS IS CONVENIENT BUT INDUCES A SERIOUS LAG IN
-    // PERFORMANCES (BOTH VERSIONS v1 and v2)
-    // LET SEE IF THERE IS NO WAY TO DO THIS DIRECTLY IN THE WRITER  !!!
-
-    /**
-     * Increases the lineprefix by one INDENT
-     */
-    private void increaseIndent() {
-	prefixCount++;
-    }
-    
-    /**
-     * Decreases the lineprefix by one INDENT
-     */
-    private void decreaseIndent() {
-	if (prefixCount > 0) {
-	    prefixCount--;
-	}
-    }
-    
-    // JE: I would like to see benchmarks showing that this is more efficient
-    // than adding them to buffer directly each time
-    private void calcPrefix() {
-	StringBuilder buffer = new StringBuilder();
-	buffer.append(NL);
-	for (int i = 0; i < prefixCount; i++) {
-	    buffer.append(INDENT);
-	}
-	linePrefix = buffer.toString();
-    }
-
-    private void indentedOutputln( String s ){
-	for (int i = 0; i < prefixCount; i++) writer.print(INDENT);
-	writer.print(s+NL);
-    }
-    private void indentedOutput( String s ){
-	for (int i = 0; i < prefixCount; i++) writer.print(INDENT);
-	writer.print(s);
-    }
-    private void indentedOutputln(){
-	for (int i = 0; i < prefixCount; i++) writer.print(INDENT);
-    }
-    private void indentedOutput(){
-	for (int i = 0; i < prefixCount; i++) writer.print(INDENT);
-    }
 }
diff --git a/src/fr/inrialpes/exmo/align/parser/RDFParser.java b/src/fr/inrialpes/exmo/align/parser/RDFParser.java
index 3d493a71..5f0dca79 100644
--- a/src/fr/inrialpes/exmo/align/parser/RDFParser.java
+++ b/src/fr/inrialpes/exmo/align/parser/RDFParser.java
@@ -539,15 +539,16 @@ public class RDFParser {
 		    throw new AlignmentException( "Bad edoal:datatype value" );
 		}
 	    } else if ( rdfType.equals( SyntaxElement.DOMAIN_RESTRICTION.resource ) ) {
-		stmt = node.getProperty( (Property)SyntaxElement.TOCLASS.resource );
-		if ( stmt == null ) throw new AlignmentException( "Required edoal:class property" );
-		RDFNode nn = stmt.getObject();
-		if ( nn.isResource() ) {
-		    return new ClassDomainRestriction( pe,  parseClass( (Resource)nn ) );
-		} else {
-		    throw new AlignmentException( "Incorrect class expression "+nn );
-		} 
-	    } else {
+		if ( (stmt = node.getProperty( (Property)SyntaxElement.TOCLASS.resource ) ) != null || (stmt = node.getProperty( (Property)SyntaxElement.ALL.resource ) ) != null ) {
+		    RDFNode nn = stmt.getObject();
+		    if ( !nn.isResource() ) throw new AlignmentException( "Incorrect class expression "+nn );
+		    return new ClassDomainRestriction( pe, true, parseClass( (Resource)nn ) );
+		} else if ( (stmt = node.getProperty( (Property)SyntaxElement.EXISTS.resource ) ) != null ) {
+		    RDFNode nn = stmt.getObject();
+		    if ( !nn.isResource() ) throw new AlignmentException( "Incorrect class expression "+nn );
+		    return new ClassDomainRestriction( pe, false, parseClass( (Resource)nn ) );
+		} else throw new AlignmentException( "Required edoal:class property" );
+	    } else { // It is a Value or Occurence restruction
 		// Find comparator
 		stmt = node.getProperty( (Property)SyntaxElement.COMPARATOR.resource );
 		if ( stmt == null ) throw new AlignmentException( "Required edoal:comparator property" );
diff --git a/src/fr/inrialpes/exmo/align/parser/SyntaxElement.java b/src/fr/inrialpes/exmo/align/parser/SyntaxElement.java
index f0ebf940..d34b86a9 100644
--- a/src/fr/inrialpes/exmo/align/parser/SyntaxElement.java
+++ b/src/fr/inrialpes/exmo/align/parser/SyntaxElement.java
@@ -119,6 +119,8 @@ public enum SyntaxElement {
 	STRING(          Namespace.EDOAL, "string"),
 	SYMMETRIC(      Namespace.EDOAL, "symmetric", Constructor.SYMMETRIC),
 	TOCLASS(        Namespace.EDOAL, "class"),
+	ALL(            Namespace.EDOAL, "all"),
+	EXISTS(         Namespace.EDOAL, "exists"),
 	TRENT1(         Namespace.EDOAL, "entity1"),
 	TRENT2(         Namespace.EDOAL, "entity2"),
 	TRANSF(         Namespace.EDOAL, "Transformation", true),
-- 
GitLab