1

Is there a workaround to make ensure_loaded/1 work in GNU Prolog as it works in many other Prolog systems? The goal is to have a preamble so that the rest of code can use ensure_loaded/1 independent of whether which Prolog system I use.

I tried the following:

:- multifile(term_expansion/2).
term_expansion((:- ensure_loaded(X)),
     (:- atom_concat('<base>\\', X, Y),
     include(Y))).

But the following query doesn't work:

:- ensure_loaded('suite.p').

The path calculation itself is not the issue of the question, but the redefinition of a directive in GNU Prolog. There is another directive that causes problems: meta_predicate/1. The byte code crashes as follows:

GNU Fatal

Bye

2 Answers2

2

A partial solution is:

ensure_loaded(File) :-
    absolute_file_name(File, Path),
    (   predicate_property(_, prolog_file(Path)) ->
        true
    ;   consult(Path)
    ).

It assumes that the file defines at least one predicate but that's a sensible assumption. However, there's seems to be no way to override the native, non-functional, definition of the ensure_loaded/1 directive. A workaround would be to wrap the ensure_loaded/1 directive within an initialization/1 directive. For example:

:- initialization(ensure_loaded('suite.pl')).

Hence this being a partial solution as we're really defining an ensure_loaded/1 predicate, not a directive.

Paulo Moura
  • 18,373
  • 3
  • 23
  • 33
  • A **necessary** functionality to be able to define an `ensure_loaded/1` directive or predicate is to be able to query the system if a file is already loaded, which is accomplished in my reply by the call to `predicate_property/2`, which is not a straightforward solution. That's the main contribution in my post. The call to `absolute_file_name/2` is necessary as the `prolog_file/1` property uses absolute file paths. The `include/1` directive does nothing in helping finding if a file is already loaded. – Paulo Moura Jun 12 '14 at 14:57
0

My current speculation is, that it is impossible with the standard distribution of GNU Prolog 1.4.4. The docu says:

The GNU Prolog compiler (section 4.4) automatically calls expand_term/2 on each Term1 read in. However, in the current release, only DCG transformation are done by the compiler (i.e. term_expansion/2 cannot be used). To use term_expansion/2, it is necessary to call expand_term/2 explicitly.

I also tried to inject some Prolog code for term_expansion/2 via the command line, but to no awail. Although the tool chain has options such as -O, -L, -A that pass options to other tools. There is not really an option that passes a Prolog text to the pl2wam, in course of the execution of a consult/1 issued inside the top-level.

At least this are my results so far.

Bye