Обходной путь sure_loaded/1 GNU Prolog?

Есть ли обходной путь, чтобы заставить sure_loaded/1 работать в GNU Prolog, как это работает во многих других системах Prolog? Цель состоит в том, чтобы иметь преамбулу, чтобы остальная часть кода могла использовать sure_loaded/1 независимо от того, какую систему Пролога я использую.

Я пробовал следующее:

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

Но следующий запрос не работает:

:- ensure_loaded('suite.p').

Само вычисление пути не является предметом вопроса, а является переопределением директивы в GNU Prolog. Есть еще одна директива, вызывающая проблемы: meta_predicate/1. Байт-код вылетает следующим образом:

GNU Fatal

Пока


person Mostowski Collapse    schedule 11.06.2014    source источник


Ответы (2)


Частичное решение:

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

Предполагается, что файл определяет по крайней мере один предикат, но это разумное предположение. Однако, похоже, нет способа переопределить родное, нефункциональное определение директивы ensure_loaded/1. Обходной путь — обернуть директиву ensure_loaded/1 директивой initialization/1. Например:

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

Следовательно, это частичное решение, поскольку мы действительно определяем ensure_loaded/1 предикат, а не директиву.

person Paulo Moura    schedule 12.06.2014
comment
Необходимая функциональность для определения директивы или предиката ensure_loaded/1 состоит в том, чтобы иметь возможность запрашивать систему, если файл уже загружен, что достигается в моем ответе вызовом predicate_property/2, который не простое решение. Это основной вклад в мой пост. Вызов absolute_file_name/2 необходим, так как свойство prolog_file/1 использует абсолютные пути к файлам. Директива include/1 никак не помогает определить, загружен ли уже файл. - person Paulo Moura; 12.06.2014

Мое текущее предположение состоит в том, что это невозможно со стандартным дистрибутивом GNU Prolog 1.4.4. В документе говорится:

Компилятор GNU Prolog (раздел 4.4) автоматически вызывает expand_term/2 для каждого считываемого Term1. Однако в текущей версии компилятор выполняет только преобразование DCG (т. е. term_expansion/2 использовать нельзя). Чтобы использовать term_expansion/2, необходимо явно вызвать expand_term/2.

Я также пытался внедрить некоторый код Prolog для term_expansion/2 через командную строку, но безрезультатно. Хотя в цепочке инструментов есть такие параметры, как -O, -L, -A, которые передают параметры другим инструментам. На самом деле нет возможности передать текст Пролога в pl2wam во время выполнения consult/1, выданного внутри верхнего уровня.

По крайней мере, это мои результаты на данный момент.

Пока

person Mostowski Collapse    schedule 12.06.2014