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)))))