From c9ea76fc7ccc182e3a6bc5dfecf86da56eb7677d Mon Sep 17 00:00:00 2001 From: Calle Ekdahl Date: Sun, 1 Oct 2017 22:38:09 +0200 Subject: [PATCH 1/3] New implementations of Map and MapIndexed --- expreduce/builtin_functional.go | 390 +++++++++++++++++++++++++++++-- expreduce/resources.go | 112 ++++----- expreduce/resources/functional.m | 63 ++++- 3 files changed, 490 insertions(+), 75 deletions(-) diff --git a/expreduce/builtin_functional.go b/expreduce/builtin_functional.go index 3514253..77ae8e0 100644 --- a/expreduce/builtin_functional.go +++ b/expreduce/builtin_functional.go @@ -4,6 +4,371 @@ import ( "math/big" ) +//The following functions help to interpret the Ex interface, they could probably be moved +//to another file since they are useful in many common situations + +func parseInteger(part Ex) (value int64, isInteger bool) { + integer, isInteger := part.(*Integer) + if isInteger { + return integer.Val.Int64(), true + } else { + return 0, false + } +} + +func parseFloat(part Ex) (value float64, isFloat bool) { + float, isFloat := part.(*Flt) + if isFloat { + value, _ := float.Val.Float64() + return value, true + } else { + return 0, false + } +} + +func parseExpression(part Ex) (expression *Expression, isExpression bool) { + expression, isExpression = part.(*Expression) + return expression, isExpression +} + +func parseSymbol(part Ex) (symbol *Symbol, isSymbol bool) { + symbol, isSymbol = part.(*Symbol) + return symbol, isSymbol +} + +func parseInfinity(part Ex, es *EvalState) bool { + symbol, isSymbol := parseSymbol(part) + if isSymbol { + return symbol.IsEqual(&Symbol{"System`Infinity"}, &es.CASLogger) == "EQUAL_TRUE" + } + return false +} + +func parseNegativeInfinity(part Ex, es *EvalState) bool { + expr, isExpr := parseExpression(part) + if isExpr { + template := NewExpression([]Ex{ + &Symbol{"System`Times"}, + &Integer{big.NewInt(-1)}, + &Symbol{"System`Infinity"}, + }) + return expr.IsEqual(template, &es.CASLogger) == "EQUAL_TRUE" + } + return false +} + +// The levelSpec struct is used to work with level specifications +type levelSpec struct { + isMinDepth bool //If the min specification represents a depth (as opposed to level) + isMaxDepth bool //If the max specification represents a depth (as opposed to level) + min int64 + max int64 + valid bool +} + +func (spec levelSpec) isLevel() (bool, bool) { + return !spec.isMinDepth, !spec.isMaxDepth +} + +func (spec levelSpec) isDepth() (bool, bool) { + return spec.isMinDepth, spec.isMaxDepth +} + +func (spec levelSpec) isValid() bool { + return spec.valid +} + +func (spec levelSpec) checkLevel(level int64) bool { + switch { + case !spec.isMinDepth && !spec.isMaxDepth: + return level >= spec.min && level <= spec.max + case !spec.isMinDepth && spec.isMaxDepth: + return level >= spec.min + case spec.isMinDepth && !spec.isMaxDepth: + return level <= spec.max + } + + return true +} + +func (spec levelSpec) checkDepth(depth int64) bool { + switch { + case spec.isMinDepth && spec.isMaxDepth: + return depth <= spec.min && depth >= spec.max + case spec.isMinDepth && !spec.isMaxDepth: + return depth <= spec.min + case !spec.isMinDepth && spec.isMaxDepth: + return depth >= spec.max + } + + return true +} + +// Levels can be specified in the form n, {n}, {n1, n2}, Infinity, -Infinity +// n, n1, n2 are integers which can be positive or negative +func parseLevelSpec(this Ex, es *EvalState) levelSpec{ + integer, isInteger := parseInteger(this) + expression, isExpression := parseExpression(this) + isInfinity := parseInfinity(this, es) + isNegativeInfinity := parseNegativeInfinity(this, es) + + //These are the maximum and minimum numbers which are representable in + //the int64 data type + const inf int64 = 1<<31 - 1 //Same but with 63 does not work for some reason + const ninf int64 = -1 << 31 + + //If it's a symbol, deal with it + //If it's not an accepted symbol and not an expression, return false + switch { + case isInteger: + if integer < 0 { + return levelSpec{false, true, 1, -integer, true} + } else { + return levelSpec{false, false, 1, integer, true} + } + case isInfinity: + return levelSpec{false, false, 1, inf, true} + case isNegativeInfinity: + return levelSpec{false, true, 1, inf, true} + case !isExpression: + return levelSpec{false, false, 1, 1, false} + } + + //If the head of the expression is not List, return false + expression, isList := headExAssertion(expression, &Symbol{"System`List"}, &es.CASLogger) + if !isList { + return levelSpec{false, false, 1, 1, false} + } + + //Handle case where the list has only one element + if len(expression.Parts) == 2 { + integer, isInteger = parseInteger(expression.Parts[1]) + isInfinity := parseInfinity(expression.Parts[1], es) + isNegativeInfinity := parseNegativeInfinity(expression.Parts[1], es) + + switch { + case isInteger: + if integer < 0 { + return levelSpec{true, true, -integer, -integer, true} + } else { + return levelSpec{false, false, integer, integer, true} + } + case isInfinity: + return levelSpec{false, false, inf, inf, true} + case isNegativeInfinity: + return levelSpec{true, true, inf, inf, true} + } + } + + //Handle case where the list has two elements + if len(expression.Parts) == 3 { + integer1, isInteger1 := parseInteger(expression.Parts[1]) + integer2, isInteger2 := parseInteger(expression.Parts[2]) + + isInfinity1 := parseInfinity(expression.Parts[1], es) + if isInfinity1 { + integer1 = inf + isInteger1 = true + } + + isInfinity2 := parseInfinity(expression.Parts[2], es) + if isInfinity2 { + integer2 = inf + isInteger2 = true + } + + isNegativeInfinity1 := parseNegativeInfinity(expression.Parts[1], es) + if isNegativeInfinity1 { + integer1 = ninf + isInteger1 = true + } + + isNegativeInfinity2 := parseNegativeInfinity(expression.Parts[2], es) + if isNegativeInfinity2 { + integer2 = ninf + isInteger2 = true + } + + if isInteger1 && isInteger2 { + switch { + case integer1 >= 0 && integer2 >= 0: + return levelSpec{false, false, integer1, integer2, true} + case integer1 < 0 && integer2 < 0: + return levelSpec{true, true, -integer1, -integer2, true} + case integer1 < 0 && integer2 >= 0: + return levelSpec{true, false, -integer1, integer2, true} + case integer1 >= 0 && integer2 < 0: + return levelSpec{false, true, integer1, -integer2, true} + } + } + } + + //If the function has not returned by now then the specification is invalid + return levelSpec{false, false, 1, 1, false} +} + +//This is an optimization with regards to expressionWalkMapBackwards which only deals with level specification, +//expressionWalkMapBackwards also deals with depths, but has to visit the entire expression tree. +func expressionWalkMap(f func(Ex, Ex, []int64) *Expression, head Ex, partSpec[]int64, this *Expression, es *EvalState, spec levelSpec) *Expression { + toReturn := NewExpression([]Ex{this.Parts[0]}) + + for i, expr := range this.Parts[1:] { + newExpression := expr + + //Keep track of which part in the full expression this corresponds to + currentPartSpec := append(partSpec, int64(i+1)) + level := int64(len(currentPartSpec)) + + //If this part is nonatomic and its level is covered by the level specification, + //apply expressionWalkMap recursively + expression, isExpression := newExpression.(*Expression) + if isExpression && level < spec.max { + newExpression = expressionWalkMap(f, head, currentPartSpec, expression, es, spec) + } + + //If this part is covered by the level specification, apply the function + //specified by the first argument of Map + if level >= spec.min { + newExpression = f(head, newExpression, currentPartSpec) + toReturn.Parts = append(toReturn.Parts, newExpression) + } else { + toReturn.Parts = append(toReturn.Parts, newExpression) + } + } + + return toReturn +} + +func expressionWalkMapBackwards(f func(Ex, Ex, []int64) *Expression, head Ex, partSpec[]int64, this *Expression, es *EvalState, spec levelSpec) (*Expression, int64) { + toReturn := NewExpression([]Ex{this.Parts[0]}) + currentMaxDepth := int64(1) + + for i, expr := range this.Parts[1:] { + newExpression := expr + depth := int64(0) + + currentPartSpec := append(partSpec, int64(i+1)) + level := int64(len(currentPartSpec)) + + expression, isExpression := newExpression.(*Expression) + if isExpression { + //Determine the depth of this part + newExpression, depth = expressionWalkMapBackwards(f, head, currentPartSpec, expression, es, spec) + if depth > currentMaxDepth { + currentMaxDepth = depth + } + + if spec.checkLevel(level) && spec.checkDepth(depth) { + newExpression = f(head, newExpression, currentPartSpec) + toReturn.Parts = append(toReturn.Parts, newExpression) + } else { + toReturn.Parts = append(toReturn.Parts, newExpression) + } + } else { //If the node is atomic + level = level+1 + depth = int64(1) + + if spec.checkLevel(level) && spec.checkDepth(depth) { + newExpression = f(head, expr, currentPartSpec) + toReturn.Parts = append(toReturn.Parts, newExpression) + } else { + toReturn.Parts = append(toReturn.Parts, newExpression) + } + } + } + + return toReturn, currentMaxDepth+1 +} + +func wrapWithHead(head Ex, expr Ex, partList []int64) *Expression { + return NewExpression([]Ex{head, expr}) +} + +func wrapWithHeadIndexed(head Ex, expr Ex, partList []int64) *Expression { + partSpec := []Ex{&Symbol{"System`List"}} + for _, part := range partList { + partSpec = append(partSpec, NewInt(part)) + } + partSpecExpr := NewExpression(partSpec) + return NewExpression([]Ex{head, expr, partSpecExpr}) +} + +//An idea for how Apply could also be implemented using mapFunction +func applyHead(head Ex, expr Ex, partList []int64) *Expression { + expression := expr.(*Expression) + toReturn := NewExpression([]Ex{head}) + toReturn.Parts = append(toReturn.Parts, expression.Parts[1:]...) + return toReturn +} + +func mapFunction(f func(Ex, Ex, []int64) *Expression) func(*Expression, *EvalState) Ex { + return func(this *Expression, es *EvalState) Ex { + // Optimization of the very common case where Map has two arguments + if len(this.Parts) == 3 { + expr, isExpr := this.Parts[2].(*Expression) + if isExpr { + toReturn := NewExpression([]Ex{expr.Parts[0]}) + for i := 1; i < len(expr.Parts); i++ { + toReturn.Parts = append(toReturn.Parts, NewExpression([]Ex{ + this.Parts[1], + expr.Parts[i], + })) + } + return toReturn + } + return this.Parts[2] + } + + if len(this.Parts) != 4 { + return this + } + + spec := parseLevelSpec(this.Parts[3], es) + if !spec.isValid() { + return this + } + + //If the second argument is atomic, it will be ignored except in one case + expression, nonAtomic := this.Parts[2].(*Expression) + if !nonAtomic { + if spec.checkLevel(0) && spec.checkDepth(0) { + return f(this.Parts[1], this.Parts[2], []int64{}) + } else { + return this.Parts[2] + } + } + + if spec.min == 0 && spec.max == 0 { + return f(this.Parts[1], this.Parts[2], []int64{}) + } + + //In this special case we do not have to keep track of depth, this can be computed faster + //than when depth is required because we do not always have to recurse all the way to the + //bottom of the expression + if !spec.isMinDepth && !spec.isMaxDepth { + newExpression := expressionWalkMap(f, this.Parts[1], []int64{}, expression, es, spec) + + if spec.checkLevel(0) && spec.checkDepth(0) { + return f(this.Parts[1], newExpression, []int64{}) + } else { + return newExpression + } + } + + //We now turn to the most general case, where levels can be specified as either + //positive or negative integers, where negative integers denote depth rather than level + newExpression, depth := expressionWalkMapBackwards(f, this.Parts[1], []int64{}, expression, es, spec) + + //Whether to wrap the zeroth level with the function. + if spec.checkLevel(0) && spec.checkDepth(depth) { + return f(this.Parts[1], newExpression, []int64{}) + } else { + return newExpression + } + } +} + + func getFunctionalDefinitions() (defs []Definition) { defs = append(defs, Definition{ Name: "Function", @@ -30,25 +395,14 @@ func getFunctionalDefinitions() (defs []Definition) { }) defs = append(defs, Definition{ Name: "Map", - legacyEvalFn: func(this *Expression, es *EvalState) Ex { - if len(this.Parts) != 3 { - return this - } + legacyEvalFn: mapFunction(wrapWithHead), + }) - expr, isExpr := this.Parts[2].(*Expression) - if isExpr { - toReturn := NewExpression([]Ex{expr.Parts[0]}) - for i := 1; i < len(expr.Parts); i++ { - toReturn.Parts = append(toReturn.Parts, NewExpression([]Ex{ - this.Parts[1], - expr.Parts[i], - })) - } - return toReturn - } - return this.Parts[2] - }, + defs = append(defs, Definition{ + Name: "MapIndexed", + legacyEvalFn: mapFunction(wrapWithHeadIndexed), }) + defs = append(defs, Definition{ Name: "FoldList", legacyEvalFn: func(this *Expression, es *EvalState) Ex { @@ -92,6 +446,7 @@ func getFunctionalDefinitions() (defs []Definition) { }, }) defs = append(defs, Definition{Name: "Fold"}) + defs = append(defs, Definition{ Name: "NestList", legacyEvalFn: func(this *Expression, es *EvalState) Ex { @@ -122,6 +477,7 @@ func getFunctionalDefinitions() (defs []Definition) { return toReturn }, }) + defs = append(defs, Definition{Name: "Nest"}) defs = append(defs, Definition{ Name: "NestWhileList", diff --git a/expreduce/resources.go b/expreduce/resources.go index a983f97..65bc1e0 100644 --- a/expreduce/resources.go +++ b/expreduce/resources.go @@ -137,7 +137,7 @@ func resourcesArithmeticM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/arithmetic.m", size: 9505, mode: os.FileMode(420), modTime: time.Unix(1504586851, 0)} + info := bindataFileInfo{name: "resources/arithmetic.m", size: 9505, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -157,7 +157,7 @@ func resourcesAtomsM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/atoms.m", size: 4303, mode: os.FileMode(420), modTime: time.Unix(1505695152, 0)} + info := bindataFileInfo{name: "resources/atoms.m", size: 4303, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -177,7 +177,7 @@ func resourcesBooleanM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/boolean.m", size: 3145, mode: os.FileMode(420), modTime: time.Unix(1501042154, 0)} + info := bindataFileInfo{name: "resources/boolean.m", size: 3145, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -197,7 +197,7 @@ func resourcesCalculusM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/calculus.m", size: 4916, mode: os.FileMode(420), modTime: time.Unix(1505695152, 0)} + info := bindataFileInfo{name: "resources/calculus.m", size: 4916, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -217,7 +217,7 @@ func resourcesCombinatoricsM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/combinatorics.m", size: 2893, mode: os.FileMode(420), modTime: time.Unix(1501042154, 0)} + info := bindataFileInfo{name: "resources/combinatorics.m", size: 2893, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -237,7 +237,7 @@ func resourcesComparisonM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/comparison.m", size: 11175, mode: os.FileMode(420), modTime: time.Unix(1505695152, 0)} + info := bindataFileInfo{name: "resources/comparison.m", size: 11175, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -257,7 +257,7 @@ func resourcesExpressionM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/expression.m", size: 5520, mode: os.FileMode(420), modTime: time.Unix(1505695152, 0)} + info := bindataFileInfo{name: "resources/expression.m", size: 5520, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -277,12 +277,12 @@ func resourcesFlowcontrolM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/flowcontrol.m", size: 4181, mode: os.FileMode(420), modTime: time.Unix(1505695152, 0)} + info := bindataFileInfo{name: "resources/flowcontrol.m", size: 4181, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _resourcesFunctionalM = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xcc\x59\x6d\x6f\xe3\xb8\x11\xfe\xae\x5f\x31\x88\x81\x3d\xe7\x4e\xcd\xc6\x8e\x9d\x6d\xf7\x1a\xc0\x8b\x76\x83\x1e\x70\x5d\x6c\x7b\x5b\xdc\x07\x41\x1b\x51\x0e\x1d\xa9\xab\x17\x83\xa2\x2e\xce\x05\xfe\xef\x9d\x21\x29\x89\x92\x25\xc7\xba\x6e\x8b\x3b\xdc\xc6\x12\x39\x33\x24\xe7\x99\x67\x86\xa4\x6e\xcb\x6c\x2d\xe3\x3c\x7b\xfb\xb6\x2c\xd8\x03\x87\x1b\x38\x0b\xaa\x36\x2f\xce\x32\x2e\xfc\x00\xee\xf9\x26\xce\x78\x01\x0c\xb6\xa5\xe0\xb0\x31\xfd\xf0\x18\x71\x7c\x0d\x94\x58\x00\x71\x01\xfc\x17\x96\x94\x4c\xf2\x7b\x78\x8c\x65\x04\xc1\x4f\x49\x2e\x03\xd8\x32\xc1\x52\x2e\xb9\x28\x2e\x1c\xa7\xb1\xbe\x73\xe1\xbf\x18\x80\x41\x11\x67\x0f\x09\x6f\xac\x43\xb0\x0b\x2e\xce\xbe\x77\xde\x49\x29\xe2\xb0\x94\xbc\xf0\xaa\xb1\x7c\x5c\xd7\xf3\xdf\xf2\xe4\xfe\x5d\x92\xb8\xf0\x51\xe4\x92\xaf\xd1\xc8\xfe\x7b\xe7\x13\x2f\x64\x51\xcf\x89\xc4\x1c\xc0\xff\xde\xff\x14\xa7\xdb\x84\xbf\xdf\x31\xfa\x29\x3c\xd5\xa8\x3b\x70\x30\x52\xf2\x66\xf0\x1d\xe0\x12\xea\xe5\xd0\xfb\xc4\xf7\x76\xbe\xef\x0e\x49\xe3\xbf\xf9\x53\x57\x85\x1a\x27\x73\x9f\xdc\xf1\xd4\xaf\xcb\x3e\xcf\x2d\x25\x94\xdb\x7d\x46\x79\x36\x4a\xd8\x85\xb0\x5f\x7e\xd7\x2b\x3f\xb0\x8a\x45\x8f\xe8\x1f\xe6\xbe\xaf\x44\x7d\x07\xfd\xe9\x10\xe4\x76\x30\x4d\x02\x28\xb8\xf8\x85\xc0\x3d\xc0\xf7\x9b\x02\x36\xb1\x28\x64\x83\x21\x05\xc8\x24\x3b\xae\x12\x64\xc1\x37\x18\x5c\x8d\x4e\x1b\x73\x9a\x80\xc2\xfb\xc3\x11\xc0\x49\xe8\xf7\x09\xf6\x27\x51\x72\x17\x05\x6f\x6e\x6e\x80\x66\xe9\xcd\x8e\xca\xcd\x1b\xc1\x79\xbf\xe0\x9c\xe1\xa0\x8b\xd0\x85\xe9\x42\x8d\x3f\x9d\xe3\xcf\xab\x73\x8c\x1f\xfa\x1b\x56\xe0\xb9\xf0\x5e\xb9\xa6\x6f\xf5\x9b\x3c\xf7\xd0\xb5\xd2\x85\x2f\x28\x37\x6d\x5e\x27\x64\x03\x5e\x79\xff\xf6\xbd\x2f\xad\x28\x78\xb7\xdd\x26\x4f\x76\x18\xa8\x06\x6f\xe3\x02\x47\xba\x4f\x83\xcd\x6a\xc5\x83\x73\x10\x7c\x9b\xb0\x35\x02\x2d\x23\x0e\x11\x67\xf7\x90\x6f\x80\xef\xb6\x82\x17\x05\xd1\x31\xe0\x81\xc9\x24\x9b\x2e\xb5\x95\x41\x85\xf3\x21\xba\xaa\x6f\x0c\xbc\x21\x13\x5e\xf1\x94\x22\x4b\xf0\x6f\x88\x6b\xd4\xd3\xc5\x66\x17\x68\xb5\x56\x5f\xbf\x93\x0f\x0c\x60\xc3\x6a\xd5\x55\xed\xd3\x7c\x6e\x04\xf6\x2e\xfc\x18\x17\x72\xb5\x9a\x52\x1b\x42\x45\x8d\xe7\xb6\xd6\x5f\xf2\x34\xe5\x99\xf4\x8c\x3f\x55\x4a\x2c\x0b\xbe\x29\x13\x4c\xa5\xb0\xe5\x62\x93\x8b\x14\xd3\x22\xb0\x87\x07\xc1\x1f\x18\x05\x5e\x01\xe4\x48\x32\x1c\x14\x6f\xcf\xfa\xe3\x15\x53\xc0\xa7\x38\x45\x1c\x56\x2b\x78\xc6\x97\xeb\x7d\x7f\x6e\x81\xd0\x16\xa4\xa4\xb2\x6f\xc2\xe7\xb6\x14\x08\xa3\xe8\xf1\xf3\xc1\xb4\x23\x24\x76\x96\x03\xdf\x6c\x10\x38\x9a\x1f\x93\x79\x3a\x38\x3b\x85\x01\x8d\x38\x1b\xf2\x7d\x2d\x81\xcf\x27\xc6\x33\x73\x43\x77\x5d\x23\x8d\x2d\x2e\x2d\x08\xdb\xf6\xfd\x38\x91\x8e\x1a\x29\x2c\x7f\xfd\xb5\xa3\x57\xb7\x9f\xa8\x6b\x26\x6b\xeb\x0d\xa9\xe1\xe2\xe7\x96\x06\xbd\xee\x6d\xa2\xfd\x9d\x6d\x6d\x9a\xe1\xab\x22\x19\x52\x08\x79\x26\xb8\x2c\x45\x46\x39\x34\xe3\x8f\x36\xaf\x14\xa7\x88\x73\x05\x8e\xa5\x89\x87\x88\x04\x24\x11\xd0\x8c\x64\xcd\x3a\x48\xd9\x76\x8b\xe5\x56\x22\x5a\x6c\x1d\x11\x3f\x49\x8f\x89\x87\x92\x20\x2d\x3a\xac\xc4\xf1\x07\x38\x89\x3d\x63\x18\xf9\xac\x30\xd2\x2b\xf7\x42\xf3\xbb\xf6\x91\x22\x6a\x89\x06\x2e\x8a\xc7\x21\xc0\x86\x2d\x90\x33\x5f\xaf\x2c\xfd\x5e\x75\xa4\x01\x96\xbb\x3f\xed\xab\x88\x7f\xad\xa9\xa1\xda\x86\x07\x34\xa4\xe8\x9d\xaf\xee\x1b\x9e\xb1\x91\xf4\x6b\x9d\xc1\x68\xb2\xac\x0e\x8a\xd9\x12\x5a\xac\xad\x75\xa8\x5a\xd3\xf4\xa3\x5d\x71\x31\x7c\xf0\xcd\x64\x19\x1d\x16\x68\x26\x18\x20\xeb\xf3\xc2\x9d\x5d\xef\x0f\xb7\x09\xc6\x7d\x8b\x01\xd7\x75\xb5\x26\x2d\x15\x2b\xde\x6f\xb1\xa6\x53\x2e\x6b\xed\x57\x4d\x1b\x45\xfe\xce\xad\xf2\x52\x1d\xfd\xcf\xd8\xb6\xa1\x79\xa8\x60\xf0\xea\xc7\xd0\xdf\x9f\x39\x8d\xee\x9d\xa6\xcd\x9d\x0f\x6f\x6f\xc0\x36\x79\x4b\x5b\x14\x4f\x51\xca\x85\x7f\xf2\xea\xd9\x77\xa6\xdf\x5a\x72\x77\xbe\x6a\xbe\x3b\xd4\x57\xd2\xf0\x73\xc4\x33\x28\xca\x90\x36\xb0\x5c\xfb\x94\x25\x49\xfe\x88\xdc\xfa\xf6\xbc\xb5\x67\x35\xaa\x03\x3c\xaa\xba\x47\x91\x89\x52\x68\x9d\x4a\xbc\xfa\xf1\x8a\xe2\xd3\x9e\x2a\xb6\x53\x8c\x5f\x0d\x51\xea\x54\x3b\x2a\x4f\x75\xed\xa0\xbb\x46\x9b\xf2\x3d\xdb\x14\x79\xea\x70\x56\x91\xc7\x95\x31\xfa\xcb\x2b\x73\xf5\x0b\xbf\x32\x2d\xdd\x36\xbe\x20\x8b\x2d\xa0\xb0\x1f\x8d\xcd\x49\x40\xf7\xf7\x7b\x21\xea\xac\x36\xc2\x05\xef\x9b\xed\x8f\x0e\xd2\x6e\x80\xb6\x83\xb3\xc9\xcd\x41\x2b\x22\x31\xfb\xb2\x0c\xb3\x6d\x84\x85\x1d\x0f\x44\x92\x6a\xf9\x3a\xcf\xf0\x97\x82\x06\xab\x3b\x24\x38\x68\x41\x69\x98\x89\x30\x96\x82\x89\x27\x48\x78\xf6\x20\xa3\x0b\xa8\xc7\x69\x32\x9b\x35\x4e\xd5\xc9\xa8\x60\xe9\xce\x5a\xc5\x57\x3b\x09\x96\x41\x8e\x7b\x08\xac\xc5\x82\x86\x4a\x71\x1a\x4c\xc2\x1a\x9b\x43\x0c\x56\xac\x77\xb1\x29\x04\x75\x21\x29\x30\xa2\xb1\x28\x50\xed\xa8\xc7\xc4\x8d\x9a\xa3\xad\x22\xa3\x76\x2d\x56\xfd\xc8\xd0\x61\x1d\xb6\x1a\x2e\xd5\x1a\x47\xa4\x87\x88\x58\x33\xb1\xcb\xc2\x03\x0b\x5a\x7e\x1c\x17\x8f\xf0\x70\x0c\x07\x5b\x31\xee\x42\x85\xc6\x0b\x8c\x1b\xd0\x7a\x99\x5f\xbd\x8a\xa7\xb0\x69\x80\x2a\xcd\xd8\x27\xb2\x24\x6a\x34\x0e\xf8\xf1\x01\x05\xba\x49\xbc\x6a\xab\x60\x72\x21\x6b\xb1\x04\x0f\x02\x42\x6f\x45\x98\xc8\x4b\xe4\x88\xde\xad\x98\x03\x64\x9e\xad\xf1\x34\x24\x09\x57\xf9\x18\xd3\x33\xd1\xa8\xc8\x69\x6f\x59\x6e\x29\x68\xf1\xd4\x08\x92\x0a\x39\x86\xa7\x85\x70\x35\x6c\x07\x65\x03\x72\xd5\x3b\x2a\xd9\xea\x72\x53\xd5\x1a\xbf\x4e\x3f\xf8\x48\xc9\xcd\x5e\xe8\x8e\xd0\xe9\x4f\x32\x35\x52\x1a\x6d\xb3\x15\xa1\xc7\xd9\xb5\x0b\x7f\x9c\x99\x97\xf9\x12\xdf\xae\x97\xd7\xb3\xbd\x6d\x1a\xcb\x27\xbc\xb2\xc2\x44\x0d\xd3\xf6\x7f\xd7\xf7\x63\xfd\x6e\xfb\x53\xeb\x57\xe4\x45\x0b\x16\xfd\xfa\x70\xf5\xbb\x08\x0c\x7b\x7f\x2c\xc5\xb4\x9b\xb5\x2b\x5e\xf0\x70\xcb\x7b\x46\xe3\x04\xc7\xfd\x1c\xc5\x09\xef\x8b\xde\xba\xa3\x59\xaa\x3e\x25\xa7\xf8\x3f\xdb\x69\xc7\xea\x34\xaa\x1d\x4b\x51\xa9\x9d\x59\x62\x86\x4f\x20\x20\xf1\x00\xee\x73\x4e\xa7\x23\x69\x40\x80\x80\x8e\xfa\xc1\x85\xf3\x83\xb4\x36\xf4\x54\x06\x54\x15\x48\xe8\xe8\x27\xb9\x48\xf9\x7d\xcc\x24\x47\x91\xa2\x4c\x70\x5f\x5e\x59\xa3\xbc\xde\x5c\xa8\xa9\x8c\x2e\xd9\x17\x7d\xb7\x12\xcb\xa2\xde\xc9\xab\x6d\x7d\x82\x88\x41\x90\x06\xb5\x15\x27\xc0\x99\xd3\xfd\x1c\xce\xc7\x1c\xd3\xb1\x21\x4e\xcb\x14\xb2\x32\x0d\xb9\x50\x73\xa0\x35\xad\xab\xc3\xe6\x46\xad\x8d\xe8\x47\x21\xd2\x68\xe2\xc0\xd4\x51\x44\x79\x89\x99\xd3\xaa\x28\x0c\x25\x22\xba\xbe\xab\x22\x0a\xd8\x06\x17\xe4\x98\x05\xd0\x59\x91\xd6\x17\x67\xea\xde\x8f\xa6\x20\xf8\xba\x14\x54\x7f\x0e\xb9\x5c\x83\x30\x1c\x52\xb5\xc8\x98\xd8\x7a\x83\x67\x73\x55\x66\x57\x6d\xa8\xa7\x74\xa5\x72\xf5\x7a\x72\xfe\x5a\x05\xce\xec\xe2\xd2\x85\x7f\x65\x74\xac\xfa\x87\x37\x99\xd1\x05\x8d\x4f\xed\x03\x77\x33\xe6\x40\x41\x8c\xc6\x50\x34\x41\xd8\x18\x37\xd1\x38\xa7\xfb\xa0\x3f\x93\x04\xbc\x3a\x12\xcb\x18\xab\xca\xda\x12\x43\xda\x85\x37\x87\xd6\xbe\x9b\xa9\x29\xba\xea\x1a\x68\xb2\x40\x93\xb3\x4b\x6a\x59\x9c\x62\xf4\x88\x39\x8a\x4f\xf3\x78\x92\x29\x3d\x3f\x4c\x62\x98\xd3\x50\xeb\xf2\x44\xd3\xa8\xd9\xcb\xc5\x5e\x1e\xfe\x8f\x38\xf8\x55\x48\x05\x63\x49\xe5\x7c\x35\x52\xc1\x6f\x27\x55\x97\x50\x8d\xab\x71\xb5\xc5\x5d\x27\xe5\x37\x60\x52\x2f\xe2\xd6\xe1\xdf\x18\xee\xa9\x2c\xdd\x0c\x77\x32\x2b\xde\xb4\xb4\x46\x46\xff\xb2\x5f\xf9\xe5\x58\x9f\x5d\xbe\xac\xd9\x09\xe5\xdb\x78\xc7\xef\x3f\xe6\x98\xc7\x0f\x8e\xb6\xad\x1e\xeb\x6a\xe7\x68\x0c\x9b\x04\x14\xd8\x9b\x76\x82\x58\x3e\xe6\x90\xe6\x05\x45\xf5\x9a\xa2\xd3\x04\xa4\x53\x95\x95\x5b\x96\x14\xfc\x02\xc6\x15\x9a\x33\xa7\x3b\xc9\xd6\x2e\x7e\xa0\x32\x9a\x29\x52\x66\xac\x36\xd4\x2d\x2b\xbf\x2d\x37\x77\x66\x72\x98\x9c\x07\xd2\xd3\xee\x33\xa6\xa6\x2b\x50\xdf\x42\xae\x69\xcf\x80\x01\x87\x30\x52\x66\xea\x98\xfc\xab\x37\xc1\x4d\x85\xca\xe9\xa8\xd4\x0f\x62\x3f\x80\xff\x1f\xf0\x6c\x34\xfa\xce\x53\x2f\xc3\x71\x88\xc7\x18\x2c\x2e\x6d\x8f\x1d\xf1\xd6\x3b\x21\x58\xfb\x03\x01\x35\xd0\x84\x28\x43\xaf\x05\x67\x92\xdb\xe1\x87\xc7\xe4\x98\x4e\xc7\xfa\x02\x2a\x0e\x50\x67\x66\xb6\xf5\xdd\x0f\x03\x64\x68\xe8\xc3\x00\xf5\x8d\xbb\x86\xf4\x66\x6a\x03\xaf\xef\x15\xd4\xed\x44\x3d\xd3\x81\x8d\xe5\x87\x92\xbe\x39\xa5\x4f\x52\x7d\x5e\xd3\xbe\x5f\xf6\xc7\xdd\x52\x55\xc3\x65\x6d\x54\x2b\x0d\x6f\x59\xa7\xf4\x55\x20\x3c\x57\x73\xaa\x9e\xe7\xd6\xb3\x35\x3f\xd5\x32\x68\xc9\xc8\xe8\x6b\x07\xeb\xc5\xbe\x6a\xfb\x01\xcb\x8c\x8c\x65\x0b\xa5\xaa\x4d\x9f\xb2\xed\x83\x82\x8a\x61\x82\xa2\x23\x42\xab\xa7\xa7\x16\x46\x95\xcc\x00\x4c\x55\xf7\x18\xa4\xd0\x8f\xf5\xc8\xcb\x81\x4f\xa3\x96\x48\xfd\xc0\x7c\x7b\xd1\xff\x09\x00\x00\xff\xff\xb9\xa0\xf4\xf7\x0f\x1f\x00\x00") +var _resourcesFunctionalM = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xcc\x3a\x6d\x6f\xdb\x38\xd2\xdf\xfd\x2b\x06\x31\xd0\x4d\x76\x95\x34\x56\x5e\xfa\x3c\xdd\x0b\xe0\xe0\xae\xc1\x05\xe8\x15\xbd\xdb\x1e\xf6\x83\xa0\x46\xb4\x4d\x45\x6a\x64\xc9\x90\xa8\xc6\xd9\xc0\xff\xfd\x66\x48\x4a\xa2\xde\x6c\xab\x9b\xf6\x2e\x68\x6d\x69\x38\x33\x1c\xce\x3b\x49\xdf\xe4\xf1\x5c\x84\x49\xfc\xf6\x6d\x9e\xb1\x7b\x0e\x57\x70\xe0\x15\x30\x27\x8c\x63\x9e\xba\x1e\x2c\xb8\x1f\xc6\x3c\x03\x06\xab\x3c\xe5\xe0\xeb\x71\x78\x0c\x38\xbe\x7a\x12\xcd\x83\x30\x03\xfe\x95\x45\x39\x13\x7c\x01\x8f\xa1\x08\xc0\xfb\x2d\x4a\x84\x07\x2b\x96\xb2\x25\x17\x3c\xcd\x4e\x46\xa3\x8a\xfb\xda\x82\x3f\x31\x01\x83\x2c\x8c\xef\x23\x5e\x71\x07\x6f\xed\x9d\x1c\xfc\x3a\xba\x16\x22\x0d\x67\xb9\xe0\x99\x53\xcc\xe5\xe2\xba\x9e\xff\x9e\x44\x8b\xeb\x28\xb2\xe0\x63\x9a\x08\x3e\x47\x26\x9b\x5f\x47\x9f\x78\x26\xb2\x52\x26\x42\x1b\x01\xfe\xbd\xfb\x2d\x5c\xae\x22\xfe\x6e\xcd\xe8\x2b\x73\x24\x50\x0d\xe0\x64\x44\xe4\x4c\xe0\x17\xc0\x25\x94\xcb\xa1\xf7\xb1\xeb\xac\x5d\xd7\xea\xc3\xc6\xff\xf6\x53\x93\x84\x80\x63\xdb\x25\x75\x3c\x75\xd3\xb2\xcf\xb6\x41\x84\x78\xeb\xcf\x88\xcf\x06\x21\x5b\x30\xeb\xc6\x5f\x77\xe2\xf7\xac\xe2\xbc\x03\xf5\xd8\x76\x5d\x89\xea\x8e\x50\x9f\x23\x32\xb9\xe9\x4c\x63\x0f\x32\x9e\x7e\x25\xe3\xb6\xec\xfb\x53\x06\x7e\x98\x66\xa2\xb2\x21\x39\xc8\x38\xde\x4e\xe2\xc5\xde\x4f\xe8\x5c\x15\x4d\xdd\xe6\x24\x80\xb4\xf7\x87\x2d\x06\x27\xa4\xff\x4d\x63\x7f\x4a\x73\x6e\x21\xe2\xd5\xd5\x15\x90\x94\xce\x64\x2b\x9e\x5d\x21\xda\xdd\x88\x36\xc3\x49\xcf\x67\x16\x1c\x9e\xcb\xf9\x0f\x6d\xfc\x7a\x75\x84\xfe\x43\x9f\xb3\xc2\x78\x16\xbc\x93\xaa\xe9\x5a\xbd\x9f\x24\x0e\xaa\x56\x58\xf0\x80\x78\x87\xd5\xeb\x98\x78\xc0\x2b\xe7\x8b\xeb\x3c\xd4\xbc\xe0\x7a\xb5\x8a\x9e\x4c\x37\x90\x00\xc7\xb7\x80\x63\xb8\x1f\x7a\xfe\x74\xca\xbd\x23\x48\xf9\x2a\x62\x73\x34\xb4\x08\x38\x04\x9c\x2d\x20\xf1\x81\xaf\x57\x29\xcf\x32\x0a\x47\x8f\x7b\x3a\x93\xf8\xcd\xd0\x96\x0c\xa5\x9d\xdb\xd6\x95\x63\x43\xcc\x3b\x63\xa9\x93\x3d\x2d\x31\x4a\xf0\x73\x86\x6b\x54\xe2\x22\xd8\x02\x5a\xad\x31\xd6\xad\xe4\x16\x03\x04\x4c\xa7\x4d\xd2\x2e\xca\xe7\x0a\x61\x63\xc1\xfb\x30\x13\xd3\xe9\x21\xc1\xd0\x54\x04\x3c\x32\xa9\xfe\x9a\x2c\x97\x3c\x16\x8e\xd6\xa7\x4c\x89\x79\xc6\xfd\x3c\xc2\x54\x0a\x2b\x9e\xfa\x49\xba\xc4\xb4\x08\xec\xfe\x3e\xe5\xf7\x8c\x1c\x2f\x03\x52\x24\x31\xf6\xb2\xb7\x07\xdd\xfe\x8a\x29\xe0\x53\xb8\x44\x3b\x4c\xa7\xf0\x8c\x2f\x97\x9b\xee\xdc\x02\x33\x13\x91\x92\xca\xa6\x72\x9f\x9b\x3c\x45\x33\xa6\x1d\x7a\x6e\x89\x1d\x60\x60\xc7\x09\x70\xdf\x47\xc3\x91\x7c\x4c\x24\xcb\x5e\xe9\xa4\x0d\x68\xc6\x49\x9f\xee\x4b\x0c\x7c\xde\xd3\x9f\x99\x35\xb3\xe6\xa5\xa5\x11\x62\xd1\x82\x10\xb6\xe9\xb6\x13\xd1\xc8\x99\x66\xf9\x1f\x7f\x34\xe8\x4a\xf8\x9e\xb4\x5a\x58\x93\xae\x8f\x0c\x17\x6f\x1b\x14\xf4\xba\x31\x03\xed\x1f\x6c\x65\x86\x19\xbe\xca\x20\xc3\x10\xc2\x38\x4b\xb9\xc8\xd3\x98\x72\x68\xcc\x1f\xcd\xb8\x92\x31\x45\x31\x97\xe1\x5c\x2a\xf0\xd0\x22\x1e\x61\x78\x24\x91\x28\xa3\x0e\x96\x6c\xb5\xc2\x72\x2b\xd0\x5a\x6c\x1e\x50\x7c\x12\x1d\x4b\xef\x73\x32\x29\x56\x74\x63\x4a\x0b\x22\xfe\x95\x47\xd9\x8a\xcf\x5d\x22\xc4\xf4\x4e\x84\x2c\x8a\x20\xcb\x67\xd5\xfc\x14\xef\x4c\x20\x86\x98\x2b\x31\x24\x19\x10\x5d\xe8\x87\x73\xe9\xb6\x15\xab\x46\xe0\xe3\x7c\x3d\x61\x8f\x23\x43\x82\xfe\x59\xba\x81\x52\xae\x33\xd3\xdf\x73\x17\xa3\x50\x2e\x49\x7b\x04\xb9\x7c\x9f\x4f\xf4\x73\x20\x7b\xbd\x9e\x1a\xf4\x9d\xe4\x18\x69\x58\x51\xff\x7f\x53\x04\xd5\x6b\x15\x7d\x12\xd6\x3f\xa1\x8e\xbb\x4e\x79\xd5\x58\xbf\xc4\x1a\xd3\x2d\x69\x7a\x1d\xd6\xe0\xda\x8b\x66\x62\x28\xb4\x3a\x55\x9b\xb4\xcc\x04\x1f\xcd\xa2\x8e\x1e\x8a\x6f\x3a\x91\x29\xcf\x43\x36\x5e\x4f\x3e\x78\x3e\xb7\x26\x97\x9b\x76\x27\xa2\xd5\x77\xde\xa3\xba\x26\xd5\x78\x27\x49\x09\xa2\x3f\xed\xe6\xcc\x99\x39\x73\x0b\x16\x54\xc8\xd0\xdd\x9d\x7b\x27\xb0\xe0\x8b\x4b\x95\x11\x3f\x9e\x8f\x6f\x63\xec\x64\x43\x81\x85\xbf\x78\x32\x79\xd3\x9f\xef\x30\xc7\x47\x2e\xbe\x43\xe9\xc7\x77\x16\xf2\x93\x53\x61\xc1\xef\x08\xe1\xf7\xf8\x3f\x90\x6f\x5f\x34\x14\x99\xbb\xba\xbe\xaa\xe4\xf6\x22\xd2\x16\x12\x36\x04\xfc\x46\xf1\x5e\x5a\xba\xe7\x63\xbb\x5f\x89\xfd\x32\xf6\x4b\xf8\xe2\x02\xa2\x7c\xc7\x76\x5b\xb2\x3a\x8d\x5f\x50\x29\xb2\x97\x16\xc2\x1e\x6c\xbc\x42\x98\xef\x64\xb6\xe3\x6e\x89\x0a\x82\x0e\x41\xea\xb6\xa9\xd7\xb6\xdb\x78\xc1\xd7\x7c\xd1\x28\x71\x1a\xfa\xa3\x2b\xdd\xf5\x62\x11\x52\xea\xc0\x7a\xf6\x24\x13\xdd\xed\x22\x26\x39\xb0\xb8\x61\x33\x10\xea\x36\x16\xf7\x25\xa2\x51\xca\x34\xab\x5a\x0d\x24\x31\x24\x90\xcf\x93\x78\x51\x4e\x43\xb8\xfe\x0f\x28\xaa\x68\xc6\x28\x4b\x94\xe4\x4f\xd4\x31\xf6\x88\x8e\x0d\xe5\x48\xaa\x63\x2f\xe1\x51\x2e\xbf\x5d\xae\xb5\xb9\x1a\x55\xbb\x2a\xda\x7a\x7c\x48\xed\x6e\xfa\xa5\xe1\x11\x2f\x9a\xa1\x2d\xd9\x72\x4d\x36\x2a\x9a\xac\xa2\x01\x93\x51\xa5\xde\xce\x36\x92\xad\x46\x29\xb3\x8f\x4a\x0f\x15\xed\x97\x12\x60\x6f\x8a\xe4\xa1\x87\x1e\xd4\x5b\x01\x57\x5f\x9b\x81\x81\xb9\xb7\x02\x76\x25\xfd\xff\xce\x8a\xbf\xd3\x62\xf7\xab\x21\xc3\x96\xfc\x27\x17\xfc\xdd\x96\x3a\xac\x1a\x19\xe2\x0d\xae\x4a\x7b\xcb\xd4\x5b\x9c\xbe\xcd\xc9\x9a\x82\xff\x40\x47\xda\x51\xd5\x76\x49\xfa\xd0\x16\xcf\xa8\x73\x37\x49\xb4\xa0\xfd\x79\xed\x0c\x56\xc3\x48\xb4\xb5\x55\xec\xb5\xcb\x3a\xf7\xbc\xa6\xc9\xf0\x43\xee\x3e\x9c\xf2\x71\xe6\x6e\x0e\x46\x15\xed\x9d\x2a\x21\x77\x2e\xbc\xbd\x02\x93\xe5\x0d\x1d\xbb\x39\xb2\x78\x5a\xf0\x2f\x5e\x3c\xbb\xa3\xc3\x9f\x0d\xbc\x3b\x57\x82\xef\xda\xf4\x12\x1b\x7e\x0f\x78\x4c\x85\x81\x0e\x65\xb9\x6a\xe2\xb1\x2c\x25\x8f\x98\xcb\x7f\x3e\xaa\x9d\xc3\x6a\xd2\x9e\x8d\x5b\x31\x3c\x68\xf7\x46\xc7\x02\xe5\xf6\xd8\x29\x1f\xcf\x68\x43\x64\x8a\x3a\x51\x76\x38\xeb\xdb\xc3\xed\xcb\x47\xfa\x68\x93\x0f\xaa\x6b\x30\x2b\xd7\x31\x59\x91\xa6\xda\x52\x05\x0e\x97\xcc\xe8\x93\x17\xec\xca\x17\x7e\xa6\x21\x4d\x18\x3f\x27\x8e\x35\x43\xe1\x38\x32\xb3\x09\x41\x8d\x77\x6b\x21\x68\xac\x36\x90\x35\xa8\xf4\x52\xe5\xa4\x4d\x07\xad\x3b\x67\xd5\x85\x79\x35\x8f\xc4\x3e\x8b\x61\x93\x20\x82\x30\xc3\xee\x2c\x13\xd4\x6d\x60\xdb\x80\xdf\xe4\x34\xd8\x60\x40\x84\x93\x66\xd4\xf9\xb0\x74\x16\x8a\x94\xa5\x4f\xd8\xa8\xc4\xf7\x22\x38\x81\x72\x9e\x6a\x2b\x6d\xcc\x53\x0c\x32\x3a\x84\x51\x83\x25\x89\x2b\x4f\xc7\x18\x76\x5f\x2b\x9e\x32\x81\xd3\xd0\xe1\x98\x6a\x92\xe6\x08\x9e\xa1\xb3\xca\xb6\x4d\xb5\x7c\x46\x1f\x95\xe5\xd8\xef\x50\x97\x58\xce\xe9\x9d\xa8\xa8\x92\x11\xb5\xae\x45\xd5\x7b\x86\x0a\x6b\x44\xab\x8e\xa5\x92\x62\x0b\x76\x5f\x20\x96\x91\xd8\x8c\xc2\x16\x07\x85\x3f\x2c\x16\xb7\xc4\xe1\x90\x18\xac\xf9\xb8\x05\x85\x35\x76\x44\x5c\x0f\xd5\xee\xf8\xea\x24\xdc\x27\x9a\x7a\x42\xa5\x9a\x7b\xcf\x28\x09\x2a\x8a\x56\x7c\x7c\x40\x84\x66\x12\x2f\x60\x55\x2b\x1f\xd7\xa2\xc4\x83\xc7\x54\x6d\x3a\x58\x9a\xe4\x18\x23\x6a\x5f\xa2\x2f\x45\x92\x78\x8e\xc5\x50\x90\x5d\xc5\x63\x48\xcf\x14\x46\xd8\xb4\x63\xff\x9d\xaf\xc8\x69\xbd\xd8\x03\x41\x27\x47\xe8\x9e\x86\x85\x8b\x69\xbb\x1b\xee\x62\x74\x50\xb2\x55\xe5\xa6\xa8\x35\x6e\x99\x7e\xf0\x91\x92\x9b\xb9\xd0\x35\x59\xa7\x3b\xc9\x94\x96\x52\xd6\xd6\x67\x5f\xb2\x15\xb8\xb4\xe0\xff\x26\xfa\xc5\xbe\xc0\xb7\xcb\x8b\xcb\xc9\xc6\x64\x3d\xfe\x6c\xc3\x2b\xc3\x4d\xe4\x34\x75\xfd\x37\x75\x3f\x54\xef\xa6\x3e\x15\x7d\x11\xbc\xc8\xc1\x08\xbf\x2e\xbb\xba\x4d\x0b\xf4\x6b\x7f\x68\x88\x29\x35\x2b\x55\xec\xd0\x70\x4d\x7b\x9a\x62\x0f\xc5\xfd\x1e\x84\x11\xef\xf2\xde\x72\xa0\x5a\xaa\xba\xf9\x59\xe2\x3f\xb6\x56\x8a\x65\x7a\xf7\x4b\x8a\x25\xaf\x54\xca\xcc\x31\xc3\x47\xe0\x11\xba\x07\x8b\x84\xd3\x89\xbf\xd0\x46\x00\x8f\xae\xaf\xbc\x93\xd1\xad\x30\xb6\xee\x54\x06\x64\x15\x88\xe8\x3a\x43\xf0\x74\xc9\x17\x21\x13\x1c\x51\xb2\x3c\xc2\x1d\x78\xc1\x8d\xf2\x7a\x75\x49\x2c\x33\xba\x60\x0f\xea\xbe\x30\x14\x99\xb1\x1f\xa5\x6d\x30\x5a\x0c\xbc\xa5\x57\x72\x19\x79\x28\x39\xdd\x39\xa3\x3c\x7a\xcf\x8e\x80\x70\x99\x2f\x21\xce\x97\x33\x9e\x4a\x19\x68\x4d\xf3\xe2\x02\xc5\x97\x6b\xa3\xf0\x23\x17\xa9\x28\x71\x62\x1a\xc8\x82\x24\xc7\xcc\x69\x54\x14\x86\x18\x01\x5d\x49\x17\x1e\x05\xcc\xc7\x05\x8d\xf4\x02\xe8\xfe\x83\xd6\x17\xc6\xf2\x2e\x9b\x44\x48\xf9\x3c\x4f\xa9\xfe\xb4\x63\xb9\x34\x42\xbf\x4b\x95\x28\x43\x7c\xeb\x8d\x05\xef\x65\x99\x9d\xd6\x4d\x7d\x48\xd7\x84\x67\xaf\xc7\x47\xaf\xa5\xe3\x4c\x4e\x4e\x2d\xf8\x77\x4c\x07\x28\xff\x74\xc6\x13\xba\x74\x74\x09\xde\x73\xdf\xa8\x4f\xb0\x29\xa2\xd1\x15\xb5\x13\x56\xcc\xb5\x37\xda\x74\xc7\xf9\x17\xc2\x80\x57\x5b\x7c\x19\x7d\x55\x72\xbb\x40\x97\xb6\xe0\x4d\x9b\xdb\x2f\x13\x29\xa2\x25\xaf\x36\xc7\xe7\xc8\x72\x72\x4a\x90\xf3\x7d\x98\x6e\x61\x47\xfe\xa9\x1f\xf7\x62\xa5\xe4\xc3\x24\x86\x39\x0d\xa9\x4e\xf7\x64\x8d\x94\x9d\xb1\xd8\x19\x87\xdf\x29\x06\x5f\x24\xa8\x60\x68\x50\x8d\x5e\x2c\xa8\xe0\xdb\x83\xaa\x19\x50\x95\xaa\x71\xb5\xd9\x5d\x23\xe5\x57\xc6\xa4\x51\xb4\x5b\x23\xfe\x86\xc4\x9e\xcc\xd2\xd5\x74\x7b\x47\xc5\x9b\x1a\xd5\x40\xef\xbf\xe8\x26\xde\xed\xeb\x93\xd3\xdd\x94\x0d\x57\xbe\x09\x71\x63\xfd\x31\xc1\x3c\xde\xda\xda\xd6\x46\x8c\x43\xdc\xad\x3e\xac\x13\x90\x67\x36\xed\x64\x62\xf1\x98\xc0\x32\xc9\xc8\xab\xe7\xe4\x9d\xda\x21\x47\x45\x59\xb9\x61\x51\xc6\x4f\x60\x58\xa1\x39\x18\x35\x85\xac\x75\xf1\x3d\x95\x51\x8b\x48\x99\xb1\x68\xa8\x6b\x5c\xbe\x2d\x37\x37\x24\x69\x27\xe7\x9e\xf4\xb4\xfe\x8c\xa9\xe9\x0c\xe4\xef\x7b\x2e\xa9\x67\x40\x87\x43\x33\x52\x66\x6a\xb0\xfc\x9b\x33\xc6\xa6\x42\xe6\x74\x24\xea\x36\x62\xb7\x01\x7f\x8c\xf1\x4c\x6b\x74\xed\xa7\x76\x9b\xa3\x6d\x8f\x21\xb6\x38\x35\x35\xb6\x45\x5b\xd7\x69\xca\xea\x3f\x7a\x21\x00\x09\x44\x19\x7a\x9e\x72\x26\xb8\xe9\x7e\xb8\x4d\x0e\x69\x77\xac\x6e\x20\x42\x0f\x69\x26\xba\xad\x6f\xfe\xd8\x85\x18\xf5\xfd\xd8\x85\xc6\x86\xdd\x7b\x3b\x13\xd9\xc0\xab\x73\x05\x79\x3a\x51\x4a\xda\xd3\x58\x7e\xc8\xe9\x77\x54\xcb\x27\xca\xb4\xce\x5a\xe9\xfe\xa2\xdb\xef\x2e\x64\x35\xbc\x28\x99\x2a\xa2\xfe\x96\xf5\x90\x7e\xe9\x32\x3b\x92\x32\x15\xcf\xb6\xf1\x6c\xc8\x27\x21\xbd\x9c\x34\x8e\x3a\x76\x30\x5e\xcc\xa3\xb6\x5b\x2c\x33\x22\x14\x35\x2b\x15\x30\xb5\xcb\x36\x37\x0a\xd2\x87\xc9\x14\x0d\x14\x5a\x3d\x3d\xd5\x6c\x54\xe0\xf4\x98\xa9\x18\x1e\x62\x29\xd4\x63\x39\xf3\x45\xcf\xcf\xfd\x0c\x94\xf2\x81\xb9\xe6\xa2\xff\x13\x00\x00\xff\xff\xf3\xbb\x86\x98\xe3\x29\x00\x00") func resourcesFunctionalMBytes() ([]byte, error) { return bindataRead( @@ -297,7 +297,7 @@ func resourcesFunctionalM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/functional.m", size: 7951, mode: os.FileMode(420), modTime: time.Unix(1505695173, 0)} + info := bindataFileInfo{name: "resources/functional.m", size: 10723, mode: os.FileMode(420), modTime: time.Unix(1506889973, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -317,7 +317,7 @@ func resourcesInitM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/init.m", size: 131, mode: os.FileMode(420), modTime: time.Unix(1501042154, 0)} + info := bindataFileInfo{name: "resources/init.m", size: 131, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -337,7 +337,7 @@ func resourcesListM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/list.m", size: 14779, mode: os.FileMode(420), modTime: time.Unix(1505695152, 0)} + info := bindataFileInfo{name: "resources/list.m", size: 14779, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -357,7 +357,7 @@ func resourcesManipM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/manip.m", size: 9421, mode: os.FileMode(420), modTime: time.Unix(1505695152, 0)} + info := bindataFileInfo{name: "resources/manip.m", size: 9421, mode: os.FileMode(420), modTime: time.Unix(1506021587, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -377,7 +377,7 @@ func resourcesMatrixM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/matrix.m", size: 5151, mode: os.FileMode(420), modTime: time.Unix(1501042154, 0)} + info := bindataFileInfo{name: "resources/matrix.m", size: 5151, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -397,7 +397,7 @@ func resourcesNumbertheoryM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/numbertheory.m", size: 5052, mode: os.FileMode(420), modTime: time.Unix(1505695152, 0)} + info := bindataFileInfo{name: "resources/numbertheory.m", size: 5052, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -417,7 +417,7 @@ func resourcesPatternM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/pattern.m", size: 30576, mode: os.FileMode(420), modTime: time.Unix(1505695152, 0)} + info := bindataFileInfo{name: "resources/pattern.m", size: 30576, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -437,7 +437,7 @@ func resourcesPowerM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/power.m", size: 31065, mode: os.FileMode(420), modTime: time.Unix(1505708817, 0)} + info := bindataFileInfo{name: "resources/power.m", size: 31065, mode: os.FileMode(420), modTime: time.Unix(1506884378, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -457,7 +457,7 @@ func resourcesRandomM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/random.m", size: 1423, mode: os.FileMode(420), modTime: time.Unix(1501042154, 0)} + info := bindataFileInfo{name: "resources/random.m", size: 1423, mode: os.FileMode(420), modTime: time.Unix(1506023714, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -477,7 +477,7 @@ func resourcesReplacementM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/replacement.m", size: 11428, mode: os.FileMode(420), modTime: time.Unix(1501042154, 0)} + info := bindataFileInfo{name: "resources/replacement.m", size: 11428, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -497,7 +497,7 @@ func resourcesRubi111LinearBinomialProductsM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi/1.1.1 Linear binomial products.m", size: 46064, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi/1.1.1 Linear binomial products.m", size: 46064, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -517,7 +517,7 @@ func resourcesRubi113GeneralBinomialProductsM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi/1.1.3 General binomial products.m", size: 109124, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi/1.1.3 General binomial products.m", size: 109124, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -537,7 +537,7 @@ func resourcesRubi114ImproperBinomialProductsM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi/1.1.4 Improper binomial products.m", size: 27222, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi/1.1.4 Improper binomial products.m", size: 27222, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -557,7 +557,7 @@ func resourcesRubi121QuadraticTrinomialProductsM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi/1.2.1 Quadratic trinomial products.m", size: 164316, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi/1.2.1 Quadratic trinomial products.m", size: 164316, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -577,7 +577,7 @@ func resourcesRubi122QuarticTrinomialProductsM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi/1.2.2 Quartic trinomial products.m", size: 70871, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi/1.2.2 Quartic trinomial products.m", size: 70871, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -597,7 +597,7 @@ func resourcesRubi123GeneralTrinomialProductsM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi/1.2.3 General trinomial products.m", size: 113715, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi/1.2.3 General trinomial products.m", size: 113715, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -617,7 +617,7 @@ func resourcesRubi124ImproperTrinomialProductsM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi/1.2.4 Improper trinomial products.m", size: 23186, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi/1.2.4 Improper trinomial products.m", size: 23186, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -637,7 +637,7 @@ func resourcesRubi13MiscellaneousAlgebraicFunctionsM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi/1.3 Miscellaneous algebraic functions.m", size: 48838, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi/1.3 Miscellaneous algebraic functions.m", size: 48838, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -657,7 +657,7 @@ func resourcesRubi2ExponentialsM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi/2 Exponentials.m", size: 25996, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi/2 Exponentials.m", size: 25996, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -677,7 +677,7 @@ func resourcesRubi3LogarithmsM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi/3 Logarithms.m", size: 40503, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi/3 Logarithms.m", size: 40503, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -697,7 +697,7 @@ func resourcesRubi41SineM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi/4.1 Sine.m", size: 256921, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi/4.1 Sine.m", size: 256921, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -717,7 +717,7 @@ func resourcesRubi42TangentM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi/4.2 Tangent.m", size: 88026, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi/4.2 Tangent.m", size: 88026, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -737,7 +737,7 @@ func resourcesRubi43SecantM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi/4.3 Secant.m", size: 126418, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi/4.3 Secant.m", size: 126418, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -757,7 +757,7 @@ func resourcesRubi44MiscellaneousTrigFunctionsM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi/4.4 Miscellaneous trig functions.m", size: 93867, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi/4.4 Miscellaneous trig functions.m", size: 93867, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -777,7 +777,7 @@ func resourcesRubi5InverseTrigFunctionsM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi/5 Inverse trig functions.m", size: 171111, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi/5 Inverse trig functions.m", size: 171111, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -797,7 +797,7 @@ func resourcesRubi6HyperbolicFunctionsM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi/6 Hyperbolic functions.m", size: 79761, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi/6 Hyperbolic functions.m", size: 79761, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -817,7 +817,7 @@ func resourcesRubi7InverseHyperbolicFunctionsM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi/7 Inverse hyperbolic functions.m", size: 190961, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi/7 Inverse hyperbolic functions.m", size: 190961, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -837,7 +837,7 @@ func resourcesRubi8SpecialFunctionsM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi/8 Special functions.m", size: 41486, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi/8 Special functions.m", size: 41486, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -857,7 +857,7 @@ func resourcesRubi91IntegrandSimplificationRulesM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi/9.1 Integrand simplification rules.m", size: 9280, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi/9.1 Integrand simplification rules.m", size: 9280, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -877,7 +877,7 @@ func resourcesRubi92DerivativeIntegrationRulesM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi/9.2 Derivative integration rules.m", size: 7068, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi/9.2 Derivative integration rules.m", size: 7068, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -897,7 +897,7 @@ func resourcesRubi93PiecewiseLinearFunctionsM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi/9.3 Piecewise linear functions.m", size: 6540, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi/9.3 Piecewise linear functions.m", size: 6540, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -917,7 +917,7 @@ func resourcesRubi94MiscellaneousIntegrationRulesM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi/9.4 Miscellaneous integration rules.m", size: 20709, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi/9.4 Miscellaneous integration rules.m", size: 20709, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -937,7 +937,7 @@ func resourcesRubiIntegrationUtilityFunctionsM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi/Integration Utility Functions.m", size: 248202, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi/Integration Utility Functions.m", size: 248202, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -957,7 +957,7 @@ func resourcesRubiMakerubimxfileM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi/MakeRubiMxFile.m", size: 1841, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi/MakeRubiMxFile.m", size: 1841, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -977,7 +977,7 @@ func resourcesRubiReadme() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi/README", size: 418, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi/README", size: 418, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -997,7 +997,7 @@ func resourcesRubiRubiM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi/Rubi.m", size: 2966, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi/Rubi.m", size: 2966, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1017,7 +1017,7 @@ func resourcesRubiShowstepRoutinesM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi/ShowStep Routines.m", size: 12146, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi/ShowStep Routines.m", size: 12146, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1037,7 +1037,7 @@ func resourcesRubiM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi.m", size: 661, mode: os.FileMode(420), modTime: time.Unix(1505704879, 0)} + info := bindataFileInfo{name: "resources/rubi.m", size: 661, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1057,7 +1057,7 @@ func resourcesRubi_loaderM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/rubi_loader.m", size: 3729, mode: os.FileMode(420), modTime: time.Unix(1505705442, 0)} + info := bindataFileInfo{name: "resources/rubi_loader.m", size: 3729, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1077,7 +1077,7 @@ func resourcesSimplifyM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/simplify.m", size: 4293, mode: os.FileMode(420), modTime: time.Unix(1501042154, 0)} + info := bindataFileInfo{name: "resources/simplify.m", size: 4293, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1097,7 +1097,7 @@ func resourcesSolveM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/solve.m", size: 1474, mode: os.FileMode(420), modTime: time.Unix(1505695152, 0)} + info := bindataFileInfo{name: "resources/solve.m", size: 1474, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1117,7 +1117,7 @@ func resourcesSortM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/sort.m", size: 6981, mode: os.FileMode(420), modTime: time.Unix(1501042154, 0)} + info := bindataFileInfo{name: "resources/sort.m", size: 6981, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1137,7 +1137,7 @@ func resourcesSpecialsymsM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/specialsyms.m", size: 2161, mode: os.FileMode(420), modTime: time.Unix(1501042154, 0)} + info := bindataFileInfo{name: "resources/specialsyms.m", size: 2161, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1157,7 +1157,7 @@ func resourcesStringM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/string.m", size: 2510, mode: os.FileMode(420), modTime: time.Unix(1501639575, 0)} + info := bindataFileInfo{name: "resources/string.m", size: 2510, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1177,7 +1177,7 @@ func resourcesSystemM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/system.m", size: 12844, mode: os.FileMode(420), modTime: time.Unix(1505695152, 0)} + info := bindataFileInfo{name: "resources/system.m", size: 12844, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1197,7 +1197,7 @@ func resourcesTimeM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/time.m", size: 409, mode: os.FileMode(420), modTime: time.Unix(1501042154, 0)} + info := bindataFileInfo{name: "resources/time.m", size: 409, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1217,7 +1217,7 @@ func resourcesTrigM() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "resources/trig.m", size: 752, mode: os.FileMode(420), modTime: time.Unix(1501042154, 0)} + info := bindataFileInfo{name: "resources/trig.m", size: 752, mode: os.FileMode(420), modTime: time.Unix(1506011164, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/expreduce/resources/functional.m b/expreduce/resources/functional.m index 1e273bc..1c5a01f 100644 --- a/expreduce/resources/functional.m +++ b/expreduce/resources/functional.m @@ -51,7 +51,8 @@ ] }; -Map::usage = "`Map[f, expr]` returns a new expression with the same head as `expr`, but with `f` mapped to each of the arguments."; +Map::usage = "`Map[f, expr]` returns a new expression with the same head as `expr`, but with `f` mapped to each of the arguments. +Map[f, expr, levelspec] maps f to all subexpressions that match the level specification levelspec."; Attributes[Map] = {Protected}; Tests`Map = { ESimpleExamples[ @@ -64,7 +65,65 @@ ESameTest[Map[foo, foo, foo], Map[foo, foo, foo]], EComment["Pure functions are useful with `Map`:"], ESameTest[{4,16}, Function[x, x^2] /@ {2,4}], - ESameTest[{4,16}, Function[#^2] /@ {2,4}] + ESameTest[{4,16}, Function[#^2] /@ {2,4}], + ESameTest[ + Map[f, a[b[c, d, e], l[g[h, j], k]], {-Infinity, Infinity}], + f[a[f[b[f[c], f[d], f[e]]], f[l[f[g[f[h], f[j]]], f[k]]]]] + ], + ESameTest[ + Map[f, a[b[c, d, e], l[g[h, j], k]], Infinity], + a[f[b[f[c], f[d], f[e]]], f[l[f[g[f[h], f[j]]], f[k]]]] + ], + ESameTest[ + Map[f, a[b[c, d, e], l[g[h, j], k]], {-2, Infinity}], + a[f[b[f[c], f[d], f[e]]], l[f[g[f[h], f[j]]], f[k]]] + ], + ESameTest[ + Map[f, a[b[c, d, e], l[g[h, j], k]], {2, -2}], + a[b[c, d, e], l[f[g[h, j]], k]] + ], + ESameTest[ + Map[f, a[b[c, d, e], l[g[h, j], k]], 2], + a[f[b[f[c], f[d], f[e]]], f[l[f[g[h, j]], f[k]]]] + ], + ESameTest[ + Map[f, a[b[c, d, e], l[g[h, j], k]], -2], + a[f[b[c, d, e]], f[l[f[g[h, j]], k]]] + ] + ] +}; + +MapIndexed::usage = "`MapIndexed[f, expr]` returns a new expression with the same head as `expr`, but with `f` mapped to each of the arguments. +Additionally, MapIdnexed supplies the part specification of the subexpression as the second argument of f. +Map[f, expr, levelspec] maps f to all subexpressions that match the level specification levelspec, also supplying the part specification for +each subexpression as the second argument to f."; +Attributes[MapIndexed] = {Protected} +Tests`MapIndexed = { + ESimpleExamples[ + ESameTest[ + MapIndexed[f, a[b[c, d, e], l[g[h, j], k]], {-Infinity, Infinity}], + f[a[f[b[f[c, {1, 1}], f[d, {1, 2}], f[e, {1, 3}]], {1}], f[l[f[g[f[h, {2, 1, 1}], f[j, {2, 1, 2}]], {2, 1}], f[k, {2, 2}]], {2}]], {}] + ], + ESameTest[ + MapIndexed[f, a[b[c, d, e], l[g[h, j], k]], Infinity], + a[f[b[f[c, {1, 1}], f[d, {1, 2}], f[e, {1, 3}]], {1}], f[l[f[g[f[h, {2, 1, 1}], f[j, {2, 1, 2}]], {2, 1}], f[k, {2, 2}]], {2}]] + ], + ESameTest[ + MapIndexed[f, a[b[c, d, e], l[g[h, j], k]], {-2, Infinity}], + a[f[b[f[c, {1, 1}], f[d, {1, 2}], f[e, {1, 3}]], {1}], l[f[g[f[h, {2, 1, 1}], f[j, {2, 1, 2}]], {2, 1}], f[k, {2, 2}]]] + ], + ESameTest[ + MapIndexed[f, a[b[c, d, e], l[g[h, j], k]], {2, -2}], + a[b[c, d, e], l[f[g[h, j], {2, 1}], k]] + ], + ESameTest[ + MapIndexed[f, a[b[c, d, e], l[g[h, j], k]], 2], + a[f[b[f[c, {1, 1}], f[d, {1, 2}], f[e, {1, 3}]], {1}], f[l[f[g[h, j], {2, 1}], f[k, {2, 2}]], {2}]] + ], + ESameTest[ + MapIndexed[f, a[b[c, d, e], l[g[h, j], k]], -2], + a[f[b[c, d, e], {1}], f[l[f[g[h, j], {2, 1}], k], {2}]] + ] ] }; From bf685cd58ed2c7579d76f4af8d01d12d44b61767 Mon Sep 17 00:00:00 2001 From: Calle Ekdahl Date: Mon, 2 Oct 2017 00:07:55 +0200 Subject: [PATCH 2/3] Fix build error --- expreduce/builtin_functional.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/expreduce/builtin_functional.go b/expreduce/builtin_functional.go index a5edcc8..edaa9f0 100644 --- a/expreduce/builtin_functional.go +++ b/expreduce/builtin_functional.go @@ -39,7 +39,7 @@ func parseSymbol(part Ex) (symbol *Symbol, isSymbol bool) { func parseInfinity(part Ex, es *EvalState) bool { symbol, isSymbol := parseSymbol(part) if isSymbol { - return symbol.IsEqual(&Symbol{"System`Infinity"}, &es.CASLogger) == "EQUAL_TRUE" + return symbol.IsEqual(&Symbol{Name:"System`Infinity"}, &es.CASLogger) == "EQUAL_TRUE" } return false } @@ -48,9 +48,9 @@ func parseNegativeInfinity(part Ex, es *EvalState) bool { expr, isExpr := parseExpression(part) if isExpr { template := NewExpression([]Ex{ - &Symbol{"System`Times"}, - &Integer{big.NewInt(-1)}, - &Symbol{"System`Infinity"}, + &Symbol{Name:"System`Times"}, + &Integer{Val:big.NewInt(-1)}, + &Symbol{Name:"System`Infinity"}, }) return expr.IsEqual(template, &es.CASLogger) == "EQUAL_TRUE" } @@ -135,7 +135,7 @@ func parseLevelSpec(this Ex, es *EvalState) levelSpec{ } //If the head of the expression is not List, return false - expression, isList := headExAssertion(expression, &Symbol{"System`List"}, &es.CASLogger) + expression, isList := headExAssertion(expression, &Symbol{Name:"System`List"}, &es.CASLogger) if !isList { return levelSpec{false, false, 1, 1, false} } @@ -285,7 +285,7 @@ func wrapWithHead(head Ex, expr Ex, partList []int64) *Expression { } func wrapWithHeadIndexed(head Ex, expr Ex, partList []int64) *Expression { - partSpec := []Ex{&Symbol{"System`List"}} + partSpec := []Ex{&Symbol{Name:"System`List"}} for _, part := range partList { partSpec = append(partSpec, NewInt(part)) } From 4b8fcd6ef87e26e0033dab56acb42df260113ba6 Mon Sep 17 00:00:00 2001 From: Calle Ekdahl Date: Mon, 2 Oct 2017 00:33:26 +0200 Subject: [PATCH 3/3] Use Ex constructors --- expreduce/builtin_functional.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/expreduce/builtin_functional.go b/expreduce/builtin_functional.go index edaa9f0..998e27a 100644 --- a/expreduce/builtin_functional.go +++ b/expreduce/builtin_functional.go @@ -39,7 +39,7 @@ func parseSymbol(part Ex) (symbol *Symbol, isSymbol bool) { func parseInfinity(part Ex, es *EvalState) bool { symbol, isSymbol := parseSymbol(part) if isSymbol { - return symbol.IsEqual(&Symbol{Name:"System`Infinity"}, &es.CASLogger) == "EQUAL_TRUE" + return symbol.IsEqual(NewSymbol("System`Infinity"), &es.CASLogger) == "EQUAL_TRUE" } return false } @@ -48,9 +48,9 @@ func parseNegativeInfinity(part Ex, es *EvalState) bool { expr, isExpr := parseExpression(part) if isExpr { template := NewExpression([]Ex{ - &Symbol{Name:"System`Times"}, - &Integer{Val:big.NewInt(-1)}, - &Symbol{Name:"System`Infinity"}, + NewSymbol("System`Times"), + NewInt(-1), + NewSymbol("System`Infinity"), }) return expr.IsEqual(template, &es.CASLogger) == "EQUAL_TRUE" } @@ -135,7 +135,7 @@ func parseLevelSpec(this Ex, es *EvalState) levelSpec{ } //If the head of the expression is not List, return false - expression, isList := headExAssertion(expression, &Symbol{Name:"System`List"}, &es.CASLogger) + expression, isList := headExAssertion(expression, NewSymbol("System`List"), &es.CASLogger) if !isList { return levelSpec{false, false, 1, 1, false} } @@ -285,7 +285,7 @@ func wrapWithHead(head Ex, expr Ex, partList []int64) *Expression { } func wrapWithHeadIndexed(head Ex, expr Ex, partList []int64) *Expression { - partSpec := []Ex{&Symbol{Name:"System`List"}} + partSpec := []Ex{NewSymbol("System`List")} for _, part := range partList { partSpec = append(partSpec, NewInt(part)) }