Re: Possible bug in setarg/3
Jan Wielemaker <[email protected]>
| Newsgroups | gmane.comp.ai.prolog.swi |
|---|---|
| Message-ID | <[email protected]> |
On 11/14/2013 10:44 AM, Michael Ben Yosef wrote: > Hi, > > I believe I've discovered a bug in setarg/3, or at least a behaviour I > really don't understand. The following session on Ubuntu 12.04 x86_64 > demonstrates a test case for it: > > ---BEGIN--- > $ cat bug.pl > bug(A, b(A,C)) :- > arg(1, A, C), > setarg(1, A, x). > > bug_new(a(_)). > $ swipl > Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 6.5.2) > Copyright (c) 1990-2013 University of Amsterdam, VU Amsterdam > SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software, > and you are welcome to redistribute it under certain conditions. > Please visit http://www.swi-prolog.org for details. > > For help, use ?- help(Topic). or ?- apropos(Word). > > ?- [bug]. > % bug compiled 0.00 sec, 3 clauses > true. > > ?- A = a(_), bug(A, B). % Behaves as expected: > > A = a(x), > B = b(a(x), _G2326). > > ?- bug_new(A), bug(A, B). % Behaves unexpectedly: > > A = a(x), > B = b(a(x), x). > > ?- > ---END--- > > Why is x unified with C in bug/2 in the second query (and not in the first one)? That is a nice question :-) It shows one of the many weird behaviours of setarg/3. The first arg/3 call unifies the variable in a(_) with the one in b(_,_). In Prolog, that means there will be a `reference pointer' from one to the other. The direction of this pointer (a->b or b->a) depends on the age of the term. So, if it is a->b and we set arg 1 of a to x, b remains a variable. If it is b->a and we set arg1 of to x, both have the value x. I must admit I never realised this. I guess it means you should typically ensure that an arg on which you want to do setarg/3 should not be aliased to anything else. In other words, generally do not use variables as initial value for args to use with setarg/3. Cheers --- Jan