Могу ли я добавить список аргументов в call/2?

Вызов (Goal,Arg) позволяет добавить аргумент Arg к аргументам Goal и вызвать полученную цель, например

call(succ(1), R).

такой же как

succ(1, R).

Тем не менее, я не хочу добавлять в список аргументов, а вместо этого добавить, например,

callpre(succ(1), R).

должно привести к

succ(R, 1).

Как я могу добавить аргументы к списку аргументов цели и назвать конечную цель?

2 ответа

Решение

Для произвольного числа аргументов вы можете определить его как

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

Вам также понадобится meta_predicate/1 декларация для этого:

:- meta_predicate callpre(1, *). 

Вы можете определить это как:

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],

Другие вопросы по тегам