operator == method
- Object other
We are implementing equals ourselves instead of using equatable, because we want to compare the sets of triples, not the order
Compares this graph to another object for equality. Two RDF graphs are equal if they contain the same set of triples, regardless of the order in which they were added.
Important: This implementation performs syntactic equality based on exact triple matching. Two graphs that are semantically equivalent but have different BlankNodeTerm instances will NOT be considered equal, even if they represent the same RDF structure. BlankNodeTerm instances are only equal if they are the identical object instance.
For semantic graph comparison: Use isIsomorphicGraphs
from
lib/src/canonical/canonical_util.dart
, which implements RDF graph
isomorphism based on the RDF Canonicalization specification. This
provides true semantic equality but is more computationally expensive
and not consistent with hashCode.
Alternative: Consider using CanonicalRdfGraph
which lazily computes
a canonical serialized form and uses it for both comparison and hashing,
providing consistent semantic equality with proper hash code behavior.
This implementation treats RDF graphs as sets rather than lists, which aligns with the syntactic definition of RDF graphs in the specification.
Example:
// These graphs are syntactically different due to different blank nodes
final graph1 = RdfGraph(triples: [Triple(BlankNodeTerm(), knows, alice)]);
final graph2 = RdfGraph(triples: [Triple(BlankNodeTerm(), knows, alice)]);
assert(graph1 != graph2); // Different BlankNodeTerm instances
// For semantic comparison:
import 'package:rdf_core/src/canonical/canonical_util.dart';
assert(isIsomorphicGraphs(graph1, graph2)); // Semantically equivalent
Implementation
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
if (other is! RdfGraph) return false;
// Compare triple sets (order doesn't matter in RDF graphs)
final Set<Triple> thisTriples = _triples.toSet();
final Set<Triple> otherTriples = other._triples.toSet();
return thisTriples.length == otherTriples.length &&
thisTriples.containsAll(otherTriples);
}