From 9d0632f645e1f5eda8c48e3b537132cf67042576 Mon Sep 17 00:00:00 2001 From: Aly Date: Thu, 6 May 2021 21:53:09 -0700 Subject: [PATCH] Working summation --- .gitignore | Bin 2854 -> 4096 bytes build.sbt | 5 +- .../main/scala/tf/bug/fancade/Fanscript.scala | 12 +- core/src/main/scala/tf/bug/fancade/Main.scala | 176 +++++++++++++++++- project/build.properties | 2 +- 5 files changed, 186 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index c6232286a9c882c2bd10af7ce21c9fab9cf84a05..24ec9f16cc249473a447abf0d7d1e4ba2ec5e622 100644 GIT binary patch literal 4096 zcmeHJTW{Mo6yCFb1qZ)usU@XJ7qkV2p>?t%#R3#|yFMBebu7`LM3toMc)xxhNy(RV z16p8vOCFNw+|PGzOeSn*h&w7-v17G!oqe6>+wC@Ux^rA*LN|Fy8&bL>WAjQnS+&|w z&O4c}$rXmn);{A(O*hi^Tv^wbQVU(uv>{lqQ(L&H6}={HABrx2q3 z^?Us#lgWg=C--(ABm)Iu%=8A?99Zo3`o_Lyx2+?kl`wlrlQ>Tcn*X{PK= z*Ufxd?89zWb5EK5A$1EzTN*7(wg{dXX3Pm=*IKTSk#fz7huM!yiWXYtqBOzB(Fu=ZAB^jLY{Ol~> zYIAQpE+~6w)Pd}{y|<^N-tvkv>$sB^ZXR(Bmz80 z2#wrYcL%&w@CV@qwHEEOA*KzhWmTu5?oG=csg~UFh3<_&!Uuy#R3v%i>6oE3+Uztv z`$b(J44(4JUCSFOPKmv|CW{^?b4o9ZmTzRm(F=j$vp2j{bcnGE-=}IyVnPCXdxg*z zcYH%F+e%k6-aDPj#&-Z@KG&f4R<_k(-=p=<(o?q6J+rm$RmtcMPkED%E)Qf}8`)(KB>@N7!k>Ep}mN^qPcYD-1q&3EXY1 zH#;tfME5TEX*yC)x76m?a;cxb6JN_Axgh)gcK&AMa;LbplDA$bjp2=LHS3M_Q!-O} z-5VNJBH)HPtXPcPUfOV5tDPU+L6ZH1upcd@Q0OuGpA!^mDGrKDdhp%1w9f1SIbvsk z1KZ#E9dJaBfFCngyfB!jBXMBnSH3m_uye8wiAnUJ6oA8uqObuO(%YWee*SHaeJVZTxB z^6ESp^7QRDCvJ6nI3V9>1Kg{f- z)_x6m)P`qCcu1ts%e1L-Lkf^kUTR_UcX6K6g~L{&GQXBsbi=}_U85#AN-J6QzQ1qLg^|p{|ry5_@3}@j)>>R`ezk_{4pE;jrV+w8XRb7 z!B*5+Ai^{>(*0}TU#x#U5X?7yIH$POArGck`%A4`Y%SPgH+bNHK6ds0^=|y(>E{W7 OCj_1lctYSmM&NIihor&) literal 2854 zcmcImOK;mo5WXAGf7rs8))7fNc8w%JQ6#c!IH&tnr@^ETsa>qX@sd@+5&2DQ&;+_6I}5LTDz^JXWajYsoy=cokAbo zZ$E4hO`e{zkKjM-{bWcXPiAI=5gmB!{^r)bWB1yFQu5=J%|p3+kQ%1!vFR4x*mla^ zcioIaV~@L8!-+EcQyPs7U0EY5wus?R*%v6I2;;h9b6J5Un{!x!1ufv+9srr_tuq(8 z&RC!CV~p50q5z!*S8(g4P~eK!=hwepUA?({J2@ehpB>oDbs*$Q3Wn&fR+Ez)4f5jb ztk@d+6@zD?LItcfRZx&1 zo{~aTC4l(`c4$v2Rsypi(oC2}XIj2vf(HjIrYC3Yv&ON|VnUf*C1*&}$kUv@QxQ_# zuDI}+pMiwJ9TrHB*Far!JBQ9-MHs>)VKp$5+egH+TvAaVy&=M$gMT{gJfh7W_!Fi? zwD^;iL8>Y{!*U|lgVD8Nx6hrz$!1xnLM`3W)#Y>CbHx?iiX>SY}nV|DRy~%PC=wnNX0n^?u!OxsZ`#-U`2*6{D{q zp3)e4I((*%cg66H2sEhH*d6|hHH^Qg7e(^Yb$bBl0!t8_<$^{CB}$okc<@&|-_rd; zH%^c9#?dWDPXCnm|I_iX#{7(kSgTqzd7`2P6w3D3$A8-RM*A>ok+`+-CWvt{vl`k3 Wn?U2(i~86to>s^jy5N7iTK@rB0;@s* diff --git a/build.sbt b/build.sbt index c034ffd..1a9f98f 100644 --- a/build.sbt +++ b/build.sbt @@ -2,8 +2,9 @@ lazy val core = (project in file("core")).settings( organization := "tf.bug", name := "fancade", version := "2.0.0-SNAPSHOT", - scalaVersion := "2.13.4", + scalaVersion := "2.13.5", libraryDependencies ++= Seq( - "tf.bug" %% "shinji" % "0.1.3", + "tf.bug" %% "shinji" % "0.1.6", + "com.lihaoyi" %% "pprint" % "0.5.6", ), ) diff --git a/core/src/main/scala/tf/bug/fancade/Fanscript.scala b/core/src/main/scala/tf/bug/fancade/Fanscript.scala index 7146973..623e5e6 100644 --- a/core/src/main/scala/tf/bug/fancade/Fanscript.scala +++ b/core/src/main/scala/tf/bug/fancade/Fanscript.scala @@ -1,6 +1,6 @@ package tf.bug.fancade -import tf.bug.shinji.{Arrow, Cartesian, Monoidal} +import tf.bug.shinji.{Arrow, ArrowLoop, Cartesian, Monoidal} object Fanscript { @@ -25,6 +25,9 @@ object Fanscript { case class Duplicate[A <: Pin]() extends (A → (A × A)) case class Terminate[A <: Pin]() extends (A → T) case class Bimap[A <: Pin, B <: Pin, C <: Pin, D <: Pin](f: A → B, g: C → D) extends ((A × C) → (B × D)) + case class Loop[A <: Pin, B <: Pin, C <: Pin](f: (A × C) → (B × C)) extends (A → B) + + case object Z extends (T → Pull) object Builtin { @@ -163,7 +166,7 @@ object Fanscript { } - implicit val arr: Cartesian[Pin, →, T, ×] with Arrow[Pin, →, T, ×, →] = new Cartesian[Pin, →, T, ×] with Arrow[Pin, →, T, ×, →] { + implicit lazy val fanscript: Cartesian[Pin, →, T, ×] with ArrowLoop[Pin, →, T, ×, →] = new Cartesian[Pin, →, T, ×] with ArrowLoop[Pin, →, T, ×, →] { override def id[A <: Pin]: A → A = Id[A]() @@ -180,7 +183,7 @@ object Fanscript { override def lift[A <: Pin, B <: Pin](f: A → B): A → B = f - override val strongProfunctorCategory: Monoidal[Pin, →, T, ×] = this + override def strongProfunctorCategory: Monoidal[Pin, →, T, ×] = this override def first[A <: Pin, B <: Pin, C <: Pin]: (A → B) ⇒ ((A × C) → (B × C)) = Bimap[A, B, C, C](_, id[C]) @@ -191,6 +194,9 @@ object Fanscript { AndThen(Swap(), AndThen(firstf, Swap())) } + override def loop[A <: Pin, B <: Pin, C <: Pin](f: (A × C) → (B × C)): A → B = + Loop(f) + override def associateRight[A <: Pin, B <: Pin, C <: Pin]: ((A × B) × C) → (A × (B × C)) = Associate[A, B, C]() diff --git a/core/src/main/scala/tf/bug/fancade/Main.scala b/core/src/main/scala/tf/bug/fancade/Main.scala index 495f41f..9edf143 100644 --- a/core/src/main/scala/tf/bug/fancade/Main.scala +++ b/core/src/main/scala/tf/bug/fancade/Main.scala @@ -5,19 +5,189 @@ object Main { def main(args: Array[String]): Unit = { import Fanscript._ import tf.bug.shinji.syntax.all._ + // min, max, start, result, after -> end, index, sum, before val sum: (Number × Number × Pull × Number × Pull) → (Pull × Number × Number × Pull) = { val getSum: T → Number = Builtin.GetNumber("Sum") + val setSum: (Number × Pull) → Pull = Builtin.SetNumber("Sum") val addToSum: (Number × Pull) → Pull = { val add: (Number × Number) → Number = Builtin.AddNumbers val sumAsFirstInput: (T × Number) → (Number × Number) = getSum.first[Number] - val branch: Number → (T × Number) = deunitL + val branch: Number → (T × Number) = deunitL(fanscript) val justSecondInput: Number → (Number × Number) = branch >>> sumAsFirstInput val addSum: Number → Number = add.ldimap(justSecondInput) - val storeSum: (Number × Pull) → Pull = Builtin.SetNumber("Sum") - storeSum.ldimap(arr.lbimap(addSum)) + val storeSum: (Number × Pull) → Pull = setSum + storeSum.ldimap(fanscript.lbimap(addSum)) } + val getIndex: T → Number = Builtin.GetNumber("Index") + val setIndex: (Number × Pull) → Pull = Builtin.SetNumber("Index") + val indexGreaterThan: Number → Bool = { + val greaterThan: (Number × Number) → Bool = Builtin.GreaterThan + val indexAsFirstInput: (T × Number) → (Number × Number) = getIndex.first[Number] + val branch: Number → (T × Number) = deunitL(fanscript) + val comparisonAsSecondInput: Number → (Number × Number) = branch >>> indexAsFirstInput + comparisonAsSecondInput >>> greaterThan + } + val indexNotGreaterThan: Number → Bool = indexGreaterThan >>> Builtin.Not + val checkContinue: (Number × Pull × Pull × Pull) → Pull = { + val ifBlock: (Bool × Pull × Pull × Pull) → Pull = Builtin.If + val checkGreater: (Number × Pull × Pull × Pull) → (Bool × Pull × Pull × Pull) = { + val one: (Number × Pull) → (Bool × Pull) = indexGreaterThan.first[Pull] + val two: (Number × Pull × Pull) → (Bool × Pull × Pull) = fanscript.first(one) + val three: (Number × Pull × Pull × Pull) → (Bool × Pull × Pull × Pull) = fanscript.first(two) + three + } + fanscript.andThen(checkGreater, ifBlock) + } + + // sumToIndex -> before + val initializeSum: Pull → Pull = { + val zero: T → Number = Builtin.NumberValue(0.0F) + val zeroAsInput: (T × Pull) → (Number × Pull) = zero.first[Pull] + val branch: Pull → (T × Pull) = fanscript.deunitorLeft[Pull] + branch >>> zeroAsInput >>> setSum + } + + // min, indexToLoopStart -> sumToIndex + val initializeIndex: (Number × Pull) → Pull = setIndex + + // max, start, ◌, after -> (indexToLoopStart + incrementToLoop) + val startLoop: (Number × Pull × Pull × Pull) → Pull = checkContinue + + // result, increaseSum -> end + val increaseSum: (Number × Pull) → Pull = addToSum + + // incrementToLoop -> increaseSum + val incrementIndex: Pull → Pull = { + val get: T → Number = getIndex + val set: (Number × Pull) → Pull = setIndex + val one: T → Number = Builtin.NumberValue(1.0F) + val additionOperands: T → (Number × Number) = get &&& one + val add: T → Number = additionOperands >>> Builtin.AddNumbers + val carryPull: (T × Pull) → (Number × Pull) = add.first[Pull] + val branch: Pull → (T × Pull) = fanscript.deunitorLeft[Pull] + branch >>> carryPull >>> set + } + + // min, indexToLoopStart -> before + val initialize: (Number × Pull) → Pull = initializeIndex >>> initializeSum + + // result, incrementToLoop -> end + val postLoop: (Number × Pull) → Pull = { + val carryResult = fanscript.second[Pull, Pull, Number](incrementIndex) + fanscript.andThen(carryResult, increaseSum) + } + + // max, start, after -> (indexToLoopStart + incrementToLoop) + val condition: (Number × Pull × Pull) → Pull = { + val zThree: (Number × Pull) → (Number × Pull × Pull) = + fanscript.andThen(fanscript.deunitorRight, fanscript.rbimap(Z)) + val zFour: (Number × Pull × Pull) → (Number × Pull × Pull × Pull) = + fanscript.lbimap(zThree) + fanscript.ldimap(zFour)(checkContinue) + } + + // min, max, start, result, after -> end, index, sum, before + val result: (Number × Number × Pull × Number × Pull) → (Pull × Number × Number × Pull) = { + // max, start, after -> indexToLoopStart, incrementToLoop + val duplicateCondition: (Number × Pull × Pull) → (Pull × Pull) = + fanscript.andThen(condition, fanscript.duplicate) + + // min, indexToLoopStart, result, incrementToLoop -> before, end + val conditionPrecursors: (Number × Pull × Number × Pull) → (Pull × Pull) = + fanscript.andThen(fanscript.associateRight[Number × Pull, Number, Pull], fanscript.split[Number × Pull, Pull, Number × Pull, Pull](initialize, postLoop)) + + // min, result, (indexToLoopStart, incrementToLoop) -> end, before + val orientConditionPrecursors: ((Number × Number) × (Pull × Pull)) → (Pull × Pull) = { + val flattenAssoc: ((Number × Number) × (Pull × Pull)) → (((Number × Number) × Pull) × Pull) = fanscript.associateLeft + val assocInside: (((Number × Number) × Pull) × Pull) → ((Number × (Number × Pull)) × Pull) = fanscript.lbimap(fanscript.associateRight) + val swapInside: ((Number × (Number × Pull)) × Pull) → ((Number × (Pull × Number)) × Pull) = fanscript.lbimap(fanscript.rbimap(fanscript.swap)) + val reassocInside: ((Number × (Pull × Number)) × Pull) → (((Number × Pull) × Number) × Pull) = fanscript.lbimap(fanscript.associateLeft) + val orientConditionInputs: ((Number × Number) × (Pull × Pull)) → (((Number × Pull) × Number) × Pull) = + fanscript.andThen(fanscript.andThen(fanscript.andThen(flattenAssoc, assocInside), swapInside), reassocInside) + + val swapEnd: (Pull × Pull) → (Pull × Pull) = fanscript.swap + + fanscript.dimap(orientConditionInputs, swapEnd)(conditionPrecursors) + } + + // min, max, start, result, after -> end, before + val nonNumbers: (Number × Number × Pull × Number × Pull) → (Pull × Pull) = { + val duplicateConditionLeftNumbers: ((Number × Number) × (Number × Pull × Pull)) → ((Number × Number) × (Pull × Pull)) = + fanscript.second[Number × Pull × Pull, Pull × Pull, Number × Number](duplicateCondition) + + // (min, result), (max, start, after) -> end, before + val aggregate: ((Number × Number) × (Number × Pull × Pull)) → (Pull × Pull) = + fanscript.andThen(duplicateConditionLeftNumbers, orientConditionPrecursors) + + // (max, start, after, (min, result)) -> end, before + val align: (Number × Pull × Pull × (Number × Number)) → (Pull × Pull) = + fanscript.andThen(fanscript.swap, aggregate) + + // max, start, after, min, result -> end, before + val assoc: (Number × Pull × Pull × Number × Number) → (Pull × Pull) = + fanscript.andThen(fanscript.associateRight, align) + + // min, max, start, result, after -> max, start, after, min, result + val realign: ((((Number × Number) × Pull) × Number) × Pull) → ((((Number × Pull) × Pull) × Number) × Number) = { + val one: ((((Number × Number) × Pull) × Number) × Pull) → (((Number × (Number × Pull)) × Number) × Pull) = + fanscript.lbimap(fanscript.lbimap(fanscript.associateRight)) + val two: (((Number × (Number × Pull)) × Number) × Pull) → ((((Number × Pull) × Number) × Number) × Pull) = + fanscript.lbimap(fanscript.lbimap(fanscript.swap)) + val three: ((((Number × Pull) × Number) × Number) × Pull) → (((Number × Pull) × Number) × (Number × Pull)) = + fanscript.associateRight + val four: (((Number × Pull) × Number) × (Number × Pull)) → (((Number × Pull) × Number) × (Pull × Number)) = + fanscript.rbimap(fanscript.swap) + val five: (((Number × Pull) × Number) × (Pull × Number)) → ((((Number × Pull) × Number) × Pull) × Number) = + fanscript.associateLeft + val six: ((((Number × Pull) × Number) × Pull) × Number) → (((Number × Pull) × (Number × Pull)) × Number) = + fanscript.lbimap(fanscript.associateRight) + val seven: (((Number × Pull) × (Number × Pull)) × Number) → (((Number × Pull) × (Pull × Number)) × Number) = + fanscript.lbimap(fanscript.rbimap(fanscript.swap)) + val eight: (((Number × Pull) × (Pull × Number)) × Number) → ((((Number × Pull) × Pull) × Number) × Number) = + fanscript.lbimap(fanscript.associateLeft) + + fanscript.andThen( + fanscript.andThen( + fanscript.andThen( + fanscript.andThen( + fanscript.andThen( + fanscript.andThen( + fanscript.andThen( + one, + two + ), + three + ), + four + ), + five + ), + six + ), + seven + ), + eight + ) + } + + fanscript.andThen(realign, assoc) + } + + // end, before -> end, index, sum, before + val addOutputs: (Pull × Pull) → (Pull × Number × Number × Pull) = + fanscript.lbimap(fanscript.andThen( + fanscript.andThen[Pull, Pull × T, Pull × Number](fanscript.deunitorRight[Pull], fanscript.rbimap(getIndex)), + fanscript.andThen[Pull × Number, Pull × Number × T, Pull × Number × Number](fanscript.deunitorRight[Pull × Number], fanscript.rbimap(getSum)) + )) + + fanscript.andThen(nonNumbers, addOutputs) + } + + result } + + pprint.pprintln(sum) } } diff --git a/project/build.properties b/project/build.properties index 0b2e09c..f0be67b 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.4.7 +sbt.version=1.5.1