--- /dev/null
+package org.simantics.graph.compiler.internal.procedures;\r
+\r
+import gnu.trove.list.array.TIntArrayList;\r
+import gnu.trove.map.hash.TIntIntHashMap;\r
+\r
+import org.simantics.graph.query.IGraph;\r
+import org.simantics.graph.query.Paths;\r
+import org.simantics.graph.query.Res;\r
+import org.simantics.graph.store.GraphStore;\r
+import org.simantics.graph.store.StatementStore;\r
+\r
+public class CreateInverseRelations implements Runnable {\r
+ IGraph graph;\r
+ GraphStore store;\r
+ \r
+ public CreateInverseRelations(IGraph graph, GraphStore store) {\r
+ this.graph = graph;\r
+ this.store = store;\r
+ }\r
+ \r
+ @Override\r
+ public void run() {\r
+ Paths paths = graph.getPaths();\r
+ int subrelationOf = store.identities.pathToId(paths.SubrelationOf);\r
+ if(subrelationOf < 0)\r
+ return;\r
+ \r
+ int inverseOf = store.identities.createPathToId(paths.InverseOf);\r
+ \r
+ int resourceCount = store.identities.getResourceCount();\r
+ TIntIntHashMap inverseMap = new TIntIntHashMap();\r
+ StatementStore statements = store.statements;\r
+ for(int id = 0;id<resourceCount;++id) {\r
+ TIntArrayList objects = statements.getObjects(id, inverseOf);\r
+ if(!objects.isEmpty()) {\r
+ inverseMap.put(id, objects.get(0));\r
+ for(int i=0;i<objects.size();++i)\r
+ inverseMap.put(objects.get(i), id);\r
+ }\r
+ }\r
+ boolean mod = true;\r
+ while(mod) {\r
+ mod = false;\r
+ for(int id = 0;id<resourceCount;++id)\r
+ if(store.identities.isNewResource(id) || !store.identities.hasIdentity(id)) {\r
+ TIntArrayList superrelations =\r
+ store.statements.getObjects(id, subrelationOf);\r
+ TIntArrayList invSuperrelations = new TIntArrayList(superrelations.size());\r
+ for(int superrelation : superrelations.toArray())\r
+ for(Res invSuperrelation : graph.rawGetObjects(store.idToRes(superrelation), \r
+ paths.InverseOf)) \r
+ invSuperrelations.add(store.createResToId(invSuperrelation));\r
+ \r
+ // Create inverse\r
+ if(!invSuperrelations.isEmpty()) {\r
+ //TIntArrayList inverses = store.statements.getObjects(id, inverseOf);\r
+ int inverse;\r
+ if(!inverseMap.containsKey(id)) { \r
+ if(store.identities.hasIdentity(id)) {\r
+ inverse = store.identities.getChild(id, "Inverse");\r
+ store.identities.markNew(inverse);\r
+ }\r
+ else\r
+ inverse = store.identities.newResource();\r
+ inverseMap.put(id, inverse);\r
+ inverseMap.put(inverse, id);\r
+ store.statements.add(id, inverseOf, inverse);\r
+ mod = true;\r
+ }\r
+ else {\r
+ inverse = inverseMap.get(id);\r
+ for(int curSuperrelation : store.statements.getObjects(inverse, subrelationOf).toArray()) {\r
+ int i = invSuperrelations.indexOf(curSuperrelation);\r
+ if(i >= 0) {\r
+ invSuperrelations.set(i, \r
+ invSuperrelations.get(invSuperrelations.size()-1));\r
+ invSuperrelations.removeAt(invSuperrelations.size()-1);\r
+ }\r
+ }\r
+ } \r
+ \r
+ for(int invSuperrelation : invSuperrelations.toArray())\r
+ store.statements.add(inverse, subrelationOf, invSuperrelation);\r
+ }\r
+ }\r
+ }\r
+ }\r
+}\r