So I'm learning Prolog. One of the things I've found to be really obnoxious is demonstrated in the following example:
foreach(
between(1,10,X),
somePredicate(X,X+Y,Result)
).
This does not work. I am well aware that X+Y is not evaluated, here, and instead I'd have to do:
foreach(
between(1,10,X),
(
XPlusY is X + Y,
somePredicate(X, XPlusY, Result)
)
).
Except, that doesn't work, either. As near as I can tell, the scope of XPlusY
extends outside of foreach
- i.e., XPlusY is 1 + Y, XPlusY is 2 + Y,
etc. must all be true AT ONCE, and there is no XPlusY for which that is the case. So I have to do the following:
innerCode(X, Result) :-
XPlusY is X + Y,
somePredicate(X, XPlusY, Result).
...
foreach(
between(1,10,X),
innerCode(X, Result)
).
This, finally, works. (At least, I think so. I haven't tried this exact code, but this was the path I took earlier from "not working" to "working".) That's fine and all, except that it's exceptionally obnoxious. If I had a way of evaluating arithmetic operations in-line, I could halve the lines of code, make it more readable, and NOT create a one-use clutter predicate.
Question: Is there a way to evaluate arithmetic operations in-line, without declaring a new variable?
Failing that, it would be acceptable (and, in some cases, still useful for other things) if there were a way to restrict the scope of new variables. Suppose, for instance, you could define a block within the foreach
, where the variables visible from the outside were marked, and any other variables in the block were considered new for that execution of the block. (I realize my terminology may be incorrect, but hopefully it gets the point across.) For example, something resembling:
foreach(
between(1,10,X),
(X, Result){
XPlusY is X + Y,
somePredicate(X, XPlusY, Result)
}
).
A possible solution might be if we can declare a lambda in-line, and immediately call it. Summed up:
Alternate question: Is there a way to limit the scope of new variables within a predicate, while retaining the ability to perform lasting unifications on one or more existing variables?
(The second half I added as clarification in response to an answer about forall
.)
A solution to both questions is preferred, but a solution to either will suffice.