Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

multiple files in GNU Prolog?

472 views
Skip to first unread message

krishna...@ccreweb.org

unread,
Oct 15, 2014, 9:30:31 PM10/15/14
to
In SWI Prolog, I can load my knowledge base from multiple files by placing in a single source file, e.g. "all.pl", the statement,

:- [file1, file2, file3, ... ].

and simply consulting the all.pl file from within the swipl environment,

?- [all].

This does not appear to work in GNU Prolog (ver 1.4.4). Is there an alternate way to accomplish the same thing in gprolog?


Krishna Myneni





R Kym Horsell

unread,
Oct 15, 2014, 9:51:00 PM10/15/14
to
Check gprolog directives:

:-include(a).

--
[On "flawed logic" and creeping denialism:]
>It's what I've called elsewhere "creeping denialism". At first the
>unwanted conclusion is rejected by attacking the original work that
>proposed it. Then maybe the observations from that work. But then, as
>other scientists become involved and support the conclusion using
>independent lines of reasoning, those theories must be attacked, too.
>Then the basic methodology of science (e.g. the idea that observations
>supporting predictions are a "good idea"). And eventually even the basic
>concepts of reasoning (e.g. if more than one method reaches the same
>conclusion then the conclusion must be wrong).

>If a theory A predicts B and we observe B then we have evidence
>the theory is true.
There is a consensus that A => B and B is true does not imply anything on A.
-- Paul Aubrin <chu8i...@free.fr>, 08 Jul 2012 12:46:34 GMT

You have been stupid enough to write: "If a theory A predicts B and we
observe B then we have evidence the theory is true" and you are telling
me that pointing your error is some sophistry?
-- Paul Aubrin <chu8i...@free.fr>, 08 Jul 2012 18:36:01 GMT

Making successful predictions is the gold standard of science.
If a theory successfully predicts phenomena that are later observed,
one can be confident that the theory captures something essential
about the real world system.
-- Andrew Dessler, testimony to US Senate, 21 Jan 2014

krishna...@ccreweb.org

unread,
Oct 15, 2014, 11:09:02 PM10/15/14
to
On Wednesday, October 15, 2014 8:51:00 PM UTC-5, kym wrote:
> krishna.myneni@... wrote:
>
> > In SWI Prolog, I can load my knowledge base from multiple files by placing in a single source file, e.g. "all.pl", the statement,
>
> >
>
> > :- [file1, file2, file3, ... ].
>
> >
>
> > and simply consulting the all.pl file from within the swipl environment,
>
> >
>
> > ?- [all].
>
> >
>
> > This does not appear to work in GNU Prolog (ver 1.4.4). Is there an alternate way to accomplish the same thing in gprolog?
>
...

>
> Check gprolog directives:
>
>
>
> :-include(a).
>
>
>
Yes, include(file1), etc. has the desired effect. However, I run into a new problem with gprolog in that it ignores my statements from the other files, beyond the first included from "all.pl" because of "discontinuous predicate" warnings, despite the fact that I have declared in each of the files,

:- multifile([session/5, image/8]).


The files load into the knowledge base without any fuss in SWI Prolog. I can also perform queries.

I am doing a simple database with two types of records, session and image, and for my application (a database of amateur astrophotography images) it makes sense to group sets of records into different files.

--
Krishna Myneni

R Kym Horsell

unread,
Oct 16, 2014, 2:01:40 AM10/16/14
to
krishna...@ccreweb.org wrote:
> On Wednesday, October 15, 2014 8:51:00 PM UTC-5, kym wrote:
>> krishna.myneni@... wrote:
>> > In SWI Prolog, I can load my knowledge base from multiple files by placin
>> > :- [file1, file2, file3, ... ].
>> > and simply consulting the all.pl file from within the swipl environment,
>> > ?- [all].
>> > This does not appear to work in GNU Prolog (ver 1.4.4). Is there an alter
> ...
>> Check gprolog directives:
>> :-include(a).
> Yes, include(file1), etc. has the desired effect. However, I run into a
new problem with gprolog in that it ignores my statements from the other
files, beyond the first included from "all.pl" because of "discontinuous
predicate" warnings, despite the fact that I have declared in each of the
files,
> :- multifile([session/5, image/8]).
> The files load into the knowledge base without any fuss in SWI Prolog. I
can also perform queries.
> I am doing a simple database with two types of records, session and image,
and for my application (a database of amateur astrophotography images) it
makes sense to group sets of records into different files.
> --
> Krishna Myneni


