--- /dev/null
+package org.simantics.graph.matching;\r
+\r
+import gnu.trove.map.hash.TIntIntHashMap;\r
+\r
+import java.util.ArrayList;\r
+\r
+import org.simantics.databoard.binding.mutable.Variant;\r
+import org.simantics.graph.representation.External;\r
+import org.simantics.graph.representation.Identity;\r
+import org.simantics.graph.representation.Internal;\r
+import org.simantics.graph.representation.Optional;\r
+import org.simantics.graph.representation.Root;\r
+import org.simantics.graph.representation.TransferableGraph1;\r
+import org.simantics.graph.representation.Value;\r
+\r
+public class CanonicalGraph {\r
+\r
+ int resourceCount;\r
+ Stat[][] statements;\r
+ TIntIntHashMap inverses = new TIntIntHashMap();\r
+ Identity[] identities;\r
+ String[] names;\r
+ Variant[] values;\r
+ \r
+ public CanonicalGraph(TransferableGraph1 tg) {\r
+ this.resourceCount = tg.resourceCount;\r
+ this.identities = tg.identities;\r
+ \r
+ int[] oldStatements = tg.statements;\r
+ @SuppressWarnings("unchecked")\r
+ ArrayList<Stat>[] newStatements = new ArrayList[tg.resourceCount];\r
+ for(int i=0;i<newStatements.length;++i)\r
+ newStatements[i] = new ArrayList<Stat>(2);\r
+ \r
+ for(int i=0;i<oldStatements.length;i+=4) {\r
+ int p = oldStatements[i+1];\r
+ int inv = oldStatements[i+2];\r
+ if(inv >= 0) {\r
+ inverses.put(p, inv);\r
+ inverses.put(inv, p);\r
+ }\r
+ }\r
+ \r
+ for(int i=0;i<oldStatements.length;i+=4) {\r
+ int s = oldStatements[i];\r
+ int p = oldStatements[i+1];\r
+ int inv = oldStatements[i+2];\r
+ int o = oldStatements[i+3];\r
+ if(inv < 0) {\r
+ if(inverses.contains(p))\r
+ inv = inverses.get(p);\r
+ else {\r
+ inv = resourceCount++;\r
+ inverses.put(p, inv);\r
+ inverses.put(inv, p);\r
+ }\r
+ }\r
+ newStatements[s].add(new Stat(p, o));\r
+ newStatements[o].add(new Stat(inv, s));\r
+ }\r
+ \r
+ // Statements\r
+ Stat[][] statements = new Stat[resourceCount][];\r
+ for(int i=0;i<tg.resourceCount;++i) {\r
+ int size = newStatements[i].size();\r
+ if(size == 0)\r
+ statements[i] = Stat.NO_STATS;\r
+ else\r
+ statements[i] = newStatements[i].toArray(new Stat[size]);\r
+ }\r
+ for(int i=tg.resourceCount;i<resourceCount;++i)\r
+ statements[i] = Stat.NO_STATS;\r
+ this.statements = statements;\r
+ \r
+ // Names\r
+ if(GraphMatching.DEBUG) {\r
+ names = new String[resourceCount];\r
+ for(Identity id : identities) {\r
+ if(id.definition instanceof External)\r
+ names[id.resource] = ((External)id.definition).name;\r
+ else if(id.definition instanceof Internal)\r
+ names[id.resource] = ((Internal)id.definition).name;\r
+ else if(id.definition instanceof Optional)\r
+ names[id.resource] = ((Optional)id.definition).name;\r
+ else if(id.definition instanceof Root)\r
+ names[id.resource] = "ROOT(" + ((Root)id.definition).name + ")";\r
+ }\r
+ for(int i=0;i<tg.resourceCount;++i)\r
+ if(names[i] == null)\r
+ names[i] = "r" + i;\r
+ for(int i=tg.resourceCount;i<resourceCount;++i)\r
+ names[i] = "inverse(" + names[inverses.get(i)] + ")";\r
+ }\r
+ \r
+ // Values\r
+ {\r
+ Variant[] values = new Variant[resourceCount];\r
+ for(Value value : tg.values)\r
+ values[value.resource] = value.value;\r
+ this.values = values;\r
+ }\r
+ }\r
+ \r
+}\r