Following the design paradigm in kmath with algebraic contexts, I am trying to build a context interface for encoding abstract vector space types: where one scalar type fulfills the Field contract and has corresponding operators defined, and the other vector type fulfills the Group contract and has its operators correspondingly defined.
I tried inheriting from both Field<FieldType> and Group<GroupType>, but this doesn't work. So next I tried building my own interface, building on Ring, FieldOps and NumericAlgebra from kmath:
public interface Equality<T> {
public infix fun T.eq(other: Any?): Boolean
}
public interface FieldContext<CoefficientT> :
Ring<CoefficientT>, FieldOps<CoefficientT>, NumericAlgebra<CoefficientT>, Equality<CoefficientT>
public interface VectorSpaceContext<FieldT, VectorT> : FieldContext<FieldT> {
// A module has addition, subtraction, unit, scalar multiplication
public val origin : VectorT
public fun vectorAdd(left: VectorT, right: VectorT): VectorT
public fun vectorNegate(v: VectorT): VectorT = vectorSubtract(origin, v)
public fun vectorSubtract(left: VectorT, right: VectorT): VectorT = vectorAdd(left, vectorNegate(right))
public fun vectorScale(scalar: FieldT, vector: VectorT): VectorT
// Type extension operators to enable all these within a context block
public operator fun VectorT.unaryPlus(): VectorT = this@unaryPlus
public operator fun VectorT.unaryMinus(): VectorT = vectorNegate(this@unaryMinus)
public operator fun VectorT.plus(other: VectorT): VectorT = vectorAdd(this@plus, other)
public operator fun VectorT.minus(other: VectorT): VectorT = vectorSubtract(this@minus, other)
public operator fun FieldT.times(other: VectorT): VectorT = vectorScale(this@times, other)
public operator fun VectorT.times(other: FieldT): VectorT = vectorScale(other, this@times)
}
But even after renaming add(left: VectorT, right: VectorT) to vectorAdd et.c. I am getting Accidental override compiler errors for all my extension operators. The errors look like this:
e: file:///[...path...]/Chain.kt:61:1 Accidental override: The following declarations have the same JVM signature (minus(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;):
fun CoefficientT.minus(arg: CoefficientT): CoefficientT defined in [package].ChainContext
fun Any?.minus(other: Any?): Any? defined in [package].ChainContext
Now, I don't understand where the fun Any?.minus(other: Any?): Any? comes from. I don't see anything like it in my code, and the kmath definitions for the interfaces I inherit from also are specific to that particular type. And even if I could give a @JvmName annotation to rename them in the JVM bytecode, I worry about losing their use as their corresponding operator symbols.
The error refers to ChainContext, which is a specific implementation of the VectorSpaceContext interface:
public class ChainContext<VertexT, CoefficientT>(
vertexComparator: Comparator<VertexT>,
public val coefficientContext: FieldContext<CoefficientT>,
) :
VectorSpaceContext<CoefficientT, Chain<VertexT, CoefficientT>>,
FieldContext<CoefficientT> by coefficientContext,
SimplexContext<VertexT>(vertexComparator) {
override val origin: Chain<VertexT, CoefficientT> = [...]
override fun vectorScale(scalar: CoefficientT, vector: Chain<VertexT, CoefficientT>): Chain<VertexT, CoefficientT> = [...]
override fun vectorNegate(v: Chain<VertexT, CoefficientT>): Chain<VertexT, CoefficientT> = [...]
override fun vectorAdd(left: Chain<VertexT, CoefficientT>,right: Chain<VertexT, CoefficientT>): Chain<VertexT, CoefficientT> = [...]
[... more stuff ...]
}