Discussion:
PAC library for develop version available
Kuniaki Mukai
2014-09-26 16:01:14 UTC
Permalink
Hi,

I have uploaded PAC library at

http://web.sfc.keio.ac.jp/~mukai/pac-lite.zip

The PAC library defines term_expression/2, which implements following featues
on SWI-Prolog *develop* version (> V7.1).

1. anonymous predicates as meta-arguments,
2. a limited functional expressions including applications, and
3. regular expressions in DCG phrases.

To try PAC library:
1. unzip pac-lite.zip
2. % swipl -f '<path-to-the>/pac-lite/start-pac'
3. run sample queries in the test-log.pl

I have announced the PAC library already, for instance, at a thread on
"[SWIPL] Conditional equations with a directive for flipping
arguments." Still no documentation is available except the uploaded
source files. Although I have been using the PAC library for years
for many small applications, many bugs may be there.

The zip file contains:

Readme this file
engine.pl helper predicates
expand-etc.pl expand etcetra (for, repeat, sed, ...)
expand-pac.pl expand (compile) pac expressions
expand-word.pl expand words in phrase (e.g. regex)
interval-boole.pl compute boolean operation on intervals for regex.
math.pl demo on conditional equations
misc.pl misc
op.pl operaters declaration.
pac-init.pl initialization for pac.
pac-loader.pl loadging files
pac.pl include file for term_expansion
reduce.pl making generated goals slim
start-pac.pl main
test-log.pl sample queries.


I will appreciate for any comment or feedback.

Regards,

Kuniaki Mukai




-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 496 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <https://lists.iai.uni-bonn.de/pipermail/swi-prolog/attachments/20140927/c91aceb9/signature.asc>
Michael Hendricks
2014-09-26 19:15:08 UTC
Permalink
Post by Kuniaki Mukai
I have uploaded PAC library at
http://web.sfc.keio.ac.jp/~mukai/pac-lite.zip
This sounds very useful. It would be great if you could bundle this up as a
package as described at http://swi-prolog.org/howto/Pack.html

That would allow others to run pack_install(pac) at the top level to
install and reuse the code locally.

Cheers.

Michael
-------------- next part --------------
HTML attachment scrubbed and removed
Kuniaki Mukai
2014-09-27 01:41:28 UTC
Permalink
Post by Michael Hendricks
Post by Kuniaki Mukai
I have uploaded PAC library at
http://web.sfc.keio.ac.jp/~mukai/pac-lite.zip
This sounds very useful. It would be great if you could bundle this up as a
package as described at http://swi-prolog.org/howto/Pack.html
Thank you for the pointer. Having visited the page, I think it is
one of the most useful and necessary information for me now.
I will learn and try the packaging system after your advice.

Kuniaki


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 496 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <https://lists.iai.uni-bonn.de/pipermail/swi-prolog/attachments/20140927/7fc73fd7/signature.asc>
Kuniaki Mukai
2014-09-27 18:04:09 UTC
Permalink
Hi,

I met an error message while "pack_install"-ing on SWI-Prolog V7.22
via GIT on Mac OSX Mavericks:

% Contacting server at http://www.swi-prolog.org/pack/query ... ok
Install ***@0.3.2 from https://github.com/samer--
/prolog/raw/master/callgraph/release/callgraph-0.3.2.tgz Y/n?
dyld: lazy symbol binding failed: Symbol not found:
_archive_read_support_filter_all

Expected in: flat namespace

Rembering similar troubles in the past, I have edited the build file of the
pl-develop directory so that LIBRARY_PATH and CPATH does not refer to
/usr/lib :

# On MacOS you need this to get some libraries from Homebrew (not Macports)
if [ "`uname`" = Darwin ]; then
export LIBRARY_PATH=/usr/local/Cellar/readline/6.2.4/lib:/usr/local/Cellar/gmp/5.1.3/lib:/usr/local/Cellar/libarchive/3.1.2/lib
export CPATH=/usr/local/Cellar/gmp/5.1.3/include:/usr/local/Cellar/readline/6.2.4/include:/usr/local/Cellar/libarchive/3.1.2/include

After this change of the build file, the pack_install has worked fine.
Excluding "/usr/lib/" seems a typical workaround for Mac OSX
SWI-Prolog users. I am not sure on the exact reason why
such editing works, but I hope this note will be useful for mac prolog users
who is suffering from similar trouble.

Kuniaki
Post by Kuniaki Mukai
Post by Michael Hendricks
Post by Kuniaki Mukai
I have uploaded PAC library at
http://web.sfc.keio.ac.jp/~mukai/pac-lite.zip
This sounds very useful. It would be great if you could bundle this up as a
package as described at http://swi-prolog.org/howto/Pack.html
Thank you for the pointer. Having visited the page, I think it is
one of the most useful and necessary information for me now.
I will learn and try the packaging system after your advice.
Kuniaki
Kuniaki Mukai
2014-09-29 20:26:53 UTC
Permalink
Hi,

I have uploaded two packages at http://www.swi-prolog.org/pack/list,
but unfortunately one of which is a wrong bundle.
Is there a way to cancel a package ? The other package
is a recovery for the wrong one.

Thank you for your help in advance.

Regards

Kuniaki Mukai
Jan Wielemaker
2014-09-30 07:11:16 UTC
Permalink
Hi Kuniaki,
Post by Kuniaki Mukai
Hi,
I have uploaded two packages at http://www.swi-prolog.org/pack/list,
but unfortunately one of which is a wrong bundle.
Is there a way to cancel a package ? The other package
is a recovery for the wrong one.
Pity. The way to recover from a wrong upload is simply to upload
a new version with a higher version number and then install that
yourself. I think that "pac" is a better name as you call it
like that a long time and "predutils" is just a very generic
and non-descriptive name.

