(* ::Package:: *)

(************************************************************************)
(* This file was generated automatically by the Mathematica front end.  *)
(* It contains Initialization cells from a Notebook file, which         *)
(* typically will have the same name as this file except ending in      *)
(* ".nb" instead of ".m".                                               *)
(*                                                                      *)
(* This file is intended to be loaded into the Mathematica kernel using *)
(* the package loading commands Get or Needs.  Doing so is equivalent   *)
(* to using the Evaluate Initialization Cells menu command in the front *)
(* end.                                                                 *)
(*                                                                      *)
(* DO NOT EDIT THIS FILE.  This entire file is regenerated              *)
(* automatically each time the parent Notebook file is saved in the     *)
(* Mathematica front end.  Any changes you make to this file will be    *)
(* overwritten.                                                         *)
(************************************************************************)



BeginPackage["loopTool`"];

dd::usage="";
vecD::usage="";
autoReduceVar::usage="";
stopAutoReduce::usage="";
nestedwhile::usage="";

coefficientList2::usage="";
intervalSign::usage="";

gatherBy::usage="";

tHold::usage="";
tHoldQ::usage="";
tApply::usage="";
tMapEvaluateAt::usage="";
		
tHoldOn::usage="";
tHoldOff::usage="";
tHoldStatus::usage="";
tHoldBlock::usage="";

solveAlways2::usage="";

bSum::usage="";
pSum::usage="";
bProduct::usage="";
pProduct::usage="";

proj\[Omega]::usage="";
proj\[Chi]::usage="";
projExpand::usage="";
projSimplify::usage="";

zeroRegionPlot::usage="";

pSwitch::usage="";
ifMatchQ::usage="";

newvar::usage="";
newvarList::usage="";

Begin["`private`"];


Unprotect["loopTool`*"];
Unprotect["loopTool`private`*"];





Clear[vecD];
vecD[a_,Subscript[b_, c:(_Symbol|_Integer)]]:=
Module[{res,tmp,\[Mu],d,n=0,int},
res/;Catch[
tmp=a//.f_^j_Integer:>f^int[j];
tmp=tmp//.{
Dot[x_,y_]:>With[{u=n++},Subscript[x,\[Mu][u]]Superscript[y,\[Mu][u]]],
(t_. b+x_.)^int[2]:>With[{u=n++},Subscript[t b+x,\[Mu][u]]Superscript[t b+x,\[Mu][u]]]
};
If[!FreeQ[tmp/.(h:Subscript|Superscript)[x_,y_]:>h[x/.b->d,y],b],Throw[False]];
If[c[[0]]===Symbol&&!FreeQ[tmp/.(h:Subscript|Superscript)[x_,y_]:>h[x,y/.c->d],c],Throw[False]];
tmp=D[tmp,b]//Expand;
tmp=tmp//.{
\!\(\*
TagBox[
StyleBox[
RowBox[{
RowBox[{"Derivative", "[", 
RowBox[{"1", ",", "0"}], "]"}], "[", "Subscript", "]"}],
ShowSpecialCharacters->False,
ShowStringCharacters->True,
NumberMarks->True],
FullForm]\)[t_. b+_.,c]/;c[[0]]===Symbol:>"dim"[c],
\!\(\*
TagBox[
StyleBox[
RowBox[{
RowBox[{"Derivative", "[", 
RowBox[{"1", ",", "0"}], "]"}], "[", "Subscript", "]"}],
ShowSpecialCharacters->False,
ShowStringCharacters->True,
NumberMarks->True],
FullForm]\)[t_. b+_.,x_]:>KroneckerDelta[x,c],
\!\(\*
TagBox[
StyleBox[
RowBox[{
RowBox[{"Derivative", "[", 
RowBox[{"1", ",", "0"}], "]"}], "[", "Superscript", "]"}],
ShowSpecialCharacters->False,
ShowStringCharacters->True,
NumberMarks->True],
FullForm]\)[t_. b+_.,x_]:>"invmetric"[x,c],
KroneckerDelta[x_,y_]Superscript[z_,y_]:>Superscript[z,x],
"invmetric"[x_,y_]Subscript[z_,y_]:>Superscript[z,x],
"invmetric"[y_,x_]Subscript[z_,y_]:>Superscript[z,x]
};
tmp=tmp//.{
"invmetric"[x__]:>"invmetric"@@Sort[{x}],
Superscript[x_,y_]Subscript[z_,y_]:>Dot@@Sort[{x,z}]
};
If[!FreeQ[tmp,\[Mu]],Throw[False]];
res=tmp/.int->Identity;
True
]
];

