- }
-
- unsigned replacements;
- bool something_changed=false;
-
- exvector::iterator it=v_contracted.begin();
- while (it!=v_contracted.end()) {
- // process only lor_g objects
- if (is_ex_exactly_of_type(*it,simp_lor) &&
- (ex_to_simp_lor(*it).type==simp_lor::simp_lor_g)) {
- simp_lor const & g=ex_to_simp_lor(*it);
- GINAC_ASSERT(g.seq.size()==2);
- idx const & first_idx=ex_to_lorentzidx(g.seq[0]);
- idx const & second_idx=ex_to_lorentzidx(g.seq[1]);
- // g_{mu,mu} should have been contracted in simp_lor::eval()
- GINAC_ASSERT(!first_idx.is_equal(second_idx));
- ex saved_g=*it; // save to restore it later
-
- // try to contract first index
- replacements=0;
- if (first_idx.is_symbolic()) {
- replacements = subs_index_in_exvector(v_contracted,
- first_idx.toggle_covariant(),second_idx);
- if (replacements==0) {
- // not contracted, restore g object
- *it=saved_g;
- } else {
- // a contracted index should occur exactly once
- GINAC_ASSERT(replacements==1);
- *it=exONE();
- something_changed=true;
- }
- }
-
- // try second index only if first was not contracted
- if ((replacements==0)&&(second_idx.is_symbolic())) {
- // first index not contracted, *it is again the original g object
- replacements = subs_index_in_exvector(v_contracted,
- second_idx.toggle_covariant(),first_idx);
- if (replacements==0) {
- // not contracted except in itself, restore g object
- *it=saved_g;
- } else {
- // a contracted index should occur exactly once
- GINAC_ASSERT(replacements==1);
- *it=exONE();
- something_changed=true;
- }
- }
- }
- ++it;
- }
-
- // process only lor_vec objects
- bool jump_to_next=false;
- exvector::iterator it1=v_contracted.begin();
- while (it1!=v_contracted.end()-1) {
- if (is_ex_exactly_of_type(*it1,simp_lor) &&
- (ex_to_simp_lor(*it1).type==simp_lor::simp_lor_vec)) {
- exvector::iterator it2=it1+1;
- while ((it2!=v_contracted.end())&&!jump_to_next) {
- if (is_ex_exactly_of_type(*it2,simp_lor) &&
- (ex_to_simp_lor(*it2).type==simp_lor::simp_lor_vec)) {
- simp_lor const & vec1=ex_to_simp_lor(*it1);
- simp_lor const & vec2=ex_to_simp_lor(*it2);
- GINAC_ASSERT(vec1.seq.size()==1);
- GINAC_ASSERT(vec2.seq.size()==1);
- lorentzidx const & idx1=ex_to_lorentzidx(vec1.seq[0]);
- lorentzidx const & idx2=ex_to_lorentzidx(vec2.seq[0]);
- if (idx1.is_symbolic() &&
- idx1.is_co_contra_pair(idx2) &&
- sp.is_defined(vec1,vec2)) {
- *it1=sp.evaluate(vec1,vec2);
- *it2=exONE();
- something_changed=true;
- jump_to_next=true;
- }
- }
- ++it2;
- }
- jump_to_next=false;
- }
- ++it1;
- }
- if (something_changed) {
- return mul(v_contracted);
- }
- return m;
-}
-
-ex simplify_simp_lor(ex const & e, scalar_products const & sp)
-{
- // all simplification is done on expanded objects
- ex e_expanded=e.expand();
-
- // simplification of sum=sum of simplifications
- if (is_ex_exactly_of_type(e_expanded,add)) {
- ex sum=exZERO();
- for (int i=0; i<e_expanded.nops(); ++i) {
- sum += simplify_simp_lor(e_expanded.op(i),sp);
- }
- return sum;
- }
-
- // simplification of commutative product=commutative product of simplifications
- if (is_ex_exactly_of_type(e_expanded,mul)) {
- return simplify_simp_lor_mul(e,sp);
- }
-
- // cannot do anything
- return e_expanded;
-}
-
-ex Dim(void)
-{
- static symbol * d=new symbol("dim");
- return *d;