]> gerrit.simantics Code Review - simantics/interop.git/commitdiff
More extensive search for comparable resources
authorluukkainen <luukkainen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Wed, 28 Sep 2011 14:43:34 +0000 (14:43 +0000)
committerMarko Luukkainen <marko.luukkainen@vtt.fi>
Thu, 2 Feb 2017 09:22:16 +0000 (11:22 +0200)
git-svn-id: https://www.simantics.org/svn/simantics/interoperability/trunk@22466 ac1ea38d-2e2b-0410-8846-a27921b304fc

org.simantics.interop/src/org/simantics/interop/test/GraphComparator.java
org.simantics.interop/src/org/simantics/interop/test/Path.java [new file with mode: 0644]

index 152d423e341ee9b28cee1c704f0a5c7d3f8a772c..8d432076fd768b74ce3cc3ccf46a1e931e0bb973 100644 (file)
@@ -11,6 +11,7 @@
  *******************************************************************************/\r
 package org.simantics.interop.test;\r
 \r
+import java.math.MathContext;\r
 import java.util.ArrayList;\r
 import java.util.Arrays;\r
 import java.util.Collection;\r
@@ -29,6 +30,7 @@ import org.simantics.db.Statement;
 import org.simantics.db.common.utils.NameUtils;\r
 import org.simantics.db.exception.DatabaseException;\r
 import org.simantics.db.exception.DoesNotContainValueException;\r
+import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;\r
 import org.simantics.db.exception.ServiceException;\r
 import org.simantics.db.exception.ValidationException;\r
 import org.simantics.layer0.Layer0;\r
