		/** Solutions of systems of equations **/

/*K: sol, equations, solution */
/*A: John Gottschalk */
/*S: University of Western Australia */
/*D: January 1986 */
/*QV: XPresolve */

Neweq_:Fvar_:Fsol_:Backsub_:Tier

/*: Fsol[$eq,$var,($bsub:1)]
	solves the list of equations $eq for the list of variables $var.
	The number of equations need not equal the number of variables. 
	The equations are solved for each of the variables in $var in turn,
	and the solution is used to create a new list $eq. If different
	equations yield different solutions for a variable $vari these 
	inconsistent equations are returned by Fsol[$eq,$var]. 
	Unsolved equations are also returned. With $bsub equal to 1 Fsol
	returns the list 
		{replacements for $var, unsolved  and inconsistent equations}.
	With $bsub equal to zero the variables $var are assigned 
	their values rather than returning these as a list of replacements, 
	and Fsol returns a list of unsolved equations. This nonstandard option
	is included due to the greater efficiency of this method, which may
	be required when handling very large calculations. 
	Fsol avoids a problem with function Presol in the SMP library file
	XPresolve, which doesn't always find the solutions of equations. 
	Fsol avoids difficulties with the system-defined function Sol, 
	for example Sol will not solve a system of equations where the number
	of equations and variables are not equal, even if the equations are
	not independent and are uniquely solvable. */
Fsol[$eq_=Listp[$eq],$var_=Listp[$var],$bsub] :: (Lcl[%eq,%i,%neq,%sol,%sub]; \
	%i : 1; %eq : Neweq[$eq,{}]; %sol : {};\
	Loop[%i <= Len[$var], %eq : Sort[%eq]; %sub : Fvar[%eq,$var[%i]];\
		Sel[Len[%sub] = 0,, \
		    Len[%sub] > 0, %sub : Cb[Rat[%sub[1]],$var]; Pr[%sub]; \
			If[(%neq : Neweq[%eq,%sub];~In[0,%neq,2]),\
				%sol[%i] : %sub; %eq : %neq, \
			Pr["There are inconsistent equations for",$var[%i]]]];\
	Inc[%i], Len[%eq] > 0]; \
	If[P[$bsub=0], (Arep[%sol];Union[%eq]), \
		{Sort[Backsub[Cat[%sol]]],Union[%eq]}])

Fsol[$eq_=Listp[$eq],$var_=Listp[$var]] :: Fsol[$eq,$var,1] 

/*: Fvar[$eq,$var]
	attempts to solve each of the equations in the list $eq for $var
	until a solution is found. A list of the solutions is returned. 
	If there are no solutions the empty list is returned. 
	Fvar[$eq,$var] is used by Fsol[$eq,$var]. */
Fvar[$eq_=Listp[$eq],$var] :: (Lcl[%j,%sol];  %j : 1;\
	Loop[%j <= Len[$eq], %sol : Sol[$eq[%j],$var]; Inc[%j], ~Listp[%sol]];\
	If[Listp[%sol],%sol,{}]) 

Fvar[{$x_=~In[$var,$x],$$y},$var] :: Fvar[{$$y},$var] 
Fvar[{$x_=~In[$var,$x]},$var]     :: {} 

/*: Neweq[$oldeq,$reps]
	substitutes $reps into $oldreps which is a list of equations. 
	Any resulting equations yielding 1 are not included. This is
	used by Fsol[$eq,$var]. */
Neweq[$oldeq,$reps] :: Cat[Ar[Len[$oldeq],S[$oldeq[$1],$reps],,$1 ~= 1]]

/*: Backsub[$sub]
	substitutes $sub[i] into all of $sub[j] where j~=i. It is used by
	Fsol[$eq,$var]. */
Backsub[$reps_=Len[$reps]>1] :: (Lcl[%backsub, %i, %reps]; \
	%backsub[$subs,$i] :: (Cat[Ar[Len[$subs],$subs,$~=$i]]; \
		Cat[{$subs[$i]},Map[S[$,$subs[$i]],%%]]); \
	%reps : $reps; \
	Do[%i,1,Len[$reps],,%reps : %backsub[%reps,%i]])
