www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | README | LICENSE

term.js (10168B)


      1 // These are the classes corresponding to the RDF and N3 data models
      2 //
      3 // Designed to look like rdflib and cwm designs.
      4 //
      5 // Issues: Should the names start with RDF to make them
      6 //      unique as program-wide symbols?
      7 //
      8 // W3C open source licence 2005.
      9 //
     10 //	Symbol
     11 $rdf.Empty = function () {
     12   return this;
     13 };
     14 
     15 $rdf.Empty.prototype.termType = 'empty';
     16 $rdf.Empty.prototype.toString = function () {
     17   return "()"
     18 };
     19 $rdf.Empty.prototype.toNT = $rdf.Empty.prototype.toString;
     20 
     21 $rdf.Symbol = function (uri) {
     22   this.uri = uri;
     23   this.value = uri; // -- why? -tim
     24   return this;
     25 }
     26 
     27 $rdf.Symbol.prototype.termType = 'symbol';
     28 $rdf.Symbol.prototype.toString = function () {
     29   return("<" + this.uri + ">");
     30 };
     31 $rdf.Symbol.prototype.toNT = $rdf.Symbol.prototype.toString;
     32 
     33 //  Some precalculated symbols
     34 $rdf.Symbol.prototype.XSDboolean = new $rdf.Symbol('http://www.w3.org/2001/XMLSchema#boolean');
     35 $rdf.Symbol.prototype.XSDdecimal = new $rdf.Symbol('http://www.w3.org/2001/XMLSchema#decimal');
     36 $rdf.Symbol.prototype.XSDfloat = new $rdf.Symbol('http://www.w3.org/2001/XMLSchema#float');
     37 $rdf.Symbol.prototype.XSDinteger = new $rdf.Symbol('http://www.w3.org/2001/XMLSchema#integer');
     38 $rdf.Symbol.prototype.XSDdateTime = new $rdf.Symbol('http://www.w3.org/2001/XMLSchema#dateTime');
     39 $rdf.Symbol.prototype.integer = new $rdf.Symbol('http://www.w3.org/2001/XMLSchema#integer'); // Used?
     40 //	Blank Node
     41 if(typeof $rdf.NextId != 'undefined') {
     42   $rdf.log.error('Attempt to re-zero existing blank node id counter at ' + $rdf.NextId);
     43 } else {
     44   $rdf.NextId = 0; // Global genid
     45 }
     46 $rdf.NTAnonymousNodePrefix = "_:n";
     47 
     48 $rdf.BlankNode = function (id) {
     49   /*if (id)
     50     	this.id = id;
     51     else*/
     52   this.id = $rdf.NextId++;
     53   this.value = id ? id : this.id.toString();
     54   return this
     55 };
     56 
     57 $rdf.BlankNode.prototype.termType = 'bnode';
     58 $rdf.BlankNode.prototype.toNT = function () {
     59   return $rdf.NTAnonymousNodePrefix + this.id
     60 };
     61 $rdf.BlankNode.prototype.toString = $rdf.BlankNode.prototype.toNT;
     62 
     63 //	Literal
     64 $rdf.Literal = function (value, lang, datatype) {
     65   this.value = value
     66   if(lang == "" || lang == null) this.lang = undefined;
     67   else this.lang = lang; // string
     68   if(datatype == null) this.datatype = undefined;
     69   else this.datatype = datatype; // term
     70   return this;
     71 }
     72 
     73 $rdf.Literal.prototype.termType = 'literal'
     74 $rdf.Literal.prototype.toString = function () {
     75   return '' + this.value;
     76 };
     77 $rdf.Literal.prototype.toNT = function () {
     78   var str = this.value
     79   if(typeof str != 'string') {
     80     if(typeof str == 'number') return '' + str;
     81     throw Error("Value of RDF literal is not string: " + str)
     82   }
     83   str = str.replace(/\\/g, '\\\\'); // escape backslashes
     84   str = str.replace(/\"/g, '\\"'); // escape quotes
     85   str = str.replace(/\n/g, '\\n'); // escape newlines
     86   str = '"' + str + '"' //';
     87   if(this.datatype) {
     88     str = str + '^^' + this.datatype.toNT()
     89   }
     90   if(this.lang) {
     91     str = str + "@" + this.lang;
     92   }
     93   return str;
     94 };
     95 
     96 $rdf.Collection = function () {
     97   this.id = $rdf.NextId++; // Why need an id? For hashstring.
     98   this.elements = [];
     99   this.closed = false;
    100 };
    101 
    102 $rdf.Collection.prototype.termType = 'collection';
    103 
    104 $rdf.Collection.prototype.toNT = function () {
    105   return $rdf.NTAnonymousNodePrefix + this.id
    106 };
    107 
    108 $rdf.Collection.prototype.toString = function () {
    109   var str = '(';
    110   for(var i = 0; i < this.elements.length; i++)
    111   str += this.elements[i] + ' ';
    112   return str + ')';
    113 };
    114 
    115 $rdf.Collection.prototype.append = function (el) {
    116   this.elements.push(el)
    117 }
    118 $rdf.Collection.prototype.unshift = function (el) {
    119   this.elements.unshift(el);
    120 }
    121 $rdf.Collection.prototype.shift = function () {
    122   return this.elements.shift();
    123 }
    124 
    125 $rdf.Collection.prototype.close = function () {
    126   this.closed = true
    127 }
    128 
    129 
    130 //      Convert Javascript representation to RDF term object
    131 //
    132 $rdf.term = function (val) {
    133   if(typeof val == 'object')
    134     if(val instanceof Date) {
    135       var d2 = function (x) {
    136           return('' + (100 + x)).slice(1, 3)
    137         }; // format as just two digits
    138       return new $rdf.Literal('' + val.getUTCFullYear() + '-' + d2(val.getUTCMonth() + 1)
    139           + '-' + d2(val.getUTCDate()) + 'T' + d2(val.getUTCHours()) + ':'
    140           + d2(val.getUTCMinutes()) + ':' + d2(val.getUTCSeconds()) + 'Z',
    141         undefined,
    142         $rdf.Symbol.prototype.XSDdateTime);
    143 
    144     } else if(val instanceof Array) {
    145       var x = new $rdf.Collection();
    146       for(var i = 0; i < val.length; i++)
    147         x.append($rdf.term(val[i]));
    148       return x;
    149     } else
    150       return val;
    151   if(typeof val == 'string')
    152     return new $rdf.Literal(val);
    153   if(typeof val == 'number') {
    154     var dt;
    155     if(('' + val).indexOf('e') >= 0) dt = $rdf.Symbol.prototype.XSDfloat;
    156     else if(('' + val).indexOf('.') >= 0) dt = $rdf.Symbol.prototype.XSDdecimal;
    157     else dt = $rdf.Symbol.prototype.XSDinteger;
    158     return new $rdf.Literal(val, undefined, dt);
    159   }
    160   if(typeof val == 'boolean')
    161     return new $rdf.Literal(val ? "1" : "0", undefined, $rdf.Symbol.prototype.XSDboolean);
    162   if(typeof val == 'undefined')
    163     return undefined;
    164   throw("Can't make term from " + val + " of type " + typeof val);
    165 }
    166 
    167 //	Statement
    168 //
    169 //  This is a triple with an optional reason.
    170 //
    171 //   The reason can point to provenece or inference
    172 //
    173 $rdf.Statement = function (subject, predicate, object, why) {
    174   this.subject = $rdf.term(subject)
    175   this.predicate = $rdf.term(predicate)
    176   this.object = $rdf.term(object)
    177   if(typeof why != 'undefined') {
    178     this.why = why;
    179   }
    180   return this;
    181 }
    182 
    183 $rdf.st = function (subject, predicate, object, why) {
    184   return new $rdf.Statement(subject, predicate, object, why);
    185 };
    186 
    187 $rdf.Statement.prototype.toNT = function () {
    188   return (this.subject.toNT() + " " + this.predicate.toNT() + " " + this.object.toNT() + " .");
    189 };
    190 
    191 $rdf.Statement.prototype.toString = $rdf.Statement.prototype.toNT;
    192 
    193 //	Formula
    194 //
    195 //	Set of statements.
    196 $rdf.Formula = function () {
    197   this.statements = []
    198   this.constraints = []
    199   this.initBindings = []
    200   this.optional = []
    201   return this;
    202 };
    203 
    204 
    205 $rdf.Formula.prototype.termType = 'formula';
    206 $rdf.Formula.prototype.toNT = function () {
    207   return "{" + this.statements.join('\n') + "}"
    208 };
    209 $rdf.Formula.prototype.toString = $rdf.Formula.prototype.toNT;
    210 
    211 $rdf.Formula.prototype.add = function (subj, pred, obj, why) {
    212   this.statements.push(new $rdf.Statement(subj, pred, obj, why))
    213 }
    214 
    215 // Convenience methods on a formula allow the creation of new RDF terms:
    216 $rdf.Formula.prototype.sym = function (uri, name) {
    217   if(name != null) {
    218     throw "This feature (kb.sym with 2 args) is removed. Do not assume prefix mappings."
    219     if(!$rdf.ns[uri]) throw 'The prefix "' + uri + '" is not set in the API';
    220     uri = $rdf.ns[uri] + name
    221   }
    222   return new $rdf.Symbol(uri)
    223 }
    224 
    225 $rdf.sym = function (uri) {
    226   return new $rdf.Symbol(uri);
    227 };
    228 
    229 $rdf.Formula.prototype.literal = function (val, lang, dt) {
    230   return new $rdf.Literal(val.toString(), lang, dt)
    231 }
    232 $rdf.lit = $rdf.Formula.prototype.literal;
    233 
    234 $rdf.Formula.prototype.bnode = function (id) {
    235   return new $rdf.BlankNode(id)
    236 }
    237 
    238 $rdf.Formula.prototype.formula = function () {
    239   return new $rdf.Formula()
    240 }
    241 
    242 $rdf.Formula.prototype.collection = function () { // obsolete
    243   return new $rdf.Collection()
    244 }
    245 
    246 $rdf.Formula.prototype.list = function (values) {
    247   var li = new $rdf.Collection();
    248   if(values) {
    249     for(var i = 0; i < values.length; i++) {
    250       li.append(values[i]);
    251     }
    252   }
    253   return li;
    254 }
    255 
    256 /*  Variable
    257  **
    258  ** Variables are placeholders used in patterns to be matched.
    259  ** In cwm they are symbols which are the formula's list of quantified variables.
    260  ** In sparl they are not visibily URIs.  Here we compromise, by having
    261  ** a common special base URI for variables. Their names are uris,
    262  ** but the ? nottaion has an implicit base uri of 'varid:'
    263  */
    264 
    265 $rdf.Variable = function (rel) {
    266   this.base = "varid:"; // We deem variabe x to be the symbol varid:x 
    267   this.uri = $rdf.Util.uri.join(rel, this.base);
    268   return this;
    269 }
    270 
    271 $rdf.Variable.prototype.termType = 'variable';
    272 $rdf.Variable.prototype.toNT = function () {
    273   if(this.uri.slice(0, this.base.length) == this.base) {
    274     return '?' + this.uri.slice(this.base.length);
    275   } // @@ poor man's refTo
    276   return '?' + this.uri;
    277 };
    278 
    279 $rdf.Variable.prototype.toString = $rdf.Variable.prototype.toNT;
    280 $rdf.Variable.prototype.classOrder = 7;
    281 
    282 $rdf.variable = $rdf.Formula.prototype.variable = function (name) {
    283   return new $rdf.Variable(name);
    284 };
    285 
    286 $rdf.Variable.prototype.hashString = $rdf.Variable.prototype.toNT;
    287 
    288 
    289 // The namespace function generator 
    290 $rdf.Namespace = function (nsuri) {
    291   return function (ln) {
    292     return new $rdf.Symbol(nsuri + (ln === undefined ? '' : ln))
    293   }
    294 }
    295 
    296 $rdf.Formula.prototype.ns = function (nsuri) {
    297   return function (ln) {
    298     return new $rdf.Symbol(nsuri + (ln === undefined ? '' : ln))
    299   }
    300 }
    301 
    302 
    303 // Parse a single token
    304 //
    305 // The bnode bit should not be used on program-external values; designed
    306 // for internal work such as storing a bnode id in an HTML attribute.
    307 // This will only parse the strings generated by the vaious toNT() methods.
    308 $rdf.Formula.prototype.fromNT = function (str) {
    309   var len = str.length
    310   var ch = str.slice(0, 1)
    311   if(ch == '<') return $rdf.sym(str.slice(1, len - 1))
    312   if(ch == '"') {
    313     var lang = undefined;
    314     var dt = undefined;
    315     var k = str.lastIndexOf('"');
    316     if(k < len - 1) {
    317       if(str[k + 1] == '@') lang = str.slice(k + 2, len);
    318       else if(str.slice(k + 1, k + 3) == '^^') dt = $rdf.fromNT(str.slice(k + 3, len));
    319       else throw "Can't convert string from NT: " + str
    320     }
    321     var str = (str.slice(1, k));
    322     str = str.replace(/\\"/g, '"'); // unescape quotes '
    323     str = str.replace(/\\n/g, '\n'); // unescape newlines
    324     str = str.replace(/\\\\/g, '\\'); // unescape backslashes 
    325     return $rdf.lit(str, lang, dt);
    326   }
    327   if(ch == '_') {
    328     var x = new $rdf.BlankNode();
    329     x.id = parseInt(str.slice(3));
    330     $rdf.NextId--
    331     return x
    332   }
    333   if(ch == '?') {
    334     var x = new $rdf.Variable(str.slice(1));
    335     return x;
    336   }
    337   throw "Can't convert from NT: " + str;
    338 
    339 }
    340 $rdf.fromNT = $rdf.Formula.prototype.fromNT; // Not for inexpert user
    341 // Convenience - and more conventional name:
    342 $rdf.graph = function () {
    343   return new $rdf.IndexedFormula();
    344 };
    345 
    346 // ends