@@ -7,7 +7,7 @@ package space.kscience.kmath.expressions
77
88import space.kscience.kmath.operations.Algebra
99import space.kscience.kmath.operations.NumericAlgebra
10- import space.kscience.kmath.operations.bindSymbol
10+ import space.kscience.kmath.operations.bindSymbolOrNull
1111
1212/* *
1313 * A Mathematical Syntax Tree (MST) node for mathematical expressions.
@@ -43,80 +43,69 @@ public sealed interface MST {
4343
4444// TODO add a function with named arguments
4545
46+
4647/* *
47- * Interprets the [MST] node with this [Algebra].
48- *
49- * @receiver the algebra that provides operations.
50- * @param node the node to evaluate.
51- * @return the value of expression.
52- * @author Alexander Nozik
48+ * Interprets the [MST] node with this [Algebra] and optional [arguments]
5349 */
54- public fun <T > Algebra<T>. evaluate ( node : MST ): T = when (node ) {
55- is MST .Numeric -> (this as ? NumericAlgebra <T >)?.number(node. value)
56- ? : error(" Numeric nodes are not supported by $this " )
50+ public fun <T > MST. interpret ( algebra : Algebra <T >, arguments : Map < Symbol , T > ): T = when (this ) {
51+ is MST .Numeric -> (algebra as NumericAlgebra <T >? )?.number(value)
52+ ? : error(" Numeric nodes are not supported by $algebra " )
5753
58- is Symbol -> bindSymbol(node )
54+ is Symbol -> algebra.bindSymbolOrNull( this ) ? : arguments.getValue( this )
5955
6056 is MST .Unary -> when {
61- this is NumericAlgebra && node.value is MST .Numeric -> unaryOperationFunction(node.operation)(number(node.value.value))
62- else -> unaryOperationFunction(node.operation)(evaluate(node.value))
57+ algebra is NumericAlgebra && this .value is MST .Numeric -> algebra.unaryOperation(
58+ this .operation,
59+ algebra.number(this .value.value),
60+ )
61+ else -> algebra.unaryOperationFunction(this .operation)(this .value.interpret(algebra, arguments))
6362 }
6463
6564 is MST .Binary -> when {
66- this is NumericAlgebra && node.left is MST .Numeric && node.right is MST .Numeric ->
67- binaryOperationFunction(node.operation)(number(node.left.value), number(node.right.value))
68-
69- this is NumericAlgebra && node.left is MST .Numeric ->
70- leftSideNumberOperationFunction(node.operation)(node.left.value, evaluate(node.right))
71-
72- this is NumericAlgebra && node.right is MST .Numeric ->
73- rightSideNumberOperationFunction(node.operation)(evaluate(node.left), node.right.value)
74-
75- else -> binaryOperationFunction(node.operation)(evaluate(node.left), evaluate(node.right))
65+ algebra is NumericAlgebra && this .left is MST .Numeric && this .right is MST .Numeric -> algebra.binaryOperation(
66+ this .operation,
67+ algebra.number(this .left.value),
68+ algebra.number(this .right.value),
69+ )
70+
71+ algebra is NumericAlgebra && this .left is MST .Numeric -> algebra.leftSideNumberOperation(
72+ this .operation,
73+ this .left.value,
74+ this .right.interpret(algebra, arguments),
75+ )
76+
77+ algebra is NumericAlgebra && this .right is MST .Numeric -> algebra.rightSideNumberOperation(
78+ this .operation,
79+ left.interpret(algebra, arguments),
80+ right.value,
81+ )
82+
83+ else -> algebra.binaryOperation(
84+ this .operation,
85+ this .left.interpret(algebra, arguments),
86+ this .right.interpret(algebra, arguments),
87+ )
7688 }
7789}
7890
79- internal class InnerAlgebra <T >(val algebra : Algebra <T >, val arguments : Map <Symbol , T >) : NumericAlgebra<T> {
80- override fun bindSymbolOrNull (value : String ): T ? = algebra.bindSymbolOrNull(value) ? : arguments[StringSymbol (value)]
81-
82- override fun unaryOperation (operation : String , arg : T ): T =
83- algebra.unaryOperation(operation, arg)
84-
85- override fun binaryOperation (operation : String , left : T , right : T ): T =
86- algebra.binaryOperation(operation, left, right)
87-
88- override fun unaryOperationFunction (operation : String ): (arg: T ) -> T =
89- algebra.unaryOperationFunction(operation)
90-
91- override fun binaryOperationFunction (operation : String ): (left: T , right: T ) -> T =
92- algebra.binaryOperationFunction(operation)
93-
94- @Suppress(" UNCHECKED_CAST" )
95- override fun number (value : Number ): T = if (algebra is NumericAlgebra <* >)
96- (algebra as NumericAlgebra <T >).number(value)
97- else
98- error(" Numeric nodes are not supported by $this " )
99- }
100-
101- /* *
102- * Interprets the [MST] node with this [Algebra] and optional [arguments]
103- */
104- public fun <T > MST.interpret (algebra : Algebra <T >, arguments : Map <Symbol , T >): T =
105- InnerAlgebra (algebra, arguments).evaluate(this )
106-
10791/* *
10892 * Interprets the [MST] node with this [Algebra] and optional [arguments]
10993 *
11094 * @receiver the node to evaluate.
11195 * @param algebra the algebra that provides operations.
11296 * @return the value of expression.
11397 */
114- public fun <T > MST.interpret (algebra : Algebra <T >, vararg arguments : Pair <Symbol , T >): T =
115- interpret(algebra, mapOf (* arguments))
98+ public fun <T > MST.interpret (algebra : Algebra <T >, vararg arguments : Pair <Symbol , T >): T = interpret(
99+ algebra,
100+ when (arguments.size) {
101+ 0 -> emptyMap()
102+ 1 -> mapOf (arguments[0 ])
103+ else -> hashMapOf(* arguments)
104+ },
105+ )
116106
117107/* *
118108 * Interpret this [MST] as expression.
119109 */
120- public fun <T : Any > MST.toExpression (algebra : Algebra <T >): Expression <T > = Expression { arguments ->
121- interpret(algebra, arguments)
122- }
110+ public fun <T : Any > MST.toExpression (algebra : Algebra <T >): Expression <T > =
111+ Expression { arguments -> interpret(algebra, arguments) }
0 commit comments