func textToCasReal(instring string, recs string) (exp Express, err error) { //TextToCas will turn a string (eg "2*x+3") to an Express class //var origin = instring //fmt.Println(instring, "oi") newstringindent := recs + " " origin := instring //fix stupid signs instring = strings.Replace(instring, "-", "+-", -1) instring = strings.Replace(instring, "++", "+", -1) instring = strings.Replace(instring, "--", "+", -1) instring = strings.Replace(instring, "(+-", "(-", -1) newinstring := "" for index, charbyte := range instring { char := string(charbyte) if char == "_" && index != 0 && strmans.StringInSlice(string(instring[index-1]), []string{"*", "/", "+", "-", "("}) == false && (((index >= 2 && string(instring[index-2]) == "-") || (index+1 < len(instring) && string(instring[index+1]) == "{")) == false) { newinstring += "*" } newinstring += char } instring = newinstring if len(strmans.StrToBracketpairs(instring)) > 0 && strmans.StrToBracketpairs(instring)[0][0] == 0 && strmans.StrToBracketpairs(instring)[0][1] == len(instring)-1 { instring = instring[1 : len(instring)-1] } if string(instring[0]) == "+" || string(instring[0]) == "*" { instring = instring[1:] } //fix negative numbers if instring == "-1" { //Avoid "-1" becomes product(-1,1) return Number("-1"), nil } if string(instring[0]) == "-" && len(strmans.FindCharOutsideBracket("+", instring)) == 0 { dbg.Debug(10, recs+origin+" Becomes minusnumber") retval, err := textToCasReal(instring[1:], newstringindent) if err == nil { return Product(Number("-1"), retval), nil } else { panic("bad input to TextToCas " + origin) } } /*if string(instring[0]) == "-" && len(strmans.StrToBracketpairs(instring)) == 0 { dbg.Debug(10, recs+origin+" Becomes minusnumber") retval, err := textToCasReal(instring[1:], newstringindent) if err == nil { return Product(Number("-1"), retval), nil } else { panic("bad input to TextToCas " + origin) } }*/ //remove unnecessary bracket it's sorrounding the whole instring bracketPairs := strmans.StrToBracketpairs(instring) if len(bracketPairs) > 0 && bracketPairs[0][0] == 0 && bracketPairs[0][1] == len(instring)-1 { instring = instring[1 : len(instring)-1] } bracketPairs = strmans.StrToBracketpairs(instring) if instring == "-1" { //Avoid "-1" becomes product(-1,1) return Number("-1"), nil } //parse addition plusses := strmans.FindCharOutsideBracket("+", instring) if len(plusses) > 0 { dbg.Debug(10, recs+origin+" becomes ADDITION"+ fmt.Sprintf("%v", strmans.SplitStringByIndexes(instring, plusses))) var retaddends []Express for _, addendstring := range strmans.SplitStringByIndexes(instring, plusses) { returnaddend, err := textToCasReal(addendstring, newstringindent) if err != nil { panic("bad input to TextToCas " + origin) } retaddends = append(retaddends, returnaddend) } return Addition(retaddends...), nil } //if it's not addition, check for product productsigns := strmans.FindCharOutsideBracket("*", instring) if len(productsigns) > 0 { dbg.Debug(10, recs+origin+" becomes PRODUCT"+ fmt.Sprintf("%v", strmans.SplitStringByIndexes(instring, productsigns))) var retfactors []Express for _, factorstring := range strmans.SplitStringByIndexes(instring, productsigns) { returnfactor, err := textToCasReal(factorstring, newstringindent) if err != nil { panic("bad input to TextToCas " + origin) } retfactors = append(retfactors, returnfactor) } return Product(retfactors...), nil } //if it's not a product, check for fraction fractionsigns := strmans.FindCharOutsideBracket("/", instring) if len(fractionsigns) > 0 { if len(fractionsigns) > 1 { dbg.Debug(0, "BAD FRACTION, DON'T DO STUFF LIKE 2/3/2 (BRACKETS PLEASE)") } dbg.Debug(10, recs+origin+" becomes FRACTION"+ fmt.Sprintf("%v", strmans.SplitStringByIndexes(instring, fractionsigns))) retnum, err1 := textToCasReal(strmans.SplitStringByIndexes(instring, fractionsigns)[0], newstringindent) retdenom, err2 := textToCasReal(strmans.SplitStringByIndexes(instring, fractionsigns)[1], newstringindent) if err1 != nil || err2 != nil { panic("bad input to TextToCas " + origin) } return Fraction(retnum, retdenom), nil } //if it's not a fraction, then it might be a power powersigns := strmans.FindCharOutsideBracket("^", instring) if len(powersigns) > 0 { if len(powersigns) > 1 { dbg.Debug(0, "BAD POWER, PLEASE USE BRACKETS") } dbg.Debug(10, recs+origin+" becomes POWER"+ fmt.Sprintf("%v", (strmans.SplitStringByIndexes(instring, powersigns)))) rootandexpstrings := strmans.SplitStringByIndexes(instring, powersigns) retroot, err1 := textToCasReal(rootandexpstrings[0], newstringindent) retexp, err2 := textToCasReal(rootandexpstrings[1], newstringindent) if err1 != nil || err2 != nil { panic("Bad input to TextToCas " + origin) } retval := Power(retroot, retexp) retval.Forcepowerprint = true return retval, nil } //no usual things to look after; check for functions for index, charbytes := range instring { char := string(charbytes) if char == "(" && string(instring[index-1]) != "(" && string(instring[index-1]) != ")" { startbracket := index //find function string bracketoffset := 1 var funcend int for indexk := len(instring) - 1; indexk > -1; indexk-- { if string(instring[indexk]) == "(" { bracketoffset++ } else if string(instring[indexk]) == ")" { bracketoffset-- if bracketoffset == 0 { funcend = indexk break } } } funcstring := instring[0:startbracket] insidebrackets := instring[startbracket+1 : funcend] //findcommas escapeoffset := 0 var commaindexes []int for index, charbytes := range insidebrackets { char := string(charbytes) if escapeoffset > 0 { if char == "}" { escapeoffset-- } } if char == "{" { escapeoffset++ } if char == "," { commaindexes = append(commaindexes, index) } } if len(commaindexes) == 0 { switch funcstring { case "sin": { dbg.Debug(10, recs+origin+" becomes sine: "+insidebrackets) argexp, err := textToCasReal(insidebrackets, newstringindent) if err != nil { panic("bad input to TextToCas " + origin) } return Sine(argexp), nil } case "cos": { dbg.Debug(10, recs+origin+" becomes cosine: "+insidebrackets) argexp, err := textToCasReal(insidebrackets, newstringindent) if err != nil { panic("bad input to TextToCas " + origin) } return Cosine(argexp), nil } case "tan": { dbg.Debug(10, recs+origin+" becomes tangent: "+insidebrackets) argexp, err := textToCasReal(insidebrackets, newstringindent) if err != nil { panic("bad input to TextToCas " + origin) } return Tangent(argexp), nil } case "arcsin": { dbg.Debug(10, recs+origin+" becomes arcsine: "+insidebrackets) argexp, err := textToCasReal(insidebrackets, newstringindent) if err != nil { panic("bad input to TextToCas " + origin) } return Arcsine(argexp), nil } case "arccos": { dbg.Debug(10, recs+origin+" becomes arccosine: "+insidebrackets) argexp, err := textToCasReal(insidebrackets, newstringindent) if err != nil { panic("bad input to TextToCas " + origin) } return Arccosine(argexp), nil } case "arctan": { dbg.Debug(10, recs+origin+" becomes arctangent: "+insidebrackets) argexp, err := textToCasReal(insidebrackets, newstringindent) if err != nil { panic("bad input to TextToCas " + origin) } return Arctangent(argexp), nil } case "ln": { dbg.Debug(10, recs+origin+" becomes natlogarithm: "+insidebrackets) argexp, err := textToCasReal(insidebrackets, newstringindent) if err != nil { panic("bad input to TextToCas " + origin) } return Natlog(argexp), nil } case "log": { dbg.Debug(10, recs+origin+" becomes comlogarithm: "+insidebrackets) argexp, err := textToCasReal(insidebrackets, newstringindent) if err != nil { panic("bad input to TextToCas " + origin) } return Comlog(argexp), nil } case "sqrt": { dbg.Debug(10, recs+origin+" becomes squareroot: "+insidebrackets) argexp, err := textToCasReal(insidebrackets, newstringindent) if err != nil { panic("bad input to TextToCas " + origin) } return Squareroot(argexp), nil } default: { dbg.Debug(10, recs+origin+" becomes unknownfunction: "+ funcstring+"("+insidebrackets+")") argexp, err := textToCasReal(insidebrackets, newstringindent) if err != nil { panic("bad input to TextToCas " + origin) } return Unknownfunction(funcstring, []Express{argexp}), nil } } } else { argstrings := strmans.SplitStringByIndexes(insidebrackets, commaindexes) dbg.Debug(10, recs+origin+"becomes unknownfunction: "+ funcstring+"("+insidebrackets+")") var retargs []Express for _, argstr := range argstrings { retarg, err := textToCasReal(argstr, newstringindent) if err != nil { panic("Bad input to TextToCas " + origin) } retargs = append(retargs, retarg) } return Unknownfunction(funcstring, retargs), nil } } } stillsignsininstring := false bracketoffset := 0 for _, charbyte := range instring { char := string(charbyte) if char == "{" { bracketoffset++ } else if char == "}" { bracketoffset-- } if bracketoffset == 0 && (char == "+" || char == "*" || char == "/" || char == "^") { stillsignsininstring = true break } } if stillsignsininstring { brackets := strmans.StrToBracketpairs(instring) if string(instring[0]) == "-" && len(brackets) > 0 && brackets[0][0] == 1 && brackets[0][1] == len(instring)-1 { dbg.Debug(10, recs+origin+"becomes negative "+instring[1:len(instring)-1]) partret, err := textToCasReal(instring[1:len(instring)-1], newstringindent) if err != nil { panic("Bad input to TextToCas: " + origin) } return Product(Number("-1"), partret), nil } panic("BAD EXPRESSION") } if string(instring[0]) == "-" { dbg.Debug(10, recs+origin+" becomes negative "+instring[1:]) dbg.Debug(10, recs+" "+"-1") partret, err := textToCasReal(instring[1:], newstringindent) if err != nil { panic("Bad input to TextToCas: " + origin) } return Product(Number("-1"), partret), nil } else { //NUMBER INSTANCE dbg.Debug(10, recs+origin) return Number(instring), nil } }
// Simplifies an input expression (instance) with respect to the focus // // Uses the Substitutiondict func (instance Express) AlgebraicSimp(focus Express, approx bool) Express { dbg.Debug(10, "starting simplify:"+instance.Tostring()+" "+instance.Etype) instancecopy := instance.Makesubs() newinstance := instancecopy var last Express dbg.Debug(10, "starting simplify:"+newinstance.Tostring()+" "+instance.Etype) for { last = newinstance var simptry Express var err error newinstance = Treesimplify(newinstance) newinstance = newinstance.Evalsimplify(approx) dbg.Debug(10, "starting simplify:"+newinstance.Tostring()+" "+instance.Etype) // Simplify all parts switch newinstance.Etype { case "Number": return newinstance case "Sine": newinstance = Sine(newinstance.Arg.AlgebraicSimp(focus, approx)) case "Cosine": newinstance = Cosine(newinstance.Arg.AlgebraicSimp(focus, approx)) case "Tangent": newinstance = Tangent(newinstance.Arg.AlgebraicSimp(focus, approx)) case "Arcsine": newinstance = Arcsine(newinstance.Arg.AlgebraicSimp(focus, approx)) case "Arccosine": newinstance = Arccosine(newinstance.Arg.AlgebraicSimp(focus, approx)) case "Arctangent": newinstance = Arctangent(newinstance.Arg.AlgebraicSimp(focus, approx)) case "Natlog": newinstance = Natlog(newinstance.Arg.AlgebraicSimp(focus, approx)) case "Comlog": newinstance = Comlog(newinstance.Arg.AlgebraicSimp(focus, approx)) case "Squareroot": newinstance = Squareroot(newinstance.Arg.AlgebraicSimp(focus, approx)) case "Addition": var newnewinstanceadds []Express for _, addend := range *newinstance.Addends { newnewinstanceadds = append(newnewinstanceadds, addend.AlgebraicSimp(focus, approx)) } newinstance = Addition(newnewinstanceadds...) case "Product": var newnewinstancefacs []Express for _, fac := range *newinstance.Factors { newnewinstancefacs = append(newnewinstancefacs, fac.AlgebraicSimp(focus, approx)) } newinstance = Product(newnewinstancefacs...) case "Unknownfunction": var newnewargs []Express for _, arg := range *newinstance.Argarr { newnewargs = append(newnewargs, arg.AlgebraicSimp(focus, approx)) } newinstance = Unknownfunction(newinstance.Funcstr, newnewargs) case "Fraction": newinstance = Fraction( newinstance.Numerator.AlgebraicSimp(focus, approx), newinstance.Denominator.AlgebraicSimp(focus, approx)) case "Power": newinstance = Power( newinstance.Root.AlgebraicSimp(focus, approx), newinstance.Exponent.AlgebraicSimp(focus, approx)) } newinstance = Treesimplify(newinstance) newinstance = newinstance.Evalsimplify(approx) switch newinstance.Etype { case "Number": return newinstance case "Addition": simptry, err = newinstance.Antidistributive(focus) if err == nil { dbg.Debug(10, "Simplifying from "+newinstance.Tostring()+ " to "+simptry.Tostring()+" with the "+"Antidistributive"+ " function") newinstance = simptry continue } //simptry, err = newinstance.Associativeadd() //if err == nil { // newinstance = simptry // continue //} case "Product": simptry, err = newinstance.Ntimes0() if err == nil { dbg.Debug(10, "Simplifying from "+newinstance.Tostring()+ " to "+simptry.Tostring()+" with the "+"Ntimes0"+ " function") newinstance = simptry continue } simptry, err = newinstance.AssociativeProd() if err == nil { dbg.Debug(10, "Simplifying from "+newinstance.Tostring()+ " to "+simptry.Tostring()+" with the "+"AssocitaiveProd"+ " function") newinstance = simptry continue } simptry, err = newinstance.Sameroot(focus, false) if err == nil { dbg.Debug(10, "Simplifying from "+newinstance.Tostring()+ " to "+simptry.Tostring()+" with the "+"Sameroot"+ " function") newinstance = simptry continue } simptry, err = newinstance.Sameexponent(focus) if err == nil { dbg.Debug(10, "Simplifying from "+newinstance.Tostring()+ " to "+simptry.Tostring()+" with the "+"Sameexponent"+ " function") newinstance = simptry continue } simptry, err = newinstance.Distributive(focus, false) if err == nil { dbg.Debug(10, "Simplifying from "+newinstance.Tostring()+ " to "+simptry.Tostring()+" with the "+"Distributive"+ " function") newinstance = simptry continue } simptry, err = newinstance.Fractionasfactor() if err == nil { dbg.Debug(10, "Simplifying from "+newinstance.Tostring()+ " to "+simptry.Tostring()+" with the "+"Fractionasfactor"+ " function") newinstance = simptry continue } case "Fraction": simptry, err = newinstance.Samerootofexponentfactors(focus) if err == nil { dbg.Debug(10, "Simplifying from "+newinstance.Tostring()+ " to "+simptry.Tostring()+" with the "+"Samerootofexponentfactor"+ " function") newinstance = simptry continue } simptry, err = newinstance.Ndiv1() if err == nil { dbg.Debug(10, "Simplifying from "+newinstance.Tostring()+ " to "+simptry.Tostring()+" with the "+"Ndiv1"+ " function") newinstance = simptry continue } simptry, err = newinstance.Antisameexponentfrac(focus) if err == nil { dbg.Debug(10, "Simplifying from "+newinstance.Tostring()+ " to "+simptry.Tostring()+" with the "+"Antisameexponentfrac"+ " function") newinstance = simptry continue } simptry, err = newinstance.Shortfract() if err == nil { dbg.Debug(10, "Simplifying from "+newinstance.Tostring()+ " to "+simptry.Tostring()+" with the "+"Shortfract"+ " function") newinstance = simptry continue } simptry, err = newinstance.Cancelfactors() if err == nil { dbg.Debug(10, "Simplifying from "+newinstance.Tostring()+ " to "+simptry.Tostring()+" with the "+"Cancelfactors"+ " function") newinstance = simptry continue } simptry, err = newinstance.Samerootofexponent(focus) if err == nil { dbg.Debug(10, "Simplifying from "+newinstance.Tostring()+ " to "+simptry.Tostring()+" with the "+"Samerootofexponent"+ " function") newinstance = simptry continue } simptry, err = newinstance.Movefactordownifalone() if err == nil { dbg.Debug(10, "Simplifying from "+newinstance.Tostring()+ " to "+simptry.Tostring()+" with the "+"Movefactordownifalone"+ " function") newinstance = simptry continue } simptry, err = newinstance.Fractionindenom() if err == nil { dbg.Debug(10, "Simplifying from "+newinstance.Tostring()+ " to "+simptry.Tostring()+" with the "+"Fractionindenom"+ " function") newinstance = simptry continue } simptry, err = newinstance.Fractioninnum() if err == nil { dbg.Debug(10, "Simplifying from "+newinstance.Tostring()+ " to "+simptry.Tostring()+" with the "+"Fractioninnum"+ " function") newinstance = simptry continue } simptry, err = newinstance.Shortenevaluables() if err == nil { dbg.Debug(10, "Simplifying from "+newinstance.Tostring()+ " to "+simptry.Tostring()+" with the "+"Shortenevaluables"+ " function") newinstance = simptry continue } case "Power": simptry, err = newinstance.Ntothe0() if err == nil { dbg.Debug(10, "Simplifying from "+newinstance.Tostring()+ " to "+simptry.Tostring()+" with the "+"Ntothe0"+ " function") newinstance = simptry continue } simptry, err = newinstance.Ntothe1() if err == nil { dbg.Debug(10, "Simplifying from "+newinstance.Tostring()+ " to "+simptry.Tostring()+" with the "+"Ntothe1"+ " function") newinstance = simptry continue } simptry, err = newinstance.Sameexponentfrac(focus) if err == nil { dbg.Debug(10, "Simplifying from "+newinstance.Tostring()+ " to "+simptry.Tostring()+" with the "+"Sameexponentfrac"+ " function") newinstance = simptry continue } simptry, err = newinstance.Antisameroot(focus) if err == nil { dbg.Debug(10, "Simplifying from "+newinstance.Tostring()+ " to "+simptry.Tostring()+" with the "+"Antisameroot"+ " function") newinstance = simptry continue } simptry, err = newinstance.Antisameexponent(focus) if err == nil { dbg.Debug(10, "Simplifying from "+newinstance.Tostring()+ " to "+simptry.Tostring()+" with the "+"Antisameexponent"+ " function") newinstance = simptry continue } simptry, err = newinstance.Powerasroot() if err == nil { dbg.Debug(10, "Simplifying from "+newinstance.Tostring()+ " to "+simptry.Tostring()+" with the "+"Powerasroot"+ " function") newinstance = simptry continue } } if Expeq(last, newinstance) { break } } return newinstance }