Once that is settled, I can throw the one you want to get rid
of out of the DB by hand. For now, the pack refuses to be
analysed. I'm sure someone will help sorting that out!

Congrats with your first pack!

Cheers --- Jan
Post by Kuniaki Mukai
Thank you for your help in advance.
Regards
Kuniaki Mukai
_______________________________________________
SWI-Prolog mailing list
https://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog
Kuniaki Mukai
2014-10-01 06:52:40 UTC
Permalink
Hi Jan,

For name of the package I have choosed "pac",
following suggestion of you and Michael. Thanks.

The url of the latest version is
http://web.sfc.keio.ac.jp/~mukai/pac-0.5.5.tgz
which is also the initial version.

However, the packaging system indicates some failing to process pack "pac":
http://www.swi-prolog.org/pack/list?p=pac

Did I something wrong on packaging system ? I am afraid so.

But, I have installed successfully "pac" package
on my machine by using the full URL:

?- pack_install("http://web.sfc.keio.ac.jp/~mukai/pac-0.5.5.tgz").

And, the "pac" package is working fine as I expected.

On the other hand, the query with package name without location fails with
exception error message:

?- pack_install(pac).

ERROR: open/3: source_sink `'pac/pack.pl'' does not
exist (No such file or directory)

Exception: (6) prolog_pack:pack_install(pac) ?

I have no idea what to do with this problem.


Kuniaki
Post by Jan Wielemaker
Hi Kuniaki,
Post by Kuniaki Mukai
Hi,
I have uploaded two packages at http://www.swi-prolog.org/pack/list,
but unfortunately one of which is a wrong bundle.
Is there a way to cancel a package ? The other package
is a recovery for the wrong one.
Pity. The way to recover from a wrong upload is simply to upload
a new version with a higher version number and then install that
yourself. I think that "pac" is a better name as you call it
like that a long time and "predutils" is just a very generic
and non-descriptive name.
Once that is settled, I can throw the one you want to get rid
of out of the DB by hand. For now, the pack refuses to be
analysed. I'm sure someone will help sorting that out!
Congrats with your first pack!
Cheers --- Jan
Post by Kuniaki Mukai
Thank you for your help in advance.
Regards
Kuniaki Mukai
_______________________________________________
SWI-Prolog mailing list
https://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog
_______________________________________________
SWI-Prolog mailing list
https://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 496 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <https://lists.iai.uni-bonn.de/pipermail/swi-prolog/attachments/20141001/cc49a0f5/signature.asc>
Kuniaki Mukai
2014-09-30 06:22:44 UTC
Permalink
Hi Michael,

I have managed to install "predutils" package, which I am calling pac library.
(ERROR message below is for minor updates.)

% swipl
Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.1.23-28-g70f014a)
Copyright (c) 1990-2014 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).

?- [library(predutils)].
true.

?- module(pac).
true.

pac: ?- phrase(w("[^\\n]*$", A), `abc\n`, R).
A = [97, 98, 99],
R = [] ;
A = [97, 98, 99],
R = [] ;
false.

pac: ?- val((X\X)@1, X).
X = 1 .

pac: ?- maplist(pred([X, Y, X-Y]), [1,2,3],[a,b,c], R).
R = [1-a, 2-b, 3-c].

pac: ?-

Anyway I have to write user manual for predutils package.

BTW, the above query "?- module(pac)." is not necessary on my
local non_package version, but as for installed package,
without changing module, the above three pac queries
do not work, with "undefined val/2", for example.
Maybe I am missing something related module behaviours in packaging
of SWI-Prolog. I am new to packaging, and it is not easy task for me,
though I am enjoying a little also.

I am looking forward to exploring into your regex package soon.

Thank you for introducing packaging to me.


Kuniaki Mukai
Post by Michael Hendricks
Post by Kuniaki Mukai
I have uploaded PAC library at
http://web.sfc.keio.ac.jp/~mukai/pac-lite.zip
This sounds very useful. It would be great if you could bundle this up as a
package as described at http://swi-prolog.org/howto/Pack.html
That would allow others to run pack_install(pac) at the top level to
install and reuse the code locally.
Cheers.
Michael
-------------- next part --------------
HTML attachment scrubbed and removed
_______________________________________________
SWI-Prolog mailing list
https://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 496 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <https://lists.iai.uni-bonn.de/pipermail/swi-prolog/attachments/20140930/dbc54227/signature.asc>
Michael Hendricks
2014-09-30 14:29:43 UTC
Permalink
Post by Kuniaki Mukai
I have managed to install "predutils" package, which I am calling pac library.
(ERROR message below is for minor updates.)
Congratulations on getting it working. When I tried to install the pack, I
got an error message saying that the tarball contents had changed. I
verified this by comparing the current tarball's SHA1
(2a551f0bd4fa491d03e2433eaf706e570b1e16d2) against the one listed on the
website (5679d4f08644a9d5eb1b5e50cb3b9e29ad129d1a).

If you need to change the contents of your pack, modify pack.pl to
increment the version number. Then create a new tarball named after that
version number. This preserves a history each pack and assures users that
they're downloading the right code.
Post by Kuniaki Mukai
?- [library(predutils)].
true.
For what it's worth, I prefer the pack name "pac" as you tried with your
initial upload. If you upload your next version as "pac", let Jan know and
he can delete the "predutils" pack.

?- module(pac).
Post by Kuniaki Mukai
true.
This is needed because library(predutils) doesn't export the predicates
from module pac. The documentation on modules should help:
http://swi-prolog.org/pldoc/man?section=modules

I hope that helps.
--
Michael
-------------- next part --------------
HTML attachment scrubbed and removed
Kuniaki Mukai
2014-10-01 06:49:25 UTC
Permalink
Post by Michael Hendricks
Post by Kuniaki Mukai
I have managed to install "predutils" package, which I am calling pac library.
(ERROR message below is for minor updates.)
Congratulations on getting it working. When I tried to install the pack, I
got an error message saying that the tarball contents had changed. I
verified this by comparing the current tarball's SHA1
(2a551f0bd4fa491d03e2433eaf706e570b1e16d2) against the one listed on the
website (5679d4f08644a9d5eb1b5e50cb3b9e29ad129d1a).
If you need to change the contents of your pack, modify pack.pl to
increment the version number. Then create a new tarball named after that
version number. This preserves a history each pack and assures users that
they're downloading the right code.
Thanks. I will keep this in mind.
Post by Michael Hendricks
Post by Kuniaki Mukai
?- [library(predutils)].
true.
For what it's worth, I prefer the pack name "pac" as you tried with your
initial upload. If you upload your next version as "pac", let Jan know and
he can delete the "predutils" pack.
I have named "pac". Thanks.

Let me explain about the acronym"
In my mind, "pac" means "Parametric Anonymous Clauses",
As in Prolog a predicate is a set of (definite) clauses,
so "pac" is nearly an acronym for "parametric anonymous predicate".
"pac" package allows recursive predicate definitions like append/3.

This feature has been used in "pac" to compile regular expressions
in DCG phrases. By "parametric" I mean "globals".
I will be happy if "pac" will contribute to a coherent
extension of DCG phrases or meta argument expansion in Prolog.
Post by Michael Hendricks
?- module(pac).
Post by Kuniaki Mukai
true.
This is needed because library(predutils) doesn't export the predicates
http://swi-prolog.org/pldoc/man?section=modules
Thanks. I will reread it. Once I had some difficulty to understand
basic notions on module something like difference between "namespace"
or "predicatebase". So I skipped it as my usual way.
I feel I have been paying to the skipping.
For instance, it is only recent (few hours ago !) for me to notice that
assert(a:(b:-c)) is not equivalent to assert(a:b :- c).

Kuniaki
Post by Michael Hendricks
I hope that helps.
--
Michael
-------------- next part --------------
HTML attachment scrubbed and removed
_______________________________________________
SWI-Prolog mailing list
https://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 496 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <https://lists.iai.uni-bonn.de/pipermail/swi-prolog/attachments/20141001/e51dd9bf/signature.asc>
Jan Wielemaker
2014-10-01 07:29:16 UTC
Permalink
Hi Kuniaki,

I've deleted the predutils registration.

?- pack_install(pac) works fine here.

I didn't really look into the details why the pack is not processed,
but quite likely it has to do with modulariry and operator usage. The
pac package adds a lot of really generically named files to your library,
a number of which are not modules and seem to fulfil diverse roles.

Things that server example purposes should go into a directory
`examples` instead of into the prolog directory. Files there are
not analysed and do not end up in your (extended) Prolog library,
so you can put there whatever you like.

Helper files should also be banned from the prolog directory, especially
if they have generic names. Many classical programs have a file `util.pl`.
If we allow for that habbit it packs, library(util) will be ambiguous.
The normal solution is to create a subdirectory, so you get

pac
pac/prolog/pac.pl
pac/prolog/pac/reduce.pl

Any .pl file below pac/prolog should be a module file and should use
:- use_module(...) to get its requirements. The helper modules in
prolog/pac should typically start with e.g., :- module(pac_reduce, ...)
to avoid name conflicts. Modules should export whatever needs to be
accessible from the outside, including operators. Code using modules
should import the module using use_module/1 or use_module/2 and use
non-qualified calls.

A good thing to read is Michael Richter's tutorial on modules.

Writing libraries is a different thing than writing a program in user
space ... I hope this helps

--- Jan
Post by Kuniaki Mukai
Post by Michael Hendricks
This is needed because library(predutils) doesn't export the predicates
http://swi-prolog.org/pldoc/man?section=modules
Thanks. I will reread it. Once I had some difficulty to understand
basic notions on module something like difference between "namespace"
or "predicatebase". So I skipped it as my usual way.
I feel I have been paying to the skipping.
For instance, it is only recent (few hours ago !) for me to notice that
assert(a:(b:-c)) is not equivalent to assert(a:b :- c).
Kuniaki Mukai
2014-10-01 12:29:20 UTC
Permalink
Hi Jan,
Post by Jan Wielemaker
Hi Kuniaki,
I've deleted the predutils registration.
Thank you for spending the extra care.
Post by Jan Wielemaker
?- pack_install(pac) works fine here.
I didn't really look into the details why the pack is not processed,
but quite likely it has to do with modulariry and operator usage.
That sounds likely. In fact, I am on the way to make the package
modular. I know how to do, except the pac top level (user) behaviour
around "expand_query". It will take some time.
Post by Jan Wielemaker
The pac package adds a lot of really generically named files to your library,
a number of which are not modules and seem to fulfil diverse roles.
Things that server example purposes should go into a directory
`examples` instead of into the prolog directory. Files there are
not analysed and do not end up in your (extended) Prolog library,
so you can put there whatever you like.
I see.
Post by Jan Wielemaker
Helper files should also be banned from the prolog directory, especially
if they have generic names. Many classical programs have a file `util.pl`.
If we allow for that habbit it packs, library(util) will be ambiguous.
The normal solution is to create a subdirectory, so you get
pac
pac/prolog/pac.pl
pac/prolog/pac/reduce.pl
I see.
Post by Jan Wielemaker
Any .pl file below pac/prolog should be a module file and should use
:- use_module(...) to get its requirements. The helper modules in
prolog/pac should typically start with e.g., :- module(pac_reduce, ...)
to avoid name conflicts. Modules should export whatever needs to be
accessible from the outside, including operators. Code using modules
should import the module using use_module/1 or use_module/2 and use
non-qualified calls.
I see well.
Post by Jan Wielemaker
A good thing to read is Michael Richter's tutorial on modules.
Writing libraries is a different thing than writing a program in user
space ... I hope this helps
Thanks for the quick and long reply. I think it is not difficult
to transform the "pac" package into fully modular one in a week,
using emacs grep heavily. The library should restrict interference to others
as minimal as possible. Of course, I agree on this.

Kuniaki
Post by Jan Wielemaker
--- Jan
Post by Kuniaki Mukai
Post by Michael Hendricks
This is needed because library(predutils) doesn't export the predicates
http://swi-prolog.org/pldoc/man?section=modules
Thanks. I will reread it. Once I had some difficulty to understand
basic notions on module something like difference between "namespace"
or "predicatebase". So I skipped it as my usual way.
I feel I have been paying to the skipping.
For instance, it is only recent (few hours ago !) for me to notice that
assert(a:(b:-c)) is not equivalent to assert(a:b :- c).
_______________________________________________
SWI-Prolog mailing list
https://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 496 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <https://lists.iai.uni-bonn.de/pipermail/swi-prolog/attachments/20141001/76ef1955/signature.asc>
Kuniaki Mukai
2014-10-02 12:31:25 UTC
Permalink
Hi Jan,

I have updated pac to V-0.5.6 from V-0.5.5, following the guideline
in the tutorial in your previous message:
1) no predicates defined in pac can be called without module prefix qualififcation,
2) operator declarations are local to pac,
3) renaming module names attaching prefix "pac_" to avoid possible
confusions with that of other packages.
Post by Jan Wielemaker
Post by Jan Wielemaker
Writing libraries is a different thing than writing a program in user
space ... I hope this helps
Deep words. I feel I have seen something of library builder's invisible efforts
for others happy life.

By the way, I would like to ask you an urgent and maybe stupid
question about module. I thought exported names can be used from any
oother contexts, i.e., globally, like builtin append/3. But a simple
experiment shows that it is not the case. So my question is: in
what contexts an exported name can be used without putting module
prefix before the name ? I have read the recommended document, but I am
afraid I have missed the point again.

Kuniaki
Post by Jan Wielemaker
Hi Kuniaki,
I've deleted the predutils registration.
?- pack_install(pac) works fine here.
I didn't really look into the details why the pack is not processed,
but quite likely it has to do with modulariry and operator usage. The
pac package adds a lot of really generically named files to your library,
a number of which are not modules and seem to fulfil diverse roles.
Things that server example purposes should go into a directory
`examples` instead of into the prolog directory. Files there are
not analysed and do not end up in your (extended) Prolog library,
so you can put there whatever you like.
Helper files should also be banned from the prolog directory, especially
if they have generic names. Many classical programs have a file `util.pl`.
If we allow for that habbit it packs, library(util) will be ambiguous.
The normal solution is to create a subdirectory, so you get
pac
pac/prolog/pac.pl
pac/prolog/pac/reduce.pl
Any .pl file below pac/prolog should be a module file and should use
:- use_module(...) to get its requirements. The helper modules in
prolog/pac should typically start with e.g., :- module(pac_reduce, ...)
to avoid name conflicts. Modules should export whatever needs to be
accessible from the outside, including operators. Code using modules
should import the module using use_module/1 or use_module/2 and use
non-qualified calls.
A good thing to read is Michael Richter's tutorial on modules.
Writing libraries is a different thing than writing a program in user
space ... I hope this helps
--- Jan
Post by Jan Wielemaker
Post by Michael Hendricks
This is needed because library(predutils) doesn't export the predicates
http://swi-prolog.org/pldoc/man?section=modules
Thanks. I will reread it. Once I had some difficulty to understand
basic notions on module something like difference between "namespace"
or "predicatebase". So I skipped it as my usual way.
I feel I have been paying to the skipping.
For instance, it is only recent (few hours ago !) for me to notice that
assert(a:(b:-c)) is not equivalent to assert(a:b :- c).
_______________________________________________
SWI-Prolog mailing list
https://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 496 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <https://lists.iai.uni-bonn.de/pipermail/swi-prolog/attachments/20141002/db5e2ec5/signature.asc>
Jan Wielemaker
2014-10-02 14:23:39 UTC
Permalink
Post by Kuniaki Mukai
Post by Jan Wielemaker
Writing libraries is a different thing than writing a program in user
space ... I hope this helps
Deep words. I feel I have seen something of library builder's invisible efforts
for others happy life.
On the other hand, writing libraries isn't too different from writing
large application where you need code structuring. Once you get the
hang of it, the extra structuring rules help you more than they hinder
you.
Post by Kuniaki Mukai
By the way, I would like to ask you an urgent and maybe stupid
question about module. I thought exported names can be used from any
oother contexts, i.e., globally, like builtin append/3. But a simple
experiment shows that it is not the case. So my question is: in
what contexts an exported name can be used without putting module
prefix before the name ? I have read the recommended document, but I am
afraid I have missed the point again.
For most Prolog systems, a use_module/1 means you can use the code from
the module you are importing from only. SWI-Prolog modules have a notion
of `default modules`: if a predicate cannot be found in a module, it will
try its default module (recursively). All modules default to `user`, while
`user` defaults to `system`. So, code that you write in (or import into)
user is visible in all modules, but can be locally overruled. B.t.w.,
system library files default directly to `system`, so you cannot modify
their behaviour by writing things in `user`. Operator inheritance follows
the same rules.

The defaulting scheme can be modified, which allows for defining other
visibility and reuse models.

Cheers --- Jan
Kuniaki Mukai
2014-10-02 15:35:23 UTC
Permalink
Hi Jan,
Post by Jan Wielemaker
Post by Kuniaki Mukai
Post by Jan Wielemaker
Writing libraries is a different thing than writing a program in user
space ... I hope this helps
Deep words. I feel I have seen something of library builder's invisible efforts
for others happy life.
On the other hand, writing libraries isn't too different from writing
large application where you need code structuring. Once you get the
hang of it, the extra structuring rules help you more than they hinder
you.
Post by Kuniaki Mukai
By the way, I would like to ask you an urgent and maybe stupid
question about module. I thought exported names can be used from any
oother contexts, i.e., globally, like builtin append/3. But a simple
experiment shows that it is not the case. So my question is: in
what contexts an exported name can be used without putting module
prefix before the name ? I have read the recommended document, but I am
afraid I have missed the point again.
For most Prolog systems, a use_module/1 means you can use the code from
the module you are importing from only. SWI-Prolog modules have a notion
of `default modules`: if a predicate cannot be found in a module, it will
try its default module (recursively). All modules default to `user`, while
`user` defaults to `system`. So, code that you write in (or import into)
user is visible in all modules, but can be locally overruled. B.t.w.,
system library files default directly to `system`, so you cannot modify
their behaviour by writing things in `user`. Operator inheritance follows
the same rules.
The defaulting scheme can be modified, which allows for defining other
visibility and reuse models.
Thank you for your clear answer. However, to be honest,
what I wanted to know is something on opposite direction
of the 'default'.

Although your answer has made me clear, let me put my intended
question in more concrete way. Suppose two module files "mod_a.pl" and
a `child` module "mod_b.pl" defined as follow:

%%%% file mod_a.pl %%%
:- module(mod_a, [hello/0]).
:- use_module(mod_b).
hello :- writeln('hello from ma.').

%%%% file mod_b.pl %%%
:- module(mod_b, [world/0]).
world :- writeln('world from mb').

% ls
mod_b.pl mod_a.pl

So setting the situation, I got the log below. Of course,
that log is what everyone expects except me.

% swipl
Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.1.23-28-g70f014a)
Copyright (c) 1990-2014 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).

?- use_module(mod_a).
true.

?- hello.
hello from ma.
true.

?- world.
Correct to: "mod_b:world"?
Please answer 'y' or 'n'?
ERROR: '$execute_goal2'/2: Undefined procedure: world/0
ERROR: However, there are definitions for:
ERROR: mod_a:world/0
ERROR: mod_b:world/0
Exception: (6) world ? abort
% Execution Aborted


I believed wrongly that imported predicates from "child modules" may get
global under some context. In fact, I expected no error message for that
query.

My question was really stupid, but I appreciate a lot for
your taking time. I hope I am the only such a prologer.


Kuniaki
Post by Jan Wielemaker
Cheers --- Jan
_______________________________________________
SWI-Prolog mailing list
https://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 496 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <https://lists.iai.uni-bonn.de/pipermail/swi-prolog/attachments/20141003/1d8d38f4/signature.asc>
Jan Wielemaker
2014-10-02 16:01:42 UTC
Permalink
Post by Kuniaki Mukai
Although your answer has made me clear, let me put my intended
question in more concrete way. Suppose two module files "mod_a.pl" and
Note that there is not really a notion of `child' modules. Modules
can use each other (even mutually, by importing each other).
Post by Kuniaki Mukai
%%%% file mod_a.pl %%%
:- module(mod_a, [hello/0]).
:- use_module(mod_b).
hello :- writeln('hello from ma.').
%%%% file mod_b.pl %%%
:- module(mod_b, [world/0]).
world :- writeln('world from mb').
% ls
mod_b.pl mod_a.pl
?- use_module(mod_a).
true.
?- hello.
hello from ma.
true.
?- world.
Correct to: "mod_b:world"?
Please answer 'y' or 'n'?
ERROR: '$execute_goal2'/2: Undefined procedure: world/0
ERROR: mod_a:world/0
ERROR: mod_b:world/0
Exception: (6) world ? abort
% Execution Aborted
I believed wrongly that imported predicates from "child modules" may get
global under some context. In fact, I expected no error message for that
query.
That is indeed not what happens. If you want that though, you can do two
things: export world/0 also from mod_a.pl, as in

