Я думаю, что это проблема, связанная с объемом. Если у меня есть правило для моего объекта, подобное этому:
:- public(new/2).
:- mode(new(+list, -object_identifier), one).
new(Args, Instance) :-
self(Self),
create_object(Instance, [instantiates(Self)], [], []),
Instance::process_arguments(Args).
Я считаю, что это прекрасно работает, если я исполняю этот танец:
:- object(name, instantiates(name)).
Я не совсем понимаю, почему это необходимо, но я подозреваю, что это связано с моей реальной проблемой, которая заключается в том, что, если у меня есть стандартный цикл Prolog в моем объекте, например, так:
process_arguments([Arg|Args]) :- process_arg(Arg), process_arguments(Args).
process_arguments([]).
process_arg(Arg) :- ::asserta(something(Arg)).
Я считаю, что использование ::asserta
помещает факты в правильное пространство имен (во вновь созданном экземпляре). Однако, если я остроумен и заменю тело process_arguments/1
этим лямбда-выражением:
process_arguments(Args) :- meta::map([Arg]>>process_arg(Arg), Args).
затем я обнаруживаю, что мои факты добавляются в родительский класс и передаются всем экземплярам. Если я заменю это следующим:
process_arguments(Args) :-
self(Self),
meta::map([Arg]>>(Self::process_arg(Arg)), Args).
тогда это работает, но я должен сделать process_arg/1
публичным правилом, когда я бы предпочел этого не делать. Что мне не хватает?