prologfreezecoroutineprolog-coroutining

How to write/edit own coroutines in Prolog?


I would like to build my own coroutines in Prolog. I'd like to add some extra functionalities.


Solution

  • One possible solution would be to use the term-expansion mechanism provided by some Prolog systems and Logtalk to rewrite calls to e.g. the freeze/2 predicate to do the extra steps you want. One must be careful, however, to not expand a call to a predicate into another goal that calls the same predicate as goal-expansion is recursively applied until a fixed-point is reached. The Logtalk implementation of the term-expansion mechanism makes it easy to avoid this trap (with the additional advantage of portability as you can use Logtalk with most Prolog systems) by using a compiler bypass control construct, {}/1. A silly example would be:

    :- object(my_expansions,
        implements(expanding)).
    
        goal_expansion(
            freeze(Var,Goal),
            (   write('If you instantiate me, I will run away!\n'),
                {freeze(Var,Goal)},  % goal will not be further expanded
                write('Bye!\n')
            )
        ).
    
    :- end_object.
    

    This object can then be used as an hook object for the compilation of source files containing calls to freeze/2 that you want to expand. Something like (assuming that the object above is saved in a file with the name my_expansions.lgt and that the source file that you want to expand is named source.lgt):

    ?- logtalk_load(my_expansions), logtalk_load(source, [hook(my_expansions)]).
    

    For full details see the Logtalk documentation and examples.

    There might be a clean way that I'm not aware of doing the same using the a Prolog system own term-expansion mechanism implementation. Anyone?