-
Notifications
You must be signed in to change notification settings - Fork 32
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
Modules? #292
Comments
It would be awesome to have modules! Some thoughts: So the use_module logic could go like this for
Maybe 2 shoud go before 1 here, I'm not sure what the ideal priority would be. |
Regarding the problem on p := prolog.New(nil, nil)
p.Exec(`
:- module(foo, [hi/0]).
hi :- write(hi), nl.
`)
p.Exec(`
:- initialization(hi).
`) |
p := prolog.New(nil, nil)
p.Exec(`
:- module(foo, [hi/0]).
hi :- write(hi), nl.
`)
p.Exec(`
:- use_module(foo, _, [hi/0]).
:- initialization(hi).
`) |
SICStus (which is also the successor of Quintus, the originator of SICStus modules) is definitely best to follow. A true weakness in SICStus is that all operators are global, but then this leads to a more conservative usage of operators. Scryer mostly follows SICStus but permits operators to be local or exported. SWI has some mixed-up system which has received some SICStus compatibility about 10 years ago. But there are still differences. In case of doubt, go for SICStus. Sometimes SWI looks better because it adds some module prefixes dynamically, this comes at a cost in particular for goal expansion. ISO permits a lot of instances of different module systems. Within 13211-2 there are already two (the one you seem to mean, and in 6.4.4.2 IF/Prolog's). Even SICStus could be seen as such an instance (which at first sight is something different, but... it's complicated). |
Placeholder if err := p.Exec(`human(?).`, "socrates"); err != nil { // Same as p.Exec(`human("socrates").`)
panic(err)
} |
What is the purpose of these placeholders? I note that they seem to be present at the top level. Are they also present in other situations?
|
I've implemented placeholders to make it safe and easy to pass Go values to Prolog. Also, it helps providing a standard Currently, It's present in every query and prolog text. We can change the code and suppress it for queries/prolog texts without extra Go arguments. That way, we'll be able to use |
So you say, your top level is special, but otherwise, the |
I mean, This can be easily fixed with the change I described above. |
What's in a module?
Footnotes
|
ISO/IEC 13211-2 6.2 says "built-in predicates and control constructs are visible everywhere and do not require module qualification." To achieve this, SICStus and others have a special module for control constructs and built-in predicates for each module to import from.
I found a problem here. If we bootstrap This won't be a problem in SICStus bc its operators don't belong to modules. I should check how other implementations solve it. :- use_module(prolog, [...]).
writeq(S, Term) :-
write_term(S, Term, [quoted(true), numbervar(true)]). % The calling context is `prolog`. Footnotes |
Most of the time operators are local because they are just needed within this module. I am not sure that it makes sense to make Look at SWI:
|
If I read it right, ISO/IEC 13211-2 says SWI's $ swipl
Welcome to SWI-Prolog (threaded, 64 bits, version 8.2.4)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.
For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).
?- use_module(library(clpfd),[]).
true.
?- module(clpfd).
true.
clpfd: ?- writeq(#=(X,Y)).
#=(_2270,_2272)
true.
clpfd: ?- current_output(S), write_term(S, #=(X,Y), [module(clpfd)]).
_3740#=_3742
S = <stream>(0x104a6e7b8). |
Just a general observation on 13211-2, I think I mentioned it somewhere already. Please look at 6.4.4.2 which shows you an entirely different module system. So 13211-2 is not as specific and as precise as you seem to interpret it. And, in case of doubt, leaning toward SICStus is definitely a safer bet. |
I'm still in a process of learning what module is in Prolog and using ISO/IEC 13211-2 as one of the resources. I'm not following it word by word anyways. One thing I learnt from it is a module has not only predicates but also operators and flags. Regarding operators and flags, SICStus looks an outlier. I should check more implementations though. I don't feel that it is a safe bet to follow SICStus on this particular matter so far. |
ISO/IEC 13211-2 was published 2000. Even in 2006, many of the aspects of relevance where not yet understood. Think of compatibility with call/N. And the only system that implemented 6.4.4.2 was IF (already in 1996). 6.4.4.1 was never implemented anywhere. You can see from the syntax error in the second line that at least that code never ran on a 13211-1 conforming processor. |
With this module :- module(modop, [wq/1]).
:- op(700, xfx, <>).
wq(X) :-
writeq(X). SWI $ swipl
Welcome to SWI-Prolog (threaded, 64 bits, version 8.2.4)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.
For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).
?- [modop].
true.
?- modop:wq(<>(a, b)), nl.
<>(a,b)
true. Scryer $ scryer-prolog
?- [modop].
true.
?- modop:wq(<>(a, b)), nl.
<>(a,b)
true. Trealla $ ../trealla/tpl
Trealla Prolog (c) Infradig 2020-2023, v2.24.19
?- [modop].
true.
?- modop:wq(<>(a, b)), nl.
<>(a,b)
true. Ciao $ ~/.ciaoroot/v1.22.0-m7/build/bin/ciao
Ciao 1.22.0 [DARWINaarch64]
?- [modop].
yes
?- modop:wq(<>(a, b)), nl.
a<>b
yes |
You are "importing" the module For the specific example: First look whether or not SWI:
I cannot see such a distinction in Ciao. Also, how would you implement a |
Thank you for the correction. Ciao's operators are not local to modules, I guess. Below is my hallucinated interpretation: A utility I found SWI had wqnl(X) :-
calling_context(M),
M:writeq(X),
nl. Also, writeq(Term) :-
calling_context(M),
current_output(S),
M:writeq(S, Term).
writeq(Stream, Term) :-
calling_context(M),
M:write_term(Stream, Term, [quoted(true), numbervars(true)]). You can try the current module implementation with $ go install github.com/ichiban/prolog/cmd/1pl@module
go: downloading github.com/ichiban/prolog v1.1.4-0.20230818110238-9673e7fb4a9e
$ $(go env GOPATH)/bin/1pl
Top level for ichiban/prolog v1.1.4-0.20230818110238-9673e7fb4a9e
This is for testing purposes only!
See https://github.com/ichiban/prolog for more details.
Type Ctrl-C or 'halt.' to exit.
?- calling_context(M).
M = user.
?- |
It really is a good idea to just stick to SICStus. In addition, local operators and the ability to export operators from a module. So like in Scryer. But no more than that. What you call now calling_context/1 in SWI comes from its previous module system which has been given up. So it is really a waste of time to look into this. Why simulate some arcane properties. |
I'm trying to figure out what SICStus module system really is. Unlike ISO/IEC 13211-2, it looks to me like module as a compilation unit- directives are there for telling how to read and compile the module file and no effect at run-time. (This could be because of my misunderstanding of ISO/IEC 13211-1 7.4.2.b, a directive specifies "the format and Syntax of read-terms in Prolog text.") My hunch is that the key is lack of context sensitivity (other than meta predicates) at run-time in contrast of context-sensitive directives at compile-time. So, predicates :- module(foo, [init/0, foo/0]).
init :- use_module(bar).
foo. :- module(bar, [bar/0]).
bar. SWI is different here and Ciao didn't work as is yet Scryer and Trealla did it as I expected.
|
This usage is not the most common one. So I would not be surprised if there are differences maybe also within the same system. In fact, use_module should be seen rather as a directive and not as a goal. On the other hand, looking at SICStus it has a meta predicate declaration for
(I added a (As a general remark, it really helps to state explicitly what you expect or not. Currently it is clear to me, but some years later it may not.) |
SICStus has the notion of a type-in module which can be changed with |
The Quintus module system looks like the de facto standard, yet I found that there's a slight problem adopting it. Its modules are coupled with files (module files) and
use_module/[1,2,3]
take filenames as an argument.In this library, a Prolog text doesn't have to be in a file. So, if we define a module in
Exec()
, we can't import the module withuse_module/[1,2,3]
. Also, a Go-defined module can't be imported withuse_module[1,2,3]
because it doesn't have a module file.We might also need
import/[1,2]
in ISO/IEC 13211-2:2000 to avoid this.The text was updated successfully, but these errors were encountered: