Library module arithmetic
has provides predicate arithmetic_expression_value/2
:
?- listing(arithmetic_expression_value).
:- meta_predicate arithmetic:arithmetic_expression_value(:,-).
arithmetic:arithmetic_expression_value(M:Expression, Result) :-
eval(Expression, M, Result).
true.
?- arithmetic_expression_value(1+1,V).
V = 2.
And I’m wondering by what magic 1+1
unfies with M:Expression
.
When a predicate is declared as a meta_predicate with “:” (or 0, 1, 2, etc.) then a call adds the module if it’s not already there. So, your arithmetic_expression_value(1+1, V)
, when executed, becomes arithmetic_expression_value(user:(1+1), V)
(or something like that).
1 Like
Thanks, Peter. That complicates using :
as a slice operator, but that’s probably fine as long as it’s only used in a block expression. Currently a naked 2:3
would evaluate to 3
since 2
isn’t a module and 3
is a valid arithmetic value. A workaround is to evaluate _:2:3
which produces the expected value.
To avoid the ambiguity I’d like to perform a quick test to see if M
in M:Expression
is a module name. The fastest I’ve been able to come up with is:
atom(M), module_property(M,_)
Any other suggestions?
Maybe a better solution is to use a different notation. For example "abcdef"[1..3]
.
1 Like
Reasonable suggestion. But I would like to maximize notation choices for the user. (This is a check in library(arithmetic)
.) Even a simple atom
check is sufficient for allowing numeric arguments with the :
operator.