:- module(mod_a, [hello/0, world/0]).
:- use_module(mod_b).
hello :- writeln('hello from ma.').

Or re-export:

:- module(mod_a, [hello/0).
:- reexport(mod_b).
hello :- writeln('hello from ma.').

rexport/1 is a simple use_module/1, followed by adding all
public predicates of the imported module to the export list
of the importing module.

In most situations, I'd go for the first solution with explicit
export of the imported predicates, as this makes it much easier
for the reader to see what you get from a module. The reexport
was mainly added to create libraries derived from similar libraries
for portability reasons. So, if I want to write a YAP compatible
library(lists), I can of course start from scratch. But, 95% is
the same anyway, so I can write a library like this:

:- module(yap_lists, [ extra-stuff, ...]).
:- reexport(library(lists), except([ incompatible stuff ]).

<definitions for the extra and incompatible stuff>

Now, I've saved myself a lot of typing and at the same time
make it obvious what is different between the two modules.
Post by Kuniaki Mukai
My question was really stupid, but I appreciate a lot for
your taking time. I hope I am the only such a prologer.
Quite unlikely :-)

Cheers --- Jan
Kuniaki Mukai
2014-10-03 04:52:07 UTC
Permalink
Hi Jan,

You have made me clear on the module system, which is more than I expected.
Thank you. Let me summarize your tutorial in my favourite terms
of graph theory.

The set of current modules form a DG (directed graph; possibly cyclic,
and not necessarily connected. ) A node (= a module) m is a direct
successor of a node m' if and only if m' has `:- use_module(m)'
directive (at the head).

Given a node m, the module system looks into the direct successors of
m in the DG, but does *NOT* look into others transitively along the
`use_module` links.

( I thought wrongly that it does `transitive search' along `use_module'
links.)

