Document AST and expressions API, implement ExtendedField over MST and Expression<T>

This commit is contained in:
Iaroslav 2020-08-08 04:57:20 +07:00
parent c8cd6cd288
commit cb5234a334
No known key found for this signature in database
GPG Key ID: 46E15E4A31B3BCD7
8 changed files with 202 additions and 58 deletions

View File

@ -5,42 +5,54 @@ import scientifik.kmath.operations.NumericAlgebra
import scientifik.kmath.operations.RealField import scientifik.kmath.operations.RealField
/** /**
* A Mathematical Syntax Tree node for mathematical expressions * A Mathematical Syntax Tree node for mathematical expressions.
*/ */
sealed class MST { sealed class MST {
/** /**
* A node containing unparsed string * A node containing raw string.
*
* @property value the value of this node.
*/ */
data class Symbolic(val value: String) : MST() data class Symbolic(val value: String) : MST()
/** /**
* A node containing a number * A node containing a numeric value or scalar.
*
* @property value the value of this number.
*/ */
data class Numeric(val value: Number) : MST() data class Numeric(val value: Number) : MST()
/** /**
* A node containing an unary operation * A node containing an unary operation.
*
* @property operation the identifier of operation.
* @property value the argument of this operation.
*/ */
data class Unary(val operation: String, val value: MST) : MST() { data class Unary(val operation: String, val value: MST) : MST() {
companion object { companion object
const val ABS_OPERATION = "abs"
//TODO add operations
}
} }
/** /**
* A node containing binary operation * A node containing binary operation.
*
* @property operation the identifier operation.
* @property left the left operand.
* @property right the right operand.
*/ */
data class Binary(val operation: String, val left: MST, val right: MST) : MST() { data class Binary(val operation: String, val left: MST, val right: MST) : MST() {
companion object companion object
} }
} }
//TODO add a function with positional arguments // TODO add a function with named arguments
//TODO add a function with named arguments
/**
* Interprets the [MST] node with this [Algebra].
*
* @receiver the algebra that provides operations.
* @param node the node to evaluate.
* @return the value of expression.
*/
fun <T> Algebra<T>.evaluate(node: MST): T = when (node) { fun <T> Algebra<T>.evaluate(node: MST): T = when (node) {
is MST.Numeric -> (this as? NumericAlgebra<T>)?.number(node.value) is MST.Numeric -> (this as? NumericAlgebra<T>)?.number(node.value)
?: error("Numeric nodes are not supported by $this") ?: error("Numeric nodes are not supported by $this")
@ -65,4 +77,11 @@ fun <T> Algebra<T>.evaluate(node: MST): T = when (node) {
} }
} }
fun <T> MST.compile(algebra: Algebra<T>): T = algebra.evaluate(this) /**
* Interprets the [MST] node with this [Algebra].
*
* @receiver the node to evaluate.
* @param algebra the algebra that provides operations.
* @return the value of expression.
*/
fun <T> MST.interpret(algebra: Algebra<T>): T = algebra.evaluate(this)

View File

