Class: RdfContext::Graph
Overview
A simple graph to hold triples.
Graphs store triples, and the namespaces associated with those triples, where defined
Direct Known Subclasses
Instance Attribute Summary (collapse)
-
- (Object) allow_n3
Returns the value of attribute allow_n3.
-
- (Object) identifier
readonly
Returns the value of attribute identifier.
-
- (Object) store
readonly
Returns the value of attribute store.
-
- (Array<Triple>) triples(triple = Triple.new(nil, nil, nil), &block)
(also: #find)
readonly
Triples from graph, optionally matching subject, predicate, or object.
Instance Method Summary (collapse)
-
- (Graph) <<(triple)
Adds an more extant triples to a graph.
-
- (Boolean) ==(other)
Two graphs are equal (==) if each other if they are both graphs have the same identifiers and the same size.
-
- (Triple) [](item)
Indexed statement in serialized graph triples.
-
- (Graph) add(*triples)
Adds one or more extant triples to a graph.
-
- (Graph) add_seq(subject, predicate, objects)
Adds a list of resources as an RDF list by creating bnodes and first/rest triples.
-
- (Graph) add_triple(subject, predicate, object)
Adds a triple to a graph directly from the intended subject, predicate, and object.
-
- (Namespace) bind(namespace)
Bind a namespace to the graph.
-
- (Array<BNode>) bnodes
Get all BNodes with usage count used within graph.
-
- close(commit_pending_transaction = false)
Close the graph store.
-
- commit
Commit changes to graph.
-
- (Boolean) contains?(triple)
Check to see if this graph contains the specified triple.
- - (Boolean) context_aware?
-
- destroy(configuration = nil)
Destroy the store identified by configuration if supported If configuration is nil, remove the graph context.
-
- (Array<Triple>) get_by_type(object)
Get list of subjects having rdf:type == object.
-
- (Boolean) graph?
Returns `false`, overridden in BNode.
-
- (Boolean) has_bnode_identifier?(bn)
Detect the presence of a BNode in the graph, either as a subject or an object.
-
- (String) hash
Hash of graph, based on graph type and identifier.
-
- (Graph) initialize(options = {})
constructor
Create a Graph with the given store and identifier.
- - (Object) inspect
-
- (Boolean) isomorphic?(other)
Two graphs are isomorphic if each is an instance of the other, considering BNode equivalence.
-
- merge!(graph)
Merge a graph into this graph.
-
- (String) n3
Return an n3 identifier for the Graph.
-
- (Namespace) namespace(prefix)
Namespace for prefix.
- - (Hash{String => Namespace}) nsbinding
-
- (Array<Resource>) objects
List of distinct objects in graph.
-
- open(configuration = {})
Open the graph store.
-
- (Graph) parse(stream, uri = nil, options = {}, &block)
Parse source into Graph.
-
- (Array<Resource>) predicates
List of distinct predicates in graph.
-
- (String) prefix(namespace)
Prefix for namespace.
-
- (Hash{String => Resource}) properties(subject, recalc = false)
Resource properties.
-
- (String) qname(uri)
QName for a URI Try bound namespaces, and if not found, try well-known namespaces.
-
- remove(triple)
Remove a triple from the graph.
-
- rollback
Rollback active transactions.
-
- (Array<Resource>) seq(subject, predicate = RDF_NS.first)
Returns ordered rdf:_n objects or rdf:first, rdf:rest for a given subject.
-
- (IO, String) serialize(options)
Serialize graph using specified serializer class.
-
- (Integer) size
Number of Triples in the graph.
-
- (Array<Resource>) subjects
List of distinct subjects in graph.
-
- sync_properties(subject)
Synchronize properties to graph.
-
- (String) to_ntriples
Exports the graph to RDF in N-Triples form.
-
- (String) to_rdfxml
Exports the graph to RDF in RDF/XML form.
-
- (String) to_s
Output graph using to_ntriples.
-
- (URIRef) type_of(subject)
Get type(s) of subject, returns a list of symbols.
- - (Hash{URIRef => Namespace}) uri_binding
Methods inherited from Resource
#bnode?, #literal?, parse, #resource?, #uri?
Constructor Details
- (Graph) initialize(options = {})
Create a Graph with the given store and identifier.
The constructor accepts a store option, that will be used to store the graph data.
Stores can be context-aware or unaware. Unaware stores take up (some) less space but cannot support features that require context, such as true merging/demerging of sub-graphs and provenance.
The Graph constructor can take an identifier which identifies the Graph by name. If none is given, the graph is assigned a BNode for it's identifier. For more on named graphs, see: en.wikipedia.org/wiki/RDFLib
28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/rdf_context/graph.rb', line 28 def initialize( = {}) # Instantiate triple store @store = case [:store] when AbstractStore then [:store] when :list_store then ListStore.new when :memory_store then MemoryStore.new else ListStore.new end @allow_n3 = [:allow_n3] @identifier = Triple.coerce_node([:identifier]) || BNode.new end |
Instance Attribute Details
- (Object) allow_n3
Returns the value of attribute allow_n3
9 10 11 |
# File 'lib/rdf_context/graph.rb', line 9 def allow_n3 @allow_n3 end |
- (Object) identifier (readonly)
Returns the value of attribute identifier
7 8 9 |
# File 'lib/rdf_context/graph.rb', line 7 def identifier @identifier end |
- (Object) store (readonly)
Returns the value of attribute store
8 9 10 |
# File 'lib/rdf_context/graph.rb', line 8 def store @store end |
- (Array<Triple>) triples(triple = Triple.new(nil, nil, nil), &block) (readonly) Also known as: find
Triples from graph, optionally matching subject, predicate, or object. Delegates to Store#triples.
278 279 280 |
# File 'lib/rdf_context/graph.rb', line 278 def triples(triple = Triple.new(nil, nil, nil), &block) # :yields: triple, context @store.triples(triple, self, &block) || [] end |
Instance Method Details
- (Graph) <<(triple)
Adds an more extant triples to a graph. Delegates to Store.
235 236 237 238 239 |
# File 'lib/rdf_context/graph.rb', line 235 def << (triple) triple.validate_rdf unless @allow_n3 # Only add triples if n3-mode is set @store.add(triple, self) self end |
- (Boolean) ==(other)
Two graphs are equal (==) if each other if they are both graphs have the same identifiers and the same size.
If each graph has a BNode identifier, they are considered to be equal if the have the same size
492 493 494 495 496 |
# File 'lib/rdf_context/graph.rb', line 492 def ==(other) #puts "== size #{self.size} vs #{other.size}" if ::RdfContext::debug? other.is_a?(Graph) && self.size == other.size && ((other.identifier.is_a?(BNode) && identifier.is_a?(BNode)) || (other.identifier.to_s == identifier.to_s)) end |
- (Triple) [](item)
Indexed statement in serialized graph triples. Equivalent to graph.triples
206 |
# File 'lib/rdf_context/graph.rb', line 206 def [] (item); @store.item(item, self); end |
- (Graph) add(*triples)
Adds one or more extant triples to a graph. Delegates to Store.
253 254 255 256 257 258 259 260 261 262 |
# File 'lib/rdf_context/graph.rb', line 253 def add(*triples) = triples.last.is_a?(Hash) ? triples.pop : {} ctx = [:context] || @default_context || self triples.each do |t| t.validate_rdf unless @allow_n3 # Only add triples if n3-mode is set #puts "Add #{t.inspect}, ctx: #{ctx.identifier}" if $verbose @store.add(t, ctx) end self end |
- (Graph) add_seq(subject, predicate, objects)
Adds a list of resources as an RDF list by creating bnodes and first/rest triples. Removes existing sequence nodes.
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 |
# File 'lib/rdf_context/graph.rb', line 329 def add_seq(subject, predicate, objects) self.triples(Triple.new(subject, predicate, nil)).each do |t, ctx| bn = t.object while bn != RDF_NS.nil rest = properties(bn)[RDF_NS.rest.to_s].first remove(Triple.new(bn, nil, nil)) bn = rest end end remove(Triple.new(subject, predicate, nil)) @properties.delete(subject.to_s) if @properties.is_a?(Hash) if objects.empty? add_triple(subject, predicate, RDF_NS.nil) return self end if RDF_NS.first != predicate bn = BNode.new add_triple(subject, predicate, bn) subject = bn end last = objects.pop objects.each do |o| add_triple(subject, RDF_NS.first, o) bn = BNode.new add_triple(subject, RDF_NS.rest, bn) subject = bn end # Last item in list add_triple(subject, RDF_NS.first, last) add_triple(subject, RDF_NS.rest, RDF_NS.nil) self end |
- (Graph) add_triple(subject, predicate, object)
Adds a triple to a graph directly from the intended subject, predicate, and object.
220 221 222 223 |
# File 'lib/rdf_context/graph.rb', line 220 def add_triple(subject, predicate, object) self.add(Triple.new(subject, predicate, object)) self end |
- (Namespace) bind(namespace)
Bind a namespace to the graph.
155 156 157 158 |
# File 'lib/rdf_context/graph.rb', line 155 def bind(namespace) raise GraphException, "Can't bind #{namespace.inspect} as namespace" unless namespace.is_a?(Namespace) @store.bind(namespace) end |
- (Array<BNode>) bnodes
Get all BNodes with usage count used within graph
445 446 447 |
# File 'lib/rdf_context/graph.rb', line 445 def bnodes @store.bnodes(self) end |
- close(commit_pending_transaction = false)
This method returns an undefined value.
Close the graph store
Might be necessary for stores that require closing a connection to a database or releasing some resource.
94 95 96 |
# File 'lib/rdf_context/graph.rb', line 94 def close(commit_pending_transaction=false) @store.close(commit_pending_transaction) end |
- commit
This method returns an undefined value.
Commit changes to graph
73 |
# File 'lib/rdf_context/graph.rb', line 73 def commit; @store.commit; end |
- (Boolean) contains?(triple)
Check to see if this graph contains the specified triple
439 440 441 |
# File 'lib/rdf_context/graph.rb', line 439 def contains?(triple) @store.contains?(triple, self) end |
- (Boolean) context_aware?
61 |
# File 'lib/rdf_context/graph.rb', line 61 def context_aware?; @store.context_aware?; end |
- destroy(configuration = nil)
This method returns an undefined value.
Destroy the store identified by configuration if supported If configuration is nil, remove the graph context
66 67 68 69 |
# File 'lib/rdf_context/graph.rb', line 66 def destroy(configuration = nil) @store.destroy(configuration ? configuration : {:context => self}) self.freeze end |
- (Array<Triple>) get_by_type(object)
Get list of subjects having rdf:type == object
453 454 455 |
# File 'lib/rdf_context/graph.rb', line 453 def get_by_type(object) triples(Triple.new(nil, RDF_TYPE, object)).map {|t, ctx| t.subject} end |
- (Boolean) graph?
Returns `false`, overridden in BNode
46 47 48 |
# File 'lib/rdf_context/graph.rb', line 46 def graph? true end |
- (Boolean) has_bnode_identifier?(bn)
Detect the presence of a BNode in the graph, either as a subject or an object
429 430 431 432 433 434 |
# File 'lib/rdf_context/graph.rb', line 429 def has_bnode_identifier?(bn) self.triples do |triple, context| return true if triple.subject.eql?(bn) || triple.object.eql?(bn) end false end |
- (String) hash
Hash of graph, based on graph type and identifier
56 57 58 |
# File 'lib/rdf_context/graph.rb', line 56 def hash [self.class.to_s, self.identifier].hash end |
- (Object) inspect
50 51 52 |
# File 'lib/rdf_context/graph.rb', line 50 def inspect "#{self.class}[id=#{identifier},store=#{store.inspect}]" end |
- (Boolean) isomorphic?(other)
Two graphs are isomorphic if each is an instance of the other, considering BNode equivalence. This may be done by creating a new graph an substituting each permutation of BNode identifiers from self to other until every permutation is exhausted, or a textual equivalence is found after sorting each graph.
We just follow Python RDFlib's lead and do a simple comparison
506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 |
# File 'lib/rdf_context/graph.rb', line 506 def isomorphic?(other) return false unless self == other bn_self = bnodes.values.sort bn_other = other.bnodes.values.sort puts "isomorphic? bnodes '#{bn_self.to_sentence}' vs '#{bn_other.to_sentence}'" if ::RdfContext::debug? return false unless bn_self == bn_other # Check each triple to see if it's contained in the other graph triples do |t, ctx| next if t.subject.is_a?(BNode) || t.predicate.is_a?(BNode) || t.object.is_a?(BNode) puts "isomorphic? contains '#{t.to_ntriples}: #{other.contains?(t)}'" if ::RdfContext::debug? return false unless other.contains?(t) end # For each BNode, check permutations of similar bnodes in other graph bnode_permutations(bnodes, other.bnodes) do |bn_map| puts "bnode permutations: #{bn_map.inspect}" if ::RdfContext::debug? # bn_map contains 1-1 mapping of bnodes from self to other catch :next_perm do triples do |t, ctx| next unless t.subject.is_a?(BNode) || t.predicate.is_a?(BNode) || t.object.is_a?(BNode) subject, predicate, object = t.subject, t.predicate, t.object subject = bn_map[subject] if bn_map.has_key?(subject) predicate = bn_map[predicate] if bn_map.has_key?(predicate) object = bn_map[object] if bn_map.has_key?(object) tn = Triple.new(subject, predicate, object) puts " isomorphic? contains '#{tn.inspect}': #{other.contains?(tn)}" if ::RdfContext::debug? next if other.contains?(tn) puts " no, next permutation" if ::RdfContext::debug? # Not a match, try next permutation throw :next_perm end # If we matched all triples in the graph using this permutation, we're done return true end end # Exhausted all permutations, unless there were no bnodes bn_self.length == 0 end |
- merge!(graph)
This method returns an undefined value.
Merge a graph into this graph
467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 |
# File 'lib/rdf_context/graph.rb', line 467 def merge!(graph) raise GraphException.new("merge without a graph") unless graph.is_a?(Graph) # Map BNodes from source Graph to new BNodes bn = graph.bnodes bn.keys.each {|k| bn[k] = BNode.new} graph.triples do |triple, context| # If triple contains bnodes, remap to new values if triple.subject.is_a?(BNode) || triple.predicate.is_a?(BNode) || triple.object.is_a?(BNode) triple = triple.clone triple.subject = bn[triple.subject] if triple.subject.is_a?(BNode) triple.predicate = bn[triple.predicate] if triple.predicate.is_a?(BNode) triple.object = bn[triple.object] if triple.object.is_a?(BNode) end self << triple end end |
- (String) n3
Return an n3 identifier for the Graph
421 422 423 |
# File 'lib/rdf_context/graph.rb', line 421 def n3 "[#{self.identifier.to_n3}]" end |
- (Namespace) namespace(prefix)
Namespace for prefix
181 |
# File 'lib/rdf_context/graph.rb', line 181 def namespace(prefix); @store.namespace(prefix); end |
- (Hash{String => Namespace}) nsbinding
161 |
# File 'lib/rdf_context/graph.rb', line 161 def nsbinding; @store.nsbinding; end |
- (Array<Resource>) objects
List of distinct objects in graph
202 |
# File 'lib/rdf_context/graph.rb', line 202 def objects; @store.objects(self); end |
- open(configuration = {})
This method returns an undefined value.
Open the graph store
Might be necessary for stores that require opening a connection to a database or acquiring some resource.
84 85 86 |
# File 'lib/rdf_context/graph.rb', line 84 def open(configuration = {}) @store.open(configuration) end |
- (Graph) parse(stream, uri = nil, options = {}, &block)
Parse source into Graph.
Merges results into a common Graph
561 562 563 564 |
# File 'lib/rdf_context/graph.rb', line 561 def parse(stream, uri = nil, = {}, &block) # :yields: triple @allow_n3 ||= [:allow_n3] Parser.parse(stream, uri, .merge(:graph => self), &block) end |
- (Array<Resource>) predicates
List of distinct predicates in graph
198 |
# File 'lib/rdf_context/graph.rb', line 198 def predicates; @store.predicates(self); end |
- (String) prefix(namespace)
Prefix for namespace
186 |
# File 'lib/rdf_context/graph.rb', line 186 def prefix(namespace); @store.prefix(namespace); end |
- (Hash{String => Resource}) properties(subject, recalc = false)
Resource properties
Properties arranged as a hash with the predicate Term as index to an array of resources or literals
384 385 386 387 388 389 390 391 392 393 394 395 396 397 |
# File 'lib/rdf_context/graph.rb', line 384 def properties(subject, recalc = false) @properties ||= {} @properties.delete(subject.to_s) if recalc @properties[subject.to_s] ||= begin hash = Hash.new self.triples(Triple.new(subject, nil, nil)).map do |t, ctx| pred = t.predicate.to_s hash[pred] ||= [] hash[pred] << t.object end hash end end |
- (String) qname(uri)
QName for a URI Try bound namespaces, and if not found, try well-known namespaces
170 171 172 173 174 175 176 |
# File 'lib/rdf_context/graph.rb', line 170 def qname(uri) uri.to_qname(self.uri_binding) || begin qn = uri.to_qname(WELLKNOWN_NAMESPACES) self.bind(uri.namespace) if qn qn end end |
- remove(triple)
This method returns an undefined value.
Remove a triple from the graph. Delegates to store. Nil matches all triples and thus empties the graph
268 269 270 271 |
# File 'lib/rdf_context/graph.rb', line 268 def remove(triple) @properties.delete(triple.subject.to_s) if @properties.is_a?(Hash) @store.remove(triple, self) end |
- rollback
This method returns an undefined value.
Rollback active transactions
77 |
# File 'lib/rdf_context/graph.rb', line 77 def rollback; @store.rollback; end |
- (Array<Resource>) seq(subject, predicate = RDF_NS.first)
Returns ordered rdf:_n objects or rdf:first, rdf:rest for a given subject
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 |
# File 'lib/rdf_context/graph.rb', line 287 def seq(subject, predicate = RDF_NS.first) props = properties(subject) rdf_type = (props[RDF_TYPE.to_s] || []) #puts "seq; #{rdf_type} #{rdf_type - [RDF_NS.Seq, RDF_NS.Bag, RDF_NS.Alt]}" if rdf_type.include?(RDF_NS.Seq) || rdf_type.include?(RDF_NS.Bag) || rdf_type.include?(RDF_NS.Alt) props.keys.select {|k| k.match(/#{RDF_NS.uri}_(\d)$/)}. sort_by {|i| i.sub(RDF_NS._.to_s, "").to_i}. map {|key| props[key]}. flatten elsif !self.triples(Triple.new(subject, predicate, nil)).empty? # N3-style first/rest chain unless predicate == RDF_NS.first subject = (properties(subject)[predicate.to_s] || []).first end list = [] while subject != RDF_NS.nil props = properties(subject) f = props[RDF_NS.first.to_s] if f.to_s.empty? || f.first == RDF_NS.nil subject = RDF_NS.nil else list += f subject = props[RDF_NS.rest.to_s].first end end list else [] end end |
- (IO, String) serialize(options)
Serialize graph using specified serializer class.
Other options are parser specific.
107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/rdf_context/graph.rb', line 107 def serialize() serializer = case [:format].to_sym when AbstractSerializer then [:serializer] when :nt, :ntriples then NTSerializer.new(self) when :ttl, :turtle, :n3 then TurtleSerializer.new(self) when :rdf, :xml, :rdfxml then XmlSerializer.new(self) else NTSerializer.new(self) end io = [:io] || StringIO.new serializer.serialize(io, ) [:io] ? io : (io.rewind; io.read) end |
- (Integer) size
Number of Triples in the graph
190 |
# File 'lib/rdf_context/graph.rb', line 190 def size; @store.size(self); end |
- (Array<Resource>) subjects
List of distinct subjects in graph
194 |
# File 'lib/rdf_context/graph.rb', line 194 def subjects; @store.subjects(self); end |
- sync_properties(subject)
This method returns an undefined value.
Synchronize properties to graph
403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 |
# File 'lib/rdf_context/graph.rb', line 403 def sync_properties(subject) props = properties(subject) # First remove all properties for subject remove(Triple.new(subject, nil, nil)) # Iterate through and add properties to graph props.each_pair do |pred, list| predicate = URIRef.intern(pred) [list].flatten.compact.each do |object| add(Triple.new(subject, predicate, object)) end end @properties.delete(subject.to_s) # Read back in from graph end |
- (String) to_ntriples
Exports the graph to RDF in N-Triples form.
131 132 133 |
# File 'lib/rdf_context/graph.rb', line 131 def to_ntriples serialize(:format => :nt) end |
- (String) to_rdfxml
Exports the graph to RDF in RDF/XML form.
143 144 145 |
# File 'lib/rdf_context/graph.rb', line 143 def to_rdfxml serialize(:format => :rdfxml) end |
- (String) to_s
Output graph using to_ntriples
137 |
# File 'lib/rdf_context/graph.rb', line 137 def to_s; self.to_ntriples; end |
- (URIRef) type_of(subject)
Get type(s) of subject, returns a list of symbols
460 461 462 |
# File 'lib/rdf_context/graph.rb', line 460 def type_of(subject) triples(Triple.new(subject, RDF_TYPE, nil)).map {|t, ctx| t.object} end |