summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpukkamustard <pukkamustard@posteo.net>2020-09-27 20:45:48 +0200
committerpukkamustard <pukkamustard@posteo.net>2020-09-27 20:45:48 +0200
commitd1c7ff331e86e3ef7f87bd91124c640bc71dbef9 (patch)
treead5e0d6016920b39fd36c4e58f7c3c22ca7cd9a1
parent4ba8a9d4965eb30dddb57fc6eb038f03cf8abd7d (diff)
(schemantic rdf datalog): add ρdf fragment of RDF from Simple and
Efficient Minimal RDFS
-rw-r--r--README.org5
-rw-r--r--schemantic/rdf/datalog.scm54
-rw-r--r--tests/data/foods.ttl16
-rw-r--r--tests/schemantic/rdf/datalog.scm38
4 files changed, 107 insertions, 6 deletions
diff --git a/README.org b/README.org
index 9633830..956968c 100644
--- a/README.org
+++ b/README.org
@@ -28,8 +28,6 @@ There are many serialization formats for RDF. Currently guile-schemantic only su
It would be nice to support more formats and also be able to write out in different formats. Maybe one could use existing C libraries such as [[https://github.com/drobilla/serd][serd]] or [[http://librdf.org/raptor/][Raptor]].
-
-
*** TODO Blank Node Skolemization
An transducer that skolemizes Blank Nodes while parsing - deal with Blank Nodes before they enter. Possible Skolemization schemes:
@@ -43,8 +41,7 @@ An transducer that skolemizes Blank Nodes while parsing - deal with Blank Nodes
While parsing it would be nice to parse into the most specific supported literal (e.g. literal with datatype ~xsd:integer~ should be parsed as a <xsd:literal> and not as a generic literal). This requires a mapping from datatype iri to appropriate literal class.
-
-*** TODO RDFS inference
+*** DONE RDFS inference
Implement [[https://sci-hub.se/https://doi.org/10.1016/j.websem.2009.07.003][Simple and Efficient Minimal RDFS]] using Datalog.
diff --git a/schemantic/rdf/datalog.scm b/schemantic/rdf/datalog.scm
index e34a272..cc8af5e 100644
--- a/schemantic/rdf/datalog.scm
+++ b/schemantic/rdf/datalog.scm
@@ -1,13 +1,17 @@
(define-module (schemantic rdf datalog)
#:use-module (schemantic rdf)
+ #:use-module ((schemantic ns) #:select (rdf rdfs))
+ #:use-module (datalog)
#:use-module (datalog vhash-set)
#:use-module (ice-9 vlist)
#:use-module (srfi srfi-1)
- #:export (add-rdf-graph-to-edb))
+ #:export (add-rdf-graph-to-edb
+
+ rhodf))
(define (add-rdf-graph-to-edb predicate-symbol graph context)
(vhash-cons
@@ -26,3 +30,51 @@
(vector-ref attributes 1)
(vector-ref attributes 2))))
context))
+
+
+;; The ρdf fragment of RDF
+;; See: Muñoz, S., Pérez, J., & Gutierrez, C. (2009). Simple and Efficient Minimal RDFS. Web Semantics: Science, Services and Agents on the World Wide Web, 7(3), 220–234. doi:10.1016/j.websem.2009.07.003
+(define rhodf
+ (list
+
+ ;; Subproperty (a)
+ (:- (rhodf (lvar 'a) (rdfs "subProperty") (lvar 'c))
+ (rhodf (lvar 'a) (rdfs "subProperty") (lvar 'b))
+ (rhodf (lvar 'b) (rdfs "subProperty") (lvar 'c)))
+
+ ;; Subproperty (b)
+ (:- (rhodf (lvar 'x) (lvar 'b) (lvar 'y))
+ (rhodf (lvar 'a) (rdfs "subProperty") (lvar 'b))
+ (rhodf (lvar 'x) (lvar 'a) (lvar 'y)))
+
+ ;; Subclass (a)
+ (:- (rhodf (lvar 'a) (rdfs "subClass") (lvar 'c))
+ (rhodf (lvar 'a) (rdfs "subClass") (lvar 'b))
+ (rhodf (lvar 'b) (rdfs "subClass") (lvar 'c)))
+
+ ;; Subclass (b)
+ (:- (rhodf (lvar 'x) (rdf "type") (lvar 'b))
+ (rhodf (lvar 'a) (rdfs "subClass") (lvar 'b))
+ (rhodf (lvar 'x) (rdf "type") (lvar 'a)))
+
+ ;; Typing (a)
+ (:- (rhodf (lvar 'x) (rdf "type") (lvar 'b))
+ (rhodf (lvar 'a) (rdfs "domain") (lvar 'b))
+ (rhodf (lvar 'x) (lvar 'a) (lvar 'y)))
+
+ ;; Typing (b)
+ (:- (rhodf (lvar 'y) (rdf "type") (lvar 'b))
+ (rhodf (lvar 'a) (rdfs "range") (lvar 'b))
+ (rhodf (lvar 'x) (lvar 'a) (lvar 'y)))
+
+ ;; Implicit Typing (a)
+ (:- (rhodf (lvar 'x) (rdf "type") (lvar 'b))
+ (rhodf (lvar 'a) (rdfs "domain") (lvar 'b))
+ (rhodf (lvar 'c) (rdfs "subProperty") (lvar 'a))
+ (rhodf (lvar 'x) (lvar 'c) (lvar 'y)))
+
+ ;; Implicit Typing (b)
+ (:- (rhodf (lvar 'y) (rdf "type") (lvar 'b))
+ (rhodf (lvar 'a) (rdfs "range") (lvar 'b))
+ (rhodf (lvar 'c) (rdfs "subProperty") (lvar 'a))
+ (rhodf (lvar 'x) (lvar 'c) (lvar 'y)))))
diff --git a/tests/data/foods.ttl b/tests/data/foods.ttl
new file mode 100644
index 0000000..212ee9c
--- /dev/null
+++ b/tests/data/foods.ttl
@@ -0,0 +1,16 @@
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix foods: <http://example.org/foods#> .
+
+foods:Food a rdfs:Class .
+
+foods:Beverage a rdfs:Class .
+
+foods:recommendedBeverage a rdfs:Property ;
+ rdfs:domain foods:Food ;
+ rdfs:range foods:Beverage .
+
+foods:Pizza a foods:Food .
+
+foods:Margherita a foods:Pizza ;
+ foods:recommendedBeverage foods:Beer .
diff --git a/tests/schemantic/rdf/datalog.scm b/tests/schemantic/rdf/datalog.scm
index 5526b8f..8f7eac1 100644
--- a/tests/schemantic/rdf/datalog.scm
+++ b/tests/schemantic/rdf/datalog.scm
@@ -1,6 +1,6 @@
(define-module (tests schemantic rdf datalog)
#:use-module (schemantic rdf)
- #:use-module ((schemantic ns) #:select (rdf))
+ #:use-module ((schemantic ns) #:select (rdf rdfs))
#:use-module (schemantic serialization turtle)
#:use-module (schemantic graph vhash)
#:use-module (schemantic rdf datalog)
@@ -47,3 +47,39 @@
(set-contains? notes (vector (make-iri "https://test.example/notes/1"))))
(test-end)
+
+(test-begin "ρdf fragment (Simple and Efficient Minimal RDFS)")
+
+(define foods-ttl (make-vhash-graph))
+
+(turtle-transduce
+ (tmap identity)
+ (graph-radd foods-ttl)
+ (call-with-input-file "tests/data/foods.ttl" get-string-all)
+ (make-iri "urn:base-iri"))
+
+(define-namespace foods "http://example.org/foods#")
+
+(define foods-rhodf
+ (cdr
+ (vhash-assoc 'rhodf
+ (datalog-eval
+ (append
+ (list
+ ;; Define all triples as rhodf triples.
+ (:- (rhodf (lvar 's) (lvar 'p) (lvar 'o)) (graph-edb (lvar 's) (lvar 'p) (lvar 'o))))
+ ;; Add the Datalog clauses that define rhodf
+ rhodf)
+ #:edb (add-rdf-graph-to-edb 'graph-edb foods-ttl vlist-null)))))
+
+(test-assert "Subclass (b) (Margherita is Food)"
+ (set-contains?
+ foods-rhodf
+ (vector (foods "Margherita") (rdf "type") (foods "Food"))))
+
+(test-assert "Typing (a)"
+ (set-contains?
+ foods-rhodf
+ (vector (foods "Beer") (rdf "type") (foods "Beverage"))))
+
+(test-end)