Parent

Namespace

Included Modules

Redleaf::Graph

An RDF graph class

Subversion Id

 $Id$

Authors

Portions of this file (namely the graph-equivalence stuff) were ported to Ruby from the Test::RDF Perl module written by Michael Hendricks. His copyright is:

  Copyright (C) 2006 Michael Hendricks <michael@palmcluster.org>

  This program is free software; you can redistribute it and/or modify it
  under the same terms as Perl itself.

Copyright © 2008-2009, Michael Granger All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Constants

SVNRev

SVN Revision

SVNId

SVN Id

Public Class Methods

model_types → hash click to toggle source

Return a hash describing all model types supported by the underlying Redland library.

static VALUE
rleaf_redleaf_graph_s_model_types( VALUE klass ) 
new() → graph new( store ) → graph click to toggle source

Create a new Redleaf::Graph object. If the optional store object is given, it is used as the backing store for the graph. If none is specified a new Redleaf::MemoryHashStore is used.

static VALUE 
rleaf_redleaf_graph_initialize( int argc, VALUE *argv, VALUE self ) 
serializers → hash click to toggle source

Return a Hash of supported serializers from the underlying Redland library.

   Redleaf::Parser.serializers
   # => { "rss-1.0"       => "RSS 1.0",
   #      "rdfxml"        => "RDF/XML",
   #      "json-triples"  => "RDF/JSON Triples",
   #      "rdfxml-abbrev" => "RDF/XML (Abbreviated)",
   #      "rdfxml-xmp"    => "RDF/XML (XMP Profile)",
   #      "turtle"        => "Turtle",
   #      "ntriples"      => "N-Triples",
   #      "json"          => "RDF/JSON Resource-Centric",
   #      "dot"           => "GraphViz DOT format",
   #      "atom"          => "Atom 1.0" }
static VALUE
rleaf_redleaf_graph_s_serializers( VALUE klass ) 
valid_format?( format ) click to toggle source

Returns true if the specified format is supported by the Redland backend.

    # File lib/redleaf/graph.rb, line 86
86:     def self::valid_format?( format )
87:         Redleaf.logger.debug "Checking validity of format %p" % [ format ]
88:         return self.serializers.key?( format )
89:     end

Public Instance Methods

<<(...) click to toggle source

Alias for #append

===( other_graph ) click to toggle source

Alias for #is_equivalent_to?

[](p1, p2, p3) click to toggle source

Alias for #search

append( *statements ) → Redleaf::Graph graph << statement → Redleaf::Graph click to toggle source

Append statements to the graph, either as Redleaf::Statements, valid triples in Arrays, or a subgraph of nodes expressed in a Hash.

   require 'redleaf/constants'
   incude Redleaf::Constants::CommonNamespaces # (for the FOAF namespace constant)

   MY_FOAF = Redleaf::Namspace.new( 'http://deveiate.org/foaf.xml#' )
   michael = MY_FOAF[:me]

   graph = Redleaf::Graph.new

   statement1 = Redleaf::Statement.new( michael, FOAF[:family_name], 'Granger' )
   statement2 = [ michael, FOAF[:givenname], 'Michael' ]
   graph.append( statement1, statement2 )

   graph << [ michael, FOAF[:homepage], URI('http://deveiate.org/') ]
static VALUE
rleaf_redleaf_graph_append( int argc, VALUE *argv, VALUE self ) 
Also aliased as: <<
arc(p1, p2) click to toggle source

Alias for #predicate

arcs(p1, p2) click to toggle source

Alias for #predicates

arcs_in(p1) click to toggle source
arcs_in?(p1, p2) click to toggle source
arcs_out(p1) click to toggle source

Alias for #predicates_about

arcs_out?(p1, p2) click to toggle source
contains?(p1) click to toggle source

Alias for #include?

context_info() click to toggle source

Return a string describing the status of contexts in the receiving graph. This will be a count of the contexts if they are enabled, or “contexts not enabled” if they aren’t enabled.

     # File lib/redleaf/graph.rb, line 196
196:     def context_info
197:         if self.contexts_enabled?
198:             return "%d contexts" % [ self.contexts.length ]
199:         else
200:             return "contexts disabled"
201:         end
202:     end
contexts → array click to toggle source

