Merge pull request #293 from mipt-npm/commandertvis/ast-stability

Promote kmath-ast as experimental, mark AST Rendering and WASM with @UnstableKMathAPI
This commit is contained in:
Alexander Nozik 2021-04-28 08:59:54 +03:00 committed by GitHub
commit 0f786e4f6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 259 additions and 100 deletions

View File

@ -18,6 +18,10 @@ kotlin.js {
} }
kotlin.sourceSets { kotlin.sourceSets {
filter { it.name.contains("test", true) }
.map(org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet::languageSettings)
.forEach { it.useExperimentalAnnotation("space.kscience.kmath.misc.UnstableKMathAPI") }
commonMain { commonMain {
dependencies { dependencies {
api("com.github.h0tk3y.betterParse:better-parse:0.4.2") api("com.github.h0tk3y.betterParse:better-parse:0.4.2")
@ -54,7 +58,7 @@ tasks.dokkaHtml {
} }
readme { readme {
maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL
propertyByTemplate("artifact", rootProject.file("docs/templates/ARTIFACT-TEMPLATE.md")) propertyByTemplate("artifact", rootProject.file("docs/templates/ARTIFACT-TEMPLATE.md"))
feature( feature(

View File

@ -29,7 +29,6 @@ import space.kscience.kmath.operations.RingOperations
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
public object ArithmeticsEvaluator : Grammar<MST>() { public object ArithmeticsEvaluator : Grammar<MST>() {
// TODO replace with "...".toRegex() when better-parse 0.4.1 is released
private val num: Token by regexToken("[\\d.]+(?:[eE][-+]?\\d+)?".toRegex()) private val num: Token by regexToken("[\\d.]+(?:[eE][-+]?\\d+)?".toRegex())
private val id: Token by regexToken("[a-z_A-Z][\\da-z_A-Z]*".toRegex()) private val id: Token by regexToken("[a-z_A-Z][\\da-z_A-Z]*".toRegex())
private val lpar: Token by literalToken("(") private val lpar: Token by literalToken("(")

View File

@ -5,6 +5,8 @@
package space.kscience.kmath.ast.rendering package space.kscience.kmath.ast.rendering
import space.kscience.kmath.misc.UnstableKMathAPI
/** /**
* [SyntaxRenderer] implementation for LaTeX. * [SyntaxRenderer] implementation for LaTeX.
* *
@ -23,6 +25,7 @@ package space.kscience.kmath.ast.rendering
* *
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public object LatexSyntaxRenderer : SyntaxRenderer { public object LatexSyntaxRenderer : SyntaxRenderer {
public override fun render(node: MathSyntax, output: Appendable): Unit = output.run { public override fun render(node: MathSyntax, output: Appendable): Unit = output.run {
fun render(syntax: MathSyntax) = render(syntax, output) fun render(syntax: MathSyntax) = render(syntax, output)

View File

@ -5,6 +5,8 @@
package space.kscience.kmath.ast.rendering package space.kscience.kmath.ast.rendering
import space.kscience.kmath.misc.UnstableKMathAPI
/** /**
* [SyntaxRenderer] implementation for MathML. * [SyntaxRenderer] implementation for MathML.
* *
@ -12,9 +14,10 @@ package space.kscience.kmath.ast.rendering
* *
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public object MathMLSyntaxRenderer : SyntaxRenderer { public object MathMLSyntaxRenderer : SyntaxRenderer {
public override fun render(node: MathSyntax, output: Appendable) { public override fun render(node: MathSyntax, output: Appendable) {
output.append("<math xmlns=\"http://www.w3.org/1998/Math/MathML\"><mrow>") output.append("<math xmlns=\"https://www.w3.org/1998/Math/MathML\"><mrow>")
render0(node, output) render0(node, output)
output.append("</mrow></math>") output.append("</mrow></math>")
} }

View File

@ -6,12 +6,14 @@
package space.kscience.kmath.ast.rendering package space.kscience.kmath.ast.rendering
import space.kscience.kmath.expressions.MST import space.kscience.kmath.expressions.MST
import space.kscience.kmath.misc.UnstableKMathAPI
/** /**
* Renders [MST] to [MathSyntax]. * Renders [MST] to [MathSyntax].
* *
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public fun interface MathRenderer { public fun interface MathRenderer {
/** /**
* Renders [MST] to [MathSyntax]. * Renders [MST] to [MathSyntax].
@ -25,6 +27,7 @@ public fun interface MathRenderer {
* @property features The applied features. * @property features The applied features.
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public open class FeaturedMathRenderer(public val features: List<RenderFeature>) : MathRenderer { public open class FeaturedMathRenderer(public val features: List<RenderFeature>) : MathRenderer {
public override fun render(mst: MST): MathSyntax { public override fun render(mst: MST): MathSyntax {
for (feature in features) feature.render(this, mst)?.let { return it } for (feature in features) feature.render(this, mst)?.let { return it }
@ -48,6 +51,7 @@ public open class FeaturedMathRenderer(public val features: List<RenderFeature>)
* @property stages The applied stages. * @property stages The applied stages.
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public open class FeaturedMathRendererWithPostProcess( public open class FeaturedMathRendererWithPostProcess(
features: List<RenderFeature>, features: List<RenderFeature>,
public val stages: List<PostProcessStage>, public val stages: List<PostProcessStage>,

View File

@ -5,11 +5,14 @@
package space.kscience.kmath.ast.rendering package space.kscience.kmath.ast.rendering
import space.kscience.kmath.misc.UnstableKMathAPI
/** /**
* Mathematical typography syntax node. * Mathematical typography syntax node.
* *
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public sealed class MathSyntax { public sealed class MathSyntax {
/** /**
* The parent node of this syntax node. * The parent node of this syntax node.
@ -22,6 +25,7 @@ public sealed class MathSyntax {
* *
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public sealed class TerminalSyntax : MathSyntax() public sealed class TerminalSyntax : MathSyntax()
/** /**
@ -29,6 +33,7 @@ public sealed class TerminalSyntax : MathSyntax()
* *
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public sealed class OperationSyntax : MathSyntax() { public sealed class OperationSyntax : MathSyntax() {
/** /**
* The operation token. * The operation token.
@ -41,6 +46,7 @@ public sealed class OperationSyntax : MathSyntax() {
* *
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public sealed class UnarySyntax : OperationSyntax() { public sealed class UnarySyntax : OperationSyntax() {
/** /**
* The operand of this node. * The operand of this node.
@ -53,6 +59,7 @@ public sealed class UnarySyntax : OperationSyntax() {
* *
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public sealed class BinarySyntax : OperationSyntax() { public sealed class BinarySyntax : OperationSyntax() {
/** /**
* The left-hand side operand. * The left-hand side operand.
@ -71,6 +78,7 @@ public sealed class BinarySyntax : OperationSyntax() {
* @property string The digits of number. * @property string The digits of number.
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public data class NumberSyntax(public var string: String) : TerminalSyntax() public data class NumberSyntax(public var string: String) : TerminalSyntax()
/** /**
@ -79,6 +87,7 @@ public data class NumberSyntax(public var string: String) : TerminalSyntax()
* @property string The symbol. * @property string The symbol.
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public data class SymbolSyntax(public var string: String) : TerminalSyntax() public data class SymbolSyntax(public var string: String) : TerminalSyntax()
/** /**
@ -89,6 +98,7 @@ public data class SymbolSyntax(public var string: String) : TerminalSyntax()
* @see UnaryOperatorSyntax * @see UnaryOperatorSyntax
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public data class OperatorNameSyntax(public var name: String) : TerminalSyntax() public data class OperatorNameSyntax(public var name: String) : TerminalSyntax()
/** /**
@ -97,6 +107,7 @@ public data class OperatorNameSyntax(public var name: String) : TerminalSyntax()
* @property kind The kind of symbol. * @property kind The kind of symbol.
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public data class SpecialSymbolSyntax(public var kind: Kind) : TerminalSyntax() { public data class SpecialSymbolSyntax(public var kind: Kind) : TerminalSyntax() {
/** /**
* The kind of symbol. * The kind of symbol.
@ -121,6 +132,7 @@ public data class SpecialSymbolSyntax(public var kind: Kind) : TerminalSyntax()
* @property parentheses Whether the operand should be wrapped with parentheses. * @property parentheses Whether the operand should be wrapped with parentheses.
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public data class OperandSyntax( public data class OperandSyntax(
public val operand: MathSyntax, public val operand: MathSyntax,
public var parentheses: Boolean, public var parentheses: Boolean,
@ -136,6 +148,7 @@ public data class OperandSyntax(
* @property prefix The prefix. * @property prefix The prefix.
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public data class UnaryOperatorSyntax( public data class UnaryOperatorSyntax(
public override val operation: String, public override val operation: String,
public var prefix: MathSyntax, public var prefix: MathSyntax,
@ -151,6 +164,7 @@ public data class UnaryOperatorSyntax(
* *
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public data class UnaryPlusSyntax( public data class UnaryPlusSyntax(
public override val operation: String, public override val operation: String,
public override val operand: OperandSyntax, public override val operand: OperandSyntax,
@ -165,6 +179,7 @@ public data class UnaryPlusSyntax(
* *
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public data class UnaryMinusSyntax( public data class UnaryMinusSyntax(
public override val operation: String, public override val operation: String,
public override val operand: OperandSyntax, public override val operand: OperandSyntax,
@ -180,6 +195,7 @@ public data class UnaryMinusSyntax(
* @property operand The radicand. * @property operand The radicand.
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public data class RadicalSyntax( public data class RadicalSyntax(
public override val operation: String, public override val operation: String,
public override val operand: MathSyntax, public override val operand: MathSyntax,
@ -197,6 +213,7 @@ public data class RadicalSyntax(
* (*e<sup>x</sup>*). * (*e<sup>x</sup>*).
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public data class ExponentSyntax( public data class ExponentSyntax(
public override val operation: String, public override val operation: String,
public override val operand: OperandSyntax, public override val operand: OperandSyntax,
@ -214,6 +231,7 @@ public data class ExponentSyntax(
* @property right The superscript. * @property right The superscript.
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public data class SuperscriptSyntax( public data class SuperscriptSyntax(
public override val operation: String, public override val operation: String,
public override val left: MathSyntax, public override val left: MathSyntax,
@ -232,6 +250,7 @@ public data class SuperscriptSyntax(
* @property right The subscript. * @property right The subscript.
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public data class SubscriptSyntax( public data class SubscriptSyntax(
public override val operation: String, public override val operation: String,
public override val left: MathSyntax, public override val left: MathSyntax,
@ -249,6 +268,7 @@ public data class SubscriptSyntax(
* @property prefix The prefix. * @property prefix The prefix.
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public data class BinaryOperatorSyntax( public data class BinaryOperatorSyntax(
public override val operation: String, public override val operation: String,
public var prefix: MathSyntax, public var prefix: MathSyntax,
@ -268,6 +288,7 @@ public data class BinaryOperatorSyntax(
* @param right The addend. * @param right The addend.
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public data class BinaryPlusSyntax( public data class BinaryPlusSyntax(
public override val operation: String, public override val operation: String,
public override val left: OperandSyntax, public override val left: OperandSyntax,
@ -286,6 +307,7 @@ public data class BinaryPlusSyntax(
* @param right The subtrahend. * @param right The subtrahend.
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public data class BinaryMinusSyntax( public data class BinaryMinusSyntax(
public override val operation: String, public override val operation: String,
public override val left: OperandSyntax, public override val left: OperandSyntax,
@ -304,6 +326,7 @@ public data class BinaryMinusSyntax(
* @property right The denominator. * @property right The denominator.
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public data class FractionSyntax( public data class FractionSyntax(
public override val operation: String, public override val operation: String,
public override val left: MathSyntax, public override val left: MathSyntax,
@ -322,6 +345,7 @@ public data class FractionSyntax(
* @property right The radicand. * @property right The radicand.
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public data class RadicalWithIndexSyntax( public data class RadicalWithIndexSyntax(
public override val operation: String, public override val operation: String,
public override val left: MathSyntax, public override val left: MathSyntax,
@ -341,6 +365,7 @@ public data class RadicalWithIndexSyntax(
* @property times whether the times (&times;) symbol should be used. * @property times whether the times (&times;) symbol should be used.
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public data class MultiplicationSyntax( public data class MultiplicationSyntax(
public override val operation: String, public override val operation: String,
public override val left: OperandSyntax, public override val left: OperandSyntax,

View File

@ -5,12 +5,15 @@
package space.kscience.kmath.ast.rendering package space.kscience.kmath.ast.rendering
import space.kscience.kmath.misc.UnstableKMathAPI
/** /**
* Abstraction of writing [MathSyntax] as a string of an actual markup language. Typical implementation should * Abstraction of writing [MathSyntax] as a string of an actual markup language. Typical implementation should
* involve traversal of MathSyntax with handling each its subtype. * involve traversal of MathSyntax with handling each its subtype.
* *
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public fun interface SyntaxRenderer { public fun interface SyntaxRenderer {
/** /**
* Renders the [MathSyntax] to [output]. * Renders the [MathSyntax] to [output].
@ -23,6 +26,7 @@ public fun interface SyntaxRenderer {
* *
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public fun SyntaxRenderer.renderWithStringBuilder(node: MathSyntax): String { public fun SyntaxRenderer.renderWithStringBuilder(node: MathSyntax): String {
val sb = StringBuilder() val sb = StringBuilder()
render(node, sb) render(node, sb)

View File

@ -7,6 +7,7 @@ package space.kscience.kmath.ast.rendering
import space.kscience.kmath.ast.rendering.FeaturedMathRenderer.RenderFeature import space.kscience.kmath.ast.rendering.FeaturedMathRenderer.RenderFeature
import space.kscience.kmath.expressions.MST import space.kscience.kmath.expressions.MST
import space.kscience.kmath.misc.UnstableKMathAPI
import space.kscience.kmath.operations.* import space.kscience.kmath.operations.*
import kotlin.reflect.KClass import kotlin.reflect.KClass
@ -15,11 +16,12 @@ import kotlin.reflect.KClass
* *
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public object PrintSymbolic : RenderFeature { public object PrintSymbolic : RenderFeature {
public override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? { public override fun render(renderer: FeaturedMathRenderer, node: MST): SymbolSyntax? =
if (node !is MST.Symbolic) return null if (node !is MST.Symbolic) null
return SymbolSyntax(string = node.value) else
} SymbolSyntax(string = node.value)
} }
/** /**
@ -27,25 +29,25 @@ public object PrintSymbolic : RenderFeature {
* *
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public object PrintNumeric : RenderFeature { public object PrintNumeric : RenderFeature {
public override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? { public override fun render(renderer: FeaturedMathRenderer, node: MST): NumberSyntax? = if (node !is MST.Numeric)
if (node !is MST.Numeric) return null null
return NumberSyntax(string = node.value.toString()) else
} NumberSyntax(string = node.value.toString())
} }
private fun printSignedNumberString(s: String): MathSyntax { @UnstableKMathAPI
if (s.startsWith('-')) private fun printSignedNumberString(s: String): MathSyntax = if (s.startsWith('-'))
return UnaryMinusSyntax( UnaryMinusSyntax(
operation = GroupOperations.MINUS_OPERATION, operation = GroupOperations.MINUS_OPERATION,
operand = OperandSyntax( operand = OperandSyntax(
operand = NumberSyntax(string = s.removePrefix("-")), operand = NumberSyntax(string = s.removePrefix("-")),
parentheses = true, parentheses = true,
), ),
) )
else
return NumberSyntax(string = s) NumberSyntax(string = s)
}
/** /**
* Special printing for numeric types which are printed in form of * Special printing for numeric types which are printed in form of
@ -53,9 +55,11 @@ private fun printSignedNumberString(s: String): MathSyntax {
* *
* @property types The suitable types. * @property types The suitable types.
*/ */
@UnstableKMathAPI
public class PrettyPrintFloats(public val types: Set<KClass<out Number>>) : RenderFeature { public class PrettyPrintFloats(public val types: Set<KClass<out Number>>) : RenderFeature {
public override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? { public override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? {
if (node !is MST.Numeric || node.value::class !in types) return null if (node !is MST.Numeric || node.value::class !in types) return null
val toString = when (val v = node.value) { val toString = when (val v = node.value) {
is Float -> v.multiplatformToString() is Float -> v.multiplatformToString()
is Double -> v.multiplatformToString() is Double -> v.multiplatformToString()
@ -110,11 +114,13 @@ public class PrettyPrintFloats(public val types: Set<KClass<out Number>>) : Rend
* *
* @property types The suitable types. * @property types The suitable types.
*/ */
@UnstableKMathAPI
public class PrettyPrintIntegers(public val types: Set<KClass<out Number>>) : RenderFeature { public class PrettyPrintIntegers(public val types: Set<KClass<out Number>>) : RenderFeature {
public override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? { public override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? =
if (node !is MST.Numeric || node.value::class !in types) return null if (node !is MST.Numeric || node.value::class !in types)
return printSignedNumberString(node.value.toString()) null
} else
printSignedNumberString(node.value.toString())
public companion object { public companion object {
/** /**
@ -130,11 +136,13 @@ public class PrettyPrintIntegers(public val types: Set<KClass<out Number>>) : Re
* *
* @property symbols The allowed symbols. * @property symbols The allowed symbols.
*/ */
@UnstableKMathAPI
public class PrettyPrintPi(public val symbols: Set<String>) : RenderFeature { public class PrettyPrintPi(public val symbols: Set<String>) : RenderFeature {
public override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? { public override fun render(renderer: FeaturedMathRenderer, node: MST): SpecialSymbolSyntax? =
if (node !is MST.Symbolic || node.value !in symbols) return null if (node !is MST.Symbolic || node.value !in symbols)
return SpecialSymbolSyntax(kind = SpecialSymbolSyntax.Kind.SMALL_PI) null
} else
SpecialSymbolSyntax(kind = SpecialSymbolSyntax.Kind.SMALL_PI)
public companion object { public companion object {
/** /**
@ -150,16 +158,18 @@ public class PrettyPrintPi(public val symbols: Set<String>) : RenderFeature {
* *
* @param operations the allowed operations. If `null`, any operation is accepted. * @param operations the allowed operations. If `null`, any operation is accepted.
*/ */
@UnstableKMathAPI
public abstract class Unary(public val operations: Collection<String>?) : RenderFeature { public abstract class Unary(public val operations: Collection<String>?) : RenderFeature {
/** /**
* The actual render function. * The actual render function specialized for [MST.Unary].
*/ */
protected abstract fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax? protected abstract fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax?
public final override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? { public final override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? =
if (node !is MST.Unary || operations != null && node.operation !in operations) return null if (node !is MST.Unary || operations != null && node.operation !in operations)
return render0(renderer, node) null
} else
renderUnary(renderer, node)
} }
/** /**
@ -168,78 +178,121 @@ public abstract class Unary(public val operations: Collection<String>?) : Render
* *
* @property operations the allowed operations. If `null`, any operation is accepted. * @property operations the allowed operations. If `null`, any operation is accepted.
*/ */
@UnstableKMathAPI
public abstract class Binary(public val operations: Collection<String>?) : RenderFeature { public abstract class Binary(public val operations: Collection<String>?) : RenderFeature {
/** /**
* The actual render function. * The actual render function specialized for [MST.Binary].
*/ */
protected abstract fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax? protected abstract fun renderBinary(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax?
public final override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? { public final override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? {
if (node !is MST.Binary || operations != null && node.operation !in operations) return null if (node !is MST.Binary || operations != null && node.operation !in operations) return null
return render0(renderer, node) return renderBinary(renderer, node)
} }
} }
/**
* Handles binary nodes by producing [BinaryPlusSyntax].
*/
@UnstableKMathAPI
public class BinaryPlus(operations: Collection<String>?) : Binary(operations) { public class BinaryPlus(operations: Collection<String>?) : Binary(operations) {
public override fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax = BinaryPlusSyntax( public override fun renderBinary(parent: FeaturedMathRenderer, node: MST.Binary): BinaryPlusSyntax =
BinaryPlusSyntax(
operation = node.operation, operation = node.operation,
left = OperandSyntax(parent.render(node.left), true), left = OperandSyntax(parent.render(node.left), true),
right = OperandSyntax(parent.render(node.right), true), right = OperandSyntax(parent.render(node.right), true),
) )
public companion object { public companion object {
/**
* The default instance configured with [GroupOperations.PLUS_OPERATION].
*/
public val Default: BinaryPlus = BinaryPlus(setOf(GroupOperations.PLUS_OPERATION)) public val Default: BinaryPlus = BinaryPlus(setOf(GroupOperations.PLUS_OPERATION))
} }
} }
/**
* Handles binary nodes by producing [BinaryMinusSyntax].
*/
@UnstableKMathAPI
public class BinaryMinus(operations: Collection<String>?) : Binary(operations) { public class BinaryMinus(operations: Collection<String>?) : Binary(operations) {
public override fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax = BinaryMinusSyntax( public override fun renderBinary(parent: FeaturedMathRenderer, node: MST.Binary): BinaryMinusSyntax =
BinaryMinusSyntax(
operation = node.operation, operation = node.operation,
left = OperandSyntax(operand = parent.render(node.left), parentheses = true), left = OperandSyntax(operand = parent.render(node.left), parentheses = true),
right = OperandSyntax(operand = parent.render(node.right), parentheses = true), right = OperandSyntax(operand = parent.render(node.right), parentheses = true),
) )
public companion object { public companion object {
/**
* The default instance configured with [GroupOperations.MINUS_OPERATION].
*/
public val Default: BinaryMinus = BinaryMinus(setOf(GroupOperations.MINUS_OPERATION)) public val Default: BinaryMinus = BinaryMinus(setOf(GroupOperations.MINUS_OPERATION))
} }
} }
/**
* Handles unary nodes by producing [UnaryPlusSyntax].
*/
@UnstableKMathAPI
public class UnaryPlus(operations: Collection<String>?) : Unary(operations) { public class UnaryPlus(operations: Collection<String>?) : Unary(operations) {
public override fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax = UnaryPlusSyntax( public override fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): UnaryPlusSyntax = UnaryPlusSyntax(
operation = node.operation, operation = node.operation,
operand = OperandSyntax(operand = parent.render(node.value), parentheses = true), operand = OperandSyntax(operand = parent.render(node.value), parentheses = true),
) )
public companion object { public companion object {
/**
* The default instance configured with [GroupOperations.PLUS_OPERATION].
*/
public val Default: UnaryPlus = UnaryPlus(setOf(GroupOperations.PLUS_OPERATION)) public val Default: UnaryPlus = UnaryPlus(setOf(GroupOperations.PLUS_OPERATION))
} }
} }
/**
* Handles binary nodes by producing [UnaryMinusSyntax].
*/
@UnstableKMathAPI
public class UnaryMinus(operations: Collection<String>?) : Unary(operations) { public class UnaryMinus(operations: Collection<String>?) : Unary(operations) {
public override fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax = UnaryMinusSyntax( public override fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): UnaryMinusSyntax = UnaryMinusSyntax(
operation = node.operation, operation = node.operation,
operand = OperandSyntax(operand = parent.render(node.value), parentheses = true), operand = OperandSyntax(operand = parent.render(node.value), parentheses = true),
) )
public companion object { public companion object {
/**
* The default instance configured with [GroupOperations.MINUS_OPERATION].
*/
public val Default: UnaryMinus = UnaryMinus(setOf(GroupOperations.MINUS_OPERATION)) public val Default: UnaryMinus = UnaryMinus(setOf(GroupOperations.MINUS_OPERATION))
} }
} }
/**
* Handles binary nodes by producing [FractionSyntax].
*/
@UnstableKMathAPI
public class Fraction(operations: Collection<String>?) : Binary(operations) { public class Fraction(operations: Collection<String>?) : Binary(operations) {
public override fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax = FractionSyntax( public override fun renderBinary(parent: FeaturedMathRenderer, node: MST.Binary): FractionSyntax = FractionSyntax(
operation = node.operation, operation = node.operation,
left = parent.render(node.left), left = parent.render(node.left),
right = parent.render(node.right), right = parent.render(node.right),
) )
public companion object { public companion object {
/**
* The default instance configured with [FieldOperations.DIV_OPERATION].
*/
public val Default: Fraction = Fraction(setOf(FieldOperations.DIV_OPERATION)) public val Default: Fraction = Fraction(setOf(FieldOperations.DIV_OPERATION))
} }
} }
/**
* Handles binary nodes by producing [BinaryOperatorSyntax].
*/
@UnstableKMathAPI
public class BinaryOperator(operations: Collection<String>?) : Binary(operations) { public class BinaryOperator(operations: Collection<String>?) : Binary(operations) {
public override fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax = BinaryOperatorSyntax( public override fun renderBinary(parent: FeaturedMathRenderer, node: MST.Binary): BinaryOperatorSyntax =
BinaryOperatorSyntax(
operation = node.operation, operation = node.operation,
prefix = OperatorNameSyntax(name = node.operation), prefix = OperatorNameSyntax(name = node.operation),
left = parent.render(node.left), left = parent.render(node.left),
@ -247,57 +300,95 @@ public class BinaryOperator(operations: Collection<String>?) : Binary(operations
) )
public companion object { public companion object {
/**
* The default instance configured with `null`.
*/
public val Default: BinaryOperator = BinaryOperator(null) public val Default: BinaryOperator = BinaryOperator(null)
} }
} }
/**
* Handles unary nodes by producing [UnaryOperatorSyntax].
*/
@UnstableKMathAPI
public class UnaryOperator(operations: Collection<String>?) : Unary(operations) { public class UnaryOperator(operations: Collection<String>?) : Unary(operations) {
public override fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax = UnaryOperatorSyntax( public override fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): UnaryOperatorSyntax =
UnaryOperatorSyntax(
operation = node.operation, operation = node.operation,
prefix = OperatorNameSyntax(node.operation), prefix = OperatorNameSyntax(node.operation),
operand = OperandSyntax(parent.render(node.value), true), operand = OperandSyntax(parent.render(node.value), true),
) )
public companion object { public companion object {
/**
* The default instance configured with `null`.
*/
public val Default: UnaryOperator = UnaryOperator(null) public val Default: UnaryOperator = UnaryOperator(null)
} }
} }
/**
* Handles binary nodes by producing [SuperscriptSyntax].
*/
@UnstableKMathAPI
public class Power(operations: Collection<String>?) : Binary(operations) { public class Power(operations: Collection<String>?) : Binary(operations) {
public override fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax = SuperscriptSyntax( public override fun renderBinary(parent: FeaturedMathRenderer, node: MST.Binary): SuperscriptSyntax =
SuperscriptSyntax(
operation = node.operation, operation = node.operation,
left = OperandSyntax(parent.render(node.left), true), left = OperandSyntax(parent.render(node.left), true),
right = OperandSyntax(parent.render(node.right), true), right = OperandSyntax(parent.render(node.right), true),
) )
public companion object { public companion object {
/**
* The default instance configured with [PowerOperations.POW_OPERATION].
*/
public val Default: Power = Power(setOf(PowerOperations.POW_OPERATION)) public val Default: Power = Power(setOf(PowerOperations.POW_OPERATION))
} }
} }
/**
* Handles binary nodes by producing [RadicalSyntax] with no index.
*/
@UnstableKMathAPI
public class SquareRoot(operations: Collection<String>?) : Unary(operations) { public class SquareRoot(operations: Collection<String>?) : Unary(operations) {
public override fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax = public override fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): RadicalSyntax =
RadicalSyntax(operation = node.operation, operand = parent.render(node.value)) RadicalSyntax(operation = node.operation, operand = parent.render(node.value))
public companion object { public companion object {
/**
* The default instance configured with [PowerOperations.SQRT_OPERATION].
*/
public val Default: SquareRoot = SquareRoot(setOf(PowerOperations.SQRT_OPERATION)) public val Default: SquareRoot = SquareRoot(setOf(PowerOperations.SQRT_OPERATION))
} }
} }
/**
* Handles unary nodes by producing [ExponentSyntax].
*/
@UnstableKMathAPI
public class Exponent(operations: Collection<String>?) : Unary(operations) { public class Exponent(operations: Collection<String>?) : Unary(operations) {
public override fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax = ExponentSyntax( public override fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): ExponentSyntax = ExponentSyntax(
operation = node.operation, operation = node.operation,
operand = OperandSyntax(operand = parent.render(node.value), parentheses = true), operand = OperandSyntax(operand = parent.render(node.value), parentheses = true),
useOperatorForm = true, useOperatorForm = true,
) )
public companion object { public companion object {
/**
* The default instance configured with [ExponentialOperations.EXP_OPERATION].
*/
public val Default: Exponent = Exponent(setOf(ExponentialOperations.EXP_OPERATION)) public val Default: Exponent = Exponent(setOf(ExponentialOperations.EXP_OPERATION))
} }
} }
/**
* Handles binary nodes by producing [MultiplicationSyntax].
*/
@UnstableKMathAPI
public class Multiplication(operations: Collection<String>?) : Binary(operations) { public class Multiplication(operations: Collection<String>?) : Binary(operations) {
public override fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax = MultiplicationSyntax( public override fun renderBinary(parent: FeaturedMathRenderer, node: MST.Binary): MultiplicationSyntax =
MultiplicationSyntax(
operation = node.operation, operation = node.operation,
left = OperandSyntax(operand = parent.render(node.left), parentheses = true), left = OperandSyntax(operand = parent.render(node.left), parentheses = true),
right = OperandSyntax(operand = parent.render(node.right), parentheses = true), right = OperandSyntax(operand = parent.render(node.right), parentheses = true),
@ -305,14 +396,21 @@ public class Multiplication(operations: Collection<String>?) : Binary(operations
) )
public companion object { public companion object {
public val Default: Multiplication = Multiplication(setOf( /**
RingOperations.TIMES_OPERATION, * The default instance configured with [RingOperations.TIMES_OPERATION].
)) */
public val Default: Multiplication = Multiplication(setOf(RingOperations.TIMES_OPERATION))
} }
} }
/**
* Handles binary nodes by producing inverse [UnaryOperatorSyntax] (like *sin<sup>-1</sup>*) with removing the `a`
* prefix of operation ID.
*/
@UnstableKMathAPI
public class InverseTrigonometricOperations(operations: Collection<String>?) : Unary(operations) { public class InverseTrigonometricOperations(operations: Collection<String>?) : Unary(operations) {
public override fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax = UnaryOperatorSyntax( public override fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): UnaryOperatorSyntax =
UnaryOperatorSyntax(
operation = node.operation, operation = node.operation,
prefix = SuperscriptSyntax( prefix = SuperscriptSyntax(
operation = PowerOperations.POW_OPERATION, operation = PowerOperations.POW_OPERATION,
@ -326,6 +424,12 @@ public class InverseTrigonometricOperations(operations: Collection<String>?) : U
) )
public companion object { public companion object {
/**
* The default instance configured with [TrigonometricOperations.ACOS_OPERATION],
* [TrigonometricOperations.ASIN_OPERATION], [TrigonometricOperations.ATAN_OPERATION],
* [ExponentialOperations.ACOSH_OPERATION], [ExponentialOperations.ASINH_OPERATION], and
* [ExponentialOperations.ATANH_OPERATION].
*/
public val Default: InverseTrigonometricOperations = InverseTrigonometricOperations(setOf( public val Default: InverseTrigonometricOperations = InverseTrigonometricOperations(setOf(
TrigonometricOperations.ACOS_OPERATION, TrigonometricOperations.ACOS_OPERATION,
TrigonometricOperations.ASIN_OPERATION, TrigonometricOperations.ASIN_OPERATION,

View File

@ -5,6 +5,7 @@
package space.kscience.kmath.ast.rendering package space.kscience.kmath.ast.rendering
import space.kscience.kmath.misc.UnstableKMathAPI
import space.kscience.kmath.operations.FieldOperations import space.kscience.kmath.operations.FieldOperations
import space.kscience.kmath.operations.GroupOperations import space.kscience.kmath.operations.GroupOperations
import space.kscience.kmath.operations.PowerOperations import space.kscience.kmath.operations.PowerOperations
@ -15,6 +16,7 @@ import space.kscience.kmath.operations.RingOperations
* *
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public object BetterMultiplication : FeaturedMathRendererWithPostProcess.PostProcessStage { public object BetterMultiplication : FeaturedMathRendererWithPostProcess.PostProcessStage {
public override fun perform(node: MathSyntax): Unit = when (node) { public override fun perform(node: MathSyntax): Unit = when (node) {
is NumberSyntax -> Unit is NumberSyntax -> Unit
@ -88,6 +90,7 @@ public object BetterMultiplication : FeaturedMathRendererWithPostProcess.PostPro
* *
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public object BetterExponent : FeaturedMathRendererWithPostProcess.PostProcessStage { public object BetterExponent : FeaturedMathRendererWithPostProcess.PostProcessStage {
private fun perform0(node: MathSyntax): Boolean { private fun perform0(node: MathSyntax): Boolean {
return when (node) { return when (node) {
@ -129,6 +132,7 @@ public object BetterExponent : FeaturedMathRendererWithPostProcess.PostProcessSt
* @property precedenceFunction Returns the precedence number for syntax node. Higher number is lower priority. * @property precedenceFunction Returns the precedence number for syntax node. Higher number is lower priority.
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public class SimplifyParentheses(public val precedenceFunction: (MathSyntax) -> Int) : public class SimplifyParentheses(public val precedenceFunction: (MathSyntax) -> Int) :
FeaturedMathRendererWithPostProcess.PostProcessStage { FeaturedMathRendererWithPostProcess.PostProcessStage {
public override fun perform(node: MathSyntax): Unit = when (node) { public override fun perform(node: MathSyntax): Unit = when (node) {

View File

@ -5,7 +5,6 @@
package space.kscience.kmath.ast package space.kscience.kmath.ast
import space.kscience.kmath.ast.parseMath
import space.kscience.kmath.expressions.evaluate import space.kscience.kmath.expressions.evaluate
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.DoubleField
import kotlin.test.Test import kotlin.test.Test

View File

@ -30,17 +30,17 @@ internal object TestUtils {
) )
internal fun testMathML(mst: MST, expectedMathML: String) = assertEquals( internal fun testMathML(mst: MST, expectedMathML: String) = assertEquals(
expected = "<math xmlns=\"http://www.w3.org/1998/Math/MathML\"><mrow>$expectedMathML</mrow></math>", expected = "<math xmlns=\"https://www.w3.org/1998/Math/MathML\"><mrow>$expectedMathML</mrow></math>",
actual = mathML(mst), actual = mathML(mst),
) )
internal fun testMathML(expression: String, expectedMathML: String) = assertEquals( internal fun testMathML(expression: String, expectedMathML: String) = assertEquals(
expected = "<math xmlns=\"http://www.w3.org/1998/Math/MathML\"><mrow>$expectedMathML</mrow></math>", expected = "<math xmlns=\"https://www.w3.org/1998/Math/MathML\"><mrow>$expectedMathML</mrow></math>",
actual = mathML(expression.parseMath()), actual = mathML(expression.parseMath()),
) )
internal fun testMathML(expression: MathSyntax, expectedMathML: String) = assertEquals( internal fun testMathML(expression: MathSyntax, expectedMathML: String) = assertEquals(
expected = "<math xmlns=\"http://www.w3.org/1998/Math/MathML\"><mrow>$expectedMathML</mrow></math>", expected = "<math xmlns=\"https://www.w3.org/1998/Math/MathML\"><mrow>$expectedMathML</mrow></math>",
actual = MathMLSyntaxRenderer.renderWithStringBuilder(expression), actual = MathMLSyntaxRenderer.renderWithStringBuilder(expression),
) )
} }

View File

@ -3,7 +3,8 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@file:Suppress("INTERFACE_WITH_SUPERCLASS", @file:Suppress(
"INTERFACE_WITH_SUPERCLASS",
"OVERRIDING_FINAL_MEMBER", "OVERRIDING_FINAL_MEMBER",
"RETURN_TYPE_MISMATCH_ON_OVERRIDE", "RETURN_TYPE_MISMATCH_ON_OVERRIDE",
"CONFLICTING_OVERLOADS", "CONFLICTING_OVERLOADS",

View File

@ -26,7 +26,7 @@ internal sealed class WasmBuilder<T>(
val keys: MutableList<String> = mutableListOf() val keys: MutableList<String> = mutableListOf()
lateinit var ctx: BinaryenModule lateinit var ctx: BinaryenModule
open fun visitSymbolic(mst: MST.Symbolic): ExpressionRef { open fun visitSymbolic(mst: Symbolic): ExpressionRef {
try { try {
algebra.bindSymbol(mst.value) algebra.bindSymbol(mst.value)
} catch (ignored: Throwable) { } catch (ignored: Throwable) {

View File

@ -10,6 +10,7 @@ import space.kscience.kmath.expressions.Expression
import space.kscience.kmath.expressions.MST import space.kscience.kmath.expressions.MST
import space.kscience.kmath.expressions.invoke import space.kscience.kmath.expressions.invoke
import space.kscience.kmath.misc.Symbol import space.kscience.kmath.misc.Symbol
import space.kscience.kmath.misc.UnstableKMathAPI
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.IntRing import space.kscience.kmath.operations.IntRing
import space.kscience.kmath.wasm.internal.DoubleWasmBuilder import space.kscience.kmath.wasm.internal.DoubleWasmBuilder
@ -20,6 +21,7 @@ import space.kscience.kmath.wasm.internal.IntWasmBuilder
* *
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public fun DoubleField.expression(mst: MST): Expression<Double> = public fun DoubleField.expression(mst: MST): Expression<Double> =
DoubleWasmBuilder(mst).instance DoubleWasmBuilder(mst).instance
@ -28,6 +30,7 @@ public fun DoubleField.expression(mst: MST): Expression<Double> =
* *
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public fun IntRing.expression(mst: MST): Expression<Int> = public fun IntRing.expression(mst: MST): Expression<Int> =
IntWasmBuilder(mst).instance IntWasmBuilder(mst).instance
@ -36,6 +39,7 @@ public fun IntRing.expression(mst: MST): Expression<Int> =
* *
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public fun MST.compileToExpression(algebra: IntRing): Expression<Int> = compileWith(algebra) public fun MST.compileToExpression(algebra: IntRing): Expression<Int> = compileWith(algebra)
@ -44,6 +48,7 @@ public fun MST.compileToExpression(algebra: IntRing): Expression<Int> = compileW
* *
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int = public fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int =
compileToExpression(algebra).invoke(arguments) compileToExpression(algebra).invoke(arguments)
@ -53,6 +58,7 @@ public fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int =
* *
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public fun MST.compile(algebra: IntRing, vararg arguments: Pair<Symbol, Int>): Int = public fun MST.compile(algebra: IntRing, vararg arguments: Pair<Symbol, Int>): Int =
compileToExpression(algebra)(*arguments) compileToExpression(algebra)(*arguments)
@ -61,6 +67,7 @@ public fun MST.compile(algebra: IntRing, vararg arguments: Pair<Symbol, Int>): I
* *
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public fun MST.compileToExpression(algebra: DoubleField): Expression<Double> = compileWith(algebra) public fun MST.compileToExpression(algebra: DoubleField): Expression<Double> = compileWith(algebra)
@ -69,6 +76,7 @@ public fun MST.compileToExpression(algebra: DoubleField): Expression<Double> = c
* *
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Double = public fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Double =
compileToExpression(algebra).invoke(arguments) compileToExpression(algebra).invoke(arguments)
@ -78,5 +86,6 @@ public fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Do
* *
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI
public fun MST.compile(algebra: DoubleField, vararg arguments: Pair<Symbol, Double>): Double = public fun MST.compile(algebra: DoubleField, vararg arguments: Pair<Symbol, Double>): Double =
compileToExpression(algebra).invoke(*arguments) compileToExpression(algebra).invoke(*arguments)

View File

@ -342,8 +342,8 @@ internal class AsmBuilder<T>(
val MAP_INTRINSICS_TYPE: Type by lazy { getObjectType("space/kscience/kmath/asm/internal/MapIntrinsics") } val MAP_INTRINSICS_TYPE: Type by lazy { getObjectType("space/kscience/kmath/asm/internal/MapIntrinsics") }
/** /**
* ASM Type for [kscience.kmath.expressions.Symbol]. * ASM Type for [space.kscience.kmath.misc.Symbol].
*/ */
val SYMBOL_TYPE: Type by lazy { getObjectType("space/kscience/kmath/expressions/Symbol") } val SYMBOL_TYPE: Type by lazy { getObjectType("space/kscience/kmath/misc/Symbol") }
} }
} }

View File

@ -52,7 +52,7 @@ internal inline fun MethodVisitor.instructionAdapter(block: InstructionAdapter.(
* *
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
internal fun MethodVisitor.label(): Label = Label().also { visitLabel(it) } internal fun MethodVisitor.label(): Label = Label().also(::visitLabel)
/** /**
* Creates a class name for [Expression] subclassed to implement [mst] provided. * Creates a class name for [Expression] subclassed to implement [mst] provided.