It's spelled discontiguous in gprolog.

--

Ulrich Neumerkel

unread,
Oct 16, 2014, 8:44:05 AM10/16/14
to
krishna...@ccreweb.org writes:
>On Wednesday, October 15, 2014 8:51:00 PM UTC-5, kym wrote:
>> krishna.myneni@... wrote:
>>=20
>> > In SWI Prolog, I can load my knowledge base from multiple files by plac=
>ing in a single source file, e.g. "all.pl", the statement,
>>=20
>> >=20
>>=20
>> > :- [file1, file2, file3, ... ].
>>=20
>> >=20
>>=20
>> > and simply consulting the all.pl file from within the swipl environment=
>,
>>=20
>> >=20
>>=20
>> > ?- [all].
>>=20
>> >=20
>>=20
>> > This does not appear to work in GNU Prolog (ver 1.4.4). Is there an alt=
>ernate way to accomplish the same thing in gprolog?
>>=20
>...
>
>>=20
>> Check gprolog directives:
>>=20
>>=20
>>=20
>> :-include(a).
>>=20
>>=20
>>=20
>Yes, include(file1), etc. has the desired effect. However, I run into a new=
> problem with gprolog in that it ignores my statements from the other files=
>, beyond the first included from "all.pl" because of "discontinuous predica=
>te" warnings, despite the fact that I have declared in each of the files,
>
>:- multifile([session/5, image/8]).
>
>
>The files load into the knowledge base without any fuss in SWI Prolog. I ca=
>n also perform queries.
>
>I am doing a simple database with two types of records, session and image, =
>and for my application (a database of amateur astrophotography images) it m=
>akes sense to group sets of records into different files.

In GNU-Prolog there is no module system. You need to enter all
files you want to have on the top. That is, either you
enter [file1,file2,file3]. interactively at the toplevel, or
with a comand-line switch like --init-goal '[file1,file2,file3]' or
(and that is the most common way how GNU is used) produce
a single stand-alone executable with gplc. See the manual
for more.

The include/1 directive is not very well suited for organizing files.
It means that the file is included literally. The directives

:- include(file1).
:- include(file2).

result in:

session(...). % from file1
image(...). % from file1
session(...). % from file2
image(...). % from file2

and thus session is now discontiguous.

The fact that SWI accepted this without any message is very problematic.
ISO conforming systems like SICStus produce a clean warning. Or warn and
ignore subsequent clauses, like GNU.














Using the directive include/1 for this purpose is quite problema



krishna...@ccreweb.org

unread,
Oct 16, 2014, 10:10:14 AM10/16/14
to
On Thursday, October 16, 2014 7:44:05 AM UTC-5, Ulrich Neumerkel wrote:
...
>
>
> In GNU-Prolog there is no module system. You need to enter all
>
> files you want to have on the top. That is, either you
>
> enter [file1,file2,file3]. interactively at the toplevel, or
>
> with a comand-line switch like --init-goal '[file1,file2,file3]' or
>
> (and that is the most common way how GNU is used) produce
>
> a single stand-alone executable with gplc. See the manual
>
> for more.
>
>
>
> The include/1 directive is not very well suited for organizing files.
>
> It means that the file is included literally. The directives
>
>
>
> :- include(file1).
>
> :- include(file2).
>
>
>
> result in:
>
>
>
> session(...). % from file1
>
> image(...). % from file1
>
> session(...). % from file2
>
> image(...). % from file2
>
>
>
> and thus session is now discontiguous.
>
>
>
> The fact that SWI accepted this without any message is very problematic.
>
> ISO conforming systems like SICStus produce a clean warning. Or warn and
>
> ignore subsequent clauses, like GNU.
>

My understanding is that I am not using Prolog modules, and that SWI Prolog's multifile directive permits non-contiguous use of predicates,

:- multifile([session/5, image/8]).

I understand that non-contiguous rules can be problematic for certain types of use, but my particular use of "session" and "image" are just assertions of facts.

Krishna Myneni

Ulrich Neumerkel

