From 57196c568b3b7f191c53f49965c593b4818bea26 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Fri, 8 Apr 2022 14:42:14 -0400 Subject: [PATCH] Added a bunch of manual functions for DistributionOperation --- packages/squiggle-lang/bsconfig.json | 2 +- packages/squiggle-lang/src/js/index.ts | 190 ++++++++++++++++-- .../DistributionOperation.res | 47 +++++ .../DistributionOperation.resi | 36 ++++ .../GenericDist/GenericDist_Types.res | 75 ++++++- .../Distributions/SampleSetDist/SampleSet.res | 1 + .../src/rescript/TSInterface.res | 14 ++ 7 files changed, 348 insertions(+), 17 deletions(-) create mode 100644 packages/squiggle-lang/src/rescript/TSInterface.res diff --git a/packages/squiggle-lang/bsconfig.json b/packages/squiggle-lang/bsconfig.json index e936eb82..958a3af8 100644 --- a/packages/squiggle-lang/bsconfig.json +++ b/packages/squiggle-lang/bsconfig.json @@ -33,7 +33,7 @@ "gentypeconfig": { "language": "typescript", "module": "commonjs", - "shims": {}, + "shims": {"Js": "Js"}, "debug": { "all": false, "basic": false diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index 7856ef6f..5f12bf56 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -1,17 +1,181 @@ -import {runAll} from '../rescript/ProgramEvaluator.gen'; -import type { Inputs_SamplingInputs_t as SamplingInputs, exportEnv, exportType, exportDistribution} from '../rescript/ProgramEvaluator.gen'; -export type { SamplingInputs, exportEnv, exportDistribution } -export type {t as DistPlus} from '../rescript/OldInterpreter/DistPlus.gen'; +import { runAll } from "../rescript/ProgramEvaluator.gen"; +import type { + Inputs_SamplingInputs_t as SamplingInputs, + exportEnv, + exportType, + exportDistribution, +} from "../rescript/ProgramEvaluator.gen"; +export type { SamplingInputs, exportEnv, exportDistribution }; +export type { t as DistPlus } from "../rescript/OldInterpreter/DistPlus.gen"; +import type { Operation_genericFunctionCallInfo } from "../rescript/Distributions/GenericDist/GenericDist_Types.gen"; +import { genericDist } from "../rescript/TSInterface.gen"; +import { + run as runR, + env, + outputType, +} from "../rescript/Distributions/DistributionOperation/DistributionOperation.gen"; +import { add } from "lodash"; -export let defaultSamplingInputs : SamplingInputs = { - sampleCount : 10000, - outputXYPoints : 10000, - pointDistLength : 1000 +export let defaultSamplingInputs: SamplingInputs = { + sampleCount: 10000, + outputXYPoints: 10000, + pointDistLength: 1000, +}; + +export function run( + squiggleString: string, + samplingInputs?: SamplingInputs, + environment?: exportEnv +): { tag: "Ok"; value: exportType } | { tag: "Error"; value: string } { + let si: SamplingInputs = samplingInputs + ? samplingInputs + : defaultSamplingInputs; + let env: exportEnv = environment ? environment : []; + return runAll(squiggleString, si, env); } -export function run(squiggleString : string, samplingInputs? : SamplingInputs, environment?: exportEnv) : { tag: "Ok"; value: exportType } - | { tag: "Error"; value: string } { - let si : SamplingInputs = samplingInputs ? samplingInputs : defaultSamplingInputs - let env : exportEnv = environment ? environment : [] - return runAll(squiggleString, si, env) +class GenericDist { + t: genericDist; + env: env; + + constructor(t: genericDist, env: env) { + this.t = t; + } + + mean(): outputType { + return runR( + { env: this.env }, + { tag: "FromDist", value: [{ tag: "ToFloat", value: "Mean" }, this.t] } + ); + } + + pdf(n: number): outputType { + return runR( + { env: this.env }, + { + tag: "FromDist", + value: [{ tag: "ToFloat", value: { NAME: "Pdf", VAL: n } }, this.t], + } + ); + } + + cdf(n: number): outputType { + return runR( + { env: this.env }, + { + tag: "FromDist", + value: [{ tag: "ToFloat", value: { NAME: "Pdf", VAL: n } }, this.t], + } + ); + } + + inv(n: number): outputType { + return runR( + { env: this.env }, + { + tag: "FromDist", + value: [{ tag: "ToFloat", value: { NAME: "Pdf", VAL: n } }, this.t], + } + ); + } + + normalize(n: number): outputType { + return runR( + { env: this.env }, + { + tag: "FromDist", + value: [{ tag: "ToDist", value: "Normalize" }, this.t], + } + ); + } + + toPointSet(): outputType { + return runR( + { env: this.env }, + { + tag: "FromDist", + value: [{ tag: "ToDist", value: "ToPointSet" }, this.t], + } + ); + } + + inspect(): outputType { + return runR( + { env: this.env }, + { tag: "FromDist", value: [{ tag: "ToDist", value: "Inspect" }, this.t] } + ); + } + + toSampleSet(n: number): outputType { + return runR( + { env: this.env }, + { + tag: "FromDist", + value: [ + { tag: "ToDist", value: { tag: "ToSampleSet", value: n } }, + this.t, + ], + } + ); + } + + truncate( + left: null | undefined | number, + right: null | undefined | number + ): outputType { + return runR( + { env: this.env }, + { + tag: "FromDist", + value: [ + { tag: "ToDist", value: { tag: "Truncate", value: [left, right] } }, + this.t, + ], + } + ); + } + + toString(): outputType { + return runR( + { env: this.env }, + { + tag: "FromDist", + value: [{ tag: "ToString", value: "ToString" }, this.t], + } + ); + } + + toSparkline(n: number): outputType { + return runR( + { env: this.env }, + { + tag: "FromDist", + value: [ + { tag: "ToString", value: { tag: "ToSparkline", value: n } }, + this.t, + ], + } + ); + } + + add(g2: genericDist): outputType { + return runR( + { env: this.env }, + { + tag: "FromDist", + value: [ + { + tag: "ToDistCombination", + value: [ + { + tag: "ToDistCombination", + value: ["Algebraic", "Add", { NAME: "Dist", VAL: g2 }], + }, + ], + }, + this.t, + ], + } + ); + } } diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res index 14e7b6c4..1d25f64c 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res @@ -185,3 +185,50 @@ module Output = { newFnCall->E.R2.fmap(run(~env))->OutputLocal.fromResult } } + +module Constructors = { + module UsingDists = { + module C = GenericDist_Types.Constructors.UsingDists + open OutputLocal + type dist = GenericDist_Types.genericDist + type fResult = result + type dResult = result + type sResult = result + + let mean = (~env, dist) => run(~env, C.mean(dist))->toFloatR + let sample = (~env, dist) => run(~env, C.sample(dist))->toFloatR + let cdf = (~env, dist, f) => run(~env, C.cdf(dist, f))->toFloatR + let inv = (~env, dist, f) => run(~env, C.inv(dist, f))->toFloatR + let pdf = (~env, dist, f) => run(~env, C.pdf(dist, f))->toFloatR + let normalize = (~env, dist) => run(~env, C.normalize(dist))->toDistR + let toPointSet = (~env, dist) => run(~env, C.toPointSet(dist))->toDistR + let toSampleSet = (~env, dist, n) => run(~env, C.toSampleSet(dist, n))->toDistR + let truncate = (~env, dist, leftCutoff, rightCutoff) => + run(~env, C.truncate(dist, leftCutoff, rightCutoff))->toDistR + let inspect = (~env, dist) => run(~env, C.inspect(dist))->toDistR + let toString = (~env, dist) => run(~env, C.toString(dist))->toStringR + let toSparkline = (~env, dist, buckets) => run(~env, C.toSparkline(dist, buckets))->toStringR + let algebraicAdd = (~env, dist1, dist2) => run(~env, C.algebraicAdd(dist1, dist2))->toDistR + let algebraicMultiply = (~env, dist1, dist2) => + run(~env, C.algebraicMultiply(dist1, dist2))->toDistR + let algebraicDivide = (~env, dist1, dist2) => + run(~env, C.algebraicDivide(dist1, dist2))->toDistR + let algebraicSubtract = (~env, dist1, dist2) => + run(~env, C.algebraicSubtract(dist1, dist2))->toDistR + let algebraicLogarithm = (~env, dist1, dist2) => + run(~env, C.algebraicLogarithm(dist1, dist2))->toDistR + let algebraicExponentiate = (~env, dist1, dist2) => + run(~env, C.algebraicExponentiate(dist1, dist2))->toDistR + let pointwiseAdd = (~env, dist1, dist2) => run(~env, C.pointwiseAdd(dist1, dist2))->toDistR + let pointwiseMultiply = (~env, dist1, dist2) => + run(~env, C.pointwiseMultiply(dist1, dist2))->toDistR + let pointwiseDivide = (~env, dist1, dist2) => + run(~env, C.pointwiseDivide(dist1, dist2))->toDistR + let pointwiseSubtract = (~env, dist1, dist2) => + run(~env, C.pointwiseSubtract(dist1, dist2))->toDistR + let pointwiseLogarithm = (~env, dist1, dist2) => + run(~env, C.pointwiseSubtract(dist1, dist2))->toDistR + let pointwiseExponentiate = (~env, dist1, dist2) => + run(~env, C.pointwiseSubtract(dist1, dist2))->toDistR + } +} diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.resi b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.resi index 3c3e132a..e39d5848 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.resi +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.resi @@ -1,14 +1,17 @@ +@genType type env = { sampleCount: int, xyPointLength: int, } +@genType type outputType = | Dist(GenericDist_Types.genericDist) | Float(float) | String(string) | GenDistError(GenericDist_Types.error) +@genType let run: (~env: env, GenericDist_Types.Operation.genericFunctionCallInfo) => outputType let runFromDist: ( ~env: env, @@ -32,3 +35,36 @@ module Output: { let toError: t => option let fmap: (~env: env, t, GenericDist_Types.Operation.singleParamaterFunction) => t } + +module Constructors: { + module UsingDists: { + type dist = GenericDist_Types.genericDist + type fResult = result + type dResult = result + type sResult = result + let mean: (~env: env, dist) => fResult + let sample: (~env: env, dist) => fResult + let cdf: (~env: env, dist, float) => fResult + let inv: (~env: env, dist, float) => fResult + let pdf: (~env: env, dist, float) => fResult + let normalize: (~env: env, dist) => dResult + let toPointSet: (~env: env, dist) => dResult + let toSampleSet: (~env: env, dist, int) => dResult + let truncate: (~env: env, dist, option, option) => dResult + let inspect: (~env: env, dist) => dResult + let toString: (~env: env, dist) => sResult + let toSparkline: (~env: env, dist, int) => sResult + let algebraicAdd: (~env: env, dist, dist) => dResult + let algebraicMultiply: (~env: env, dist, dist) => dResult + let algebraicDivide: (~env: env, dist, dist) => dResult + let algebraicSubtract: (~env: env, dist, dist) => dResult + let algebraicLogarithm: (~env: env, dist, dist) => dResult + let algebraicExponentiate: (~env: env, dist, dist) => dResult + let pointwiseAdd: (~env: env, dist, dist) => dResult + let pointwiseMultiply: (~env: env, dist, dist) => dResult + let pointwiseDivide: (~env: env, dist, dist) => dResult + let pointwiseSubtract: (~env: env, dist, dist) => dResult + let pointwiseLogarithm: (~env: env, dist, dist) => dResult + let pointwiseExponentiate: (~env: env, dist, dist) => dResult + } +} diff --git a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist_Types.res b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist_Types.res index 0eb64bd7..f472a6e0 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist_Types.res +++ b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist_Types.res @@ -3,6 +3,7 @@ type genericDist = | SampleSet(SampleSet.t) | Symbolic(SymbolicDistTypes.symbolicDist) +@genType type error = | NotYetImplemented | Unreachable @@ -52,9 +53,9 @@ module Operation = { type toFloatArray = Sample(int) - type toString = - | ToString - | ToSparkline(int) + type toString = + | ToString + | ToSparkline(int) type fromDist = | ToFloat(toFloat) @@ -66,6 +67,7 @@ module Operation = { | FromDist(fromDist) | FromFloat(fromDist) + @genType type genericFunctionCallInfo = | FromDist(fromDist, genericDist) | FromFloat(fromDist, float) @@ -95,3 +97,70 @@ module Operation = { | Mixture(_) => `mixture` } } + +module Constructors = { + type t = Operation.genericFunctionCallInfo + + module UsingDists = { + let mean = (dist): t => FromDist(ToFloat(#Mean), dist) + let sample = (dist): t => FromDist(ToFloat(#Mean), dist) + let cdf = (dist, f): t => FromDist(ToFloat(#Cdf(f)), dist) + let inv = (dist, f): t => FromDist(ToFloat(#Inv(f)), dist) + let pdf = (dist, f): t => FromDist(ToFloat(#Pdf(f)), dist) + let normalize = (dist): t => FromDist(ToDist(Normalize), dist) + let toPointSet = (dist): t => FromDist(ToDist(ToPointSet), dist) + let toSampleSet = (dist, r): t => FromDist(ToDist(ToSampleSet(r)), dist) + let truncate = (dist, left, right): t => FromDist(ToDist(Truncate(left, right)), dist) + let inspect = (dist): t => FromDist(ToDist(Inspect), dist) + let toString = (dist): t => FromDist(ToString(ToString), dist) + let toSparkline = (dist, n): t => FromDist(ToString(ToSparkline(n)), dist) + let algebraicAdd = (dist1, dist2:genericDist): t => FromDist( + ToDistCombination(Algebraic, #Add, #Dist(dist2)), + dist1, + ) + let algebraicMultiply = (dist1, dist2): t => FromDist( + ToDistCombination(Algebraic, #Multiply, #Dist(dist2)), + dist1, + ) + let algebraicDivide = (dist1, dist2): t => FromDist( + ToDistCombination(Algebraic, #Divide, #Dist(dist2)), + dist1, + ) + let algebraicSubtract = (dist1, dist2): t => FromDist( + ToDistCombination(Algebraic, #Subtract, #Dist(dist2)), + dist1, + ) + let algebraicLogarithm = (dist1, dist2): t => FromDist( + ToDistCombination(Algebraic, #Logarithm, #Dist(dist2)), + dist1, + ) + let algebraicExponentiate = (dist1, dist2): t => FromDist( + ToDistCombination(Algebraic, #Exponentiate, #Dist(dist2)), + dist1, + ) + let pointwiseAdd = (dist1, dist2): t => FromDist( + ToDistCombination(Algebraic, #Add, #Dist(dist2)), + dist1, + ) + let pointwiseMultiply = (dist1, dist2): t => FromDist( + ToDistCombination(Pointwise, #Multiply, #Dist(dist2)), + dist1, + ) + let pointwiseDivide = (dist1, dist2): t => FromDist( + ToDistCombination(Pointwise, #Divide, #Dist(dist2)), + dist1, + ) + let pointwiseSubtract = (dist1, dist2): t => FromDist( + ToDistCombination(Pointwise, #Subtract, #Dist(dist2)), + dist1, + ) + let pointwiseLogarithm = (dist1, dist2): t => FromDist( + ToDistCombination(Pointwise, #Logarithm, #Dist(dist2)), + dist1, + ) + let pointwiseExponentiate = (dist1, dist2): t => FromDist( + ToDistCombination(Pointwise, #Exponentiate, #Dist(dist2)), + dist1, + ) + } +} diff --git a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSet.res b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSet.res index eebb9efc..3c8f686a 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSet.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSet.res @@ -1,3 +1,4 @@ +@genType type t = array // TODO: Refactor to raise correct error when not enough samples diff --git a/packages/squiggle-lang/src/rescript/TSInterface.res b/packages/squiggle-lang/src/rescript/TSInterface.res new file mode 100644 index 00000000..8df300f8 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/TSInterface.res @@ -0,0 +1,14 @@ +@genType +type functionCallInfo = GenericDist_Types.Operation.genericFunctionCallInfo; + +@genType +type env = DistributionOperation.env; + +@genType +type genericDist = GenericDist_Types.genericDist; + +@genType +type error = GenericDist_Types.error; + +@genType +let runDistributionOperation = DistributionOperation.run; \ No newline at end of file