Provide dynamic operations currying for Algebra<T> instead of eager calls and add JS code generation support #162

Merged
CommanderTvis merged 44 commits from feature/dynamic-ops-currying into dev 2021-01-05 16:36:51 +03:00
14 changed files with 168 additions and 168 deletions
Showing only changes of commit 2c7cb1b04f - Show all commits

View File

@ -57,22 +57,22 @@ public fun <T> Algebra<T>.evaluate(node: MST): T = when (node) {
?: error("Numeric nodes are not supported by $this") ?: error("Numeric nodes are not supported by $this")
is MST.Symbolic -> symbol(node.value) is MST.Symbolic -> symbol(node.value)
is MST.Unary -> unaryOperation(node.operation)(evaluate(node.value)) is MST.Unary -> unaryOperationFunction(node.operation)(evaluate(node.value))
is MST.Binary -> when { is MST.Binary -> when {
this !is NumericAlgebra -> binaryOperation(node.operation)(evaluate(node.left), evaluate(node.right)) this !is NumericAlgebra -> binaryOperationFunction(node.operation)(evaluate(node.left), evaluate(node.right))
node.left is MST.Numeric && node.right is MST.Numeric -> { node.left is MST.Numeric && node.right is MST.Numeric -> {
val number = RealField val number = RealField
.binaryOperation(node.operation) .binaryOperationFunction(node.operation)
.invoke(node.left.value.toDouble(), node.right.value.toDouble()) .invoke(node.left.value.toDouble(), node.right.value.toDouble())
number(number) number(number)
} }
node.left is MST.Numeric -> leftSideNumberOperation(node.operation)(node.left.value, evaluate(node.right)) node.left is MST.Numeric -> leftSideNumberOperationFunction(node.operation)(node.left.value, evaluate(node.right))
node.right is MST.Numeric -> rightSideNumberOperation(node.operation)(evaluate(node.left), node.right.value) node.right is MST.Numeric -> rightSideNumberOperationFunction(node.operation)(evaluate(node.left), node.right.value)
else -> binaryOperation(node.operation)(evaluate(node.left), evaluate(node.right)) else -> binaryOperationFunction(node.operation)(evaluate(node.left), evaluate(node.right))
} }
} }

View File

