[m-users.] Confusion over try goal determinism.
Sean Charles (emacstheviking)
objitsu at gmail.com
Sun Nov 19 22:08:33 AEDT 2023
Thank you Julien,
I have solved my problem, not sure if I *totally* understand what with me being a bit slow and all that but here goes....
Firstly, I found a small bug, in my tail-call in the predicate merth_session_() I was calling back to the parent predicate, merth_session/4, without the underscore on the end, the 'aux' predicate I guess, from Prolog hackery days. I actually removed that call as it, with the try catch etc the control flow requirements changed a little, the bug was found by the compiler because I had had to change the merth_session/4 to cc_multi and so calling back to the cc_multi predicate from the det aux. p[redicate raised the error.
Then, in my main/2 predicate I now have this:
S0 = merth_init_with(tokens(L)),
S1 = S0 ^merth_mode := interp_mode,
promise_equivalent_solutions [!:IO] merth_session(S1, _, !IO).
Currently I don't care about the final state of the session, although this particular project is going to form a part of my transpiler, it's a stack based FORTH type dialect I've been pondering on for quite a while, hence the name MERTH, or MErcury foRTH. It makes me laugh, too. It currently has these words and grows daily, I am currently working on control flow stack stiff for IF THEN ELSE
* + - -ROT . .S / 0< 0<= 0<> 0= 0> 0>= : ; < <= <> = > >= ?DUP BYE CR DROP DUP EMIT FALSE NIP OVER ROT SEE SPACE SPACES SWAP TRACE TRUE TUCK T{ VMTRACE WORDS }T
I digress!
Then I had to change the declaration of merth_session/4 to be this:
:- pred merth_session(mstate::in, mstate::out, io::di, io::uo) is cc_multi.
merth_session(!S, !IO) :-
(
try [ io(!IO) ]
merth_session_(!S, !IO)
then
!S ^loop_count := loop_count(!.S)+1,
( if !.S ^exit = no then
merth_session(!S, !IO)
else
true
)
catch stack_depth(X, Y) ->
console_error("Stack depth! %i %i", [ i(X), i(Y)], !IO)
catch stack_type_int(T) ->
console_error("Wrong type, int expected, got %s",
[ s(string(T)) ], !IO)
catch compile_time_word(Word) ->
console_error("%s is compile time only", [ s(Word) ], !IO)
catch interpret_time_word(Word) ->
console_error("%s is interpret time only", [ s(Word) ], !IO)
).
This is because, if I understand what Julien tells me, is because in the manual it says 'A try goal has determinism cc_multi.' which then means that the containing predicate also has to be declared as cc_multi, hence the need for the promise_equivalent_solutions in main.
And finally, the auxiliary predicate is a simple deterministic one:
:- pred merth_session_(mstate::in, mstate::out, io::di, io::uo) is det.
merth_session_(!S, !IO) :-
:
:
So, I figured it out, I *think* I understand why I did what I did, but as usual if anybody has the time and energy to expand / add further details I am always very happy to read such details!
Thanks Julien.
:)
Sean
PS. Have I ever said I love Mercury even though it confounds me at times?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/users/attachments/20231119/5851c1f9/attachment.html>
More information about the users
mailing list