Now things look much simpler than I thought.
Your tutorial has recovered the hard time lost of mine
for reading articles on modules. Thank you again.

Kuniaki
Post by Jan Wielemaker
Post by Kuniaki Mukai
Although your answer has made me clear, let me put my intended
question in more concrete way. Suppose two module files "mod_a.pl" and
Note that there is not really a notion of `child' modules. Modules
can use each other (even mutually, by importing each other).
Post by Kuniaki Mukai
%%%% file mod_a.pl %%%
:- module(mod_a, [hello/0]).
:- use_module(mod_b).
hello :- writeln('hello from ma.').
%%%% file mod_b.pl %%%
:- module(mod_b, [world/0]).
world :- writeln('world from mb').
% ls
mod_b.pl mod_a.pl
?- use_module(mod_a).
true.
?- hello.
hello from ma.
true.
?- world.
Correct to: "mod_b:world"?
Please answer 'y' or 'n'?
ERROR: '$execute_goal2'/2: Undefined procedure: world/0
ERROR: mod_a:world/0
ERROR: mod_b:world/0
Exception: (6) world ? abort
% Execution Aborted
I believed wrongly that imported predicates from "child modules" may get
global under some context. In fact, I expected no error message for that
query.
That is indeed not what happens. If you want that though, you can do two
things: export world/0 also from mod_a.pl, as in
:- module(mod_a, [hello/0, world/0]).
:- use_module(mod_b).
hello :- writeln('hello from ma.').
:- module(mod_a, [hello/0).
:- reexport(mod_b).
hello :- writeln('hello from ma.').
rexport/1 is a simple use_module/1, followed by adding all
public predicates of the imported module to the export list
of the importing module.
In most situations, I'd go for the first solution with explicit
export of the imported predicates, as this makes it much easier
for the reader to see what you get from a module. The reexport
was mainly added to create libraries derived from similar libraries
for portability reasons. So, if I want to write a YAP compatible
library(lists), I can of course start from scratch. But, 95% is
:- module(yap_lists, [ extra-stuff, ...]).
:- reexport(library(lists), except([ incompatible stuff ]).
<definitions for the extra and incompatible stuff>
Now, I've saved myself a lot of typing and at the same time
make it obvious what is different between the two modules.
Post by Kuniaki Mukai
My question was really stupid, but I appreciate a lot for
your taking time. I hope I am the only such a prologer.
Quite unlikely :-)
Cheers --- Jan
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 496 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <https://lists.iai.uni-bonn.de/pipermail/swi-prolog/attachments/20141003/605578cf/signature.asc>
Richard A. O'Keefe
2014-10-03 03:24:56 UTC
Permalink
'use_module' comes from Quintus Prolog.
The way it was intended to be used was

:- use_module(Module_Name, [
Imported_Predicate_1/Arity_1,
...,
Imported_Predicate_n/Arity_n
]).

It was considered to be important for software maintenance
that you should explicitly list all the predicates you
needed from the module. Having done this, the imported
predicates are then available *without* requiring any prefix.

This is like the way you do

from fractions import Fraction

in Python, after which you use fractions.Fraction as just
plain Fraction.

This is dual to the way that a :- module directive lists
all the things *exported* from a module.

The idea was that *all* the stuff relating to modules
(:- module, :- use_module, :- meta_predicate) should be
at the very top of a file, and the rest of the file
should as much as possible look as though modules did
not exist.
Kuniaki Mukai
2014-10-03 05:15:53 UTC
Permalink
Hi Richard,
Post by Richard A. O'Keefe
'use_module' comes from Quintus Prolog.
The way it was intended to be used was
:- use_module(Module_Name, [
Imported_Predicate_1/Arity_1,
...,
Imported_Predicate_n/Arity_n
]).
It was considered to be important for software maintenance
that you should explicitly list all the predicates you
needed from the module. Having done this, the imported
predicates are then available *without* requiring any prefix.
This is like the way you do
from fractions import Fraction
in Python, after which you use fractions.Fraction as just
plain Fraction.
This is dual to the way that a :- module directive lists
all the things *exported* from a module.
The idea was that *all* the stuff relating to modules
(:- module, :- use_module, :- meta_predicate) should be
at the very top of a file, and the rest of the file
should as much as possible look as though modules did
not exist.
Interesting. Thank you for fresh historical information
and original idea on module system of Quintus Prolog.

One question. I want to put meta_predicate directive close
at the definition like this.

:- meta_predicate my_flip(2, ?, ?).
my_flip(F, X, Y):- call(F, Y, X).

(Though I am not sure whether the directive is necessary
in this particular case).

Is this a bad practice ? Or are you saying on `header information`
for use of external predicates, which sounds reasonable principle.

Kuniaki
Post by Richard A. O'Keefe
_______________________________________________
SWI-Prolog mailing list
https://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 496 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <https://lists.iai.uni-bonn.de/pipermail/swi-prolog/attachments/20141003/91fc2200/signature.asc>
Richard A. O'Keefe
2014-10-03 06:11:39 UTC
Permalink
Post by Kuniaki Mukai
Post by Richard A. O'Keefe
The idea was that *all* the stuff relating to modules
(:- module, :- use_module, :- meta_predicate) should be
at the very top of a file, and the rest of the file
should as much as possible look as though modules did
not exist.
Interesting. Thank you for fresh historical information
and original idea on module system of Quintus Prolog.
One question. I want to put meta_predicate directive close
at the definition like this.
In order to handle circular dependencies between modules,
it was necessary to be able to read and process all the
linkage information without having to read all of a file.
In QP it was quite important therefore to put :-meta_predicate
declarations *for exported predicates* at the top. Others
just had to go before their first use.

Jan can tell you whether this is still necessary or useful in
SWI Prolog.
Post by Kuniaki Mukai
:- meta_predicate my_flip(2, ?, ?).
my_flip(F, X, Y):- call(F, Y, X).
That makes perfect sense in a multipass implementation.
Quintus Prolog was a single pass implementation:
- while reading a term does not fail
expand it
for each clause in the expansion
apply module-related transformations
compile it
add it to memory (or the .qof file)

An arguably *better* scheme would read an entire file
into memory and check it and process it before storing
any part of it (the way the Erlang compiler processes
Erlang files), but that wasn't the way Prolog worked
before Quintus, and customers depended on immediate-
incremental processing.

And that meant meta-predicates had to have their
interface declared before any definition or call.

The problem with putting the :- meta_predicate
declaration immediately before the definition is
"what if there is a *call* even earlier?" How
can you have mutually recursive meta-predicates if
:- meta_predicate declarations can follow calls?

Again, I do not speak for SWI Prolog here. For all I
know, now that we no longer have to live with 4 MB
machines, Jan may have decided to process whole files.
(ISO Prolog certainly jettisoned historic features in
order to make that straightforward.) Whether it's
portable to take advantage of that is another matter.
Post by Kuniaki Mukai
(Though I am not sure whether the directive is necessary
in this particular case).
To the best of my knowledge SWI does no meta-predicate
inference.
Post by Kuniaki Mukai
Is this a bad practice ? Or are you saying on `header information`
for use of external predicates, which sounds reasonable principle.
What I am saying is
- if a predicate is exported, include it in the :-meta_predicate
declaration at the beginning of the file.
- if a predicate is not exported, make sure its :-meda_predicate
declaration precedes the first use. (And a good way to do
_that_ is to put it before any predicate definitions or
initialisation commands.)

It was historic practice before Quintus Prolog to put
:- mode declarations for all the predicates in a file
at the beginning of that file. More precisely, it was
the practice to write a single :- mode declaration
listing all the predicates, typically in alphabetic
order, so that the user had a handy list of predicates.

:- meta_predicate declarations are just :- mode
declarations with a few extra options.

If we were designing Prolog these days, when people carry around
lightweight laptops with 8 GB of memory, we'd probably do what
Haskell and Erlang do, and that is parse and check a whole module
before acting on any part of it

SWI Prolog 7.x has cut the umbilical cord of backwards
compatibility, so it would not be out of place for SWI 8.x
to adopt a whole-file-processing approach. It always did
feel a little bit wrong that a declarative language should
have any dependency on the order in which declarations and
definitions were written.
Jan Wielemaker
2014-10-03 09:43:07 UTC
Permalink
Post by Richard A. O'Keefe
In order to handle circular dependencies between modules,
it was necessary to be able to read and process all the
linkage information without having to read all of a file.
In QP it was quite important therefore to put :-meta_predicate
declarations *for exported predicates* at the top. Others
just had to go before their first use.
Jan can tell you whether this is still necessary or useful in
SWI Prolog.
No and yes. Well, it is more subtle. SWI-Prolog does not need
meta-predicate declarations to be in any specific order for getting the
module qualification of terms correct. It doesn't even need the
declaration before the definition, but it does need it before the first
call. The module qualification is in the startup code of the
meta-predicate itself. The startup code also deals with stuff like
indexing and is generated lazily at the first call. This is achieved by
setting the initial startup code to S_VIRGIN. The implementation of
S_VIRGIN considers the clauses and predicate properties and replaces
itself with a sequence that realises the proper startup for this
predicate.

It is useful because the cross-referencer that drives the semantic
highlighting for the built-in editor works pretty much like Quintus:
it reads (only) the headers of the imported modules.

It is also useful to deal with goal-expansion. If a predicate has an
argument with the meta-specification `0`, expand_goal/2 will be called
for that argument (recursively). This means that if your code relies on
goal expansion, you need to make sure that meta predicate declarations
are known before the first usage. I consider that pretty unfortunate.
I see various ways out:

- Enforce Quintus-like ordering, emitting an error if these are
not respected (i.e., the system will assume that a predicate
is not a meta-predicate on first reference and raise a warning
if it finds a meta-predicate declaration).
- Implement multi-pass compilation, so the order doesn't matter
anymore. More below.
- Drop goal_expansion/2 and introduce inline predicates. ECLiPSe
went that way. Now, missing a declaration will only have some
impact on performance (no inlining). We could even dynamically
repair that by rewriting the calling clause at the moment that
we discover that we are making a call to the implementation of
an inline predicate.
Post by Richard A. O'Keefe
Post by Kuniaki Mukai
:- meta_predicate my_flip(2, ?, ?).
my_flip(F, X, Y):- call(F, Y, X).
That makes perfect sense in a multipass implementation.
- while reading a term does not fail
expand it
for each clause in the expansion
apply module-related transformations
compile it
add it to memory (or the .qof file)
An arguably *better* scheme would read an entire file
into memory and check it and process it before storing
any part of it (the way the Erlang compiler processes
Erlang files), but that wasn't the way Prolog worked
before Quintus, and customers depended on immediate-
incremental processing.
And that meant meta-predicates had to have their
interface declared before any definition or call.
The problem with putting the :- meta_predicate
declaration immediately before the definition is
"what if there is a *call* even earlier?" How
can you have mutually recursive meta-predicates if
:- meta_predicate declarations can follow calls?
Again, I do not speak for SWI Prolog here. For all I
know, now that we no longer have to live with 4 MB
machines, Jan may have decided to process whole files.
(ISO Prolog certainly jettisoned historic features in
order to make that straightforward.) Whether it's
portable to take advantage of that is another matter.
Post by Kuniaki Mukai
(Though I am not sure whether the directive is necessary
in this particular case).
To the best of my knowledge SWI does no meta-predicate
inference.
What do you mean by `meta-predicate inference'? It qualifies
arguments, its list_undefined/0 (called by make/0 and check/0)
use meta-predicate declaration to compute what can be called,
etc. What would be missing?
Post by Richard A. O'Keefe
Post by Kuniaki Mukai
Is this a bad practice ? Or are you saying on `header information`
for use of external predicates, which sounds reasonable principle.
What I am saying is
- if a predicate is exported, include it in the :-meta_predicate
declaration at the beginning of the file.
- if a predicate is not exported, make sure its :-meda_predicate
declaration precedes the first use. (And a good way to do
_that_ is to put it before any predicate definitions or
initialisation commands.)
I think that is a good style guide. For SWI-Prolog, you could opt to
place meta-predicate declarations of local meta-predicates before their
definition. Note that technically you don't need these declarations
anyway, but they help the code analysis tools (although code analysis
will find the simple cases itself thanks to code contributed by the
group of Guenter Kniesel).
Post by Richard A. O'Keefe
It was historic practice before Quintus Prolog to put
:- mode declarations for all the predicates in a file
at the beginning of that file. More precisely, it was
the practice to write a single :- mode declaration
listing all the predicates, typically in alphabetic
order, so that the user had a handy list of predicates.
:- meta_predicate declarations are just :- mode
declarations with a few extra options.
We have PlDoc for documenting the mode and modern editors typically
provide some overview of the content of a file.
Post by Richard A. O'Keefe
If we were designing Prolog these days, when people carry around
lightweight laptops with 8 GB of memory, we'd probably do what
Haskell and Erlang do, and that is parse and check a whole module
before acting on any part of it
SWI Prolog 7.x has cut the umbilical cord of backwards
compatibility, so it would not be out of place for SWI 8.x
to adopt a whole-file-processing approach. It always did
feel a little bit wrong that a declarative language should
have any dependency on the order in which declarations and
definitions were written.
One could surely argue for that. There are also some counter
arguments.

