Skip to content

Commit

Permalink
Resolve conflicts in resources.go
Browse files Browse the repository at this point in the history
  • Loading branch information
cekdahl committed Oct 1, 2017
2 parents c9ea76f + c77d3e9 commit 8c73d88
Show file tree
Hide file tree
Showing 67 changed files with 1,896 additions and 747 deletions.
28 changes: 23 additions & 5 deletions README.md
Expand Up @@ -35,31 +35,49 @@ Welcome to Expreduce!
In[1]:= D[Cos[Log[Sin[x]]+x]+x,x]
Out[1]= (1 + (-1 * (1 + Cot[x]) * Sin[(x + Log[Sin[x]])]))
Out[1]= 1 + -(1 + Cot[x])*Sin[x + Log[Sin[x]]]
In[2]:= Integrate[5*E^(3*x),{x,2,a}] // Expand
Out[2]= ((-5/3 * E^6) + (5/3 * E^(3 * a)))
Out[2]= -5/3*E^6 + 5/3*E^(3*a)
In[3]:= FactorSquareFree[1 - 2*x^2 + x^4]
Out[3]= (-1 + x^2)^2
In[4]:= Sum[i, {i, 1, n}]
Out[4]= (1/2 * n * (1 + n))
Out[4]= 1/2*n*(1 + n)
In[5]:= Together[(1/2 + 3/a)^2+b/c]
Out[5]= (1/4 * a^-2 * c^-1 * ((4 * a^2 * b) + (36 * c) + (12 * a * c) + (a^2 * c)))
Out[5]= 1/4*a^-2*c^-1*(4*a^2*b + 36*c + 12*a*c + a^2*c)
In[6]:= 40!
Out[6]= 815915283247897734345611269596115894272000000000
In[7]:= Solve[x^2-x-2.5==0,x]
Out[7]= {{(x) -> (-1.15831)}, {(x) -> (2.15831)}}
Out[7]= {{x -> -1.15831}, {x -> 2.15831}}
```

# Rubi integration rules

Expreduce uses the Rubi integration suite by Albert Rich. The rules can be loaded by running `LoadRubi[]` and then the integration can be called like `Int[Sin[a + b*Log[c*x^n]], x]`. These rules are much more powerful than the simplistic ones in `Integrate[]`.

http://www.apmaths.uwo.ca/~arich/

## Integration examples

```
In[1]:= Int[((A + C*Sin[e + f*x]^2)*(a + a*Sin[e + f*x])^m*(c + -c*Sin[e + f*x])^(-1/2)), x]
Out[1]= (f^-1*Cos[e + f*x]*Hypergeometric2F1[1, 1/2 + m, 3/2 + m, 1/2*(1 + Sin[e + f*x])]*(1 + 2*m)^-1*(A + C)*(a + a*Sin[e + f*x])^m*(c + -c*Sin[e + f*x])^(-1/2) + -2*C*a^-1*f^-1*Cos[e + f*x]*(3 + 2*m)^-1*(a + a*Sin[e + f*x])^(1 + m)*(c + -c*Sin[e + f*x])^(-1/2))
In[2]:= Int[(x^-5*(a*x)^(-1/2)*(1 + -a*x)^(-1/2)*(1 + a*x)), x]
Out[1]= (-2/9*a^4*(a*x)^(-9/2)*(1 + -a*x)^(1/2) + -34/63*a^4*(a*x)^(-7/2)*(1 + -a*x)^(1/2) + -68/105*a^4*(a*x)^(-5/2)*(1 + -a*x)^(1/2) + -272/315*a^4*(a*x)^(-3/2)*(1 + -a*x)^(1/2) + -544/315*a^4*(a*x)^(-1/2)*(1 + -a*x)^(1/2))
```

# Technical notes
Expand Down
5 changes: 2 additions & 3 deletions expreduce.go
Expand Up @@ -72,7 +72,6 @@ func main() {

if !isNull {
// Print formatted result
context, contextPath := expreduce.ActualStringFormArgs(es)
specialForms := []string{
"System`FullForm",
"System`OutputForm",
Expand All @@ -92,13 +91,13 @@ func main() {
promptNum,
specialForm[7:],
asSpecialForm.Parts[1].StringForm(
specialForm[7:], context, contextPath),
expreduce.ActualStringFormArgsFull(specialForm[7:], es)),
)
wasSpecialForm = true
}
if !wasSpecialForm {
fmt.Printf("Out[%d]= %s\n\n", promptNum, res.StringForm(
"InputForm", context, contextPath))
expreduce.ActualStringFormArgsFull("InputForm", es)))
}
}

