graph library

joshsh edited this page Mar 2, 2012 · 14 revisions

The graph: library contains primitives for querying against and updating sets of RDF statements, as well as for traversing through key/value structures including JSON objects.

Note: in all of the RDF graph primitives, the default graph context is represented by the nil list (() or rdf:nil).

Key/value objects

Key/value objects are an abstract class of items annotated with key/value pairs. For example, the JSON objects produced by to-json (see below) are key/value objects in which keys are strings and values are strings, numbers, boolean values, arrays or further key/value JSON objects.

You can navigate from a key/value object through a key into a value using a key/value predicate, which is simply a string. For example, if the key/value object named :arthur has a "name" property, you can retrieve its value with the construction "name".:

1)  :arthur "name".

   [1]  "Arthur Dent"

Key/value objects are also used in connection with the blueprints library.

to-json

This primitive reifies the string representation of a JSON object as an equivalent simple value, list, or key/value object. It expects a single argument at the top of the stack. It pops the argument from the stack, converts the argument to a string (see to-string), then parses the string according to JSON syntax to produce a value equivalent to the JSON object represented by the string. If this process succeeds, the resulting value is pushed to the stack. Otherwise, no solution is produced.

The produced object is one of:

  • a simple value (boolean, string, or number)
  • a list of values corresponding to a JSON array
  • a key/value object corresponding to a JSON object

Lists thus produced may contain other objects of any of the above three kinds, while key/value objects thus produced may have key/value pairs, the key of which is a string and the value of which is another object of one of the above three kinds. The resulting value is equivalent to corresponding object in JSON, with the exception that null values are simply ignored. It can be converted to a string to obtain a string representation equivalent to the original representation, again with the exception of nulls, and ignoring the order of key/value pairs.

Examples (see also this blog post):

1)  @list j: "{\\"foo\\": true, \\"bar\\": [6, 9, 42]}" to-json.
2)  :j.

  [1]  {"foo":true,"bar":[6,9,42]}

3)  :j. "foo".

  [1]  true

4)  :j. "bar". each.

  [1]  6
  [2]  9
  [3]  42

keys

This primitive finds all keys of key/value pairs attached to a given object. It expects a stack with one argument on top: a key/value object. It pops the object from the stack and pushes the key of each key/value pair attached to the object.

Example:

1)  "{\\"foo\\": true, \\"bar\\": [6, 9, 42]}" to-json. keys.

  [1]  "foo"
  [2]  "bar"

key-values

This primitive finds all key/value pairs attached to a given object. It expects a stack with one argument on top: a key/value object. It pops the object from the stack and pushes first the key, then the value of each key/value pair attached to the object.

Example:

1)  "{\\"foo\\": true, \\"bar\\": [6, 9, 42]}" to-json. key-values.

  [1]  "foo" true
  [2]  "bar" (6 9 42)

values

This primitive finds all values of key/value pairs attached to a given object. It expects a stack with one argument on top: a key/value object. It pops the object from the stack and pushes the value of each key/value pair attached to the object.

Example:

1)  "{\\"foo\\": true, \\"bar\\": [6, 9, 42]}" to-json. values.

  [1]  true
  [2]  (6 9 42)

RDF queries

in-context

This primitive behaves like an RDF predicate mapping (e.g. like the predicate foaf:knows, which maps a person to a set of people he or she knows) but restricts its solutions to a specified graph context. It expects three arguments on the top of the stack: the subject, predicate, and graph context of matching RDF statements. It pops the arguments from the stack and, for each matching RDF statement, pushes the object of the statement.

Examples:

1)  rdfs:Class rdf:type.

  [1]  owl:Class
  [2]  rdfs:Class

2)  # One of the above types is asserted in the FOAF vocab document, the other in the RDFS schema document.
3)  # Let's select only those from the RDFS document.
4)  rdfs:Class rdf:type <http://www.w3.org/2000/01/rdf-schema> in-context.

  [1]  rdfs:Class

inlinks

This primitive finds all RDF statements with a specified object. It expects one argument on the top of the stack. It pops the argument from the stack, finds all matching RDF statements (in any context) and, for each matching statement, pushes the subject, predicate, and object of the statement.

Note: if otherwise identical RDF statements exist in multiple contexts, then inlinks may produce duplicate solutions.

Example:

1)  <http://identi.ca/user/114> inlinks. 5 limit. 2 2 ary.

  [1]  <http://identi.ca/user/114> foaf:maker <http://identi.ca/user/114> <http://identi.ca/user/114>
  [2]  <http://identi.ca/user/114> foaf:primaryTopic <http://identi.ca/user/114> <http://identi.ca/user/114>
  [3]  <http://identi.ca/user/114#acct> sioc:account_of <http://identi.ca/user/114> <http://identi.ca/user/114>
  [4]  <http://identi.ca/user/114#acct> sioc:account_of <http://identi.ca/user/114> <http://identi.ca/user/22871>
  [5]  <http://identi.ca/user/114#acct> sioc:account_of <http://identi.ca/user/114> <http://identi.ca/user/45468>

links

This primitive finds all RDF statements with a specified subject. It expects one argument on the top of the stack. It pops the argument from the stack, finds all matching RDF statements (in any context) and, for each matching statement, pushes the subject, predicate, and object of the statement.

Note: if otherwise identical RDF statements exist in multiple contexts, then links may produce duplicate solutions.

Example:

10 <http://identi.ca/user/114> links.

  [1]  <http://identi.ca/user/114> foaf:name "Danny Ayers" <http://identi.ca/user/114>
  [2]  <http://identi.ca/user/114> foaf:mbox_sha1sum "669fe353dbef63d12ba11f69ace8acbec1ac8b17" <http://identi.ca/user/114>
  [3]  <http://identi.ca/user/114> foaf:based_near <http://sws.geonames.org/3179523/> <http://identi.ca/user/114>
  [...]

