Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Heisenbug involving attributed variables, lists and (is)/2 #2706

Open
bakaq opened this issue Dec 14, 2024 · 0 comments
Open

Heisenbug involving attributed variables, lists and (is)/2 #2706

bakaq opened this issue Dec 14, 2024 · 0 comments

Comments

@bakaq
Copy link
Contributor

bakaq commented Dec 14, 2024

Stumbled on this one in bakaq/constrained.pl#16 (comment). The most I could isolate it is this:

:- use_module(library(atts)).
:- use_module(library(format)).
:- use_module(library(diag)).
:- use_module(library(lists)).

:- attribute a/1.

verify_attributes(_,_, []).

asdf1([_|Xs], N) :-
    N1 is N - 1,
    asdf1(Xs, N1).

asdf2([_|Xs], N) :-
    true,
    N1 is N - 1,
    asdf2(Xs, N1).

% This errors.
test1 :-
    put_atts(A, a(1)),
    asdf1(A, 1).

% But this loops, as expected.
test2 :-
    put_atts(A, a(1)),
    asdf2(A, 1).
?- test1.
   error(type_error(evaluable,user/0),(is)/2).
?- test2.
   % Loops.

The decompilation of the predicates is as follows:

% asdf1/2
allocate(2).
get_list(level(shallow),x(1)).
unify_void(1).
unify_variable(y(1)).
put_variable(y(2),1).
sub(x(2),1,1).
call(is,2).
put_value(y(1),1).
put_value(y(2),2).
deallocate.
execute(asdf1,2).

% asdf2/2
allocate(3).
get_list(level(shallow),x(1)).
unify_void(1).
unify_variable(y(1)).
get_variable(y(2),2).
call(true,0).
put_variable(y(3),1).
sub(y(2),1,1).
call(is,2).
put_value(y(1),1).
put_value(y(3),2).
deallocate.
execute(asdf2,2).

I don't know enough about the WAM to understand this properly, but I guess the problem is the sub(x(2),1,1). (which gets corrected to sub(y(2),1,1). in the version with the extra true). It seems that only 1 x register is allocated but it's trying to use the second one, while in the version with an extra true it uses the correct y(2) register.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant