+ if (tinfo() == pattern.bp->tinfo()) {
+
+ // Check whether global wildcard (one that matches the "rest of the
+ // expression", like "*" above) is present
+ bool has_global_wildcard = false;
+ ex global_wildcard;
+ for (unsigned int i=0; i<pattern.nops(); i++) {
+ if (is_ex_exactly_of_type(pattern.op(i), wildcard)) {
+ has_global_wildcard = true;
+ global_wildcard = pattern.op(i);
+ break;
+ }
+ }
+
+ // Unfortunately, this is an O(N^2) operation because we can't
+ // sort the pattern in a useful way...
+
+ // Chop into terms
+ exvector ops;
+ ops.reserve(nops());
+ for (unsigned i=0; i<nops(); i++)
+ ops.push_back(op(i));
+
+ // Now, for every term of the pattern, look for a matching term in
+ // the expression and remove the match
+ for (unsigned i=0; i<pattern.nops(); i++) {
+ ex p = pattern.op(i);
+ if (has_global_wildcard && p.is_equal(global_wildcard))
+ continue;
+ exvector::iterator it = ops.begin(), itend = ops.end();
+ while (it != itend) {
+ if (it->match(p, repl_lst)) {
+ ops.erase(it);
+ goto found;
+ }
+ ++it;
+ }
+ return false; // no match found
+found: ;
+ }
+
+ if (has_global_wildcard) {
+
+ // Assign all the remaining terms to the global wildcard (unless
+ // it has already been matched before, in which case the matches
+ // must be equal)
+ unsigned num = ops.size();
+ epvector *vp = new epvector();
+ vp->reserve(num);
+ for (unsigned i=0; i<num; i++)
+ vp->push_back(split_ex_to_pair(ops[i]));
+ ex rest = thisexpairseq(vp, default_overall_coeff());
+ for (unsigned i=0; i<repl_lst.nops(); i++) {
+ if (repl_lst.op(i).op(0).is_equal(global_wildcard))
+ return rest.is_equal(*repl_lst.op(i).op(1).bp);
+ }
+ repl_lst.append(global_wildcard == rest);
+ return true;
+
+ } else {
+
+ // No global wildcard, then the match fails if there are any
+ // unmatched terms left
+ return ops.empty();
+ }
+ }
+ return inherited::match(pattern, repl_lst);