Subject: Re: non-determinism & cleanup [was: Fwd: Non-redundant wrappers?]

From: Jan Wielemaker <[email-masked]>
Date: Fri, 19 May 2000 21:51:42 +0200

> > In other words, if you have a deterministic get-first, get-next and
> > cleanup you can use SWI-Prolog foreign code to construct a
> > non-deterministic predicate that is guaranteed to call cleanup.
> 
> ...or open/get/close, as in:
> 
>   generate(A, B) :-
>       open(A, X),
>       generate_1(X, B).
> 
>   generate_1(X, B) :-
>       get(X, B1),    % failure indicates no more Bs
>       (    B = B1
>       ;    generate_1(X, B)
>       ).
> 
>   close(X) :-        % we want this called automatically
> 
> OK, this idiom isn't completely general (?), but it's common enough so I've
> implemented a generic foreign predicate
> 
>   cleanup_open_get_close(OpenPredName, GetPredName, ClosePredName, In, Out) :-
>     % a PL_FA_NONDETERMINISTIC foreign function using PL_call_predicate()
>     % on OpenPredName/2, GetPredName/2, ClosePredName/1
> 
> and have tested it by generating the chars of a file, closing the stream on
> cut etc.
> 
>   file_char(F, C) :-
>       cleanup_open_get_close(p1, p2, p3, F, C).
> 
>   p1(A, X) :-
>       open(A, read, S).
> 
>   p2(X, B) :-
>       get0(X, B),
>       B \== -1.
> 
>   p3(X) :-
>       close(X).
> 
> I'm saving the 'X' state from first call to redo with PL_record(X) - can I
> stash a (maybe not always ground?) term in the context structure safely?

On PL_REDO, the argument vector is the same as on PL_FIRST_CALL.  On
PL_CUTTED, the arguments, except for the context arguments are
undefined.  The context returns whatever you returned from the last
nondeterministic success.  PL_CUTTED is invoked on ! as well as on
exceptions (is there any reason to distinguish?).

	Regards --- Jan