")
(defvar @@ nil)
(defun make-treeview (file name kb &optional (depth *treeview-depth*))
(maybe-hook-@@)
(#"setDismissDelay" (#"sharedInstance" 'tooltipmanager) 300000) ;; make the tooltips last longer
(#"setInitialDelay" (#"sharedInstance" 'tooltipmanager) 10)
(let ((jpanel (#"demo" 'prefuse.demos.TreeView file "name"))
(jframe (new 'JFrame (string-capitalize name))))
(setq panel jpanel)
(let ((visualization (#"getVisualization" (#"getComponent" jpanel 0) )))
(setq vis visualization)
(#"addControlListener" (#"getComponent" jpanel 0) (make-tooltip-control kb 'tree-tooltip))
(#"setDistance" (#"get" (#"getAction" visualization "filter") 0) depth) ;; 3 deep versus 2
(#"setDefaultFont" (#"get" (#"getAction" visualization "filter") 1) (#"getFont" 'FontLib "Tahoma" 12 12) ) ;smaller font
(#"run" visualization "filter")
(#"run" visualization "treeLayout")
;(print (#"get" (#"getItem" (#"getVisualGroup" it "tree.nodes") 1) "name"))
; (#"getDOI" (#"getItem" (#"getVisualGroup" it "tree.nodes") 1))`
;; (let ((bounds (#"getBounds" visualization (get-java-field 'Visualization "ALL_ITEMS"))))
;; (#"expand" 'GraphicsLib bounds (#"getScale" (#"getComponent" jpanel 0)))
;; (#"fitViewToBounds" 'DisplayLib (#"getComponent" jpanel 0) bounds (make-immediate-object 0 :long)))
(#"setContentPane" jframe jpanel)
(#"pack" jframe)
(#"setVisible" jframe t)
#+darwin (run-shell-command "osascript -e 'tell application \"java\"' -e \"activate\" -e \"end tell\"")
))
kb)
(defmethod show-classtree ((url string) &rest stuff)
(apply 'show-classtree (load-kb-jena url) stuff))
(defmethod show-classtree ((symbol symbol) &rest stuff)
(apply 'show-classtree (load-kb-jena symbol) (append (standard-ontology-classtree-options symbol) stuff )))
(defmethod show-classtree ((o owl-ontology) &rest stuff) ;&key root include-instances merge-same dont-show (use-labels t))
(make-treeview (apply 'write-classtree-treeml (kb o) stuff) (string (name o)) (kb o)
(or (getf stuff :depth) *treeview-depth*)))
;:root root :dont-show dont-show :include-instances include-instances :merge-same merge-same :use-labels use-labels) (string (name o)) (kb o)))
(defmethod show-classtree ((kb kb) &rest stuff)
(make-treeview (apply 'write-classtree-treeml kb stuff) (string(kb-loaded-from kb)) kb (or (getf stuff :depth) *treeview-depth*)))
(defmethod show-propertytree ((symbol symbol) &rest stuff)
(apply 'show-propertytree (load-kb-jena symbol) stuff))
(defmethod show-propertytree ((url string) &key root include-instances merge-same (include-annotation-properties t) (use-labels t) (dont-show t))
(show-propertytree (load-kb-jena url) :root root :include-instances include-instances :merge-same merge-same
:include-annotation-properties include-annotation-properties))
(defmethod show-propertytree ((o owl-ontology) &key root include-instances merge-same (include-annotation-properties t) (use-labels t) (dont-show nil))
(make-treeview (write-propertytree-treeml (kb o) :root root :include-instances include-instances :merge-same merge-same
:include-annotation-properties include-annotation-properties)
(string (name o)) (kb o)))
(defmethod show-propertytree ((kb kb) &key root include-instances merge-same (include-annotation-properties t) (use-labels t) (dont-show nil))
(make-treeview (write-propertytree-treeml kb :root root :include-instances include-instances :merge-same merge-same
:include-annotation-properties include-annotation-properties :dont-show dont-show)
(string(kb-loaded-from kb)) kb))
;; http://sourceforge.net/forum/message.php?msg_id=3339297
;; RE: directed layered (hierarchical) layout
;; 2005-09-14 15:10
;; There's no existing layout that will do this exactly. Some options include hacking VerticalTreeLayout to create a new layout that does what you want, or playing with the ForceDirectedLayout and adding a downstream Action instance that forces nodes to stay within horizontal "bands" depending on the depth level of the node.
;; Hope that helps,
;; -jeff
(defun make-tooltip-control (kb tooltip-function &optional
(tooltip-ok? (lambda(item) (#"canGetString" item "entity")))
(tooltip-arg (lambda(item) (#"getString" item "entity"))))
(let ((fields (jnew-array "java.lang.String" 1)))
(jarray-set fields "tooltip" 0)
(let ((wrapped (new 'tooltipcontrol fields))
(interfaces (jclass-all-interfaces 'tooltipcontrol)))
(jdelegating-interface-implementation
(car interfaces)
wrapped
"itemEntered"
(let ((kb kb))
(lambda (item event &aux display)
(unless (#"isShiftDown" event)
(handler-case
(multiple-value-bind (value errorp)
(ignore-errors
(setq display (#"getSource" event))
(when (funcall tooltip-ok? item)
(funcall tooltip-function kb (funcall tooltip-arg item))))
(and display
(if (and value (not errorp))
(#"setToolTipText" display value)
(if errorp
(#"setToolTipText" display (format nil "Error creating tooltip for ~a" (#"getSourceTuple" item)))))))
(condition () nil)
))))
"itemExited"
(lambda (item event &aux display)
(handler-case
(multiple-value-bind (value errorp)
(ignore-errors
(setq display (#"getSource" event)))
(and display
(if (not errorp)
(unless (#"isShiftDown" event)
(#"setToolTipText" display (make-immediate-object nil :ref)))
)))
(condition () nil)
))
))))
(defun rdfs-comment (entity kb)
(let ((uri (make-uri entity)))
(format nil "~{~a~^; ~}"
(or
(or
(and *classtree-preferred-language*
(sparql `(:select (?comment) () (,uri !oboinowl:hasDefinition ?def) (?def !rdfs:label ?comment) (:filter (and (equal (lang ?comment) ,*classtree-preferred-language*) (not (equal ?comment ""))))) :use-reasoner *annotation-query-reasoner* :kb kb :flatten t))
(sparql `(:select (?comment) () (,uri !oboinowl:hasDefinition ?def) (?def !rdfs:label ?comment) (:filter (not (equal ?comment "")))) :use-reasoner *annotation-query-reasoner* :kb kb :flatten t)
)
(or
(and *classtree-preferred-language*
(sparql `(:select (?comment) () (,uri !rdfs:comment ?comment) (:filter (and (equal (lang ?comment) ,*classtree-preferred-language*)
(not (equal ?comment "")))))
:kb kb :use-reasoner *annotation-query-reasoner* :flatten t))
(sparql `(:select (?comment) () (,uri !rdfs:comment ?comment) (:filter (not (equal ?comment "")))) :kb kb :use-reasoner *annotation-query-reasoner* :flatten t))
(or
(and *classtree-preferred-language*
(sparql `(:select (?comment) () (:union ((,uri !obi:OBI_0000291 ?comment))
((,uri !obi:IAO_0000115 ?comment)))
(:filter (and (equal (lang ?comment) ,*classtree-preferred-language*)
(not (equal ?comment "")))))
:kb kb :use-reasoner *annotation-query-reasoner* :flatten t))
(sparql `(:select (?comment) () (:union ((,uri !obi:OBI_0000291 ?comment))
((,uri !obi:IAO_0000115 ?comment))) (:filter (not (equal ?comment "")))) :kb kb :use-reasoner *annotation-query-reasoner* :flatten t))
))))
;; (defun rdfs-comment (entity kb)
;; (let ((uri (make-uri entity)))
;; (or
;; (caar (sparql `(:select (?comment) ()
;; (:union
;; ((,uri !rdfs:comment ?comment))
;; ((,uri !oboinowl:hasDefinition ?def) (?def !rdfs:label ?comment))))
;; :use-reasoner :jena :kb kb)))))
(defun clean-label (label &optional (ignore-if-xml nil))
(let ((cleaned
(and label
(#"replaceAll"
(#"replaceAll"
(#"replaceAll" (#"replaceFirst" (#0"replaceFirst" label "^\\s+" "") "\\s+$" "") "<" "<")
">" ">") "\"" """))))
(when cleaned
(if (and (> (length cleaned) 35) (char= (char cleaned 0) #\&))
(if ignore-if-xml
nil
cleaned)
(if (equal cleaned "") nil cleaned)
))))
(defun rdfs-label (entity kb)
(let ((uri (make-uri entity)))
(remove nil
(mapcar 'clean-label
(append
(or
(and *classtree-preferred-language*
(mapcar 'car (sparql `(:select (?label) (:distinct t) (,uri !rdfs:label ?label)
(:filter (equal (lang ?label) ,*classtree-preferred-language*))) :kb kb :use-reasoner *annotation-query-reasoner*)))
(mapcar 'car (sparql `(:select (?label) (:distinct t) (,uri !rdfs:label ?label)) :kb kb :use-reasoner *annotation-query-reasoner*)))
(or
(and *classtree-preferred-language*
(mapcar 'car (sparql `(:select (?label) (:distinct t) (,uri !foaf:name ?label) (:filter (equal (lang ?label) ,*classtree-preferred-language*))) :kb kb :use-reasoner *annotation-query-reasoner*)))
(mapcar 'car (sparql `(:select (?label) (:distinct t) (,uri !foaf:name ?label)) :kb kb :use-reasoner *annotation-query-reasoner*)))
(or
(and *classtree-preferred-language*
(mapcar 'car (sparql `(:select (?comment) (:distinct t) (,uri !swan:title ?comment)(:filter (equal (lang ?comment) ,*classtree-preferred-language*))) :use-reasoner *annotation-query-reasoner* :kb kb)))
(mapcar 'car (sparql `(:select (?comment) (:distinct t) (,uri !swan:title ?comment)) :use-reasoner *annotation-query-reasoner* :kb kb))))))))
(defun rdfs-labels (kb)
(or (kb-uri2label kb)
(setf (kb-uri2label kb)
(loop with table = (make-hash-table)
for (uri label) in
(or
(or
(and *classtree-preferred-language*
(sparql `(:select (?uri ?label) () (?uri !rdfs:label ?label)
(:filter (equal (lang ?label) ,*classtree-preferred-language*))) :kb kb :use-reasoner *annotation-query-reasoner*))
(sparql `(:select (?uri ?label) () (?uri !rdfs:label ?label)) :kb kb :use-reasoner *annotation-query-reasoner*))
(or
(and *classtree-preferred-language*
(sparql `(:select (?uri ?label) () (?uri !foaf:name ?label) (:filter (equal (lang ?label) ,*classtree-preferred-language*))) :kb kb :use-reasoner *annotation-query-reasoner*))
(sparql `(:select (?uri ?label) () (?uri !foaf:name ?label)) :kb kb :use-reasoner *annotation-query-reasoner*))
(or
(and *classtree-preferred-language*
(sparql `(:select (?uri ?comment) () (?uri !swan:title ?comment)(:filter (equal (lang ?comment) ,*classtree-preferred-language*))) :use-reasoner *annotation-query-reasoner* :kb kb))
(sparql `(:select (?uri ?comment) () (?uri !swan:title ?comment)) :use-reasoner *annotation-query-reasoner* :kb kb)))
for clean-label = (clean-label label t)
when clean-label do (setf (gethash uri table ) clean-label)
finally (return table)))))
(defun encode-tooltip-for-xml-attribute (tooltip)
(xml-encode-string-with-unicode (#"replaceAll" tooltip "\\n" "
")))
;; BUG (:filter (not (regex ?comment "^\\s*$"))) doesn't work
(defun rdfs-comments (kb)
(or (kb-uri2comment kb)
(setf (kb-uri2comment kb)
(loop with table = (make-hash-table)
for (uri comment) in
(append
(sparql `(:select (?uri ?comment) () (?uri !rdfs:comment ?comment) ) :kb kb :use-reasoner *annotation-query-reasoner*)
(sparql `(:select (?uri ?comment) () (:union ((?uri !obi:OBI_0000291 ?comment))
((?uri !obi:IAO_0000115 ?comment))))
:kb kb :use-reasoner *annotation-query-reasoner*)
(sparql `(:select (?uri ?comment) () (?uri !oboinowl:hasDefinition ?def) (?def !rdfs:label ?comment)) :use-reasoner *annotation-query-reasoner* :kb kb)
)
do
(when (and comment (not (#"matches" comment "^\\s*$")))
(if (gethash uri table nil)
(setf (gethash uri table) (format nil "~a; ~a" comment (gethash uri table)))
(setf (gethash uri table) comment)))
finally (return table)))))
;; unused
(defun wrap-comment (comment &optional (prefix ""))
(and comment
(let ((words nil) (lines nil) (so-far 0) (max-length 80))
(flet ((end-line () (push (format nil "~{~a~^ ~}" (reverse words)) lines)
(setq words nil so-far 0)))
(loop for word in (map 'list #"toString" (#"split" (#"replaceAll" comment "\\\\\"" "\"") "\\s+"))
do
(cond ((> (+ so-far (length word)) max-length)
(end-line)
(push word words) (incf so-far (length word)))
(t (push word words) (incf so-far (length word)))))
(when words (end-line)))
(format nil (concatenate 'string "~{~a~^
" prefix "~}") (reverse lines)))))
(defun format-sexp-for-tooltip (form)
(if (equal form "")
""
(#"replaceAll"
(#"replaceAll"
(#"replaceAll"
(#"replaceAll"
(let ((*print-case* :downcase)
(*print-pretty* t)
(*print-right-margin* 100)
(*print-readably* nil))
(loop for (old pretty) in '((and "and") (some "some") (or "or")
(all "all") (has "has")
(min "min") (max "max")
(exactly "exactly") (not "not"))
do (setq form (subst pretty old form)))
(format nil "~w" (or form "")))
"\\n" "
")
" " " ")
"([^\\\\]|^)\"" "$1")
"\\\\\"" "\"")))
(defun format-parents (entity kb)
(let* ((asserted (sparql `(:select (?parent) () (,entity !rdfs:subClassOf ?parent) (:filter (not (isblank ?parent)))) :kb kb :use-reasoner :none :flatten t))
(inferred (set-difference (parents entity kb) asserted))
(mi? (> (length asserted) 1)))
(if (or inferred asserted)
(format nil "~{~a~^, ~}"
(append
(mapcar (lambda(c)
(if mi?
(format nil "~a" (car (rdfs-label c kb)) )
(car (rdfs-label c kb))))
(remove-duplicates asserted :test 'equalp))
(mapcar (lambda(c) (format nil "~a" (car (rdfs-label c kb)) inferred))
(remove-duplicates inferred :test 'equalp))
))
"Thing")))
;; to make note of relevant properties for each class
;; for each property, extract and name the class foo-domain, foo-range
;; take a probe class.
;; If it is equivalent to any of these, then say it *is* dr
;; If it is a subclass of any of these then report all of it is *part* of dr
;; If it is a superclass of any of these then report some of it is in dr
;; If it is non-disjoint sibling (or subclass) then report it might overlap dr
;; If DR is owl:thing perhaps say something different
(defun tree-tooltip (kb entity &key (width 500))
(if (java-object-p entity)
(setq entity (uri-full (aterm-to-sexp entity)))
(when (uri-p entity) (setq entity (uri-full entity))))
(let ((*default-kb* kb))
(let ((*current-labels* (rdfs-labels kb)))
(multiple-value-bind (aterm type) (and (has-entity? entity kb) (get-entity entity kb))
(setq @ (make-uri entity))
(let ((comment (let ((it (rdfs-comment entity kb)))
(and it (#"replaceAll" it "<" "<"))))
(labels (rdfs-label entity kb)))
(flet ((p-label (uri from-aterm)
(if (rdfs-label uri kb)
(car (rdfs-label uri kb))
from-aterm)))
(setq @@
(format nil "~a~a~a~a
" *toolip-font-size* width
(format nil "~{~a
~}"
(loop for e in (if (eq type :class)
(or (equivalents (make-uri entity) kb) (list (make-uri entity)))
(if (member type '(:object-property :datatype-property))
(cons (make-uri entity) (same-properties (make-uri entity) kb))
(if (or (null type) (eq type :annotation-property))
(list (make-uri entity))
(cons (make-uri entity) (sames (make-uri entity) kb)))))
collect (format nil "~a~a" (if type (concatenate 'string (string-capitalize (string type)) ": ") "") (uri-full e))))
(if labels (format nil "~{~a~^
~}" labels) "")
(if (equal entity (uri-full !owl:Nothing))
"These classes are unsatisfiable!
"
(if (and comment (not (equal comment "")))
(format nil "~a
" comment)
(if labels "
" ""))) ;
(cond ((eq type :class)
(let ((parents (format-parents (make-uri entity) kb))
(form (coalesce-disjoints (pretty-aterm-sexp
(mapcar
'aterm-to-sexp
(setq axioms
(set-to-list
(#"getAxioms" (#"getTBox" (kb-kb kb)) aterm))))))))
(with-output-to-string (s)
(format s "~a: ~a"
*super-label*
parents)
(when *show-logical-in-tooltip*
(format s "
~a"
(let ((*print-right-margin* (floor width 8)))
(if (consp form)
(concatenate 'string (format-sexp-for-tooltip form) "
")
""
))))
(let* ((apv (annotation-property-values-or-labels entity kb)))
(loop for (p val) in apv
with need-hrule = t
when (and val (not (eq p !rdfs:comment)) (not (eq p !rdfs:label)))
unless (and (not (uri-p val)) (#"matches" val *flush-annotation-value-regexp*))
do
(let ((p-label (p-label (uri-full p) (pretty-aterm-sexp (aterm-to-sexp (get-entity (uri-full p) kb))))))
(when (and need-hrule *want-hrule*) (format s "
") (setq need-hrule nil))
(format s "~a: ~a
"
p-label
(if (uri-p val)
(or (car (rdfs-label (uri-full p) kb))
(pretty-aterm-sexp val))
(if (stringp val)
val
val)))))
)
(unless (or *inhibit-property-info-in-toolips* (equal entity (uri-full !owl:Nothing)))
(let nil ;((*current-labels* nil))
(multiple-value-bind (in-domain-of in-domain-of-subclass maybe-in-domain-of) (properties-that-can-have-as-subject (make-uri entity) kb)
(multiple-value-bind (in-range-of in-range-of-subclass maybe-in-range-of) (properties-that-can-have-as-object (make-uri entity) kb)
(when (or in-domain-of in-range-of maybe-in-range-of maybe-in-domain-of in-domain-of-subclass in-range-of-subclass)
(when *want-hrule* (write-string "
" s))
(when in-domain-of
(format s "Subject of: ~a
" (join-with-char (remove "ObsoleteProperty" (mapcar 'pretty-aterm-sexp in-domain-of) :test 'equal) ", " )))
(when (or maybe-in-domain-of in-range-of-subclass)
(format s "Possibly subject of: ~a
"
(join-with-char (remove "ObsoleteProperty"
(append (mapcar (lambda(p) (format nil "~a" (pretty-aterm-sexp p))) maybe-in-domain-of)
(mapcar (lambda(p) (format nil "~a" (pretty-aterm-sexp p))) in-domain-of-subclass))
:test 'equal)
", ")
))
(when in-range-of
(format s "Object of: ~a
" (join-with-char (remove "ObsoleteProperty" (mapcar 'pretty-aterm-sexp in-range-of) :test 'equal) ", " )))
(when (or maybe-in-range-of in-range-of-subclass)
(format s "Possibly object of: ~a
"
(join-with-char (remove "ObsoleteProperty"
(append (mapcar (lambda(p) (format nil "~a" (pretty-aterm-sexp p))) maybe-in-range-of)
(mapcar (lambda(p) (format nil "~a" (pretty-aterm-sexp p))) in-range-of-subclass))
:test 'equal)
", ")
))))))))))
((eq type :individual)
(with-output-to-string (s)
(format s "a ~{~a~^, ~}
"
(or (remove "_TOP_"
(mapcar 'pretty-aterm-sexp
(mapcar 'aterm-to-sexp
(apply 'append
(map 'list 'set-to-list
(set-to-list (#"getTypes" (kb-kb kb) aterm t))))))
:test 'equal)
(list "Thing")))
(let* ((props (kb-properties kb))
(vs (mapcar (lambda(p) (mapcar 'aterm-to-sexp (set-to-list (#"getPropertyValues" (kb-kb kb) p aterm)))) props))
(apv (annotation-property-values-or-labels entity kb)))
(loop for p in (append props (mapcar (lambda(pv) (get-entity (uri-full(first pv)) kb)) apv))
for vals in (append vs (mapcar 'list (mapcar 'second apv)))
with need-hrule = t
when vals
do (let ((p (pretty-aterm-sexp (aterm-to-sexp p))))
(unless (and (listp p) (equal (caar p) :inv))
(when (and need-hrule *want-hrule*) (format s "
") (setq need-hrule nil))
(write-string
(format nil "~a: ~{~a~^, ~}
"
p
(mapcar (lambda (v) (if (stringp v)
v
(if (uri-p v)
(or (car (rdfs-label (uri-full v) kb))
(pretty-aterm-sexp v))
(pretty-aterm-sexp v))))
vals)
" ") s)))
))))
((member type '(:object-property :datatype-property))
(let ((subs
(pretty-aterm-sexp
(mapcar (lambda(a)
(if (atom a) (uri-name-for-node a) a))
(mapcar 'aterm-to-sexp
(apply 'append (mapcar 'set-to-list
(set-to-list
(#"getSubProperties" (kb-kb kb) aterm t))))))))
(supers
(pretty-aterm-sexp
(mapcar (lambda(a)
(if (atom a) (uri-name-for-node a) a))
(mapcar 'aterm-to-sexp
(apply 'append (mapcar 'set-to-list
(set-to-list
(#"getSuperProperties" (kb-kb kb) aterm t))))))))
(inverses
(mapcar (lambda(a)
(if (atom a) (uri-name-for-node a) a))
(mapcar 'aterm-to-sexp
(set-to-list
(#"getInverses" (kb-kb kb) aterm)) )))
(domain (let ((raw (#"getDomain" (#"getRole" (#"getRBox" (kb-kb kb)) aterm))))
(pretty-aterm-sexp
(if (null raw)
(pretty-aterm-sexp !owl:Thing)
(aterm-to-sexp (#"nnf" 'AtermUtils raw))))))
(range (let ((raw (#"getRange" (#"getRole" (#"getRBox" (kb-kb kb)) aterm))))
(pretty-aterm-sexp
(if (null raw)
(if (eq type :object-property) !owl:Thing !rdf:Literal)
(aterm-to-sexp (#"nnf" 'AtermUtils raw))))))
)
(with-output-to-string (s)
(write-string (property-attributes type aterm kb) s)
(when inverses
(format s "Inverse of: ~{~a~^, ~}
" inverses))
(when supers
(format s "Subproperty of: ~{~a~^, ~}
" (if (not (listp supers)) (list supers) supers)))
(when subs
(format s "Subproperties: ~{~a~^, ~}
" (if (not (listp subs)) (list subs) subs)))
(format s "Domain: ~a
" (format-sexp-for-tooltip domain))
(format s "Range: ~a
" (format-sexp-for-tooltip range))
(let* ((apv (annotation-property-values-or-labels entity kb)))
(loop for (p val) in apv
with need-hrule = t
when (and val (not (eq p !rdfs:comment)) (not (eq p !rdfs:label)))
do
(let ((p-label (p-label (uri-full p) (pretty-aterm-sexp (aterm-to-sexp (get-entity (uri-full p) kb))))))
(when (and need-hrule *want-hrule*) (format s "
") (setq need-hrule nil))
(format s "~a: ~a
"
p-label
(if (uri-p val)
(pretty-aterm-sexp val)
(if (stringp val)
val
val))))
))
)))
(t ""))))
(prog1 @@
(setq @@ (#"replaceAll"
(#"replaceAll"
(#"replaceAll" (#"replaceAll" @@ "<(\/div|br)>" (load-time-value (concatenate 'string (string #\linefeed) (string #\linefeed)))) "<\\S+?>" "")
"(<(div|font) .*?>)" "")
"&\\S+?;" " ")))
))))))
(defun tree-tooltip-text (entity kb)
(#"replaceAll" (#"replaceAll" (#"replaceAll" (tree-tooltip entity kb) "(
)|(|
]*>)" "
")" " " ") "<[^<]+>" ""))
;; (let ((sames (list-of-entity-names2 (#"getSames" (kb-kb kb) ent ))))
;; (when sames
;; (format t "Same as: ~{~s~^, ~}~%" sames)))
(defun coalesce-disjoints (conjunction)
(if (and (consp conjunction) (eq (car conjunction) 'and))
(let ((nots (remove-if-not (lambda(c) (and (consp c) (eq (car c) 'not) (atom (second c)))) (cdr conjunction))))
(if (> (length nots) 1)
(append '(and)
(remove-if (lambda(c) (and (consp c) (eq (car c) 'not) (atom (second c)))) (cdr conjunction))
(list (list* "disjoint-with" (mapcar 'second nots))))
conjunction))
conjunction))
(defun property-attributes (type ent kb)
(let ((pprops nil))
(when (eq type :object-property)
(when (#"isInverseFunctionalProperty" (kb-kb kb) ent)
(push "Inverse Functional" pprops))
(when (#"isSymmetricProperty" (kb-kb kb) ent) (push "Symmetric" pprops))
(when (#"isTransitiveProperty" (kb-kb kb) ent) (push "Transitive" pprops)))
(when (#"isFunctionalProperty" (kb-kb kb) ent) (push "Functional" pprops))
(if pprops
(format nil "~{~a~^, ~}
" pprops)
"")))
(defun pretty-aterm-sexp (sexp)
(if (stringp sexp)
sexp;(uri-name-for-node (make-uri sexp))
(if (uri-p sexp)
(uri-name-for-node sexp)
(if (atom sexp)
sexp
(cond ((eq (car sexp) :subclass-of)
(pretty-aterm-sexp (third sexp)))
((and (consp (car sexp)) (eq (caar sexp) :subclass-of))
(pretty-aterm-sexp
`(:and ,sexp)))
((equal (car sexp) '(:same))
`(equivalent-class ,@(rest (mapcar 'pretty-aterm-sexp (rest sexp)))))
((equal (car sexp) '(:equivalent-classes))
`(equivalent-class ,@(mapcar 'pretty-aterm-sexp (rest sexp))))
((= (length sexp) 1)
(pretty-aterm-sexp (car sexp)))
((eq (car sexp) :literal)
(cond ((equal (fourth sexp) "http://www.w3.org/2001/XMLSchema#int")
(parse-integer (second sexp)))
((equal (fourth sexp) "http://www.w3.org/2001/XMLSchema#double")
(float (read-from-string (second sexp))))
((equal (fourth sexp) "http://www.w3.org/2001/XMLSchema#float")
(float (read-from-string (second sexp))))
((equal (fourth sexp) "http://www.w3.org/2001/XMLSchema#string")
(prin1-to-string (second sexp)))
(t (prin1-to-string (second sexp)))))
((and (eq (car sexp) 'and) (= (length sexp) 2))
(pretty-aterm-sexp (second sexp)))
((and (eq (car sexp) 'and) (some (lambda(e)(and (consp e) (eq (car e) 'and))) (rest sexp)))
`(and
,@(remove-duplicates
(loop for el in (cdr sexp)
if (and (consp el) (eq (car el) 'and))
append (pretty-aterm-sexp (cdr el))
else if (stringp el) collect el;(uri-name-for-node (make-uri el))
else collect (pretty-aterm-sexp el))
:test 'equal)))
((eq (car sexp) :subclass-of)
(list (car sexp) (second sexp)
(pretty-aterm-sexp (third sexp))))
((and (eq (car sexp) :and) (= (length (rest sexp)) 1)
(every 'consp (second sexp))
(eq (car (first (second sexp))) :mincardinality)
(eq (car (second (second sexp))) :maxcardinality))
(destructuring-bind (name card &rest ignore)
(cdar (cdadr sexp))
(list (uri-name-for-node (make-uri name)) 'exactly card )))
((eq (car sexp) :cardinality)
(destructuring-bind (name card &rest ignore)
(cdr sexp)
(list (uri-name-for-node (make-uri name)) 'exactly card )))
((and (member (car sexp) '(:and :or)) (= (length (rest sexp)) 1))
(let ((conjuncts (remove "_TOP_" (mapcar (lambda(e) (if (stringp e)
(pretty-aterm-sexp (make-uri e))
(pretty-aterm-sexp e))) (second sexp))
:test 'equal)))
(cond ((= (length conjuncts) 1)
(pretty-aterm-sexp (car conjuncts)))
(conjuncts (pretty-aterm-sexp (list* (if (eq (car sexp) :and) 'and 'or) conjuncts)))
(t nil))))
((eq (car sexp) :mincardinality)
`( ,(uri-name-for-node (make-uri (second sexp))) min ,(third sexp)))
((eq (car sexp) :hasvalue)
`(has ,(pretty-aterm-sexp (second sexp)))) ; (uri-name-for-node (make-uri (second sexp)))))
((eq (car sexp) :maxcardinality)
`( ,(uri-name-for-node (make-uri (second sexp))) max ,(third sexp)))
((member (car sexp) '(:all-values-from :some-values-from))
`(,(if (stringp (second sexp))
(uri-name-for-node (make-uri (second sexp)))
(pretty-aterm-sexp (second sexp)))
,@(if (stringp (third sexp))
(progn
(list (if (eq (car sexp) :all-values-from) "all" 'some)
(uri-name-for-node (make-uri (third sexp)))))
(if (and (consp (third sexp)) (eq (car (third sexp)) :hasvalue))
(list 'has (pretty-aterm-sexp (second (third sexp))))
(list (if (eq (car sexp) :all-values-from) 'all 'some)
(pretty-aterm-sexp (third sexp)))))))
((eq (car sexp) :not)
(if (consp (second sexp))
`(not ,(pretty-aterm-sexp (second sexp)))
`(not ,(uri-name-for-node (make-uri (second sexp))))))
;; ((eq (car sexp) 'and)
;; (loop for conjunct in (cdr sexp) append
;; (if (and (consp conjunct) (eq (car conjunct) 'and))
;; (pretty-aterm-sexp (cadr conjunct))
;; (list (pretty-aterm-sexp conjunct)) )))
(t sexp))))))
(defun @@ (&rest args) (if (eq (car args) '@@) (progn (princ @@) (values)) (apply 'eval args)))
(defun maybe-hook-@@ ()
(let ((sreh (and (find-package 'swank)
(find-symbol "*SLIME-REPL-EVAL-HOOKS*" 'swank))))
(when (and sreh (boundp sreh))
(eval `(pushnew '@@ ,sreh)))))
(setq test
'((:SUBCLASS-OF "ncbilsid:pubmed-classes:Investigator"
(:AND
((:AND
((:MINCARDINALITY
"ncbilsid:pubm
ed-predicates:Investigator_lastName" 1)
(:MAXCARDINALITY
"ncbilsid:pubmed-predicates:Investigator_lastName" 1)))
(:AND
((:MINCARDINALITY
"ncbilsid:pubmed-predicates:Investigator_initials" 1)
(:MAXCARDINALITY
"ncbilsid:pubmed-predicates:Investigator_initials" 1)))
(:AND
((:MINCARDINALITY
"ncbilsid:pubmed-predicates:Investigator_firstName" 1)
(:MAXCARDINALITY
"ncbilsid:pubmed-predicates:Investigator_firstName" 1)))
(:AND
((:MINCARDINALITY
"ncbilsid:pubmed-predicates:Investigator_middleName" 1)
(:MAXCARDINALITY
"ncbilsid:pubmed-predicates:Investigator_middleName" 1)))
(:AND
((:MINCARDINALITY
"ncbilsid:pubmed-predicates:Investigator_foreName" 1)
(:MAXCARDINALITY
"ncbilsid:pubmed-predicates:Investigator_foreName" 1)))
(:AND
((:MINCARDINALITY
"ncbilsid:pubmed-predicates:Investigator_affiliation" 1)
(:MAXCARDINALITY
"ncbilsid:pubmed-predicates:Investigator_affiliation" 1)))
(:AND
((:MINCARDINALITY
"ncbilsid:pubmed-predicates:Investigator_suffix" 1)
(:MAXCARDINALITY
"ncbilsid:pubmed-predicates:Investigator_suffix" 1))))))))