[4suite-checkins] In 4Suite/Ft/Rdf/Serializers, files N3.py

Chimezie Ogbuji cogbuji at 4suite.org
Tue May 31 08:21:44 MDT 2005


Update of /var/local/cvsroot/4Suite/Ft/Rdf/Serializers
In directory dollar:/tmp/cvs-serv4779/Serializers

Added Files:
	N3.py 
Log Message:
Added N3 deserialization to 4RDF (via Sean B. Palmer's n3p module)
see:  http://copia.ogbuji.net/blog/keyword/n3

In addition, the 4rdf command line was updated to include the ability to deserialize via this format



New file: N3.py
ViewCVS view:
  http://cvs.4suite.org/viewcvs/4Suite/Ft/Rdf/Serializers/N3.py?rev=1.1&content-type=text/vnd.viewcvs-markup

===================================================================
Checking out N3.py
RCS:  /var/local/cvsroot/4Suite/Ft/Rdf/Serializers/N3.py,v
VERS: 1.1
***************
"""
N3 Deserializer which makes use of Sean B. Palmer's n3p <http://inamidst.com/n3p>

see: http://copia.ogbuji.net/blog/keyword/n3 and
     http://www.w3.org/DesignIssues/Notation3


The 4Suite project has secured licensing under the 4Suite license from Sean B. Palmer for the modules included within 4Suite. If you intend to use these modules separately from 4Suite, you must either conform to the GPL 2, or request an alternate license from Mr. Palmer.

Copyright 2005 Fourthought, Inc. (USA).
Detailed license and copyright information: http://4suite.org/COPYRIGHT
Project home, documentation, distributions: http://4suite.org/
"""

import re, urllib, cStringIO
from Ft.Rdf import RDF_MS_BASE, RDF_SCHEMA_BASE
from Ft.Rdf import OBJECT_TYPE_RESOURCE, OBJECT_TYPE_LITERAL, OBJECT_TYPE_UNKNOWN
from Ft.Rdf import Statement
from Ft.Lib.Uri import GetScheme
from n3proc import N3Processor, N3R

class FtRDFSink:
   """
   A n3proc sink that captures statements produced from
   processing an N3 document
   """
   def __init__(self, scope,model): 
      self.stmtTuples = []
      self.scope = scope
      self.model = model
      self.bnodes = {}
      self.resources = {}

   def start(self, root):      
      self.root = root

   def statement(self, s, p, o, f):
      #First check if the subject is a bnode (via n3proc convention)
      #If so, use 4RDF's bnode convention instead
      #Use self.bnodes as a map from n3proc bnode uris -> 4RDF bnode urns
      if s.startswith('_:'):
         if s in self.bnodes:
            s = self.bnodes[s]
         else:
            newBNode = self.model.generateBnode()
            self.bnodes[s] = newBNode
            s = newBNode
            
      #Make the same check for the statement's object      
      if o.startswith('_:'):
         if o in self.bnodes:
            o = self.bnodes[o]
         else:
            newBNode = self.model.generateBnode()
            self.bnodes[o] = newBNode
            o = newBNode

      #Mark the statement's subject as a resource (used later for objectType)
      self.resources[s] = None      

      if f == self.root:
         #Regular, in scope statement
         stmt=(s,p,o,self.scope)         
         self.stmtTuples.append(stmt)         
      else:
         #Special case
         #This is where the features of N3 beyond standard RDF can be harvested
         #In particular, a statement with a different scope / context than
         #that of the containing N3 document is a 'hypothetical statement'
         #Such statement(s) are mostly used to specify impliciation via log:implies
         #Such implications rules can be persisted (by flattening the forumae) 
         #and later interpreted by a forwards / backward-chaining inference process
         #Forumulae are assigned a bnode uri by n3proc which needs to be mapped
         #to a 4RDF bnode urn
         if f in self.bnodes:
            f = self.bnodes[f]
         else:
            newBNode = self.model.generateBnode()
            self.bnodes[f] = newBNode
            f = newBNode
            
         self.resources[f] = None
         
         self.flatten(s, p, o, f)

   def quantify(self, formula, var):
      #Not certain of the role of this callback function
      raise "Not Supported"

   def flatten(self, s, p, o, f):
      """
      Adds a 'Reified' hypothetical statement (associated with the formula f)
      """
      #FIXME:  This flattening of hypothetical statements should take advantage
      #of 4RDF's statementUri for identifying hypothetical statements directly
      #without flattening them  i.e.:
      #<formula_Uri> n3r:statement <statementUri>      
      #This will make the extraction of implication ancendents/consequents by a reasoner
      #much quicker
      fs = self.model.generateUri()
      self.stmtTuples.append((f,
                              N3R.statement,
                              fs,
                              self.scope))
      self.stmtTuples.append((fs,
                              N3R.subject,
                              s,
                              self.scope))
      self.stmtTuples.append((fs,
                              N3R.predicate,
                              p,
                              self.scope))
      self.stmtTuples.append((fs,
                              N3R.object,
                              o,
                              self.scope))             

class Serializer:
    """Serialize or deserialize a model using N3."""
    def __init__(self, reify=1):
        self.reify = 0        
        return

    def serialize(self, model, nsMap=None):
        raise "Not Supported!"

    def deserialize(self, model, stream, scope=None):        
        sink = FtRDFSink(scope,model)
        n3Processor = N3Processor('nowhere',
                                  sink,
                                  baseURI = GetScheme(scope) == 'urn' and 'http://nowhere' or scope)        
        n3Processor.data = stream.read().replace('\t','  ')        
        n3Processor.parse()

        stmts = []
        
        for triple in sink.stmtTuples:
            subject,predicate,object,scp = triple
            #N3 notation renders uri's as <uri>
            subject = (subject[0] == '<' and subject[-1] == '>') and subject[1:-1] or subject
            escapeChars = [('<','"'),('>','"')]
            #The objectType can be determined via the escape characters: <resource>  "string"
            objectType = OBJECT_TYPE_UNKNOWN
            if object[0] == '"' and object[-1] == '"':
               objectType = OBJECT_TYPE_LITERAL
            objectType = (object in sink.resources or object[0] == '<' and object[-1] == '>') and OBJECT_TYPE_RESOURCE or objectType
            object = (object[0] in escapeChars[0] and object[-1] in escapeChars[-1]) and object[1:-1] or object
            predicate = (predicate[0] == '<' and predicate[-1] == '>') and predicate[1:-1] or predicate

            
            stmts.append(Statement.Statement(subject,
                                             predicate,
                                             object,
                                             scope=scope,
                                             objectType=objectType))        
        
        model.add(stmts)



More information about the 4suite-checkins mailing list