Welcome to Cadabra Q&A, where you can ask questions and receive answers from other members of the community.
+1 vote

Consider the following:

{a,b,c}::Indices(vector, position=independent).
{i,j,k}::Indices(isospin, position=independent).

bool1 = $\Lambda_{a}$.matches($\Lambda_{i}$);

bool2 = $\Lambda_{a}$.matches($\Lambda^{i}$);

bool1 evaluates to False, while bool2 evaluates to True.

The same behavior occurs if we use position=fixed. However, for position=free, both evaluate to False (as expected). This would seem to be a bug.

in Bug reports by (1.1k points)

1 Answer

+1 vote

Pattern matching has a lot of different branches to handle these days... The underlying C++ matcher returns a variety of more subtle answers (not just true or false) and I did not map that to true/false correctly.

Now fixed in github.

by (83.1k points)

Precisely for these kind of things Ex_comparator has functions like match_subproduct and match_subsum. I just never wrote anything like that on the Python side.

Those examples all work as intended, even though I understand the results are not particularly useful for you.

ExNode.compare(...) may get you a bit further, but will probably still not be enough. Let me know, it may be time to export Ex_comparator.

After taking a peak at your implementation of zoom.cc, I realize I could just do the same thing on the Python side: recast the list of patterns as dummy rules and then just use substitute and see if it does anything. But since Python doesn't have access to can_apply, I think this may involve making copies of each ExNode. I've no idea how slow that will be.

I may also see if I can modify zoom.cc to handle a list of rules. From your implementation, it seems all I need to do is to change the code that wraps the rules. But that requires me to understand more C++. :-)

Thanks for handling all my recent questions, by the way. I've been trying to port my old very bad code for arxiv:1609.09083 and make it cleverer (as an excuse to learn python).

I think this is trivial to do on the C++ side by modifying zoom.cc, and useful as an addition anyway. If you don't feel digging into that, let me know and I will do it later tonight.

Hi Kasper. I wasn't sure I should be so presumptuous to put this somewhere on Github, but I think the following does the trick.

In zoom.cc, replace zoom::zoom contents with:

// Convert rules into a list (if it isn't already)
rules = cadabra::make_list(rules);

// Iterate over the list
cadabra::do_list(rules, rules.begin(), [&](Ex::iterator it) {
    // Create a proper substitution rule out of the pattern (otherwise
    // substitute will not swallow it).

    auto wrap = rules.wrap(it, str_node("\\arrow"));
    rules.append_child(wrap, str_node("dummy"));
    return true;
});

This acts as

ex := A1 x+A2 y + A3 z.
zoom(ex, ${x A??, y A??});

and returns

A1 x + A2 y + ...

It also preserves the original behavior if the argument is not a list.

See, that wasn't so hard ;-) I have pushed this to github now.

...