Subject: RE: Predicate Determining the port in which was called.

From: Jan Wielemaker <[email-masked]>
Date: Fri, 11 Aug 2000 12:22:51 +0200

On Fri, 11 Aug 2000, Douglas Miles (Volt Computer) wrote:
>> On Fri, 11 Aug 2000,  Jan Wielemaker wrote:
>> > On Fri, 11 Aug 2000,  Douglas Miles (Volt Computer) wrote:
>> 
>> >
>> >Thats very iteresting about the 
>> >
>> >"call,(exit,redo)*,(deterministic_exit|exit,cut|fail)"
>> >
>> >So there are 3 unique finishing states?
>> >
>> >* deterministic_exit
>> >* exit,cut
>> >* fail
>> 
>> Actually 4: there are also exceptions.  In addition, deterministic
>> exit is a bit vague as sometimes non-deterministic exit could actually
>> have been deterministic, but Prolog may fail to see it (either because
>> it doesn't look at exclusive cases or because hashing yields the same
>> key for two values of the first argument that are actually
>> different).
>> 
>> Altogether, call and fail are easy, and so are exceptions.
>> 
>> With some extremely dirty hacking using prolog_current_frame/1 and
>> prolog_frame_attribute/3 you can at runtime find out about Prolog's
>> notion of the last choice-point.  This is highly non-portable.
>
>When I very first sent mail on this topic, I thought the first advice I'd
>recieve
>was going to involve: prolog_current_frame/1 and prolog_frame_attribute/3.
>If you feel it is a resonable idea for now, i am game and not affraid of
>non-portiblity.

It is not really reasonable in the sense that it is far too messy, but
here you go:

det(G) :-
	G,
	prolog_current_frame(F0),
	(   prolog_frame_attribute(F0, alternative, FB),
	    FB > F0
	->  format('Non-deterministic exit~n', [])
	;   format('Deterministic exit~n', [])
	).

Note this makes assumptions on the fact that
frame-references are offsets in the stack and the stack-layout.

But you can do:

?- det(true).
Deterministic exit

Yes

?- det(between(0, 3, X)).
Non-deterministic exit

X = 0 ;
Non-deterministic exit

X = 1 ;
Non-deterministic exit

X = 2 ;
Deterministic exit

X = 3 ;

No

>> I've seen various proposals around to deal with these issues.  I'm
>> in favour of something along these lines
>> 
>> 	guard(Goal, Event, Guard)
>> 
>> Where, if Event is unified to the event (call, redo, fail, exit,
>> deterministic_exit, cut, exception(Exception)) Guard will be
>> called.
>
>I do like the guard/3 actually I really like it, especially since you are
>supporting deterministic_exit, cut, exit with failure and a unifiable
>exception handler.
>
>> 
>> Should deterministic_exit be the sequence exit, cut?
>> 
>
>Logicly I'd think it could be.  (seems the programmer could have volentarily
>put a cut on the edge of a deterministic exit and )  would we always
>understand an deterministic_exit if it is broken into two separate events or
>would be shown only as one event or perhaps still two:  exit, (cut |
>deterministic_exit)
>
>Richard is definately better to answer this.  

I'm keen to see his historic and technical knowledge on this point.

	Regards --- Jan