@ -9,10 +9,10 @@ public object MstAlgebra : NumericAlgebra<MST> {
public override fun number(value: Number): MST.Numeric = MST.Numeric(value) public override fun number(value: Number): MST.Numeric = MST.Numeric(value)
public override fun symbol(value: String): MST.Symbolic = MST.Symbolic(value) public override fun symbol(value: String): MST.Symbolic = MST.Symbolic(value)
public override fun unaryOperation(operation: String): (arg: MST) -> MST.Unary = public override fun unaryOperationFunction(operation: String): (arg: MST) -> MST.Unary =
{ arg -> MST.Unary(operation, arg) } { arg -> MST.Unary(operation, arg) }
public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST.Binary = public override fun binaryOperationFunction(operation: String): (left: MST, right: MST) -> MST.Binary =
{ left, right -> MST.Binary(operation, left, right) } { left, right -> MST.Binary(operation, left, right) }
} }
@ -24,21 +24,21 @@ public object MstSpace : Space<MST>, NumericAlgebra<MST> {
public override fun number(value: Number): MST.Numeric = MstAlgebra.number(value) public override fun number(value: Number): MST.Numeric = MstAlgebra.number(value)
public override fun symbol(value: String): MST.Symbolic = MstAlgebra.symbol(value) public override fun symbol(value: String): MST.Symbolic = MstAlgebra.symbol(value)
public override fun add(a: MST, b: MST): MST.Binary = binaryOperation(SpaceOperations.PLUS_OPERATION)(a, b) public override fun add(a: MST, b: MST): MST.Binary = binaryOperationFunction(SpaceOperations.PLUS_OPERATION)(a, b)
public override operator fun MST.unaryPlus(): MST.Unary = unaryOperation(SpaceOperations.PLUS_OPERATION)(this) public override operator fun MST.unaryPlus(): MST.Unary = unaryOperationFunction(SpaceOperations.PLUS_OPERATION)(this)
public override operator fun MST.unaryMinus(): MST.Unary = unaryOperation(SpaceOperations.MINUS_OPERATION)(this) public override operator fun MST.unaryMinus(): MST.Unary = unaryOperationFunction(SpaceOperations.MINUS_OPERATION)(this)
public override operator fun MST.minus(b: MST): MST.Binary = public override operator fun MST.minus(b: MST): MST.Binary =
binaryOperation(SpaceOperations.MINUS_OPERATION)(this, b) binaryOperationFunction(SpaceOperations.MINUS_OPERATION)(this, b)
public override fun multiply(a: MST, k: Number): MST.Binary = public override fun multiply(a: MST, k: Number): MST.Binary =
binaryOperation(RingOperations.TIMES_OPERATION)(a, number(k)) binaryOperationFunction(RingOperations.TIMES_OPERATION)(a, number(k))
public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST.Binary = public override fun binaryOperationFunction(operation: String): (left: MST, right: MST) -> MST.Binary =
MstAlgebra.binaryOperation(operation) MstAlgebra.binaryOperationFunction(operation)
public override fun unaryOperation(operation: String): (arg: MST) -> MST.Unary = public override fun unaryOperationFunction(operation: String): (arg: MST) -> MST.Unary =
MstAlgebra.unaryOperation(operation) MstAlgebra.unaryOperationFunction(operation)
} }
/** /**
@ -54,16 +54,16 @@ public object MstRing : Ring<MST>, NumericAlgebra<MST> {
public override fun symbol(value: String): MST.Symbolic = MstSpace.symbol(value) public override fun symbol(value: String): MST.Symbolic = MstSpace.symbol(value)
public override fun add(a: MST, b: MST): MST.Binary = MstSpace.add(a, b) public override fun add(a: MST, b: MST): MST.Binary = MstSpace.add(a, b)
public override fun multiply(a: MST, k: Number): MST.Binary = MstSpace.multiply(a, k) public override fun multiply(a: MST, k: Number): MST.Binary = MstSpace.multiply(a, k)
public override fun multiply(a: MST, b: MST): MST.Binary = binaryOperation(RingOperations.TIMES_OPERATION)(a, b) public override fun multiply(a: MST, b: MST): MST.Binary = binaryOperationFunction(RingOperations.TIMES_OPERATION)(a, b)
public override operator fun MST.unaryPlus(): MST.Unary = MstSpace { +this@unaryPlus } public override operator fun MST.unaryPlus(): MST.Unary = MstSpace { +this@unaryPlus }
public override operator fun MST.unaryMinus(): MST.Unary = MstSpace { -this@unaryMinus } public override operator fun MST.unaryMinus(): MST.Unary = MstSpace { -this@unaryMinus }
public override operator fun MST.minus(b: MST): MST.Binary = MstSpace { this@minus - b } public override operator fun MST.minus(b: MST): MST.Binary = MstSpace { this@minus - b }
public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST.Binary = public override fun binaryOperationFunction(operation: String): (left: MST, right: MST) -> MST.Binary =
MstSpace.binaryOperation(operation) MstSpace.binaryOperationFunction(operation)
public override fun unaryOperation(operation: String): (arg: MST) -> MST.Unary = public override fun unaryOperationFunction(operation: String): (arg: MST) -> MST.Unary =
MstAlgebra.unaryOperation(operation) MstAlgebra.unaryOperationFunction(operation)
} }
/** /**
@ -81,15 +81,15 @@ public object MstField : Field<MST> {
public override fun add(a: MST, b: MST): MST.Binary = MstRing.add(a, b) public override fun add(a: MST, b: MST): MST.Binary = MstRing.add(a, b)
public override fun multiply(a: MST, k: Number): MST.Binary = MstRing.multiply(a, k) public override fun multiply(a: MST, k: Number): MST.Binary = MstRing.multiply(a, k)
public override fun multiply(a: MST, b: MST): MST.Binary = MstRing.multiply(a, b) public override fun multiply(a: MST, b: MST): MST.Binary = MstRing.multiply(a, b)
public override fun divide(a: MST, b: MST): MST.Binary = binaryOperation(FieldOperations.DIV_OPERATION)(a, b) public override fun divide(a: MST, b: MST): MST.Binary = binaryOperationFunction(FieldOperations.DIV_OPERATION)(a, b)
public override operator fun MST.unaryPlus(): MST.Unary = MstRing { +this@unaryPlus } public override operator fun MST.unaryPlus(): MST.Unary = MstRing { +this@unaryPlus }
public override operator fun MST.unaryMinus(): MST.Unary = MstRing { -this@unaryMinus } public override operator fun MST.unaryMinus(): MST.Unary = MstRing { -this@unaryMinus }
public override operator fun MST.minus(b: MST): MST.Binary = MstRing { this@minus - b } public override operator fun MST.minus(b: MST): MST.Binary = MstRing { this@minus - b }
public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST.Binary = public override fun binaryOperationFunction(operation: String): (left: MST, right: MST) -> MST.Binary =
MstRing.binaryOperation(operation) MstRing.binaryOperationFunction(operation)
public override fun unaryOperation(operation: String): (arg: MST) -> MST.Unary = MstRing.unaryOperation(operation) public override fun unaryOperationFunction(operation: String): (arg: MST) -> MST.Unary = MstRing.unaryOperationFunction(operation)
} }
/** /**
@ -103,18 +103,18 @@ public object MstExtendedField : ExtendedField<MST> {
get() = MstField.one get() = MstField.one
public override fun symbol(value: String): MST.Symbolic = MstField.symbol(value) public override fun symbol(value: String): MST.Symbolic = MstField.symbol(value)
public override fun sin(arg: MST): MST.Unary = unaryOperation(TrigonometricOperations.SIN_OPERATION)(arg) public override fun sin(arg: MST): MST.Unary = unaryOperationFunction(TrigonometricOperations.SIN_OPERATION)(arg)
public override fun cos(arg: MST): MST.Unary = unaryOperation(TrigonometricOperations.COS_OPERATION)(arg) public override fun cos(arg: MST): MST.Unary = unaryOperationFunction(TrigonometricOperations.COS_OPERATION)(arg)
public override fun tan(arg: MST): MST.Unary = unaryOperation(TrigonometricOperations.TAN_OPERATION)(arg) public override fun tan(arg: MST): MST.Unary = unaryOperationFunction(TrigonometricOperations.TAN_OPERATION)(arg)
public override fun asin(arg: MST): MST.Unary = unaryOperation(TrigonometricOperations.ASIN_OPERATION)(arg) public override fun asin(arg: MST): MST.Unary = unaryOperationFunction(TrigonometricOperations.ASIN_OPERATION)(arg)
public override fun acos(arg: MST): MST.Unary = unaryOperation(TrigonometricOperations.ACOS_OPERATION)(arg) public override fun acos(arg: MST): MST.Unary = unaryOperationFunction(TrigonometricOperations.ACOS_OPERATION)(arg)
public override fun atan(arg: MST): MST.Unary = unaryOperation(TrigonometricOperations.ATAN_OPERATION)(arg) public override fun atan(arg: MST): MST.Unary = unaryOperationFunction(TrigonometricOperations.ATAN_OPERATION)(arg)
public override fun sinh(arg: MST): MST.Unary = unaryOperation(HyperbolicOperations.SINH_OPERATION)(arg) public override fun sinh(arg: MST): MST.Unary = unaryOperationFunction(HyperbolicOperations.SINH_OPERATION)(arg)
public override fun cosh(arg: MST): MST.Unary = unaryOperation(HyperbolicOperations.COSH_OPERATION)(arg) public override fun cosh(arg: MST): MST.Unary = unaryOperationFunction(HyperbolicOperations.COSH_OPERATION)(arg)
public override fun tanh(arg: MST): MST.Unary = unaryOperation(HyperbolicOperations.TANH_OPERATION)(arg) public override fun tanh(arg: MST): MST.Unary = unaryOperationFunction(HyperbolicOperations.TANH_OPERATION)(arg)
public override fun asinh(arg: MST): MST.Unary = unaryOperation(HyperbolicOperations.ASINH_OPERATION)(arg) public override fun asinh(arg: MST): MST.Unary = unaryOperationFunction(HyperbolicOperations.ASINH_OPERATION)(arg)
public override fun acosh(arg: MST): MST.Unary = unaryOperation(HyperbolicOperations.ACOSH_OPERATION)(arg) public override fun acosh(arg: MST): MST.Unary = unaryOperationFunction(HyperbolicOperations.ACOSH_OPERATION)(arg)
public override fun atanh(arg: MST): MST.Unary = unaryOperation(HyperbolicOperations.ATANH_OPERATION)(arg) public override fun atanh(arg: MST): MST.Unary = unaryOperationFunction(HyperbolicOperations.ATANH_OPERATION)(arg)
public override fun add(a: MST, b: MST): MST.Binary = MstField.add(a, b) public override fun add(a: MST, b: MST): MST.Binary = MstField.add(a, b)
public override fun multiply(a: MST, k: Number): MST.Binary = MstField.multiply(a, k) public override fun multiply(a: MST, k: Number): MST.Binary = MstField.multiply(a, k)
public override fun multiply(a: MST, b: MST): MST.Binary = MstField.multiply(a, b) public override fun multiply(a: MST, b: MST): MST.Binary = MstField.multiply(a, b)
@ -124,13 +124,13 @@ public object MstExtendedField : ExtendedField<MST> {
public override operator fun MST.minus(b: MST): MST.Binary = MstField { this@minus - b } public override operator fun MST.minus(b: MST): MST.Binary = MstField { this@minus - b }
public override fun power(arg: MST, pow: Number): MST.Binary = public override fun power(arg: MST, pow: Number): MST.Binary =
binaryOperation(PowerOperations.POW_OPERATION)(arg, number(pow)) binaryOperationFunction(PowerOperations.POW_OPERATION)(arg, number(pow))
public override fun exp(arg: MST): MST.Unary = unaryOperation(ExponentialOperations.EXP_OPERATION)(arg) public override fun exp(arg: MST): MST.Unary = unaryOperationFunction(ExponentialOperations.EXP_OPERATION)(arg)
public override fun ln(arg: MST): MST.Unary = unaryOperation(ExponentialOperations.LN_OPERATION)(arg) public override fun ln(arg: MST): MST.Unary = unaryOperationFunction(ExponentialOperations.LN_OPERATION)(arg)
public override fun binaryOperation(operation: String): (left: MST, right: MST) -> MST.Binary = public override fun binaryOperationFunction(operation: String): (left: MST, right: MST) -> MST.Binary =
MstField.binaryOperation(operation) MstField.binaryOperationFunction(operation)
public override fun unaryOperation(operation: String): (arg: MST) -> MST.Unary = MstField.unaryOperation(operation) public override fun unaryOperationFunction(operation: String): (arg: MST) -> MST.Unary = MstField.unaryOperationFunction(operation)
} }

View File

@ -21,8 +21,8 @@ public class MstExpression<T, out A : Algebra<T>>(public val algebra: A, public
null null
} ?: arguments.getValue(StringSymbol(value)) } ?: arguments.getValue(StringSymbol(value))
override fun unaryOperation(operation: String): (arg: T) -> T = algebra.unaryOperation(operation) override fun unaryOperationFunction(operation: String): (arg: T) -> T = algebra.unaryOperationFunction(operation)
override fun binaryOperation(operation: String): (left: T, right: T) -> T = algebra.binaryOperation(operation) override fun binaryOperationFunction(operation: String): (left: T, right: T) -> T = algebra.binaryOperationFunction(operation)
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
override fun number(value: Number): T = if (algebra is NumericAlgebra<*>) override fun number(value: Number): T = if (algebra is NumericAlgebra<*>)

View File

@ -26,31 +26,31 @@ internal fun <T> MST.compileWith(algebra: Algebra<T>): Expression<T> {
} }
is MST.Numeric -> constant(node.value) is MST.Numeric -> constant(node.value)
is MST.Unary -> call(algebra.unaryOperation(node.operation), visit(node.value)) is MST.Unary -> call(algebra.unaryOperationFunction(node.operation), visit(node.value))
is MST.Binary -> when { is MST.Binary -> when {
algebra is NumericAlgebra<T> && node.left is MST.Numeric && node.right is MST.Numeric -> constant( algebra is NumericAlgebra<T> && node.left is MST.Numeric && node.right is MST.Numeric -> constant(
algebra.number( algebra.number(
RealField RealField
.binaryOperation(node.operation) .binaryOperationFunction(node.operation)
.invoke(node.left.value.toDouble(), node.right.value.toDouble()) .invoke(node.left.value.toDouble(), node.right.value.toDouble())
) )
) )
algebra is NumericAlgebra<T> && node.left is MST.Numeric -> call( algebra is NumericAlgebra<T> && node.left is MST.Numeric -> call(
algebra.leftSideNumberOperation(node.operation), algebra.leftSideNumberOperationFunction(node.operation),
visit(node.left), visit(node.left),
visit(node.right), visit(node.right),
) )
algebra is NumericAlgebra<T> && node.right is MST.Numeric -> call( algebra is NumericAlgebra<T> && node.right is MST.Numeric -> call(
algebra.rightSideNumberOperation(node.operation), algebra.rightSideNumberOperationFunction(node.operation),
visit(node.left), visit(node.left),
visit(node.right), visit(node.right),
) )
else -> call( else -> call(
algebra.binaryOperation(node.operation), algebra.binaryOperationFunction(node.operation),
visit(node.left), visit(node.left),
visit(node.right), visit(node.right),
) )

View File

@ -13,8 +13,8 @@ internal class TestESTreeConsistencyWithInterpreter {
@Test @Test
fun mstSpace() { fun mstSpace() {
val res1 = MstSpace.mstInSpace { val res1 = MstSpace.mstInSpace {
binaryOperation("+")( binaryOperationFunction("+")(
unaryOperation("+")( unaryOperationFunction("+")(
number(3.toByte()) - (number(2.toByte()) + (multiply( number(3.toByte()) - (number(2.toByte()) + (multiply(
add(number(1), number(1)), add(number(1), number(1)),
2 2
@ -26,8 +26,8 @@ internal class TestESTreeConsistencyWithInterpreter {
}("x" to MST.Numeric(2)) }("x" to MST.Numeric(2))
val res2 = MstSpace.mstInSpace { val res2 = MstSpace.mstInSpace {
binaryOperation("+")( binaryOperationFunction("+")(
unaryOperation("+")( unaryOperationFunction("+")(
number(3.toByte()) - (number(2.toByte()) + (multiply( number(3.toByte()) - (number(2.toByte()) + (multiply(
add(number(1), number(1)), add(number(1), number(1)),
2 2
@ -44,8 +44,8 @@ internal class TestESTreeConsistencyWithInterpreter {
@Test @Test
fun byteRing() { fun byteRing() {
val res1 = ByteRing.mstInRing { val res1 = ByteRing.mstInRing {
binaryOperation("+")( binaryOperationFunction("+")(
unaryOperation("+")( unaryOperationFunction("+")(
(symbol("x") - (2.toByte() + (multiply( (symbol("x") - (2.toByte() + (multiply(
add(number(1), number(1)), add(number(1), number(1)),
2 2
@ -57,8 +57,8 @@ internal class TestESTreeConsistencyWithInterpreter {
}("x" to 3.toByte()) }("x" to 3.toByte())
val res2 = ByteRing.mstInRing { val res2 = ByteRing.mstInRing {
binaryOperation("+")( binaryOperationFunction("+")(
unaryOperation("+")( unaryOperationFunction("+")(
(symbol("x") - (2.toByte() + (multiply( (symbol("x") - (2.toByte() + (multiply(
add(number(1), number(1)), add(number(1), number(1)),
2 2
@ -74,7 +74,7 @@ internal class TestESTreeConsistencyWithInterpreter {
@Test @Test
fun realField() { fun realField() {
val res1 = RealField.mstInField { val res1 = RealField.mstInField {
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperation("+")( +(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
(3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0 (3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0
+ number(1), + number(1),
number(1) / 2 + number(2.0) * one number(1) / 2 + number(2.0) * one
@ -82,7 +82,7 @@ internal class TestESTreeConsistencyWithInterpreter {
}("x" to 2.0) }("x" to 2.0)
val res2 = RealField.mstInField { val res2 = RealField.mstInField {
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperation("+")( +(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
(3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0 (3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0
+ number(1), + number(1),
number(1) / 2 + number(2.0) * one number(1) / 2 + number(2.0) * one
@ -95,7 +95,7 @@ internal class TestESTreeConsistencyWithInterpreter {
@Test @Test
fun complexField() { fun complexField() {
val res1 = ComplexField.mstInField { val res1 = ComplexField.mstInField {
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperation("+")( +(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
(3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0 (3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0
+ number(1), + number(1),
number(1) / 2 + number(2.0) * one number(1) / 2 + number(2.0) * one
@ -103,7 +103,7 @@ internal class TestESTreeConsistencyWithInterpreter {
}("x" to 2.0.toComplex()) }("x" to 2.0.toComplex())
val res2 = ComplexField.mstInField { val res2 = ComplexField.mstInField {
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperation("+")( +(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
(3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0 (3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0
+ number(1), + number(1),
number(1) / 2 + number(2.0) * one number(1) / 2 + number(2.0) * one

View File

@ -9,44 +9,44 @@ import kotlin.test.assertEquals
internal class TestESTreeSpecialization { internal class TestESTreeSpecialization {
@Test @Test
fun testUnaryPlus() { fun testUnaryPlus() {
val expr = RealField.mstInField { unaryOperation("+")(symbol("x")) }.compile() val expr = RealField.mstInField { unaryOperationFunction("+")(symbol("x")) }.compile()
assertEquals(2.0, expr("x" to 2.0)) assertEquals(2.0, expr("x" to 2.0))
} }
@Test @Test
fun testUnaryMinus() { fun testUnaryMinus() {
val expr = RealField.mstInField { unaryOperation("-")(symbol("x")) }.compile() val expr = RealField.mstInField { unaryOperationFunction("-")(symbol("x")) }.compile()
assertEquals(-2.0, expr("x" to 2.0)) assertEquals(-2.0, expr("x" to 2.0))
} }
@Test @Test
fun testAdd() { fun testAdd() {
val expr = RealField.mstInField { binaryOperation("+")(symbol("x"), symbol("x")) }.compile() val expr = RealField.mstInField { binaryOperationFunction("+")(symbol("x"), symbol("x")) }.compile()
assertEquals(4.0, expr("x" to 2.0)) assertEquals(4.0, expr("x" to 2.0))
} }
@Test @Test
fun testSine() { fun testSine() {
val expr = RealField.mstInField { unaryOperation("sin")(symbol("x")) }.compile() val expr = RealField.mstInField { unaryOperationFunction("sin")(symbol("x")) }.compile()
assertEquals(0.0, expr("x" to 0.0)) assertEquals(0.0, expr("x" to 0.0))
} }
@Test @Test
fun testMinus() { fun testMinus() {
val expr = RealField.mstInField { binaryOperation("-")(symbol("x"), symbol("x")) }.compile() val expr = RealField.mstInField { binaryOperationFunction("-")(symbol("x"), symbol("x")) }.compile()
assertEquals(0.0, expr("x" to 2.0)) assertEquals(0.0, expr("x" to 2.0))
} }
@Test @Test
fun testDivide() { fun testDivide() {
val expr = RealField.mstInField { binaryOperation("/")(symbol("x"), symbol("x")) }.compile() val expr = RealField.mstInField { binaryOperationFunction("/")(symbol("x"), symbol("x")) }.compile()
assertEquals(1.0, expr("x" to 2.0)) assertEquals(1.0, expr("x" to 2.0))
} }
@Test @Test
fun testPower() { fun testPower() {
val expr = RealField val expr = RealField
.mstInField { binaryOperation("pow")(symbol("x"), number(2)) } .mstInField { binaryOperationFunction("pow")(symbol("x"), number(2)) }
.compile() .compile()
assertEquals(4.0, expr("x" to 2.0)) assertEquals(4.0, expr("x" to 2.0))

View File

@ -34,28 +34,28 @@ internal fun <T : Any> MST.compileWith(type: Class<T>, algebra: Algebra<T>): Exp
} }
is MST.Numeric -> loadNumberConstant(node.value) is MST.Numeric -> loadNumberConstant(node.value)
is MST.Unary -> buildCall(algebra.unaryOperation(node.operation)) { visit(node.value) } is MST.Unary -> buildCall(algebra.unaryOperationFunction(node.operation)) { visit(node.value) }
is MST.Binary -> when { is MST.Binary -> when {
algebra is NumericAlgebra<T> && node.left is MST.Numeric && node.right is MST.Numeric -> loadObjectConstant( algebra is NumericAlgebra<T> && node.left is MST.Numeric && node.right is MST.Numeric -> loadObjectConstant(
algebra.number( algebra.number(
RealField RealField
.binaryOperation(node.operation) .binaryOperationFunction(node.operation)
.invoke(node.left.value.toDouble(), node.right.value.toDouble()) .invoke(node.left.value.toDouble(), node.right.value.toDouble())
) )
) )
algebra is NumericAlgebra<T> && node.left is MST.Numeric -> buildCall(algebra.leftSideNumberOperation(node.operation)) { algebra is NumericAlgebra<T> && node.left is MST.Numeric -> buildCall(algebra.leftSideNumberOperationFunction(node.operation)) {
visit(node.left) visit(node.left)
visit(node.right) visit(node.right)
} }
algebra is NumericAlgebra<T> && node.right is MST.Numeric -> buildCall(algebra.rightSideNumberOperation(node.operation)) { algebra is NumericAlgebra<T> && node.right is MST.Numeric -> buildCall(algebra.rightSideNumberOperationFunction(node.operation)) {
visit(node.left) visit(node.left)
visit(node.right) visit(node.right)
} }
else -> buildCall(algebra.binaryOperation(node.operation)) { else -> buildCall(algebra.binaryOperationFunction(node.operation)) {
visit(node.left) visit(node.left)
visit(node.right) visit(node.right)
} }

View File

@ -13,8 +13,8 @@ internal class TestAsmConsistencyWithInterpreter {
@Test @Test
fun mstSpace() { fun mstSpace() {
val res1 = MstSpace.mstInSpace { val res1 = MstSpace.mstInSpace {
binaryOperation("+")( binaryOperationFunction("+")(
unaryOperation("+")( unaryOperationFunction("+")(
number(3.toByte()) - (number(2.toByte()) + (multiply( number(3.toByte()) - (number(2.toByte()) + (multiply(
add(number(1), number(1)), add(number(1), number(1)),
2 2
@ -26,8 +26,8 @@ internal class TestAsmConsistencyWithInterpreter {
}("x" to MST.Numeric(2)) }("x" to MST.Numeric(2))
val res2 = MstSpace.mstInSpace { val res2 = MstSpace.mstInSpace {
binaryOperation("+")( binaryOperationFunction("+")(
unaryOperation("+")( unaryOperationFunction("+")(
number(3.toByte()) - (number(2.toByte()) + (multiply( number(3.toByte()) - (number(2.toByte()) + (multiply(
add(number(1), number(1)), add(number(1), number(1)),
2 2
@ -44,8 +44,8 @@ internal class TestAsmConsistencyWithInterpreter {
@Test @Test
fun byteRing() { fun byteRing() {
val res1 = ByteRing.mstInRing { val res1 = ByteRing.mstInRing {
binaryOperation("+")( binaryOperationFunction("+")(
unaryOperation("+")( unaryOperationFunction("+")(
(symbol("x") - (2.toByte() + (multiply( (symbol("x") - (2.toByte() + (multiply(
add(number(1), number(1)), add(number(1), number(1)),
2 2
@ -57,8 +57,8 @@ internal class TestAsmConsistencyWithInterpreter {
}("x" to 3.toByte()) }("x" to 3.toByte())
val res2 = ByteRing.mstInRing { val res2 = ByteRing.mstInRing {
binaryOperation("+")( binaryOperationFunction("+")(
unaryOperation("+")( unaryOperationFunction("+")(
(symbol("x") - (2.toByte() + (multiply( (symbol("x") - (2.toByte() + (multiply(
add(number(1), number(1)), add(number(1), number(1)),
2 2
@ -74,7 +74,7 @@ internal class TestAsmConsistencyWithInterpreter {
@Test @Test
fun realField() { fun realField() {
val res1 = RealField.mstInField { val res1 = RealField.mstInField {
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperation("+")( +(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
(3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0 (3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0
+ number(1), + number(1),
number(1) / 2 + number(2.0) * one number(1) / 2 + number(2.0) * one
@ -82,7 +82,7 @@ internal class TestAsmConsistencyWithInterpreter {
}("x" to 2.0) }("x" to 2.0)
val res2 = RealField.mstInField { val res2 = RealField.mstInField {
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperation("+")( +(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
(3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0 (3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0
+ number(1), + number(1),
number(1) / 2 + number(2.0) * one number(1) / 2 + number(2.0) * one
@ -95,7 +95,7 @@ internal class TestAsmConsistencyWithInterpreter {
@Test @Test
fun complexField() { fun complexField() {
val res1 = ComplexField.mstInField { val res1 = ComplexField.mstInField {
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperation("+")( +(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
(3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0 (3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0
+ number(1), + number(1),
number(1) / 2 + number(2.0) * one number(1) / 2 + number(2.0) * one
@ -103,7 +103,7 @@ internal class TestAsmConsistencyWithInterpreter {
}("x" to 2.0.toComplex()) }("x" to 2.0.toComplex())
val res2 = ComplexField.mstInField { val res2 = ComplexField.mstInField {
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperation("+")( +(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
(3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0 (3.0 - (symbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0
+ number(1), + number(1),
number(1) / 2 + number(2.0) * one number(1) / 2 + number(2.0) * one

View File

@ -9,44 +9,44 @@ import kotlin.test.assertEquals
internal class TestAsmSpecialization { internal class TestAsmSpecialization {
@Test @Test
fun testUnaryPlus() { fun testUnaryPlus() {
val expr = RealField.mstInField { unaryOperation("+")(symbol("x")) }.compile() val expr = RealField.mstInField { unaryOperationFunction("+")(symbol("x")) }.compile()
assertEquals(2.0, expr("x" to 2.0)) assertEquals(2.0, expr("x" to 2.0))
} }
@Test @Test
fun testUnaryMinus() { fun testUnaryMinus() {
val expr = RealField.mstInField { unaryOperation("-")(symbol("x")) }.compile() val expr = RealField.mstInField { unaryOperationFunction("-")(symbol("x")) }.compile()
assertEquals(-2.0, expr("x" to 2.0)) assertEquals(-2.0, expr("x" to 2.0))
} }
@Test @Test
fun testAdd() { fun testAdd() {
val expr = RealField.mstInField { binaryOperation("+")(symbol("x"), symbol("x")) }.compile() val expr = RealField.mstInField { binaryOperationFunction("+")(symbol("x"), symbol("x")) }.compile()
assertEquals(4.0, expr("x" to 2.0)) assertEquals(4.0, expr("x" to 2.0))
} }
@Test @Test
fun testSine() { fun testSine() {
val expr = RealField.mstInField { unaryOperation("sin")(symbol("x")) }.compile() val expr = RealField.mstInField { unaryOperationFunction("sin")(symbol("x")) }.compile()
assertEquals(0.0, expr("x" to 0.0)) assertEquals(0.0, expr("x" to 0.0))
} }
@Test @Test
fun testMinus() { fun testMinus() {
val expr = RealField.mstInField { binaryOperation("-")(symbol("x"), symbol("x")) }.compile() val expr = RealField.mstInField { binaryOperationFunction("-")(symbol("x"), symbol("x")) }.compile()
assertEquals(0.0, expr("x" to 2.0)) assertEquals(0.0, expr("x" to 2.0))
} }
@Test @Test
fun testDivide() { fun testDivide() {
val expr = RealField.mstInField { binaryOperation("/")(symbol("x"), symbol("x")) }.compile() val expr = RealField.mstInField { binaryOperationFunction("/")(symbol("x"), symbol("x")) }.compile()
assertEquals(1.0, expr("x" to 2.0)) assertEquals(1.0, expr("x" to 2.0))
} }
@Test @Test
fun testPower() { fun testPower() {
val expr = RealField val expr = RealField
.mstInField { binaryOperation("pow")(symbol("x"), number(2)) } .mstInField { binaryOperationFunction("pow")(symbol("x"), number(2)) }
.compile() .compile()
assertEquals(4.0, expr("x" to 2.0)) assertEquals(4.0, expr("x" to 2.0))

View File

@ -42,11 +42,11 @@ internal class ParserTest {
val magicalAlgebra = object : Algebra<String> { val magicalAlgebra = object : Algebra<String> {
override fun symbol(value: String): String = value override fun symbol(value: String): String = value
override fun unaryOperation(operation: String): (arg: String) -> String { override fun unaryOperationFunction(operation: String): (arg: String) -> String {
throw NotImplementedError() throw NotImplementedError()
} }
override fun binaryOperation(operation: String): (left: String, right: String) -> String = override fun binaryOperationFunction(operation: String): (left: String, right: String) -> String =
when (operation) { when (operation) {
"magic" -> { left, right -> "$left$right" } "magic" -> { left, right -> "$left$right" }
else -> throw NotImplementedError() else -> throw NotImplementedError()

View File

@ -24,18 +24,18 @@ public abstract class FunctionalExpressionAlgebra<T, A : Algebra<T>>(public val
/** /**
* Builds an Expression of dynamic call of binary operation [operation] on [left] and [right]. * Builds an Expression of dynamic call of binary operation [operation] on [left] and [right].
*/ */
public override fun binaryOperation(operation: String): (left: Expression<T>, right: Expression<T>) -> Expression<T> = public override fun binaryOperationFunction(operation: String): (left: Expression<T>, right: Expression<T>) -> Expression<T> =
{ left, right -> { left, right ->
Expression { arguments -> Expression { arguments ->
algebra.binaryOperation(operation)(left.invoke(arguments), right.invoke(arguments)) algebra.binaryOperationFunction(operation)(left.invoke(arguments), right.invoke(arguments))
} }
} }
/** /**
* Builds an Expression of dynamic call of unary operation with name [operation] on [arg]. * Builds an Expression of dynamic call of unary operation with name [operation] on [arg].
*/ */
public override fun unaryOperation(operation: String): (arg: Expression<T>) -> Expression<T> = { arg -> public override fun unaryOperationFunction(operation: String): (arg: Expression<T>) -> Expression<T> = { arg ->
Expression { arguments -> algebra.unaryOperation(operation)(arg.invoke(arguments)) } Expression { arguments -> algebra.unaryOperationFunction(operation)(arg.invoke(arguments)) }
} }
} }
@ -50,7 +50,7 @@ public open class FunctionalExpressionSpace<T, A : Space<T>>(algebra: A) :
* Builds an Expression of addition of two another expressions. * Builds an Expression of addition of two another expressions.
*/ */
public override fun add(a: Expression<T>, b: Expression<T>): Expression<T> = public override fun add(a: Expression<T>, b: Expression<T>): Expression<T> =
binaryOperation(SpaceOperations.PLUS_OPERATION)(a, b) binaryOperationFunction(SpaceOperations.PLUS_OPERATION)(a, b)
/** /**
* Builds an Expression of multiplication of expression by number. * Builds an Expression of multiplication of expression by number.
@ -64,11 +64,11 @@ public open class FunctionalExpressionSpace<T, A : Space<T>>(algebra: A) :
public operator fun T.plus(arg: Expression<T>): Expression<T> = arg + this public operator fun T.plus(arg: Expression<T>): Expression<T> = arg + this
public operator fun T.minus(arg: Expression<T>): Expression<T> = arg - this public operator fun T.minus(arg: Expression<T>): Expression<T> = arg - this
public override fun unaryOperation(operation: String): (arg: Expression<T>) -> Expression<T> = public override fun unaryOperationFunction(operation: String): (arg: Expression<T>) -> Expression<T> =
super<FunctionalExpressionAlgebra>.unaryOperation(operation) super<FunctionalExpressionAlgebra>.unaryOperationFunction(operation)
public override fun binaryOperation(operation: String): (left: Expression<T>, right: Expression<T>) -> Expression<T> = public override fun binaryOperationFunction(operation: String): (left: Expression<T>, right: Expression<T>) -> Expression<T> =
super<FunctionalExpressionAlgebra>.binaryOperation(operation) super<FunctionalExpressionAlgebra>.binaryOperationFunction(operation)
} }
public open class FunctionalExpressionRing<T, A>(algebra: A) : FunctionalExpressionSpace<T, A>(algebra), public open class FunctionalExpressionRing<T, A>(algebra: A) : FunctionalExpressionSpace<T, A>(algebra),
@ -80,16 +80,16 @@ public open class FunctionalExpressionRing<T, A>(algebra: A) : FunctionalExpress
* Builds an Expression of multiplication of two expressions. * Builds an Expression of multiplication of two expressions.
*/ */
public override fun multiply(a: Expression<T>, b: Expression<T>): Expression<T> = public override fun multiply(a: Expression<T>, b: Expression<T>): Expression<T> =
binaryOperation(RingOperations.TIMES_OPERATION)(a, b) binaryOperationFunction(RingOperations.TIMES_OPERATION)(a, b)
public operator fun Expression<T>.times(arg: T): Expression<T> = this * const(arg) public operator fun Expression<T>.times(arg: T): Expression<T> = this * const(arg)
public operator fun T.times(arg: Expression<T>): Expression<T> = arg * this public operator fun T.times(arg: Expression<T>): Expression<T> = arg * this
public override fun unaryOperation(operation: String): (arg: Expression<T>) -> Expression<T> = public override fun unaryOperationFunction(operation: String): (arg: Expression<T>) -> Expression<T> =
super<FunctionalExpressionSpace>.unaryOperation(operation) super<FunctionalExpressionSpace>.unaryOperationFunction(operation)
public override fun binaryOperation(operation: String): (left: Expression<T>, right: Expression<T>) -> Expression<T> = public override fun binaryOperationFunction(operation: String): (left: Expression<T>, right: Expression<T>) -> Expression<T> =
super<FunctionalExpressionSpace>.binaryOperation(operation) super<FunctionalExpressionSpace>.binaryOperationFunction(operation)
} }
public open class FunctionalExpressionField<T, A>(algebra: A) : public open class FunctionalExpressionField<T, A>(algebra: A) :
@ -99,49 +99,49 @@ public 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.
*/ */
public override fun divide(a: Expression<T>, b: Expression<T>): Expression<T> = public override fun divide(a: Expression<T>, b: Expression<T>): Expression<T> =
binaryOperation(FieldOperations.DIV_OPERATION)(a, b) binaryOperationFunction(FieldOperations.DIV_OPERATION)(a, b)
public operator fun Expression<T>.div(arg: T): Expression<T> = this / const(arg) public operator fun Expression<T>.div(arg: T): Expression<T> = this / const(arg)
public operator fun T.div(arg: Expression<T>): Expression<T> = arg / this public operator fun T.div(arg: Expression<T>): Expression<T> = arg / this
public override fun unaryOperation(operation: String): (arg: Expression<T>) -> Expression<T> = public override fun unaryOperationFunction(operation: String): (arg: Expression<T>) -> Expression<T> =
super<FunctionalExpressionRing>.unaryOperation(operation) super<FunctionalExpressionRing>.unaryOperationFunction(operation)
public override fun binaryOperation(operation: String): (left: Expression<T>, right: Expression<T>) -> Expression<T> = public override fun binaryOperationFunction(operation: String): (left: Expression<T>, right: Expression<T>) -> Expression<T> =
super<FunctionalExpressionRing>.binaryOperation(operation) super<FunctionalExpressionRing>.binaryOperationFunction(operation)
} }
public open class FunctionalExpressionExtendedField<T, A>(algebra: A) : public open class FunctionalExpressionExtendedField<T, A>(algebra: A) :
FunctionalExpressionField<T, A>(algebra), FunctionalExpressionField<T, A>(algebra),
ExtendedField<Expression<T>> where A : ExtendedField<T>, A : NumericAlgebra<T> { ExtendedField<Expression<T>> where A : ExtendedField<T>, A : NumericAlgebra<T> {
public override fun sin(arg: Expression<T>): Expression<T> = public override fun sin(arg: Expression<T>): Expression<T> =
unaryOperation(TrigonometricOperations.SIN_OPERATION)(arg) unaryOperationFunction(TrigonometricOperations.SIN_OPERATION)(arg)
public override fun cos(arg: Expression<T>): Expression<T> = public override fun cos(arg: Expression<T>): Expression<T> =
unaryOperation(TrigonometricOperations.COS_OPERATION)(arg) unaryOperationFunction(TrigonometricOperations.COS_OPERATION)(arg)
public override fun asin(arg: Expression<T>): Expression<T> = public override fun asin(arg: Expression<T>): Expression<T> =
unaryOperation(TrigonometricOperations.ASIN_OPERATION)(arg) unaryOperationFunction(TrigonometricOperations.ASIN_OPERATION)(arg)
public override fun acos(arg: Expression<T>): Expression<T> = public override fun acos(arg: Expression<T>): Expression<T> =
unaryOperation(TrigonometricOperations.ACOS_OPERATION)(arg) unaryOperationFunction(TrigonometricOperations.ACOS_OPERATION)(arg)
public override fun atan(arg: Expression<T>): Expression<T> = public override fun atan(arg: Expression<T>): Expression<T> =
unaryOperation(TrigonometricOperations.ATAN_OPERATION)(arg) unaryOperationFunction(TrigonometricOperations.ATAN_OPERATION)(arg)
public override fun power(arg: Expression<T>, pow: Number): Expression<T> = public override fun power(arg: Expression<T>, pow: Number): Expression<T> =
binaryOperation(PowerOperations.POW_OPERATION)(arg, number(pow)) binaryOperationFunction(PowerOperations.POW_OPERATION)(arg, number(pow))
public override fun exp(arg: Expression<T>): Expression<T> = public override fun exp(arg: Expression<T>): Expression<T> =
unaryOperation(ExponentialOperations.EXP_OPERATION)(arg) unaryOperationFunction(ExponentialOperations.EXP_OPERATION)(arg)
public override fun ln(arg: Expression<T>): Expression<T> = unaryOperation(ExponentialOperations.LN_OPERATION)(arg) public override fun ln(arg: Expression<T>): Expression<T> = unaryOperationFunction(ExponentialOperations.LN_OPERATION)(arg)
public override fun unaryOperation(operation: String): (arg: Expression<T>) -> Expression<T> = public override fun unaryOperationFunction(operation: String): (arg: Expression<T>) -> Expression<T> =
super<FunctionalExpressionField>.unaryOperation(operation) super<FunctionalExpressionField>.unaryOperationFunction(operation)
public override fun binaryOperation(operation: String): (left: Expression<T>, right: Expression<T>) -> Expression<T> = public override fun binaryOperationFunction(operation: String): (left: Expression<T>, right: Expression<T>) -> Expression<T> =
super<FunctionalExpressionField>.binaryOperation(operation) super<FunctionalExpressionField>.binaryOperationFunction(operation)
} }
public inline fun <T, A : Space<T>> A.expressionInSpace(block: FunctionalExpressionSpace<T, A>.() -> Expression<T>): Expression<T> = public inline fun <T, A : Space<T>> A.expressionInSpace(block: FunctionalExpressionSpace<T, A>.() -> Expression<T>): Expression<T> =