@@ -173,8 +175,7 @@ public class GraphComparator {
                objectsRight.push(r2);\r
                \r
                \r
-               List<Statement> ss1 = new ArrayList<Statement>();\r
-               List<Statement> ss2 = new ArrayList<Statement>();\r
+               \r
                \r
                Set<Statement> unreliableLeft = new HashSet<Statement>();\r
                Set<Statement> unreliableRight = new HashSet<Statement>();\r
@@ -183,47 +184,15 @@ public class GraphComparator {
                        if (objectsLeft.isEmpty())\r
                                break;\r
                        \r
-                       while (!objectsLeft.isEmpty()) {\r
-                               Resource r1 = objectsLeft.pop();\r
-                               Resource r2 = objectsRight.pop();\r
-                       \r
-                               if (comparableResources.contains(r1, r2)) {\r
-                                       //System.out.println("already tested " + NameUtils.getSafeName(g, r1) + " " + NameUtils.getSafeName(g, r2));\r
-                                       continue;\r
-                               }\r
-                               comparableResources.map(r1, r2);\r
-                               \r
-                               //System.out.println("test " + NameUtils.getSafeName(g, r1) + " " + NameUtils.getSafeName(g, r2));\r
-                               compareProps(r1, r2);\r
-                               \r
-                               for (Resource rel : tested) {\r
-                                       ss1.addAll(g.getStatements(r1, rel));\r
-                                       ss2.addAll(g.getStatements(r2, rel));\r
-                                       ss1 = filterAsserted(r1, ss1);\r
-                                       ss2 = filterAsserted(r2, ss2);\r
-                                       ss1 = filterTraversed(ss1);\r
-                                       ss2 = filterTraversed(ss2);\r
-                                       ss1 = filterNonTested(ss1);\r
-                                       ss2 = filterNonTested(ss2);\r
-                                       \r
-                                       compareStatements(ss1, ss2, null, null,null,null);\r
-                                       ss1.clear();\r
-                                       ss2.clear();\r
-                               }\r
-                               \r
-                               for (Resource rel : traversed) {\r
-                                       ss1.addAll(g.getStatements(r1, rel));\r
-                                       ss2.addAll(g.getStatements(r2, rel));\r
-                                       ss1 = filterAsserted(r1, ss1);\r
-                                       ss2 = filterAsserted(r2, ss2);\r
-                                       compareStatements(ss1, ss2, objectsLeft, objectsRight,unreliableLeft,unreliableRight);\r
-                                       ss1.clear();\r
-                                       ss2.clear();\r
-                                       \r
-                               }\r
-                       }\r
-                       \r
+                       // process compares objects that are identified and searches for more resources to process. \r
+                       process(objectsLeft, objectsRight, unreliableLeft, unreliableRight);\r
+                       // process unreliable handles cases where unidentified resources have path of length one to identified resource\r
                        processUnreliable(unreliableLeft, unreliableRight,objectsLeft,objectsRight);\r
+                       if (objectsLeft.isEmpty() && unreliableLeft.size() > 0 && unreliableRight.size() > 0) {\r
+                               // comparison is ending, but we have still unprocessed unidentified resources left.\r
+                               // These cases have longer path than one to identified objects.\r
+                               processUnreliableDeep(unreliableLeft, unreliableRight, objectsLeft, objectsRight);\r
+                       }\r
                        \r
                }\r
                for (Statement s : unreliableLeft) {\r
@@ -238,6 +207,50 @@ public class GraphComparator {
                \r
        }\r
        \r
+       private void process(Stack<Resource> objectsLeft, Stack<Resource> objectsRight, Set<Statement> unreliableLeft, Set<Statement> unreliableRight) throws DatabaseException {\r
+               List<Statement> ss1 = new ArrayList<Statement>();\r
+               List<Statement> ss2 = new ArrayList<Statement>();\r
+               \r
+               while (!objectsLeft.isEmpty()) {\r
+                       Resource r1 = objectsLeft.pop();\r
+                       Resource r2 = objectsRight.pop();\r
+               \r
+                       if (comparableResources.contains(r1, r2)) {\r
+                               //System.out.println("already tested " + NameUtils.getSafeName(g, r1) + " " + NameUtils.getSafeName(g, r2));\r
+                               continue;\r
+                       }\r
+                       comparableResources.map(r1, r2);\r
+                       \r
+                       //System.out.println("test " + NameUtils.getSafeName(g, r1) + " " + NameUtils.getSafeName(g, r2));\r
+                       compareProps(r1, r2);\r
+                       \r
+                       for (Resource rel : tested) {\r
+                               ss1.addAll(g.getStatements(r1, rel));\r
+                               ss2.addAll(g.getStatements(r2, rel));\r
+                               ss1 = filterAsserted(r1, ss1);\r
+                               ss2 = filterAsserted(r2, ss2);\r
+                               ss1 = filterTraversed(ss1);\r
+                               ss2 = filterTraversed(ss2);\r
+                               ss1 = filterNonTested(ss1);\r
+                               ss2 = filterNonTested(ss2);\r
+                               \r
+                               compareStatements(ss1, ss2, null, null,null,null);\r
+                               ss1.clear();\r
+                               ss2.clear();\r
+                       }\r
+                       \r
+                       for (Resource rel : traversed) {\r
+                               ss1.addAll(g.getStatements(r1, rel));\r
+                               ss2.addAll(g.getStatements(r2, rel));\r
+                               ss1 = filterAsserted(r1, ss1);\r
+                               ss2 = filterAsserted(r2, ss2);\r
+                               compareStatements(ss1, ss2, objectsLeft, objectsRight,unreliableLeft,unreliableRight);\r
+                               ss1.clear();\r
+                               ss2.clear();\r
+                               \r
+                       }\r
+               }\r
+       }\r
        private void processUnreliable(Set<Statement> unreliableLeft, Set<Statement> unreliableRight, Stack<Resource> objectsLeft, Stack<Resource> objectsRight) {\r
                MapList<Resource,Statement> subjectLeft = new MapList<Resource, Statement>();\r
                MapList<Resource,Statement> subjectRight = new MapList<Resource, Statement>();\r
@@ -350,6 +363,122 @@ public class GraphComparator {
                \r
        }\r
        \r
+       private void processUnreliableDeep(Set<Statement> unreliableLeft, Set<Statement> unreliableRight, Stack<Resource> objectsLeft, Stack<Resource> objectsRight) throws ManyObjectsForFunctionalRelationException, ServiceException {\r
+               MapList<Resource,Statement> subjectLeft = new MapList<Resource, Statement>();\r
+               MapList<Resource,Statement> subjectRight = new MapList<Resource, Statement>();\r
+               MapList<Resource,Statement> objectLeft = new MapList<Resource, Statement>();\r
+               MapList<Resource,Statement> objectRight = new MapList<Resource, Statement>();\r
+               \r
+               for (Statement s : unreliableLeft) {\r
+                       subjectLeft.add(s.getSubject(),s);\r
+                       objectLeft.add(s.getObject(),s);\r
+               }\r
+               for (Statement s : unreliableRight) {\r
+                       subjectRight.add(s.getSubject(),s);\r
+                       objectRight.add(s.getObject(),s);\r
+               }\r
+               for (Resource ol : objectLeft.getKeys()) {\r
+                       Set<Path> pathsLeft = new HashSet<Path>();\r
+                       for (Resource rel : traversed) {\r
+                               pathsLeft.addAll(Path.create(g.getStatements(ol, rel)));\r
+                       }\r
+                       while (true) {\r
+                               expand(pathsLeft);\r
+                               if (pathsLeft.size() == 0)\r
+                                       break;\r
+                               Collection<Path> endPaths = new ArrayList<Path>(1);\r
+                               for (Path p : pathsLeft) {\r
+                                       if (comparableResources.containsLeft(p.getEnd())) {\r
+                                               endPaths.add(p);\r
+                                       }\r
+                               }\r
+                               if (endPaths.size() > 0) {\r
+                                       pathsLeft.clear();\r
+                                       pathsLeft.addAll(endPaths);\r
+                                       break;\r
+                               }       \r
+                       }\r
+                       if (pathsLeft.size() > 0) {\r
+                               Resource sl = objectLeft.getValues(ol).get(0).getSubject();\r
+                               Resource sr = comparableResources.getRight(sl);\r
+                               Collection<Resource> possibleOR = new ArrayList<Resource>();\r
+                               for (Statement s : subjectRight.getValues(sr)) {\r
+                                       possibleOR.add(s.getObject());\r
+                               }\r
+                               Map<Resource,Set<Path>> matchingPaths = new HashMap<Resource, Set<Path>>();\r
+                               for (Resource or : possibleOR) {\r
+                                       Set<Path> possiblePathsRight = new HashSet<Path>();\r
+                                       for (Path leftPath : pathsLeft) {\r
+                                               possiblePathsRight.addAll(findComparableRight(leftPath, or));\r
+                                       }\r
+                                       if (possiblePathsRight.size() == pathsLeft.size()) {\r
+                                               matchingPaths.put(or, possiblePathsRight);\r
+                                       }\r
+                               }\r
+                               if (matchingPaths.size() > 0) {\r
+                                       if (matchingPaths.size() == 1) {\r
+                                               Resource or = matchingPaths.keySet().iterator().next();\r
+                                               objectsLeft.add(ol);\r
+                                               objectsRight.add(or);\r
+                                               Collection<Statement> statementsLeft = objectLeft.getValues(ol);\r
+                                               Collection<Statement> statementsRight = objectRight.getValues(or);\r
+                                               unreliableLeft.removeAll(statementsLeft);\r
+                                               unreliableRight.removeAll(statementsRight);\r
+                                               System.out.println();\r
+                                       } else {\r
+                                               System.out.println();\r
+                                       }\r
+                               }\r
+                       }\r
+                       \r
+               }\r
+               \r
+       }\r
+       \r
+       private void expand(Set<Path> paths) throws ManyObjectsForFunctionalRelationException, ServiceException {\r
+               Set<Path> stepPathsLeft = new HashSet<Path>();\r
+               if (paths.size() == 0)\r
+                       return;\r
+               int length = paths.iterator().next().getLength() + 1;\r
+               for (Path p : paths) {\r
+                       for (Resource rel : traversed) {\r
+                               stepPathsLeft.addAll(Path.expand(p,g.getStatements(p.getEnd(), rel)));\r
+                       }\r
+               }\r
+               paths.clear();\r
+               for (Path p : stepPathsLeft) {\r
+                       if (p.getLength() == length)\r
+                               paths.add(p);\r
+               }\r
+       }\r
+       \r
+       private Collection<Path> findComparableRight(Path leftPath, Resource beginRight) throws ManyObjectsForFunctionalRelationException, ServiceException {\r
+               Set<Path> rightPaths = new HashSet<Path>();\r
+               rightPaths.addAll(Path.create(g.getStatements(beginRight, getRight(leftPath.getStatements().get(0).getPredicate()))));\r
+               for (int i = 1; i < leftPath.getLength(); i++) {\r
+                       if (rightPaths.size() == 0)\r
+                               return rightPaths;\r
+                       Set<Path> stepPaths = new HashSet<Path>();\r
+                       for (Path p : rightPaths) {\r
+                               stepPaths.addAll(Path.expand(p, g.getStatements(p.getEnd(), getRight(leftPath.getStatements().get(i).getPredicate()))));\r
+                       }\r
+                       rightPaths.clear();\r
+                       for (Path p : stepPaths)\r
+                               if (p.getLength() == i+1) \r
+                                       rightPaths.add(p);\r
+               }\r
+               return rightPaths;\r
+               \r
+       }\r
+       \r
+       private Resource getRight(Resource r) {\r
+               if (comparableResources.containsLeft(r))\r
+                       return comparableResources.getRight(r);\r
+               return r;\r
+       }\r
+       \r
+\r
+       \r
        public BijectionMap<Statement, Statement> getComparableStatements() {\r
                return comparableStatements;\r
        }\r
diff --git a/org.simantics.interop/src/org/simantics/interop/test/Path.java b/org.simantics.interop/src/org/simantics/interop/test/Path.java
new file mode 100644 (file)
index 0000000..b772267
--- /dev/null
@@ -0,0 +1,99 @@
+package org.simantics.interop.test;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.List;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Statement;\r
+\r
+public class Path {\r
+       private Resource begin;\r
+       private Resource end;\r
+       private List<Statement> statements = new ArrayList<Statement>(2);\r
+       \r
+       public Path(Statement s) {\r
+               begin = s.getSubject();\r
+               end = s.getObject();\r
+               statements.add(s);\r
+       }\r
+       \r
+       public Path(Path p) {\r
+               begin = p.begin;\r
+               end = p.end;\r
+               statements.addAll(p.statements);\r
+       }\r
+       \r
+       public Resource getBegin() {\r
+               return begin;\r
+       }\r
+       \r
+       public Resource getEnd() {\r
+               return end;\r
+       }\r
+       \r
+       public List<Statement> getStatements() {\r
+               return statements;\r
+       }\r
+       \r
+       public int getLength() {\r
+               return statements.size();\r
+       }\r
+       \r
+       public boolean add(Statement s) {\r
+               if (!statements.get(statements.size()-1).getObject().equals(s.getSubject()))\r
+                       //throw new RuntimeException("Non continuous path. " + s.getSubject() + " does not match " + statements.get(statements.size()-1).getObject());\r
+                       return false;\r
+               if (s.getObject().equals(begin))\r
+                       return false;\r
+               for (Statement stm : statements) {\r
+                       if (stm.getObject().equals(s.getObject()))\r
+                               return false;\r
+               }\r
+               end = s.getObject();\r
+               statements.add(s);\r
+               return true;\r
+       }\r
+       \r
+       public static Collection<Path> expand(Path path, Collection<Statement> statements) {\r
+               Collection<Path> result = new ArrayList<Path>(statements.size());\r
+               for (Statement s : statements) {\r
+                       Path p = new Path(path);\r
+                       p.add(s);\r
+                       result.add(p);\r
+               }\r
+               return result;\r
+       }\r
+       \r
+       public static Collection<Path> create(Collection<Statement> statements) {\r
+               Collection<Path> result = new ArrayList<Path>(statements.size());\r
+               for (Statement s : statements) {\r
+                       Path p = new Path(s);\r
+                       result.add(p);\r
+               }\r
+               return result;\r
+       }\r
+       \r
+       @Override\r
+       public boolean equals(Object arg0) {\r
+               if(!arg0.getClass().equals(getClass()))\r
+                       return false;\r
+               Path other = (Path)arg0;\r
+               if (!begin.equals(other.begin))\r
+                       return false;\r
+               if (!end.equals(other.end))\r
+                       return false;\r
+               if (statements.size() != other.statements.size())\r
+                       return false;\r
+               for (int i = 0; i < statements.size(); i++) {\r
+                       if (!statements.get(i).equals(other.statements.get(i)))\r
+                               return false;\r
+               }\r
+               return false;\r
+       }\r
+       \r
+       @Override\r
+       public int hashCode() {\r
+               return begin.hashCode() + end.hashCode();\r
+       }\r
+}\r