Add simple entailment regime and associated tests

Julien LepillerFri Apr 03 03:36:30+0200 2020

63e0b0f

Add simple entailment regime and associated tests

Makefile.am

11
include guile.am
22
33
SOURCES= \
4+
  rdf/entailment/simple.scm \
45
  rdf/rdf.scm \
56
  rdf/xsd.scm \
67
  turtle/parser.scm \

1213
1314
TEST_EXTENSIONS = .scm
1415
SCM_LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/tap-driver.sh --color-tests yes --ignore-exit
15-
TESTS = tests/turtle.scm
16+
TESTS = tests/turtle.scm tests/semantics.scm
1617
EXTRA_DIST += $(TESTS)

configure.ac

1111
GUILE_SITE_DIR
1212
1313
AC_CONFIG_FILES([pre-inst-env], [chmod +x pre-inst-env])
14+
AC_CONFIG_FILES([tests/semantics.scm], [chmod +x tests/semantics.scm])
1415
AC_CONFIG_FILES([tests/turtle.scm], [chmod +x tests/turtle.scm])
1516
AC_CONFIG_FILES(Makefile)
1617
AC_REQUIRE_AUX_FILE([tap-driver.sh])

rdf/entailment/simple.scm unknown status 1

1+
;;;; Copyright (C) 2020 Julien Lepiller <julien@lepiller.eu>
2+
;;;; 
3+
;;;; This library is free software; you can redistribute it and/or
4+
;;;; modify it under the terms of the GNU Lesser General Public
5+
;;;; License as published by the Free Software Foundation; either
6+
;;;; version 3 of the License, or (at your option) any later version.
7+
;;;; 
8+
;;;; This library is distributed in the hope that it will be useful,
9+
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11+
;;;; Lesser General Public License for more details.
12+
;;;; 
13+
;;;; You should have received a copy of the GNU Lesser General Public
14+
;;;; License along with this library; if not, write to the Free Software
15+
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16+
;;;; 
17+
18+
(define-module (rdf entailment simple)
19+
  #:use-module (ice-9 match)
20+
  #:use-module (rdf rdf)
21+
  #:use-module (srfi srfi-1)
22+
  #:export (consistent-graph?
23+
            entails?))
