Skip to content

Commit

Permalink
Merge pull request #103 from cekdahl/functional
Browse files Browse the repository at this point in the history
Functional operators
  • Loading branch information
corywalker committed Sep 12, 2017
2 parents 011f1b0 + 3989b82 commit b9903b6
Show file tree
Hide file tree
Showing 5 changed files with 338 additions and 15 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Expand Up @@ -3,3 +3,11 @@ calc.go
y.output
rubi
test_rubi

.idea/expreduce.iml

.idea/modules.xml

.idea/vcs.xml

.idea/workspace.xml
39 changes: 28 additions & 11 deletions expreduce/builtin_comparison.go
Expand Up @@ -106,7 +106,7 @@ func getComparisonDefinitions() (defs []Definition) {
},
})
defs = append(defs, Definition{
Name: "NumberQ",
Name: "NumberQ",
legacyEvalFn: singleParamQEval(numberQ),
})
defs = append(defs, Definition{
Expand All @@ -121,11 +121,16 @@ func getComparisonDefinitions() (defs []Definition) {
if len(this.Parts) != 3 {
return this
}
if !numberQ(this.Parts[1]) || !numberQ(this.Parts[2]) {

a := NewExpression([]Ex{&Symbol{"System`N"}, this.Parts[1]}).Eval(es)
b := NewExpression([]Ex{&Symbol{"System`N"}, this.Parts[2]}).Eval(es)

if !numberQ(a) || !numberQ(b) {
return this
}

// Less
if ExOrder(this.Parts[1], this.Parts[2]) == 1 {
if ExOrder(a, b) == 1 {
return &Symbol{"System`True"}
}
return &Symbol{"System`False"}
Expand All @@ -140,11 +145,15 @@ func getComparisonDefinitions() (defs []Definition) {
if len(this.Parts) != 3 {
return this
}
if !numberQ(this.Parts[1]) || !numberQ(this.Parts[2]) {

a := NewExpression([]Ex{&Symbol{"System`N"}, this.Parts[1]}).Eval(es)
b := NewExpression([]Ex{&Symbol{"System`N"}, this.Parts[2]}).Eval(es)

if !numberQ(a) || !numberQ(b) {
return this
}
// Greater
if ExOrder(this.Parts[1], this.Parts[2]) == -1 {
if ExOrder(a, b) == -1 {
return &Symbol{"System`True"}
}
return &Symbol{"System`False"}
Expand All @@ -159,15 +168,19 @@ func getComparisonDefinitions() (defs []Definition) {
if len(this.Parts) != 3 {
return this
}
if !numberQ(this.Parts[1]) || !numberQ(this.Parts[2]) {

a := NewExpression([]Ex{&Symbol{"System`N"}, this.Parts[1]}).Eval(es)
b := NewExpression([]Ex{&Symbol{"System`N"}, this.Parts[2]}).Eval(es)

if !numberQ(a) || !numberQ(b) {
return this
}
// Less
if ExOrder(this.Parts[1], this.Parts[2]) == 1 {
if ExOrder(a, b) == 1 {
return &Symbol{"System`True"}
}
// Equal
if ExOrder(this.Parts[1], this.Parts[2]) == 0 {
if ExOrder(a, b) == 0 {
return &Symbol{"System`True"}
}
return &Symbol{"System`False"}
Expand All @@ -182,15 +195,19 @@ func getComparisonDefinitions() (defs []Definition) {
if len(this.Parts) != 3 {
return this
}
if !numberQ(this.Parts[1]) || !numberQ(this.Parts[2]) {

a := NewExpression([]Ex{&Symbol{"System`N"}, this.Parts[1]}).Eval(es)
b := NewExpression([]Ex{&Symbol{"System`N"}, this.Parts[2]}).Eval(es)

if !numberQ(a) || !numberQ(b) {
return this
}
// Greater
if ExOrder(this.Parts[1], this.Parts[2]) == -1 {
if ExOrder(a, b) == -1 {
return &Symbol{"System`True"}
}
// Equal
if ExOrder(this.Parts[1], this.Parts[2]) == 0 {
if ExOrder(a, b) == 0 {
return &Symbol{"System`True"}
}
return &Symbol{"System`False"}
Expand Down
184 changes: 183 additions & 1 deletion expreduce/builtin_functional.go
@@ -1,6 +1,8 @@
package expreduce

import "math/big"
import (
"math/big"
)

func getFunctionalDefinitions() (defs []Definition) {
defs = append(defs, Definition{
Expand Down Expand Up @@ -47,6 +49,186 @@ func getFunctionalDefinitions() (defs []Definition) {
return this.Parts[2]
},
})
defs = append(defs, Definition{
Name: "FoldList",
legacyEvalFn: func(this *Expression, es *EvalState) Ex {
if len(this.Parts) != 4 {
return this
}

f := this.Parts[1]
first := this.Parts[2]
values, nonAtomic := this.Parts[3].(*Expression)

if !nonAtomic {
return this
}

toReturn := NewExpression([]Ex{values.Parts[0], first})

if len(values.Parts) < 2 {
return toReturn
}

expr := NewExpression([]Ex{
f,
first,
values.Parts[1],
})

toReturn.Parts = append(toReturn.Parts, expr);

for i:= 2; i < len(values.Parts); i++ {
expr = NewExpression([]Ex{
f,
expr,
values.Parts[i],
})

toReturn.Parts = append(toReturn.Parts, expr)
}

return toReturn
},
})
defs = append(defs, Definition{Name: "Fold"})
defs = append(defs, Definition{
Name: "NestList",
legacyEvalFn: func(this *Expression, es *EvalState) Ex {
if len(this.Parts) != 4 {
return this
}

f := this.Parts[1]
expr := this.Parts[2]
nInt, isInteger := this.Parts[3].(*Integer)
n := nInt.Val.Int64()

if !isInteger || n < 0 {
return this
}

toReturn := NewExpression([]Ex{&Symbol{"System`List"}, expr})

for i := int64(1); i <= n; i++ {
expr = NewExpression([]Ex {
f,
expr,
})

toReturn.Parts = append(toReturn.Parts, expr)
}

return toReturn
},
})
defs = append(defs, Definition{Name: "Nest"})
defs = append(defs, Definition{
Name: "NestWhileList",
legacyEvalFn: func(this *Expression, es *EvalState) Ex {
if len(this.Parts) < 4 || len(this.Parts) > 7 {
return this
}

f := this.Parts[1]
expr := this.Parts[2]
test := this.Parts[3]

m := int64(1)
if len(this.Parts) > 4 {
mInt, isInteger := this.Parts[4].(*Integer)
mSymbol, isSymbol := this.Parts[4].(*Symbol)
if isInteger {
m = mInt.Val.Int64()
if m < 0 {
return this
}
} else if isSymbol {
if mSymbol.IsEqual(&Symbol{"System`All"}, &es.CASLogger) == "EQUAL_TRUE" {
m = -1
} else {
return this
}
} else {
return this
}
}

max := int64(-1)
if len(this.Parts) > 5 {
maxInt, isInteger := this.Parts[5].(*Integer)
maxSymbol, isSymbol := this.Parts[5].(*Symbol)
if isInteger {
max = maxInt.Val.Int64()
if maxInt.Val.Int64() < 0 {
return this
}
} else if isSymbol {
if maxSymbol.IsEqual(&Symbol{"System`Infinity"}, &es.CASLogger) == "EQUAL_TRUE" {
max = -1
} else {
return this
}
} else {
return this
}
}

n := int64(0)
if len(this.Parts) > 6 {
bonusIterationsInt, isInteger := this.Parts[6].(*Integer)
if isInteger && bonusIterationsInt.Val.Int64() >= int64(0) {
n = bonusIterationsInt.Val.Int64()
}
}

evaluated := []Ex{expr.DeepCopy().Eval(es)}
toReturn := NewExpression([]Ex{&Symbol{"System`List"}, expr})

isequal := "EQUAL_TRUE"
cont := isequal == "EQUAL_TRUE"
for i := int64(2); cont; i++ {
expr = NewExpression([]Ex {
f,
expr,
})
toReturn.Parts = append(toReturn.Parts, expr)
evaluated = append(evaluated, expr.DeepCopy().Eval(es)) // Could use a stack of length m

if i >= m {
testExpression := NewExpression([]Ex {test})
if m >= 0 {
testExpression.Parts = append(testExpression.Parts, evaluated[int64(len(evaluated))-m:]...)
} else {
testExpression.Parts = append(testExpression.Parts, evaluated...)
}
isequal = testExpression.Eval(es).IsEqual(&Symbol{"System`True"}, &es.CASLogger)
cont = isequal == "EQUAL_TRUE"
}

if i > max && max != -1 {
cont = false
}
}

if n > 0 {
for i := int64(0); i < n; i++ {
expr = NewExpression([]Ex {
f,
expr,
})
toReturn.Parts = append(toReturn.Parts, expr)
}
} else {
toReturn.Parts = toReturn.Parts[:int64(len(toReturn.Parts))+n]
}

return toReturn
},
})
defs = append(defs, Definition{Name: "NestWhile"})
defs = append(defs, Definition{Name: "FixedPointList"})
defs = append(defs, Definition{Name: "FixedPoint"})
defs = append(defs, Definition{
Name: "Array",
legacyEvalFn: func(this *Expression, es *EvalState) Ex {
Expand Down

0 comments on commit b9903b6

Please sign in to comment.