将Prolog谓词拆分为两部分,并在其间执行一些代码

将Prolog谓词拆分为两部分,并在其间执行一些代码,prolog,Prolog,假设我有一个用户可以像这样编写Prolog谓词pred/2: pred('an atom chosen by the user', OutputList) :- %Part 1 %Here he can write every Prolog predicate that he wants %and before split_here he has to inizialize the OutputList ... split_here, %this is a special

假设我有一个用户可以像这样编写Prolog谓词
pred/2

pred('an atom chosen by the user', OutputList) :-
  %Part 1
  %Here he can write every Prolog predicate that he wants
  %and before split_here he has to inizialize the OutputList
  ...

  split_here, %this is a special fact that that says where to split

  %Part 2
  %Here he can write every Prolog predicate that he wants
  ...
clause(pred(X, OutputList), Body),
split(Body, split_here, Part1Goals, Part2Goals),
call(Part1Goals),
engine_code,
call(Part2Goals),
...
然后,我有一种引擎,它试图执行用户定义的
pred/2
,但为了提高效率,它需要在声明
split\u
的地方执行一些代码(比如一个谓词
engine\u code/0

如何实现此模式

第1部分和第2部分中的变量可以共享,而
engine\u code/0
只关注
OutputList
(它包含什么类型的术语并不重要)

你能想出一个简单的方法来实现这一点吗?

现在,我使用
子句/2
如下:

pred('an atom chosen by the user', OutputList) :-
  %Part 1
  %Here he can write every Prolog predicate that he wants
  %and before split_here he has to inizialize the OutputList
  ...

  split_here, %this is a special fact that that says where to split

  %Part 2
  %Here he can write every Prolog predicate that he wants
  ...
clause(pred(X, OutputList), Body),
split(Body, split_here, Part1Goals, Part2Goals),
call(Part1Goals),
engine_code,
call(Part2Goals),
...
似乎当我用
engine\u code/0
编写
call(Part1Goals)
call(Part2Goals)
时,变量不会被共享

例如:

pred(userPred, OutputList) :-
  findall(myTerm(X,Y,Z), myTerm(X,Y,Z), OutputList),
  split_here,
  member(myTerm(X,_,_), OutputList),
  use_x(X).

一种可能的解决方案是使用目标扩展机制,用对
引擎代码/0
谓词的调用替换此处的
分割标记。转换将在加载用户代码时完成。术语和目标扩展机制在一些Prolog系统中可用。对于大多数编译器系统的可移植解决方案,可以使用Logtalk的机制实现。例如:

---- user.pl ----
pred(userPred, OutputList) :-
  findall(myTerm(X,Y,Z), myTerm(X,Y,Z), OutputList),
  split_here,
  member(myTerm(X,_,_), OutputList),
  use_x(X).
-----------------
目标扩展代码:

---- hook.lgt ----
:- object(hook, implements(expanding)).

    goal_expansion(split_here, engine_code).

:- end_object.
-----------------
来自顶层的示例用法。首先,加载Prolog文件,用
hook
对象展开它:

| ?- logtalk_load('user.pl', [hook(hook)]).
...
其次,只需调用转换后的用户谓词:

| ?- pred(userPred, OutputList).
...

这对您有用吗?

在向动态谓词添加子句时执行您想要的转换如何?现在我找到了一种方法使我的工作正常,但我也喜欢您的想法。split_here谓词的必要性是因为我没有考虑这个可能性。谢谢