unread,
Oct 16, 2014, 11:20:07 AM10/16/14
to
krishna...@ccreweb.org writes:
>On Thursday, October 16, 2014 7:44:05 AM UTC-5, Ulrich Neumerkel wrote:
>...
>> The fact that SWI accepted this without any message is very problematic.
>> ISO conforming systems like SICStus produce a clean warning. Or warn and
>> ignore subsequent clauses, like GNU.
>
>My understanding is that I am not using Prolog modules, and
>that SWI Prolog's multifile directive permits non-contiguous
>use of predicates,
>
>:- multifile([session/5, image/8]).

I verified your claim about SWI with:

:- multifile([a/0,b/0]).
a.
b.
a.

And yes, there is no warning. But there should be one. Like GNU
does, or SICStus, IF any system that claims ISO conformance.

samp.pl:4: warning: discontiguous predicate a/0 - clause ignored

>I understand that non-contiguous rules can be problematic for
>certain types of use, but my particular use of "session" and
>"image" are just assertions of facts.

It is pretty rare that you want a predicate's definition spread
all over a file. And in your case, there is probably no
reason to do so.

So, you can depend on SWI's ideosyncratic behaviour, or simply
stick to the standard.





Jan Burse

unread,
Oct 16, 2014, 12:13:29 PM10/16/14
to
ulr...@mips.complang.tuwien.ac.at (Ulrich Neumerkel) schrieb:
> :- include(file1).
> :- include(file2).
> The fact that SWI accepted this without any message is
> very problematic.

Works fine on my side:

Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.1.22)
Copyright (c) 1990-2014 University of Amsterdam, VU Amsterdam

?- [user].
:- include('/Users/janburse/Desktop/file1.pl').
:- include('/Users/janburse/Desktop/file2.pl').
Warning: /Users/janburse/Desktop/file2.pl:3:
Clauses of session/1 are not together in the source-file
Warning: /Users/janburse/Desktop/file2.pl:6:
Clauses of image/1 are not together in the source-file

krishna...@ccreweb.org

unread,
Oct 16, 2014, 1:02:41 PM10/16/14
to
On Thursday, October 16, 2014 10:20:07 AM UTC-5, Ulrich Neumerkel wrote:
> krishna...@ccreweb.org writes:
>
...
>
> >My understanding is that I am not using Prolog modules, and
>
> >that SWI Prolog's multifile directive permits non-contiguous
>
> >use of predicates,
>
> >
>
> >:- multifile([session/5, image/8]).
>
>
>
> I verified your claim about SWI with:
>
>
>
> :- multifile([a/0,b/0]).
>
> a.
>
> b.
>
> a.
>
>
>
> And yes, there is no warning. But there should be one. Like GNU
>
> does, or SICStus, IF any system that claims ISO conformance.
>
>
>
> samp.pl:4: warning: discontiguous predicate a/0 - clause ignored
>
>
>
> >I understand that non-contiguous rules can be problematic for
>
> >certain types of use, but my particular use of "session" and
>
> >"image" are just assertions of facts.
>
>
>
> It is pretty rare that you want a predicate's definition spread
>
> all over a file. And in your case, there is probably no
>
> reason to do so.
>
>
>
> So, you can depend on SWI's ideosyncratic behaviour, or simply
>
> stick to the standard.

From my point of view, there is a very good reason to keep the records distributed over several files. Each file corresponds to an observing session, i.e. a particular date and set of instrumentation. In a given file, the details of the session are asserted with the "session" predicate, and following this, the details of each acquired image are asserted by the "image" predicate.

It is possible to combine all of the records and separate the two types, "session" and "image", within one file, but that is very awkward and tedious when information needs to be updated for individual records. I see nothing particularly problematic about SWI Prolog's "multifile" directive. It seems as though it was intended to solve exactly the type of problem arising in my application. Perhaps the problem is that Prolog as a language is not really the correct tool for making this type of a database, in which the records are distributed across multiple files.

It should be noted that SWI Prolog behaves exactly as GNU Prolog when the "multifile" directive is not used. That is, warnings are given and earlier predicates are removed from the knowledge base when another file is included.

Cheers,
Krishna

R Kym Horsell

unread,
Oct 16, 2014, 4:35:00 PM10/16/14
to
AFAIK both swi and g produce appropriate warnings for things.
g even says multifile is ignored.
Which is why you need in g to put in
:- discontiguous([foo/211,bar/42]).
(presumably at the top of "all.pl" or somesuch)
if you plan to have foobar things scattered around different include-ed files.

