% test of DUMMY package version 1.1 running in REDUCE 3.6 and 3.7
% DATE: 15 September 1998
% Authors: H. Caprasse <hubert.caprasse@ulg.ac.be>
%
% Case of commuting operator:
%
operator co1,co2;



% declare dummy indices

% first syntax : base <name>
%
dummy_base dv;


dv


% dummy indices are dv1, dv2, dv3, ...

exp := co2(dv2)*co2(dv2)$


c_exp := canonical(exp);


                 2
c_exp := co2(dv1)


exp := dv2*co2(dv2)*co2(dv2)$


c_exp := canonical(exp);


                 2
c_exp := co2(dv1) *dv1


exp := c_exp * co1(dv3);


                        2
exp := co1(dv3)*co2(dv1) *dv1

c_exp := canonical(exp);


                          2
c_exp := co1(dv2)*co2(dv1) *dv1


%
operator a,aa,dd,te;



clear_dummy_base;


t


dummy_names a1,a2,b1,b2,mu1,mu2,nu1,nu2;


t


es1:=a(a1,b1)*a(a2,b2);


es1 := a(a1,b1)*a(a2,b2)


asn14:=aa(mu1,a1)*aa(nu2,b2)*dd(nu1,b1,mu2,a2)
         *te(mu1,mu2,nu1,nu2);


asn14 := aa(mu1,a1)*aa(nu2,b2)*dd(nu1,b1,mu2,a2)*te(mu1,mu2,nu1,nu2)

asn17:=aa(mu1,a1)*aa(mu2,a2)*dd(nu1,b1,nu2,b2)
          *te(mu1,mu2,nu1,nu2);


asn17 := aa(mu1,a1)*aa(mu2,a2)*dd(nu1,b1,nu2,b2)*te(mu1,mu2,nu1,nu2)

             
esn14:=es1*asn14;


esn14 := 

a(a1,b1)*a(a2,b2)*aa(mu1,a1)*aa(nu2,b2)*dd(nu1,b1,mu2,a2)*te(mu1,mu2,nu1,nu2)

esn17:=es1*asn17;


esn17 := 

a(a1,b1)*a(a2,b2)*aa(mu1,a1)*aa(mu2,a2)*dd(nu1,b1,nu2,b2)*te(mu1,mu2,nu1,nu2)

esn:=es1*(asn14+asn17);


esn := a(a1,b1)*a(a2,b2)*aa(mu1,a1)*te(mu1,mu2,nu1,nu2)

       *(aa(mu2,a2)*dd(nu1,b1,nu2,b2) + aa(nu2,b2)*dd(nu1,b1,mu2,a2))
 
canonical esn;


a(a1,a2)*a(b1,b2)*aa(mu2,b1)*(aa(mu1,a1)*dd(nu1,b2,nu2,a2)*te(mu2,mu1,nu1,nu2)

    + aa(mu1,a2)*dd(nu1,b2,nu2,a1)*te(mu2,nu2,nu1,mu1))

% that the next result is correct is not trivial 
% to show.
% for esn14 changes of names are 
%
%  nu1 -> nu1
%  b1 -> b2 -> a2
%  mu2 -> nu2 -> mu1 -> mu2
%    
% for esn17 they are
%
%  nu1 -> nu1
%  nu2 -> nu2
%  b1 -> b2 -> a2 -> a1 -> b1
%
% the last result should be zero 
canonical esn -(canonical esn14 +canonical esn17);


0

% remove dummy_names and operators.
clear_dummy_names;


t

clear a,aa,dd,te;


%
% Case of anticommuting operators
%
operator ao1, ao2;


anticom ao1, ao2;


t

% product of anticommuting operators with FREE indices
a_exp := ao1(s1)*ao1(s2) - ao1(s2)*ao1(s1);


a_exp := ao1(s1)*ao1(s2) - ao1(s2)*ao1(s1)

a_exp := canonical(a_exp);


a_exp := 2*ao1(s1)*ao1(s2)


% the indices are summed upon, i.e. are DUMMY indices

clear_dummy_names;


t


dummy_base dv;


dv


a_exp := ao1(dv1)*ao1(dv2)$


canonical(a_exp);


0


a_exp := ao1(dv1)*ao1(dv2) - ao1(dv2)*ao1(dv1);


