AwwswDboothsRules
AwwswHome . AwwswTopicsBrainstormPage
Rules for HTTP Inferences
This page contains David Booth's draft n3 rules for HTTP inferences:
- rules.n3
and some test data:
- test1.n3
- test2.n3
- test3.n3
- test4.n3
- test5.n3
It should produce a message saying: "PASSED: test1". The other tests are run similarly. Comments and suggestions are invited: david@dbooth.org
To Do
Per meeting http://www.w3.org/2008/03/04-awwsw-minutes.html
- Make the rules use both the verb style and noun style of properties (e.g., hasRacine and racine): one as the name of the property, the other as the label.
- "timbl: issues about what has to be asserted or inferred all has to do with your test harnes" "<alanr> the thing that makes sense is to say, the system can not infer x, given y"
- Take out debugging statements
- Use a separate namespace for headers. "timbl: I suggest a separate namespace for htttp headers -- hh or httph."
- Check the actual data type of the headers in the HTTP spec and use that data type in the rules.
- Change the 301 rule to infer the same "Work" instead of inferring the same IR.
- Change "Reply" to "Response" to match HTTP spec http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6
Niggling details that were postponed:
- Find a proper data type for a sequence of octets.
- Figure out if something else is needed to model the character encoding.
rules.n3: Classes, Properties and Rules
For convenience this file combines what should logically be a few different ontologies: one for HTTP, one for URI declarations, one for AWWW, one for the "text/rdf+n3" media type, etc. All of the http://example/ namespaces are defined in this file.
1. # CWM rules for HTTP protocol: What can be inferred from a GET? 2. # This is a DRAFT and surely will change without notice. 3. # 4. # Author: David Booth <dbooth@hp.com> 5. # Date: 26-Feb-2008 6. # License: GPLv3: http://www.gnu.org/licenses/gpl-3.0.html 7. # 8. # See associated test data. 9. 10. ######################## Prefixes ########################### 11. # I see python code for parsing URIs here: 12. # http://www.w3.org/2000/10/swap/uripath.py 13. # but I haven't yet found an ontology for parsing URIs, 14. # though maybe the POWDER working group will eventually make one. 15. # @@@@ TODO: Find URI parsing ontology 16. @prefix uri: <http://example/uri#> . 17. @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . 18. @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . 19. @prefix log: <http://www.w3.org/2000/10/swap/log#>. 20. # These two HTTP ontologies by David Sheets are not currently used, 21. # but relationships between my http: ontology and his 22. # are shown in comments: 23. # @prefix dshttp: <http://www.w3.org/2007/ont/http#> . 24. # @prefix dshttph: <http://www.w3.org/2007/ont/httph#> . 25. @prefix http: <http://example/httpspec#> . 26. @prefix sumo: <http://example/sumo#> . 27. @prefix owl: <http://www.w3.org/2002/07/owl#> . 28. @prefix xsd: <http://www.w3.org/2001/XMLSchema#> . 29. @prefix decl: <http://example/uridecl#> . 30. @prefix n3: <http://example/n3#> . 31. @prefix string: <http://www.w3.org/2000/10/swap/string#> . 32. @prefix awww: <http://example/awww#> . 33. 34. ########################## AWWW ############################# 35. # Concepts from the Architecture of the World Wide Web: 36. # http://www.w3.org/TR/webarch/ 37. # 38. awww:Resource a rdfs:Class ; 39. rdf:comment "A resource, as defined in http://www.w3.org/TR/webarch/#def-resource : 'We do not limit the scope of what might be a resource. The term ''resource'' is used in a general sense for whatever might be identified by a URI. It is conventional on the hypertext Web to describe Web pages, images, product catalogs, etc. as ''resources''." . 40. 41. awww:InformationResource a rdfs:Class ; 42. rdf:label "InformationResource" ; 43. rdf:comment "An information resource, roughly as defined in http://www.w3.org/TR/webarch/#def-information-resource though that definition is flawed. According to http://www.w3.org/TR/webarch/#p43 'Other things, such as cars and dogs (and, if you've printed this document on physical sheets of paper, the artifact that you are holding in your hand), are resources too. They are not information resources, however . . . .', so I will take this to mean that an information resource is an abstract entity. This property may either be asserted explicitly or inferred by the httpRange-14 rule." ; 44. rdfs:subClassOf sumo:AbstractEntity . 45. 46. ######################### URI Parsing ############################## 47. 48. uri:hasRacine a rdf:Property ; 49. rdf:label "hasRacine" ; 50. rdf:comment "Parse a URI with optional fragment identifier to extract the racine (the part before the #). The URI is NOT required to contain a fragment identifier. A URI with no fragID will map to itself. Compare hasProperRacine. This property should NOT be asserted explicitly -- it will be inferred from the URI." ; 51. rdfs:domain xsd:anyURI ; 52. rdfs:range xsd:anyURI . # But no fragID 53. 54. uri:hasProperRacine a rdf:Property ; 55. rdf:label "hasProperRacine" ; 56. rdf:comment "Parse a URI with fragment identifier to extract the racine (the part before the #). The URI must have a fragment identifier for this property to hold. Compare hasRacine. This property should NOT be asserted explicitly -- it will be inferred from the URI." ; 57. rdfs:domain xsd:anyURI ; 58. rdfs:range xsd:anyURI . # But no fragID 59. 60. # Rule for hasRacine. 61. # Test with: 62. # "http://example/people#fred"^^xsd:anyURI a xsd:anyURI . 63. # "http://example/people#"^^xsd:anyURI a xsd:anyURI . 64. # "http://example/people"^^xsd:anyURI a xsd:anyURI . 65. { ?u a xsd:anyURI . 66. # FragID would be: 67. # (?u "\\A[^\\#]*\\#(.+)\\Z") string:scrape ?fragid . 68. # Racine as a simple string: 69. (?u "\\A([^\\#]+)") string:scrape ?stringRacine . 70. # Turn ?stringRacine into type xsd:anyURI: 71. (?stringRacine xsd:anyURI) log:dtlit ?racine . 72. # ("FIRED: " ?u " uri:hasRacine " ?racine "\n") string:concatenation ?fired . # Debug 73. } => { ?u uri:hasRacine ?racine . 74. # "a" log:outputString ?fired . # Debug 75. } . 76. 77. # Rule for hasProperRacine. 78. # Test with: 79. # "http://example/people#fred"^^xsd:anyURI a xsd:anyURI . 80. # "http://example/people#"^^xsd:anyURI a xsd:anyURI . 81. # This last one should fail to match, because it has no #: 82. # "http://example/people"^^xsd:anyURI a xsd:anyURI . 83. { ?u a xsd:anyURI . 84. # FragID would be: 85. # (?u "\\A[^\\#]*\\#(.+)\\Z") string:scrape ?fragid . 86. # Proper racine as a simple string: 87. (?u "\\A([^\\#]+)\\#") string:scrape ?stringRacine . 88. # Turn ?stringRacine into type xsd:anyURI: 89. (?stringRacine xsd:anyURI) log:dtlit ?racine . 90. # ("FIRED: " ?u " uri:hasProperRacine " ?racine "\n") string:concatenation ?fired . # Debug 91. } => { ?u uri:hasProperRacine ?racine . 92. # "a" log:outputString ?fired . # Debug 93. } . 94. 95. uri:hasURI a rdf:Property ; 96. rdf:label "hasURI" ; 97. rdf:comment "The subject resource is denoted by the object URI. It is basically the same as log:uri, but has a range of xsd:anyURI, so that a simple assertion like {r hasURI u} will cause u to be recognized as type xsd:anyURI without having to assert it explicitly. This property should be asserted explicitly -- it is NOT inferred." ; 98. rdfs:subPropertyOf log:uri ; 99. # rdfs:domain rdfs:Resource ; 100. rdfs:range xsd:anyURI . 101. 102. 103. ########################## HTTP ############################# 104. # HTTP 1.1 105. 106. ########## Classes 107. http:Reply a rdfs:Class ; 108. # Maybe: owl:sameClassAs dshttp:ResponseMessage ; 109. rdf:comment "An HTTP 1.1 reply, as defined in http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6 ." . 110. 111. ## Deleted class http:StatusCode, as it wasn't used. 112. 113. ########### Properties 114. http:hasLocation a rdf:Property ; 115. rdf:comment "The Reply has an HTTP 1.1 Location response-header field, as defined in http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.30 ." ; 116. # Would probably be: rdfs:subPropertyOf dshttph:location ; 117. # except that dshttph: doesn't currently define that property. 118. rdfs:domain http:Reply ; 119. rdfs:range xsd:anyURI . 120. 121. http:hasStatusCode a rdf:Property ; 122. rdf:comment "The Reply has an HTTP 1.1 Status-Code, as defined in http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10 ." ; 123. rdfs:domain http:Reply ; 124. rdfs:range rdfs:Literal . # Was rdfs:Literal 125. 126. http:hasContentType a rdf:Property ; 127. rdf:comment "The Reply has an HTTP 1.1 Content-Type entity-header field, as defined in http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.17 ." ; 128. # Would probably be: rdfs:subPropertyOf dshttp:status ; 129. rdfs:domain http:Reply ; 130. rdfs:range rdfs:Literal . 131. 132. http:hasEntityBody a rdf:Property ; 133. rdf:comment "The Reply has an HTTP 1.1 Entity Body, as defined in http://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.2 . The Entity Body 'is obtained from the message-body by decoding any Transfer-Encoding that might have been applied to ensure safe and proper transfer of the message'. I did not bother to model the message-body, as it was not needed. Also, the spec defines an Entity Body as a sequence of octets. I don't know if this is the same data type as xsd:hexBinary, but for simplicity I assumed that an Entity Body can be modeled as an rdfs:Literal." ; 134. # Would probably be: rdfs:subPropertyOf dshttp:entity-body ; 135. rdfs:domain http:Reply ; 136. rdfs:range rdfs:Literal . 137. 138. http:hasDirectGetReply a rdf:Property ; 139. rdf:comment "An HTTP 1.1 GET on the URI directly yielded a Reply. By the HTTP 1.1 spec, http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.2 the URI must not contain a fragment identifier. GET is defined in http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3 . Compare hasGetReply. Test data should assert hasDirectGetReply, from which hasGetReply will be inferred." ; 140. rdfs:domain xsd:anyURI ; 141. rdfs:range http:Reply . 142. 143. http:hasGetReply a rdf:Property ; 144. rdf:comment "An HTTP 1.1 GET on the URI directly or indirectly (through 301, 302 or 307 redirects) yielded a Reply. Compare hasDirectGetReply. Among other things, hasGetReply is used to delegate authority for URI declaration: if ?u hasGetReply ?r then ?r is treated as authoritative in the sense described in http://dbooth.org/2007/uri-decl/20070817.htm#precise-def-uri-decl , such that the act of serving the reply via the original URI satisfies the requirement for a performative speech act. Test data should NOT assert hasGetReply, but should instead assert hasDirectGetReply and let hasGetReply be inferred." ; 145. rdfs:domain xsd:anyURI ; 146. rdfs:range http:Reply . 147. 148. ########### Rules 149. 150. # httpRange-14 rule: 200 response => InformationResource 151. # http://lists.w3.org/Archives/Public/www-tag/2005Jun/0039.html 152. { ?r uri:hasURI ?u . 153. ?u http:hasGetReply ?reply . 154. ?reply http:hasStatusCode 200 . 155. # ("FIRED: " ?r " a awww:InformationResource \n") string:concatenation ?fired . # Debug 156. } => { 157. ?r a awww:InformationResource . 158. # "a" log:outputString ?fired . # Debug 159. } . 160. 161. # Definition of hasGetReply (base case). 162. # hasDirectGetReply => hasGetReply. 163. { ?u http:hasDirectGetReply ?reply . # IF direct deref ?u yields ?reply 164. # ("FIRED base: " ?u " http:hasGetReply " ?reply "\n") string:concatenation ?fired . # Debug 165. } => { ?u http:hasGetReply ?reply . # THEN it derefs to ?reply. 166. # "a" log:outputString ?fired . # Debug 167. } . 168. 169. # Definition of hasGetReply (recursive case). 170. # For the purpose of hasGetReply, 301, 302 and 307 are treated the same: 171. # they are all deemed to delegate URI declaration authority to the new URI. 172. { 173. ?u1 http:hasGetReply ?reply1 . # IF ?u1 derefs to ?reply1 174. ?reply1 http:hasStatusCode 301 . # ... with 301 status 175. ?reply1 http:hasLocation ?u2 . # ... and new URI ?u2 176. ?u2 http:hasGetReply ?reply2 . # ... which derefs to ?reply2 177. # ("FIRED recursive: " ?u1 " http:hasGetReply " ?reply2 "\n") string:concatenation ?fired . # Debug 178. } => { # THEN 179. ?u1 http:hasGetReply ?reply2 . # ... ?u1 derefs to ?reply2 180. # "a" log:outputString ?fired . # Debug 181. } . 182. 183. # Furthermore, 301, 302 and 307 (but NOT 303) redirects are 184. # treated as saying that the resources denoted by the old and 185. # new URIs are the same resource. This is significant 186. # because it highlights the difference between talking about 187. # the resource denoted by a URI, versus the use of the URI 188. # in an HTTP GET: two URIs may denote the same resource, but 189. # dereferencing them may yield *different* results. For 190. # example, dereferencing a URI may yield a 301 redirect, 191. # but dereferencing the new URI may yield a 200 response. 192. # This helps explain why these HTTP rules are written in 193. # terms of URIs rather than awww:InformationResources. 194. { 195. ?u1 a xsd:anyURI . # Old URI 196. # ?r1 a rdfs:Resource . 197. ?r1 uri:hasURI ?u1 . 198. ?u2 a xsd:anyURI . # New URI 199. # ?r2 a rdfs:Resource . 200. ?r2 uri:hasURI ?u2 . 201. ?u1 http:hasGetReply ?reply1 . # IF ?u1 derefs to ?reply1 202. ?reply1 http:hasStatusCode 301 . # ... with 301 status 203. ?reply1 http:hasLocation ?u2 . # ... and new URI ?u2 204. # ("FIRED 301: " ?r1 " = " ?r2 "\n") string:concatenation ?fired . # Debug 205. } => { # THEN they denote 206. ?r1 = ?r2 . # ... the same thing. 207. # "a" log:outputString ?fired . # Debug 208. } . 209. 210. # 211. # @@@@ TODO: Implement 302 and 307 cases the same as 301. 212. 213. 214. ########################## URI Declaration ############################ 215. # This section defines concepts involved in URI declaration, as 216. # described in http://dbooth.org/2007/uri-decl/ 217. # Rules that assert these predicates are defined by each media type. 218. 219. decl:parsesTo a rdf:Property ; 220. rdf:label "parsesTo" ; 221. rdf:comment "The given EntityBody parses to an N3 formula according to the given media type. The subject is a list: the first element is the entity body to be parsed; the second element is the media type. The resulting object formula is a set of RDF statements as described in http://dbooth.org/2007/uri-decl/ . This property should NOT normally be asserted explicitly, but should be inferred by media-type-specific parsing rules." ; 222. # @@@@ TODO: Change the entity body type to octet stream. 223. # rdfs:domain ( rdfs:Literal rdfs:Literal ) ; # ( EntityBody, MediaType ) 224. rdfs:range log:Formula . 225. 226. decl:hasDeclaration a rdf:Property ; 227. rdf:label "hasDeclaration" ; 228. rdf:comment "The subject URI has a URI declaration consisting of the object formula -- a set of RDF statements as described in http://dbooth.org/2007/uri-decl/ . This property will normally be inferred from a successful http response, either from the URI's racine or via a 303 redirect using media-type-specific rules." ; 229. rdfs:domain xsd:anyURI ; # May have a fragID 230. rdfs:range log:Formula . 231. 232. # URI declaration rule for hash URIs. The rules for each media 233. # type must specify how a body is parsed to a formula. 234. { ?u a xsd:anyURI . 235. ?u uri:hasProperRacine ?racine . 236. ?racine http:hasGetReply ?reply . 237. ?reply http:hasStatusCode 200 . 238. ?reply http:hasContentType ?mediaType . 239. ?reply http:hasEntityBody ?body . 240. ( ?body ?mediaType ) decl:parsesTo ?formula . 241. # ("FIRED hash: " ?u " decl:hasDeclaration " ?formula "\n") string:concatenation ?fired . # Debug 242. } => { 243. ?u decl:hasDeclaration ?formula . 244. # "a" log:outputString ?fired . # Debug 245. } . 246. 247. # URI declaration rule for 303 redirect URIs (which may also contain 248. # a fragment identifier). 249. # Note that this rule may involve any number of 301, 302 or 307 250. # redirects before or after the 303, but only a single 303. 251. # Thus, 303 is viewed as a less transferrable delegation of authority 252. # for URI declaration as 301, 302 and 307. The idea is that if we 253. # have u1 --303--> u2 --303--> u3, then u2 is treated as authoritative 254. # for URI declaration of u1, and u3 is treates as authoritative for 255. # URI declaration of u2, but u3 is NOT treated as authoritative for 256. # URI declaration of u1. I am not certain that this is the right 257. # choice -- perhaps it should be fully transitive -- but given that 258. # 303 is a weaker relationship than 301, 302 or 307 I think it may 259. # be a good choice. Comments on this question are invited. 260. { ?u a xsd:anyURI . 261. ?u uri:hasRacine ?racine . 262. ?racine http:hasGetReply ?reply1 . 263. ?reply1 http:hasStatusCode 303 . 264. ?reply1 http:hasLocation ?u2 . # ... forwarding to ?u2 265. ?u2 http:hasGetReply ?reply2 . # ... which derefs to reply2 266. ?reply2 http:hasStatusCode 200 . 267. ?reply2 http:hasContentType ?mediaType . 268. ?reply2 http:hasEntityBody ?body . 269. ( ?body ?mediaType ) decl:parsesTo ?formula . 270. # ("FIRED 303: " ?u " decl:hasDeclaration " ?formula "\n") string:concatenation ?fired . # Debug 271. } => { 272. ?u decl:hasDeclaration ?formula . 273. # "a" log:outputString ?fired . # Debug 274. } . 275. 276. # Notice that there is no URI declaration rule for non-hash URIs 277. # that do not use a 303 redirect. This is intentional, to permit 278. # users to make assertions about the information resource that 279. # such a URI denotes without accepting the assertions served by 280. # that information resource. For example, if dereferencing 281. # http://example/foo yields a 200 response with RDF/N3 content 282. # that parses to an n3 formula (i.e., a set of RDF assertions), 283. # then the rules for URI declaration will not automatically 284. # require everyone who writes that URI to accept those assertions. 285. 286. # URI declaration rule for rdfs:isDefinedBy, which is viewed 287. # as providing core assertions for a URI declaration, whereas 288. # the rdfs:seeAlso relationship is viewed as providing 289. # ancillary assertions, as described in 290. # http://dbooth.org/2007/uri-decl/#ancillary . 291. { ?r uri:hasURI ?u . 292. ?rdef uri:hasURI ?udef . 293. ?r rdfs:isDefinedBy ?rdef . 294. ?udef http:hasGetReply ?reply . 295. ?reply http:hasStatusCode 200 . 296. ?reply http:hasContentType ?mediaType . 297. ?reply http:hasEntityBody ?body . 298. ( ?body ?mediaType ) decl:parsesTo ?formula . 299. # ("FIRED isDefinedBy: " ?u " decl:hasDeclaration " ?formula "\n") string:concatenation ?fired . # Debug 300. } => { 301. ?u decl:hasDeclaration ?formula . 302. # "a" log:outputString ?fired . # Debug 303. } . 304. 305. ######################### N3 Media Type ############################## 306. # Properties and rule for media type: text/n3. 307. # Not sure if this media type is registered yet, but 308. # TimBL suggests text/rdf+n3 here: 309. # http://www.nabble.com/N-Triples-MIME-type-should-not-be-text-plain----comment-on-RDF-Test-Cases.-td13220788.html 310. # but here mentions that there was strong push for text/n3 instead: 311. # http://lists.w3.org/Archives/Public/public-awwsw/2008Feb/0027.html . 312. # Either way, this is good enough for demonstrating the concepts. 313. 314. # @@@@ TODO: Define/find rule for parsing octet stream as RDF/n3. 315. # Should be able to use log:parsedAsN3 316. # In the meantime, this will do for test1: 317. { 318. ?mediaType = "text/n3" . 319. ?s = "@prefix sumo: <http://example/sumo#> . <http://example/people#dan> a sumo:Human . " . 320. ?f = { <http://example/people#dan> a sumo:Human . } . 321. # ("FIRED: ( " ?s " " ?mediaType " ) n3:parsesTo " ?f "\n") string:concatenation ?fired . # Debug 322. } => { 323. ( ?s ?mediaType ) decl:parsesTo ?f . 324. # "a" log:outputString ?fired . # Debug 325. } . 326. # And this will do for test2: 327. { 328. ?mediaType = "text/n3" . 329. ?s = "@prefix sumo: <http://example/sumo#> . <http://example/people/dan303> a sumo:Human . " . 330. ?f = { <http://example/people/dan303> a sumo:Human . } . 331. # ("FIRED: ( " ?s " " ?mediaType " ) n3:parsesTo " ?f "\n") string:concatenation ?fired . # Debug 332. } => { 333. ( ?s ?mediaType ) decl:parsesTo ?f . 334. # "a" log:outputString ?fired . # Debug 335. } . 336. 337. ########################## SUMO ############################# 338. # Concepts from Suggested Upper Merged Ontology (SUMO): 339. # http://www.ontologyportal.org/ 340. # This is used only: 341. # - to assert a simple, interesting fact, i.e., 342. # that <...#dan> is a sumo:Human; and 343. # - to demonstrate how one could detect when the same URI is 344. # used to denote both an awww:InformationResource and a 345. # a sumo:Human, which the AWWW says is contradictory: 346. # http://www.w3.org/TR/webarch/#def-information-resource 347. # "Other things, such as cars and dogs (and, if you've printed 348. # this document on physical sheets of paper, the artifact that 349. # you are holding in your hand), are resources too. They are 350. # not information resources, however, . . . ." 351. 352. sumo:AbstractEntity a rdfs:Class ; 353. rdf:label "sumo:AbstractEntity" ; 354. rdf:comment "An abstract entity, as defined in http://sigma.ontologyportal.org:4010/sigma/Browse.jsp?lang=EnglishLanguage&kb=SUMO&term=Abstract . 'Entity is exhaustively partitioned into physical and abstract.'" ; 355. owl:disjointWith sumo:PhysicalEntity . 356. 357. sumo:PhysicalEntity a rdfs:Class ; 358. rdf:label "sumo:PhysicalEntity" ; 359. rdf:comment "A physical entity, as defined in http://sigma.ontologyportal.org:4010/sigma/Browse.jsp?lang=EnglishLanguage&kb=SUMO&term=Physical ." . 360. 361. sumo:Human a rdfs:Class ; 362. rdf:label "sumo:Human" ; 363. rdf:comment "A human, as defined in http://sigma.ontologyportal.org:4010/sigma/Browse.jsp?kb=SUMO&term=Human . The SUMO ontology has a long chain of superclassing to get from human to physical entity: human, hominid, primate, mammal, warm blooded vertebrate, vertebrate, animal, organism, organic object, corpuscular object, self connected object, object, physical entity. Hence, I have abbreviated this chain for simplicity." ; 364. rdfs:subClassOf sumo:PhysicalEntity . 365. 366. ########################## Standard RDF and OWL Rules ########################## 367. # I haven't yet found out where to get these standard rules for cwm, 368. # so I hand coded them for the moment. 369. 370. # rdfs:subClassOf 371. { ?a a ?ca . ?ca rdfs:subClassOf ?cb . } 372. => { ?a a ?cb . } . 373. 374. # owl:sameAs 375. { ?a = ?b } => { ?b = ?a } . 376. { ?a = ?b . ?a ?p ?c } => { ?b ?p ?c } . 377. { ?a = ?b . ?c ?p ?a } => { ?c ?p ?b } . 378. 379. # rdfs:domain 380. { ?p rdfs:domain ?d . ?a ?p ?b } => { ?a a ?d } . 381. 382. # rdfs:range 383. { ?p rdfs:range ?r . ?a ?p ?b } => { ?b a ?r } .
test1.n3: Hash URI, direct 200 response with RDF/n3
1. ########################### test1.n3 ############################ 2. # test1.n3: Hash URI with racine serving direct 200 response with RDF/n3. 3. # 4. # Sample input data for HTTP inferencing rules. 5. # This is a DRAFT and surely will change without notice. 6. # 7. # Test with: cwm rules.n3 test1.n3 --think --strings 8. # 9. # Author: David Booth <dbooth@hp.com> 10. # Date: 26-Feb-2008 11. # License: GPLv3: http://www.gnu.org/licenses/gpl-3.0.html 12. 13. ######################## Prefixes ########################### 14. # I see python code for parsing URIs here: 15. # http://www.w3.org/2000/10/swap/uripath.py 16. # but I haven't yet found an ontology for parsing URIs, 17. # though maybe the POWDER working group will eventually make one. 18. # @@@@ TODO: Find URI parsing ontology 19. @prefix uri: <http://example/uri#> . 20. @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . 21. @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . 22. @prefix log: <http://www.w3.org/2000/10/swap/log#>. 23. # These two HTTP ontologies by David Sheets are not currently used, 24. # but relationships between my http: ontology and his 25. # are shown in comments: 26. # @prefix dshttp: <http://www.w3.org/2007/ont/http#> . 27. # @prefix dshttph: <http://www.w3.org/2007/ont/httph#> . 28. @prefix http: <http://example/httpspec#> . 29. @prefix sumo: <http://example/sumo#> . 30. @prefix owl: <http://www.w3.org/2002/07/owl#> . 31. @prefix xsd: <http://www.w3.org/2001/XMLSchema#> . 32. @prefix decl: <http://example/uridecl#> . 33. @prefix n3: <http://example/n3#> . 34. @prefix string: <http://www.w3.org/2000/10/swap/string#> . 35. @prefix awww: <http://example/awww#> . 36. 37. ######################## Ground Facts ########################### 38. # Suppose an app comes across a triple such as 39. # _:foo _:fum <http://example/people#dan> . 40. # and somehow decides that it wants to learn more about <...#dan>. 41. # We'll assume that in parsing the above triple, the app 42. # *also* automatically asserted the following triple: 43. 44. <http://example/people#dan> uri:hasURI 45. "http://example/people#dan"^^xsd:anyURI . 46. 47. # And we'll assume that the app knows to "follow its nose" to 48. # learn more about <...#dan> by dereferencing the racine 49. # of its associated URI in search of a URI declaration. 50. # In this particular test case, we'll assume that 51. # the racine dereferences directly to 52. # a 200 OK response with a text/n3 53. # body. The following RDF expresses these assumptions. 54. # RDF has a 55. # restriction that a literal cannot be a subject in a triple, 56. # but n3 doesn't seem to have this restriction, so 57. # I don't know if I should write this differently or not. 58. # In any case that would be a rather trivial change. 59. 60. "http://example/people"^^xsd:anyURI 61. http:hasDirectGetReply 62. <http://example/test1#reply> . 63. 64. <http://example/test1#reply> 65. http:hasStatusCode 200 ; 66. http:hasContentType "text/n3" ; 67. http:hasEntityBody "@prefix sumo: <http://example/sumo#> . <http://example/people#dan> a sumo:Human . " . 68. 69. # Finally, we'll give a name for the awww:InformationResource 70. # that the racine denotes, so that the results will show that it 71. # is an awww:InformationResource: 72. <http://example/people> uri:hasURI 73. "http://example/people"^^xsd:anyURI . 74. 75. ######################## Results ########################### 76. # Given the above facts, the following rule checks to see if this 77. # test case succeeded, i.e., it checks whether the correct things 78. # were inferred. 79. 80. { 81. # Here is the main result that test1 should infer: 82. "http://example/people#dan"^^xsd:anyURI 83. decl:hasDeclaration 84. { <http://example/people#dan> a sumo:Human . } . 85. # And it should infer that the racine is an awww:InformationResource: 86. <http://example/people> a awww:InformationResource . 87. } => { 88. "test1" log:outputString "PASSED: test1\n" . 89. } .
test2.n3: Hash URI, 301 redirect, 200 response with RDF/n3
1. ########################### test2.n3 ############################ 2. # test2.n3: Hash URI with racine 301 redirected to RDF/n3. 3. # 4. # Sample input data for HTTP inferencing rules. 5. # This is a DRAFT and surely will change without notice. 6. # 7. # Test with: cwm rules.n3 test2.n3 --think --strings 8. # 9. # Author: David Booth <dbooth@hp.com> 10. # Date: 26-Feb-2008 11. # License: GPLv3: http://www.gnu.org/licenses/gpl-3.0.html 12. 13. ######################## Prefixes ########################### 14. # I see python code for parsing URIs here: 15. # http://www.w3.org/2000/10/swap/uripath.py 16. # but I haven't yet found an ontology for parsing URIs, 17. # though maybe the POWDER working group will eventually make one. 18. # @@@@ TODO: Find URI parsing ontology 19. @prefix uri: <http://example/uri#> . 20. @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . 21. @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . 22. @prefix log: <http://www.w3.org/2000/10/swap/log#>. 23. # These two HTTP ontologies by David Sheets are not currently used, 24. # but relationships between my http: ontology and his 25. # are shown in comments: 26. # @prefix dshttp: <http://www.w3.org/2007/ont/http#> . 27. # @prefix dshttph: <http://www.w3.org/2007/ont/httph#> . 28. @prefix http: <http://example/httpspec#> . 29. @prefix sumo: <http://example/sumo#> . 30. @prefix owl: <http://www.w3.org/2002/07/owl#> . 31. @prefix xsd: <http://www.w3.org/2001/XMLSchema#> . 32. @prefix decl: <http://example/uridecl#> . 33. @prefix n3: <http://example/n3#> . 34. @prefix string: <http://www.w3.org/2000/10/swap/string#> . 35. @prefix awww: <http://example/awww#> . 36. 37. ######################## Ground Facts ########################### 38. # Suppose an app comes across a triple such as 39. # _:foo _:fum <http://example/people#dan> . 40. # and somehow decides that it wants to learn more about <...#dan>. 41. # We assume that the parser has automatically asserted: 42. 43. <http://example/people#dan> uri:hasURI 44. "http://example/people#dan"^^xsd:anyURI . 45. 46. # And we'll assume that the app knows to "follow its nose" 47. # by dereferencing the URI's racine in search of a 48. # URI declaration. We'll assume that the racine denotes 49. # some as-yet-unknown resource: 50. 51. <http://example/people> uri:hasURI 52. "http://example/people"^^xsd:anyURI . 53. 54. # In this test case, the racine dereferences to a 301 55. # redirect that supplies a new metadata URI: 56. 57. "http://example/people"^^xsd:anyURI 58. http:hasDirectGetReply 59. <http://example/test2#reply301> . 60. 61. <http://example/test2#reply301> 62. http:hasStatusCode 301 ; 63. http:hasLocation "http://example/people/metadata"^^xsd:anyURI . 64. 65. # And this metadata URI dereferences to a 200 response with 66. # RDF/n3: 67. 68. "http://example/people/metadata"^^xsd:anyURI 69. http:hasDirectGetReply 70. <http://example/test2#reply200> . 71. 72. <http://example/test2#reply200> 73. http:hasStatusCode 200 ; 74. http:hasContentType "text/n3" ; 75. http:hasEntityBody "@prefix sumo: <http://example/sumo#> . <http://example/people#dan> a sumo:Human . " . 76. 77. # And this new metadata URI also denotes some 78. # as-yet-unknown resource: 79. 80. <http://example/people/metadata> uri:hasURI 81. "http://example/people/metadata"^^xsd:anyURI . 82. 83. ######################## Results ########################### 84. # Given the above facts, the following rule checks to see if this 85. # test case succeeded. 86. 87. { 88. # Here is the main result that test2 should infer: 89. "http://example/people#dan"^^xsd:anyURI 90. decl:hasDeclaration 91. { <http://example/people#dan> a sumo:Human . } . 92. # And, because of the 301 redirect, these are the same: 93. <http://example/people#dan> = 94. <http://example/people#dan> . 95. # And the metadata URI denotes an awww:InformationResource: 96. <http://example/people/metadata> a awww:InformationResource. 97. # And because of the second 301 redirect, the racine denotes 98. # the same resource that the new metadata URI denotes: 99. <http://example/people> = 100. <http://example/people/metadata> . 101. } => { 102. "test2" log:outputString "PASSED: test2\n" . 103. } .
test3.n3: Hashless URI, 303 redirect, 200 response with RDF/n3
1. ########################### test3.n3 ############################ 2. # test3.n3: Hashless URI, 303 redirect to 200 response serving RDF/n3. 3. # 4. # Sample input data for HTTP inferencing rules. 5. # This is a DRAFT and surely will change without notice. 6. # 7. # Test with: cwm rules.n3 test3.n3 --think --strings 8. # 9. # Author: David Booth <dbooth@hp.com> 10. # Date: 26-Feb-2008 11. # License: GPLv3: http://www.gnu.org/licenses/gpl-3.0.html 12. 13. ######################## Prefixes ########################### 14. # I see python code for parsing URIs here: 15. # http://www.w3.org/2000/10/swap/uripath.py 16. # but I haven't yet found an ontology for parsing URIs, 17. # though maybe the POWDER working group will eventually make one. 18. # @@@@ TODO: Find URI parsing ontology 19. @prefix uri: <http://example/uri#> . 20. @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . 21. @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . 22. @prefix log: <http://www.w3.org/2000/10/swap/log#>. 23. # These two HTTP ontologies by David Sheets are not currently used, 24. # but relationships between my http: ontology and his 25. # are shown in comments: 26. # @prefix dshttp: <http://www.w3.org/2007/ont/http#> . 27. # @prefix dshttph: <http://www.w3.org/2007/ont/httph#> . 28. @prefix http: <http://example/httpspec#> . 29. @prefix sumo: <http://example/sumo#> . 30. @prefix owl: <http://www.w3.org/2002/07/owl#> . 31. @prefix xsd: <http://www.w3.org/2001/XMLSchema#> . 32. @prefix decl: <http://example/uridecl#> . 33. @prefix n3: <http://example/n3#> . 34. @prefix string: <http://www.w3.org/2000/10/swap/string#> . 35. @prefix awww: <http://example/awww#> . 36. 37. ######################## Ground Facts ########################### 38. # Suppose an app comes across a triple such as 39. # _:foo _:fum <http://example/people/dan303> . 40. # and somehow decides that it wants to learn more about <.../dan303>. 41. # We assume that the parser has automatically asserted: 42. 43. <http://example/people/dan303> uri:hasURI 44. "http://example/people/dan303"^^xsd:anyURI . 45. 46. # And we'll assume that the app knows to "follow its nose" 47. # by dereferencing the URI in search of a URI declaration. 48. # In this test case, the URI dereferences to a 303 redirect 49. # to a metadata URI: 50. 51. "http://example/people/dan303"^^xsd:anyURI 52. http:hasDirectGetReply 53. <http://example/test3#reply303> . 54. 55. <http://example/test3#reply303> 56. http:hasStatusCode 303 ; 57. http:hasLocation "http://example/people/metadata"^^xsd:anyURI . 58. 59. # And the metadata URI dereferences to a 200 response with 60. # RDF/n3: 61. 62. <http://example/people/metadata> uri:hasURI 63. "http://example/people/metadata"^^xsd:anyURI . 64. 65. "http://example/people/metadata"^^xsd:anyURI 66. http:hasDirectGetReply 67. <http://example/test3#reply200> . 68. 69. <http://example/test3#reply200> 70. http:hasStatusCode 200 ; 71. http:hasContentType "text/n3" ; 72. http:hasEntityBody "@prefix sumo: <http://example/sumo#> . <http://example/people/dan303> a sumo:Human . " . 73. 74. ######################## Results ########################### 75. # Given the above facts, the following rule checks to see if this 76. # test case succeeded, i.e., it checks whether the correct things 77. # were inferred. 78. 79. { 80. # Here is the main result that test3 should infer: 81. "http://example/people/dan303"^^xsd:anyURI 82. decl:hasDeclaration 83. { <http://example/people/dan303> a sumo:Human . } . 84. # And in the course of things, it should also infer that the metadata URI 85. # is an awww:InformationResource (because it returned a 200 response): 86. <http://example/people/metadata> a awww:InformationResource . 87. } => { 88. "test3" log:outputString "PASSED: test3\n" . 89. } .
test4.n3: Hashless URI, 301-->303-->301-->200, RDF/n3
1. ########################### test4.n3 ############################ 2. # test4.n3: Hashless URI; RDF/n3 via 301-->303-->301-->200. 3. # 4. # Sample input data for HTTP inferencing rules. 5. # This is a DRAFT and surely will change without notice. 6. # 7. # Test with: cwm rules.n3 test4.n3 --think --strings 8. # 9. # Author: David Booth <dbooth@hp.com> 10. # Date: 26-Feb-2008 11. # License: GPLv3: http://www.gnu.org/licenses/gpl-3.0.html 12. 13. ######################## Prefixes ########################### 14. # I see python code for parsing URIs here: 15. # http://www.w3.org/2000/10/swap/uripath.py 16. # but I haven't yet found an ontology for parsing URIs, 17. # though maybe the POWDER working group will eventually make one. 18. # @@@@ TODO: Find URI parsing ontology 19. @prefix uri: <http://example/uri#> . 20. @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . 21. @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . 22. @prefix log: <http://www.w3.org/2000/10/swap/log#>. 23. # These two HTTP ontologies by David Sheets are not currently used, 24. # but relationships between my http: ontology and his 25. # are shown in comments: 26. # @prefix dshttp: <http://www.w3.org/2007/ont/http#> . 27. # @prefix dshttph: <http://www.w3.org/2007/ont/httph#> . 28. @prefix http: <http://example/httpspec#> . 29. @prefix sumo: <http://example/sumo#> . 30. @prefix owl: <http://www.w3.org/2002/07/owl#> . 31. @prefix xsd: <http://www.w3.org/2001/XMLSchema#> . 32. @prefix decl: <http://example/uridecl#> . 33. @prefix n3: <http://example/n3#> . 34. @prefix string: <http://www.w3.org/2000/10/swap/string#> . 35. @prefix awww: <http://example/awww#> . 36. 37. ######################## Ground Facts ########################### 38. # Suppose an app comes across a triple such as 39. # _:foo _:fum <http://example/people/dan303> . 40. # and somehow decides that it wants to learn more about <.../dan303>. 41. # We assume that the parser has automatically asserted: 42. 43. <http://example/people/dan303> uri:hasURI 44. "http://example/people/dan303"^^xsd:anyURI . 45. 46. # And we'll assume that the app knows to "follow its nose" 47. # by dereferencing the URI in search of a URI declaration. 48. # In this test case, the URI dereferences to a 301 redirect: 49. 50. "http://example/people/dan303"^^xsd:anyURI 51. http:hasDirectGetReply 52. <http://example/test4#reply301a> . 53. 54. <http://example/test4#reply301a> 55. http:hasStatusCode 301 ; 56. http:hasLocation "http://example/people/dan303New"^^xsd:anyURI . 57. 58. # And this new URI denotes some resource: 59. 60. <http://example/people/dan303New> uri:hasURI 61. "http://example/people/dan303New"^^xsd:anyURI . 62. 63. # And it 303-redirects to a metadata URI: 64. 65. "http://example/people/dan303New"^^xsd:anyURI 66. http:hasDirectGetReply 67. <http://example/test4#reply303> . 68. 69. <http://example/test4#reply303> 70. http:hasStatusCode 303 ; 71. http:hasLocation "http://example/people/metadata"^^xsd:anyURI . 72. 73. # . . . which denotes some resource: 74. 75. <http://example/people/metadata> uri:hasURI 76. "http://example/people/metadata"^^xsd:anyURI . 77. 78. # And the metadata URI dereferences to another 301-redirect: 79. 80. "http://example/people/metadata"^^xsd:anyURI 81. http:hasDirectGetReply 82. <http://example/test4#reply301b> . 83. 84. <http://example/test4#reply301b> 85. http:hasStatusCode 301 ; 86. http:hasLocation "http://example/people/metadataNew"^^xsd:anyURI . 87. 88. # And the new metadata URI dereferences to a 200 response with 89. # RDF/n3: 90. 91. "http://example/people/metadataNew"^^xsd:anyURI 92. http:hasDirectGetReply 93. <http://example/test4#reply200> . 94. 95. <http://example/test4#reply200> 96. http:hasStatusCode 200 ; 97. http:hasContentType "text/n3" ; 98. http:hasEntityBody "@prefix sumo: <http://example/sumo#> . <http://example/people/dan303> a sumo:Human . " . 99. 100. # And this new metadata URI also denotes some resource: 101. 102. <http://example/people/metadataNew> uri:hasURI 103. "http://example/people/metadataNew"^^xsd:anyURI . 104. 105. ######################## Results ########################### 106. # Given the above facts, the following rule checks to see if this 107. # test case succeeded. 108. 109. { 110. # Here is the main result that test4 should infer: 111. "http://example/people/dan303"^^xsd:anyURI 112. decl:hasDeclaration 113. { <http://example/people/dan303> a sumo:Human . } . 114. # And, because of the 301 redirect, these are the same: 115. <http://example/people/dan303> = 116. <http://example/people/dan303New> . 117. # And the new metadata URI denotes an awww:InformationResource: 118. <http://example/people/metadataNew> a awww:InformationResource. 119. # And because of the second 301 redirect, the the old metadata 120. # URI denotes the same thing: 121. <http://example/people/metadataNew> = 122. <http://example/people/metadata> . 123. } => { 124. "test4" log:outputString "PASSED: test4\n" . 125. } .
test5.n3: URI declaration provided via rdfs:isDefinedBy
1. ########################### test5.n3 ############################ 2. # test5.n3: Hash URI with URI declaration provided via rdfs:isDefinedBy . 3. # 4. # Sample input data for HTTP inferencing rules. 5. # This is a DRAFT and surely will change without notice. 6. # 7. # Test with: cwm rules.n3 test5.n3 --think --strings 8. # 9. # Author: David Booth <dbooth@hp.com> 10. # Date: 26-Feb-2008 11. # License: GPLv3: http://www.gnu.org/licenses/gpl-3.0.html 12. 13. ######################## Prefixes ########################### 14. # I see python code for parsing URIs here: 15. # http://www.w3.org/2000/10/swap/uripath.py 16. # but I haven't yet found an ontology for parsing URIs, 17. # though maybe the POWDER working group will eventually make one. 18. # @@@@ TODO: Find URI parsing ontology 19. @prefix uri: <http://example/uri#> . 20. @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . 21. @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . 22. @prefix log: <http://www.w3.org/2000/10/swap/log#>. 23. # These two HTTP ontologies by David Sheets are not currently used, 24. # but relationships between my http: ontology and his 25. # are shown in comments: 26. # @prefix dshttp: <http://www.w3.org/2007/ont/http#> . 27. # @prefix dshttph: <http://www.w3.org/2007/ont/httph#> . 28. @prefix http: <http://example/httpspec#> . 29. @prefix sumo: <http://example/sumo#> . 30. @prefix owl: <http://www.w3.org/2002/07/owl#> . 31. @prefix xsd: <http://www.w3.org/2001/XMLSchema#> . 32. @prefix decl: <http://example/uridecl#> . 33. @prefix n3: <http://example/n3#> . 34. @prefix string: <http://www.w3.org/2000/10/swap/string#> . 35. @prefix awww: <http://example/awww#> . 36. 37. ######################## Ground Facts ########################### 38. # Suppose an app comes across a triple such as 39. # _:foo _:fum <http://example/people#dan> . 40. # and it knows that: 41. 42. <http://example/people#dan> rdfs:isDefinedBy 43. <http://example/people/metadata> . 44. 45. # and somehow the app decides that it wants to learn 46. # more about <...#dan>. 47. # We assume that the parser has automatically asserted: 48. 49. <http://example/people#dan> uri:hasURI 50. "http://example/people#dan"^^xsd:anyURI . 51. 52. <http://example/people/metadata> uri:hasURI 53. "http://example/people/metadata"^^xsd:anyURI . 54. 55. # And we'll assume that dereferencing http://.../metadata 56. # yields a 200 response with RDF/n3: 57. 58. "http://example/people/metadata"^^xsd:anyURI 59. http:hasDirectGetReply 60. <http://example/test5#reply200> . 61. 62. <http://example/test5#reply200> 63. http:hasStatusCode 200 ; 64. http:hasContentType "text/n3" ; 65. http:hasEntityBody "@prefix sumo: <http://example/sumo#> . <http://example/people#dan> a sumo:Human . " . 66. 67. ######################## Results ########################### 68. # Given the above facts, the following rule checks to see if this 69. # test case succeeded. 70. 71. { 72. # Here is the main result that test5 should infer: 73. "http://example/people#dan"^^xsd:anyURI 74. decl:hasDeclaration 75. { <http://example/people#dan> a sumo:Human . } . 76. # And the metadata URI denotes an awww:InformationResource: 77. <http://example/people/metadata> a awww:InformationResource. 78. } => { 79. "test5" log:outputString "PASSED: test5\n" . 80. } .
CWM Questions
I'm a CWM newbie, so please tell me if you know the answer to any of these.
- How do I write a multi-line literal string? Use a triple double-quoted string, like in python.
I'd show and example but who knows what the wiki would do with it.
- If I write a literal string with no explicit data type, such as "this string", what is its default data type? Is it xsd:string? I.e., is "this string" the same as "this string"xsd:string? It has no datatype. But note later discussion thread starting here: http://lists.w3.org/Archives/Public/public-awwsw/2008Mar/0001.html
- Do I need to avoid using a literal as the subject of a triple? Or will CWM somehow fix it if I do (perhaps by generating a bnode), given that RDF does not allow it? Does CWM generate conforming RDF/XML in these cases? You can make a literal the subject of a string, just you can't serialize
it with the RDF/XML version 1.0. You can serialize it in N3.
- Is there an easy way to parse a URI to get its racine? I need to say: ?uri hasRacine ?racine .
A: You need ?thing log:uri ?ur; log:racine ?doc. ?doc log:uri ?racine. I suppose. log:racine is defined n eth things not the URIs IIRC.
- How do I parse a string (or better yet, an octet sequence) as RDF/XML? I need to say: ?octets parsesTo ?formula .
- Is there some sort of #include mechanism? How do I easily share the same set of @prefix declarations between several n3 files? No, there is no #include. You have to repeat the prefixed. This means that each N3 file stands on its own.
- What data type should I use for a sequence of octets?