--
ENGROSSED HOUSE BILL No. 246

A Bill for an act introducing a new mathematical truth and offered as
a contribution to education to be used only by the State of Indiana
free of cost by paying any royalties whatever on the same, provided it
is accepted and adopted by the official action of the Legislature of 1897.

Section -1- Be it enacted by the General Assembly of the State of
Indiana: It has been found that a circular area is to the square on a
line equal to the quadrant of the circumference, as the area of an
equilateral rectangle is to the square on one side. The diameter
employed as the linear unit according to the present rule in computing
the circle's area is entirely wrong, as it represents the circle's
area one and one-fifth times the area of a square whose perimeter is
equal to the circumference of the circle. This is because onefifth
[sic] of the diameter fails to be represented four times in the
circle's circumference. For example: if we multiply the perimeter of a
square by one-fourth of any line one-fifth greater than one side, we
can in like manner make the square's area to appear one-fifth greater
than the fact, as is done by taking the diameter for the linear unit
instead of the quadrant of the circle's circumference.

Jan Burse

unread,
Oct 16, 2014, 5:33:21 PM10/16/14
to
R Kym Horsell schrieb:
> g even says multifile is ignored.

Yes and the documentation is inconsistent, since it says:

multifile(Pred) specifies that the procedure
whose predicate indicator is Pred is a multifle
procedure (the clauses of Pred can reside in
several source files). This directive is only
>>>>> supported by GNU Prolog since version 1.4.0. <<<<<<
http://www.gprolog.org/manual/gprolog.html#sec53

But what one gets is:

GNU Prolog 1.4.4 (64 bits)
Compiled Apr 23 2013, 16:05:07 with cl
By Daniel Diaz
Copyright (C) 1999-2013 Daniel Diaz
| ?- ['C:\\Users\\Jan Burse\\Desktop\\tt\\file1.pl', 'C:\\Users\\Jan
Burse\\Desktop\\tt\\file2.pl'].
compiling C:/Users/Jan Burse/Desktop/tt/file1.pl for byte code...
C:/Users/Jan Burse/Desktop/tt/file1.pl:2: warning: unknown directive
multfile/1 - maybe use initialization/1 - directive ignored
C:/Users/Jan Burse/Desktop/tt/file1.pl:7: warning: unknown directive
multfile/1 - maybe use initialization/1 - directive ignored
C:/Users/Jan Burse/Desktop/tt/file1.pl compiled, 10 lines read - 581
bytes written, 0 ms
compiling C:/Users/Jan Burse/Desktop/tt/file2.pl for byte code...
C:/Users/Jan Burse/Desktop/tt/file2.pl compiled, 10 lines read - 581
bytes written, 0 ms
warning: C:/Users/Jan Burse/Desktop/tt/file2.pl:3: redefining procedure
session/1
C:/Users/Jan Burse/Desktop/tt/file1.pl:3: previous definition
warning: C:/Users/Jan Burse/Desktop/tt/file2.pl:8: redefining procedure
image/1
C:/Users/Jan Burse/Desktop/tt/file1.pl:8: previous definition

Paulo Moura

unread,
Oct 16, 2014, 5:54:49 PM10/16/14
to
multifile/1, NOT multfile/1 !!!

R Kym Horsell

unread,
Oct 16, 2014, 6:26:14 PM10/16/14
to
Jan Burse <janb...@fastmail.fm> wrote:
> R Kym Horsell schrieb:
>> g even says multifile is ignored.
>
> Yes and the documentation is inconsistent, since it says:
>
> multifile(Pred) specifies that the procedure
> whose predicate indicator is Pred is a multifle
> procedure (the clauses of Pred can reside in
> several source files). This directive is only
> >>>>> supported by GNU Prolog since version 1.4.0. <<<<<<
> http://www.gprolog.org/manual/gprolog.html#sec53


Ah, yes. By "support" I think they mean "recognized well enough to
do nothing". :)

>[...]

--
How many hardware engineers does it take to change a lightbulb?
None: "We'll fix it in software."

How many software engineers does it take to change a lightbulb?
None: "We'll document it in the manual."

How many tech writers does it take to change a lightbulb?
None: "The user can work it out."

krishna...@ccreweb.org

unread,
Oct 16, 2014, 6:26:35 PM10/16/14
to
I can't get multifile/1 to work as expected in gprolog:

$ gprolog
GNU Prolog 1.4.4 (64 bits)
Compiled Apr 24 2013, 15:23:52 with gcc
By Daniel Diaz
Copyright (C) 1999-2013 Daniel Diaz
| ?- [all].
compiling /home/krishna/Pictures/astrophoto/Catalog/all.pl for byte code...
/home/krishna/Pictures/astrophoto/Catalog/all.pl including file2.pl:1: warning: directive occurs after definition of session/1 - directive ignored
/home/krishna/Pictures/astrophoto/Catalog/all.pl including file2.pl:1: warning: directive occurs after definition of image/1 - directive ignored
/home/krishna/Pictures/astrophoto/Catalog/all.pl including file2.pl:2: warning: discontiguous predicate session/1 - clause ignored
/home/krishna/Pictures/astrophoto/Catalog/all.pl including file2.pl:3: warning: discontiguous predicate image/1 - clause ignored
/home/krishna/Pictures/astrophoto/Catalog/all.pl compiled, 12 lines read - 390 bytes written, 30 ms

(2 ms) yes
| ?-

The same files work in SWI Prolog:

$ swipl
Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 6.2.6)
Copyright (c) 1990-2012 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).

