From 5b6b32388b34931e1fa7f76d7c98b29c7053fcba Mon Sep 17 00:00:00 2001 From: Julian Peeters Date: Tue, 9 Jan 2024 15:58:06 -0800 Subject: [PATCH] Prepare for Scala 3.4 Type matches become more strict following https://github.com/lampepfl/dotty/pull/18262 --- README.md | 2 +- build.sbt | 1 - .../scala/polynomial/mermaid/Mermaid.scala | 69 ++++++------ .../mermaid/render/p/MermaidP.scala | 42 ++++---- .../mermaid/render/q/MermaidQ.scala | 49 +++++---- .../src/main/scala/polynomial/morphism.scala | 100 +++++++++++++++--- .../src/main/scala/polynomial/object.scala | 4 +- .../scala/polynomial/product/Tensor.scala | 17 ++- 8 files changed, 177 insertions(+), 107 deletions(-) diff --git a/README.md b/README.md index beb3b81..288fbbb 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ import polynomial.morphism.~> type F[Y] = (Store[Boolean, _] ~> Monomial[Byte, Char, _])[Y] val M: Mermaid[F] = summon[Mermaid[F]] -// M: Mermaid[F] = polynomial.mermaid.Mermaid$$anon$1@6470dd67 +// M: Mermaid[F] = polynomial.mermaid.Mermaid$$anon$1@c13f7ae println(M.showTitledGraph(titleFmt = Format.Cardinal, graphFmt = Format.Specific)) // ```mermaid diff --git a/build.sbt b/build.sbt index 01d2640..5d14157 100644 --- a/build.sbt +++ b/build.sbt @@ -17,7 +17,6 @@ inThisBuild(List( ) ), scalacOptions ++= Seq( - "-deprecation", "-feature", "-source:future", "-Werror", diff --git a/modules/mermaid/shared/src/main/scala/polynomial/mermaid/Mermaid.scala b/modules/mermaid/shared/src/main/scala/polynomial/mermaid/Mermaid.scala index f5a368e..6d95849 100644 --- a/modules/mermaid/shared/src/main/scala/polynomial/mermaid/Mermaid.scala +++ b/modules/mermaid/shared/src/main/scala/polynomial/mermaid/Mermaid.scala @@ -4,38 +4,37 @@ import polynomial.mermaid.Mermaid.CustomLabels import polynomial.mermaid.render.p.MermaidP import polynomial.mermaid.render.q.MermaidQ import polynomial.mermaid.render.Format.{Cardinal, Generic, Specific} -import polynomial.mermaid.render.{Render} -import polynomial.mermaid.render.addTitle +import polynomial.mermaid.render.{Render, addTitle} import polynomial.morphism.PolyMap import polynomial.`object`.{Binomial, Monomial, Store} trait Mermaid[F[_]]: def showGraph(graphFmt: Format): String - def showGraphCustom(graphFmt: Format, labels: CustomLabels[F]): String + def showGraphCustom[Y](graphFmt: Format, labels: CustomLabels[F[Y]]): String def showTitle(titleFmt: Format): String - def showTitleCustom(labels: CustomLabels[F]): String + def showTitleCustom[Y](labels: CustomLabels[F[Y]]): String def showTitleHtml(titleFmt: Format): String - def showTitleHtmlCustom(labels: CustomLabels[F]): String + def showTitleHtmlCustom[Y](labels: CustomLabels[F[Y]]): String def showTitledGraph(titleFmt: Format, graphFmt: Format): String - def showTitledGraphCustom(graphFmt: Format, labels: CustomLabels[F]): String + def showTitledGraphCustom[Y](graphFmt: Format, labels: CustomLabels[F[Y]]): String object Mermaid: - type ParamLabels[P[_]] = P[Any] match - case Monomial[a, b, Any] => (String, String) - case Binomial[a1, b1, a2, b2, Any] => ((String, String), (String, String)) - case Store[s, Any] => String + type ParamLabels[X] = X match + case Monomial[a, b, y] => (String, String) + case Binomial[a1, b1, a2, b2, y] => ((String, String), (String, String)) + case Store[s, y] => String - type PolynomialLabels[P[_]] = P[Any] match - case Binomial[a1, b1, a2, b2, Any] => String - case Monomial[a, b, Any] => String - case Store[s, Any] => String + type PolynomialLabels[X] = X match + case Binomial[a1, b1, a2, b2, y] => String + case Monomial[a, b, y] => String + case Store[s, y] => String - type CustomLabels[P[_]] = P[Any] match - case PolyMap[Binomial[a1, b1, a2, b2, _], Monomial[a3, b3, _], Any] => (String, String) - case PolyMap[Monomial[a, b, _], Monomial[a3, b3, _], Any] => (String, String) - case PolyMap[Store[s, _], Monomial[a3, b3, _], Any] => (String, String) - case PolyMap[Store[s, _], Binomial[a1, b1, a2, b2, _], Any] => (String, String) + type CustomLabels[X] = X match + case PolyMap[p, q, y] => CustomLabels[(p[y], q[y])] + case (Monomial[a1, b1, y1], Monomial[a2, b2, y2]) => (String, String) + case (Store[s, y1], Binomial[a1, b1, a2, b2, y2]) => (String, String) + case (Store[s, y1], Monomial[a, b, y2]) => (String, String) given mooreStoreToMono[S, A, B](using P: MermaidP[Store[S, _]], @@ -53,7 +52,7 @@ object Mermaid: Render.mermaidCodeFence(Q.graphQGeneric((labelA, labelB))(P.graphPGeneric(P.polynomialGeneric(labelS), labelS))) case Specific => Render.mermaidCodeFence(Q.graphQSpecific(P.graphPSpecific(P.polynomialSpecific))) - def showGraphCustom(graphFmt: Format, labels: (String, String)): String = + def showGraphCustom[Y](graphFmt: Format, labels: (String, String)): String = graphFmt match case Cardinal => Render.mermaidCodeFence(Q.graphQCardinal(P.graphPCardinal(P.polynomialCardinal))) @@ -69,7 +68,7 @@ object Mermaid: Render.mermaidCodeFence(Render.title(P.polynomialGeneric(labelS), 3, Q.polynomialGeneric((labelA, labelB)), 3)) case Specific => Render.mermaidCodeFence(Render.title(P.polynomialSpecific, 3, Q.polynomialSpecific, 3)) - def showTitleCustom(labels: (String, String)): String = + def showTitleCustom[Y](labels: (String, String)): String = Render.mermaidCodeFence(Render.title(labels._1, 3, labels._2, 3)) def showTitleHtml(titleFmt: Format): String = titleFmt match @@ -79,7 +78,7 @@ object Mermaid: Render.polyMap(P.graphPGeneric(P.polynomialGeneric(labelS), labelS), Q.graphQGeneric((labelA, labelB))(P.graphPGeneric(P.polynomialGeneric(labelS), labelS))) case Specific => Render.polyMap(P.graphPSpecific(P.polynomialSpecific), Q.graphQSpecific(P.graphPSpecific(P.polynomialSpecific))) - def showTitleHtmlCustom(labels: (String, String)): String = + def showTitleHtmlCustom[Y](labels: (String, String)): String = Render.polyMap(labels._1, labels._2) def showTitledGraph(titleFmt: Format, graphFmt: Format): String = (titleFmt, graphFmt) match @@ -110,7 +109,7 @@ object Mermaid: case (Specific, Specific) => Render.mermaidCodeFence(Q.graphQSpecific(P.graphPSpecific(P.polynomialSpecific))) .addTitle(P.polynomialSpecific, 3, Q.polynomialSpecific, 3) - def showTitledGraphCustom(graphFmt: Format, labels: (String, String)): String = + def showTitledGraphCustom[Y](graphFmt: Format, labels: (String, String)): String = graphFmt match case Cardinal => Render.mermaidCodeFence(Q.graphQCardinal(P.graphPCardinal(P.polynomialCardinal))) @@ -138,7 +137,7 @@ object Mermaid: Render.mermaidCodeFence(Q.graphQGeneric((labelA, labelB))(P.graphPGeneric(P.polynomialGeneric(labelS), labelS))) case Specific => Render.mermaidCodeFence(Q.graphQSpecific(P.graphPSpecific(P.polynomialSpecific))) - def showGraphCustom(graphFmt: Format, labels: (String, String)): String = + def showGraphCustom[Y](graphFmt: Format, labels: (String, String)): String = graphFmt match case Cardinal => Render.mermaidCodeFence(Q.graphQCardinal(P.graphPCardinal(P.polynomialCardinal))) @@ -154,7 +153,7 @@ object Mermaid: Render.mermaidCodeFence(Render.title(P.polynomialGeneric(labelS), 3, Q.polynomialGeneric((labelA, labelB)), 3)) case Specific => Render.mermaidCodeFence(Render.title(P.polynomialSpecific, 3, Q.polynomialSpecific, 3)) - def showTitleCustom(labels: (String, String)): String = + def showTitleCustom[Y](labels: (String, String)): String = Render.mermaidCodeFence(Render.title(labels._1, 3, labels._2, 3)) def showTitleHtml(titleFmt: Format): String = titleFmt match @@ -164,7 +163,7 @@ object Mermaid: Render.polyMap(P.graphPGeneric(P.polynomialGeneric(labelS), labelS), Q.graphQGeneric((labelA, labelB))(P.graphPGeneric(P.polynomialGeneric(labelS), labelS))) case Specific => Render.polyMap(P.graphPSpecific(P.polynomialSpecific), Q.graphQSpecific(P.graphPSpecific(P.polynomialSpecific))) - def showTitleHtmlCustom(labels: (String, String)): String = + def showTitleHtmlCustom[Y](labels: (String, String)): String = Render.polyMap(labels._1, labels._2) def showTitledGraph(titleFmt: Format, graphFmt: Format): String = (titleFmt, graphFmt) match @@ -195,7 +194,7 @@ object Mermaid: case (Specific, Specific) => Render.mermaidCodeFence(Q.graphQSpecific(P.graphPSpecific(P.polynomialSpecific))) .addTitle(P.polynomialSpecific, 3, Q.polynomialSpecific, 3) - def showTitledGraphCustom(graphFmt: Format, labels: (String, String)): String = + def showTitledGraphCustom[Y](graphFmt: Format, labels: (String, String)): String = graphFmt match case Cardinal => Render.mermaidCodeFence(Q.graphQCardinal(P.graphPCardinal(P.polynomialCardinal))) @@ -224,7 +223,7 @@ object Mermaid: Render.mermaidCodeFence(Q.graphQGeneric((labelA2, labelB2))(P.graphPGeneric(P.polynomialGeneric((labelA1, labelB1)), (labelA1, labelB1)))) case Specific => Render.mermaidCodeFence(Q.graphQSpecific(P.graphPSpecific(P.polynomialSpecific))) - def showGraphCustom(graphFmt: Format, labels: (String, String)): String = + def showGraphCustom[Y](graphFmt: Format, labels: (String, String)): String = graphFmt match case Cardinal => Render.mermaidCodeFence(Q.graphQCardinal(P.graphPCardinal(P.polynomialCardinal))) @@ -240,7 +239,7 @@ object Mermaid: Render.mermaidCodeFence(Render.title(P.polynomialGeneric((labelA1, labelB1)), 4, Q.polynomialGeneric((labelA2, labelB2)), 4)) case Specific => Render.mermaidCodeFence(Render.title(P.polynomialSpecific, 4, Q.polynomialSpecific, 4)) - def showTitleCustom(labels: (String, String)): String = + def showTitleCustom[Y](labels: (String, String)): String = Render.mermaidCodeFence(Render.title(labels._1, 4, labels._2, 4)) def showTitleHtml(titleFmt: Format): String = titleFmt match @@ -250,7 +249,7 @@ object Mermaid: Render.polyMap(P.graphPGeneric(P.polynomialGeneric((labelA1, labelB1)), (labelA1, labelB1)), Q.graphQGeneric((labelA2, labelB2))(P.graphPGeneric(P.polynomialGeneric((labelA1, labelB1)), (labelA1, labelB1)))) case Specific => Render.polyMap(P.graphPSpecific(P.polynomialSpecific), Q.graphQSpecific(P.graphPSpecific(P.polynomialSpecific))) - def showTitleHtmlCustom(labels: (String, String)): String = + def showTitleHtmlCustom[Y](labels: (String, String)): String = Render.polyMap(labels._1, labels._2) def showTitledGraph(titleFmt: Format, graphFmt: Format): String = (titleFmt, graphFmt) match @@ -281,7 +280,7 @@ object Mermaid: case (Specific, Specific) => Render.mermaidCodeFence(Q.graphQSpecific(P.graphPSpecific(P.polynomialSpecific))) .addTitle(P.polynomialSpecific, 4, Q.polynomialSpecific, 4) - def showTitledGraphCustom(graphFmt: Format, labels: (String, String)): String = + def showTitledGraphCustom[Y](graphFmt: Format, labels: (String, String)): String = graphFmt match case Cardinal => Render.mermaidCodeFence(Q.graphQCardinal(P.graphPCardinal(P.polynomialCardinal))) @@ -311,7 +310,7 @@ object Mermaid: Render.mermaidCodeFence(Q.graphQGeneric(((labelA1, labelB1), (labelA2, labelB2)))(P.graphPGeneric(P.polynomialGeneric(labelS), labelS))) case Specific => Render.mermaidCodeFence(Q.graphQSpecific(P.graphPSpecific(P.polynomialSpecific))) - def showGraphCustom(graphFmt: Format, labels: (String, String)): String = + def showGraphCustom[Y](graphFmt: Format, labels: (String, String)): String = graphFmt match case Cardinal => Render.mermaidCodeFence(Q.graphQCardinal(P.graphPCardinal(P.polynomialCardinal))) @@ -327,7 +326,7 @@ object Mermaid: Render.mermaidCodeFence(Render.title(P.polynomialGeneric(labelS), 3, Q.polynomialGeneric(((labelA1, labelB1), (labelA2, labelB2))), 3)) case Specific => Render.mermaidCodeFence(Render.title(P.polynomialSpecific, 3, Q.polynomialSpecific, 3)) - def showTitleCustom(labels: (String, String)): String = + def showTitleCustom[Y](labels: (String, String)): String = Render.mermaidCodeFence(Render.title(labels._1, 3, labels._2, 3)) def showTitleHtml(titleFmt: Format): String = titleFmt match @@ -337,7 +336,7 @@ object Mermaid: Render.polyMap(P.graphPGeneric(P.polynomialGeneric(labelS), labelS), Q.graphQGeneric(((labelA1, labelB1), (labelA2, labelB2)))(P.graphPGeneric(P.polynomialGeneric(labelS), labelS))) case Specific => Render.polyMap(P.graphPSpecific(P.polynomialSpecific), Q.graphQSpecific(P.graphPSpecific(P.polynomialSpecific))) - def showTitleHtmlCustom(labels: (String, String)): String = + def showTitleHtmlCustom[Y](labels: (String, String)): String = Render.polyMap(labels._1, labels._2) def showTitledGraph(titleFmt: Format, graphFmt: Format): String = (titleFmt, graphFmt) match @@ -368,7 +367,7 @@ object Mermaid: case (Specific, Specific) => Render.mermaidCodeFence(Q.graphQSpecific(P.graphPSpecific(P.polynomialSpecific))) .addTitle(P.polynomialSpecific, 3, Q.polynomialSpecific, 3) - def showTitledGraphCustom(graphFmt: Format, labels: (String, String)): String = + def showTitledGraphCustom[Y](graphFmt: Format, labels: (String, String)): String = graphFmt match case Cardinal => Render.mermaidCodeFence(Q.graphQCardinal(P.graphPCardinal(P.polynomialCardinal))) diff --git a/modules/mermaid/shared/src/main/scala/polynomial/mermaid/render/p/MermaidP.scala b/modules/mermaid/shared/src/main/scala/polynomial/mermaid/render/p/MermaidP.scala index 1519614..8c28ccd 100644 --- a/modules/mermaid/shared/src/main/scala/polynomial/mermaid/render/p/MermaidP.scala +++ b/modules/mermaid/shared/src/main/scala/polynomial/mermaid/render/p/MermaidP.scala @@ -8,17 +8,17 @@ import typesize.SizeOf trait MermaidP[P[_]]: // Base constructor of the P component of the graph - def graphP(polynomialLabelP: PolynomialLabels[P], paramLabelsP: ParamLabels[P]): String + def graphP[Y](polynomialLabelP: PolynomialLabels[P[Y]], paramLabelsP: ParamLabels[P[Y]]): String // Impl constructors of the P component of the graph e.g. A[ ]-->B[ ] - def graphPCardinal(polynomialLabelP: PolynomialLabels[P]): String - def graphPGeneric(polynomialLabelP: PolynomialLabels[P], paramLabelsP: ParamLabels[P]): String - def graphPSpecific(polynomialLabelP: PolynomialLabels[P]): String + def graphPCardinal[Y](polynomialLabelP: PolynomialLabels[P[Y]]): String + def graphPGeneric[Y](polynomialLabelP: PolynomialLabels[P[Y]], paramLabelsP: ParamLabels[P[Y]]): String + def graphPSpecific[Y](polynomialLabelP: PolynomialLabels[P[Y]]): String // Built-in coefficient labels and exponent labels, e.g., Boolean - def paramLabelsCardinal: ParamLabels[P] - def paramLabelsSpecific: ParamLabels[P] + def paramLabelsCardinal[Y]: ParamLabels[P[Y]] + def paramLabelsSpecific[Y]: ParamLabels[P[Y]] // Text representation of polynomials e.g., Byᴬ def polynomialCardinal: String - def polynomialGeneric(paramLabelsP: ParamLabels[P]): String + def polynomialGeneric[Y](paramLabelsP: ParamLabels[P[Y]]): String def polynomialSpecific: String // Variable labels, e.g., y def variableLabel: String @@ -27,21 +27,21 @@ object MermaidP: given [S](using N: NameOf[S], S: SizeOf[S]): MermaidP[Store[S, _]] = new MermaidP[Store[S, _]]: - def graphP(polynomialLabelP: String, paramLabelsP: String): String = + def graphP[Y](polynomialLabelP: String, paramLabelsP: String): String = s"S[$paramLabelsP]" - def graphPCardinal(polynomialLabelP: String): String = + def graphPCardinal[Y](polynomialLabelP: String): String = graphP(polynomialLabelP, paramLabelsCardinal) - def graphPGeneric(polynomialLabelP: String, paramLabelsP: String): String = + def graphPGeneric[Y](polynomialLabelP: String, paramLabelsP: String): String = graphP(polynomialLabelP, Font.courier(paramLabelsP)) - def graphPSpecific(polynomialLabelP: String): String = + def graphPSpecific[Y](polynomialLabelP: String): String = graphP(polynomialLabelP, Font.courier(paramLabelsSpecific)) - def paramLabelsCardinal: String = + def paramLabelsCardinal[Y]: String = Render.cardinality(S.size) - def paramLabelsSpecific: String = + def paramLabelsSpecific[Y]: String = N.name def polynomialCardinal: String = Render.monomial(paramLabelsCardinal, variableLabel, paramLabelsCardinal) - def polynomialGeneric(paramLabelsP: String): String = + def polynomialGeneric[Y](paramLabelsP: String): String = Render.monomial(Font.courier(paramLabelsP), variableLabel, Font.courier(paramLabelsP)) def polynomialSpecific: String = Render.monomial(Font.courier(paramLabelsSpecific), variableLabel, Font.courier(paramLabelsSpecific)) @@ -50,7 +50,7 @@ object MermaidP: given [A, B](using NA: NameOf[A], NB: NameOf[B], SA: SizeOf[A], SB: SizeOf[B]): MermaidP[Monomial[A, B, _]] = new MermaidP[Monomial[A, B, _]]: - def graphP(polynomialLabelP: String, paramLabelsQ: (String, String)): String = + def graphP[Y](polynomialLabelP: String, paramLabelsQ: (String, String)): String = s"""|A2[ ]:::point |subgraph s[ ] | A2:::point---MermaidPMono @@ -58,19 +58,19 @@ object MermaidP: | MermaidPMono---B2 |end |B2[ ]:::point""".stripMargin - def graphPCardinal(polynomialLabelP: String): String = + def graphPCardinal[Y](polynomialLabelP: String): String = graphP(polynomialLabelP, paramLabelsCardinal) - def graphPGeneric(polynomialLabelP: String, paramLabelsP: (String, String)): String = + def graphPGeneric[Y](polynomialLabelP: String, paramLabelsP: (String, String)): String = graphP(polynomialLabelP, paramLabelsP) - def graphPSpecific(polynomialLabelP: String): String = + def graphPSpecific[Y](polynomialLabelP: String): String = graphP(polynomialLabelP, paramLabelsSpecific) - def paramLabelsCardinal: (String, String) = + def paramLabelsCardinal[Y]: (String, String) = (Render.cardinality(SA.size), Render.cardinality(SB.size)) - def paramLabelsSpecific: (String, String) = + def paramLabelsSpecific[Y]: (String, String) = (NA.name, NB.name) def polynomialCardinal: String = Render.monomial(Font.courier(paramLabelsCardinal._2), variableLabel, Font.courier(paramLabelsCardinal._1)) - def polynomialGeneric(paramLabelsP: (String, String)): String = + def polynomialGeneric[Y](paramLabelsP: (String, String)): String = Render.monomial(Font.courier(paramLabelsP._2), variableLabel, Font.courier(paramLabelsP._1)) def polynomialSpecific: String = Render.monomial(Font.courier(paramLabelsSpecific._2), variableLabel, Font.courier(paramLabelsSpecific._1)) diff --git a/modules/mermaid/shared/src/main/scala/polynomial/mermaid/render/q/MermaidQ.scala b/modules/mermaid/shared/src/main/scala/polynomial/mermaid/render/q/MermaidQ.scala index c373f80..0a3a3e9 100644 --- a/modules/mermaid/shared/src/main/scala/polynomial/mermaid/render/q/MermaidQ.scala +++ b/modules/mermaid/shared/src/main/scala/polynomial/mermaid/render/q/MermaidQ.scala @@ -8,18 +8,18 @@ import typesize.SizeOf trait MermaidQ[Q[_]]: // Base constructors of the Q component of the graph - def graphQ(p: String, paramLabelsQ: ParamLabels[Q]): String + def graphQ[Y](p: String, paramLabelsQ: ParamLabels[Q[Y]]): String // Impl constructors of the Q component of the graph, e.g. A[ ]-->B[ ] def graphQCardinal: String => String - def graphQCustom(paramLabelsQ: ParamLabels[Q]): String => String - def graphQGeneric(paramLabelsQ: ParamLabels[Q]): String => String + def graphQCustom[Y](paramLabelsQ: ParamLabels[Q[Y]]): String => String + def graphQGeneric[Y](paramLabelsQ: ParamLabels[Q[Y]]): String => String def graphQSpecific: String => String // Built-in coefficient labels and exponent labels, e.g., Boolean - def paramLabelsCardinal: ParamLabels[Q] - def paramLabelsSpecific: ParamLabels[Q] + def paramLabelsCardinal[Y]: ParamLabels[Q[Y]] + def paramLabelsSpecific[Y]: ParamLabels[Q[Y]] // String representation of polynomials e.g., Byᴬ def polynomialCardinal: String - def polynomialGeneric(paramLabelsQ: ParamLabels[Q]): String + def polynomialGeneric[Y](paramLabelsQ: ParamLabels[Q[Y]]): String def polynomialSpecific: String // Variable labels, e.g., y def variableLabel: String @@ -34,24 +34,23 @@ object MermaidQ: SB: SizeOf[B] ): MermaidQ[Monomial[A, B, _]] = new MermaidQ[Monomial[A, B, _]]: - def graphQ(p: String, paramLabelsQ: (String, String)) = + def graphQ[Y](p: String, paramLabelsQ: (String, String)) = s"A:::hidden---|${paramLabelsQ._1}|${p}---|${paramLabelsQ._2}|B:::hidden;" - def graphQCardinal: String => String = p => graphQ(p, paramLabelsCardinal) - def graphQCustom(paramLabelsQ: (String, String)): String => String = + def graphQCustom[Y](paramLabelsQ: (String, String)): String => String = p => graphQ(p, paramLabelsQ) - def graphQGeneric(paramLabelsQ: (String, String)): String => String = + def graphQGeneric[Y](paramLabelsQ: (String, String)): String => String = p => graphQ(p, (Font.courier(paramLabelsQ._1), Font.courier(paramLabelsQ._2))) def graphQSpecific: String => String = p => graphQ(p, (Font.courier(paramLabelsSpecific._1), Font.courier(paramLabelsSpecific._2))) - def paramLabelsCardinal: (String, String) = + def paramLabelsCardinal[Y]: (String, String) = (Render.cardinality(SA.size), Render.cardinality(SB.size)) - def paramLabelsSpecific: (String, String) = + def paramLabelsSpecific[Y]: (String, String) = (NA.name, NB.name) def polynomialCardinal: String = Render.monomial(paramLabelsCardinal._2, variableLabel, paramLabelsCardinal._1) - def polynomialGeneric(paramLabelsQ: (String, String)): String = + def polynomialGeneric[Y](paramLabelsQ: (String, String)): String = Render.monomial(Font.courier(paramLabelsQ._2), variableLabel, Font.courier(paramLabelsQ._1)) def polynomialSpecific: String = Render.monomial(Font.courier(paramLabelsSpecific._2), variableLabel, Font.courier(paramLabelsSpecific._1)) @@ -66,23 +65,23 @@ object MermaidQ: SB: SizeOf[B] ): MermaidQ[Monomial[A, A => B, _]] = new MermaidQ[Monomial[A, A => B, _]]: - def graphQ(p: String, paramLabelsQ: (String, String)) = + def graphQ[Y](p: String, paramLabelsQ: (String, String)) = s"A:::hidden---|${paramLabelsQ._1}|${p}---|${paramLabelsQ._2}|B:::hidden;" def graphQCardinal: String => String = p => graphQ(p, paramLabelsCardinal) - def graphQCustom(paramLabelsQ: (String, String)): String => String = + def graphQCustom[Y](paramLabelsQ: (String, String)): String => String = p => graphQ(p, paramLabelsQ) - def graphQGeneric(paramLabelsQ: (String, String)): String => String = + def graphQGeneric[Y](paramLabelsQ: (String, String)): String => String = p => graphQ(p, (Font.courier(paramLabelsQ._1), Font.courier(paramLabelsQ._2))) def graphQSpecific: String => String = p => graphQ(p, (Font.courier(paramLabelsSpecific._1), Font.courier(paramLabelsSpecific._2))) - def paramLabelsCardinal: (String, String) = + def paramLabelsCardinal[Y]: (String, String) = (Render.cardinality(SA.size), Render.cardinality(SA.size) + " => " + Render.cardinality(SB.size)) - def paramLabelsSpecific: (String, String) = + def paramLabelsSpecific[Y]: (String, String) = (NA.name, (NA.name + " => " + NB.name)) def polynomialCardinal: String = Render.monomial(paramLabelsCardinal._2, variableLabel, paramLabelsCardinal._1) - def polynomialGeneric(paramLabelsQ: (String, String)): String = + def polynomialGeneric[Y](paramLabelsQ: (String, String)): String = Render.monomial(Font.courier(paramLabelsQ._2), variableLabel, Font.courier(paramLabelsQ._1)) def polynomialSpecific: String = Render.monomial(Font.courier(paramLabelsSpecific._2), variableLabel, Font.courier(paramLabelsSpecific._1)) @@ -100,26 +99,26 @@ object MermaidQ: SB2: SizeOf[B2], ): MermaidQ[Binomial[A1, B1, A2, B2, _]] = new MermaidQ[Binomial[A1, B1, A2, B2, _]]: - def graphQ(p: String, paramLabelsQ: ((String, String), (String, String))): String = + def graphQ[Y](p: String, paramLabelsQ: ((String, String), (String, String))): String = s"A:::hidden---|${paramLabelsQ._1._1}
${paramLabelsQ._2._1}|${p}---|${paramLabelsQ._1._2}
${paramLabelsQ._2._2}|B:::hidden;" def graphQCardinal: String => String = p => graphQ(p, paramLabelsCardinal) - def graphQCustom(paramLabelsQ: ((String, String), (String, String))): String => String = + def graphQCustom[Y](paramLabelsQ: ((String, String), (String, String))): String => String = p => graphQ(p, paramLabelsQ) - def graphQGeneric(paramLabelsQ: ((String, String), (String, String))): String => String = + def graphQGeneric[Y](paramLabelsQ: ((String, String), (String, String))): String => String = p => graphQ(p, ((Font.courier(paramLabelsQ._1._1), Font.courier(paramLabelsQ._1._2)), (Font.courier(paramLabelsQ._2._1), Font.courier(paramLabelsQ._2._2)))) def graphQSpecific: String => String = p => graphQ(p, paramLabelsSpecific) - def paramLabelsCardinal: ((String, String), (String, String)) = + def paramLabelsCardinal[Y]: ((String, String), (String, String)) = ((Render.cardinality(SA1.size), Render.cardinality(SB1.size)), (Render.cardinality(SA2.size), Render.cardinality(SB2.size))) - def paramLabelsSpecific: ((String, String), (String, String)) = + def paramLabelsSpecific[Y]: ((String, String), (String, String)) = ((NA1.name, NB1.name), (NA2.name, NB2.name)) def polynomialCardinal: String = Render.binomial( paramLabelsCardinal._1._2, variableLabel, paramLabelsCardinal._1._1, paramLabelsCardinal._2._2, variableLabel, paramLabelsCardinal._2._1 ) - def polynomialGeneric(paramLabelsQ: ((String, String), (String, String))): String = + def polynomialGeneric[Y](paramLabelsQ: ((String, String), (String, String))): String = Render.binomial( paramLabelsQ._1._2, variableLabel, paramLabelsQ._1._1, paramLabelsQ._2._2, variableLabel, paramLabelsQ._2._1 diff --git a/modules/poly/shared/src/main/scala/polynomial/morphism.scala b/modules/poly/shared/src/main/scala/polynomial/morphism.scala index b1a6f81..7814c55 100644 --- a/modules/poly/shared/src/main/scala/polynomial/morphism.scala +++ b/modules/poly/shared/src/main/scala/polynomial/morphism.scala @@ -1,7 +1,7 @@ package polynomial import polynomial.`object`.{Binomial, Monomial, Store} -import polynomial.product.⊗ +import polynomial.product.{Tensor, ⊗} object morphism: @@ -14,20 +14,30 @@ object morphism: object PolyMap: type Phi[P[_], Q[_], Y] = (P[Y], Q[Y]) match - case (PolyMap[Store[s, _], Binomial[a1, b1, a2, b2, _], Y], Binomial[a3, b3, a4, b4, Y]) => (s => b3, s => b4) - case (PolyMap[Store[s, _], Monomial[a1, b1, _], Y], Monomial[a2, b2, Y]) => s => b2 - case (Binomial[a1, b1, a2, b2, Y], Binomial[a3, b3, a4, b4, Y]) => (b1 => b3, b2 => b4) - case (Monomial[a1, b1, Y], Monomial[a2, b2, Y]) => b1 => b2 - case (Store[s, Y], Binomial[a1, b1, a2, b2, Y]) => (s => b1, s => b2) - case (Store[s, Y], Monomial[a, b, Y]) => s => b - + case (Binomial[a1, b1, a2, b2, Y], Binomial[a3, b3, a4, b4, Y]) => (b1 => b3, b2 => b4) + case (Binomial[a1, b1, a2, b2, Y], Monomial[a3, b3, Y]) => (b1 => b3, b2 => b3) + case (Monomial[a1, b1, Y], Binomial[a3, b3, a4, b4, Y]) => (b1 => b3, b1 => b4) + case (Monomial[a1, b1, Y], Monomial[a2, b2, Y]) => b1 => b2 + case (PolyMap[p, q, Y], Binomial[a3, b3, a4, b4, Y]) => Phi[p, Binomial[a3, b3, a4, b4, _], Y] + case (PolyMap[p, q, Y], Monomial[a2, b2, Y]) => Phi[p, Monomial[a2, b2, _], Y] + case (PolyMap[o, p, Y], Tensor[q, r, Y]) => Phi[o, Tensor[q, r, _], Y] + case (Store[s, Y], Binomial[a1, b1, a2, b2, Y]) => (s => b1, s => b2) + case (Store[s, Y], Monomial[a, b, Y]) => s => b + case (Tensor[p, q, Y], Monomial[a1, b1, Y]) => Phi[Tensor.DayConvolution[p, q, _], Monomial[a1, b1, _], Y] + case (Tensor[p, q, Y], Binomial[a1, b1, a2, b2, Y]) => Phi[Tensor.DayConvolution[p, q, _], Binomial[a1, b1, a2, b2, _], Y] + case (Tensor[o, p, Y], Tensor[q, r, Y]) => Phi[Tensor.DayConvolution[o, p, _], Tensor.DayConvolution[q, r, _], Y] + type PhiSharp[P[_], Q[_], Y] = (P[Y], Q[Y]) match - case (PolyMap[Store[s, _], Binomial[a1, b1, a2, b2, _], Y], Binomial[a3, b3, a4, b4, Y]) => ((s, a3) => s, (s, a4) => s) - case (PolyMap[Store[s, _], Monomial[a1, b1, _], Y], Monomial[a2, b2, Y]) => (s, a2) => s - case (Binomial[a1, b1, a2, b2, Y], Binomial[a3, b3, a4, b4, Y]) => ((b1, a3) => b3, (b2, a4) => b4) - case (Monomial[a1, b1, Y], Monomial[a2, b2, Y]) => Function2[b1, a2, a1] - case (Store[s, Y], Binomial[a1, b1, a2, b2, Y]) => (Function2[s, a1, s], Function2[s, a2, s]) - case (Store[s, Y], Monomial[a, b, Y]) => Function2[s, a, s] + case (Binomial[a1, b1, a2, b2, Y], Binomial[a3, b3, a4, b4, Y]) => ((b1, a3) => a1, (b2, a4) => a2) + case (Monomial[a1, b1, Y], Monomial[a2, b2, Y]) => (b1, a2) => a1 + case (PolyMap[p, q, Y], Binomial[a3, b3, a4, b4, Y]) => PhiSharp[p, Binomial[a3, b3, a4, b4, _], Y] + case (PolyMap[p, q, Y], Monomial[a2, b2, Y]) => PhiSharp[p, Monomial[a2, b2, _], Y] + case (PolyMap[o, p, Y], Tensor[q, r, Y]) => PhiSharp[o, Tensor[q, r, _], Y] + case (Store[s, Y], Binomial[a1, b1, a2, b2, Y]) => ((s, a1) => s, (s, a2) => s) + case (Store[s, Y], Monomial[a, b, Y]) => (s, a) => s + case (Tensor[p, q, Y], Binomial[a1, b1, a2, b2, Y]) => PhiSharp[Tensor.DayConvolution[p, q, _], Binomial[a1, b1, a2, b2, _], Y] + case (Tensor[p, q, Y], Monomial[a1, b1, Y]) => PhiSharp[Tensor.DayConvolution[p, q, _], Monomial[a1, b1, _], Y] + case (Tensor[o, p, Y], Tensor[q, r, Y]) => PhiSharp[Tensor.DayConvolution[o, p, _], Tensor.DayConvolution[q, r, _], Y] def apply[P[_], Q[_], Y]( phi: Phi[P, Q, Y], @@ -57,7 +67,63 @@ object morphism: def φ: Phi[PolyMap[Store[S, _], Binomial[A1, B1, A2, B2, _], _], Binomial[A1, A1 => B1, A2, A2 => B2, _], Y] = (p.φ._1.andThen(w.φ._1), p.φ._2.andThen(w.φ._2)) def `φ#`: PhiSharp[PolyMap[Store[S, _], Binomial[A1, B1, A2, B2, _], _], Binomial[A1, A1 => B1, A2, A2 => B2, _], Y] = - ((s, a) => p.`φ#`._1(s, a), (s, a) => p.`φ#`._2(s, a)) + ((s, a) => p.`φ#`._1(s, a), (s, a) => p.`φ#`._2(s, a)) + + extension [S1, S2, A1, B1, A2, B2, Y] (p: PolyMap[Store[S1, _] ⊗ Store[S2, _], Monomial[A1, B1, _] ⊗ Monomial[A2, B2, _], Y]) + @scala.annotation.targetName("andThenTensoredStoreTensoredMonoToMonof") + def andThen( + w: PolyMap[Monomial[A1, B1, _] ⊗ Monomial[A2, B2, _], Monomial[A1, A1 => B2, _], Y] + ): PolyMap[PolyMap[Store[S1, _] ⊗ Store[S2, _], Monomial[A1, B1, _] ⊗ Monomial[A2, B2, _], _], Monomial[A1, A1 => B2, _], Y] = + new PolyMap[PolyMap[Store[S1, _] ⊗ Store[S2, _], Monomial[A1, B1, _] ⊗ Monomial[A2, B2, _], _], Monomial[A1, A1 => B2, _], Y]: + def φ: Phi[PolyMap[Store[S1, _] ⊗ Store[S2, _], Monomial[A1, B1, _] ⊗ Monomial[A2, B2, _], _], Monomial[A1, A1 => B2, _], Y] = + p.φ.andThen(w.φ) + def `φ#`: PhiSharp[PolyMap[Store[S1, _] ⊗ Store[S2, _], Monomial[A1, B1, _] ⊗ Monomial[A2, B2, _], _], Monomial[A1, A1 => B2, _], Y] = + (s, a) => p.`φ#`(s, w.`φ#`(p.φ(s), a)) + + extension [S1, S2, A1, B1, A2, B2, Y] (p: PolyMap[Store[S1, _] ⊗ Store[S2, _], Monomial[A1, B1, _] ⊗ Monomial[A2, B2, _], Y]) + @scala.annotation.targetName("andThenTensoredStoreTensoredMonoToMono") + def andThen( + w: PolyMap[Monomial[A1, B1, _] ⊗ Monomial[A2, B2, _], Monomial[A1, B2, _], Y] + ): PolyMap[PolyMap[Store[S1, _] ⊗ Store[S2, _], Monomial[A1, B1, _] ⊗ Monomial[A2, B2, _], _], Monomial[A1, B2, _], Y] = + new PolyMap[PolyMap[Store[S1, _] ⊗ Store[S2, _], Monomial[A1, B1, _] ⊗ Monomial[A2, B2, _], _], Monomial[A1, B2, _], Y]: + def φ: Phi[PolyMap[Store[S1, _] ⊗ Store[S2, _], Monomial[A1, B1, _] ⊗ Monomial[A2, B2, _], _], Monomial[A1, B2, _], Y] = + p.φ.andThen(w.φ) + def `φ#`: PhiSharp[PolyMap[Store[S1, _] ⊗ Store[S2, _], Monomial[A1, B1, _] ⊗ Monomial[A2, B2, _], _], Monomial[A1, B2, _], Y] = + (s, a) => p.`φ#`(s, w.`φ#`(p.φ(s), a)) + + extension [S1, S2, A, B, C, Y] (p: PolyMap[(Store[S1, _] ⊗ Store[S2, _]), (Monomial[(A, B), C, _] ⊗ Monomial[C, B, _]), Y]) + @scala.annotation.targetName("andThenTensoredStoreTensoredMonoToMono2") + def andThen( + w: PolyMap[(Monomial[(A, B), C, _] ⊗ Monomial[C, B, _]), Monomial[A, C, _], Y] + ): PolyMap[(Store[S1, _] ⊗ Store[S2, _]) ~> (Monomial[(A, B), C, _] ⊗ Monomial[C, B, _]), Monomial[A, C, _], Y] = + new PolyMap[(Store[S1, _] ⊗ Store[S2, _]) ~> (Monomial[(A, B), C, _] ⊗ Monomial[C, B, _]), Monomial[A, C, _], Y]: + def φ: Phi[(Store[S1, _] ⊗ Store[S2, _]) ~> (Monomial[(A, B), C, _] ⊗ Monomial[C, B, _]), Monomial[A, C, _], Y] = + p.φ.andThen(w.φ) + def `φ#`: PhiSharp[(Store[S1, _] ⊗ Store[S2, _]) ~> (Monomial[(A, B), C, _] ⊗ Monomial[C, B, _]), Monomial[A, C, _], Y] = + (s, a) => p.`φ#`(s, w.`φ#`(p.φ(s), a)) + + + extension [S1, S2, A, B, C, Y] (p: PolyMap[(Store[S1, _] ⊗ Store[S2, _]), (Monomial[(A, B), C, _] ⊗ Monomial[C, B, _]), Y]) + @scala.annotation.targetName("andThenTensoredStoreTensoredMonoToMono3") + def andThen( + w: PolyMap[(Monomial[(A, B), C, _] ⊗ Monomial[C, B, _]), Monomial[A, A => C, _], Y] + ): PolyMap[(Store[S1, _] ⊗ Store[S2, _]) ~> (Monomial[(A, B), C, _] ⊗ Monomial[C, B, _]), Monomial[A, A => C, _], Y] = + new PolyMap[(Store[S1, _] ⊗ Store[S2, _]) ~> (Monomial[(A, B), C, _] ⊗ Monomial[C, B, _]), Monomial[A, A => C, _], Y]: + def φ: Phi[(Store[S1, _] ⊗ Store[S2, _]) ~> (Monomial[(A, B), C, _] ⊗ Monomial[C, B, _]), Monomial[A, A => C, _], Y] = + p.φ.andThen(w.φ) + def `φ#`: PhiSharp[(Store[S1, _] ⊗ Store[S2, _]) ~> (Monomial[(A, B), C, _] ⊗ Monomial[C, B, _]), Monomial[A, A => C, _], Y] = + (s, a) => p.`φ#`(s, w.`φ#`(p.φ(s), a)) + + extension [S1, S2, A1, B1, A2, B2, Y] (p: PolyMap[Store[S1, _] ⊗ Store[S2, _], Monomial[A1, B1, _] ⊗ Monomial[A2, B2, _], Y]) + @scala.annotation.targetName("andThenTensoredStoreTensoredMonoToTensoredMono") + def andThen[A3, B3, A4, B4]( + w: PolyMap[Monomial[A1, B1, _] ⊗ Monomial[A2, B2, _], Monomial[A3, B3, _] ⊗ Monomial[A4, B4, _], Y] + ): PolyMap[PolyMap[Store[S1, _] ⊗ Store[S2, _], Monomial[A1, B1, _] ⊗ Monomial[A2, B2, _], _], Monomial[A3, B3, _] ⊗ Monomial[A4, B4, _], Y] = + new PolyMap[PolyMap[Store[S1, _] ⊗ Store[S2, _], Monomial[A1, B1, _] ⊗ Monomial[A2, B2, _], _], Monomial[A3, B3, _] ⊗ Monomial[A4, B4, _], Y]: + def φ: Phi[PolyMap[Store[S1, _] ⊗ Store[S2, _], Monomial[A1, B1, _] ⊗ Monomial[A2, B2, _], _], Monomial[A3, B3, _] ⊗ Monomial[A4, B4, _], Y] = + p.φ.andThen(w.φ) + def `φ#`: PhiSharp[PolyMap[Store[S1, _] ⊗ Store[S2, _], Monomial[A1, B1, _] ⊗ Monomial[A2, B2, _], _], Monomial[A3, B3, _] ⊗ Monomial[A4, B4, _], Y] = + (s, a) => p.`φ#`(s, w.`φ#`(p.φ(s), a)) extension [S1, S2, A1, B1, A2, B2, A3, B3, A4, B4, Y] (p: PolyMap[(Store[S1, _] ⊗ Store[S2, _]), (Binomial[A1, B1, A2, B2, _] ⊗ Binomial[A3, B3, A4, B4, _]), Y]) @scala.annotation.targetName("andThenTensorStoreTensorBiToBi") @@ -76,8 +142,8 @@ object morphism: ) def `φ#`: PhiSharp[PolyMap[(Store[S1, _] ⊗ Store[S2, _]), (Binomial[A1, B1, A2, B2, _] ⊗ Binomial[A3, B3, A4, B4, _]), _], Binomial[A1, A1 => B3, A2, A2 => B4, _], Y] = ( - (s, a1) => p.`φ#`._1(s, (a1, f(s._2))), - (s, a2) => p.`φ#`._2(s, (a2, g(s._1))) + (s: (S1, S2), a1: A1) => p.`φ#`._1(s, (a1, f(s._2))), + (s: (S1, S2), a2: A2) => p.`φ#`._2(s, (a2, g(s._1))) ) extension [S, A1, B1, A2, B2, Y] (p: PolyMap[Store[S, _], Binomial[A1, B1, A2, B2, _], Y]) diff --git a/modules/poly/shared/src/main/scala/polynomial/object.scala b/modules/poly/shared/src/main/scala/polynomial/object.scala index d19bc17..c8d734e 100644 --- a/modules/poly/shared/src/main/scala/polynomial/object.scala +++ b/modules/poly/shared/src/main/scala/polynomial/object.scala @@ -9,10 +9,10 @@ object `object`: type Terminal[Y] = Monomial[Nothing, Unit, Y] // `Syˢ` - type Store[S, Y] = cats.data.Store[S, Y] + case class Store[S, Y](yᵉˣᵖ: S => Y, coeff: S) // isomorphic to `cats.data.Store[S, Y]` // Byᴬ - case class Monomial[A, B, Y](yᵉˣᵖ: A => Y, coeff: B) // isomorphic to `cats.data.Store[S, Y]` when `A =:= B` + case class Monomial[A, B, Y](yᵉˣᵖ: A => Y, coeff: B) // B₁yᴬ¹ + B₂yᴬ² sealed trait Binomial[+A1, +B1, +A2, +B2, Y] diff --git a/modules/poly/shared/src/main/scala/polynomial/product/Tensor.scala b/modules/poly/shared/src/main/scala/polynomial/product/Tensor.scala index 1d3586d..2a2b8c0 100644 --- a/modules/poly/shared/src/main/scala/polynomial/product/Tensor.scala +++ b/modules/poly/shared/src/main/scala/polynomial/product/Tensor.scala @@ -5,8 +5,15 @@ import polynomial.morphism.PolyMap type ⊗[P[_], Q[_]] = Tensor[P, Q, _] -type Tensor[P[_], Q[_], Y] = (P[Y], Q[Y]) match - case (Binomial[a1, b1, a2, b2, Y], Binomial[a3, b3, a4, b4, Y]) => Binomial[(a1, a3), (b1, b3), (a2, a4), (b2, b4), Y] - case (Monomial[a1, b1, Y], Monomial[a2, b2, Y]) => Monomial[(a1, a2), (b1, b2), Y] - case (PolyMap[Store[s1, _], Monomial[a1, b1, _], Y], PolyMap[Store[s2, _], Monomial[a2, b2, _], Y]) => PolyMap[Store[(s1, s2), _], Monomial[(a1, a2), (b1, b2), _], Y] - case (Store[s1, Y], Store[s2, Y]) => Store[(s1, s2), Y] \ No newline at end of file +abstract class Tensor[P[_], Q[_], Y] +object Tensor: + + type DayConvolution[P[_], Q[_], Y] = (P[Y], Q[Y]) match + case (Binomial[a1, b1, a2, b2, Y], Binomial[a3, b3, a4, b4, Y]) => Binomial[(a1, a3), (b1, b3), (a2, a4), (b2, b4), Y] + case (Monomial[a1, b1, Y], Monomial[a2, b2, Y]) => Monomial[(a1, a2), (b1, b2), Y] + case (PolyMap[o, p, Y], PolyMap[q, r, Y]) => PolyMap[DayConvolution[o, q, _], DayConvolution[p, r, _], Y] + case (Store[s1, Y], Store[s2, Y]) => Store[(s1, s2), Y] + + + +