1

Is there a workaround to make ensure_loaded/1 work in B-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.

  • It seems that it does not resolve a relative path to the currently consulted file, as many Prolog systems do.
  • It seems that it does not allow a Prolog text but expects some byte code, which would force me to compile stuff.

So I tried the following:

:- set_prolog_flag(redefine_builtin, on).
ensure_loaded(X) :-
    atom_concat('<base>\\',X,Y),
    consult(Y).
:- set_prolog_flag(redefine_builtin, off).

But when a Prolog text with the following directive is consulted, I wont work:

:- ensure_loaded('suite.p').

It still doesn't find suite.p.

What could I do?

Bye

  • 1
    What do you get with `include/1`? Not that this solves your problem, but at least it might narrow down how path resolution is implemented. – false Jun 11 '14 at 16:14
  • The path calculation itself is not the issue of the question, but the redefinition of a directive in B-Prolog. –  Jun 12 '14 at 15:15

2 Answers2

1

Regarding the expansion of paths, in the Logtalk adapter file for B-Prolog I (must) use:

% '$lgt_expand_path'(+nonvar, -atom)
%
% expands a file path to a full path

'$lgt_expand_path'(Path, ExpandedPath) :-
    % first expand any environment variable
    expand_environment(Path, ExpandedPath0),
    (   (   sub_atom(ExpandedPath0, 0, 1, _, '/')
            % assume POSIX full path 
        ;   sub_atom(ExpandedPath0, 1, 1, _, ':')
            % assume Windows full Path starting with a drive letter followed by ":"
        ) ->
        % assume full path
        ExpandedPath = ExpandedPath0
    ;   % assume path relative to the current directory
        working_directory(Current),
        atom_concat(Current, '/', Directory),
        atom_concat(Directory, ExpandedPath0, ExpandedPath)
    ).

It's basically an hack (that can be improved by e.g. trying to find first in which OS you're running) for missing functionality that should be provided by B-Prolog itself.

Paulo Moura
  • 18,373
  • 3
  • 23
  • 33
  • Your requirements are not expressed as such anywhere in your question. My reply simply illustrates how to go from a path to a full path in B-Prolog. From this knowledge you can try to rewrite your code snippet and check if the file is now found. – Paulo Moura Jun 11 '14 at 19:34
  • 2
    There's no suggestion in my reply for you to use Logtalk. Your code snippet is already overriding the built-in definition of the `ensure_loaded/1` directive. My suggestion is for you to simply update it to try to expand the path (as illustrated in my reply) before calling `consult/1`. – Paulo Moura Jun 11 '14 at 20:09
0

I could only arrive at the following analysis and workaround.

The set_prolog_flag(redefine_builtin, on) doesn't work inside a Prolog text for B-Prolog. I get:

B-Prolog Version 8.1
?- consult('<base>\\bprolog.p').
consulting::<base>\bprolog.p
** Error  : Trying to redefine built-
     in:'<base>\\bprolog.p',18::ensure_loaded/1
*** error(file_not_found,suite.p)

When I do the set_prolog_flag(redefine_builtin, on) in the top-level, things are fine:

?- set_prolog_flag(redefine_builtin, on).
?- consult('<base>\\bprolog.p').
consulting::<base>\bprolog.p
consulting::<base>\suite.p
Etc.. 

Bye