24+
25+
;; The simple entailment regime doesn't impose any condition of graph consistency.
26+
(define consistent-graph? (const #t))
27+
28+
;; G entails E if E has an instance (where blank nodes are replaced by literals
29+
;; or IRIs) that is a subgraph of G.
30+
;;
31+
;; We re-use similar procedures to verifying isomorphism of graphs, but this time
32+
;; blank nodes can also map to literals and IRIs.
33+
34+
(define (sat? equivalences)
35+
  "Return whether the set of equivalences satisfies the condition that it represents
36+
an isomorphism between two blank node sets: for every equality, check that the
37+
first component is always associated to the same second component, and that the
38+
second component is always associated with the first."
39+
  (match equivalences
40+
    ('() #t)
41+
    (((first . second) equivalences ...)
42+
     (if (and (null? (filter
43+
                       (lambda (eq)
44+
                         (and (equal? (car eq) first)
45+
                              (not (equal? (cdr eq) second))))
46+
                       equivalences))
47+
              (null? (filter
48+
                       (lambda (eq)
49+
                         (and (not (equal? (car eq) first))
50+
                              (equal? (cdr eq) second)))
51+
                       equivalences)))
52+
         (sat? equivalences)
53+
         #f))))
54+
55+
(define (merge-joins l1 l2)
56+
  (cond
57+
    ((null? l1) l2)
58+
    ((null? l2) l1)
59+
    (else
60+
      (fold
61+
        (lambda (e1 res)
62+
          (append
63+
            (map (lambda (e2)
64+
                   (append e1 e2))
65+
                 l2)
66+
            res))
67+
        '()
68+
        l1))))
69+
70+
(define (to-disjunctions constraints)
71+
  (match constraints
72+
    (('equiv b1 b2) (list (list (cons b1 b2))))
73+
    ('none (list (list)))
74+
    ('bot 'bot)
75+
    (('or e1 e2)
76+
     (let ((e1 (to-disjunctions e1))
77+
           (e2 (to-disjunctions e2)))
78+
       (cond
79+
         ((equal? e2 'bot)
80+
          e1)
81+
         ((equal? e1 'bot)
82+
          e2)
83+
         (else
84+
           (append e1 e2)))))
85+
    (('and e1 e2)
86+
     (let ((e1 (to-disjunctions e1))
87+
           (e2 (to-disjunctions e2)))
88+
       (cond
89+
         ((equal? e1 'bot)
90+
          'bot)
91+
         ((equal? e2 'bot)
92+
          'bot)
93+
         (else
94+
           (merge-joins e1 e2)))))))
95+
96+
(define (generate-triple-constraints t1 t2)
97+
  (pk 'generate t1 t2)
98+
  (match t1
99+
    (($ rdf-triple s1 p1 o1)
100+
     (match t2
101+
       (($ rdf-triple s2 p2 o2)
102+
        (if (and (or (equal? s1 s2) (blank-node? s1))
103+
                 (equal? p1 p2)
104+
                 (or (equal? o1 o2) (blank-node? o1)))
105+
            (list 'and
106+
                  (if (blank-node? s1)
107+
                      (list 'equiv s1 s2)
108+
                      'none)
109+
                  (if (blank-node? o1)
110+
                      (list 'equiv o1 o2)
111+
                      'none))
112+
            #f))))))
113+
114+
(define (generate-constraints t1 g2)
115+
  (match g2
116+
    ('() 'bot)
117+
    ((t2 g2 ...)
118+
     (let ((c (generate-triple-constraints t1 t2)))
119+
       (if c
120+
         (list 'or c (generate-constraints t1 g2))
121+
         (generate-constraints t1 g2))))))
122+
123+
(define (validate-mapping mapping g1 g2)
124+
  (match g1
125+
    ('() #t)
126+
    ((t1 g1 ...)
127+
     (and (not (null? (filter
128+
                        (lambda (t2)
129+
                          (let ((s1 (rdf-triple-subject t1))
130+
                                (s2 (rdf-triple-subject t2))
131+
                                (p1 (rdf-triple-predicate t1))
132+
                                (p2 (rdf-triple-predicate t2))
133+
                                (o1 (rdf-triple-object t1))
134+
                                (o2 (rdf-triple-object t2)))
135+
                            (and
136+
                              (if (blank-node? s1)
137+
                                  (equal? (assoc-ref mapping s1) s2)
138+
                                  (equal? s1 s2))
139+
                              (equal? p1 p2)
140+
                              (if (blank-node? o1)
141+
                                  (equal? (assoc-ref mapping o1) o2)
142+
                                  (equal? o1 o2)))))
143+
                        g2)))
144+
          (validate-mapping mapping g1 g2)))))
145+
146+
(define (entails? g e)
147+
  "Return true if g entails e"
148+
  (or (not (consistent-graph? g))
149+
      (let* ((constraints (fold (lambda (t constraints)
150+
                                  (list 'and (generate-constraints t g) constraints))
151+
                                'none e))
152+
             (disjunctions (to-disjunctions constraints)))
153+
        (if (equal? disjunctions 'bot)
154+
            #f
155+
            (let loop ((disjunctions (filter sat? disjunctions)))
156+
              (match disjunctions
157+
                ('() #f)
158+
                ((mapping disjunctions ...)
159+
                 (if (validate-mapping mapping e g)
160+
                   #t
161+
                   (loop disjunctions)))))))))

test-modules/online.scm

2020
  #:use-module (rnrs bytevectors)
2121
  #:use-module (srfi srfi-1)
2222
  #:use-module (test-modules result)
23+
  #:use-module ((rdf entailment simple) #:prefix simple:)
2324
  #:use-module (rdf rdf)
2425
  #:use-module (srfi srfi-1)
2526
  #:use-module (turtle tordf)

4748
(define (execute-test test)
4849
  (let* ((predicates (test-case-document test))
4950
         (type (car (get-objects predicates "http://www.w3.org/1999/02/22-rdf-syntax-ns#type")))
50-
         (type (substring type (string-length "http://www.w3.org/ns/rdftest#")))
51+
         (type (car (reverse (string-split type #\#))))
5152
         (action (car (get-objects predicates "http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#action"))))
5253
    (turtle->rdf (get-test-doc action) action)))
5354
5455
(define (run-test test)
5556
  (let* ((predicates (test-case-document test))
5657
         (type (car (get-objects predicates "http://www.w3.org/1999/02/22-rdf-syntax-ns#type")))
57-
         (type (substring type (string-length "http://www.w3.org/ns/rdftest#")))
58+
         (type (car (reverse (string-split type #\#))))
5859
         (result
5960
           (catch #t
6061
             (lambda ()

100101
                   #:result 'fail
101102
                   #:reason (format #f "expected ~a but got ~a"
102103
                                    expected result)))))))
104+
      ((member type '("PositiveEntailmentTest" "NegativeEntailmentTest"))
105+
       (let* ((regime (rdf-literal-lexical-form
106+
                        (car
107+
                          (get-objects
108+
                            predicates
109+
                            (string-append
110+
                              "http://www.w3.org/2001/sw/DataAccess/tests/"
111+
                              "test-manifest#entailmentRegime")))))
112+
              (expected
113+
                (car
114+
                  (get-objects
115+
                    predicates
116+
                    (string-append "http://www.w3.org/2001/sw/DataAccess/tests/"
117+
                                   "test-manifest#result"))))
118+
              (expected
119+
                (catch #t
120+
                  (lambda ()
121+
                    (if expected
122+
                        (turtle->rdf (get-test-doc expected) expected)
123+
                        #f))
124+
                  (lambda (key . value)
125+
                    (cons key value)))))
126+
         (match regime
127+
           ("simple"
128+
            (if (if (equal? expected #f)
129+
                    (simple:consistent-graph? result)
130+
                    (simple:entails? result expected))
131+
                (if (equal? type "PositiveEntailmentTest")
132+
                    (update-test-case test #:result 'pass)
133+
                    (update-test-case test
134+
                      #:result 'fail
135+
                      #:reason "Expected negative result, got positive"))
136+
                (if (equal? type "PositiveEntailmentTest")
137+
                    (update-test-case test
138+
                      #:result 'fail
139+
                      #:reason (format #f "Expected positive result, got negative"))
140+
                    (update-test-case test #:result 'pass))))
141+
           (_ (update-test-case test
142+
                #:result 'skip
143+
                #:reason (format #f "Unrecognized entailment regime: ~a"
144+
                                 regime))))))
103145
      (else
104146
        (update-test-case test
105147
          #:result 'skip

157199
          manifest))))
158200
159201
  (define (find-rest node)
160-
    (pk 'rest node)
161202
    (rdf-triple-object
162203
      (car
163204
        (filter

test-modules/testsuite.scm

1717
1818
(define-module (test-modules testsuite)
1919
  #:export (expected-failures
20-
            turtle-test-manifest))
20+
            turtle-test-manifest
21+
            semantics-test-manifest))
2122
2223
(define expected-failures
2324
  '())
2425
2526
(define turtle-test-manifest "http://www.w3.org/2013/TurtleTests/manifest.ttl")
27+
(define semantics-test-manifest
28+
  "https://www.w3.org/2013/rdf-mt-tests/manifest.ttl")

tests/semantics.scm.in unknown status 1

1+
#!@abs_top_srcdir@/pre-inst-env guile
2+
!#
3+
;;;; Copyright (C) 2020 Julien Lepiller <julien@lepiller.eu>
4+
;;;; 
5+
;;;; This library is free software; you can redistribute it and/or
6+
;;;; modify it under the terms of the GNU Lesser General Public
7+
;;;; License as published by the Free Software Foundation; either
8+
;;;; version 3 of the License, or (at your option) any later version.
9+
;;;; 
10+
;;;; This library is distributed in the hope that it will be useful,
11+
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13+
;;;; Lesser General Public License for more details.
14+
;;;; 
15+
;;;; You should have received a copy of the GNU Lesser General Public
16+
;;;; License along with this library; if not, write to the Free Software
17+
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18+
;;;; 
19+
20+
(use-modules (test-modules online))
21+
(use-modules (test-modules result))
22+
(use-modules (test-modules testsuite))
23+
24+
(run-test-suite semantics-test-manifest expected-failures tap-driver)

turtle/tordf.scm

8989
       (not (string-any #\> iri))))
9090
9191
(define (parse-iri iri state)
92-
  (pk 'iri iri)
9392
  (match iri
9493
    (('iri ('prefixed-name ('pname-ln ('pname-ns ns) ('pn-local suffix))))
9594
     `(("iri" . ,(string-append (assoc-ref (parser-state-namespaces state) ns)