Here is a partial solution. In principle, one can call
x::Weight(value=1, label=field);
Weight.get($x$, label="field").value("field");
This returns an error because an underlying function is returning value in the mpq_class for precision rational numbers. This needs to be recast.
A bugfix is to edit cadabra2/core/pythoncdb/py_properties.cc and replace
def_abstract_prop<Py_WeightBase>(m, "WeightBase")
.def("value", [](const Py_WeightBase & p,
const std::string& forcedLabel) {
return p.get_prop()->
value(p.get_kernel(), p.get_it(), forcedLabel); });
with
def_abstract_prop<Py_WeightBase>(m, "WeightBase")
.def("value", [](const Py_WeightBase & p, const std::string& forcedLabel) {
// This is mpq_class. We convert it to a string.
return p.get_prop()->
value(p.get_kernel(), p.get_it(), forcedLabel).get_str();
});
Then the given Weight.get routine will work. (It returns the rational as a string. If you want some other return form, you can use a different function than get_str in the mpq_class.)
Unfortunately, it does not seem smart enough to handle more than single term arguments.
Similarly, you can use WeightInherit to get the weights of operators that carry weight, but it doesn't account for the weights of their arguments. In principle, these two functions can be chained together to find the Weight of any expression (assuming it has a definite weight).
I've been trying to write something that will do the trick on the C++ side, but I think the Python side should be straightforward with the above fix.