[comp.lang.prolog] hierarchy among modules in prolog

sreerang@portia.Stanford.EDU (Sreeranga Rajan) (10/08/89)

I would like to know if it is possible to make the visibility of
assertions in modules hierarchical in prolog. The prolog I am using
being Quintus prolog running on Sun-unix, seems to have a flat
module system. Would there be any other prolog where its possible to
have a hierachical module system? Any input on this is greatly
appreciated.
Thanks in advance!
-- Sree
--------------------------------------------------------------------
Sreeranga Rajan  			Ph: (408)433-7867
--------------------------------------------------------------------

ok@cs.mu.oz.au (Richard O'Keefe) (10/08/89)

In article <5641@portia.Stanford.EDU>, sreerang@portia.Stanford.EDU (Sreeranga Rajan) writes:
> I would like to know if it is possible to make the visibility of
> assertions in modules hierarchical in Prolog.

Please say more.  What is it that you want to do?
There are two separate questions:  the structure of the space of module
names, and the set of visibility graphs you can construct.


> The Prolog I am using being Quintus Prolog running on SunOS,
> seems to have a flat module system.

The space of module names in Quintus Prolog is indeed flat:
there is a one-to-one correspondence between modules and atoms.
However the space of module names were structured, there would
be *some* "flat" set which could be placed in correspondence with it.

As for the visibility graphs you can construct in Quintus Prolog,
think of modules (M) and predicates (M:P/N) as being nodes in a
bipartite graph, where there is an arc from a predicate (M:P/N)
to the module (M) it is defined in and an arc from a module (M)
to every predicate (M':P'/N') which is visible in M.  Any such
graph is possible.

Suppose that you want to have some sort of tree-structured scheme,
where a module may have other modules as "children", and everything
that is visible in a parent is visible in all its children.

It is already the case that a module in Quintus Prolog may re-export
something that it has imported from another module, so there would
be no problem with having the parent export something which is
actually defined in a child.  The trick is to get the children to
see the parent's private predicates.

Actually, there isn't any trick.  A module can forcibly import something
from another module even if the other module didn't export it.  You do
get a warning message.  So the children could simply import everything
they need from the parent.  We would have

% File parent.pl	% File child1.pl	% File child2.pl
:- module(parent, [	:- module(child1, [	:- module(child2, [
	mine/1,			onea/1,			twoa/1,
	onea/1,			oneb/2			twob/2
	twob/2		   ]).			   ]).
   ]).
:- use_module(child1).	:- use_module(parent, [	:- use_module(parent, [
:- use_module(child2).		needed/1,		needed/1,
				vital/3			useful/2
			   ]).			   ]).

define mine/1		define onea/1		define twoa/1
   and needed/1		   and oneb/2		   and twob/2
   and useful/2
   and vital/3

Yes, there is a cycle here: parent uses child1 uses parent.  But that's
just fine.  use_module is like ensure_loaded; both are just as happy as
can be with usage cycles, and do exactly the right thing.

Just because there isn't a hierarchy in the NAMES of the modules
doesn't mean there can't be a hierarchy in the CONTENTS!

Suppose that you really don't want to get these error messages.
You can restructure the parent module as two modules.

	% File parent.pl
	:- module(parent, [
		mine/1,
		onea/1,
		twob/2
	   ]).
	:- use_module(local,  [mine/1]),
	   use_module(child1, [onea/1]),
	   use_module(child2, [twob/2]).
	end_of_file.

	% File local.pl
	:- module(parent, [
		mine/1,
		needed/1,
		useful/2,
		vital/3
	   ]).
	/* former body of parent.pl goes here */

The children are then modified to use the 'local' module rather than
the 'parent' module.

Now it really doesn't take a lot of ingenuity to write a little
preprocessor that will generate these headers automatically.  In fact,
the headers and the clauses don't have to be in the same files.
For example, child1.pl could look like

	% File child1.pl
	
	:- module(child1, [
		onea/1,
		oneb/2
	   ]).
	:- use_module(local, [
		needed/1,
		vital/3
	   ]).
	:- compile('child1.body').	% no :-module header in that!
	end_of_file.

So your preprocessor doesn't need to alter any files containing declarations
or rules, it can just generate new header files.

"Hierarchical" could mean almost anything, so there's a good chance that
the sketch above doesn't address your problem.  Tell us more about what
you're trying to do.

karam@sce.carleton.ca (Gerald Karam) (10/08/89)

In article <5641@portia.Stanford.EDU> sreerang@Portia.Stanford.EDU (Sreeranga Rajan) writes:
>I would like to know if it is possible to make the visibility of
>assertions in modules hierarchical in prolog. The prolog I am using
>being Quintus prolog running on Sun-unix, seems to have a flat
>module system. Would there be any other prolog where its possible to
>have a hierachical module system? Any input on this is greatly
>appreciated.

Logiware International's MProlog allows modules to be constructed into a 
hierarchy using their consolidator (which is a module linker for 
applications).  It permits the user to construct a new interface (exports) 
and hide internal modules.

Their original system (v 1.5 circa 1984) had flat modules like every other 
Prolog I'd seen and I complained at the time that hierarchical modules had 
value.  They half heard me because the next major release (v2.1 i believe)
did support this concept, but not at the syntactic level --- which remained 
flat.  As a result, the hierarchical module feature was such a pain to use, 
I just ignored it.

gerald karam

karam@sce.carleton.ca
karam@sce.uucp

sreerang@portia.Stanford.EDU (Sreeranga Rajan) (10/09/89)

In article <2326@munnari.oz.au> ok@cs.mu.oz.au (Richard O'Keefe) writes:
>In article <5641@portia.Stanford.EDU>, sreerang@portia.Stanford.EDU (Sreeranga Rajan) writes:
>> I would like to know if it is possible to make the visibility of
>> assertions in modules hierarchical in Prolog.
>
>Please say more.  What is it that you want to do?
>There are two separate questions:  the structure of the space of module
>names, and the set of visibility graphs you can construct.
>
>
>
>Now it really doesn't take a lot of ingenuity to write a little
>preprocessor that will generate these headers automatically.  In fact,
>the headers and the clauses don't have to be in the same files.
>"Hierarchical" could mean almost anything, so there's a good chance that
>the sketch above doesn't address your problem.  Tell us more about what
>you're trying to do.

In trying to write a small compiler for a Algol-like language I need
to having scoping of declarations and the visibility rules as in
Algol-like languages.The most common occurrence would be a loop
variable. Such a variable most of the time would be the same
identifier in a main program and subprograms. In such a case I would
like to create modules dynamically in prolog and have exactly the
same scoping and visibility among modules arranged hierarchically. 
The solution given by Richard O'Keefe does give a solution, but
falls short of solving the problem of having only private predicates
in the case of dynamycally created modules.
To clarify further, if I have a main program with subprograms and
functions, I would like to create modules dynamycally corresponding
to each of them so that I can have private name spaces for each, and
also address the problem of scope and visibility hierarchically.

ok@cs.mu.oz.au (Richard O'Keefe) (10/09/89)

In article <5669@portia.Stanford.EDU>, sreerang@portia.Stanford.EDU (Sreeranga Rajan) writes:
> >> I would like to know if it is possible to make the visibility of
> >> assertions in modules hierarchical in Prolog.

> In trying to write a small compiler for an Algol-like language I need
> to having scoping of declarations and the visibility rules as in
> Algol-like languages.

I don't understand this.  Compilers for languages like Algol and Pascal
and Ada compile to machine language or assembly language.  Assembly
language does not have hierarchical name scopes.  If the 4.2BSD Pascal
compiler sees procedure fred declared inside jim inside alphonse it
generates a name like alphonse_jim_fred.

You have two languages: the source language and the target language.
Provided that each identifier in the source language is mapped into
a different identifier in the target language, there is no need for
the target language to have any name scoping at all.  One simple
device is to number the blocks of the program and generate names like
'12.fred' (the fred appearing in block 12).  It is the compiler's job
to work out which definition is associated with what use, having done
that there is no point in having the target language do it all over
again.

> The most common occurrence would be a loop variable.

Hang on a minute:  Prolog module systems apply to *predicate* names.
Now you wouldn't be translating an Algol loop variable as a *predicate*,
you'd be translating it as a Prolog variable.  For example,
consider the Algol 60 loop

	for i := 1 step 1 until 27 do a[i] := a[i]+1

This would translate into a predicate

	%  for_i(CurrentI, FinalI, CurrentA, FinalA)

	for_i(I0, I, A0, A) :-
	    (	I0 =< 27 ->
		fetch(I0, A0, A_sub_I_0),		
		A_sub_I_1 is A_sub_I_0 + 1,
		store(I0, A0, A_sub_I_1, A1),
		I1 is I0+1,
		for_i(I1, I, A1, A)
	    ;	I = I0, A = A0
	    ).

and a call to it
	    ...	for_i(1, FinalI, CurrentA, FinalA)

You *could* turn Algol variables into dynamic predicates, but changing
a dynamic predicate is literally thousands of times slower than binding
a new variable.

> Such a variable most of the time would be the same
> identifier in a main program and subprograms.

In any case, that is a job for _your_ compiler to resolve.
If you were translating to assembly code, you'd have to do that.
If you were translating to Lisp, you'd have to do that.

> To clarify further, if I have a main program with subprograms and
> functions, I would like to create modules dynamycally corresponding
> to each of them so that I can have private name spaces for each, and
> also address the problem of scope and visibility hierarchically.

Again, in Quintus Prolog there is nothing to stop you creating a module
dynamically.  You just create a predicate in it and the module materialises.
There doesn't have to be a module header.  Suppose you have a procedure
P which you have put in module M1 (you *KNOW* this because you chose to
put it there) and you have another procedure Q in module M2 which wants
to call P.  Then do

	:- M2:assert((Q :- ..., M1:P, ...)).

In Quintus Prolog, a module prefix M appearing on a goal G, as in M:G,
means "do G as if it appeared textually inside the module M".  So here
we are saying:
	do assert((Q :- ..., M1:P, ...)
	as if this assert command appeared textually inside M2.

For example, suppose you have something like
	real procedure f(X); value X; real X;
	    begin
		real procedure g(X); value X; real X;
		    g := (X+1)/(X-1);

		f := g(3*X/2)*g(2*X/3)
	    end f;
and there are two modules:  inside_f (where g appears) and outside_f
(where f appears).  You could do
	:- inside_f:assert((
		g(X, Result) :- Result is (X+1)/(X-1)
	   )),
	   outside_f:assert((
		f(X, Result) :-
			T1 is 3*X/2,
			inside_f:g(T1, T2),
			T3 is 2*X/3,
			inside_f:g(T3, T4),
			Result is T2*T4
	   )).
Of course bringing modules into it at all is quite unnecessary
(well, it's a good idea to put the translated code in ONE module).
Just do
	:- algol_module:assert((
		'main.f.g'(X, Result) :- ...
	   )),
	   algol_module:assert((
		'main.f'(X, Result) :- ...
			'main.f.g'(T1, T2), ...
			'main.f.g'(T3, T4), ...
	   )).

finin@prc.unisys.com (Tim Finin) (10/09/89)

In article <5641@portia.Stanford.EDU>,sreerang@portia(Sreeranga Rajan) writes:
>I would like to know if it is possible to make the visibility of
>assertions in modules hierarchical in prolog. The prolog I am using
>being Quintus prolog running on Sun-unix, seems to have a flat
>module system. Would there be any other prolog where its possible to
>have a hierarchical module system? Any input on this is greatly appreciated.

As Richard pointed out, there are many possible notions of a
"hierarchical module system".  We've explored one possibility that is
motivated more from a AI knowledge representation and reasoning
perspective than from a programming language one.  We have a
forthcoming paper on this:

  Finin, Tim and James McGuire, ``Inheritance Hierarchies in Logic
  Programming Languages'', in Inheritance Hierarchies in Knowledge
  Representation, M.  Lenzerini, D. Nardi and M. Simi (eds.), Wiley, 1990.

Which is available in draft form as Technical report PRC-LBS-8812
which can be obtained by contacting Judy Norton, Unisys Paoli Research
Center, Box 517, Paoli PA 19301.  Here is the paper's abstract:

  This paper presents an extended model for a logic programming
  language's knowledge base.  Instead of being restricted to one global
  knowledge base, as is the case with Prolog, we allow segmentation into
  units which are linked together into a lattice.  Each unit defines a
  view on the knowledge base which includes those clauses which have
  been asserted into that unit as well as clauses inherited from its
  ancestors higher in the lattice structure.  This model supports
  arbitrary retraction.  Retracting a clause in a knowledge base unit
  effectively blocks its inheritance for that unit and all of its
  descendants. Motivations for using this model are given.  We also
  discuss the design-iterations of a Prolog-based implementation (Phd)
  of this model.
-- 
______________________________________________________________________________
Tim Finin                     finin@prc.unisys.com (internet)
Unisys Paoli Research Center  ..!{psuvax1,sdcrdcf,cbmvax}!burdvax!finin (uucp)
PO Box 517                    215-648-7446 (office), 215-386-1749 (home),