Next: Query Hooks, Previous: Query Classes, Up: Query Processing [Contents][Index]
Query processing is done in several phases, described below. We will illustrate what is done in each phase through a simple example: the question put to the user when the solution to the toplevel query ‘X is 1+1’ is displayed, requesting a decision whether to find alternative answers or not:
| ?- X is 1+1. X = 2 ? no Please enter ";" for more choices; otherwise, <return> ? ;
We focus on the query ‘X = 2 ? ’ in the above script.
The example query belongs to the class next_solution
, its text is
described by the message term solutions([binding("X",2)])
,
and its help text by the message term bindings_help
.
Accordingly, such a query is executed by calling:
ask_query(next_solution, /* QueryClass */ solutions([binding("X",2)]), /* Query */ bindings_help, /* Help */ Answer)
In general, execution of ask_query(QueryClass, Query,
Help, Answer)
consists of the following phases:
The abstract message terms Query
(for the text of the query) and Help (for the help message) are
converted to format-command lines via the message generation and
line splitting phases (see Message Processing). Let us call the
results of the two conversions QueryLines and HelpLines,
respectively. The text of the query, QueryLines is printed
immediately (via the message printing phase, using query
severity). HelpLines may be printed later, and QueryLines
printed again, in case of invalid user input.
The characteristics of QueryClass (described in the previous subsubsection) are retrieved to control the exact behavior of the further phases.
In our example, the following parameters are sent in the preparation phase:
QueryLines | = | [[],['~s = '-["X"],write_term(2)]] |
HelpLines | = |
[['Please enter ";" for more choices; otherwise, <return>'-[]]]
Prompt | = | ' ? ' |
InputMethod | = | line |
MapMethod | = | char([yes-";", no-[0'\n]]) |
FailureMode | = | help |
QueryLines is displayed immediately, printing:
X = 2
(Note that the first element of QueryLines is []
, therefore
the output is preceded by a newline. Also note that no newline is
printed at the end of the last line, because the query
severity
is used.)
The subsequent phases will be called repeatedly until the mapping phase succeeds in generating an answer.
By default, the input phase is implemented by the hook predicate
'SU_messages':query_input(InputMethod, Prompt, RawInput).
This phase uses the Prompt and InputMethod characteristics of the query class. InputMethod specifies the method of obtaining input from the user. This method is executed, and the result (RawInput) is passed on to the next phase.
The use of Prompt may depend on InputMethod. For example,
the built-in input method line
prints the prompt unconditionally,
while the input method term(_)
passes Prompt to
prompt/2
.
In the example, first the ‘ ? ’ prompt is displayed. Next, because
InputMethod is line
, a line of input is read, and the
code list is returned in RawInput. Supposing that the user
typed noRET, RawInput becomes " no"
=
[32,110,111]
.
By default, the mapping phase is implemented by the hook predicate
'SU_messages':query_map(MapMethod, RawInput, Result, Answer).
This phase uses the MapMethod parameter to control the method of converting the raw input to the abstract answer.
In some cases RawInput is returned as it is, but otherwise it has to be processed (parsed) to generate the answer.
The conversion process may have two outcomes indicated in the Result returned:
In the latter case a message describing the cause of failure may be returned, to be printed before the query is repeated.
In our example, the map method is char([yes-";", no-[0'\n]])
.
The mapping phase fails for the RawInput passed on by the previous
phase of the example, as the first non-whitespace character is n,
which does not match any of the given characters.
This phase is executed only if the mapping phase returned with failure.
First, if a message was returned by the mapping, then it is printed. Subsequently, if requested by the FailureMode parameter, then the help message HelpLines and/or the text of the query QueryLines is printed.
The query is then repeated—the input and mapping phase will be called again to try to get a valid answer.
In the above example, the user typed an invalid character, so the
mapping failed. The char(_)
mapping does not return any
message in case of failure. The FailureMode of the query class
is help
, so the help message HelpLines is
printed, but the query is not repeated:
Please enter ";" for more choices; otherwise, <return>
Having completed the query restart phase, the example script continues
by re-entering the input phase: the prompt ‘ ? ’ is printed,
another line is read, and is processed by the mapping phase. If the
user types the character ; this time, then the mapping phase
returns successfully and gives the abstract answer term
yes
.