我可以在 call/2 中添加参数列表吗?

Can I prepend the argument list in call/2?

call(Goal,Arg) 允许将参数 Arg 附加到 Goal 的参数并调用结果目标,例如

call(succ(1), R).

相同
succ(1, R).

但是,我不想附加到参数列表,而是在前面添加,例如

callpre(succ(1), R).

应该导致

succ(R, 1).

如何将参数添加到 Goal 的参数列表中并调用生成的目标?

您可以将其定义为:

callpre(Goal,Z):-
  Goal=.. [Predicate, Y],
  Goal2=.. [Predicate, Z],
  call(Goal2,Y).

如果 Goal 有多个参数,您可以这样写:

  callpre(Goal,Z):-
     Goal=.. [Predicate,Arg1| Y],
     reverse([Arg1|Y],[H|T]),
     reverse(T,T1),
     Goal2=.. [Predicate,Z| T1],
     call(Goal2,H).

(这也适用于一个参数)

请注意,=../2 运算符将函子和参数与列表统一起来,例如 succ(X,Y)=.. [succ,X,Y]

对于任意数量的参数,您可以将其定义为

callpre(MGoal, Arg) :-
    strip_module(MGoal, M, Goal), 
    Goal =.. [F | Args],
    NewGoal =.. [F, Arg|Args], 
    M:NewGoal.

您还需要一个 meta_predicate/1 声明:

:- meta_predicate callpre(1, *).