Open jjtolton opened 1 week ago
I've been programming in Prolog for couple years now and I never had to use library(cont)
, so it is a grey area for me. My feeling is that it is useful mostly for "low-level" Prolog (like described here) and with an advent of attributed variables usefulness of it has declined.
Regarding your question all predicates that start with $
are not supposed to be called by user code and should be used through wrappers. If there is no wrapper then this predicate counts as not-implemented, so I'm not surprised that it doesn't work as expected. The only implemented predicates are shift/1
and reset/3
.
Also I see that Cont
is a free variable, and it shouldn't be so, it must be unified with "continuation"
Also I see that
Cont
is a free variable, and it shouldn't be so, it must be unified with "continuation"
Ugh, yeah, you are absolutely right. Fixed the code.
I've been programming in Prolog for couple years now and I never had to use
library(cont)
, so it is a grey area for me. My feeling is that it is useful mostly for "low-level" Prolog (like described here) and with an advent of attributed variables usefulness of it has declined.Regarding your question all predicates that start with
$
are not supposed to be called by user code and should be used through wrappers. If there is no wrapper then this predicate counts as not-implemented, so I'm not surprised that it doesn't work as expected. The only implemented predicates areshift/1
andreset/3
.
You could be right -- it's hard to say until I understand how to use it better. The paper has some really interesting examples:
yield(Term) :-
shift(yield(Term)).
init_iterator(Goal,Iterator) :-
reset(Goal,Cont,YE),
( YE = yield(Element) ->
Iterator = next(Element,Cont)
;
Iterator = done
).
next(next(Element,Cont),Element,Iterator) :-
init_iterator(call_continuation(Cont),Iterator).
ask(X) :-
shift(ask(X)).
with_read(Goal) :-
reset(Goal,Cont,Term),
( Term = ask(X) ->
read(X),
with_read(call_continuation(Cont))
;
true
).
with_list(L,Goal) :-
reset(Goal,Cont,Term),
( Term = ask(X) ->
L = [X|T],
with_list(T,call_continuation(Cont))
;
true
).
transduce(IG,TG) :-
reset(TG,ContT,TermT),
transduce_(TermT,ContT,IG).
transduce_(0,_,_).
transduce_(yield(NValue),ContT,IG)) :-
yield(NValue),
transduce(IG,call_continuation(ContT)).
transduce_(ask(Value),ContT,IG) :-
reset(IG,ContI,TermI),
( TermI == 0 ->
true
;
TermI = yield(Value),
transduce(call_continuation(ContI),call_continuation(ContT))
).
doubler :-
ask(Value),
NValue is Value * 2,
yield(NValue),
doubler.
?- play(sum(Sum),transduce(fromList([1,2]),doubler)).
%@ Sum = 6.
These are just a few of the patterns mentioned in the paper, some of which I recognized as being quite useful/powerful! I'd be curious to know how much effort it would take to get call_continuation
working :thinking:
Regarding your question all predicates that start with
$
are not supposed to be called by user code and should be used through wrappers. If there is no wrapper then this predicate counts as not-implemented, so I'm not surprised that it doesn't work as expected. The only implemented predicates areshift/1
andreset/3
.
Good point, changed to feature request.
As mentioned in https://github.com/mthom/scryer-prolog/issues/2537#issue-2512093075, the paper is the only source of documentation for the
cont
library right now, so simply based on this I would assume the current behavior qualifies as an issue.Edit: fixed code per @hurufu 's observation
Edit1: Changing the code to the type expected by
$call_continuation
/1 does not work either:Edit2: Per @hurufu 's observation, converted this to a feature request rather than an "issue"