Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!wuarchive!gem.mps.ohio-state.edu!ginosko!uunet!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: <2337@munnari.oz.au> Date: 9 Oct 89 08:37:13 GMT References: <5641@portia.Stanford.EDU> <2326@munnari.oz.au> <5669@portia.Stanford.EDU> Sender: news@cs.mu.oz.au Lines: 113 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), ... )).