Returns an Array of URIs describing the contexts in the receiving graph.

static VALUE
rleaf_redleaf_graph_contexts( VALUE self ) 
contexts_enabled?() click to toggle source
delete(p1) click to toggle source

Alias for #remove

dup → graph click to toggle source

Duplicate the receiver and return the copy.

static VALUE
rleaf_redleaf_graph_dup( VALUE self ) 
each() click to toggle source

Alias for #each_statement

each_statement {|statement| block } → graph each {|statement| block } → graph click to toggle source

Call block once for each statement in the graph.

static VALUE
rleaf_redleaf_graph_each_statement( VALUE self ) 
Also aliased as: each
empty?() click to toggle source

Returns true if the graph does not contain any statements.

     # File lib/redleaf/graph.rb, line 101
101:     def empty?
102:         return self.size.zero?
103:     end
Also aliased as: is_empty?
equivalent_to?( other_graph ) click to toggle source

Alias for #is_equivalent_to?

execute_query( qstring, language=:sparql, limit=nil, offset=nil ) → queryresult click to toggle source

Run the query in the given query string (qstring) against the graph. The query language specifies the query language, and limit, and offset can be used to limit the results. The #query method is the public interface to this method.

static VALUE
rleaf_redleaf_graph_execute_query( int argc, VALUE *argv, VALUE self ) 
has_arcs_in?(p1, p2) click to toggle source
has_arcs_out?(p1, p2) click to toggle source
has_predicate_about?( subject, predicate ) → true or false click to toggle source

Returns true if the graph has at least one statement with the specified subject and predicate.

static VALUE
rleaf_redleaf_graph_has_predicate_about_p( VALUE self, VALUE subject, VALUE predicate ) 
Also aliased as: has_arcs_out?, arcs_out?
has_predicate_entailing?( predicate, object ) → true or false click to toggle source

Returns true if the graph has at least one statement with the specified predicate and object.

static VALUE
rleaf_redleaf_graph_has_predicate_entailing_p( VALUE self, VALUE predicate, VALUE object ) 
Also aliased as: has_arcs_in?, arcs_in?
include?( statement ) → true or false contains?( statement ) → true or false click to toggle source

Return true if the receiver contains the specified statement, which can be either a Redleaf::Statement object or a valid triple in an Array.

static VALUE
rleaf_redleaf_graph_include_p( VALUE self, VALUE statement ) 
Also aliased as: contains?
include_object?( object ) → true or false click to toggle source

Returns true if the graph contains any statements with the specified object.

static VALUE
rleaf_redleaf_graph_include_object_p( VALUE self, VALUE object ) 
include_subject?( subject ) → true or false click to toggle source

Returns true if the graph contains any statements with the specified subject.

static VALUE
rleaf_redleaf_graph_include_subject_p( VALUE self, VALUE subject ) 
inspect() click to toggle source

Return a human-readable representation of the object suitable for debugging.

     # File lib/redleaf/graph.rb, line 184
184:     def inspect
185:         return "#<%s:0x%x %d statements, %s>" % [
186:             self.class.name,
187:             self.object_id * 2,
188:             self.size,
189:             self.context_info
190:         ]
191:     end
is_empty?() click to toggle source

Alias for #empty?

is_equivalent_to?( other_graph ) click to toggle source

call-seq:

   graph.is_equivalent_to?( other_graph )   -> true or false
   graph === other_graph                    -> true or false

Equivalence method — compare the receiving graph with other_graph according to the graph equivalency rules in:

  http://www.w3.org/TR/rdf-concepts/#section-graph-equality
     # File lib/redleaf/graph.rb, line 145
