(full-reset) (racer-read-file "z:/temp/people+pets.racer") ;;; ---------------------------- ;;; Explain: Shell (get-racer- tab), completion, lambda-list, ... ;;; ---------------------------- ;;; Concepts ("classes") in an subclass-of hierachy ;;; Explain subsumption between cat-liker and cat-owner: ;;; "Class reasoning" #| (equivalent cat_liker (and person (some likes cat))) (equivalent cat_owner (and person (some has_pet cat))) (define-primitive-role has_pet :parents likes ...) |# ;;; Show role hierachy (has_pet is subrole of likes) ;;; Position in class hierarchy computed from definitions ;;; Explain old-lady #| (equivalent old_lady (and person female elderly)) (implies old_lady (and (all has_pet cat) (some has_pet animal))) |# ;;; Class / concept consistency ;;; there are no mad cows #| (define-concept mad_cow (and cow (some eats (and brain (some part_of sheep))))) (implies cow vegetarian) (define-concept vegetarian (and animal (all eats (not animal)) (all eats (not (some part_of animal))))) (implies sheep animal) |# ;;; ---------------------------- ;;; "Individual reasoning" ;;; Individual Minnie (Individuals Tab -> Assertion Tab) ;;; Old_lady not explicit ;;; ABox Graph : Minnie has_pet Tom ;;; Select Tom -> Describe -> Cat ;;; Assertions Tab: nothing was asserted for Tom ;;; Is a cat by inference (see old_lady) ;;; Interplay of definitions <-> individuals (TBox <-> ABox) ;;; The classes an individual is an instance of ;;; is computed from the definitions! ;;; multiple classification ;;; ---------------------------- ;;; ;;; ABox Queries ;;; (Go to ABox Graph!) ;;; (concept-instances cat_owner) (retrieve (?x) (?x cat_owner)) (retrieve (?x ?y) (and (?x cat_owner) (?x ?y has_pet))) (retrieve (?x ?y) (and (?x cat_owner) (?x ?y has_pet) (?y cat))) (retrieve (?x ?y (direct-types ?y)) (and (?x pet_owner) (?x ?y has_pet)) :dont-show-lambdas-p t) ;;; ;;; Queries involving negation ;;; 2 types of negation ;;; (retrieve (?x) (?x (not pet_owner))) (retrieve (?x) (neg (?x pet_owner))) ;;; ;;; OWA ;;; (retrieve (?x) (?x (and cat_owner (all has_pet cat)))) (retrieve (?x) (?x (and dog_owner (all has_pet dog)))) (equivalent duck_owner (and pet_owner (some has_pet duck))) (retrieve (?x) (?x duck_owner)) (retrieve (?x) (?x (and duck_owner (all has_pet duck)))) ;;; whats the difference? OWA! ;;; Why did it work for Minnie? Definition ;;; Why did it work for Joe? At-most 1 pet (instance Walt (at-most 3 has_pet)) (retrieve (?x) (?x (and duck_owner (all has_pet duck)))) ;;; still not sufficent, might be the same individual! ;;; no UNA assumed (all-different Huey Dewey Louie) (retrieve (?x) (?x (and duck_owner (all has_pet duck)))) ;;; at last... ;;; ;;; Some more advanced queries ;;; Aggregation: ;;; (retrieve (?x (count ?y) (group-by ?x)) (?x ?y has_pet)) ;;; Nested Queries (retrieve (?x ((lambda (x) (let ((pets (retrieve `(?y) `(,x ?y has_pet)))) `(has ,(length pets) pets ,@pets))) ?x)) (?x pet_owner) :dont-show-lambdas-p t) (retrieve (?x ((lambda (x) (let ((pets (retrieve `(?y) `(,x ?y has_pet)))) (format nil "~A has ~A pets:~{ ~S~}" x (length pets) (maplist cadar pets)))) ?x)) (?x pet_owner) :dont-show-lambdas-p t) ;;; ;;; An optimized version with query pre-compilation: ;;; (delete-all-queries) (with-future-bindings (?x) (prepare-abox-query (?y) (?x ?y has_pet) :id :pet-query)) (retrieve (?x ((lambda (x) (with-nrql-settings (:bindings `((?x ,x))) (let ((pets (execute-or-reexecute-query :pet-query))) (format nil "~A has ~A pets:~{ ~S~}" x (length pets) (maplist cadar pets))))) ?x)) (?x pet_owner) :dont-show-lambdas-p t) ;;; ;;; Datatype Queries ;;; (define-concrete-domain-attribute age :type real) (instance Louie (= age 1.0)) (instance Dewey (= age 2.0)) (instance Huey (= age 3.0)) (enable-data-substrate-mirroring) (retrieve (?x ?*age) (and (?x duck) (?*x ?*age age))) ;;; ;;; Universal Quantification ;;; with "neg" and "project-to" ;;; Oldest duck: ;;; (retrieve (?x ?*age-of-x) (and (?x duck) (?*x ?*age-of-x age) (neg (project-to (?*age-of-x) (and (?y duck) (?*y ?*age-of-y age) (?*age-of-x ?*age-of-y (:satisfies (:predicate <)))))))) ;;; Youngest duck: (retrieve (?x ?*age-of-x) (and (?x duck) (?*x ?*age-of-x age) (neg (project-to (?*age-of-x) (and (?y duck) (?*y ?*age-of-y age) (?*age-of-x ?*age-of-y (:satisfies (:predicate >)))))))) ;;; ;;; Rules ;;; (firerule (and (?x person) (neg (?x pet_owner))) ((related ?x (new-ind pet-of ?x) has_pet))) (retrieve (?y) (and (Kevin ?y has_pet) (?y pet))) (individual-instance? Kevin (or dog_owner cat_owner duck_owner)) (firerule (and (?x pet) (neg (?x (or cat dog duck)))) ((instance ?x (lambda (nth (random 3) '(cat dog duck)))))) (individual-instance? Kevin (or dog_owner cat_owner duck_owner)) (firerule (and (?x pet) (neg (?x (or cat dog duck)))) ((instance ?x (lambda (nth (random 3) '(cat dog duck)))))) ;;; non-monotonic due to NEG, doesn't fire twice ;;; ;;; Reasoning with queries / rules ;;; (report-inconsistent-queries-and-rules) (firerule (?x old_lady) ((related ?x (new-ind another-dog-for ?x) has_pet) (instance (new-ind another-dog-for ?x) dog))) (dont-report-inconsistent-queries-and-rules) ;;; ;;; HTML Report Generation ;;; (evaluate (let ((res (retrieve '(?x ?y) '(and (?x ?y has_pet))))) (with-html ( "/home/mi.wessel/temp/pets.html") (html (head) (html (title) (content "Query Evaluation Output"))) (html (body) (html (h1) (content "Query Evaluation Output")) (html (h2) (content "Query Head")) (content (query-head :last)) (html (h2) (content "Query Body")) (content (query-body :last)) (html (h2) (content "Query Answer")) (html (table :border 1) (let ((count 0)) (maplist (lambda (bindings) (html (tr) (html (th :colspan 2) (content (format nil "Result Tuple No. ~A" (incf count))))) (maplist (lambda (var-val) (let ((var (first var-val)) (val (second var-val))) (html (tr) (html (td) (content var)) (html (td) (content val))))) bindings)) res))))))) (evaluate (publish-file "/home/mi.wessel/temp/pets.html" "/pets.html" "text/html")) ;;; http://localhost:8080/pets.html ;;; ;;; SPARQL Queries to OWL version ;;; (full-reset) (owl-read-file "/home/mi.wessel/temp/people+pets.owl") (sparql-answer-query "prefix pets: select ?x where { ?x rdf:type pets:cat }") (sparql-answer-query "prefix pets: select ?x ?y where { ?x rdf:type pets:old_lady ; pets:has_pet ?y . ?y rdf:type pets:cat . }")