(playground) use module import of overridden predicate
Jean-Luc-Picard-2021 opened this issue · 4 comments
While trying to port:
fCube: an efficient prover for Intuitionistic propositional Logic
in Rextester - Vidal-Rosset, 2022
https://rextester.com/SEOO25214
I was running into a predicate lookup problem. I tried the following:
tab(X) :- Y is X, io_basic:tab(Y).
But the top-level cannot resolved the overridden tab/1:
?- tab(2*3+1).
{ERROR: No handle found for thrown exception
error(type_error(integer,2*3+1),'io_basic:tab'/1-1)}
This works in other Prolog systems that have a module system.
Yes, you can do it no problem:
:- module(foo,[main/0,tab/1]).
main :-
tab(4),
write(a).
tab(X) :- Y is X, io_basic:tab(Y).
and now:
?- use_module('/draft.pl').
{Compiling /draft.pl
WARNING: (lns 2-5) Unqualified predicate call to tab/1 assumed to local version, calls to predicate imported from io_basic must be qualified
}
yes
?- draft:tab(3+2), write(a).
a
yes
If you want to avoid the warning when compiling the module you can do:
:- module(foo,[main/0,tab/1]).
main :-
foo:tab(4),
write(a).
tab(X) :- Y is X, io_basic:tab(Y).
or use use :- redefining(tab/1).
:- module(_,[main/0,tab/1]).
main :-
tab(4),
write(a).
:- redefining(tab/1).
tab(X) :- Y is X, io_basic:tab(Y).
In the top level:
?- use_module('/draft.pl').
yes
?- draft:tab(3+2), write(a).
a
yes
Note that predicates are never overridden, so the problem may be in the predicate visibility rules.
:- module(a, [foo/1]).
foo(a).
:- module(b, [foo/1]).
foo(b).
?- use_module(a).
yes
?- foo(X).
X = a ?
yes
?- use_module(b).
yes
?- foo(X).
X = a ?
yes
As @mherme says both a:foo(X)
and b:foo(X)
work, but module visibility rules in Ciao resolves foo(X)
as a:foo(X)
. Perhaps b:foo(X)
would be more natural? Changing it is not trivial but can do it, specially if this is expected in other languages.
With Novacore and Liblets its not needed anymore.
Can put into swi/core.pl to make it run elsewhere.
OK. I'll mark this as 'wontfix' and cite from another issue.