?- [all].
% all compiled 0.00 sec, 9 clauses
true.

?- listing.

:- thread_local thread_message_hook/3.
:- dynamic thread_message_hook/3.
:- volatile thread_message_hook/3.


:- multifile session/1.

session(a).
session(b).

:- multifile image/1.

image(100).
image(234).
true.

?-

As can be seen, SWI Prolog has compiled all statements in both files.

Krishna

--
The contents of the test files are as follows.

all.pl:
------
:- multifile([session/1, image/1]).
:- include('file1.pl').
:- include('file2.pl').

file1.pl:
--------
:- multifile([session/1,image/1]).
session(a).
image(100).

file2.pl:
--------
:- multifile([session/1,image/1]).
session(b).
image(234).

R Kym Horsell

unread,
Oct 16, 2014, 6:28:34 PM10/16/14
to
Paulo Moura <pjlm...@gmail.com> wrote:
...
> multifile/1, NOT multfile/1 !!!


Ah. My poor old brine dudnt notice the spel error.
But I do know g does have a warning that it's ignoring multifile
when it sees it.

--
Clearly a statement cannot be tested by observation unless it is an
assertion about the results of observation.
-- A S Eddington, "The Philosophy of Physical Science", 1938

krishna...@ccreweb.org

unread,
Oct 16, 2014, 6:30:22 PM10/16/14
to
On Thursday, October 16, 2014 5:26:14 PM UTC-5, kym wrote:
> Jan Burse <janb...@fastmail.fm> wrote:
>
> > R Kym Horsell schrieb:
...
>
> > Yes and the documentation is inconsistent, since it says:
>
> >
>
> > multifile(Pred) specifies that the procedure
>
> > whose predicate indicator is Pred is a multifle
>
> > procedure (the clauses of Pred can reside in
>
> > several source files). This directive is only
>
> > >>>>> supported by GNU Prolog since version 1.4.0. <<<<<<
>
> > http://www.gprolog.org/manual/gprolog.html#sec53
>
>
>
>
>
> Ah, yes. By "support" I think they mean "recognized well enough to
>
> do nothing". :)
>
>
>
> >[...]


Isn't multifile/1 standard Prolog? The GNU Prolog documentation indicates it is ISO compliant, if that means anything.

Krishna

R Kym Horsell

unread,
Oct 16, 2014, 6:44:05 PM10/16/14
to
krishna...@ccreweb.org wrote:
...
>
> Isn't multifile/1 standard Prolog? The GNU Prolog documentation indicates it is ISO compliant, if that means anything.
> Krishna


You have learned something deep and meaningful. :)

As I said, if you s/multifile/discontigous/g your code is g compliant.

--
Famous last words:

Don't worry, Paw, I checked and the gun ain't lo...

Don't worry, our maintenance crews have retro-fitted all the modern
safety devices and systems and even though it's 50 years old
this aircraft is perfectly sa...

The bridge looks rickety, but it's up to code and even in
high winds it won't collap...

Isn't that funny, you slap enough fissionable material together
and it goes ba...

Paulo Moura

