The *context* argument is the name of the context in which *query* is to be compiled or evaluated.

If the *3-valued-p* argument is **t**, the query returns **:true**, **:false**, or **:unknown**.

query-expr ::= ( {:AND | :OR} query-expr+ ) | ( {:NOT | :FAIL} query-expr ) | ( :IMPLIES query-expr query-expr ) | ( {:FOR-SOME | :FOR-ALL} ( ?Var+ ) query-expr ) | ( :COLLECT ( ?Var ) query-expr ) | ( concept instance ) | ( relation instance+ value ) | ( :SAME-AS instance instance ) | ( :SUBSET instance instance ) | ( :PREDCALL LispPredicate value+ ) | ( :ABOUT instance about-clause* ) ;

about-clause ::=The query expressions in the

concept |

( concept ) |

( relation value ) |

( :FILLED-BY relation value+ ) |

( {:AT-LEAST | :AT-MOST | :EXACTLY} Integer relation ) |

( {:ALL | :SOME | :THE} relation concept ) ;

The query-expression operators have the following semantics:

- If Q = (
**:and**Q1...Qn), Q is true if Q1...Qn are all true. - If Q = (
**:or**Q1...Qn), Q is true if at least one of Q1...Qn is true. - If Q = (
**:not**Q1), Q is true if Loom can prove that Q1 cannot be true. - If Q = (
**:fail**Q1), Q is true if Loom cannot prove that Q1 is true. - If Q = (
**:for-some**(?X1...?Xn) Q1), Q is true if there are bindings for ?X1...?Xn that satisfy Q1. - If Q = (
**:for-all**(?X1...?Xn) (**:implies**Q1 Q2)), Q is true if all bindings of ?X1...?Xn that satisfy Q1 necessarily satisfy Q2. - If Q = (C I), Q is true if I is an instance of concept C.
- If Q = (R I V), Q is true if V is a filler of role R on instance I.
- If Q = (R I1...In), Q is true if the tuple <I1...In> satisfies n-ary relation R.
- If Q = (
**:same-as**V1 V2), Q is true if values V1 and V2 are equivalent. - If Q = (
**:subset**V1 V2), Q is true if V1 and V2 evaluate to sets of values, and V1 is a subset of V2. - If Q = (
**:predcall**P V), Q is true if application of Lisp predicate P to value V returns a value other than**nil**. - If Q = (
**:about**I C) or (**:about**I (C)), Q is true if I is an instance of concept C. - If Q = (
**:about**I (R V)), Q is true if the filler of role R on instance I is V. - If Q = (
**:about**I (**:filled-by**R V1...Vn)), Q is true if every value Vi is a filler of role R on instance I. - If Q = (
**:about**I (**:at-least**K R)), Q is true if instance I has at least K fillers of role R. The**:at-most**and**:exactly**operators have corresponding semantics. - If Q = (
**:about**I (**:all**R C)), Q is true if all fillers of role R on instance I are instances of concept C. The**:some**and**:the**operators have corresponding semantics.

Any **?**-variable not bound in a **:for-some** or **:for-all** clause is assumed to be bound externally. The value of an external **?**-variable should be a Loom object, i.e., a concept, relation, or instance, rather than the name of such an object.

The **:filled-by-list** operator cannot be used in the **:about** clause of a query. The Loom Grammar at the end of this manual is too general in this respect.

Concepts and relations referenced by name in a query must be defined at the time the query is compiled. Instances referenced by identifier must exist at the time the query is executed.

(ask (Artist Joe)) ==> T

(ask (age Joe 40) :context cl-user-theory) ==> NIL

(ask (child Joe Fred) :3-valued-p t) ==> :UNKNOWN

(ask (max (age (child Joe)) 13))

(ask (distance Paris Rome 1000))

(ask (:and (Woman Boxer) (Senator Boxer)))

(ask (:not (Dog Duke)))

(ask (:fail (:or (French Jean) (resides Jean France))))

(ask (:for-some ?y (:and (author Joe ?y) (Best-Seller ?y))))

(ask (:for-some ?y (:and (age (child Joe) ?y) (:predcall \#'oddp ?y))))

(ask (:for-all ?y (:implies (author Joe ?y) (Best-Seller ?y))))

(ask (:same-as (home Joe) (office Joe)))

(ask (:subset (customer Fred) (customer Joe)))

(ask (:about Joe (:at-least 2 child) (:exactly 0 son)))

(ask (:about Joe (:all child Female) (:some child Teen-Ager)))

(ask (:about Joe (:filled-by daughter Mary Sue)))

(setq ?C (fc Artist) ?R (fr friend) ?V (fi Fred) ?I (fi Joe))

(ask (:and (?C ?I) (?R ?I ?V) (:about ?I (:all ?R ?C))))