// Attempt to solve a system of equations. use solvingTransformations.frink showApproximations[false] symbolicMode[true] solveSystem[equations, solveForString] := { eqArray = new array size = length[equations] allUnknowns = new set for i=0 to size-1 { syms = getSymbols[parseToExpression[equations@i]] equation = equations@i // println["Equation is $equation"] // println["Symbols are $syms"] eqArray.push[ [equation, syms] ] // println["eqArray is $eqArray"] allUnknowns = union[allUnknowns, syms] // println["allUnknowns is $allUnknowns"] } // println["All unknowns: $allUnknowns"] // Sort equations by number of unknowns (fewest first) sort[eqArray, {|a,b| length[a@1] <=> length[b@1]}] res = solveParts[eqArray, solveForString] res = eliminateDuplicates[res] res = eliminateOverconstrained[res] // res = eliminateSelfReferential[res] return res } // This is a recursive internal method to solve for other unknowns. solveParts[eqArray, solveForString] := { results = new array size = length[eqArray] for i=0 to size-1 { [eq, unknowns] = eqArray@i if unknowns.contains[solveForString] { oe = parseToExpression[eq] equation = parseToExpression["solve[$eq, $solveForString]"] solvedEq = transformExpression["solving", equation] results.push[solvedEq] println["Result is $solvedEq"] otherEqs = eqArray.shallowCopy[] otherEqs.remove[i] otherSize = length[otherEqs] for unknown = unknowns { pUnknown = parseToExpression[unknown] if (unknown != solveForString) for j=0 to otherSize-1 { res2 = solveParts[otherEqs, unknown] // println["Unknown is $unknown"] // println["Res2 is $res2"] for respart = res2 { // println["Replacing in $solvedEq, $pUnknown becomes " + child[respart,1]] // TODO: Replace solving with simplification rules. r = transformExpression["solving",substituteExpression[solvedEq, pUnknown, child[respart,1]]] // println[" Result: $r"] results.push[r] } } } } } return flatten[results] } eliminateDuplicates[eqArray] := { i=0 j=1 while (i