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

Module qualifications not resolved at runtime #2826

Open
bakaq opened this issue Feb 14, 2025 · 4 comments
Open

Module qualifications not resolved at runtime #2826

bakaq opened this issue Feb 14, 2025 · 4 comments

Comments

@bakaq
Copy link
Contributor

bakaq commented Feb 14, 2025

It seems that module qualifications are resolved at compile-time1, and variable module qualifications are just ignored:

%% a.pl
:- module(a, []).

a(1).
?- use_module(a).
   true.
?- [user].
a(2).

?- a:a(A).
   A = 1.
?- a(A).
   A = 2.
?- Module = a, Module:a(A).
   Module = a, A = 2, unexpected.
   Module = a, A = 1. % expected, but not found

This quite limits the kind of things you can do with that, and makes this pattern currently used in the test suite useless, because only the tests visible in the unqualified module are found, instead of only the tests visible in the qualified module (which is the intended behavior).

I found this while adapting that test framework into something to be provided by the Scryer Prolog standard library.

Footnotes

  1. Actually, I think at expansion-time, because if I remember correctly that is when module qualifications are dealt with. I think I even remember seeing the specific code that ignores variables once.

@triska
Copy link
Contributor

triska commented Feb 15, 2025

Regarding the footnote, maybe #2811?

@triska
Copy link
Contributor

triska commented Feb 15, 2025

The WAM instructions look sensible, so there is hope that the issue is limited to the interpreter:

For instance, when I define:

p(M) :-
        M:p.

I get:

?- wam_instructions(p/1, Is), maplist(portray_clause, Is).
dynamic_else(1,inf,0).
put_structure(:,2,x(1)).
set_local_value(x(1)).
set_constant(p).
execute(call,1).

It seems to correctly call (:)/2.

But, I unexpectedly get:

?- p(a).
   error(type_error(atom,... :a),call/0), unexpected.

@UWN
Copy link

UWN commented Feb 15, 2025

Even more so:

?- Module = a, call(Module:a(X)).
   Module = a, X = 2, unexpected.
   Module = a, X = 1. % expected, but not found
?- Module = a, G_0=Module:a(X), G_0.
   Module = a, G_0 = a:a(1), X = 1. % expected

So there is some premature expansion of call/1.

@bakaq
Copy link
Contributor Author

bakaq commented Feb 15, 2025

This seems to be a good workaround for now:

?- Module = a, G0 = Module:a(A), call(G0).
   Module = a, G0 = a:a(1), A = 1.

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

3 participants