Backsub[$reps] : $reps

/*W: Even if an equation is nonlinear and has multiple solutions, Fsol 
	chooses only one solution. Fsol sometimes chooses the trivial 
	solution for an equation, for example Fsol[{x=x/z},{x,z}] returns
	{{x -> 0},{}} instead of {{z -> 1},{}}. This is because Fsol uses
	Sol, which has this property. */

/*F: The functionality of Fsol should be incorporated into the existing
	library function Presol. */

/*E:
SMP 1.5.0   (May 14 1986)

#I[1]::  eq2 : {n+3x,-3+g+a z, 3x+a n,-x+e g,x+b t+d e-x^4,\
	 	 3x+g n,1+d t,b+e-x-x^4,-x+a e,b e-x^5,n b+3x^5,\
	 	 -3+a t+g z,2+d z,-1+g t,-1+a,-2+z,6x+a n+n };

#I[2]::  eq1 : Ldist[eq2=0]

								       4
#O[2]:   {n + 3x = 0,g + a z = 3,3x + a n = 0,e g = x,x + b t + d e = x ,

						      4 	       5
		3x + g n = 0,1 + d t = 0,b + e = x + x ,a e = x,b e = x ,

			 5
		b n + 3 x  = 0,a t + g z = 3,2 + d z = 0,g t = 1,a = 1,z = 2,

		n + 6x + a n = 0}

#I[3]::  var1 : {a,b,d,e,g,n,t,x,z};

#I[4]::  <XPresolve

#I[5]::  Presol[eq2,var1]

#O[5]:   {{a -> 1,d -> -1,g -> 1,t -> 1,z -> 2},

					     5  	5              4
		{e - x,n + 3x,2n + 6x,b e - x ,b n + 3 x ,b - e + x - x ,

				    4
		       b + e - x - x }, {b,e,n,x}}

/* Presol failed to solve the equations for e, n and b. */

#I[6]::  <XSolve

#I[7]::  Fsol[eq1,var1]

#O[7]:   {{a -> 1,b -> 0,d -> -1,e -> 0,g -> 1,n -> 0,t -> 1,x -> 0,\
	    z -> 2},{}}

/* This solution is not unique, as shown by the next example */

#I[8]::  var2 : {a,b,d,e,g,n,t,z};

#I[9]::  Fsol[eq1,var2]

#O[9]:   {{a -> 1,b -> x^4,d -> -1,e -> x,g -> 1,n -> -3x,t -> 1,\
	    z -> 2},{}}

#I[10]::  var3 : {a,b,d,e};

#I[11]::  Fsol[eq1,var3]

			 4      -1
#O[11]:   {{a -> 1,b -> x ,d -> --,e -> x},
				t

		      z
		 {2 = -,z = 2,g t = 1,g x = x,g + z = 3,n + 3x = 0,2n + 6x = 0,
		      t

					   4   x    4
			t + g z = 3,x + t x  = - + x ,3x + g n = 0,
					       t

			   4      5
			n x  + 3 x  = 0}}

#I[12]::  var4 : {a,b,d,n,t,u,v,x,z};

#I[13]::  Fsol[eq1,var4]

			 4
#O[13]:   {{a -> 1,b -> e ,d -> -1,n -> -3e,t -> 1,x -> e,z -> 2},

		 {3e = 3e g,g = 1,2g = 2,e g = e}}

#I[14]::  eq2 : {n+3x=0,-3+g+a z=0, 3x+a n=0,g+a z=2};

#I[15]::  Fsol[eq2,{n,g,a,z}]

There are inconsistent equations for    g
There are inconsistent equations for    z

#O[15]:   {{a -> 1,n -> -3x},{g + z = 2,g + z = 3}}

#I[16]::  eq : {n+3x=0,-3+g+a z=0, 3x+a n=0,g+a z=2};

#I[17]::  Fsol[eq,{n,g,a,z},0]

There are inconsistent equations for    g
There are inconsistent equations for    z

#O[17]:   {g + z = 2,g + z = 3}

#I[18]::  n

#O[18]:   -3x

#I[19]::  a

#O[19]:   1
*/
