2.3 Control flow
ECLiPSe and a C or C++ main program are like threads running in a
single process. Each maintains its state and methods for exchanging
data and yielding control to the other thread.
The main method of sending data from C++ to ECLiPSe is by posting
goals for it to solve. All posted goals are solved in conjunction
with each other, and with any previously posted goals that have
Data is passed back by binding logical variables within the goals.
Control is explicit in C++. After posting some goals, the C++ program
EC_resume() function and these goals are all
solved. A return code says whether they were successfully solved
or whether a failure occurred.
In ECLiPSe control is normally implicit. Control returns to C++ when all
goals have been solved.
/* writeln("hello world"), */
The above is an example program that posts a goal and executes it.
2.3.1 Control flow and search
Using this model of communication it is possible to construct programs where
execution of C++ code and search within the ECLiPSe are interleaved.
If you post a number of goals (of which some are non-deterministic) and
resume the ECLiPSe execution and the goals succeed, then control returns
to the C++ level. By posting a goal that fails, the ECLiPSe execution
will fail back into the previous set of goals and these will succeed with
a different solution.
while (EC_succeed == EC_resume())
The above example prints all the built ins available in ECLiPSe.
EC_succeed there is a solution
to a set of posted goals, and we print out the value of
EC_fail to indicate
that no more solutions to any set of posted goals is available.
It is possible also to cut such search. So for example one could modify
the example above to only print the 10th answer. Initially one simply
fails, but at the tenth solution one cuts further choices. Then
one prints the value of 'Pred'.
int i = 0;
while (EC_succeed == EC_resume(Choice))
if (i++ == 10)
EC_resume() is called with an
EC_ref argument, this
is for data returned by the
EC_resume() If the return code is
EC_ref is set to a choicepoint identifier
which can be used for cutting further choices at that point.
2.3.2 Asynchronous events
The posting of goals and building of any ECLiPSe terms in general
cannot be done asynchronously to the ECLiPSe execution. It has to
be done after the
EC_resume() function has returned.
Sometimes it may be necessary to signal some asynchronous event to
ECLiPSe, for example to implement a time-out. To do this one
posts a named event to ECLiPSe. At the next synchronous point
within the eclipse execution, the handler for that event is
/* C++ code, possibly within a signal handler */
/* ECLiPSe code */
:- set_event_handler(timeout, handle_timeout/1).
2.3.3 The yield-resume model
Although implicitly yielding control when a set of goals succeeds
or fails is often enough, it is possible to explicitly yield
control to the C++ level. This is done with the
predicate. This yields control to the calling C++ program.
The arguments are used for passing data to C++ and from C++.
When yield/2 is called within ECLiPSe code, the
function returns the value
EC_yield so one can recognise this case.
The data passed out via the first argument of yield/2
can be accessed from C++ via the
EC_ref argument to
The data received in the second argument of yield/2 is either
the list of posted goals, or an
EC_word passed as an input
In this example the compound term
out(1,2) is passed to C++.
If we had previously called:
result = EC_resume(FromEclipse);
result would be
out(1,2). If then we resumed execution with:
result = EC_resume(EC_atom("ok"),FromEclipse);
then the variable
InData on the ECLiPSe side
would be set to the atom 'ok'.
2.3.4 Summary of EC_resume() arguments
EC_resume() can be called with two optional arguments. An
input argument that is an
EC_word and an output that is an
If the input argument is omitted, input is taken as the list of posted
goals. Otherwise the input to ECLiPSe is exactly that argument.
If the output argument is present, its content depends on the value
EC_resume(). If it returns
EC_succeed it is
the choicepoint identifier. If it returns
EC_yield It is the
first argument to the yield/2 goal. If it returns
it is not modified.