[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