* Prolog programs may not be just code, but can also be
(potentially huge) amounts of data. We want as little
as possible overhead loading that.
* Especially when prototyping, it is so nice that you don't
have to specify all dependencies upfront. Some people
like exhaustive use_module/2 declarations to specify
exactly what they want, others prefer use_module/1,
import the whole lot into `user` and rely on module
defaulting or rely on auto loading. Depending on
the project, organization of the development team
and probably many other factors, there are advantages
in each of these approaches. Anything except using
use_module/2 however forces the system to make
assumptions about the properties of referenced
predicates.
* It allows for local definition of source transformation
and generation rules without the need for boilerplate.

I think that my long-term plan is to properly implement code inlining,
so we can do `:- inline maplist/2.` instead of the ugly
library(apply_macros). Inlining avoids visibility ambiguity issues of
goal expansion and guarantees consistent semantics. It also simplifies
source-level debugging. Possibly we can compile inlined code in such a
way that the original code remains accessible, so your call to maplist
becomes something like this internally:

( inlining
-> 'generated_pred_XXX'(...)
; maplist(XXX, ...)
).

This would make SWI-Prolog source code completely order independent,
while allowing for single-pass compilation and even dynamically fixing
your code if the definition of an inlined predicate has changed.

I think that working towards a safe fully dynamic system is a promising
route. (SWI-)Prolog is already quite strong in this area, but currently
there are a few places where you need to get things in the right order
and this confuses people.