145:     def is_equivalent_to?( other_graph )
146:         unless other_graph.size == self.size
147:             self.log.debug "Graphs differ in size (%d vs. %d)" % [ self.size, other_graph.size ]
148:             return false
149:         end
150: 
151:         other = other_graph.dup
152:         bnode_map = BnodeMap.new
153:         difference = nil
154: 
155:         difference = self.find do |stmt|
156:             # If the copy of the other graph has an equivalent statement, remove it
157:             # and move on to the next one.
158:             if other.remove_equivalent_statement( stmt, bnode_map )
159:                 next
160: 
161:             # Otherwise, we've found a difference
162:             else
163:                 stmt
164:             end
165:         end
166: 
167:         buf = ''
168:         PP.pp( bnode_map, buf )
169:         self.log.debug "Bnode map after comparison:\n%s" % [ buf ]
170: 
171:         if difference
172:             self.log.debug "%p is not equivalent to %p because it does not contain %p" %
173:                 [ self, other_graph, difference ]
174:             return false
175:         else
176:             return true
177:         end
178:     end
Also aliased as: equivalent_to?, ===
length() click to toggle source

Alias for #size

load( uri ) → Fixnum click to toggle source

Parse the RDF at the specified uri into the receiving graph. Returns the number of statements added to the graph (if the underlying store supports ).

   graph = Redleaf::Graph.new
   graph.load( "http://bigasterisk.com/foaf.rdf" )
   graph.load( "http://www.w3.org/People/Berners-Lee/card.rdf" )
   graph.load( "http://danbri.livejournal.com/data/foaf" )

   graph.size
static VALUE
rleaf_redleaf_graph_load( VALUE self, VALUE uri ) 
object( subject, predicate ) → nodes click to toggle source

Return one object of a statement with the specified subject and predicate.

static VALUE 
rleaf_redleaf_graph_object( VALUE self, VALUE subject, VALUE predicate ) 
Also aliased as: target
objects( subject, predicate ) → [ nodes ] click to toggle source

Return an Array of object nodes from the graph that have the specified subject and predicate.

static VALUE 
rleaf_redleaf_graph_objects( VALUE self, VALUE subject, VALUE predicate ) 
Also aliased as: targets
predicate( subject, object ) → nodes click to toggle source

Return one predicate of a statement with the specified subject and object.

static VALUE 
rleaf_redleaf_graph_predicate( VALUE self, VALUE subject, VALUE object ) 
Also aliased as: arc
predicates( subject, object ) → [ nodes ] click to toggle source

Return an Array of predicate nodes from the graph that have the specified subject and object.

static VALUE 
rleaf_redleaf_graph_predicates( VALUE self, VALUE subject, VALUE object ) 
Also aliased as: arcs
predicates_about( subject ) → nodes click to toggle source

Returns an Array of predicates (URI objects) that point from the specified subject.

static VALUE 
rleaf_redleaf_graph_predicates_about( VALUE self, VALUE subject ) 
Also aliased as: arcs_out
predicates_entailing( object ) → nodes click to toggle source

Returns an Array of predicates (URI objects) that point to the specified object.

static VALUE 
rleaf_redleaf_graph_predicates_entailing( VALUE self, VALUE object ) 
Also aliased as: arcs_in
query( querystring, *args ) click to toggle source

Run a SPARQL query against the graph. The optional prefixes hash can be used to set up prefixes in the query.

   require 'redleaf/constants'
   include Redleaf::Constants::CommonNamespaces

   # Declare a custom namespace and create a graph with a node about its title
   book = Redleaf::Namespace.new( 'http://example.org/book' )
   graph = Redleaf::Graph.new
   graph << [ book[:book1], DC[:title], "SPARQL Tutorial" ]

   qstring = 'SELECT ?title WHERE { book:book1 dc:title ?title }'
   res = graph.query( qstring, :book => book, :dc => DC )
   # => #<Redleaf::BindingsQueryResult:0x07466b3>

   res.each do |row|
           puts row.title
   end
     # File lib/redleaf/graph.rb, line 126
126:     def query( querystring, *args )
127:         prefixes = args.last.is_a?( Hash ) ? args.last : {}
128: 
129: 
130:         prelude = prefixes.collect {|prefix, uri| "PREFIX %s: <%s>\n" % [ prefix, uri ] }.join
131:         querystring = prelude + querystring
132:         self.log.debug "Querystring is: %p" % [ querystring ]
133: 
134:         return self.execute_query( querystring )
135:     end
remove( statement ) → array click to toggle source