members

This primitive finds all members of an rdfs:Container, according to RDF descriptions in any graph context. It expects a single argument at the top of the stack, which must be (explicitly or implicitly) an instance of rdfs:Container. It pops the container from the stack, then for each member of the container, the member is pushed to the stack.

Example:

1)  <http://identi.ca/rss> rss:items. members.

  [1]  <http://identi.ca/rss>
  [2]  <http://identi.ca/notice/73943987>
  [3]  <http://identi.ca/notice/73943938>
  [4]  <http://identi.ca/notice/73943916>
  [5]  <http://identi.ca/notice/73943897>
  [...]

sparql

This primitive evaluates a SPARQL query against the RDF statements of the knowledge base. It expects a single argument at the top of the stack: a string representing the SPARQL query. It pops the query from the stack, then evaluates it. The result of query evaluation is a series of binding sets of key/value pairs, in which every binding set has the same set of keys (although some of the values may be null). For each binding set, sparql pushes to the stack a key/value value whose keys are the binding set's keys, with the corresponding values. Values for specific variables can then be accessed using key predicates, as with JSON.

Examples:

1) "select ?s ?p ?o where { ?s ?p ?o }" sparql.

  [...]
  [6295]  {s:dcterms:Location, p:rdf:type, o:rdfs:Class
  [6296]  {s:dcterms:Location, p:dcterms:hasVersion, o:<http://dublincore.org/usage/terms/history/#Location-001>
  [6297]  {s:dcterms:Location, p:rdfs:subClassOf, o:dcterms:LocationPeriodOrJurisdiction
  [6298]  {s:dcterms:LocationPeriodOrJurisdiction, p:rdfs:label, o:"Location, Period, or Jurisdiction"@en-us
  [6299]  {s:dcterms:LocationPeriodOrJurisdiction, p:rdfs:comment, o:"A location, period of time, or jurisdiction."@en-us
  [...]

2)  "select ?s ?p ?o where { ?s ?p ?o}" sparql. "p". distinct.

  [1]  <http://fortytwo.net/2008/01/webclosure#memo>
  [2]  rdf:type
  [3]  dc11:title
  [4]  dc11:description
  [5]  rdfs:subClassOf
  [...]

RDF graph operations with side effects

These primitives update the RDF knowledge base. Unlike most primitives in Ripple, these exert changes on the scripting environment in a non-monotonic fashion. Their use in a program requires special attention to order of evaluation.

assert

This primitive asserts an RDF statement, i.e. adds it to the knowledge base, in the default graph context. It expects three arguments on the top of the stack: the subject, predicate, and object of the statement. It pops the arguments from the stack, constructs and asserts the corresponding RDF statement, then pushes the subject of the statement back to the stack.

Note: the action of this primitive alters the scripting environment. Its use in a program requires special attention to order of evaluation.

Examples:

1)  ex:FordPrefect rdf:type.

  [1]  foaf:Person

2)  ex:FordPrefect rdf:type ex:Betelgeusian assert.

  [1]  ex:FordPrefect

3)  ex:FordPrefect rdf:type.                       

  [1]  foaf:Person
  [2]  ex:Betelgeusian

assert-in-context

Like assert (see above) this primitive asserts an RDF statement, i.e. adds it to the knowledge base, but in a specified graph context. It expects four arguments on the top of the stack: the subject, predicate, object, and context of the statement. It pops the arguments from the stack, constructs and asserts the corresponding RDF statement, then pushes the subject of the statement back to the stack.

Note: the action of this primitive alters the scripting environment. Its use in a program requires special attention to order of evaluation.

Examples:

1)  ex:TheGalaxy ex:population 5.982915e20 ex:megadodo2009Census assert-in-context.

  [1]  ex:TheGalaxy

2)  ex:TheGalaxy ex:population 6.016003e20 ex:megadodo2010Census assert-in-context.

  [1]  ex:TheGalaxy

3)  ex:TheGalaxy ex:population.

  [1]  5.982915E11
  [2]  6.016003E11

4)  ex:TheGalaxy ex:population ex:megadodo2009Census in-context.

  [1]  5.982915E11

5)  ex:TheGalaxy ex:population ex:megadodo2010Census in-context.

  [1]  6.016003E11

deny

This primitive denies an RDF statement, i.e. removes it from the knowledge base (in all contexts) if it exists. It expects three arguments on the top of the stack: the subject, predicate, and object of matching statements. It pops the arguments from the stack, removes all matching RDF statements from the knowledge base, then pushes the subject of the statement back to the stack.

Note: the action of this primitive alters the scripting environment. Its use in a program requires special attention to order of evaluation.

deny-in-context

Like deny, this primitive denies an RDF statement, i.e. removes it from the knowledge base, but only from a specified graph context. It expects four arguments on the top of the stack: the subject, predicate, object, and context of matching statements. It pops the arguments from the stack, removes all matching RDF statements from the knowledge base, then pushes the subject of the statement back to the stack.

Note: the action of this primitive alters the scripting environment. Its use in a program requires special attention to order of evaluation.

new

This primitive creates a new, unique blank node or a domain-neutral, randomized URI (the two are considered equivalent for Ripple's purposes). It takes no arguments, and pushes a randomized, newly-minted blank node or URI to its input stack.

Example:

1)  new. rdf:type foaf:Person assert. foaf:name "Arthur Dent" assert.

  [1]  <urn:random:dc96970127b7af20c17cec984e0bb228>
          rdf:type
             foaf:Person;
          foaf:name
             "Arthur Dent".