packages/extension-map/test/Map-test.js
/** graphEquals: test if two graphs are isomorphic through some bnode mapping.
 *
 * this: one of the graphs to test, referred to as "left" below.
 * right: the other graph to test.
 * m: (optional) writable mapping from left bnodes to write bnodes.
 * returns: true or false
 * side effects: m is populated with a working mapping.
 */
test if two graphs are isomorphic through some bnode mapping.
this: one of the graphs to test, referred to as "left" below.
right: the other graph to test.
m: (optional) writable mapping from left bnodes to write bnodes.
returns: true or false
side effects: m is populated with a working mapping.
test if two graphs are isomorphic through some bnode mapping . this : one of the graphs to test referred to as " left " below . right : the other graph to test . m : ( optional ) writable mapping from left bnodes to write bnodes . returns : true or false side effects : m is populated with a working mapping .
function graphEquals (right, m) {
  if (this.size !== right.size)
    return false;
  m = m || {};                                    
  var back = Object.keys(m).reduce(function (ret, from) { 
    ret[m[from]] = from;                                  
    return ret;
  }, {});
  function match (g) {
    function val (term, mapping) {
      mapping = mapping || m;                     
      if (ShExTerm.isBlank(term))
        return (term in mapping) ? mapping[term] : null 
      else
        return term;                              
    }
    if (g.length == 0)                            
      return true;
    var t = g.pop(), s = val(t.subject), o = val(t.object); 
    var tm = right.getQuads(
      s ? ShExTerm.externalTerm(s, require("n3").DataFactory) : null,
      ShExTerm.externalTerm(t.predicate, require("n3").DataFactory),
      o ? ShExTerm.externalTerm(o, require("n3").DataFactory) : null  
    ).map(ShExTerm.internalTriple);
    var r = tm.reduce(function (ret, triple) {    
      if (ret) return true;                       
      var adds = [];                              
      function add (from, to) {
        if (val(from) === null) {                   
          if (val(to, back) === null) {                
            adds.push(from);                           
            m[from] = to;
            back[to] = from;
            return true;
          } else {                                     
            return false;                              
          }
        } else {                                    
          return true;                                 
        }
      }
      if (!add(t.subject, triple.subject) ||     
          !add(t.object, triple.object) ||       
          !match(g)) {                           
        adds.forEach(function (added) {             
          delete back[m[added]];
          delete m[added];
        });
        return false;
      } else
        return true;
    }, false);                                    
    if (!r) {
      g.push(t);                                  
    }
    return r;
  }
  return match(this.getQuads(null, null, null)     
               .map(ShExTerm.internalTriple));
}
function graphEquals ( right , m ) { if ( this . size !== right . size ) return false ; m = m || { } ; var back = Object . keys ( m ) . reduce ( function ( ret , from ) { ret [ m [ from ] ] = from ; return ret ; } , { } ) ; function match ( g ) { function val ( term , mapping ) { mapping = mapping || m ; if ( ShExTerm . isBlank ( term ) ) return ( term in mapping ) ? mapping [ term ] : null else return term ; } if ( g . length == 0 ) return true ; var t = g . pop ( ) , s = val ( t . subject ) , o = val ( t . object ) ; var tm = right . getQuads ( s ? ShExTerm . externalTerm ( s , require ( "n3" ) . DataFactory ) : null , ShExTerm . externalTerm ( t . predicate , require ( "n3" ) . DataFactory ) , o ? ShExTerm . externalTerm ( o , require ( "n3" ) . DataFactory ) : null ) . map ( ShExTerm . internalTriple ) ; var r = tm . reduce ( function ( ret , triple ) { if ( ret ) return true ; var adds = [ ] ; function add ( from , to ) { if ( val ( from ) === null ) { if ( val ( to , back ) === null ) { adds . push ( from ) ; m [ from ] = to ; back [ to ] = from ; return true ; } else { return false ; } } else { return true ; } } if ( ! add ( t . subject , triple . subject ) || ! add ( t . object , triple . object ) || ! match ( g ) ) { adds . forEach ( function ( added ) { delete back [ m [ added ] ] ; delete m [ added ] ; } ) ; return false ; } else return true ; } , false ) ; if ( ! r ) { g . push ( t ) ; } return r ; } return match ( this . getQuads ( null , null , null ) . map ( ShExTerm . internalTriple ) ) ; }
graphEquals: test if two graphs are isomorphic through some bnode mapping.
graphEquals : test if two graphs are isomorphic through some bnode mapping .
// Left→right mappings (optional argument). // Right→left mappings //  populated if m was passed in. // Mostly used for left→right mappings. // Bnodes get current binding or null. // Other terms evaluate to themselves. // Success if there's nothing left to match. // Take the first triple in left. // Find candidates in right. // Walk through candidates in right. // Only examine first successful mapping. // List of candidate mappings. // If there's no binding from tₗ to tᵣ, // If we can bind to to the object //  add a candidate binding. // Otherwise, //  it's not a viable mapping. // Otherwise, //  there's no new binding. // If the bindings for tₗ.s→tᵣ.s fail // or the bindings for tₗ.o→tᵣ.o fail // of the remaining triples fail, // remove each added binding. // Empty tm returns failure. // No binding for t in cancidate mapping. // Start with all triples.