+ // 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 (size_t 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 (size_t 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)
+ size_t num = ops.size();
+ std::auto_ptr<epvector> vp(new epvector);
+ vp->reserve(num);
+ for (size_t i=0; i<num; i++)
+ vp->push_back(split_ex_to_pair(ops[i]));
+ ex rest = thisexpairseq(vp, default_overall_coeff());
+ for (lst::const_iterator it = repl_lst.begin(); it != repl_lst.end(); ++it) {
+ if (it->op(0).is_equal(global_wildcard))
+ return rest.is_equal(it->op(1));
+ }
+ 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);
+}
+
+ex expairseq::subs(const exmap & m, unsigned options) const