a_exp := ao1(dv1)*ao1(dv2) - ao1(dv2)*ao1(dv1)

a_exp := canonical(a_exp);


a_exp := 0


a_exp := ao1(dv2,dv3)*ao2(dv1,dv2)$


a_exp := canonical(a_exp);


a_exp := ao1(dv1,dv2)*ao2(dv3,dv1)


a_exp := ao1(dv1)*ao1(dv3)*ao2(dv3)*ao2(dv1)$


a_exp := canonical(a_exp);


a_exp :=  - ao1(dv1)*ao1(dv2)*ao2(dv1)*ao2(dv2)


% Case of non commuting operators
%
operator no1, no2, no3;


noncom no1, no2, no3;



n_exp := no3(dv2)*no2(dv3)*no1(dv1) + no3(dv3)*no2(dv1)*no1(dv2)
         + no3(dv1)*no2(dv2)*no1(dv3);


n_exp := no3(dv1)*no2(dv2)*no1(dv3) + no3(dv2)*no2(dv3)*no1(dv1)

          + no3(dv3)*no2(dv1)*no1(dv2)


n_exp:=canonical n_exp;


n_exp := 3*no3(dv3)*no2(dv2)*no1(dv1)


% ***
% The example below displays a restriction of the package i.e
% The non commuting operators are ASSUMED to COMMUTE with the
% anticommuting operators.
% ***
exp := co1(dv1)*ao1(dv2,dv1,dv4)*no1(dv1,dv5)*co2(dv3)*ao1(dv1,dv3);


exp := co1(dv1)*co2(dv3)*(ao1(dv2,dv1,dv4)*no1(dv1,dv5)*ao1(dv1,dv3))

canonical(exp);


 - co1(dv1)*co2(dv2)*ao1(dv1,dv2)*ao1(dv3,dv1,dv4)*no1(dv1,dv5)


exp := c_exp * a_exp * no3(dv2)*no2(dv3)*no1(dv1);


                           2
exp :=  - co1(dv2)*co2(dv1) *dv1*ao1(dv1)*ao1(dv2)*ao2(dv1)*ao2(dv2)*no3(dv2)

       *no2(dv3)*no1(dv1)

can_exp := canonical(exp);


                               2
can_exp :=  - co1(dv2)*co2(dv1) *dv1*ao1(dv1)*ao1(dv2)*ao2(dv1)*ao2(dv2)

           *no3(dv2)*no2(dv3)*no1(dv1)


% Case where some operators have a symmetry.
%
operator as1, as2;


antisymmetric as1, as2;



dummy_base s;


s


% With commuting and antisymmetric:

asc_exp:=as1(s1,s2)*as1(s1,s3)*as1(s3,s4)*co1(s3)*co1(s4)+
        2*as1(s1,s2)*as1(s1,s3)*as1(s3,s4)*co1(s2)*co1(s4)$



canonical asc_exp;


as1(s1,s2)*as1(s1,s3)*as1(s3,s4)*co1(s3)*co1(s4)


% Indeed: the second term is identically zero as one sees 
%          if the substitutions s2->s4, s4->s2 and 
%           s1->s3, s3->s1 are sucessively done.
% 
% With anticommuting and antisymmetric operators:

dummy_base dv;


dv


exp1 := ao1(dv1)*ao1(dv2)$


canonical(exp1);


0


exp2 := as1(dv1,dv2)$



canonical(exp2);


0


canonical(exp1*exp2);


as1(dv1,dv2)*ao1(dv1)*ao1(dv2)


canonical(as1(dv1,dv2)*as2(dv2,dv1));


 - as1(dv1,dv2)*as2(dv1,dv2)


% With symmetric and antisymmetric operators:

operator ss1, ss2;


symmetric ss1, ss2;



exp := ss1(dv1,dv2)*ss2(dv1,dv2) - ss1(dv2,dv3)*ss2(dv2,dv3);


exp := ss1(dv1,dv2)*ss2(dv1,dv2) - ss1(dv2,dv3)*ss2(dv2,dv3)

canonical(exp);


0


exp := as1(dv1,dv2)*as1(dv3,dv4)*as1(dv1,dv4);