vecD[a_,Superscript[b_,c:(_Symbol|_Integer)]]:=
Module[{res,tmp},
res/;Catch[
tmp=a/.{Superscript->Subscript,Subscript->Superscript};
tmp=vecD[tmp,Subscript[b,c]];
If[tmp[[0]]===vecD,Throw[False]];
res=tmp/.{Superscript->Subscript,Subscript->Superscript,"invmetric"->"metric"};
True
]
];


autoReduceVar[var_,func_]:=(
	ToExpression["$autoReducted"<>ToString[var]<>"[_]=False;"];
	ToExpression[
		ToString[var]<>"[autoReduceVar__]:=Module[{tmp},
				("<>ToString[var]<>"[autoReduceVar]=Collect[tmp,"<>ToString[var]<>"[__],Together])/;(
					If[$autoReducted"<>ToString[var]<>"[autoReduceVar],Return[False]];
					If[MemberQ[Cases[{autoReduceVar},l_[___]:>l,Infinity],
									Pattern|PatternSequence|Blank|BlankSequence|
									BlankNullSequence|Optional|Repeated|RepeatedNull
							],
						Return[False];
					];
					Block[{"<>ToString[var]<>"},
						tmp="<>ToString[func]<>"["<>ToString[var]<>"[autoReduceVar]];
						If[MemberQ[tmp,"<>ToString[var]<>"[autoReduceVar],{0,Infinity}],
							tmp="<>ToString[var]<>"[autoReduceVar];
							$autoReducted"<>ToString[var]<>"[autoReduceVar]=True;
							False
							,True
						]
					]
				)
			];"
		];
);

stopAutoReduce[var_]:=(var[a__]=.;ToExpression["Remove[$autoReducted"<>ToString[var]<>"]"]);


nestedwhile[f_,len_]:=
	Module[{counter,pos,res},
		counter=ConstantArray[0,len];
		pos=len;
		While[True,
			res=f[counter];
			If[!res,
				If[pos==1,Break[]];
				counter[[pos;;]]=0;
				pos--,
				pos=len;
			];
			counter[[pos]]++;
		];
	];


