Next: , Up: Queries and Directives   [Contents][Index]


3.4.1 Queries

The full syntax of a query is ‘?-’ followed by a sequence of goals. The top level expects queries. This is signaled by the initial prompt ‘?- . Thus a query at top level looks like:

| ?- memb(X, [a,b,c]).

Remember that Prolog terms must terminate with a full stop (‘.’, possibly followed by whitespace), and that therefore Prolog will not execute anything until you have typed the full stop (and then RET) at the end of the query.

If some query variables not beginning with ‘_’ were bound, as in this example, then the final value of each variable is displayed. Thus the above query would be answered by:

X = a ?

At this point, the development system accepts one-letter commands corresponding to certain actions. To execute an action simply type the corresponding character followed by RET. The available commands in development systems are:

RET
y

“accepts” the solution; the query is terminated and the development system responds with ‘yes’.

;
n

“rejects” the solution; the development system backtracks (see ref-sem) looking for alternative solutions. If no further solutions can be found, then it outputs ‘no’.

b

invokes a recursive top level.

<

In the top level, a global printdepth is in effect for limiting the subterm nesting level when printing bindings. The limit is initially 10.

This command, without arguments, resets the printdepth to 10. With an argument of n, the printdepth is set to n, treating 0 as infinity. This command works by changing the value of the toplevel_print_options Prolog flag.

^

A local subterm selector, initially [], is maintained. The subterm selector provides a way of zooming in to some subterm of each binding. For example, the subterm selector [2,3] causes the 3rd subterm of the 2nd subterm of each binding to be selected.

This command, without arguments, resets the subterm selector to []. With an argument of 0, the last element of the subterm selector is removed. With an argument of n (> 0), n is added to the end of the subterm selector. With multiple arguments separated by whitespace, the arguments are applied from left to right. n

h
?

lists available commands.

While the variable bindings are displayed, all variables occurring in the values are replaced by friendlier variable names. Such names come out as a sequence of letters and digits preceded by ‘_’. The outcome of some queries is shown below.

| ?- memb(X, [tom,dick,harry]).

X = tom ;
X = dick ;
X = harry ;

no
| ?- memb(X, [a,b,f(Y,c)]), memb(X, [f(b,Z),d]).

X = f(b,c),
Y = b,
Z = c

| ?- memb(X, [f(_),g]).

X = f(_A)

If the goal(s) specified in a query can be satisfied, and if no variables not beginning with ‘_’ were bound, then no variable bindings will be displayed. In this case there are two possible answers.

In the simplest case, when the system can determine that there cannot be any more solutions, then the system answers:

yes

and execution of the query terminates.

Alternatively, if there are potentially more answers1, the system instead answers:

true ?

and waits for the usual one-letter commands, as described above.

This example shows what happens when there are multiple solutions, but when no variable binding is shown:

| ?- memb(_X, [a,b,c]).
true ? 

here there are three possible solutions, binding the variable _X to ‘a’, ‘b’ and ‘c’, respectively. But, as the variable name starts with ‘_’, its bindings will not be displayed. Since there are more solutions after the first solution, the system prompts for a one-letter command even though there are no variable bindings to display.

The following example illustrates a difference in behavior when using the memb/2 as defined above, and the builtin member/2, when there is only one solution:

memb(c, [a,b,c]).
true ? 

here ‘c’ is the last element, but the system cannot determine that this is the last solution. Therefore, the system answers ‘true’ and waits for a one-letter command.

| ?- member(c, [a,b,c]).
yes

in this case too ‘c’ is the last element, but the system can determine that this is the last solution. Since there are also no variable bindings to display, the system answers ‘yes’ and the execution of the query terminates without waiting for a one-letter command.

The difference in behavior is because the builtin member/2 is carefully constructed to ensure that no useless alternatives (i.e. choicepoints) are created. This makes member/2 more efficient than the naive implementation of memb/2. See Indexing for more on this.


Footnotes

(1)

I.e. there are pending choicepoints.



Send feedback on this subject.