[m-users.] Problems with store and mostly unique/unique predicates.

Mark Brown mark at mercurylang.org
Sat Feb 8 12:09:27 AEDT 2014


On Sat, Feb 8, 2014 at 11:50 AM, Mark Brown <mark at mercurylang.org> wrote:
> On Sat, Feb 8, 2014 at 9:26 AM, Bartosz Witkowski
> <bartosz.witkowski at like-a-boss.net> wrote:
>> On Fri, 7 Feb 2014, Julien Fischer wrote:
>>> (1) if semi_pred/2 does not actually update !A then you could use a unique-input (ui)
>>> mode in the semidet predicate, e.g.
>>>
>>>     uses_semi(!A) :-
>>>        pred1(A!),
>>>        ( if semi_pred(!.A) then
>>>        true
>>>        else
>>>       true
>>>        ),
>>>       pred2(!A)
>>>
>>>     :- pred semi_pred(A::ui) is semidet.
>>>
>>> (2) if semi_pred/2 is intended to update the state represented by !A then using
>>> unique modes is the wrong thing to do and you should be using mostly-unique modes
>>> (and a compilation grade that supports trailing).
>>
>> Unfortunately, I'm dealing with the second case. I think I could manage
>> to turn the predicate into a `det` one using an auxiliary variable
>> (using the method I described previously) - which while cumbersome is
>> doable.
>>
>> Then again using the tr_store could be a much better option.
>
> These have different meanings, so you need to figure out which is
> correct for your situation. If, in the case that semi_pred fails, you
> need to ensure that the A value is back in its original state, then
> the tr_store approach would work.
>
> Julien's option (1) can also be applied if you have your own means of
> rolling back any changes prior to failing (like a transaction
> journal).
>

I mean your first option, not Julien's. Viz:

:- pred p1c(bool::out, A::di, A::uo) is det.

p1c(Result, !A) :-
    get_ticket(Ticket, !A),
    % ... do stuff to !A, bind Result
    (
        Result = yes
    ;
        Result = no,
        rollback(Ticket, !A)
    ).

Cheers,
Mark.



More information about the users mailing list