Add RDFS entailments

Julien LepillerSat Apr 04 18:49:38+0200 2020

725334b

Add RDFS entailments

Makefile.am

11
include guile.am
22
33
SOURCES= \
4-
		 rdf/entailment/d.scm \
4+
  rdf/entailment/d.scm \
55
  rdf/entailment/rdf.scm \
6+
  rdf/entailment/rdfs.scm \
67
  rdf/entailment/simple.scm \
78
  rdf/rdf.scm \
89
  rdf/xsd.scm \

rdf/entailment/rdf.scm

8080
(define (rdf-container-properties g)
8181
  (let loop ((answer '()) (g g))
8282
    (match g
83-
      (() answer)
83+
      (() (if (null? answer) (list (rdf-iri "_1")) answer))
8484
      ((($ rdf-triple subject predicate object) g ...)
8585
       (let* ((answer (if (and (rdf-container-property? subject)
8686
                               (not (member subject answer)))

rdf/entailment/rdfs.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 rdfs)
19+
  #:use-module (ice-9 match)
20+
  #:use-module (rdf rdf)
21+
  #:use-module ((rdf entailment d) #:prefix d:)
22+
  #:use-module (srfi srfi-1)
23+
  #:export (consistent-graph?
24+
            entails?))
25+
26+
(define (rdf-iri name)
27+
  (string-append "http://www.w3.org/1999/02/22-rdf-syntax-ns#" name))
28+
29+
(define (rdfs-iri name)
30+
  (string-append "http://www.w3.org/2000/01/rdf-schema#" name))
31+
32+
(define (consistent-graph? graph)
33+
  (define (non-overlapping-types? graph)
34+
    (let loop ((graph graph) (type-mappings '()))
35+
      (if (null? graph)
36+
          #t
37+
          (let* ((t (car graph)))
38+
            (if (equal? (rdf-triple-predicate t) (rdf-iri "type"))
39+
                (if (assoc-ref type-mappings (rdf-triple-subject t))
40+
                    #f
41+
                    (loop (cdr graph)
42+
                          (cons
43+
                            (cons (rdf-triple-subject t) (rdf-triple-object t))
44+
                            type-mappings)))
45+
                (loop (cdr graph) type-mappings))))))
46+
  (and (d:consistent-graph? graph)
47+
       (non-overlapping-types? graph)))
48+
49+
;; G entails E if E has an instance (where blank nodes are replaced by literals
50+
;; or IRIs) that is a subgraph of G.
51+
;;
52+
;; We re-use similar procedures to verifying isomorphism of graphs, but this time
53+
;; blank nodes can also map to literals and IRIs.
54+
55+
;; We follow appendix A and use a subgraph comparison (like the simple:entails?
56+
;; procedure) after augmenting the graph with additional true triples.
57+
58+
(define rdfs-axioms
59+
  (list
60+
     (make-rdf-triple (rdf-iri "type") (rdfs-iri "domain") (rdfs-iri "Resource"))
61+
     (make-rdf-triple (rdfs-iri "domain") (rdfs-iri "domain") (rdf-iri "Property"))
62+
     (make-rdf-triple (rdfs-iri "range") (rdfs-iri "domain") (rdf-iri "Property"))
63+
     (make-rdf-triple (rdfs-iri "subPropertyOf") (rdfs-iri "domain")
64+
                      (rdf-iri "Property"))
65+
     (make-rdf-triple (rdfs-iri "subClassOf") (rdfs-iri "domain") (rdfs-iri "Class"))
66+
     (make-rdf-triple (rdf-iri "subject") (rdfs-iri "domain") (rdf-iri "Statement"))
67+
     (make-rdf-triple (rdf-iri "predicate") (rdfs-iri "domain") (rdf-iri "Statement"))
68+
     (make-rdf-triple (rdf-iri "object") (rdfs-iri "domain") (rdf-iri "Statement"))
69+
     (make-rdf-triple (rdfs-iri "member") (rdfs-iri "domain") (rdfs-iri "Resource"))
70+
     (make-rdf-triple (rdf-iri "first") (rdfs-iri "domain") (rdf-iri "List"))
71+
     (make-rdf-triple (rdf-iri "rest") (rdfs-iri "domain") (rdf-iri "List"))
72+
     (make-rdf-triple (rdfs-iri "seeAlso") (rdfs-iri "domain") (rdfs-iri "Resource"))
73+
     (make-rdf-triple (rdfs-iri "isDefinedBy") (rdfs-iri "domain")
74+
                      (rdfs-iri "Resource"))
75+
     (make-rdf-triple (rdfs-iri "comment") (rdfs-iri "domain") (rdfs-iri "Resource"))
76+
     (make-rdf-triple (rdfs-iri "label") (rdfs-iri "domain") (rdfs-iri "Resource"))
77+
     (make-rdf-triple (rdf-iri "value") (rdfs-iri "domain") (rdfs-iri "Resource"))
78+
79+
     (make-rdf-triple (rdf-iri "type") (rdfs-iri "range") (rdfs-iri "Class"))
80+
     (make-rdf-triple (rdfs-iri "domain") (rdfs-iri "range") (rdfs-iri "Class"))
81+
     (make-rdf-triple (rdfs-iri "range") (rdfs-iri "range") (rdfs-iri "Class"))
82+
     (make-rdf-triple (rdfs-iri "subPropertyOf") (rdfs-iri "range")
83+
                      (rdf-iri "Property"))
84+
     (make-rdf-triple (rdfs-iri "subClassOf") (rdfs-iri "range") (rdfs-iri "Class"))
85+
     (make-rdf-triple (rdf-iri "subject") (rdfs-iri "range") (rdfs-iri "Resource"))
86+
     (make-rdf-triple (rdf-iri "predicate") (rdfs-iri "range") (rdfs-iri "Resource"))
87+
     (make-rdf-triple (rdf-iri "object") (rdfs-iri "range") (rdfs-iri "Resource"))
88+
     (make-rdf-triple (rdfs-iri "member") (rdfs-iri "range") (rdfs-iri "Resource"))
89+
     (make-rdf-triple (rdf-iri "first") (rdfs-iri "range") (rdfs-iri "Resource"))
90+
     (make-rdf-triple (rdf-iri "rest") (rdfs-iri "range") (rdf-iri "List"))
91+
     (make-rdf-triple (rdfs-iri "seeAlso") (rdfs-iri "range") (rdfs-iri "Resource"))
92+
     (make-rdf-triple (rdfs-iri "isDefinedBy") (rdfs-iri "range")
93+
                      (rdfs-iri "Resource"))
94+
     (make-rdf-triple (rdfs-iri "comment") (rdfs-iri "range") (rdfs-iri "Literal"))
95+
     (make-rdf-triple (rdfs-iri "label") (rdfs-iri "range") (rdfs-iri "Literal"))
96+
     (make-rdf-triple (rdf-iri "value") (rdfs-iri "range") (rdfs-iri "Resource"))
97+
98+
     (make-rdf-triple (rdf-iri "Alt") (rdfs-iri "subClassOf") (rdfs-iri "Container"))
99+
     (make-rdf-triple (rdf-iri "Bag") (rdfs-iri "subClassOf") (rdfs-iri "Container"))
100+
     (make-rdf-triple (rdf-iri "Seq") (rdfs-iri "subClassOf") (rdfs-iri "Container"))
101+
     (make-rdf-triple (rdfs-iri "ContainerMembershipProperty")
102+
                      (rdfs-iri "subClassOf") (rdf-iri "Property"))
103+
104+
     (make-rdf-triple (rdfs-iri "isDefinedBy") (rdfs-iri "subPropertyOf")
105+
                      (rdfs-iri "seeAlso"))
106+
107+
     (make-rdf-triple (rdfs-iri "Datatype") (rdfs-iri "subClassOf")
108+
                      (rdfs-iri "Class"))))
109+
110+
(define (rdfs-axioms-container container)
111+
  (list
112+
    (make-rdf-triple 
113+
      container (rdf-iri "type") (rdfs-iri "ContainerMembershipProperty"))
114+
    (make-rdf-triple
115+
      container (rdfs-iri "domain") (rdfs-iri "Resource"))
116+
    (make-rdf-triple
117+
      container (rdfs-iri "range") (rdfs-iri "Resource"))))
118+
119+
(define (rdf-container-property? p)
120+
  (define rdf-container-property-base (rdf-iri "_"))
121+
  (and (string? p)
122+
       (> (string-length p) (string-length rdf-container-property-base))
123+
       (equal? (substring p 0 (string-length rdf-container-property-base))
124+
               rdf-container-property-base)
125+
       (string->number
126+
         (substring p (string-length rdf-container-property-base)))))
127+
128+
(define (rdf-container-properties g)
129+
  (let loop ((answer '()) (g g))
130+
    (match g
131+
      (() (if (null? answer) (list (rdf-iri "_1")) answer))
132+
      ((($ rdf-triple subject predicate object) g ...)
133+
       (let* ((answer (if (and (rdf-container-property? subject)
134+
                               (not (member subject answer)))
135+
                          (cons subject answer)
136+
                          answer))
137+
              (answer (if (and (rdf-container-property? predicate)
138+
                               (not (member predicate answer)))
139+
                          (cons predicate answer)
140+
                          answer))
141+
              (answer (if (and (rdf-container-property? object)
142+
                               (not (member object answer)))
143+
                          (cons object answer)
144+
                          answer)))
145+
         (loop answer g))))))
146+
147+
(define (grdf1 graph)
148+
  "Implements Grdf1 entailment."
149+
  (filter
150+
    (lambda (a) a)
151+
    (map
152+
      (match-lambda
153+
        (($ rdf-triple subject predicate object)
154+
         (if (and (rdf-literal? object)
155+
                  (rdf-datatype? (rdf-literal-type object)))
156+
             (make-rdf-triple object (rdf-iri "type")
157+
                              (rdf-literal-type object))
158+
             #f)))
159+
      graph)))
160+
161+
(define (rdf2 graph)
162+
  "Implements rdf2 entailment."
163+
  (map
164+
    (match-lambda
165+
      (($ rdf-triple subject predicate object)
166+
       (make-rdf-triple predicate (rdf-iri "type")
167+
                        (rdf-iri "Property"))))
168+
    graph))
169+
170+
(define (rdfs1 graph)
171+
  "Implements rdfs1 entailment."
172+
  (filter
173+
    (lambda (a) a)
174+
    (append-map
175+
      (match-lambda
176+
        (($ rdf-triple subject predicate object)
177+
         (list
178+
           (if (rdf-datatype? subject)
179+
               (make-rdf-triple subject (rdf-iri "type") (rdfs-iri "Datatype"))
180+
               #f)
181+
           (if (rdf-datatype? predicate)
182+
               (make-rdf-triple predicate (rdf-iri "type") (rdfs-iri "Datatype"))
183+
               #f)
184+
           (if (rdf-datatype? object)
185+
               (make-rdf-triple object (rdf-iri "type") (rdfs-iri "Datatype"))
186+
               #f))))
187+
      graph)))
188+
189+
(define (rdfs2 graph)
190+
  (let ((domains
191+
         (filter
192+
           (match-lambda
193+
             (($ rdf-triple _ p _)
194+
              (or (and (string? p) (equal? p (rdfs-iri "domain")))
195+
                  (and (rdf-datatype? p)
196+
                       (member (rdfs-iri "domain") (rdf-datatype-iris p))))))
197+
           graph)))
198+
    (append-map
199+
      (lambda (domain)
200+
        (map
201+
          (match-lambda
202+
            (($ rdf-triple subject _ _)
203+
             (make-rdf-triple subject (rdf-iri "type") (rdf-triple-object domain))))
204+
          (filter
205+
            (match-lambda
206+
              (($ rdf-triple _ p _)
207+
               (equal? p (rdf-triple-subject domain))))
208+
            graph)))
209+
      domains)))
210+
211+
(define (rdfs3 graph)
212+
  (let ((ranges
213+
         (filter
214+
           (match-lambda
215+
             (($ rdf-triple _ p _)
216+
              (or (and (string? p) (equal? p (rdfs-iri "range")))
217+
                  (and (rdf-datatype? p)
218+
                       (member (rdfs-iri "range") (rdf-datatype-iris p))))))
219+
           graph)))
220+
    (append-map
221+
      (lambda (range)
222+
        (map
223+
          (match-lambda
224+
            (($ rdf-triple _ _ object)
225+
             (make-rdf-triple object (rdf-iri "type") (rdf-triple-object range))))
226+
          (filter
227+
            (match-lambda
228+
              (($ rdf-triple _ p _)
229+
               (equal? p (rdf-triple-subject range))))
230+
            graph)))
231+
      ranges)))
232+
233+
(define (rdfs4a graph)
234+
  (map
235+
    (match-lambda
236+
      (($ rdf-triple subject predicate object)
237+
       (make-rdf-triple subject (rdf-iri "type")
238+
                        (rdf-iri "Resource"))))
239+
    graph))
240+
241+
(define (rdfs4b graph)
242+
  (map
243+
    (match-lambda
244+
      (($ rdf-triple subject predicate object)
245+
       (make-rdf-triple object (rdf-iri "type")
246+
                        (rdf-iri "Resource"))))
247+
    graph))
248+
249+
(define (rdfs5 graph)
250+
  (let ((subprops
251+
         (filter
252+
           (match-lambda
253+
             (($ rdf-triple _ p _)
254+
              (or (and (string? p) (equal? p (rdfs-iri "subPropertyOf")))
255+
                  (and (rdf-datatype? p)
256+
                       (member (rdfs-iri "subPropertyOf") (rdf-datatype-iris p))))))
257+
           graph)))
258+
    (append-map
259+
      (lambda (prop)
260+
        (map
261+
          (match-lambda
262+
            (($ rdf-triple _ _ o)
263+
             (make-rdf-triple (rdf-triple-subject prop)
264+
                              (rdfs-iri "subPropertyOf") o)))
265+
          (filter
266+
            (match-lambda
267+
              (($ rdf-triple s _ _)
268+
               (equal? s (rdf-triple-object prop))))
269+
            subprops)))
270+
      subprops)))
271+
272+
(define (rdfs6 graph)
273+
  "Implements rdfs6 entailment."
274+
  (filter
275+
    (lambda (a) a)
276+
    (map
277+
      (match-lambda
278+
        (($ rdf-triple subject predicate object)
279+
         (if (and (or (equal? predicate (rdf-iri "type"))
280+
                      (and
281+
                        (rdf-datatype? predicate)
282+
                        (member (rdf-iri "type") (rdf-datatype-iris predicate))))
283+
                  (or (equal? object (rdfs-iri "Property"))
284+
                      (and
285+
                        (rdf-datatype? object)
286+
                        (member (rdf-iri "Property") (rdf-datatype-iris object)))))
287+
             (make-rdf-triple subject (rdf-iri "subPropertyOf") subject)
288+
             #f)))
289+
      graph)))
290+
291+
(define (rdfs7 graph)
292+
  (let ((subprops
293+
         (filter
294+
           (match-lambda
295+
             (($ rdf-triple _ p _)
296+
              (or (and (string? p) (equal? p (rdfs-iri "subPropertyOf")))
297+
                  (and (rdf-datatype? p)
298+
                       (member (rdfs-iri "subPropertyOf") (rdf-datatype-iris p))))))
299+
           graph)))
300+
    (append-map
301+
      (lambda (prop)
302+
        (map
303+
          (match-lambda
304+
            (($ rdf-triple subject _ object)
305+
             (make-rdf-triple object (rdf-triple-subject prop) subject)))
306+
          (filter
307+
            (match-lambda
308+
              (($ rdf-triple _ p _)
309+
               (equal? p (rdf-triple-subject prop))))
310+
            graph)))
311+
      subprops)))
312+
313+
(define (rdfs8 graph)
314+
  "Implements rdfs8 entailment."
315+
  (filter
316+
    (lambda (a) a)
317+
    (map
318+
      (match-lambda
319+
        (($ rdf-triple subject predicate object)
320+
         (if (and (or (equal? predicate (rdf-iri "type"))
321+
                      (and
322+
                        (rdf-datatype? predicate)
323+
                        (member (rdf-iri "type") (rdf-datatype-iris predicate))))
324+
                  (or (equal? object (rdfs-iri "Class"))
325+
                      (and
326+
                        (rdf-datatype? object)
327+
                        (member (rdf-iri "Class") (rdf-datatype-iris object)))))
328+
             (make-rdf-triple subject (rdfs-iri "subClassOf") (rdfs-iri "Resource"))
329+
             #f)))
330+
      graph)))
331+
332+
(define (rdfs9 graph)
333+
  (let ((subclasses
334+
         (filter
335+
           (match-lambda
336+
             (($ rdf-triple _ p _)
337+
              (or (and (string? p) (equal? p (rdfs-iri "subClassOf")))
338+
                  (and (rdf-datatype? p)
339+
                       (member (rdfs-iri "subClassOf") (rdf-datatype-iris p))))))
340+
           graph)))
341+
    (append-map
342+
      (lambda (class)
343+
        (map
344+
          (match-lambda
345+
            (($ rdf-triple subject _ object)
346+
             (make-rdf-triple subject (rdf-iri "type") (rdf-triple-subject class))))
347+
          (filter
348+
            (match-lambda
349+
              (($ rdf-triple _ p o)
350+
               (and (equal? o (rdf-triple-object class))
351+
                    (or (equal? p (rdf-iri "type"))
352+
                        (and
353+
                          (rdf-datatype? p)
354+
                          (member (rdf-iri "type") (rdf-datatype-iris p)))))))
355+
            graph)))
356+
      subclasses)))
357+
358+
(define (rdfs10 graph)
359+
  "Implements rdfs10 entailment."
360+
  (filter
361+
    (lambda (a) a)
362+
    (map
363+
      (match-lambda
364+
        (($ rdf-triple subject predicate object)
365+
         (if (and (or (equal? predicate (rdf-iri "type"))
366+
                      (and
367+
                        (rdf-datatype? predicate)
368+
                        (member (rdf-iri "type") (rdf-datatype-iris predicate))))
369+
                  (or (equal? object (rdfs-iri "Class"))
370+
                      (and
371+
                        (rdf-datatype? object)
372+
                        (member (rdf-iri "Class") (rdf-datatype-iris object)))))
373+
             (make-rdf-triple subject (rdfs-iri "subClassOf") subject)
374+
             #f)))
375+
      graph)))
376+
377+
(define (rdfs11 graph)
378+
  (let ((subclasses
379+
         (filter
380+
           (match-lambda
381+
             (($ rdf-triple _ p _)
382+
              (or (and (string? p) (equal? p (rdfs-iri "subClassOf")))
383+
                  (and (rdf-datatype? p)
384+
                       (member (rdfs-iri "subClassOf") (rdf-datatype-iris p))))))
385+
           graph)))
386+
    (append-map
387+
      (lambda (class)
388+
        (map
389+
          (match-lambda
390+
            (($ rdf-triple _ _ o)
391+
             (make-rdf-triple (rdf-triple-subject class)
392+
                              (rdfs-iri "subClassOf") o)))
393+
          (filter
394+
            (match-lambda
395+
              (($ rdf-triple s _ _)
396+
               (equal? s (rdf-triple-object class))))
397+
            subclasses)))
398+
      subclasses)))
399+
400+
(define (rdfs12 graph)
401+
  "Implements rdfs12 entailment."
402+
  (filter
403+
    (lambda (a) a)
404+
    (map
405+
      (match-lambda
406+
        (($ rdf-triple subject predicate object)
407+
         (if (and (or (equal? predicate (rdf-iri "type"))
408+
                      (and
409+
                        (rdf-datatype? predicate)
410+
                        (member (rdf-iri "type") (rdf-datatype-iris predicate))))
411+
                  (or (equal? object (rdfs-iri "ContainerMembershipProperty"))
412+
                      (and
413+
                        (rdf-datatype? object)
414+
                        (member (rdf-iri "ContainerMembershipProperty")
415+
                                (rdf-datatype-iris object)))))
416+
             (make-rdf-triple subject (rdfs-iri "subPropertyOf")
417+
                              (rdfs-iri "member"))
418+
             #f)))
419+
      graph)))
420+
421+
(define (rdfs13 graph)
422+
  "Implements rdfs13 entailment."
423+
  (filter
424+
    (lambda (a) a)
425+
    (map
426+
      (match-lambda
427+
        (($ rdf-triple subject predicate object)
428+
         (if (and (or (equal? predicate (rdf-iri "type"))
429+
                      (and
430+
                        (rdf-datatype? predicate)
431+
                        (member (rdf-iri "type") (rdf-datatype-iris predicate))))
432+
                  (or (equal? object (rdfs-iri "Datatype"))
433+
                      (and
434+
                        (rdf-datatype? object)
435+
                        (member (rdf-iri "Datatype") (rdf-datatype-iris object)))))
436+
             (make-rdf-triple subject (rdfs-iri "subClass") (rdfs-iri "Literal"))
437+
             #f)))
438+
      graph)))
439+
440+
(define rdfs-entailments
441+
  (list grdf1 rdf2 rdfs1 rdfs2 rdfs3 rdfs4a rdfs4b rdfs5 rdfs6 rdfs7 rdfs8
442+
        rdfs9 rdfs10 rdfs11 rdfs12 rdfs13))
443+
444+
(define (augment g d entailments)
445+
  (let* ((g (append rdfs-axioms g))
446+
         (g (append
447+
              (append-map rdfs-axioms-container (rdf-container-properties g))
448+
              g)))
449+
    (let loop ((g g) (to-entail entailments) (augmented? #f))
450+
      (if (null? to-entail)
451+
          (if augmented?
452+
              (loop g entailments #f)
453+
              g)
454+
          (let loop2 ((g g) (augmented-entail? #f))
455+
            (pk 'looping-until (car to-entail) 'is-exhausted)
456+
            (let* ((new-triples ((car to-entail) g))
457+
                   (new-triples (recognize new-triples d)))
458+
              (let loop3 ((g g) (new-triples new-triples) (augmented-here? #f))
459+
                (match new-triples
460+
                  (() (if augmented-here?
461+
                          (loop2 g #t)
462+
                          (loop g (cdr to-entail) augmented-entail?)))
463+
                  ((t new-triples ...)
464+
                   (if (member t g)
465+
                       (loop3 g new-triples augmented-here?)
466+
                       (loop3 (cons t g) new-triples #t)))))))))))
467+
468+
(define (entails? g e d)
469+
  "Return true if g entails e recognizing d"
470+
  (let* ((g (recognize g d))
471+
         (g (augment g d rdfs-entailments)))
472+
    (pk 'augment-done)
473+
    (or (not (consistent-graph? g))
474+
        (d:entails? g e))))

rdf/xsd.scm

7878
    string->number
7979
    number->string))
8080
81+
(define-public int
82+
  (make-xsd-datatype
83+
    "int"
84+
    "Limited-range integer numbre (32 bits)"
85+
    (lambda (lexical)
86+
      (and (integer? (string->number lexical))
87+
           (>= (string->number lexical) 2147483648)
88+
           (<= (string->number lexical) 2147483647)))
89+
    (lambda (value)
90+
      (and (integer? value)
91+
           (>= value 2147483648)
92+
           (<= value 2147483647)))
93+
    string->number
94+
    number->string))
95+
8196
(define datatypes
82-
  (list string boolean decimal integer))
97+
  (list string boolean decimal integer int))

test-modules/online.scm

2121
  #:use-module (srfi srfi-1)
2222
  #:use-module (test-modules result)
2323
  #:use-module ((rdf entailment rdf) #:prefix rdf:)
24+
  #:use-module ((rdf entailment rdfs) #:prefix rdfs:)
2425
  #:use-module ((rdf entailment simple) #:prefix simple:)
2526
  #:use-module (rdf rdf)
2627
  #:use-module ((rdf xsd) #:prefix xsd:)

209210
                      #:result 'fail
210211
                      #:reason (format #f "Expected positive result, got negative"))
211212
                    (update-test-case test #:result 'pass))))
213+
           ("RDFS"
214+
            (if (if (equal? expected #f)
215+
                    (rdfs:consistent-graph? result)
216+
                    (rdfs:entails? result expected recognized))
217+
                (if (equal? type "PositiveEntailmentTest")
218+
                    (update-test-case test #:result 'pass)
219+
                    (update-test-case test
220+
                      #:result 'fail
221+
                      #:reason "Expected negative result, got positive"))
222+
                (if (equal? type "PositiveEntailmentTest")
223+
                    (update-test-case test
224+
                      #:result 'fail
225+
                      #:reason (format #f "Expected positive result, got negative"))
226+
                    (update-test-case test #:result 'pass))))
212227
           (_ (update-test-case test
213228
                #:result 'skip
214229
                #:reason (format #f "Unrecognized entailment regime: ~a"