coefficientList2[poly_,form_]:=
	Module[{f,res,allVar,var,diff,ratio},
		f=Catch[
			allVar=Variables[form];
			var=Select[allVar,PolynomialQ[form,#]&&Exponent[form,#]==1&,1];
			If[var==={},Throw[False],var=var[[1]]];
			ratio=Coefficient[form,var];
			diff=form/ratio-var//Expand;
			res=CoefficientList[poly /.var->var-diff,var];
			res=res/Table[ratio^i,{i,0,Length[res]-1}];
			True
			];
		Cancel[res]/;f
	];

coefficientList2[poly_,{form_}]/;form[[0]]=!=List:=coefficientList2[poly,form];

coefficientList2[poly_,{x_,y__}]:=coefficientList2[#,{y}]&/@coefficientList2[poly,x]//PadRight;


intervalSign[in_Interval]:=
	Module[{min,max},
		{min,max}={Min[in],Max[in]};
		Which[
			!FreeQ[{min,max},Min|Max],Indeterminate,
			min==max==0,0,
			min>0,Positive,
			max<0,Negative,
			min==0,NonNegative,
			max==0,NonPositive,
			True,Indeterminate
		]
	];


gatherBy[list_,f_/;f[[0]]=!=List]:=
	Gather[list,f[#1]===f[#2]&];

gatherBy[list_,f:{__}]:=
	Fold[gatherBy,list,f];

gatherBy[list_,{}]:=Gather[list];

gatherBy[list_]:=Gather[list];


Attributes[tHold]={HoldAll};

ssymb=Hold/@{
	Set,SetDelayed,UpSet,UpSetDelayed,TagSet,TagSetDelayed,TagUnset,
	Rule,RuleDelayed,ReleaseHold,Hold,HoldPattern,HoldComplete,
	tHold,tApply,tMapEvaluateAt,tHoldQ,If
};

gsymb=Union[
	Hold/@{
		Span,All,List,\!\(\*
TagBox["DirectedInfinity",
FullForm]\),
		Blank,BlankSequence,BlankNullSequence,Alternatives,Repeated,RepeatedNull,
		Pattern,Except,Longest,Shortest,OptionsPattern,PatternSequence,Verbatim,
		Condition,PatternTest,Optional,Default,
		Symbol,Integer,Real,Rational,Complex,Integers,Reals,Rationals,Complexes,
		Equal,Unequal,SameQ,UnsameQ,Less,Greater,LessEqual,GreaterEqual,Inequality,
		True,False,Function,Slot,SlotSequence
	}
];

tHoldOn//Clear;
Options[tHoldOn]={NumericFunction->True,NumericQ->True};

tHoldOn[OptionsPattern[]]:=(
	tHoldOff[];
	Unprotect[tHold,Part];
	$thStatus={
		NumericFunction->TrueQ[OptionValue[NumericFunction]],
		NumericQ->TrueQ[OptionValue[NumericQ]]
	};
	$thCheck=
		If[$thStatus[[1,2]],
			If[$thStatus[[2,2]],
				AtomQ[Unevaluated[#]]&&!NumericQ[Unevaluated[#]]&&
					FreeQ[Attributes[#],NumericFunction]&&#=!=Indeterminate&,
				AtomQ[Unevaluated[#]]&&!NumberQ[Unevaluated[#]]&&
					FreeQ[Attributes[#],NumericFunction]&&#=!=Indeterminate&
			],
			If[$thStatus[[2,2]],
				AtomQ[Unevaluated[#]]&&!NumericQ[Unevaluated[#]]&,
				AtomQ[Unevaluated[#]]&&!NumberQ[Unevaluated[#]]&
			]
		];
	tHold/:h_[x___,tHold[y___],z___]/;FreeQ[ssymb,Hold[h],{1},Heads->False]:=
		Module[{m,originalSymbol,temporarySymbol,holdRule,releaseHoldRule,result},
			originalSymbol=Complement[
				Cases[Hold[h,x,y,z]/.tHold->Hold,a_/;$thCheck[Unevaluated[a]]:>Hold[a],
					{0,\[Infinity]},Heads->True],
				gsymb
			];
			temporarySymbol=Table[Unique["xxx"],{Length[originalSymbol]}];
			(*SetAttributes[Evaluate[temporarySymbol],Temporary];*)
			holdRule=Thread[originalSymbol->temporarySymbol]/.Hold->HoldPattern;
			releaseHoldRule=Thread[temporarySymbol:>Evaluate[originalSymbol]]/.Hold[a_]:>a;
			result=Hold[Evaluate[h@@(Hold[x,y,z]/.holdRule)]]/.releaseHoldRule;
			Remove/@temporarySymbol;
			tHold@@result
		];
	tHold[a___]/;!FreeQ[Hold[a],tHold]:=tHold@@(Hold[a]/.tHold[x___]:>x);
	Part/:Set[Part[a_,b___],c_]/;tHoldQ[a]:=
		If[tHoldQ[c],
			Block[{tHold=Unevaluated},Set@@Hold[Part[a,1,b],Evaluate[c]]],
			Block[{tHoldQ=False&},Set[Part[a,1,b],Unevaluated[c]]]
		];
	ReleaseHold[tHold[a___]]^:=a;
	Protect[tHold,Part];
);

tHoldOff[]:=(
	Unprotect[tHold,Part];
	$thStatus={};
	Clear[tHold];
	Quiet[Part/:Set[Part[a_,b___],c_]/;tHoldQ[a]=.];
	Protect[tHold,Part];
);

tHoldQ[a_]:=Module[{s},Block[{tHold=s},Head[a]]===s];

tHoldStatus[]:=$thStatus;

tApply[f_,a:HoldPattern[tHold[___]..]]:=Sequence@@(f/@{a});

(*tMapEvaluateAt[a_tHold,n_]:=
	Module[{c,f,res},
		(* \:30e1\:30c3\:30bb\:30fc\:30b8 symbol::tag \:304c On \:304b\:3089 Off \:306b\:5909\:66f4\:3055\:308c\:305f\:5834\:5408\:3001Update[symbol]\:3092
			\:884c\:308f\:306a\:3044\:9650\:308a\:3001\:95a2\:6570\:5185\:3067\:7528\:3044\:3089\:308c\:308b symbol::tag \:306b\:5909\:66f4\:304c\:53cd\:6620\:3055\:308c\:306a\:3044 *)
		Update[MapAt];
		c=MapAt::partw=!=$Off[];
		If[c,
			f=Check[
				res=a[[0]]@@MapAt[Evaluate,ReleaseHold[Hold@@a],n];
				True,
				False,
				{MapAt::partw}
			],
			On[MapAt::partw];
			f=Quiet[				
				Check[
					res=a[[0]]@@MapAt[Evaluate,ReleaseHold[Hold@@a],n];
					True,
					False,
					{MapAt::partw}
				],
				{MapAt::partw}
			];
			Off[MapAt::partw];
		];
		res/;f
	];*)

Attributes[tHoldBlock]=HoldFirst;

tHoldBlock[in_,opt:OptionsPattern[]]:=
	Module[{st,res},
		st=tHoldStatus[];
		tHoldOn[opt];
		res=in;
		If[st==={},
			tHoldOff[],
			tHoldOn[st]
		];
		res
	];		

tHoldOff[];


(*
tHold2[Span]=Span;
tHold2[All]=All;
tHold2[List]=List;
*)

(*tHold[a_Integer]:=a;
tHold[a_Rational]:=a;
tHold[a_Real]:=a;
tHold[a_Complex]:=a;
tHold[a_]/;Length[{a}]==1&&AtomQ[a]&&Hold[a]===Hold[Evaluate[a]]:=a;
*)

(*
tHold/:h_[x___,y:tHold[___],z___]/;FreeQ[ssymb,Hold[h],{1},Heads->False]:=
		tHold@@(
			Hold[
				Evaluate[
					h@@(Hold[x,y,z]/.tHold[a___]:>a/.
						a_Symbol/;FreeQ[ssymb,Hold[a],{1},Heads->False]:>tHold2[a])
				]
			]//.
			tHold2[a___]:>a
		);
*)

(*
tApply[f_,a:HoldPattern[tHold[___]..]]:=
	tHold@@Block[{tHold=Hold},
		f@@@Hold[a]
	];
*)


parallelCollect[expr_,var_,h_]:=
	Module[{i=1,f,res1,tmp},
		tmp=Reap[res1=Collect[expr,var,(Sow[#];f[i++])&];];
		tmp=If[tmp[[2]]=!={},tmp[[2,1]],{}];
		DistributeDefinitions[tmp];
		tmp=ParallelTable[h[tmp[[i]]],{i,Length[tmp]}];
		ParallelEvaluate[Remove[tmp,i]];
		tmp=Thread[Array[f,Length[tmp]]->tmp];
		res1/.Dispatch[tmp]
	];


solveAlways2[a_,b_,c___]:=
	Module[{tmp,tmp2,tmp3,i,c1,v},
		tmp=Solve[!Eliminate[!a,b],c];
		Select[tmp,Simplify[a/.#]&]
	];


Attributes[bSum]={HoldFirst};

bSum[a_,b___,{i_,x1_,x2_},c___]:=
	Module[{s=Simplify[Sign[x2-x1]],sum},
		(	
			Distribute[
				sum[
					Switch[
						s,
						_?NonNegative,Sum[sum[a,c],{i,Expand[x1+1],Expand[x2]}],
						_?Negative,-Sum[sum[a,c],{i,Expand[x2+1],Expand[x1]}]
					],
					b
				]
			]/.sum[h_. sum[x_,y___],z___]:>sum[h x,z,y]/.sum->bSum
		)/;IntegerQ[s]
	];

bSum[a_,b___,{i_,x1_,x2_},c___]/;FreeQ[a,i]:=bSum[a(x2-x1),b,c];
		
bSum[a_]:=a;


Attributes[pSum]={HoldFirst};

pSum[a_,b___,{i_,x1_,x2_},c___]:=
	Module[{s=Simplify[Sign[x2-x1]],sum},
		(	
			Distribute[
				sum[
					Switch[
						s,
						_?NonNegative,Sum[sum[a,c],{i,Expand[x1],Expand[x2]}],
						_?Negative,-Sum[sum[a,c],{i,Expand[x2+1],Expand[x1-1]}]
					],
					b
				]
			]/.sum[h_. sum[x_,y___],z___]:>sum[h x,z,y]/.sum->pSum
		)/;IntegerQ[s]
	];

pSum[a_]:=a;

pSum[0,___]=0;


Attributes[bProduct]={HoldFirst};

bProduct[a_,b___,{i_,x1_,x2_},c___]:=
	Module[{s=Simplify[Sign[x2-x1]],prod},
		(	
			Distribute[
				prod[
					Switch[
						s,
						_?NonNegative,Product[prod[a,c],{i,Expand[x1+1],Expand[x2]}],
						_?Negative,1/Product[prod[a,c],{i,Expand[x2+1],Expand[x1]}]
					],
					b
				]
			]/.prod[prod[x_,y___]^h_.,z___]:>prod[x^h,z,y]/.prod->bProduct
		)/;IntegerQ[s]
	];

bProduct[a_,b___,{i_,x1_,x2_},c___]/;FreeQ[a,i]:=bProduct[a,b,c]^(x2-x1);

bProduct[a_]:=a;


Attributes[pProduct]={HoldFirst};

pProduct[a_,b___,{i_,x1_,x2_},c___]:=
	Module[{s=Simplify[Sign[x2-x1]],prod},
		(	
			Distribute[
				prod[
					Switch[
						s,
						_?NonNegative,Product[prod[a,c],{i,Expand[x1],Expand[x2]}],
						_?Negative,1/Product[prod[a,c],{i,Expand[x2+1],Expand[x1-1]}]
					],
					b
				]
			]/.prod[prod[x_,y___]^h_.,z___]:>prod[x^h,z,y]/.prod->pProduct
		)/;IntegerQ[s]
	];

pProduct[a_]:=a;

pProduct[1,___]=1;


zeroRegionPlot[f_,{a_,a0_,a1_},{b_,b0_,b1_},p_:20,d_:10^-10,opt___]:=
	RegionPlot[
		Chop[
			SetPrecision[f,p]/.
				{a->SetPrecision[ai,p],b->SetPrecision[bi,p]},
		d]==0,
		{ai,a0,a1},{bi,b0,b1},opt
	];


Clear[proj\[Omega]];

proj\[Omega][a_Integer,b_Integer,c_][d_Integer]:=If[Mod[d-b,a]==0,c^d,0];
proj\[Omega][a_Integer,b_Integer,c_][d_+e_Integer]:=c^e proj\[Omega][a,b-e,c][d];

proj\[Omega][a_Integer,b_Integer,c_]:=proj\[Omega][-a,b,c]/;Negative[a];
proj\[Omega][a_Integer,b_Integer,c_]:=With[{k=Mod[b,a]},proj\[Omega][a,k,c]/;k!=b];

proj\[Omega]/:proj\[Omega][a_Integer,b_Integer,_]proj\[Omega][a_Integer,e_Integer,_]/;Mod[b-e,a]!=0:=0;
proj\[Omega]/:proj\[Omega][a_Integer,b_Integer,c_]proj\[Omega][a_Integer,b_Integer,e_]:=proj\[Omega][a,b,c e];
proj\[Omega]/:proj\[Omega][a_Integer,b_Integer,c_]^e_Integer?Positive:=proj\[Omega][a,b,c^e];
proj\[Omega]/:proj\[Omega][a_Integer,b_Integer,c_]proj\[Omega][e_Integer,f_Integer,g_]/;a!=e:=
	Module[{k=LCM[a,e],i},
		Expand[Sum[proj\[Omega][k,b+i a,c],{i,0,k/a-1}]Sum[proj\[Omega][k,f+i e,g],{i,0,k/e-1}]]
	];

proj\[Omega]/:proj\[Omega][a_Integer,b_Integer,c_][p_. d_]proj\[Omega][e_Integer,f_Integer,g_][q_. d_]/;IntegerQ[p]&&IntegerQ[q]:=
	With[{k=LCM[p,q]},
		proj\[Omega][a k/p,b k/p,c^(p/k)]proj\[Omega][e k/q,f k/q,g^(q/k)]/.x_proj\[Omega]:>x[k d]
	];

proj\[Omega]/:proj\[Omega][a_Integer,b_Integer,c_][d_]^e_Integer?Positive:=proj\[Omega][a,b,c]^e/.x_proj\[Omega]:>x[d];

projExpand[in_]:=Module[{i},in/.(proj\[Omega]|proj\[Chi])[a_,b_,c_][k_]:>c^k/a Sum[(-1)^((2 i (b-k))/a),{i,a}]];

projSimplify[in_]:=
	FixedPoint[
		Expand[#/.
			proj\[Omega][a_Integer,b_Integer,c_][p_. d_+e_]/;IntegerQ[p]&&FreeQ[d,e]:>pe[proj\[Chi][a,b,c][p d+e],d]/.
			proj\[Omega][a_Integer,b_Integer,c_][d_Integer e_]:>
				Module[{k},
					k=GCD[a,b,d];
					Which[
						k!=1,proj\[Omega][a/k,b/k,c^k][(d e)/k],
						!CoprimeQ[a,d],0,
						True,k=mm[a,b,d];proj\[Omega][a,k,c^d][e]
					]
				]
		]&,
		in
	];

mm[a_,b0_,c0_]:=
	Module[{b,c},
		{b,c}={b0,c0};
		While[True,
			If[Divisible[b,c],Return[Mod[b/c,a]]];
			b+=a
		]
	];

pe[in_,s_]:=
	Module[{tmp,lcm,fac,F},
		tmp=Cases[in,x_proj\[Chi][t_]/;!FreeQ[t,s]:>Coefficient[t,s]x[[1]],{0,\[Infinity]}];
		lcm=LCM@@tmp;
		tmp=Sum[in F[s],{s,0,2lcm-1}]/.proj\[Chi]->proj\[Omega];
		If[tmp===0,Return[0]];
		fac=Quiet[Divide@@Partition[Coefficient[tmp,Array[F,2lcm,0]],lcm]];
		fac=DeleteCases[fac,Indeterminate]//Union;
		If[!MatchQ[fac,{_}],Abort[]];
		fac=(1/fac[[1]])^(1/lcm)//PowerExpand;
		tmp/.F[a_]/;a>=lcm->0/.F[a_]:>proj\[Omega][lcm,0,fac][s-a]
	];


(*Clear[proj\[Omega]];
proj\[Omega][a_Integer,b_Integer,c_][d_Integer]:=If[Mod[d-b,a]==0,c^d,0];
proj\[Omega][a_Integer,b_Integer,c_]:=With[{k=Mod[b,a]},proj\[Omega][a,k,c]/;k!=b];
proj\[Omega][a_Integer,b_Integer,c_][d_+e_Integer]:=c^e proj\[Omega][a,b-e,c][d];
proj\[Omega]/:proj\[Omega][a_Integer,b_Integer,_]proj\[Omega][a_Integer,e_Integer,_]/;Mod[b-e,a]!=0:=0;
proj\[Omega]/:proj\[Omega][a_Integer,b_Integer,c_]proj\[Omega][a_Integer,b_Integer,e_]:=proj\[Omega][a,b,c e];
proj\[Omega]/:proj\[Omega][a_Integer,b_Integer,c_]^e_Integer?Positive:=proj\[Omega][a,b,c^e];
proj\[Omega]/:proj\[Omega][a_Integer,b_Integer,c_]proj\[Omega][e_Integer,f_Integer,g_]/;a!=e:=
	With[{k=LCM[a,e]},
		Expand[Sum[proj\[Omega][k,b+i a,c],{i,0,k/a-1}]Sum[proj\[Omega][k,f+i e,g],{i,0,k/e-1}]]
	];
proj\[Omega]/:proj\[Omega][a_,b_,c_][p_. d_]proj\[Omega][e_,f_,g_][q_. d_]:=
	With[{k=LCM[p,q]},proj\[Omega][a k/p,b k/p,c^(p/k)]proj\[Omega][e k/q,f k/q,g^(q/k)]/.x_proj\[Omega]:>x[k d]];
proj\[Omega]/:proj\[Omega][a_,b_,c_][d_]^e_Integer?Positive:=proj\[Omega][a,b,c]^e/.x_proj\[Omega]:>x[d];

projExpand[in_]:=Module[{i},in/.(proj\[Omega]|proj\[Chi])[a_,b_,c_][k_]:>c^k/a Sum[(-1)^(-2i b/a) ((-1)^(2i/a))^k,{i,a}]];
*)


pSwitch[expr_,fv:(_Rule|_RuleDelayed)...]:=
	Module[{res,tmp,rul},
		Do[
			tmp=Cases[expr,rul,{0}];
			If[tmp=!={},res=tmp[[1]];Break[]],
			{rul,{fv}}
		];
		res/;ValueQ[res]
	];

(*Attributes[ifMatchQ]={HoldRest};
ifMatchQ[expr_,form_,t_,f_:Null]:=pSwitch[expr,form:>t,_:>f];*)


newvar[a_]:=
Module[{vl},
vl={\[FormalA],\[FormalB],\[FormalC],\[FormalD],\[FormalE],\[FormalF],\[FormalG],\[FormalH],\[FormalI],\[FormalJ],\[FormalK],\[FormalL],\[FormalM],\[FormalN],\[FormalO],\[FormalP],\[FormalQ],\[FormalR],\[FormalS],\[FormalT],\[FormalU],\[FormalV],\[FormalW],\[FormalZ],\[FormalY],\[FormalZ],\[FormalCapitalA],\[FormalCapitalB],\[FormalCapitalC],\[FormalCapitalD],\[FormalCapitalE],\[FormalCapitalF],\[FormalCapitalG],\[FormalCapitalH],\[FormalCapitalI],\[FormalCapitalJ],\[FormalCapitalK],\[FormalCapitalL],\[FormalCapitalM],\[FormalCapitalN],\[FormalCapitalO],\[FormalCapitalP],\[FormalCapitalQ],\[FormalCapitalR],\[FormalCapitalS],\[FormalCapitalT],\[FormalCapitalU],\[FormalCapitalV],\[FormalCapitalW],\[FormalCapitalZ],\[FormalCapitalY],\[FormalCapitalZ]};
vl=Complement[vl,Cases[a,Alternatives@@vl,{0,\[Infinity]}]];
If[vl==={},Unique["$formal"],vl[[1]]]
];


newvarList[a_,b_]:=Take[Flatten[Nest[{#,newvar[#]}&,{a},b]],-b];


Protect["loopTool`*"];
Protect["loopTool`private`*"];
Unprotect["loopTool`$*"];
Unprotect["loopTool`private`$*"];


End[];

EndPackage[];
