Path: utzoo!attcan!uunet!ginosko!uakari.primate.wisc.edu!ames!uhccux!munnari.oz.au!cs.mu.oz.au!ok From: ok@cs.mu.oz.au (Richard O'Keefe) Newsgroups: comp.lang.prolog Subject: Re: hierarchy among modules in prolog Keywords: modules, hierarchy, Quintus prolog Message-ID: <2326@munnari.oz.au> Date: 8 Oct 89 07:48:14 GMT References: <5641@portia.Stanford.EDU> Sender: news@cs.mu.oz.au Lines: 112 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.