/** Answer true iff this graph is isomorphic to <code>g</code> according to the algorithm (indeed, method) in <code>GraphMatcher</code>. */ @Override public boolean isIsomorphicWith( Graph g ) { checkOpen(); return g != null && GraphMatcher.equals( this, g ); }
/** * Return an isomorphism between the two models. * This function is nondeterministic in that it may return a * different bijection on each call, in cases where there are * multiple isomorphisms between the models. * @return <code>null</code> on failure or an array of related pairs (arrays of length 2) of anonymous nodes. <code>match(m1,m2)[i][0]</code> is from <code>m1</code>, and <code>match(m1,m2)[i][1]</code> is the corresponding node in <code>m2</code>. */ static public Node[][] match(Graph m1,Graph m2) { return new GraphMatcher(m1).match(new GraphMatcher(m2)); } /* NOTE: inner classes
private void check(int s) { if (( state & s) == 0 ) impossible(); }
private boolean bind() { Set<AnonResource> locallyBound = obligBindings(); if (locallyBound==null) // Contradiction reached - fail. return false; check(HASH_OK); Bucket bkt = smallestBucket(); if ( bkt == null ) return true; // No smallest bucket - we are finished. Bucket otherBkt = other.matchBucket(bkt); if ( otherBkt != null ) { AnonResource v = bkt.aMember(); Iterator<AnonResource> candidates = otherBkt.members(); // System.out.println("Guessing"); while ( candidates.hasNext() ) { check(HASH_OK|HASH_BAD); AnonResource otherV = candidates.next(); trace(true,"Guess: "); if (!bkt.bind(v,otherBkt,otherV)) continue; if (bind()) return true; v.unbind(); } } unbindAll(locallyBound); return false; } /*
boolean newBinding; Set<AnonResource> rslt = CollectionFactory.createHashedSet(); check(HASH_OK|HASH_BAD); do { if ( rehash(hashLevel) != other.rehash(hashLevel) ){ unbindAll(rslt); return null; Iterator<Bucket> singles = scanBuckets(); while ( singles.hasNext() ) { newBinding = true; Bucket bkt = singles.next(); Bucket otherBkt = other.matchBucket(bkt); if ( otherBkt == null ) { unbindAll(rslt); return null; unbindAll(rslt); return null;
private Node[][] match(GraphMatcher oth) { other = oth; oth.other = this; in(HASH_BAD); && m.size() > other.m.size() ) return null; int myPrep = prepare(other.m); if ( myPrep == -1 || myPrep != other.prepare(m) ) { return null; if ( bind() ) { if ( !unboundAnonResources.isEmpty() ) impossible(); Node rslt[][] = new Node[boundAnonResources.size()][]; int ix = 0;
private Bucket smallestBucket() { check(HASH_OK); Iterator<Bucket> bit = table.values().iterator(); Bucket smallB = null; int smallest = Integer.MAX_VALUE; while ( bit.hasNext() ) { Bucket b = bit.next(); int sz = b.size(); if ( sz < smallest ) { smallB = b; smallest = sz; } } return smallB; } private Bucket matchBucket(Bucket key) {
private void unbindAll(Set<AnonResource> s) { Iterator<AnonResource> rs = s.iterator(); while (rs.hasNext()) rs.next().unbind(); in(HASH_BAD); } private int prepare(Graph otherm) {
/** * Are the two models isomorphic? * The isomorphism is defined as a bijection between the anonymous * variables such that the statements are identical. * This is * described in * <a href="http://www.w3.org/TR/rdf-concepts#section-Graph-syntax"> * http://www.w3.org/TR/rdf-concepts#section-Graph-syntax * </a> */ static public boolean equals(Graph m1,Graph m2) { if ( m1 == m2 ) return true; return match(m1,m2) != null; }
static public int hashCode(Graph g) { ClosableIterator<Triple> ci = GraphUtil.findAll( g ); int hash = 0; GraphMatcher gm = new GraphMatcher(g); while ( ci.hasNext() ) { Triple t = ci.next(); hash += gm.new AnonStatement(t).myHashCode(null); } return hash; } /**
private Iterator<Bucket> scanBuckets() { // Looks through buckets, // if has single member then return in iterator. // Otherwise if some member of the bucket has friends // we can refine the hash, and we set refinableHash. check(HASH_OK); return new FilterIterator<Bucket>( new Filter<Bucket>() { @Override public boolean accept(Bucket o) { Bucket b = o; if (b.size()==1) return true; if (!refinableHash) { Iterator<AnonResource> it = b.members(); while ( it.hasNext() ) if (!it.next() .friends.isEmpty()) { refinableHash = true; break; } } return false; } },table.values().iterator()); } private void unbindAll(Set<AnonResource> s) {
/** Answer true iff this graph is isomorphic to <code>g</code> according to the algorithm (indeed, method) in <code>GraphMatcher</code>. */ public boolean isIsomorphicWith( Graph g ) { checkOpen(); return g != null && GraphMatcher.equals( this, g ); }
private Bucket matchBucket(Bucket key) { check(HASH_OK); Integer hash = new Integer(key.aMember().myHash); Bucket rslt = table.get(hash); if ( rslt != null ) { if ( key.size() != rslt.size() ) return null; } return rslt; }