Dev #127
@ -25,12 +25,3 @@ interface ExpressionContext<T, E> : Algebra<E> {
|
||||
*/
|
||||
fun const(value: T): E
|
||||
}
|
||||
|
||||
fun <T, E> ExpressionContext<T, E>.produce(node: SyntaxTreeNode): E {
|
||||
return when (node) {
|
||||
is NumberNode -> error("Single number nodes are not supported")
|
||||
is SingularNode -> variable(node.value)
|
||||
is UnaryNode -> unaryOperation(node.operation, produce(node.value))
|
||||
is BinaryNode -> binaryOperation(node.operation, produce(node.left), produce(node.right))
|
||||
}
|
||||
}
|
@ -1,11 +1,25 @@
|
||||
package scientifik.kmath.expressions
|
||||
|
||||
import scientifik.kmath.operations.NumericAlgebra
|
||||
|
||||
/**
|
||||
* A syntax tree node for mathematical expressions
|
||||
*/
|
||||
sealed class SyntaxTreeNode
|
||||
|
||||
/**
|
||||
* A node containing unparsed string
|
||||
*/
|
||||
data class SingularNode(val value: String) : SyntaxTreeNode()
|
||||
|
||||
/**
|
||||
* A node containing a number
|
||||
*/
|
||||
data class NumberNode(val value: Number) : SyntaxTreeNode()
|
||||
|
||||
/**
|
||||
* A node containing an unary operation
|
||||
*/
|
||||
data class UnaryNode(val operation: String, val value: SyntaxTreeNode) : SyntaxTreeNode() {
|
||||
companion object {
|
||||
const val ABS_OPERATION = "abs"
|
||||
@ -17,12 +31,22 @@ data class UnaryNode(val operation: String, val value: SyntaxTreeNode) : SyntaxT
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A node containing binary operation
|
||||
*/
|
||||
data class BinaryNode(val operation: String, val left: SyntaxTreeNode, val right: SyntaxTreeNode) : SyntaxTreeNode() {
|
||||
companion object {
|
||||
//TODO add operations
|
||||
}
|
||||
companion object
|
||||
}
|
||||
|
||||
//TODO add a function with positional arguments
|
||||
|
||||
//TODO add a function with named arguments
|
||||
|
||||
fun <T> NumericAlgebra<T>.compile(node: SyntaxTreeNode): T{
|
||||
return when (node) {
|
||||
is NumberNode -> number(node.value)
|
||||
is SingularNode -> raw(node.value)
|
||||
is UnaryNode -> unaryOperation(node.operation, compile(node.value))
|
||||
is BinaryNode -> binaryOperation(node.operation, compile(node.left), compile(node.right))
|
||||
}
|
||||
}
|
@ -7,10 +7,35 @@ annotation class KMathContext
|
||||
* Marker interface for any algebra
|
||||
*/
|
||||
interface Algebra<T> {
|
||||
/**
|
||||
* Wrap raw string or variable
|
||||
*/
|
||||
fun raw(value: String): T = error("Wrapping of '$value' is not supported in $this")
|
||||
|
||||
/**
|
||||
* Dynamic call of unary operation with name [operation] on [arg]
|
||||
*/
|
||||
fun unaryOperation(operation: String, arg: T): T
|
||||
|
||||
/**
|
||||
* Dynamic call of binary operation [operation] on [left] and [right]
|
||||
*/
|
||||
fun binaryOperation(operation: String, left: T, right: T): T
|
||||
}
|
||||
|
||||
/**
|
||||
* An algebra with numeric representation of members
|
||||
*/
|
||||
interface NumericAlgebra<T> : Algebra<T> {
|
||||
/**
|
||||
* Wrap a number
|
||||
*/
|
||||
fun number(value: Number): T
|
||||
}
|
||||
|
||||
/**
|
||||
* Call a block with an [Algebra] as receiver
|
||||
*/
|
||||
inline operator fun <A : Algebra<*>, R> A.invoke(block: A.() -> R): R = run(block)
|
||||
|
||||
/**
|
||||
@ -87,7 +112,7 @@ interface RingOperations<T> : SpaceOperations<T> {
|
||||
else -> super.binaryOperation(operation, left, right)
|
||||
}
|
||||
|
||||
companion object{
|
||||
companion object {
|
||||
const val TIMES_OPERATION = "*"
|
||||
}
|
||||
}
|
||||
@ -95,13 +120,16 @@ interface RingOperations<T> : SpaceOperations<T> {
|
||||
/**
|
||||
* The same as {@link Space} but with additional multiplication operation
|
||||
*/
|
||||
interface Ring<T> : Space<T>, RingOperations<T> {
|
||||
interface Ring<T> : Space<T>, RingOperations<T>, NumericAlgebra<T> {
|
||||
/**
|
||||
* neutral operation for multiplication
|
||||
*/
|
||||
val one: T
|
||||
|
||||
// operator fun T.plus(b: Number) = this.plus(b * one)
|
||||
override fun number(value: Number): T = one * value.toDouble()
|
||||
|
||||
// those operators are blocked by type conflict in RealField
|
||||
// operator fun T.plus(b: Number) = this.plus(b * one)
|
||||
// operator fun Number.plus(b: T) = b + this
|
||||
//
|
||||
// operator fun T.minus(b: Number) = this.minus(b * one)
|
||||
@ -121,7 +149,7 @@ interface FieldOperations<T> : RingOperations<T> {
|
||||
else -> super.binaryOperation(operation, left, right)
|
||||
}
|
||||
|
||||
companion object{
|
||||
companion object {
|
||||
const val DIV_OPERATION = "/"
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user