exp := as1(dv1,dv2)*as1(dv1,dv4)*as1(dv3,dv4)

canonical(exp);


0


% The last result is equal to half the sum given below:
%
exp + sub(dv2 = dv3, dv3 = dv2, dv1 = dv4, dv4 = dv1, exp);


0


exp1 := as2(dv3,dv2)*as1(dv3,dv4)*as1(dv1,dv2)*as1(dv1,dv4);


exp1 :=  - as1(dv1,dv2)*as1(dv1,dv4)*as1(dv3,dv4)*as2(dv2,dv3)

canonical(exp1);


as1(dv1,dv2)*as1(dv1,dv3)*as1(dv3,dv4)*as2(dv2,dv4)


exp2 := as2(dv1,dv4)*as1(dv1,dv3)*as1(dv2,dv4)*as1(dv2,dv3);


exp2 := as1(dv1,dv3)*as1(dv2,dv3)*as1(dv2,dv4)*as2(dv1,dv4)

canonical(exp2);


as1(dv1,dv2)*as1(dv1,dv3)*as1(dv3,dv4)*as2(dv2,dv4)


canonical(exp1-exp2);


0


% Indeed:
%
exp2 - sub(dv1 = dv3, dv2 = dv1, dv3 = dv4, dv4 = dv2, exp1);


0


% Case where mixed or incomplete symmetries for operators are declared.

% Function 'symtree' can be used to declare an operator symmetric 
% or antisymmetric:
operator om;



symtree(om,{!+,1,2,3});


exp:=om(dv1,dv2,dv3)+om(dv2,dv1,dv3)+om(dv3,dv2,dv1);


exp := om(dv1,dv2,dv3) + om(dv2,dv1,dv3) + om(dv3,dv2,dv1)

canonical exp;


3*om(dv1,dv2,dv3)


% Declare om to be antisymmetric in the two last indices ONLY:
symtree(om,{!*,{!*,1},{!-,2,3}});


canonical exp;


0
 

% With an antisymmetric operator m:
operator m;


dummy_base s;


s

exp := om(nu,s3,s4)*i*psi*(m(s1,s4)*om(mu,s1,s3) 
+ m(s2,s3)*om(mu,s4,s2) - m(s1,s3)*om(mu,s1,s4) 
- m(s2,s4)*om(mu,s3,s2))$



canonical exp;


 - 4*m(s1,s2)*om(mu,s1,s3)*om(nu,s2,s3)*i*psi


% Case of the Riemann tensor
%
operator r;


symtree (r, {!+, {!-, 1, 2}, {!-, 3, 4}});


% Without anty dummy indices.
clear_dummy_base;


t


exp := r(dv1, dv2, dv3, dv4) * r(dv2, dv1, dv4, dv3)$


canonical(exp);


                  2
r(dv1,dv2,dv3,dv4)


% With dummy indices:
 
dummy_base dv;


dv


canonical( r(x,y,z,t) );


 - r(t,z,x,y)

canonical( r(x,y,t,z) );


r(t,z,x,y)

canonical( r(t,z,y,x) );


 - r(t,z,x,y)


exp := r(dv1, dv2, dv3, dv4) * r(dv2, dv1, dv4, dv3)$


canonical(exp);


                  2
r(dv1,dv2,dv3,dv4)


exp := r(dv1, dv2, dv3, dv4) * r(dv1, dv3, dv2, dv4)$


canonical(exp);


r(dv1,dv2,dv3,dv4)*r(dv1,dv3,dv2,dv4)


clear_dummy_base;


t

dummy_names i,j,k,l;


t


exp := r(i,j,k,l)*ao1(i,j)*ao1(k,l)$



canonical(exp);


0


exp := r(k,i,l,j)*as1(k,i)*as1(k,j)$


canonical(exp);


 - as1(i,j)*as1(i,k)*r(i,k,j,l)


% Cleanup of the previousy declared dummy variables..

clear_dummy_names;


t
 clear_dummy_base;


t


exp := co1(dv3)$


c_exp := canonical(exp);


c_exp := co1(dv3)


end;

Tested on x86_64-pc-windows CSL
Time (counter 1): 16 ms

End of Lisp run after 0.01+0.04 seconds
real 0.19
user 0.00
sys 0.09
