2016-03-30 3 views
5

В SICStus Prolog есть крючок для расширения цели: goal_expansion/6, который вызывается как во время компиляции, так и во время выполнения при метакалировании. Эти вызовы несут на себе некоторые издержки во время выполнения, которые замедляют метакалирование. Цель моего расширения - только оптимизация. Таким образом, семантически цели и расширенные цели эквивалентны.Ограничение цели goal_expansion/6 только для компиляции

Как отключить такие вызовы во время выполнения?

(Кажется, мне пришлось бы отменить goal_expansion/6, который выглядит немного грубым для меня. Это также помешает lightweight recompilation).

+2

Я бы даже поддержал мнение о том, что оптимизация является единственным законным использованием расширения * цели *. Это означало бы, что оно всегда является необязательным и, вероятно, не должно быть сделано автоматически для метаколлажей и, возможно, даже утверждает. – jschimpf

+1

@jschimpf: (только для спекуляций) Возможно, в других целях используется некоторая специальная обработка мета-аргументов или макроподобных вещей. Не то чтобы я знал о таком использовании. Например: добавление отладочной информации. – false

ответ

4

Обходным решением было бы назвать предикат prolog_load_context/2. Что-то вроде:

goal_expansion(...) :- 
    prolog_load_context(source, _), 
    % compile-time; expand the goal 
    ... . 

prolog_load_context/2 предикат преуспевает только во время компиляции.

5

Идиоматический способ заключается в загрузке кода времени с использованием load_files/3 с опцией when(compile_time). К сожалению, это не поможет, если вы хотите (повторно) скомпилировать в том же процессе, в котором вы затем запускаете свой код.

Использование abolish для удаления определения goal_expansion/5 также не является идеальным (так как оно исчезнет, ​​если вы затем повторно скомпилируете его). Это не так плохо/грубо, как кажется: goal_expansion/5 на каждый модуль, поэтому вы можете отменить его, не опасаясь, что вы уничтожите некоторые функции в каком-либо другом модуле.