@@ -36,7 +36,7 @@ Algorithm::result_t combine::apply(iterator& it)
3636
3737 while (ind_dummy.begin ()!=ind_dummy.end ()) {
3838 bool found=false ;
39- index_map_t ::iterator start=ind_dummy.begin ();
39+ index_map_t ::iterator start=ind_dummy.begin (), backup ;
4040 while (!found && start!=ind_dummy.end ()) {
4141 iterator parent=tr.parent (start->second );
4242 sibling_iterator ch=tr.begin (parent), last_part;
@@ -46,11 +46,17 @@ Algorithm::result_t combine::apply(iterator& it)
4646 ++ch;
4747 }
4848 if (last_part==start->second ) {
49- // We are on a rightmost contracted index
50- found=true ;
49+ ++last_part;
50+ if (last_part==tr.end (parent)) {
51+ // Dummy index with nothing to the right is preferred
52+ found=true ;
53+ }
54+ else backup=start;
5155 }
52- else ++start;
56+ if (!found) ++start;
5357 }
58+ // As a backup, we use a dummy index with only non-dummies to the right
59+ if (!found) start=backup;
5460 bool paired=true ;
5561 while (paired && start!=ind_dummy.end ()) {
5662 iterator parent=tr.parent (start->second );
@@ -133,6 +139,38 @@ Algorithm::result_t combine::apply(iterator& it)
133139 iterator brackprod=tr.append_child (outerbrack, str_node (" \\ prod" ));
134140 iterator parn1=tr.parent (*dums1);
135141 iterator parn2=tr.parent (*dums2);
142+
143+ // count how many sign changes stand between the two objects
144+ int sign=1 ;
145+ unsigned int hits=0 ;
146+ Ex_comparator compare (kernel.properties );
147+ sib=tr.begin (it);
148+ while (hits<2 ) {
149+ if (hits==1 && sib!=parn2) {
150+ // pass arguments manually as can_swap() does not check them
151+ bool isbrack=*(sib->name )==" \\ indexbracket" ;
152+ if (isbrack && isbrack2) {
153+ auto es=compare.equal_subtree (tr.begin (parn2), tr.begin (sib));
154+ sign*=compare.can_swap (tr.begin (parn2), tr.begin (sib), es, true );
155+ }
156+ else if (isbrack && !isbrack2) {
157+ auto es=compare.equal_subtree (parn2, tr.begin (sib));
158+ sign*=compare.can_swap (parn2, tr.begin (sib), es, true );
159+ }
160+ else if (!isbrack && isbrack2) {
161+ auto es=compare.equal_subtree (tr.begin (parn2), sib);
162+ sign*=compare.can_swap (tr.begin (parn2), sib, es, true );
163+ }
164+ else {
165+ auto es=compare.equal_subtree (parn2, sib);
166+ sign*=compare.can_swap (parn2, sib, es, true );
167+ }
168+ }
169+ if (sib==parn1 || sib==parn2) ++hits;
170+ ++sib;
171+ }
172+ if (sign==-1 ) flip_sign (brackprod->multiplier );
173+
136174 // remove the dummy index from these two objects, and move
137175 // other (dummy or not) indices to the outer indexbracket.
138176 sibling_iterator ind1=tr.begin (tr.parent (*dums1));
0 commit comments