Queries
A query is simply a goal without sub-goals (or a rule without a body). It is assumed that all intensional relations have been inferred using the program’s rules and so the goal’s predicate may be extensional or intensional.
While a query is just a goal it is syntactically distinct either with the prefix "?-"
or the suffix "?"
.
query ::= ( "?-" atom "." ) | ( atom "?" ) ;
The following are equivalent queries.
?- ancestor(xerces, X).
ancestor(xerces, X)?
Query Forms
While a query is syntactically simple, an Atom with constant and variable terms, it’s application falls into some distinct patterns or forms.
- Existential – determines the existance of a fact by only providing constant terms; this can be reduced to a boolean response value.
- Selection – one or more variables will result in all facts that match any provided constants.
- Projection (narrower) – one or more anonymous variables will remove the corresponding attribute from any results.
Examples
We refer to our common syllogism example.
human("Socrates").
mortal(X) <- human(X).
?- mortal("Socrates").
The execution of this program will start with the goal query
mortal("Socrates")
which can be read as “is there an atom with the label
‘mortal’ with a single attribute value ‘Socrates’?”.
+------------+
| _: string |
+============+
| "Socrates" |
+------------+
As all terms are constant in this query, a processor MAY return a boolean
value rather than the matching fact, in this case true
.
+------------+
| _: boolean |
+============+
| true |
+------------+
However, if we were to change the final query to replace the constant with a variable, as follows:
?- mortal(X).
The program will select all matching (in this case all) facts from the
mortal relation. In this case the column is named for the variable X
, the
previous example used the anonymous identifier.
+------------+
| X: string |
+============+
| "Socrates" |
+------------+
When the value _
is used in a query it denotes an attribute of the relation that has no meaning
in either the query or the response. For example, in the following query we ask for all values of
the model attribute in the car relation where the make is “ford”, and ignore the age entirely.
.assert car(make: string, model: string, age: integer).
car("ford", X, _)?
The results of this query would not include the age column:
+------------+
| model |
+============+
| edge |
+------------+
| escort |
+------------+
| fiesta |
+------------+
| focus |
+------------+
| fusion |
+------------+
| mustang |
+------------+
...