unread,
Oct 16, 2014, 6:51:12 PM10/16/14
to
GNU Prolog is being standards compliant and is telling you what's wrong in the warning messages. The directive include/1 means textually include another file at the point where the directive occurs. Given your definition of the "all.pl" file, none of the three files should use a multifile/1 directive. Instead, the "all.pl" file should contain a discontiguous/1 directive. With that fix, this is the contents of the "all.pl" file as seen by the compiler after processing the include/1 directives:

:- discontiguous([session/1, image/1]).
session(a).
image(100).
session(b).
image(234).

Including a file is not the same thing as consulting a file. The multifile/1 directive is required when predicate definitions are spread among several files (which will be consulted/compiled). That's not the case here where, given the semantics of the include/1 directive, you have virtually a single file. Just because SWI-Prolog is more permissive to programmers errors doesn't make GNU Prolog behavior wrong.

Cheers,

Paulo

Jan Burse

unread,
Oct 16, 2014, 7:59:50 PM10/16/14
to
Paulo Moura schrieb:
>> > C:/Users/Jan Burse/Desktop/tt/file1.pl:8:
> previous definition
> multifile/1, NOT multfile/1 !!!

Oops, my bad. The directive wurks in GNU Prolog:

?- ['C:\\Users\\Jan Burse\\Desktop\\tt\\file1.pl',
'C:\\Users\\Jan Burse\\Desktop\\tt\\file2.pl'].
compiling C:/Users/Jan Burse/Desktop/tt/file1.pl
for byte code...
C:/Users/Jan Burse/Desktop/tt/file1.pl compiled,
12 lines read - 582 bytes written, 0 ms
compiling C:/Users/Jan Burse/Desktop/tt/file2.pl
for byte code...
C:/Users/Jan Burse/Desktop/tt/file2.pl compiled,
12 lines read - 582 bytes written, 0 ms

And this also works, which is what the OP probably wants:

?- ['C:\\Users\\Jan Burse\\Desktop\\tt\\all.pl'].
compiling C:/Users/Jan Burse/Desktop/tt/all.pl
for byte code...
C:/Users/Jan Burse/Desktop/tt/all.pl compiled,
3 lines read - 283 bytes written, 0 ms
compiling C:/Users/Jan Burse/Desktop/tt/file1.pl
for byte code...
C:/Users/Jan Burse/Desktop/tt/file1.pl compiled,
12 lines read - 582 bytes written, 0 ms
compiling C:/Users/Jan Burse/Desktop/tt/file2.pl
for byte code...
C:/Users/Jan Burse/Desktop/tt/file2.pl compiled,
12 lines read - 582 bytes written, 0 ms

Bye

P.S.: Source code:

file1.pl:

:- multifile(session/1).

session(x).
session(y).
session(z).

:- multifile(image/1).

image(x).
image(y).
image(z).


file2.pl:


:- multifile(session/1).

session(a).
session(b).
session(c).

:- multifile(image/1).

image(a).
image(b).
image(c).


all.pl:


