query [Function]


Purpose

The query function provides a functional interface for runningarbitrary queries. The results of the query are identical to {\bfretrieve} except that its arguments are evaluated and free variablesmust be declared special.

Syntax

query variables expression

Arguments

The variables argument is either nil, a single query variable, or a list of query variables (where a query variable is a symbol beginning with the character `?'). If variables is nil, query has the effect of an ask rather than a retrieve.

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.

Value

If variables is null, t is returned if expression is provably true, and nil otherwise. If variables is a symbol, query returns a list of values satisfying expression. If variables is a list, a list of tuples is returned, where each tuple contains as many values as there are variables.

Remarks

It is preferable to use retrieve whenever possible because {\bfretrieve} is generally much faster than query. Query doesall of its query optimization work at run-time and may call thecompiler. Retrieve does its query optimization work atcompile-time is will therefore run faster. Since retrieve supportsparameterized queries, the only reason to use the query functionis when the form of the query is not known until run-time.

Examples

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

See Also

Last modified: Jun 1 1995