View File

@ -19,10 +19,10 @@ public interface MatrixContext<T : Any, out M : Matrix<T>> : SpaceOperations<Mat
public fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> T): M public fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> T): M
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
public override fun binaryOperation(operation: String): (left: Matrix<T>, right: Matrix<T>) -> M = public override fun binaryOperationFunction(operation: String): (left: Matrix<T>, right: Matrix<T>) -> M =
when (operation) { when (operation) {
"dot" -> { left, right -> left dot right } "dot" -> { left, right -> left dot right }
else -> super.binaryOperation(operation) as (Matrix<T>, Matrix<T>) -> M else -> super.binaryOperationFunction(operation) as (Matrix<T>, Matrix<T>) -> M
} }
/** /**

View File

@ -33,12 +33,12 @@ public interface Algebra<T> {
* *
* 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException]. * 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException].
* 2. This function is symmetric with second `unaryOperation` overload: * 2. This function is symmetric with second `unaryOperation` overload:
* i.e. `unaryOperation(a)(b) == unaryOperation(a, b)`. * i.e. `unaryOperationFunction(a)(b) == unaryOperation(a, b)`.
* *
* @param operation the name of operation. * @param operation the name of operation.
* @return an operation. * @return an operation.
*/ */
public fun unaryOperation(operation: String): (arg: T) -> T = public fun unaryOperationFunction(operation: String): (arg: T) -> T =
error("Unary operation $operation not defined in $this") error("Unary operation $operation not defined in $this")
/** /**
@ -47,14 +47,14 @@ public interface Algebra<T> {
* This function must follow two properties: * This function must follow two properties:
* *
* 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException]. * 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException].
* 2. This function is symmetric with second [unaryOperation] overload: * 2. This function is symmetric with second [unaryOperationFunction] overload:
* i.e. `unaryOperation(a)(b) == unaryOperation(a, b)`. * i.e. `unaryOperationFunction(a)(b) == unaryOperation(a, b)`.
* *
* @param operation the name of operation. * @param operation the name of operation.
* @param arg the argument of operation. * @param arg the argument of operation.
* @return a result of operation. * @return a result of operation.
*/ */
public fun unaryOperation(operation: String, arg: T): T = unaryOperation(operation)(arg) public fun unaryOperation(operation: String, arg: T): T = unaryOperationFunction(operation)(arg)
/** /**
* Dynamically dispatches a binary operation with the certain name. * Dynamically dispatches a binary operation with the certain name.
@ -62,13 +62,13 @@ public interface Algebra<T> {
* This function must follow two properties: * This function must follow two properties:
* *
* 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException]. * 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException].
* 2. This function is symmetric with second [binaryOperation] overload: * 2. This function is symmetric with second [binaryOperationFunction] overload:
* i.e. `binaryOperation(a)(b, c) == binaryOperation(a, b, c)`. * i.e. `binaryOperationFunction(a)(b, c) == binaryOperation(a, b, c)`.
* *
* @param operation the name of operation. * @param operation the name of operation.
* @return an operation. * @return an operation.
*/ */
public fun binaryOperation(operation: String): (left: T, right: T) -> T = public fun binaryOperationFunction(operation: String): (left: T, right: T) -> T =
error("Binary operation $operation not defined in $this") error("Binary operation $operation not defined in $this")
/** /**
@ -77,15 +77,15 @@ public interface Algebra<T> {
* This function must follow two properties: * This function must follow two properties:
* *
* 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException]. * 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException].
* 2. This function is symmetric with second [binaryOperation] overload: * 2. This function is symmetric with second [binaryOperationFunction] overload:
* i.e. `binaryOperation(a)(b, c) == binaryOperation(a, b, c)`. * i.e. `binaryOperationFunction(a)(b, c) == binaryOperation(a, b, c)`.
* *
* @param operation the name of operation. * @param operation the name of operation.
* @param left the first argument of operation. * @param left the first argument of operation.
* @param right the second argument of operation. * @param right the second argument of operation.
* @return a result of operation. * @return a result of operation.
*/ */
public fun binaryOperation(operation: String, left: T, right: T): T = binaryOperation(operation)(left, right) public fun binaryOperation(operation: String, left: T, right: T): T = binaryOperationFunction(operation)(left, right)
} }
/** /**
@ -109,13 +109,13 @@ public interface NumericAlgebra<T> : Algebra<T> {
* *
* 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException]. * 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException].
* 2. This function is symmetric with the other [leftSideNumberOperation] overload: * 2. This function is symmetric with the other [leftSideNumberOperation] overload:
* i.e. `leftSideNumberOperation(a)(b, c) == leftSideNumberOperation(a, b)`. * i.e. `leftSideNumberOperationFunction(a)(b, c) == leftSideNumberOperation(a, b)`.
* *
* @param operation the name of operation. * @param operation the name of operation.
* @return an operation. * @return an operation.
*/ */
public fun leftSideNumberOperation(operation: String): (left: Number, right: T) -> T = public fun leftSideNumberOperationFunction(operation: String): (left: Number, right: T) -> T =
{ l, r -> binaryOperation(operation)(number(l), r) } { l, r -> binaryOperationFunction(operation)(number(l), r) }
/** /**
* Dynamically invokes a binary operation with the certain name with numeric first argument. * Dynamically invokes a binary operation with the certain name with numeric first argument.
@ -124,7 +124,7 @@ public interface NumericAlgebra<T> : Algebra<T> {
* *
* 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException]. * 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException].
* 2. This function is symmetric with second [leftSideNumberOperation] overload: * 2. This function is symmetric with second [leftSideNumberOperation] overload:
* i.e. `leftSideNumberOperation(a)(b, c) == leftSideNumberOperation(a, b, c)`. * i.e. `leftSideNumberOperationFunction(a)(b, c) == leftSideNumberOperation(a, b, c)`.
* *
* @param operation the name of operation. * @param operation the name of operation.
* @param left the first argument of operation. * @param left the first argument of operation.
@ -132,7 +132,7 @@ public interface NumericAlgebra<T> : Algebra<T> {
* @return a result of operation. * @return a result of operation.
*/ */
public fun leftSideNumberOperation(operation: String, left: Number, right: T): T = public fun leftSideNumberOperation(operation: String, left: Number, right: T): T =
leftSideNumberOperation(operation)(left, right) leftSideNumberOperationFunction(operation)(left, right)
/** /**
* Dynamically dispatches a binary operation with the certain name with numeric first argument. * Dynamically dispatches a binary operation with the certain name with numeric first argument.
@ -140,14 +140,14 @@ public interface NumericAlgebra<T> : Algebra<T> {
* This function must follow two properties: * This function must follow two properties:
* *
* 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException]. * 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException].
* 2. This function is symmetric with the other [rightSideNumberOperation] overload: * 2. This function is symmetric with the other [rightSideNumberOperationFunction] overload:
* i.e. `rightSideNumberOperation(a)(b, c) == leftSideNumberOperation(a, b, c)`. * i.e. `rightSideNumberOperationFunction(a)(b, c) == leftSideNumberOperation(a, b, c)`.
* *
* @param operation the name of operation. * @param operation the name of operation.
* @return an operation. * @return an operation.
*/ */
public fun rightSideNumberOperation(operation: String): (left: T, right: Number) -> T = public fun rightSideNumberOperationFunction(operation: String): (left: T, right: Number) -> T =
{ l, r -> binaryOperation(operation)(l, number(r)) } { l, r -> binaryOperationFunction(operation)(l, number(r)) }
/** /**
* Dynamically invokes a binary operation with the certain name with numeric second argument. * Dynamically invokes a binary operation with the certain name with numeric second argument.
@ -155,8 +155,8 @@ public interface NumericAlgebra<T> : Algebra<T> {
* This function must follow two properties: * This function must follow two properties:
* *
* 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException]. * 1. In case if operation is not defined in the structure, the function throws [kotlin.IllegalStateException].
* 2. This function is symmetric with the other [rightSideNumberOperation] overload: * 2. This function is symmetric with the other [rightSideNumberOperationFunction] overload:
* i.e. `rightSideNumberOperation(a)(b, c) == rightSideNumberOperation(a, b, c)`. * i.e. `rightSideNumberOperationFunction(a)(b, c) == rightSideNumberOperation(a, b, c)`.
* *
* @param operation the name of operation. * @param operation the name of operation.
* @param left the first argument of operation. * @param left the first argument of operation.
@ -164,7 +164,7 @@ public interface NumericAlgebra<T> : Algebra<T> {
* @return a result of operation. * @return a result of operation.
*/ */
public fun rightSideNumberOperation(operation: String, left: T, right: Number): T = public fun rightSideNumberOperation(operation: String, left: T, right: Number): T =
rightSideNumberOperation(operation)(left, right) rightSideNumberOperationFunction(operation)(left, right)
} }
/** /**
@ -261,16 +261,16 @@ public interface SpaceOperations<T> : Algebra<T> {
*/ */
public operator fun Number.times(b: T): T = b * this public operator fun Number.times(b: T): T = b * this
public override fun unaryOperation(operation: String): (arg: T) -> T = when (operation) { public override fun unaryOperationFunction(operation: String): (arg: T) -> T = when (operation) {
PLUS_OPERATION -> { arg -> arg } PLUS_OPERATION -> { arg -> arg }
MINUS_OPERATION -> { arg -> -arg } MINUS_OPERATION -> { arg -> -arg }
else -> super.unaryOperation(operation) else -> super.unaryOperationFunction(operation)
} }
public override fun binaryOperation(operation: String): (left: T, right: T) -> T = when (operation) { public override fun binaryOperationFunction(operation: String): (left: T, right: T) -> T = when (operation) {
PLUS_OPERATION -> ::add PLUS_OPERATION -> ::add
MINUS_OPERATION -> { left, right -> left - right } MINUS_OPERATION -> { left, right -> left - right }
else -> super.binaryOperation(operation) else -> super.binaryOperationFunction(operation)
} }
public companion object { public companion object {
@ -322,9 +322,9 @@ public interface RingOperations<T> : SpaceOperations<T> {
*/ */
public operator fun T.times(b: T): T = multiply(this, b) public operator fun T.times(b: T): T = multiply(this, b)
public override fun binaryOperation(operation: String): (left: T, right: T) -> T = when (operation) { public override fun binaryOperationFunction(operation: String): (left: T, right: T) -> T = when (operation) {
TIMES_OPERATION -> ::multiply TIMES_OPERATION -> ::multiply
else -> super.binaryOperation(operation) else -> super.binaryOperationFunction(operation)
} }
public companion object { public companion object {
@ -409,9 +409,9 @@ public interface FieldOperations<T> : RingOperations<T> {
*/ */
public operator fun T.div(b: T): T = divide(this, b) public operator fun T.div(b: T): T = divide(this, b)
public override fun binaryOperation(operation: String): (left: T, right: T) -> T = when (operation) { public override fun binaryOperationFunction(operation: String): (left: T, right: T) -> T = when (operation) {
DIV_OPERATION -> ::divide DIV_OPERATION -> ::divide
else -> super.binaryOperation(operation) else -> super.binaryOperationFunction(operation)
} }
public companion object { public companion object {

View File

@ -14,7 +14,7 @@ public interface ExtendedFieldOperations<T> :
public override fun tan(arg: T): T = sin(arg) / cos(arg) public override fun tan(arg: T): T = sin(arg) / cos(arg)
public override fun tanh(arg: T): T = sinh(arg) / cosh(arg) public override fun tanh(arg: T): T = sinh(arg) / cosh(arg)
public override fun unaryOperation(operation: String): (arg: T) -> T = when (operation) { public override fun unaryOperationFunction(operation: String): (arg: T) -> T = when (operation) {
TrigonometricOperations.COS_OPERATION -> ::cos TrigonometricOperations.COS_OPERATION -> ::cos
TrigonometricOperations.SIN_OPERATION -> ::sin TrigonometricOperations.SIN_OPERATION -> ::sin
TrigonometricOperations.TAN_OPERATION -> ::tan TrigonometricOperations.TAN_OPERATION -> ::tan
@ -30,7 +30,7 @@ public interface ExtendedFieldOperations<T> :
PowerOperations.SQRT_OPERATION -> ::sqrt PowerOperations.SQRT_OPERATION -> ::sqrt
ExponentialOperations.EXP_OPERATION -> ::exp ExponentialOperations.EXP_OPERATION -> ::exp
ExponentialOperations.LN_OPERATION -> ::ln ExponentialOperations.LN_OPERATION -> ::ln
else -> super<FieldOperations>.unaryOperation(operation) else -> super<FieldOperations>.unaryOperationFunction(operation)
} }
} }
@ -45,10 +45,10 @@ public interface ExtendedField<T> : ExtendedFieldOperations<T>, Field<T> {
public override fun acosh(arg: T): T = ln(arg + sqrt((arg - one) * (arg + one))) public override fun acosh(arg: T): T = ln(arg + sqrt((arg - one) * (arg + one)))
public override fun atanh(arg: T): T = (ln(arg + one) - ln(one - arg)) / 2 public override fun atanh(arg: T): T = (ln(arg + one) - ln(one - arg)) / 2
public override fun rightSideNumberOperation(operation: String): (left: T, right: Number) -> T = public override fun rightSideNumberOperationFunction(operation: String): (left: T, right: Number) -> T =
when (operation) { when (operation) {
PowerOperations.POW_OPERATION -> ::power PowerOperations.POW_OPERATION -> ::power
else -> super.rightSideNumberOperation(operation) else -> super.rightSideNumberOperationFunction(operation)
} }
} }
@ -80,10 +80,10 @@ public object RealField : ExtendedField<Double>, Norm<Double, Double> {
public override val one: Double public override val one: Double
get() = 1.0 get() = 1.0
public override fun binaryOperation(operation: String): (left: Double, right: Double) -> Double = public override fun binaryOperationFunction(operation: String): (left: Double, right: Double) -> Double =
when (operation) { when (operation) {
PowerOperations.POW_OPERATION -> ::power PowerOperations.POW_OPERATION -> ::power
else -> super.binaryOperation(operation) else -> super.binaryOperationFunction(operation)
} }
public override inline fun add(a: Double, b: Double): Double = a + b public override inline fun add(a: Double, b: Double): Double = a + b
@ -131,9 +131,9 @@ public object FloatField : ExtendedField<Float>, Norm<Float, Float> {
public override val one: Float public override val one: Float
get() = 1.0f get() = 1.0f
public override fun binaryOperation(operation: String): (left: Float, right: Float) -> Float = when (operation) { public override fun binaryOperationFunction(operation: String): (left: Float, right: Float) -> Float = when (operation) {
PowerOperations.POW_OPERATION -> ::power PowerOperations.POW_OPERATION -> ::power
else -> super.binaryOperation(operation) else -> super.binaryOperationFunction(operation)
} }
public override inline fun add(a: Float, b: Float): Float = a + b public override inline fun add(a: Float, b: Float): Float = a + b