Re: freeze/2 and nb_setarg/3 interaction

Michael Hendricks <[email protected]> Thu, 10 Apr 2014 10:16:52 -0600
Newsgroups gmane.comp.ai.prolog.swi
Message-ID <CAFHuXuZPt54fxGNPbt6dUQhSrhw9Ny2mmhHU9Cy8DN5zxkA_aw@mail.gmail.com>
Hi Alan,

On Thu, Apr 10, 2014 at 9:56 AM, Alan Baljeu <[email protected]> wrote:

> I'm not convinced SWI is wrong here.  I suspect in your 'broken' case
> that the second writeln is actually writing [H|T].
>

I suspect so too, which is why it's broken.


> It also seems odd that given X is already [H|T] you would attempt
> setarg(1,X,H), which is a no-op.
>

In the "broken" example, by the time nb_setarg/3 is called, H (or T) has a
nonvar value.  That value is copied with duplicate_term/2 (according to the
docs).  So the value permanently stored in the X term should no longer have
any relation to the variable H.  However, on backtracking, the copied value
is discarded and a variable returns.

I've tried explicitly copying the value in H (or T) using duplicate_term/2
or copy_term_nat/2 before calling nb_setarg/3, but I get the same results.
 I even get variables on backtracking if the "broken" example uses these
goals in freeze/2:

nb_setarg(1,X,a)
nb_setarg(1,X,[b,c])

Somehow nb_setarg/3 is being undone on backtracking when freeze/2 is
involved.

If instead you initialized X=[_|_] the code would make a little more sense.
>  In fact, it works.
>

It works when H and T are set explicitly but not when they're set
indirectly via X=[a,b,c].  I think that demonstrates this is a strange
interaction between freeze/2 and nb_setarg/3.  Or I'm very confused about
how those predicates are supposed to work.

-- 
Michael
-------------- next part --------------
HTML attachment scrubbed and removed