package tf.bug.fancade 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(fanscript) val justSecondInput: Number → (Number × Number) = branch >>> sumAsFirstInput val addSum: Number → Number = add.ldimap(justSecondInput) 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) } }