Итак, я изучаю пролог.Одна из вещей, которые я нашел действительно неприятными, продемонстрирована в следующем примере:
foreach(
between(1,10,X),
somePredicate(X,X+Y,Result)
).
Это не работает.Я хорошо знаю, что X + Y здесь не оценивается, и вместо этого я должен был бы сделать:
foreach(
between(1,10,X),
(
XPlusY is X + Y,
somePredicate(X, XPlusY, Result)
)
).
Кроме того, это тоже не работает.Насколько я могу судить, область действия XPlusY
выходит за пределы foreach
, т. Е., XPlusY is 1 + Y, XPlusY is 2 + Y,
и т. Д. Должны быть истинными сразу, и не существует XPlusY, для которого это имеет место.Поэтому я должен сделать следующее:
innerCode(X, Result) :-
XPlusY is X + Y,
somePredicate(X, XPlusY, Result).
...
foreach(
between(1,10,X),
innerCode(X, Result)
).
Это, наконец, работает.(По крайней мере, я так думаю. Я не пробовал этот точный код, но этот путь я выбрал ранее от «не работает» до «работает».) Это нормально и все, кроме того, что этоисключительно неприятный.Если бы у меня был способ вычисления арифметических операций в строке, я мог бы вдвое сократить строки кода, сделать его более читабельным и НЕ создавать одноразовый предикат беспорядка.
Вопрос: есть лиспособ оценить арифметические операции в строке, не объявляя новую переменную?
Если это не удастся, было бы приемлемо (и, в некоторых случаях, все еще полезно для других вещей), если бы был способограничить область применения новых переменных.Предположим, например, что вы можете определить блок в foreach
, где были помечены видимые извне переменные, а любые другие переменные в блоке считались новыми для этого выполнения блока.(Я понимаю, что моя терминология может быть неправильной, но, надеюсь, она все поймет.) Например, что-то похожее:
foreach(
between(1,10,X),
(X, Result){
XPlusY is X + Y,
somePredicate(X, XPlusY, Result)
}
).
Возможное решение может быть, если мы можем объявить лямбда-строку и немедленноназови это.Суммировано:
Альтернативный вопрос: есть ли способ ограничить область применения новых переменных в предикате, сохраняя при этом возможность выполнять длительные объединения для одной или нескольких существующих переменных?
(Вторую половину я добавил в качестве пояснения в ответ на ответ о forall
.)
Решение обоих вопросов предпочтительнее, но решения любого из них будет достаточно.