How to obtain the name of a constant given it's value?

Suppose we have defined some const MY_CONST_NAME = 1. Then we have some function x = returnSomeNumber() which returns 1. Is it possible to print MY_CONST_NAME instead of 1 given the value of x without using, e.g., an additional dictionary? In some sense a “back-referencing”.
Many thanks in advance.

I think you would have to use a dictionary for this, and enter all you constants into the dictionary.

julia> AllConsts = Dict([1 => :MY_CONST_NAME, 2 => :MY_OTHER_CONST,pi => :π])
Dict{Float64, Symbol} with 3 entries:
  3.141592653589793 => :π
  2.000000000000000 => :MY_OTHER_CONST
  1.000000000000000 => :MY_CONST_NAME

julia> AllConsts[1.0*pi]
:π

julia> AllConsts[1]
:MY_CONST_NAME

julia> AllConsts[pi-1e-15]
ERROR: KeyError: key 3.141592653589792 not found
Stacktrace:
 [1] getindex(h::Dict{Float64, Symbol}, key::Float64)
   @ Base ./dict.jl:498
 [2] top-level scope
   @ REPL[29]:1

In a dict you can use all kinds of object as keys, not only numbers and strings but also arrays.
You have to keep in mind though that this only works up to floating point precision…

You could also go through all the names in the current module and search for a constant that has the requested value:

function findconst(mod, val)
  predicate = x->isconst(mod, x) && isequal(getproperty(mod, x), val)
  return filter(predicate, names(mod))
end

const b = 23
const c = 23.0

julia> findconst(@__MODULE__, 23)
2-element Vector{Symbol}:
 :b
 :c

(Replace isequal by another test such as === depending on what you want, but note that some tests can fail, for example == will cause the filter to fail on missing values.)

In general I think this kind of things should be avoided, it looks like a hack to work around a problem in the code which will make it harder to understand. But maybe you have a good reason to do it!

This may be an instance of XY problem, where you ask for help for what you think is a solution for your task, instead of giving a better overview of your actual task at hand, which may (or may not!) have a more straightforward solution.

3 Likes

You are seemingly right, here the actual task: I use CPLEX which has defined many constants. CPLEX functions return a number meaning a specific constant, e.g, CPX_CALLBACK_MIP_INCUMBENT_MIPSTART = 119. The constant name is easy to interpet while the number is not. I was wondering if there exists an easy way for doing the back-mapping.

Note: I just noticed that many CPLEX constants point to the same number, thus, the approach of my initial question would not work because of ambiguity for this use case anyway.