1#############################################################################
2#0
3#F	BarResolutionEquivalence
4##	Input:	A HAP resolution
5##	Output:	An equivariant chain homotopy between the bar & the HAP resolution
6##
7InstallGlobalFunction(BarResolutionEquivalence,function(R)
8local
9	nElts,Elts,e,nR,n,k,
10	SearchPosition,AddElement,HapHomotopy,BarHomotopy,BarBoundary,
11	PsiBasis,BoundBasis,TmpPsi,tmp1,tmp2,sign,base,g,Stmp,
12	Phi,Psi,Equiv;
13
14	Elts:=R!.elts;
15	nElts:=Length(Elts);
16	e:=Identity(R!.group);
17	nR:=EvaluateProperty(R,"length");
18
19	######################################################################
20	#1
21	##	SearchPosition
22	##	Input:	An element g of G
23	##	Output:	The position of g in Elts
24	##
25	SearchPosition:=function(g)
26	local 	n,i;
27
28		n:=Length(Elts);
29		for i in [1..n] do
30			if Elts[i]=g then
31				return i;
32			fi;
33		od;
34		Add(Elts,g);        	#These two lines added by Graham
35		return n+1;   			#
36	end;
37	##
38	############### end of SearchPosition ################################
39
40	######################################################################
41	#1
42	#F	AddElement
43	##	Input:	A list L=[[m_1,h_1,g_11,...,g_1n],...,[m_k,h_k,g_k1,...,g_kn]]
44	##				and an element x=[m',h',g'_1,...,g'_n]
45	##	Output:	Add the element x into the list L
46	##
47	AddElement:=function(L,x)
48	local	sx,nx,nL,flag,i,j;
49
50		sx:=StructuralCopy(x);
51		nx:=Length(sx);
52		nL:=Length(L);
53		for i in [1..nL] do
54			flag:=0;
55			for j in [2..nx] do
56				if L[i][j]<>sx[j] then
57				   flag:=1;
58				   break;
59				fi;
60			od;
61			if flag=0 then
62				L[i][1]:=L[i][1]+sx[1];
63				if L[i][1]=0 then
64					Remove(L,i);
65				fi;
66				return;
67			fi;
68		od;
69		Add(L,sx);
70	end;
71	##
72	#################### end of AddElement  ##############################
73
74	######################################################################
75	#1
76	#F	BarBoundary
77	##	Input:	A word w =[[m_1,h_1,g_11,...,g_1n],...,[m_k,h_k,g_k1,...,g_kn]]
78	##				and number n
79	##	Output:	The image of w under the boudary d_n:B_n->B_{n-1}
80	##
81	BarBoundary:=function(n,w)
82	local i,j,tmp,x,Rew;
83
84		Rew:=[];
85		for x in w do
86
87			############### Compute 0 #####################
88			tmp:=[x[1],x[2]*x[3]];
89			for j in [2..n] do
90				Add(tmp,x[j+2]);
91			od;
92			AddElement(Rew,tmp);
93
94			############### Compute 1 -> n-1 ##############
95			for i in [1..n-1] do
96				tmp:=[(-1)^i*x[1],x[2]];
97				for j in [1..i-1]	do
98					Add(tmp,x[j+2]);
99				od;
100				Add(tmp,x[i+2]*x[i+3]);
101				for j in [i+2..n]do
102					Add(tmp,x[j+2]);
103				od;
104				AddElement(Rew,tmp);
105			od;
106
107			############### Compute n #####################
108			tmp:=[(-1)^n*x[1],x[2]];
109			for j in [1..n-1] do
110				Add(tmp,x[j+2]);
111			od;
112			AddElement(Rew,tmp);
113		od;
114	return Rew;
115	end;
116	##
117	################### end of BarBoundary ###############################
118
119	######################################################################
120	#1
121	#F	HapHomotopy
122	##	Input: A word w:=[[m_1,e_1,pos_1],...,[m_k,e_k,pos_k]] and number n
123	##	Output: The image of w under the boundary h_n: R_n->R_{n+1}
124	##
125	HapHomotopy:=function(n,w)
126	local	Rew, x, Hw,iHw,m;
127
128		Rew:=[];
129		for x in w do
130			m:=x[1];
131			Hw:=R!.homotopy(n,[x[2],x[3]]);
132			for iHw in Hw do
133				if iHw[1]>0 then
134					AddElement(Rew,[m,iHw[1],iHw[2]]);
135				else
136					AddElement(Rew,[-m,-iHw[1],iHw[2]]);
137				fi;
138			od;
139		od;
140		return Rew;
141	end;
142	##
143	############### end of HapHomotopy ###################################
144
145	######################################################################
146	#1
147	#F	BarHomotopy
148	##	Input:	A word w =[[m_1,h_1,g_11,...,g_1n],...,[m_k,h_k,g_k1,...,g_kn]]
149	##				and number n
150	##	Output: The image of w under the boundary h_n: B_n->B_{n+1}
151	##
152	BarHomotopy:=function(n,w)
153	local i,x,Rew,tmp;
154
155		Rew:=[];
156		for x in w do
157			tmp:=[x[1],e,x[2]];
158			for i in [1..n] do
159				Add(tmp,x[i+2]);
160			od;
161			AddElement(Rew,tmp);
162		od;
163		return Rew;
164	end;
165	##
166	############### end of HapHomotopy ###################################
167
168	########## Compute the image of basis of R under the map psi:R->B ####
169	PsiBasis:=List([0..nR],x->[]);
170	PsiBasis[1][1]:=[[1,e]];  					##[0+1][1]
171	for n in [1..nR] do
172		for k in [1..R!.dimension(n)] do
173			TmpPsi:=[];
174			BoundBasis:=R!.boundary(n,k); 		##ex:[[2,3],[-3,5]]
175			for tmp1 in BoundBasis do
176				if tmp1[1]<0 then
177					sign:=-1;
178					base:=-tmp1[1];
179				else
180					sign:=1;
181					base:=tmp1[1];
182				fi;
183				g:=Elts[tmp1[2]];
184				Stmp:=StructuralCopy(PsiBasis[n][base]); ##n = (n-1) +1
185				for tmp2 in Stmp do
186					tmp2[1]:=sign*tmp2[1];
187					tmp2[2]:=g*tmp2[2];
188				od;
189				Append(TmpPsi,Stmp);
190			od;
191			PsiBasis[n+1][k]:=BarHomotopy(n-1,TmpPsi);
192		od;
193	od;
194
195	######################################################################
196	#1
197	#F	Psi
198	##	Input: A word w:=[[m1,e1,pos1],...,[mk,ek,posk]] and number n
199	##	Output: The image of w under the map psi_n: R_n->B_n
200	##
201	Psi:= function(n,w)
202	local Rew,m,h,x,u,Psix;
203
204		Rew:=[];
205		for x in w do
206			m:=x[1];
207			h:=Elts[x[3]];
208			Psix:=StructuralCopy(PsiBasis[n+1][x[2]]);
209			for u in Psix do
210				u[1]:=m*u[1];
211				u[2]:=h*u[2];
212				AddElement(Rew,u);
213			od;
214		od;
215		return Rew;
216	end;
217	##
218	################ end of Psi ##########################################
219
220	######################################################################
221	#1
222	#F	Phi
223	##	Input: A word w =[[m1,h1,g11,g12,g13,..,g1n],...,[mk,hk,gk1,...gkn]]
224	##	Output: The image of w under the map phi_n: B_n->R_n
225	##
226	Phi:=function(n,w)
227	local	x,Rew,Rex,h,u,cw;
228
229		cw:=StructuralCopy(w);
230		Rew:=[];
231		if n=0 then
232		   for x in cw do
233				AddElement(Rew,[x[1],1,SearchPosition(x[2])]);
234		   od;
235		   return Rew;
236		fi;
237		for x in cw do
238			h:=x[2];
239			x[2]:=e;
240			Rex:=HapHomotopy(n-1,Phi(n-1,
241					BarBoundary(n,[x])));
242			for u in Rex do
243				u[3]:=SearchPosition(h*Elts[u[3]]);
244				AddElement(Rew,u);
245			od;
246		od;
247		return Rew;
248	end;
249	##
250	################ end of Phi ##########################################
251
252	######################################################################
253	#1
254	#F	Equiv
255	##	Input: A word w =[[m1,h1,g11,g12,g13,..,g1n],...,[mk,hk,gk1,...gkn]]
256	##	Output: The image of w under the homotopy map H_n: B_n->B_{n+1}
257	##
258	Equiv:=function(n,w)
259    local
260		cw,h,x,
261		PsiPhix,HBx,HLx,
262		tmp,Rex,Rew,u;
263
264		cw:=StructuralCopy(w);
265		if n = 0 then
266			return [];
267		fi;
268		Rew:=[];
269		for x in cw do
270			h:=x[2];
271			x[2]:=e;
272			HBx:=Equiv(n-1,BarBoundary(n,[x]));
273			AddElement(HBx,x);
274			for tmp in HBx do
275				tmp[1]:=-tmp[1];
276			od;
277			PsiPhix:= Psi(n,Phi(n,[x]));
278			HLx:= Concatenation(PsiPhix,HBx);
279			Rex:=BarHomotopy(n,HLx);
280			for u in Rex do
281				u[2]:=h*u[2];
282				AddElement(Rew,u);
283			od;
284		od;
285		return Rew;
286	end;
287	##
288	################ end of Equiv ########################################
289
290	return rec(
291				phi:=Phi,
292				psi:=Psi,
293				equiv:=Equiv,
294                                barBoundary:=BarBoundary,
295                                barHomotopy:=BarHomotopy
296			);
297end);
298##
299################### end of BarResolutionEquivalence #########################
300
301
302