(register-namespace "mung:" "http://purl.org/obo/owl/") (define-ontology po (:base "http://purl.org/obo/owl/Y" :about !mung:) (object-property !mung:obo#part_of :transitive) (class !mung:X#X_0 :partial) (class !mung:X#X_1 :partial !mung:X#X_0) (class !mung:X#X_2 :partial !mung:X#X_1) (class !mung:X#X_3 :partial !mung:X#X_2) (class !mung:X#X_4 :partial !mung:X#X_3) (class !mung:Y#Y_1 :partial !mung:X#X_0) (class !mung:Y#Y_2 :partial !mung:Y#Y_1) (class !mung:Y#Y_2 :partial (restriction !mung:obo#part_of (some-values-from !mung:X#X_2))) (class !mung:Y#Y_3 :partial !mung:Y#Y_2) (class !mung:Y#Y_3 :partial (restriction !mung:obo#part_of (some-values-from !mung:X#X_3))) (class !mung:Y#Y_4 :partial !mung:Y#Y_3) (class !mung:Z#Z_1 :partial !mung:X#X_0) (class !mung:Z#Z_2 :partial !mung:Z#Z_1) (class !mung:Z#Z_2 :partial (restriction !mung:obo#part_of (some-values-from !mung:Y#Y_2))) (class !mung:Z#Z_3 :partial !mung:Z#Z_2) (class !mung:Z#Z_3 :partial (restriction !mung:obo#part_of (some-values-from !mung:Y#Y_3))) (class !mung:Z#Z_4 :partial !mung:Z#Z_3) ) ;; slight variant - means the same thing, but uses a slightly different expression. (define-ontology po2 (:base "http://purl.org/obo/owl/Y" :about !mung:) (object-property !mung:obo#part_of :transitive) (class !mung:X#X_0 :partial) (class !mung:X#X_1 :partial !mung:X#X_0) (class !mung:X#X_2 :partial !mung:X#X_1) (class !mung:X#X_3 :partial !mung:X#X_2) (class !mung:X#X_4 :partial !mung:X#X_3) (class !mung:Y#Y_1 :partial !mung:X#X_0) (class !mung:Y#Y_2 :partial !mung:Y#Y_1) (class !mung:Y#Y_2 :partial (restriction !mung:obo#part_of (some-values-from !mung:X#X_2))) (class !mung:Y#Y_3 :partial !mung:Y#Y_2) (class !mung:Y#Y_3 :partial (restriction !mung:obo#part_of (some-values-from !mung:X#X_3))) (class !mung:Y#Y_4 :partial !mung:Y#Y_3) (class !mung:Z#Z_1 :partial !mung:X#X_0) (class !mung:Z#Z_2 :partial !mung:Z#Z_1) (class !mung:Z#Z_2 :partial (restriction !mung:obo#part_of (some-values-from !mung:Y#Y_2))) ;; Note that we use intersection here! (class !mung:Z#Z_3 :partial (intersection-of !mung:Z#Z_2 (restriction !mung:obo#part_of (some-values-from !mung:Y#Y_3)))) (class !mung:Z#Z_4 :partial !mung:Z#Z_3) ) (defun po-compare-dig-sparql (&optional (po po)) (let ((sparql (sparql `(:select (?wholet ?part ) (:distinct t) (?whole !rdfs:subClassOf ?wholet) (?part !rdfs:subClassOf ?partt) (?partt !rdfs:subClassOf :_restriction) (:_restriction !owl:onProperty !mung:obo#part_of) (:_restriction !owl:someValuesFrom ?whole) (:filter (and (not (equal ?part !owl:Nothing)) (not (equal ?wholet !owl:Thing)) (not (equal ?whole !owl:Nothing)) (not (isblank ?wholet)))) ) :kb po :use-reasoner :jena :trace "The sparql query")) (dig (loop for whole in (descendants !owl:Thing po) append (loop for part in (descendants (restriction !mung:obo#part_of (some-values-from whole) ) po) collect (list whole part))))) (format t "In sparql, but not dig: ~%~{~a~%~}" (set-difference sparql dig :test 'equalp)) (format t "In dig, but not sparql: ~%~{~a~%~}" (set-difference dig sparql :test 'equalp)) (format t "In both ~%~{~a~%~}" (intersection dig sparql :test 'equalp)))) ;; note that the sparql is very sensitive to exact expression. If you do ;; (po-compare-dig-sparql po2) then you will see that dig gets the same answer, but ;; sparql loses a couple. See below for the two runs. ;; (po-compare-dig-sparql) ;; Query: The sparql query ;; PREFIX owl: ;; PREFIX rdfs: ;; SELECT DISTINCT ?wholet ?part ;; WHERE { ;; ?whole rdfs:subClassOf ?wholet . ;; ?part rdfs:subClassOf ?partt . ;; ?partt rdfs:subClassOf _:RESTRICTION . ;; _:RESTRICTION owl:onProperty . ;; _:RESTRICTION owl:someValuesFrom ?whole . ;; FILTER ((!((?part = ))) && (!((?wholet = ))) && (!((?whole = ))) && (!(isblank(?wholet))))} ;; In sparql, but not dig: ;; In dig, but not sparql: ;; (!mung:X#X_3 !mung:Z#Z_4) ;; (!mung:X#X_3 !mung:Z#Z_3) ;; (!mung:X#X_1 !mung:Z#Z_4) ;; (!mung:X#X_1 !mung:Z#Z_3) ;; (!mung:X#X_1 !mung:Z#Z_2) ;; (!mung:X#X_2 !mung:Z#Z_4) ;; (!mung:X#X_2 !mung:Z#Z_3) ;; (!mung:X#X_2 !mung:Z#Z_2) ;; In both ;; (!mung:X#X_0 !mung:Z#Z_4) ;; (!mung:X#X_0 !mung:Z#Z_3) ;; (!mung:X#X_0 !mung:Y#Y_4) ;; (!mung:X#X_0 !mung:Y#Y_2) ;; (!mung:X#X_0 !mung:Z#Z_2) ;; (!mung:X#X_0 !mung:Y#Y_3) ;; (!mung:Y#Y_3 !mung:Z#Z_4) ;; (!mung:Y#Y_3 !mung:Z#Z_3) ;; (!mung:X#X_3 !mung:Y#Y_4) ;; (!mung:X#X_3 !mung:Y#Y_3) ;; (!mung:X#X_1 !mung:Y#Y_4) ;; (!mung:X#X_1 !mung:Y#Y_2) ;; (!mung:X#X_1 !mung:Y#Y_3) ;; (!mung:X#X_2 !mung:Y#Y_4) ;; (!mung:X#X_2 !mung:Y#Y_2) ;; (!mung:X#X_2 !mung:Y#Y_3) ;; (!mung:Y#Y_1 !mung:Z#Z_4) ;; (!mung:Y#Y_1 !mung:Z#Z_3) ;; (!mung:Y#Y_1 !mung:Z#Z_2) ;; (!mung:Y#Y_2 !mung:Z#Z_4) ;; (!mung:Y#Y_2 !mung:Z#Z_3) ;; (!mung:Y#Y_2 !mung:Z#Z_2) ;; **************************************************************** ;; (po-compare-dig-sparql p02) ;; same sparql query ;; In sparql, but not dig: ;; In dig, but not sparql: ;; (!mung:Y#Y_3 !mung:Z#Z_4) ;; (!mung:Y#Y_3 !mung:Z#Z_3) ;; (!mung:X#X_3 !mung:Z#Z_4) ;; (!mung:X#X_3 !mung:Z#Z_3) ;; (!mung:X#X_1 !mung:Z#Z_4) ;; (!mung:X#X_1 !mung:Z#Z_3) ;; (!mung:X#X_1 !mung:Z#Z_2) ;; (!mung:X#X_2 !mung:Z#Z_4) ;; (!mung:X#X_2 !mung:Z#Z_3) ;; (!mung:X#X_2 !mung:Z#Z_2) ;; In both ;; (!mung:X#X_0 !mung:Z#Z_4) ;; (!mung:X#X_0 !mung:Z#Z_3) ;; (!mung:X#X_0 !mung:Y#Y_4) ;; (!mung:X#X_0 !mung:Y#Y_2) ;; (!mung:X#X_0 !mung:Z#Z_2) ;; (!mung:X#X_0 !mung:Y#Y_3) ;; (!mung:X#X_3 !mung:Y#Y_4) ;; (!mung:X#X_3 !mung:Y#Y_3) ;; (!mung:X#X_1 !mung:Y#Y_4) ;; (!mung:X#X_1 !mung:Y#Y_2) ;; (!mung:X#X_1 !mung:Y#Y_3) ;; (!mung:X#X_2 !mung:Y#Y_4) ;; (!mung:X#X_2 !mung:Y#Y_2) ;; (!mung:X#X_2 !mung:Y#Y_3) ;; (!mung:Y#Y_1 !mung:Z#Z_4) ;; (!mung:Y#Y_1 !mung:Z#Z_3) ;; (!mung:Y#Y_1 !mung:Z#Z_2) ;; (!mung:Y#Y_2 !mung:Z#Z_4) ;; (!mung:Y#Y_2 !mung:Z#Z_3) ;; (!mung:Y#Y_2 !mung:Z#Z_2)