:- initialization(consult('C:\\Users\\Jan Burse\\Desktop
\\tt\\file1.pl')).
:- initialization(consult('C:\\Users\\Jan Burse\\Desktop
\\tt\\file2.pl')).


krishna...@ccreweb.org schrieb:

krishna...@ccreweb.org

unread,
Oct 16, 2014, 8:01:19 PM10/16/14
to
On Thursday, October 16, 2014 5:51:12 PM UTC-5, Paulo Moura wrote:
...
> GNU Prolog is being standards compliant and is telling you what's wrong in the warning messages. The directive include/1 means textually include another file at the point where the directive occurs.

Ah, yes, now I see! Someone suggested using the include directive instead of multifile, and I misunderstood it as a replacement. The prolog include directive does pretty much what is done in other languages (C, Fortran, Forth) with an include statement.

> Given your definition of the "all.pl" file, none of the three files should use a multifile/1 directive. Instead, the "all.pl" file should contain a discontiguous/1 directive. With that fix, this is the contents of the "all.pl" file as seen by the compiler after processing the include/1 directives:
>
>
>
> :- discontiguous([session/1, image/1]).
>
> session(a).
>
> image(100).
>
> session(b).
>
> image(234).
>
>
>
> Including a file is not the same thing as consulting a file.

Thank you very much for that clarification!

> The multifile/1 directive is required when predicate definitions are spread among several files (which will be consulted/compiled). That's not the case here where, given the semantics of the include/1 directive, you have virtually a single file. Just because SWI-Prolog is more permissive to programmers errors doesn't make GNU Prolog behavior wrong.
>
>

Agreed. I replaced multifile/1 with discontiguous/1 in all.pl, and everything loads fine now. This is actually cleaner, since I don't have to clutter the remaining files with a multifile/1 directive.


Krishna

krishna...@ccreweb.org

unread,
Oct 16, 2014, 8:14:12 PM10/16/14
to
Thanks! As I just mentioned in my reply to Paulo, I think using the discontiguous/1 directive in all.pl with include/1 is probably cleaner than using the multifile/1 directive with consult/1, since multifile/1 has to appear in each of the files.

I appreciate everyone's help, despite the intermediate confusion, in understanding my misinterpretation of the behavior of gprolog.

Incidentally, below are some examples of assertions and queries, showing how I intend to use them, at a basic level. Currently I have a few hundred records, but expect to have on the order of 10,000 records in the database in a couple of years.

Cheers,
Krishna

--

session( s20140927a, 'Myneni, Krishna',
location(34.7300, 86.5850),
optics( 'Newtonian 6-inch f/8 prime focus', 'D3200' ),
sky( 'mostly hazy with partially clear patches' ) ).
...

image( 12, s20140927a, 20140927, '20:30:50',
fi('DSC_0012.JPG', jpeg),
size( 6016, 4000 ), exposure(1600, 8),
object('Capricorn', 'Dabih') ).

image( 13, s20140927a, 20140927, '20:36:55',
fi('DSC_0013.JPG', jpeg),
size( 6016, 4000 ), exposure(1600, 8),
object('Aquarius', 'Albali') ).

...

A query to give a list of all objects which I have photographed in the constellation Lyra is accomplished by,

findall(Object, image(_,_,_,_,_,_,_,object('Lyra',Object)),
List), sort(List, NList).


Direct queries of this sort are skeletal and would be done indirectly through other higher level predicates.

Jan Burse

unread,
Oct 16, 2014, 8:21:47 PM10/16/14
to
krishna...@ccreweb.org schrieb:
> Agreed. I replaced multifile/1 with discontiguous/1 in
> all.pl, and everything loads fine now. This is actually
> cleaner, since I don't have to clutter the remaining
> files with a multifile/1 directive.

I wouldn't be that happy. The directive discontiguous/1 is
usually not recommended. If you use the directive discontiguous/1
you might not notice typos such as:

:- discontiguous session/1.

session(a).
sassion(b).
session(c).

Interestingly the directive is probably originally
intended to ease the compiler in compiling predicates.

This is for example seen in the source code of the
GNU compiler. The GNU compiler can more quickly
compile predicates that are not NOT discontiguous.
It will read all the clauses in one go and compile
them, without needing a last open try statement in
the WAM code, that is later fixed by more clauses.
Maybe the code quality of discontiguous predicates
is therefore even not that good.

This doesn't hold for other Prolog systems anymore.
In many other Prolog systems, such as SWI-Prolog and
Jekejeke Prolog I guess the discontiguous/1 directive
is just a style check and not anymore a necessesity for
compilation.

And this style check effectively helps in finding
such typos as above. Happened more than once with me,
was quite happy that code didn't use the discontiguous/1
directive.

Bye

Jan Burse

unread,
Oct 16, 2014, 8:23:49 PM10/16/14
to
Jan Burse schrieb:
> them, without needing a last open try statement in
> the WAM code, that is later fixed by more clauses.

There are even a couple of papers that mention
this "feature" of WAM code. Anybody good in googling?

Bye

Jan Burse

unread,
Oct 16, 2014, 8:25:08 PM10/16/14
to
krishna...@ccreweb.org schrieb:
> Thanks! As I just mentioned in my reply to Paulo, I think using
> the discontiguous/1 directive in all.pl with include/1 is probably
> cleaner than using the multifile/1 directive with consult/1,
> since multifile/1 has to appear in each of the files.

Define cleaner. Usually discontiguous/1 is considered dirty,
at least in my opinion. See my other post.

Jan Burse

unread,
Oct 16, 2014, 8:44:53 PM10/16/14
to
Jan Burse schrieb:
> Maybe the code quality of discontiguous predicates
> is therefore even not that good.

It depends whether the fixup can also fix incomplete
indexes. Or whether the last try is kind of a
catch all, so that with each block of clauses a
new sub index starts.

Having a couple of sub indexes, on type or newer
WAM code on functor, might slow down your code,
since re-indexing the same argument multiple times,
can be slower I guess.

But this is all guesswork. Probably papers and
inspecting the WAM code that GNU Prolog generates,
or even going down an looking at the assembler code,
would be more serious work here. Not really that
time at my hands.

Bye

P.S.: The multi-file directive has also an interesting
history. It wasn't that sophisticated in the beginning
I guess, and simply only prevented abolishing the given
predicate during reconsult. But it needed also to do the
last try WAM code thing, because well as the directive
says, another file can also have the predicate.

But nowadays one expects that a prolog system keeps
track for each clause from which source file it comes,
so that a reconsult can only expell exactly these clauses.
What must be tested for GNU Prolog is whether multi-file
implies discontiguous, which would be bad news.

But I guess modern Prolog systems don't mix multi-file
and discontiguous anymore. Or lets say, they shouldn't
mix multi-file and discontiguous. Sadly some Prolog
systems still do. Here is an example from SWI-Prolog:

Without multifile:

Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.1.23)
Copyright (c) 1990-2014 University of Amsterdam, VU Amsterdam

?- [user].
a.
b.
a.
Warning: user://1:11:
Clauses of a/0 are not together in the source-file

With multifile:

?- [user].
:- multifile p/0.
p.
q.
p.

Compare this to Jekejeke Prolog:

Without multifile:

Jekejeke Prolog, Development Environment 1.0.4
(c) 1985-2014, XLOG Technologies GmbH, Switzerland

?- [user].
a.
b.
a.
Warning: Discontiguous predicate a/0, declare accordingly.

With multifile:

?- [user].
:- multifile p/0.
p.
q.
p.
Warning: Discontiguous predicate p/0, declare accordingly.

Jan Burse

unread,
Oct 16, 2014, 8:45:35 PM10/16/14
to
Jan Burse schrieb:
But it depends a little whether multifile in GNU Prolog
also implies discontiguous. Have to check.

krishna...@ccreweb.org

unread,
Oct 16, 2014, 9:07:38 PM10/16/14
to
It appears that in GNU Prolog, multifile/1 does not imply discontiguous/1, as it does in SWI Prolog.

Krishna
--

$ gprolog
GNU Prolog 1.4.4 (64 bits)
Compiled Apr 24 2013, 15:23:52 with gcc
By Daniel Diaz
Copyright (C) 1999-2013 Daniel Diaz
| ?- [user].
compiling user for byte code...
:- multifile(p/0).
p.
q.
p.
user:4: warning: discontiguous predicate p/0 - clause ignored

krishna...@ccreweb.org

unread,
Oct 16, 2014, 9:11:19 PM10/16/14
to
In the case of multifile/1, the compiler will not complain unless one makes the same typo in multiple files, which I guess is a realistic possibility. Certainly something to consider in choosing between the two approaches.

Krishna


Jan Burse

unread,
Oct 17, 2014, 6:55:29 AM10/17/14
to
Cool! Thx for testing.

Jan Burse

unread,
Oct 17, 2014, 7:33:00 AM10/17/14
to
Jan Burse schrieb:
>
> But this is all guesswork. Probably papers and
> inspecting the WAM code that GNU Prolog generates,
> or even going down an looking at the assembler code,
> would be more serious work here. Not really that
> time at my hands.

It seems that they are grouped and delayed compiled:

buff_discontig_clause(Pred,N,SrcCl):
records a clause of a discontiguous predicate
(:- discontiguous). Eacho clause of a discontiguous
predicate is asserted when it is read. When the
end of file is reached all clauses of a discontiguous
pred are grouped to return a list of source clauses
LSrcCl. Thus discontiguous predicates are always
compiled after other predicates.

http://code.metager.de/source/xref/gnu/gprolog/
1.4.2/src/Pl2Wam/read_file.pl

So I guess there is no penalty in GNU Prolog in using
discontiguous.

But there might be a penalty for multifile, I am not
sure, I read:

594 handle_directive(multifile, DLst, Where) :-
595 !,
596 DLst \== [],
597 set_flag_for_preds(DLst, multi),
598 add_empty_dyn(DLst, Where).

So I guess there is something going on with an interface
predicate, something Head :- call(Head) (ugh).

Bye

0 new messages