В коде, который вы показываете, есть несколько проблем.
Плохой мета-аргумент
Во-первых, встроенный предикат setof/3
имеет следующие свойства:
| ?- predicate_property(setof(A,B,C),P).
P = (meta_predicate setof(?,0,?)) ? ;
P = built_in ? ;
P = jittable ? ;
no
что близко соответствует декларациям ISO в ISO/IEC 13211-1:
8.10.3.2 Шаблон и режимы
setof(?term, +callable_term, ?list)
Второй аргумент — это цель, которую должен выполнить call/1
. Никаких дополнительных аргументов не требуется. Об этом говорит нам 0
.
С другой стороны, ваш код, который вы показываете, содержит другое объявление метапредиката:
:- meta_predicate set_of(+,:,+) .
Здесь второй аргумент — это :
. В SICStus, YAP и SWI :
означает: Этот аргумент будет автоматически уточняться текущим модулем, чтобы информация о модуле могла передаваться дальше. Подумайте о asserta(:)
. Здесь аргумент является не целью, а условием.
Итак, что вам нужно исправить, это заменить :
на 0
. И вы можете указать этот факт в используемом имени переменной. То есть Goal_0
вместо call(Goal_0)
, Goal_1
вместо call(Goal_1, Arg1)
, Goal_2
вместо call(Goal_2, Arg1, Arg2)
и т. д.
Плохие режимы
+
в первом и третьем аргументе неуместно. Третий аргумент обычно представляет собой переменную без инстанции, которая должна быть объединена с результирующим списком.
setof/3
барокко Пролога?
% Прологи set_of вычурны
Комментарий, наверное, хочет сказать, что setof/3
содержит лишние украшения. На самом деле setof/3
гораздо более универсален, чем упомянутый set_of/3
. Возьмите этот недавний вопрос или что. Часто вы сначала думаете об очень конкретной ситуации. Скажем, вам нужен список актеров определенного фильма. Затем, позже, вы хотите спросить, какие есть фильмы. Именно это обобщение очень хорошо работает с setof/3
, тогда как без него оно чрезвычайно сложно.
Еще один очень полезный способ использования setof/3
— это когда вы хотите исключить избыточные ответы:
| ?- (X = 2;X=1;X=2).
X = 2 ? ;
X = 1 ? ;
X = 2 ? ;
no
| ?- setof(t, (X=2;X=1;X=2), _).
X = 1 ? ;
X = 2 ? ;
no
Попробуйте подражать этому эффективно.
Накладные расходы во время выполнения
Они близки к ничтожным. Если вы действительно считаете, что есть накладные расходы, просто используйте setof/3
с единственной целью. Таким образом, предварительная обработка практически бесполезна.
person
false
schedule
15.06.2014