@ -2,6 +2,9 @@ package scientifik.kmath.ast
import scientifik.kmath.operations.* import scientifik.kmath.operations.*
/**
* [Algebra] over [MST] nodes.
*/
object MstAlgebra : NumericAlgebra<MST> { object MstAlgebra : NumericAlgebra<MST> {
override fun number(value: Number): MST = MST.Numeric(value) override fun number(value: Number): MST = MST.Numeric(value)
@ -14,17 +17,16 @@ object MstAlgebra : NumericAlgebra<MST> {
MST.Binary(operation, left, right) MST.Binary(operation, left, right)
} }
/**
* [Space] over [MST] nodes.
*/
object MstSpace : Space<MST>, NumericAlgebra<MST> { object MstSpace : Space<MST>, NumericAlgebra<MST> {
override val zero: MST = number(0.0) override val zero: MST = number(0.0)
override fun number(value: Number): MST = MstAlgebra.number(value) override fun number(value: Number): MST = MstAlgebra.number(value)
override fun symbol(value: String): MST = MstAlgebra.symbol(value) override fun symbol(value: String): MST = MstAlgebra.symbol(value)
override fun add(a: MST, b: MST): MST = binaryOperation(SpaceOperations.PLUS_OPERATION, a, b)
override fun add(a: MST, b: MST): MST = override fun multiply(a: MST, k: Number): MST = binaryOperation(RingOperations.TIMES_OPERATION, a, number(k))
binaryOperation(SpaceOperations.PLUS_OPERATION, a, b)
override fun multiply(a: MST, k: Number): MST =
binaryOperation(RingOperations.TIMES_OPERATION, a, number(k))
override fun binaryOperation(operation: String, left: MST, right: MST): MST = override fun binaryOperation(operation: String, left: MST, right: MST): MST =
MstAlgebra.binaryOperation(operation, left, right) MstAlgebra.binaryOperation(operation, left, right)
@ -32,41 +34,69 @@ object MstSpace : Space<MST>, NumericAlgebra<MST> {
override fun unaryOperation(operation: String, arg: MST): MST = MstAlgebra.unaryOperation(operation, arg) override fun unaryOperation(operation: String, arg: MST): MST = MstAlgebra.unaryOperation(operation, arg)
} }
/**
* [Ring] over [MST] nodes.
*/
object MstRing : Ring<MST>, NumericAlgebra<MST> { object MstRing : Ring<MST>, NumericAlgebra<MST> {
override val zero: MST = number(0.0) override val zero: MST = number(0.0)
override val one: MST = number(1.0) override val one: MST = number(1.0)
override fun number(value: Number): MST = MstAlgebra.number(value) override fun number(value: Number): MST = MstSpace.number(value)
override fun symbol(value: String): MST = MstAlgebra.symbol(value) override fun symbol(value: String): MST = MstSpace.symbol(value)
override fun add(a: MST, b: MST): MST = binaryOperation(SpaceOperations.PLUS_OPERATION, a, b) override fun add(a: MST, b: MST): MST = MstSpace.add(a, b)
override fun multiply(a: MST, k: Number): MST = override fun multiply(a: MST, k: Number): MST = MstSpace.multiply(a, k)
binaryOperation(RingOperations.TIMES_OPERATION, a, MstSpace.number(k))
override fun multiply(a: MST, b: MST): MST = binaryOperation(RingOperations.TIMES_OPERATION, a, b) override fun multiply(a: MST, b: MST): MST = binaryOperation(RingOperations.TIMES_OPERATION, a, b)
override fun binaryOperation(operation: String, left: MST, right: MST): MST = override fun binaryOperation(operation: String, left: MST, right: MST): MST =
MstAlgebra.binaryOperation(operation, left, right) MstSpace.binaryOperation(operation, left, right)
override fun unaryOperation(operation: String, arg: MST): MST = MstAlgebra.unaryOperation(operation, arg) override fun unaryOperation(operation: String, arg: MST): MST = MstAlgebra.unaryOperation(operation, arg)
} }
/**
* [Field] over [MST] nodes.
*/
object MstField : Field<MST> { object MstField : Field<MST> {
override val zero: MST = number(0.0) override val zero: MST = number(0.0)
override val one: MST = number(1.0) override val one: MST = number(1.0)
override fun symbol(value: String): MST = MstAlgebra.symbol(value) override fun symbol(value: String): MST = MstRing.symbol(value)
override fun number(value: Number): MST = MstAlgebra.number(value) override fun number(value: Number): MST = MstRing.number(value)
override fun add(a: MST, b: MST): MST = binaryOperation(SpaceOperations.PLUS_OPERATION, a, b) override fun add(a: MST, b: MST): MST = MstRing.add(a, b)
override fun multiply(a: MST, k: Number): MST = MstRing.multiply(a, k)
override fun multiply(a: MST, k: Number): MST = override fun multiply(a: MST, b: MST): MST = MstRing.multiply(a, b)
binaryOperation(RingOperations.TIMES_OPERATION, a, MstSpace.number(k))
override fun multiply(a: MST, b: MST): MST = binaryOperation(RingOperations.TIMES_OPERATION, a, b)
override fun divide(a: MST, b: MST): MST = binaryOperation(FieldOperations.DIV_OPERATION, a, b) override fun divide(a: MST, b: MST): MST = binaryOperation(FieldOperations.DIV_OPERATION, a, b)
override fun binaryOperation(operation: String, left: MST, right: MST): MST = override fun binaryOperation(operation: String, left: MST, right: MST): MST =
MstAlgebra.binaryOperation(operation, left, right) MstRing.binaryOperation(operation, left, right)
override fun unaryOperation(operation: String, arg: MST): MST = MstAlgebra.unaryOperation(operation, arg) override fun unaryOperation(operation: String, arg: MST): MST = MstRing.unaryOperation(operation, arg)
}
/**
* [ExtendedField] over [MST] nodes.
*/
object MstExtendedField : ExtendedField<MST> {
override val zero: MST = number(0.0)
override val one: MST = number(1.0)
override fun sin(arg: MST): MST = unaryOperation(TrigonometricOperations.SIN_OPERATION, arg)
override fun cos(arg: MST): MST = unaryOperation(TrigonometricOperations.COS_OPERATION, arg)
override fun asin(arg: MST): MST = unaryOperation(InverseTrigonometricOperations.ASIN_OPERATION, arg)
override fun acos(arg: MST): MST = unaryOperation(InverseTrigonometricOperations.ACOS_OPERATION, arg)
override fun atan(arg: MST): MST = unaryOperation(InverseTrigonometricOperations.ATAN_OPERATION, arg)
override fun add(a: MST, b: MST): MST = MstField.add(a, b)
override fun multiply(a: MST, k: Number): MST = MstField.multiply(a, k)
override fun multiply(a: MST, b: MST): MST = MstField.multiply(a, b)
override fun divide(a: MST, b: MST): MST = MstField.divide(a, b)
override fun power(arg: MST, pow: Number): MST = binaryOperation(PowerOperations.POW_OPERATION, arg, number(pow))
override fun exp(arg: MST): MST = unaryOperation(ExponentialOperations.EXP_OPERATION, arg)
override fun ln(arg: MST): MST = unaryOperation(ExponentialOperations.LN_OPERATION, arg)
override fun binaryOperation(operation: String, left: MST, right: MST): MST =
MstField.binaryOperation(operation, left, right)
override fun unaryOperation(operation: String, arg: MST): MST = MstField.unaryOperation(operation, arg)
} }

View File

@ -1,19 +1,16 @@
package scientifik.kmath.ast package scientifik.kmath.ast
import scientifik.kmath.expressions.Expression import scientifik.kmath.expressions.*
import scientifik.kmath.expressions.FunctionalExpressionField
import scientifik.kmath.expressions.FunctionalExpressionRing
import scientifik.kmath.expressions.FunctionalExpressionSpace
import scientifik.kmath.operations.* import scientifik.kmath.operations.*
/** /**
* The expression evaluates MST on-flight. Should be much faster than functional expression, but slower than ASM-generated expressions. * The expression evaluates MST on-flight. Should be much faster than functional expression, but slower than
* ASM-generated expressions.
*
* @property algebra the algebra that provides operations.
* @property mst the [MST] node.
*/ */
class MstExpression<T>(val algebra: Algebra<T>, val mst: MST) : Expression<T> { class MstExpression<T>(val algebra: Algebra<T>, val mst: MST) : Expression<T> {
/**
* Substitute algebra raw value
*/
private inner class InnerAlgebra(val arguments: Map<String, T>) : NumericAlgebra<T> { private inner class InnerAlgebra(val arguments: Map<String, T>) : NumericAlgebra<T> {
override fun symbol(value: String): T = arguments[value] ?: algebra.symbol(value) override fun symbol(value: String): T = arguments[value] ?: algebra.symbol(value)
override fun unaryOperation(operation: String, arg: T): T = algebra.unaryOperation(operation, arg) override fun unaryOperation(operation: String, arg: T): T = algebra.unaryOperation(operation, arg)
@ -30,26 +27,62 @@ class MstExpression<T>(val algebra: Algebra<T>, val mst: MST) : Expression<T> {
override fun invoke(arguments: Map<String, T>): T = InnerAlgebra(arguments).evaluate(mst) override fun invoke(arguments: Map<String, T>): T = InnerAlgebra(arguments).evaluate(mst)
} }
/**
* Builds [MstExpression] over [Algebra].
*/
inline fun <reified T : Any, A : Algebra<T>, E : Algebra<MST>> A.mst( inline fun <reified T : Any, A : Algebra<T>, E : Algebra<MST>> A.mst(
mstAlgebra: E, mstAlgebra: E,
block: E.() -> MST block: E.() -> MST
): MstExpression<T> = MstExpression(this, mstAlgebra.block()) ): MstExpression<T> = MstExpression(this, mstAlgebra.block())
/**
* Builds [MstExpression] over [Space].
*/
inline fun <reified T : Any> Space<T>.mstInSpace(block: MstSpace.() -> MST): MstExpression<T> = inline fun <reified T : Any> Space<T>.mstInSpace(block: MstSpace.() -> MST): MstExpression<T> =
MstExpression(this, MstSpace.block()) MstExpression(this, MstSpace.block())
/**
* Builds [MstExpression] over [Ring].
*/
inline fun <reified T : Any> Ring<T>.mstInRing(block: MstRing.() -> MST): MstExpression<T> = inline fun <reified T : Any> Ring<T>.mstInRing(block: MstRing.() -> MST): MstExpression<T> =
MstExpression(this, MstRing.block()) MstExpression(this, MstRing.block())
/**
* Builds [MstExpression] over [Field].
*/
inline fun <reified T : Any> Field<T>.mstInField(block: MstField.() -> MST): MstExpression<T> = inline fun <reified T : Any> Field<T>.mstInField(block: MstField.() -> MST): MstExpression<T> =
MstExpression(this, MstField.block()) MstExpression(this, MstField.block())
inline fun <reified T : Any, A : Space<T>> FunctionalExpressionSpace<T, A>.mstInSpace(block: MstSpace.() -> MST): MstExpression<T> = /**
algebra.mstInSpace(block) * Builds [MstExpression] over [ExtendedField].
*/
inline fun <reified T : Any> Field<T>.mstInExtendedField(block: MstExtendedField.() -> MST): MstExpression<T> =
MstExpression(this, MstExtendedField.block())
inline fun <reified T : Any, A : Ring<T>> FunctionalExpressionRing<T, A>.mstInRing(block: MstRing.() -> MST): MstExpression<T> = /**
algebra.mstInRing(block) * Builds [MstExpression] over [FunctionalExpressionSpace].
*/
inline fun <reified T : Any, A : Space<T>> FunctionalExpressionSpace<T, A>.mstInSpace(
block: MstSpace.() -> MST
): MstExpression<T> = algebra.mstInSpace(block)
inline fun <reified T : Any, A : Field<T>> FunctionalExpressionField<T, A>.mstInField(block: MstField.() -> MST): MstExpression<T> = /**
algebra.mstInField(block) * Builds [MstExpression] over [FunctionalExpressionRing].
*/
inline fun <reified T : Any, A : Ring<T>> FunctionalExpressionRing<T, A>.mstInRing(
block: MstRing.() -> MST
): MstExpression<T> = algebra.mstInRing(block)
/**
* Builds [MstExpression] over [FunctionalExpressionField].
*/
inline fun <reified T : Any, A : Field<T>> FunctionalExpressionField<T, A>.mstInField(
block: MstField.() -> MST
): MstExpression<T> = algebra.mstInField(block)
/**
* Builds [MstExpression] over [FunctionalExpressionExtendedField].
*/
inline fun <reified T : Any, A : ExtendedField<T>> FunctionalExpressionExtendedField<T, A>.mstInExtendedField(
block: MstExtendedField.() -> MST
): MstExpression<T> = algebra.mstInExtendedField(block)

View File

@ -80,5 +80,18 @@ object ArithmeticsEvaluator : Grammar<MST>() {
override val rootParser: Parser<MST> by subSumChain override val rootParser: Parser<MST> by subSumChain
} }
/**
* Tries to parse the string into [MST].
*
* @receiver the string to parse.
* @return the [MST] node.
*/
fun String.tryParseMath(): ParseResult<MST> = ArithmeticsEvaluator.tryParseToEnd(this) fun String.tryParseMath(): ParseResult<MST> = ArithmeticsEvaluator.tryParseToEnd(this)
/**
* Parses the string into [MST].
*
* @receiver the string to parse.
* @return the [MST] node.
*/
fun String.parseMath(): MST = ArithmeticsEvaluator.parseToEnd(this) fun String.parseMath(): MST = ArithmeticsEvaluator.parseToEnd(this)

View File

@ -1,5 +1,6 @@
package scientifik.kmath.expressions package scientifik.kmath.expressions
import scientifik.kmath.operations.ExtendedField
import scientifik.kmath.operations.Field import scientifik.kmath.operations.Field
import scientifik.kmath.operations.Ring import scientifik.kmath.operations.Ring
import scientifik.kmath.operations.Space import scientifik.kmath.operations.Space
@ -21,3 +22,10 @@ fun <T> Ring<T>.ringExpression(block: FunctionalExpressionRing<T, Ring<T>>.() ->
*/ */
fun <T> Field<T>.fieldExpression(block: FunctionalExpressionField<T, Field<T>>.() -> Expression<T>): Expression<T> = fun <T> Field<T>.fieldExpression(block: FunctionalExpressionField<T, Field<T>>.() -> Expression<T>): Expression<T> =
FunctionalExpressionField(this).run(block) FunctionalExpressionField(this).run(block)
/**
* Creates a functional expression with this [ExtendedField].
*/
fun <T> ExtendedField<T>.fieldExpression(
block: FunctionalExpressionExtendedField<T, ExtendedField<T>>.() -> Expression<T>
): Expression<T> = FunctionalExpressionExtendedField(this).run(block)

View File

@ -6,6 +6,12 @@ import scientifik.kmath.operations.Algebra
* An elementary function that could be invoked on a map of arguments * An elementary function that could be invoked on a map of arguments
*/ */
interface Expression<T> { interface Expression<T> {
/**
* Calls this expression from arguments.
*
* @param arguments the map of arguments.
* @return the value.
*/
operator fun invoke(arguments: Map<String, T>): T operator fun invoke(arguments: Map<String, T>): T
companion object companion object
@ -19,6 +25,12 @@ fun <T> Algebra<T>.expression(block: Algebra<T>.(arguments: Map<String, T>) -> T
override fun invoke(arguments: Map<String, T>): T = block(arguments) override fun invoke(arguments: Map<String, T>): T = block(arguments)
} }
/**
* Calls this expression from arguments.
*
* @param pairs the pair of arguments' names to values.
* @return the value.
*/
operator fun <T> Expression<T>.invoke(vararg pairs: Pair<String, T>): T = invoke(mapOf(*pairs)) operator fun <T> Expression<T>.invoke(vararg pairs: Pair<String, T>): T = invoke(mapOf(*pairs))
/** /**

View File

@ -40,7 +40,6 @@ internal class FunctionalConstProductExpression<T>(
* @param algebra The algebra to provide for Expressions built. * @param algebra The algebra to provide for Expressions built.
*/ */
abstract class FunctionalExpressionAlgebra<T, A : Algebra<T>>(val algebra: A) : ExpressionAlgebra<T, Expression<T>> { abstract class FunctionalExpressionAlgebra<T, A : Algebra<T>>(val algebra: A) : ExpressionAlgebra<T, Expression<T>> {
/** /**
* Builds an Expression of constant expression which does not depend on arguments. * Builds an Expression of constant expression which does not depend on arguments.
*/ */
@ -69,14 +68,13 @@ abstract class FunctionalExpressionAlgebra<T, A : Algebra<T>>(val algebra: A) :
*/ */
open class FunctionalExpressionSpace<T, A : Space<T>>(algebra: A) : open class FunctionalExpressionSpace<T, A : Space<T>>(algebra: A) :
FunctionalExpressionAlgebra<T, A>(algebra), Space<Expression<T>> { FunctionalExpressionAlgebra<T, A>(algebra), Space<Expression<T>> {
override val zero: Expression<T> get() = const(algebra.zero) override val zero: Expression<T> get() = const(algebra.zero)
/** /**
* Builds an Expression of addition of two another expressions. * Builds an Expression of addition of two another expressions.
*/ */
override fun add(a: Expression<T>, b: Expression<T>): Expression<T> = override fun add(a: Expression<T>, b: Expression<T>): Expression<T> =
FunctionalBinaryOperation(algebra, SpaceOperations.PLUS_OPERATION, a, b) binaryOperation(SpaceOperations.PLUS_OPERATION, a, b)
/** /**
* Builds an Expression of multiplication of expression by number. * Builds an Expression of multiplication of expression by number.
@ -105,7 +103,7 @@ open class FunctionalExpressionRing<T, A>(algebra: A) : FunctionalExpressionSpac
* Builds an Expression of multiplication of two expressions. * Builds an Expression of multiplication of two expressions.
*/ */
override fun multiply(a: Expression<T>, b: Expression<T>): Expression<T> = override fun multiply(a: Expression<T>, b: Expression<T>): Expression<T> =
FunctionalBinaryOperation(algebra, RingOperations.TIMES_OPERATION, a, b) binaryOperation(RingOperations.TIMES_OPERATION, a, b)
operator fun Expression<T>.times(arg: T): Expression<T> = this * const(arg) operator fun Expression<T>.times(arg: T): Expression<T> = this * const(arg)
operator fun T.times(arg: Expression<T>): Expression<T> = arg * this operator fun T.times(arg: Expression<T>): Expression<T> = arg * this
@ -124,7 +122,7 @@ open class FunctionalExpressionField<T, A>(algebra: A) :
* Builds an Expression of division an expression by another one. * Builds an Expression of division an expression by another one.
*/ */
override fun divide(a: Expression<T>, b: Expression<T>): Expression<T> = override fun divide(a: Expression<T>, b: Expression<T>): Expression<T> =
FunctionalBinaryOperation(algebra, FieldOperations.DIV_OPERATION, a, b) binaryOperation(FieldOperations.DIV_OPERATION, a, b)
operator fun Expression<T>.div(arg: T): Expression<T> = this / const(arg) operator fun Expression<T>.div(arg: T): Expression<T> = this / const(arg)
operator fun T.div(arg: Expression<T>): Expression<T> = arg / this operator fun T.div(arg: Expression<T>): Expression<T> = arg / this
@ -136,6 +134,34 @@ open class FunctionalExpressionField<T, A>(algebra: A) :
super<FunctionalExpressionRing>.binaryOperation(operation, left, right) super<FunctionalExpressionRing>.binaryOperation(operation, left, right)
} }
open class FunctionalExpressionExtendedField<T, A>(algebra: A) :
FunctionalExpressionField<T, A>(algebra),
ExtendedField<Expression<T>> where A : ExtendedField<T>, A : NumericAlgebra<T> {
override fun sin(arg: Expression<T>): Expression<T> = unaryOperation(TrigonometricOperations.SIN_OPERATION, arg)
override fun cos(arg: Expression<T>): Expression<T> = unaryOperation(TrigonometricOperations.COS_OPERATION, arg)
override fun asin(arg: Expression<T>): Expression<T> =
unaryOperation(InverseTrigonometricOperations.ASIN_OPERATION, arg)
override fun acos(arg: Expression<T>): Expression<T> =
unaryOperation(InverseTrigonometricOperations.ACOS_OPERATION, arg)
override fun atan(arg: Expression<T>): Expression<T> =
unaryOperation(InverseTrigonometricOperations.ATAN_OPERATION, arg)
override fun power(arg: Expression<T>, pow: Number): Expression<T> =
binaryOperation(PowerOperations.POW_OPERATION, arg, number(pow))
override fun exp(arg: Expression<T>): Expression<T> = unaryOperation(ExponentialOperations.EXP_OPERATION, arg)
override fun ln(arg: Expression<T>): Expression<T> = unaryOperation(ExponentialOperations.LN_OPERATION, arg)
override fun unaryOperation(operation: String, arg: Expression<T>): Expression<T> =
super<FunctionalExpressionField>.unaryOperation(operation, arg)
override fun binaryOperation(operation: String, left: Expression<T>, right: Expression<T>): Expression<T> =
super<FunctionalExpressionField>.binaryOperation(operation, left, right)
}
inline fun <T, A : Space<T>> A.expressionInSpace(block: FunctionalExpressionSpace<T, A>.() -> Expression<T>): Expression<T> = inline fun <T, A : Space<T>> A.expressionInSpace(block: FunctionalExpressionSpace<T, A>.() -> Expression<T>): Expression<T> =
FunctionalExpressionSpace(this).block() FunctionalExpressionSpace(this).block()
@ -144,3 +170,6 @@ inline fun <T, A : Ring<T>> A.expressionInRing(block: FunctionalExpressionRing<T
inline fun <T, A : Field<T>> A.expressionInField(block: FunctionalExpressionField<T, A>.() -> Expression<T>): Expression<T> = inline fun <T, A : Field<T>> A.expressionInField(block: FunctionalExpressionField<T, A>.() -> Expression<T>): Expression<T> =
FunctionalExpressionField(this).block() FunctionalExpressionField(this).block()
inline fun <T, A : ExtendedField<T>> A.expressionInExtendedField(block: FunctionalExpressionExtendedField<T, A>.() -> Expression<T>): Expression<T> =
FunctionalExpressionExtendedField(this).block()

View File

@ -11,7 +11,7 @@ import kotlin.reflect.KClass
* Thread-safe ring buffer * Thread-safe ring buffer
*/ */
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
internal class RingBuffer<T>( class RingBuffer<T>(
private val buffer: MutableBuffer<T?>, private val buffer: MutableBuffer<T?>,
private var startIndex: Int = 0, private var startIndex: Int = 0,
size: Int = 0 size: Int = 0