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> ::= <Class rdf:about=" <u>URI</u> "/> | <Class> <u>classconst</u> </Class> | <AttributeOccurenceRestriction> <u>onatt</u> <u>comp</u> <u>INTEGER</u> </AttributeOccurenceRestriction> - | <AttributeDomainRestriction> <u>onatt</u> (<class><u>classexpr</u></class>|<u>datatype</u>) </AttributeDomainRestriction> + | <AttributeDomainRestriction> <u>onatt</u> <u>classrest</u> </AttributeDomainRestriction> + | <AttributeTypeRestriction> <u>onatt</u> <u>typerest</u> </AttributeTypeRestriction> | <AttributeValueRestriction> <u>onatt</u> <u>comp</u> (<value><u>instexpr</u></value>|<u>val</u>) </AttributeValueRestriction> <u>classconst</u> ::= <and rdf:parseType="Collection"> <u>classexpr</u>+</and> @@ -160,7 +161,9 @@ A class can be defined using its URI or a restriction. Restrictions are defined <u>val</u> ::= <value> <u>value</u> </value> -<u>datatype</u> ::= <type> <u>value</u> </type> +<u>typerest</u> ::= <!--<all> <u>type</u> </all> | <exists> <u>type</u> </exists> | --><type> <u>type</u> </type> + +<u>classrest</u> ::= <all> <u>classexpr</u> </all> | <exists> <u>classexpr</u> </exists> | <class> <u>classexpre</u> </class> <u>comp</u> ::= <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> ::= <Property rdf:about=" <u>URI</u> "/> | <Property> <u>propconst</u>+ </Property> - | <PropertyDomainRestriction> <class> <u>classexpr</u> </class> </PropertyDomainRestrict - | <PropertyTypeRestriction> <u>datatype</u> </PropertyTypeRestriction> + | <PropertyDomainRestriction> <class> <u>classexpr</u> </class> </PropertyDomainRestriction> + | <PropertyTypeRestriction> <u>typerest</u> </PropertyTypeRestriction> | <PropertyValueRestriction> <u>comp</u> <u>val</u> </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