Removes one or more statements from the graph that match the specified statement (either a Redleaf::Statement or a valid triple in an Array) and returns any that were removed.

Any nil values in the statement will match any value.

   # Set a new home page for the Redleaf project, preserving the old one
   # as the 'old_homepage'
   stmt = graph.remove([ :Redleaf, DOAP[:homepage], nil ])
   stmt.predicate = DOAP[:old_homepage]
   graph.append( stmt )
   graph.append([ :Redleaf, DOAP[:homepage],
                  URL.parse('http://deveiate.org/projects/Redleaf') ])
static VALUE
rleaf_redleaf_graph_remove( VALUE self, VALUE statement ) 
Also aliased as: delete
search( subject, predicate, object ) → array graph[ subject, predicate, object ] → array click to toggle source

Search for statements in the graph with the specified subject, predicate, and object and return them. If subject, predicate, or object are nil, they will match any value.

   # Match any statements about authors
   graph.load( 'http://deveiant.livejournal.com/data/foaf' )

   #
   graph[ nil, FOAF[:knows], nil ]  # => [...]
static VALUE
rleaf_redleaf_graph_search( VALUE self, VALUE subject, VALUE predicate, VALUE object ) 
Also aliased as: []
serialized_as( format, nshash={} ) → string click to toggle source

Return the graph serialized to a String in the specified format. Valid +format+s are keys of the Hash returned by ::serializers.

The nshash argument can be used to set namespaces in the output (for serializers that support them). It should be of the form:

  { :nsname => <namespace URI> }

Examples:

   turtle = graph.serialized_as( 'turtle' )
   xml = graph.serialized_as( 'rdfxml-abbrev', :foaf => 'http://xmlns.com/foaf/0.1/' )
static VALUE
rleaf_redleaf_graph_serialized_as( int argc, VALUE *argv, VALUE self ) 
size => fixnum click to toggle source

Return the number of statements in the graph. If the underlying store doesn’t support fetching the size of the graph, the return value will be negative.

static VALUE
rleaf_redleaf_graph_size( VALUE self ) 
Also aliased as: length
source(p1, p2) click to toggle source

Alias for #subject

sources(p1, p2) click to toggle source

Alias for #subjects

statements → array click to toggle source

Return an Array of all the statements in the graph.

static VALUE 
rleaf_redleaf_graph_statements( VALUE self ) 
store → a_store click to toggle source

Return the Redleaf::Store associated with the receiver.

static VALUE
rleaf_redleaf_graph_store( VALUE self ) 
store = new_store click to toggle source

Associate the given new_store with the receiver, breaking the association between it and any previous Store.

static VALUE
rleaf_redleaf_graph_store_eq( VALUE self, VALUE storeobj ) 
subject( predicate, object ) → nodes click to toggle source

Return one subject of a statement with the specified predicate and object.

static VALUE 
rleaf_redleaf_graph_subject( VALUE self, VALUE predicate, VALUE object ) 
Also aliased as: source
subjects( predicate, object ) → [ nodes ] click to toggle source

Return an Array of subject nodes from the graph that have the specified predicate and object.

static VALUE 
rleaf_redleaf_graph_subjects( VALUE self, VALUE predicate, VALUE object ) 
Also aliased as: sources
supports_contexts? → true or false click to toggle source

Returns true if the receiving model supports contexts.

static VALUE
rleaf_redleaf_graph_supports_contexts_p( VALUE self ) 
Also aliased as: contexts_enabled?
sync click to toggle source

Synchronise the model to the model implementation.

static VALUE
rleaf_redleaf_graph_sync( VALUE self ) 
target(p1, p2) click to toggle source

Alias for #object

targets(p1, p2) click to toggle source

Alias for #objects

to_json() click to toggle source

Defined explicitly so the ‘json’ library’s default implementation doesn’t override the serializer.

     # File lib/redleaf/graph.rb, line 207
207:     def to_json
208:         return self.serialized_as( 'json' )
209:     end
to_xml() click to toggle source

Return the graph as RDF/XML.

     # File lib/redleaf/graph.rb, line 213
213:     def to_xml
214:         return self.to_rdfxml
215:     end

Protected Instance Methods