Cheers --- Jan

Richard A. O'Keefe
2014-10-01 22:48:35 UTC
Permalink
Post by Kuniaki Mukai
Let me explain about the acronym"
In my mind, "pac" means "Parametric Anonymous Clauses",
As in Prolog a predicate is a set of (definite) clauses,
so "pac" is nearly an acronym for "parametric anonymous predicate".
"pac" package allows recursive predicate definitions like append/3.
Drat. When I saw the name "PAC" I hoped it had something
to do with Probably Approximately Correct learning (see
http://www.cs.iastate.edu/~honavar/pac.pdf), a major theory
of machine learning.

"Parametric" really shouldn't mean "globals".
Kuniaki Mukai
2014-10-02 04:32:48 UTC
Permalink
Post by Richard A. O'Keefe
Post by Kuniaki Mukai
Let me explain about the acronym"
In my mind, "pac" means "Parametric Anonymous Clauses",
As in Prolog a predicate is a set of (definite) clauses,
so "pac" is nearly an acronym for "parametric anonymous predicate".
"pac" package allows recursive predicate definitions like append/3.
Drat. When I saw the name "PAC" I hoped it had something
to do with Probably Approximately Correct learning (see
http://www.cs.iastate.edu/~honavar/pac.pdf), a major theory
of machine learning.
Thank you for comment. I should have been careful.
Yes, PAC learning is now major, seems still rapidly developing.
In fact, I am interested in the their recent
mathematical frameworks.
Post by Richard A. O'Keefe
"Parametric" really shouldn't mean "globals".
In general, differences between usages of the following terms
are not not clear for me:
parameter
globals
variable
indeterminate
argument (place).

As far as my "PAC" concerns,
the first argument of pred/2 and rec/2 term is simply called "parameter",
and the occurrence of the "pred" and "rec" term in meta argument context
is replaced by an appropriately generated unary term with the parameter, and
with the definition of the unary term being asserted as
prolog standard predicate. For me, the behaviour of the parameter
looks very much like that of free variables of lambda calculus, (aside unification).
That is my reason for using "parametric" as "free".

Kuniaki
Post by Richard A. O'Keefe
_______________________________________________
SWI-Prolog mailing list
https://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 496 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <https://lists.iai.uni-bonn.de/pipermail/swi-prolog/attachments/20141002/ab53879b/signature.asc>
Loading...