2016-10-21 14 views
2

call(Goal,Arg) позволяет добавить аргумент Arg к аргументам цели и вызвать результирующую цель, например.Могу ли я добавить список аргументов в call/2?

call(succ(1), R). 

такая же, как

succ(1, R). 

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

callpre(succ(1), R). 

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

succ(R, 1). 

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

+1

[Аналогичный вопрос для 'maplist'] (HTTP : //stackoverflow.com/questions/36582088/is-there-a-better-method-than-making-a-new-rule-to-change-variable-order-for-map). Я бы предпочел ответ, который не «использует эту библиотеку», хотя это то, что мы получаем по этому вопросу. – Fatalize

+2

Неверное описание 'call/2' в первом предложении вашего вопроса. 'call/2' не принимает список аргументов' Goal' во втором аргументе. Он принимает один дополнительный аргумент в «Цель», как вы потом правильно описываете. – Eyal

+0

@Eyal спасибо, исправил это. – morxa

ответ

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, *). 
+1

Интересно, что произойдет, если Goal принимает 3 или более аргумента. –

+1

Ваша декларация meta_predicate хорошо обозначена, но неточна. Это скорее должно быть:: - meta_predicate (:, *) '. Только «1» означает, что один аргумент отсутствует ** и **, который нужно вызвать с помощью «call (G_1, A_1)». Именно эту вторую часть вы нарушаете. – false

+0

@Boris: Вы можете уточнить? – false

1

Вы могли бы определить, что, как:

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

если цель имеет более чем аргументы, которые вы могли бы написать:

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

+0

Спасибо за опечатку и исправление !!, отредактировал сообщение. – coder

 Смежные вопросы

  • Нет связанных вопросов^_^