method_missing( sym, *args ) click to toggle source

Proxy method — handle #to_«format» methods by invoking a serializer for the specified format.

     # File lib/redleaf/graph.rb, line 225
225:     def method_missing( sym, *args )
226:         super unless sym.to_s =~ /^to_(\w+)$/
227: 
228:         format = $1.tr( '_', '-' )
229:         super unless self.class.valid_format?( format )
230: 
231:         serializer = lambda { self.serialized_as(format) }
232: 
233:         # Install the closure as a new method and call it
234:         self.class.send( :define_method, sym, &serializer )
235:         return self.method( sym ).call
236:     end
remove_equivalent_statement( statement, bnode_map ) click to toggle source

Given the specified bnode_map (a BnodeMap object which contains an equivalence mapping between blank nodes in the receiver and statement), remove the given statement from the receiver if an equivalent one exists. If an equivalent exists, return it, otherwise return nil. This was ported from Michael Hendricks’s Test::RDF Perl module. :TODO: Refactor into multiple methods

     # File lib/redleaf/graph.rb, line 245
245:     def remove_equivalent_statement( statement, bnode_map )
246:         subject     = statement.subject
247:         predicate = statement.predicate
248:         object      = statement.object
249: 
250:         subject_is_floating = false
251:         object_is_floating  = false
252: 
253:         # anchor the subject if possible
254:         if subject.is_a?( Symbol )
255:             subject_is_floating = true
256:             if mapped = bnode_map[ subject ]
257:                 subject = mapped
258:                 subject_is_floating = false
259:             end
260:         end
261: 
262:         # anchor the object if possible
263:         if object.is_a?( Symbol )
264:             object_is_floating = true
265:             if mapped = bnode_map[ object ]
266:                 object = mapped
267:                 object_is_floating = false
268:             end
269:         end
270: 
271:         # If both the subject and object are unmapped bnodes, select the first
272:         # triple with the same predicate and unmapped bnode subject and objects
273:         if subject_is_floating && object_is_floating
274:             self.log.debug "Anchoring a subject (%p) and an object (%p)" %
275:                 [ subject, object ]
276:             equivalent = self[ nil, predicate, nil ].find do |stmt|
277:                 if stmt.subject.is_a?( Symbol ) &&
278:                    stmt.object.is_a?( Symbol ) &&
279:                    bnode_map.valid?( subject, stmt.subject ) &&
280:                    bnode_map.valid?( object, stmt.object )
281: 
282:                     bnode_map[ subject ] = stmt.subject
283:                     bnode_map[ object ] = stmt.object
284: 
285:                     stmt
286:                 end
287:             end
288: 
289:         # If the subject is an unanchored bnode, select the first
290:         # triple with the same predicate and object and an unmapped subject
291:         elsif subject_is_floating
292:             self.log.debug "Anchoring a subject (%p)" % [ subject ]
293:             equivalent = self[ nil, predicate, object ].find do |stmt|
294:                 if stmt.subject.is_a?( Symbol ) &&
295:                    bnode_map.valid?( subject, stmt.subject )
296: 
297:                     bnode_map[ subject ] = stmt.subject
298:                     stmt
299:                 end
300:             end
301: 
302:         # Do the same for an unanchored object
303:         elsif object_is_floating
304:             self.log.debug "Anchoring an object (%p)" % [ object ]
305:             equivalent = self[ subject, predicate, nil ].find do |stmt|
306:                 if stmt.object.is_a?( Symbol ) &&
307:                    bnode_map.valid?( object, stmt.object )
308: 
309:                     bnode_map[ object ] = stmt.object
310:                     stmt
311:                 end
312:             end
313: 
314:         # If the statement's nodes are all either mapped or not bnodes, just
315:         # search for an equivalent
316:         else
317:             self.log.debug "Searching for an anchored statement {%p, %p, %p}" %
318:                 [ subject, predicate, object ]
319:             equivalent = self[ subject, predicate, object ].first
320:         end
321: 
322:         self.log.debug "Equivalent is: %p" % [ equivalent ]
323: 
324:         return self.remove( equivalent ).first if equivalent
325:         return nil
326:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.