Expand Down
8 changes: 4 additions & 4 deletions expreduce/blank.go
Expand Up @@ -98,14 +98,14 @@ func IsBlankTypeCapturing(e Ex, target Ex, head Ex, pm *PDManager, cl *CASLogger

func BlankNullSequenceToBlank(bns *Expression) *Expression {
if len(bns.Parts) < 2 {
return NewExpression([]Ex{&Symbol{"System`Blank"}})
return NewExpression([]Ex{NewSymbol("System`Blank")})
}
return NewExpression([]Ex{&Symbol{"System`Blank"}, bns.Parts[1]})
return NewExpression([]Ex{NewSymbol("System`Blank"), bns.Parts[1]})
}

func BlankSequenceToBlank(bs *Expression) *Expression {
if len(bs.Parts) < 2 {
return NewExpression([]Ex{&Symbol{"System`Blank"}})
return NewExpression([]Ex{NewSymbol("System`Blank")})
}
return NewExpression([]Ex{&Symbol{"System`Blank"}, bs.Parts[1]})
return NewExpression([]Ex{NewSymbol("System`Blank"), bs.Parts[1]})
}
6 changes: 3 additions & 3 deletions expreduce/builtin.go
Expand Up @@ -146,9 +146,9 @@ func (def *Definition) AnnotateWithDynamicUsage(es *EvalState) {
return
}
lhs := NewExpression([]Ex{
&Symbol{"System`MessageName"},
&Symbol{"System`" + def.Name},
&String{"usage"},
NewSymbol("System`MessageName"),
NewSymbol("System`" + def.Name),
NewString("usage"),
})
usage, usageIsDef, _ := es.GetDef("System`MessageName", lhs)
if !usageIsDef {
Expand Down
61 changes: 33 additions & 28 deletions expreduce/builtin_arithmetic.go
@@ -1,6 +1,7 @@
package expreduce

import "math/big"
import "strings"

func ExArrayContainsFloat(a []Ex) bool {
res := false
Expand Down Expand Up @@ -131,8 +132,8 @@ func computeRealPart(fn FoldFn, e *Expression) (Ex, int) {
func splitTerm(e Ex) (Ex, Ex, bool) {
asSym, isSym := e.(*Symbol)
if isSym {
return &Integer{big.NewInt(1)}, NewExpression([]Ex{
&Symbol{"System`Times"},
return NewInteger(big.NewInt(1)), NewExpression([]Ex{
NewSymbol("System`Times"),
asSym,
}), true
}
Expand All @@ -143,16 +144,16 @@ func splitTerm(e Ex) (Ex, Ex, bool) {
}
if numberQ(asTimes.Parts[1]) {
if len(asTimes.Parts) > 2 {
return asTimes.Parts[1], NewExpression(append([]Ex{&Symbol{"System`Times"}}, asTimes.Parts[2:]...)), true
return asTimes.Parts[1], NewExpression(append([]Ex{NewSymbol("System`Times")}, asTimes.Parts[2:]...)), true
}
} else {
return &Integer{big.NewInt(1)}, NewExpression(append([]Ex{&Symbol{"System`Times"}}, asTimes.Parts[1:]...)), true
return NewInteger(big.NewInt(1)), NewExpression(append([]Ex{NewSymbol("System`Times")}, asTimes.Parts[1:]...)), true
}
}
asExpr, isExpr := e.(*Expression)
if isExpr {
return &Integer{big.NewInt(1)}, NewExpression([]Ex{
&Symbol{"System`Times"},
return NewInteger(big.NewInt(1)), NewExpression([]Ex{
NewSymbol("System`Times"),
asExpr,
}), true
}
Expand All @@ -167,9 +168,9 @@ func collectedToTerm(coeffs []Ex, vars Ex, fullPart Ex) Ex {
}

finalC, _ := computeRealPart(FoldFnAdd, NewExpression(append([]Ex{
&Symbol{"System`Plus"}}, coeffs...)))
NewSymbol("System`Plus")}, coeffs...)))

toAdd := NewExpression([]Ex{&Symbol{"System`Times"}})
toAdd := NewExpression([]Ex{NewSymbol("System`Times")})
cAsInt, cIsInt := finalC.(*Integer)
if !(cIsInt && cAsInt.Val.Cmp(big.NewInt(1)) == 0) {
toAdd.Parts = append(toAdd.Parts, finalC)
Expand All @@ -186,7 +187,7 @@ func collectedToTerm(coeffs []Ex, vars Ex, fullPart Ex) Ex {
}

func collectTerms(e *Expression) *Expression {
collected := NewExpression([]Ex{&Symbol{"System`Plus"}})
collected := NewExpression([]Ex{NewSymbol("System`Plus")})
var lastVars Ex
var lastFullPart Ex
lastCoeffs := []Ex{}
Expand Down Expand Up @@ -222,13 +223,13 @@ func getArithmeticDefinitions() (defs []Definition) {
defs = append(defs, Definition{
Name: "Plus",
Default: "0",
toString: func(this *Expression, form string, context *String, contextPath *Expression) (bool, string) {
return ToStringInfix(this.Parts[1:], " + ", form, context, contextPath)
toString: func(this *Expression, params ToStringParams) (bool, string) {
return ToStringInfix(this.Parts[1:], " + ", "System`Plus", params)
},
legacyEvalFn: func(this *Expression, es *EvalState) Ex {
// Calls without argument receive identity values
if len(this.Parts) == 1 {
return &Integer{big.NewInt(0)}
return NewInteger(big.NewInt(0))
}

res := this
Expand All @@ -237,7 +238,7 @@ func getArithmeticDefinitions() (defs []Definition) {
if symStart == -1 {
return realPart
}
res = NewExpression([]Ex{&Symbol{"System`Plus"}})
res = NewExpression([]Ex{NewSymbol("System`Plus")})
rAsInt, rIsInt := realPart.(*Integer)
if !(rIsInt && rAsInt.Val.Cmp(big.NewInt(0)) == 0) {
res.Parts = append(res.Parts, realPart)
Expand All @@ -261,19 +262,23 @@ func getArithmeticDefinitions() (defs []Definition) {
defs = append(defs, Definition{
Name: "Sum",
legacyEvalFn: func(this *Expression, es *EvalState) Ex {
return this.evalIterationFunc(es, &Integer{big.NewInt(0)}, "System`Plus")
return this.evalIterationFunc(es, NewInteger(big.NewInt(0)), "System`Plus")
},
})
defs = append(defs, Definition{
Name: "Times",
Default: "1",
toString: func(this *Expression, form string, context *String, contextPath *Expression) (bool, string) {
return ToStringInfix(this.Parts[1:], " * ", form, context, contextPath)
toString: func(this *Expression, params ToStringParams) (bool, string) {
ok, res := ToStringInfix(this.Parts[1:], "*", "System`Times", params)
if ok && strings.HasPrefix(res, "-1*") {
return ok, "-" + res[3:]
}
return ok, res
},
legacyEvalFn: func(this *Expression, es *EvalState) Ex {
// Calls without argument receive identity values
if len(this.Parts) == 1 {
return &Integer{big.NewInt(1)}
return NewInteger(big.NewInt(1))
}

res := this
Expand All @@ -282,19 +287,19 @@ func getArithmeticDefinitions() (defs []Definition) {
if symStart == -1 {
return realPart
}
res = NewExpression([]Ex{&Symbol{"System`Times"}})
res = NewExpression([]Ex{NewSymbol("System`Times")})
rAsInt, rIsInt := realPart.(*Integer)
if rIsInt && rAsInt.Val.Cmp(big.NewInt(0)) == 0 {
containsInfinity := MemberQ(this.Parts[symStart:], NewExpression([]Ex{
&Symbol{"System`Alternatives"},
&Symbol{"System`Infinity"},
&Symbol{"System`ComplexInfinity"},
&Symbol{"System`Indeterminate"},
NewSymbol("System`Alternatives"),
NewSymbol("System`Infinity"),
NewSymbol("System`ComplexInfinity"),
NewSymbol("System`Indeterminate"),
}), es)
if containsInfinity {
return &Symbol{"System`Indeterminate"}
return NewSymbol("System`Indeterminate")
}
return &Integer{big.NewInt(0)}
return NewInteger(big.NewInt(0))
}
if !(rIsInt && rAsInt.Val.Cmp(big.NewInt(1)) == 0) {
res.Parts = append(res.Parts, realPart)
Expand All @@ -314,13 +319,13 @@ func getArithmeticDefinitions() (defs []Definition) {
rightplus, rightplusok := HeadAssertion(res.Parts[2], "System`Plus")
if leftintok && rightplusok {
if leftint.Val.Cmp(big.NewInt(-1)) == 0 {
toreturn := NewExpression([]Ex{&Symbol{"System`Plus"}})
toreturn := NewExpression([]Ex{NewSymbol("System`Plus")})
addends := rightplus.Parts[1:len(rightplus.Parts)]
for i := range addends {
toAppend := NewExpression([]Ex{
&Symbol{"System`Times"},
NewSymbol("System`Times"),
addends[i],
&Integer{big.NewInt(-1)},
NewInteger(big.NewInt(-1)),
})

toreturn.Parts = append(toreturn.Parts, toAppend)
Expand All @@ -336,7 +341,7 @@ func getArithmeticDefinitions() (defs []Definition) {
defs = append(defs, Definition{
Name: "Product",
legacyEvalFn: func(this *Expression, es *EvalState) Ex {
return this.evalIterationFunc(es, &Integer{big.NewInt(1)}, "System`Times")
return this.evalIterationFunc(es, NewInteger(big.NewInt(1)), "System`Times")
},
})
defs = append(defs, Definition{Name: "Abs"})
Expand Down
10 changes: 10 additions & 0 deletions expreduce/builtin_atoms.go
Expand Up @@ -19,5 +19,15 @@ func getAtomsDefinitions() (defs []Definition) {
defs = append(defs, Definition{Name: "Real"})
defs = append(defs, Definition{Name: "Integer"})
defs = append(defs, Definition{Name: "IntegerQ"})
defs = append(defs, Definition{
Name: "Im",
OmitDocumentation: true,
ExpreduceSpecific: true,
})
defs = append(defs, Definition{
Name: "Re",
OmitDocumentation: true,
ExpreduceSpecific: true,
})
return
}
24 changes: 12 additions & 12 deletions expreduce/builtin_boolean.go
Expand Up @@ -3,23 +3,23 @@ package expreduce
func GetBooleanDefinitions() (defs []Definition) {
defs = append(defs, Definition{
Name: "And",
toString: func(this *Expression, form string, context *String, contextPath *Expression) (bool, string) {
return ToStringInfix(this.Parts[1:], " && ", form, context, contextPath)
toString: func(this *Expression, params ToStringParams) (bool, string) {
return ToStringInfix(this.Parts[1:], " && ", "", params)
},
legacyEvalFn: func(this *Expression, es *EvalState) Ex {
res := NewExpression([]Ex{&Symbol{"System`And"}})
res := NewExpression([]Ex{NewSymbol("System`And")})
for i := 1; i < len(this.Parts); i++ {
this.Parts[i] = this.Parts[i].Eval(es)
if booleanQ(this.Parts[i], &es.CASLogger) {
if falseQ(this.Parts[i], &es.CASLogger) {
return &Symbol{"System`False"}
return NewSymbol("System`False")
}
} else {
res.appendEx(this.Parts[i])
}
}
if len(res.Parts) == 1 {
return &Symbol{"System`True"}
return NewSymbol("System`True")
}
if len(res.Parts) == 2 {
return res.Parts[1]
Expand All @@ -29,23 +29,23 @@ func GetBooleanDefinitions() (defs []Definition) {
})
defs = append(defs, Definition{
Name: "Or",
toString: func(this *Expression, form string, context *String, contextPath *Expression) (bool, string) {
return ToStringInfix(this.Parts[1:], " || ", form, context, contextPath)
toString: func(this *Expression, params ToStringParams) (bool, string) {
return ToStringInfix(this.Parts[1:], " || ", "", params)
},
legacyEvalFn: func(this *Expression, es *EvalState) Ex {
res := NewExpression([]Ex{&Symbol{"System`Or"}})
res := NewExpression([]Ex{NewSymbol("System`Or")})
for i := 1; i < len(this.Parts); i++ {
this.Parts[i] = this.Parts[i].Eval(es)
if booleanQ(this.Parts[i], &es.CASLogger) {
if trueQ(this.Parts[i], &es.CASLogger) {
return &Symbol{"System`True"}
return NewSymbol("System`True")
}
} else {
res.appendEx(this.Parts[i])
}
}
if len(res.Parts) == 1 {
return &Symbol{"System`False"}
return NewSymbol("System`False")
}
if len(res.Parts) == 2 {
return res.Parts[1]
Expand All @@ -60,10 +60,10 @@ func GetBooleanDefinitions() (defs []Definition) {
return this
}
if trueQ(this.Parts[1], &es.CASLogger) {
return &Symbol{"System`False"}
return NewSymbol("System`False")
}
if falseQ(this.Parts[1], &es.CASLogger) {
return &Symbol{"System`True"}
return NewSymbol("System`True")
}
return this
},
Expand Down

0 comments on commit 8c73d88

Please sign in to comment.