The expression variable is an arbitrary expression in the Loom query language. (See retrieve Remarks for a summary of the query syntax). Any free variables, (i.e., externally bound query variables) that appear in expression must be declared special.
(tellm (:about Joe Writer Surfer Tenor Sagittarius
(wife Sue) (age 37) (child Jason) (child Mark)))
(query nil '(Writer Joe)) ==> T ;; Ask would be better
(query '?x '(Writer ?x)) ==> (|I|JOE) ;; Retrieve would be better
(let ((?V 37)) ;; Retrieve would be better
(declare (special ?V)) ; special only needed for query
(query '(?x ?y) '(:and (Writer ?x) (wife ?x ?y) (age ?x ?V)))) ==>
((|I|JOE |I|SUE))
(defun find-instances-with-constrained-fillers (fillerConstraintsList)
;; This function retrieves instances which have role fillers
;; that match the fillerConstraintsList. It has the format
;; of ((<role> <concept>*) ...) where some <role> filler must
;; satisfy all of the <concepts> for that <role>:
(let ((queryBody nil)
(innerQuery nil)
(innerVariable nil))
;; Iterate over each constraint and build a query
(dolist (constraint fillerConstraintsList)
(setq innerQuery nil)
(setq innerVariable (gentemp "?V-"))
(dolist (concept (rest constraint))
(push (list concept innerVariable) innerQuery))
(push (list :for-some innerVariable
`(:and (,(first constraint) ?x ,innerVariable) ; bind filler
,@innerQuery)) ; apply constraints
queryBody))
(query '?x `(:and ,@queryBody)) ))
(find-instances-with-constrained-fillers
'((son pisces musician) (son famous movie-star) (wife sagittarius)))
==> Creates the following query and returns the results:
(QUERY '?X
'(:AND (:FOR-SOME ?V-7
(:AND (WIFE ?X ?V-7) (SAGITTARIUS ?V-7)))
(:FOR-SOME ?V-6
(:AND (SON ?X ?V-6) (MOVIE-STAR ?V-6) (FAMOUS ?V-6)))
(:FOR-SOME ?V-5
(:AND (SON ?X ?V-5) (MUSICIAN ?V-5) (PISCES ?V-5)))))