summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpukkamustard <pukkamustard@posteo.net>2020-09-04 12:03:54 +0200
committerpukkamustard <pukkamustard@posteo.net>2020-09-04 12:03:54 +0200
commit856fd98d8497c46b5b1b8c1598550cd960e3d228 (patch)
tree5cb6691e5d4557a8c15aa91c2f7ea41d725355ce
parent34ca11f116140409be7210ef7af4ff1c45698f29 (diff)
(schemantic serialization turtle): use the Turtle parser from guile-rdf
-rw-r--r--README.org3
-rw-r--r--guix.scm2
-rw-r--r--hall.scm12
-rw-r--r--schemantic/interop/guile-rdf.scm45
-rw-r--r--schemantic/literal.scm6
-rw-r--r--schemantic/rdf.scm17
-rw-r--r--schemantic/serialization/turtle.scm19
-rw-r--r--tests/data/clowns.ttl21
-rw-r--r--tests/schemantic/serializaton/turtle.scm38
9 files changed, 154 insertions, 9 deletions
diff --git a/README.org b/README.org
index 273c1ef..0a2447f 100644
--- a/README.org
+++ b/README.org
@@ -5,7 +5,6 @@
A [[https://www.gnu.org/software/guile/][Guile]] library for the Semantic Web. Implements the Resource Description Framework (RDF).
* Caveats
-
** No Blank Nodes
Instead there is a ~<lvar>~ that can be used as a local existential variable. ~<lvar>~ can not be serialized.
@@ -35,4 +34,4 @@ A collection of tools related to the Semantic Web for Scheme48 (mostly portable)
** [[https://framagit.org/tyreunom/guile-rdf][Guile RDF]]
-Guile library for RDF.
+Guile library for RDF. This library uses the RDF/Turtle parser from Guile RDF.
diff --git a/guix.scm b/guix.scm
index e69b68c..2f10459 100644
--- a/guix.scm
+++ b/guix.scm
@@ -22,7 +22,7 @@
("pkg-config" ,pkg-config)
("texinfo" ,texinfo)))
(inputs `(("guile" ,guile-3.0)))
- (propagated-inputs `())
+ (propagated-inputs `(("guile-rdf" ,guile-rdf)))
(synopsis "Guile library for the Semantic Web")
(description
"Guile Schemantic is a Guile library for the Semantic Web and implements the Resource Description Framework (RDF).")
diff --git a/hall.scm b/hall.scm
index 03d9123..449bb2f 100644
--- a/hall.scm
+++ b/hall.scm
@@ -10,15 +10,19 @@
(home-page
"https://gitlab.com/openengiadina/guile-schemantic")
(license gpl3+)
- (dependencies `())
+ (dependencies `(("guile-rdf" ,guile-rdf)))
(files (libraries
((scheme-file "schemantic")
(directory
"schemantic"
((directory
+ "serialization"
+ ((scheme-file "turtle")))
+ (directory
"graph"
((directory "vhash" ((scheme-file "index")))
(scheme-file "vhash")))
+ (directory "interop" ((scheme-file "guile-rdf")))
(directory "rdf" ((scheme-file "lang-string")))
(scheme-file "iri")
(scheme-file "xsd")
@@ -27,9 +31,13 @@
(scheme-file "ns")))))
(tests ((directory
"tests"
- ((directory
+ ((directory "data" ())
+ (directory
"schemantic"
((directory "graph" ((scheme-file "vhash")))
+ (directory
+ "serializaton"
+ ((scheme-file "turtle")))
(scheme-file "iri")
(scheme-file "literal")))))))
(programs ((directory "scripts" ())))
diff --git a/schemantic/interop/guile-rdf.scm b/schemantic/interop/guile-rdf.scm
new file mode 100644
index 0000000..97ccfef
--- /dev/null
+++ b/schemantic/interop/guile-rdf.scm
@@ -0,0 +1,45 @@
+; SPDX-FileCopyrightText: 2020 pukkamustard <pukkamustard@posteo.net>
+;
+; SPDX-License-Identifier: GPL-3.0-or-later
+
+(define-module (schemantic interop guile-rdf)
+ #:use-module (schemantic rdf)
+ #:use-module ((schemantic ns) #:select (xsd rdf))
+
+ #:use-module (rdf rdf)
+
+ #:export (rdf-triple->triple))
+
+;; Interop to the guile-rdf library
+
+;; NOTE maybe it makes sense to keep the mapping of datatype+lexical-form to
+;; literal in some other place as this is something that would be used by other
+;; serializations... literals are tricky
+(define (rdf-literal->literal literal)
+ (let ((datatype (make-iri (rdf-literal-type literal))))
+ (cond
+
+ ((equal? (rdf "langString") datatype)
+ (make-lang-string
+ (rdf-literal-lexical-form literal)
+ #:language (rdf-literal-langtag literal)))
+
+ ((equal? (xsd "string") datatype)
+ (make-literal (rdf-literal-lexical-form literal)))
+
+ ((equal? (xsd "integer") datatype)
+ (make-literal (string->number (rdf-literal-lexical-form literal))))
+
+ (else (make-generic-literal (rdf-literal-lexical-form literal)
+ #:datatype datatype)))))
+
+(define (rdf-term->term term)
+ (cond
+ ((string? term) (make-iri term))
+ ((rdf-literal? term) (rdf-literal->literal term))))
+
+(define (rdf-triple->triple t)
+ (make-triple
+ (rdf-term->term (rdf-triple-subject t))
+ (rdf-term->term (rdf-triple-predicate t))
+ (rdf-term->term (rdf-triple-object t))))
diff --git a/schemantic/literal.scm b/schemantic/literal.scm
index 1733cdf..a4cfb77 100644
--- a/schemantic/literal.scm
+++ b/schemantic/literal.scm
@@ -10,12 +10,14 @@
#:export (<literal>
literal?
make-literal
- make-generic-literal
literal-value
literal-lexical
literal-canonical
literal-datatype
- literal-language))
+ literal-language
+
+ <generic-literal>
+ make-generic-literal))
(define-class <literal> (<term>)
(value #:init-keyword #:value #:getter literal-value))
diff --git a/schemantic/rdf.scm b/schemantic/rdf.scm
index f3a2e0d..cc8a0a9 100644
--- a/schemantic/rdf.scm
+++ b/schemantic/rdf.scm
@@ -24,6 +24,7 @@
<graph>
graph?
graph-add
+ graph-radd
graph-match
<description>
@@ -42,13 +43,18 @@
<literal>
make-literal
- make-generic-literal
literal?
literal-value
literal-lexical
literal-canonical
literal-datatype
- literal-language))
+ literal-language
+
+ <generic-literal>
+ make-generic-literal
+
+ <rdf:langString>
+ make-lang-string))
;; Triple
@@ -100,6 +106,13 @@
(define-generic graph-add)
(define-generic graph-match)
+(define-method (graph-radd (g <graph>))
+ "Returns a SRFI-171 reducer that adds triples to graph g"
+ (case-lambda
+ (() g)
+ ((result) result)
+ ((result triple) (graph-add g triple))))
+
(define-method (graph-match (g <graph>) (t <triple>))
(graph-match g (triple-subject t) (triple-predicate t) (triple-object t)))
diff --git a/schemantic/serialization/turtle.scm b/schemantic/serialization/turtle.scm
new file mode 100644
index 0000000..73e3c26
--- /dev/null
+++ b/schemantic/serialization/turtle.scm
@@ -0,0 +1,19 @@
+; SPDX-FileCopyrightText: 2020 pukkamustard <pukkamustard@posteo.net>
+;
+; SPDX-License-Identifier: GPL-3.0-or-later
+
+(define-module (schemantic serialization turtle)
+ #:use-module (schemantic rdf)
+ #:use-module (schemantic interop guile-rdf)
+
+ #:use-module (turtle tordf)
+
+ #:use-module (srfi srfi-171)
+
+ #:export (turtle-transduce))
+
+(define (turtle-transduce xform f string base-iri)
+ (list-transduce
+ (compose (tmap rdf-triple->triple) xform)
+ f
+ (turtle->rdf string (iri-value base-iri))))
diff --git a/tests/data/clowns.ttl b/tests/data/clowns.ttl
new file mode 100644
index 0000000..44fe9e3
--- /dev/null
+++ b/tests/data/clowns.ttl
@@ -0,0 +1,21 @@
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix schema: <https://schema.org/> .
+@prefix as: <https://www.w3.org/ns/activitystreams> .
+
+<https://test.example/notes/1>
+ rdf:type as:Note ;
+ as:attributedTo <https://test.example/alice> ;
+ as:content "The clowns just went trough the loop!"@en ;
+ as:image <https://test.example/notes/1#image> ;
+ as:context <https://circus.show/performance-in-funky-town> .
+
+<https://test.example/notes/1#image>
+ rdf:type as:Image ;
+ as:url <https://test.example/images/1.jpg> .
+
+<https://test.example/alice>
+ rdf:type as:Person .
+
+<https://circus.show/performance-in-funky-town>
+ rdf:type schema:Event ;
+ schema:location <https://circus.show/performance-in-funky-town#location> .
diff --git a/tests/schemantic/serializaton/turtle.scm b/tests/schemantic/serializaton/turtle.scm
new file mode 100644
index 0000000..e03a260
--- /dev/null
+++ b/tests/schemantic/serializaton/turtle.scm
@@ -0,0 +1,38 @@
+; SPDX-FileCopyrightText: 2020 pukkamustard <pukkamustard@posteo.net>
+;
+; SPDX-License-Identifier: GPL-3.0-or-later
+
+(define-module (tests schemantic serialization turtle)
+ #:use-module (schemantic rdf)
+ #:use-module (schemantic serialization turtle)
+
+ #:use-module (oop goops)
+ #:use-module (schemantic graph vhash)
+
+ #:use-module (ice-9 textual-ports) ; for reading ttl file
+
+ #:use-module (srfi srfi-64)
+ #:use-module (srfi srfi-171))
+
+
+(define clowns (call-with-input-file "tests/data/clowns.ttl" get-string-all))
+
+(test-begin "turtle")
+
+(test-equal "transduce 10 triples into list"
+ 10 (length (turtle-transduce (tmap identity)
+ rcons
+ clowns (make-iri "urn:base"))))
+
+
+(test-equal "transduce into graph"
+ 10
+ (begin
+ (define g (make <vhash-graph>))
+ (turtle-transduce (tmap identity)
+ (graph-radd g)
+ clowns
+ (make-iri "urn:base"))
+ (length (graph-match g (lvar) (lvar) (lvar)))))
+
+(test-end "turtle")