From 61b589d0bd096decb7048b02c58f3b2790217817 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Mon, 11 Apr 2022 13:16:31 +1000 Subject: [PATCH] Change typescript interface to reducer --- packages/squiggle-lang/__tests__/JS__Test.ts | 31 ++--- packages/squiggle-lang/src/js/index.ts | 127 +++++++++++------- .../src/rescript/Reducer/Reducer.res | 1 + .../src/rescript/Reducer/Reducer.resi | 5 +- .../rescript/Reducer/Reducer_ErrorValue.res | 1 + .../Reducer_Expression.resi | 3 +- .../ReducerInterface_ExpressionValue.res | 1 + .../src/rescript/TypescriptInterface.res | 27 ++-- .../src/rescript/shims/Js.shim.ts | 1 + 9 files changed, 117 insertions(+), 80 deletions(-) create mode 100644 packages/squiggle-lang/src/rescript/shims/Js.shim.ts diff --git a/packages/squiggle-lang/__tests__/JS__Test.ts b/packages/squiggle-lang/__tests__/JS__Test.ts index ffba5b82..67e42e55 100644 --- a/packages/squiggle-lang/__tests__/JS__Test.ts +++ b/packages/squiggle-lang/__tests__/JS__Test.ts @@ -1,11 +1,10 @@ -import { run, Distribution, resultMap } from "../src/js/index"; +import { run, Distribution, resultMap, squiggleExpression } from "../src/js/index"; -let testRun = (x: string) => { - let result = run(x); - if (result.tag == "Ok") { - return { tag: "Ok", value: result.value.exports }; - } else { - return result; +let testRun = (x: string): squiggleExpression => { + let result = run(x, {sampleCount: 100, xyPointLength: 100}); + expect(result.tag).toEqual("Ok") + if(result.tag === "Ok") { + return result.value } }; @@ -16,29 +15,19 @@ function Ok(x: b) { describe("Simple calculations and results", () => { test("mean(normal(5,2))", () => { expect(testRun("mean(normal(5,2))")).toEqual({ - tag: "Ok", - value: [{ NAME: "Float", VAL: 5 }], + tag: "number", + value: 5 }); }); test("10+10", () => { let foo = testRun("10 + 10"); - expect(foo).toEqual({ tag: "Ok", value: [{ NAME: "Float", VAL: 20 }] }); + expect(foo).toEqual({ tag: "number", value: 20 }); }); }); describe("Log function", () => { test("log(1) = 0", () => { let foo = testRun("log(1)"); - expect(foo).toEqual({ tag: "Ok", value: [{ NAME: "Float", VAL: 0 }] }); - }); -}); - -describe("Multimodal too many weights error", () => { - test("mm(0,0,[0,0,0])", () => { - let foo = testRun("mm(0,0,[0,0,0])"); - expect(foo).toEqual({ - tag: "Error", - value: "Function multimodal error: Too many weights provided", - }); + expect(foo).toEqual({ tag: "number", value: 0 }); }); }); diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index 8ff08228..923303ef 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -1,13 +1,10 @@ -import { runAll } from "../rescript/ProgramEvaluator.gen"; +import * as _ from 'lodash' 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 { genericDist, env, error } from "../rescript/TypescriptInterface.gen"; +export type { exportEnv, exportDistribution }; +import { genericDist, samplingParams, evaluate, expressionValue, errorValue, distributionError } from "../rescript/TypescriptInterface.gen"; export { makeSampleSetDist } from "../rescript/TypescriptInterface.gen"; import { Constructors_mean, @@ -36,23 +33,16 @@ import { Constructors_pointwisePower, } from "../rescript/Distributions/DistributionOperation/DistributionOperation.gen"; -export let defaultSamplingInputs: SamplingInputs = { - sampleCount: 10000, - outputXYPoints: 10000, - pointDistLength: 1000, +export type SamplingInputs = { + readonly sampleCount?: number; + readonly outputXYPoints?: number; + readonly kernelWidth?: number; + readonly pointDistLength?: number +}; +export let defaultSamplingInputs: samplingParams = { + sampleCount: 10000, + xyPointLength: 10000 }; - -export function run( - squiggleString: string, - samplingInputs?: SamplingInputs, - environment?: exportEnv -): result { - let si: SamplingInputs = samplingInputs - ? samplingInputs - : defaultSamplingInputs; - let env: exportEnv = environment ? environment : []; - return runAll(squiggleString, si, env); -} type result = | { @@ -75,147 +65,186 @@ export function resultMap( } } +type tagged = {tag: a, value: b} + +function tag(x: a, y: b) : tagged{ + return { tag: x, value: y} +} + +export type squiggleExpression = tagged<"symbol", string> | tagged<"string", string> | tagged<"array", squiggleExpression[]> | tagged<"boolean", boolean> | tagged<"distribution", Distribution> | tagged<"number", number> | tagged<"record", {[key: string]: squiggleExpression }> +export function run( + squiggleString: string, + samplingInputs?: samplingParams, + _environment?: exportEnv +): result { + let si: samplingParams = samplingInputs + ? samplingInputs + : defaultSamplingInputs; + let result : result = evaluate(squiggleString); + return resultMap(result, x => createTsExport(x, si)); +} + + +function createTsExport(x: expressionValue, sampEnv: samplingParams): squiggleExpression { + switch (x.tag) { + case "EvArray": + return tag("array", x.value.map(x => createTsExport(x, sampEnv))); + case "EvBool": + return tag("boolean", x.value); + case "EvDistribution": + return tag("distribution", new Distribution(x.value, sampEnv)); + case "EvNumber": + return tag("number", x.value); + case "EvRecord": + return tag("record", _.mapValues(x.value, x => createTsExport(x, sampEnv))) + + + + } +} + + export function resultExn(r: result): a | c { return r.value; } export class Distribution { t: genericDist; - env: env; + env: samplingParams; - constructor(t: genericDist, env: env) { + constructor(t: genericDist, env: samplingParams) { this.t = t; this.env = env; return this; } - mapResultDist(r: result): result { + mapResultDist(r: result): result { return resultMap(r, (v: genericDist) => new Distribution(v, this.env)); } - mean(): result { + mean(): result { return Constructors_mean({ env: this.env }, this.t); } - sample(): result { + sample(): result { return Constructors_sample({ env: this.env }, this.t); } - pdf(n: number): result { + pdf(n: number): result { return Constructors_pdf({ env: this.env }, this.t, n); } - cdf(n: number): result { + cdf(n: number): result { return Constructors_cdf({ env: this.env }, this.t, n); } - inv(n: number): result { + inv(n: number): result { return Constructors_inv({ env: this.env }, this.t, n); } - normalize(): result { + normalize(): result { return this.mapResultDist( Constructors_normalize({ env: this.env }, this.t) ); } - toPointSet(): result { + toPointSet(): result { return this.mapResultDist( Constructors_toPointSet({ env: this.env }, this.t) ); } - toSampleSet(n: number): result { + toSampleSet(n: number): result { return this.mapResultDist( Constructors_toSampleSet({ env: this.env }, this.t, n) ); } - truncate(left: number, right: number): result { + truncate(left: number, right: number): result { return this.mapResultDist( Constructors_truncate({ env: this.env }, this.t, left, right) ); } - inspect(): result { + inspect(): result { return this.mapResultDist(Constructors_inspect({ env: this.env }, this.t)); } - toString(): result { + toString(): result { return Constructors_toString({ env: this.env }, this.t); } - toSparkline(n: number): result { + toSparkline(n: number): result { return Constructors_toSparkline({ env: this.env }, this.t, n); } - algebraicAdd(d2: Distribution): result { + algebraicAdd(d2: Distribution): result { return this.mapResultDist( Constructors_algebraicAdd({ env: this.env }, this.t, d2.t) ); } - algebraicMultiply(d2: Distribution): result { + algebraicMultiply(d2: Distribution): result { return this.mapResultDist( Constructors_algebraicMultiply({ env: this.env }, this.t, d2.t) ); } - algebraicDivide(d2: Distribution): result { + algebraicDivide(d2: Distribution): result { return this.mapResultDist( Constructors_algebraicDivide({ env: this.env }, this.t, d2.t) ); } - algebraicSubtract(d2: Distribution): result { + algebraicSubtract(d2: Distribution): result { return this.mapResultDist( Constructors_algebraicSubtract({ env: this.env }, this.t, d2.t) ); } - algebraicLogarithm(d2: Distribution): result { + algebraicLogarithm(d2: Distribution): result { return this.mapResultDist( Constructors_algebraicLogarithm({ env: this.env }, this.t, d2.t) ); } - algebraicPower(d2: Distribution): result { + algebraicPower(d2: Distribution): result { return this.mapResultDist( Constructors_algebraicPower({ env: this.env }, this.t, d2.t) ); } - pointwiseAdd(d2: Distribution): result { + pointwiseAdd(d2: Distribution): result { return this.mapResultDist( Constructors_pointwiseAdd({ env: this.env }, this.t, d2.t) ); } - pointwiseMultiply(d2: Distribution): result { + pointwiseMultiply(d2: Distribution): result { return this.mapResultDist( Constructors_pointwiseMultiply({ env: this.env }, this.t, d2.t) ); } - pointwiseDivide(d2: Distribution): result { + pointwiseDivide(d2: Distribution): result { return this.mapResultDist( Constructors_pointwiseDivide({ env: this.env }, this.t, d2.t) ); } - pointwiseSubtract(d2: Distribution): result { + pointwiseSubtract(d2: Distribution): result { return this.mapResultDist( Constructors_pointwiseSubtract({ env: this.env }, this.t, d2.t) ); } - pointwiseLogarithm(d2: Distribution): result { + pointwiseLogarithm(d2: Distribution): result { return this.mapResultDist( Constructors_pointwiseLogarithm({ env: this.env }, this.t, d2.t) ); } - pointwisePower(d2: Distribution): result { + pointwisePower(d2: Distribution): result { return this.mapResultDist( Constructors_pointwisePower({ env: this.env }, this.t, d2.t) ); diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer.res index 6e8dbdfa..7e93f367 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer.res @@ -5,5 +5,6 @@ module Extra = Reducer_Extra module Js = Reducer_Js module MathJs = Reducer_MathJs +type expressionValue = Reducer_Expression.expressionValue let evaluate = Expression.eval let parse = Expression.parse diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi b/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi index cf015a95..b5b811e6 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi @@ -6,5 +6,8 @@ module Js = Reducer_Js module MathJs = Reducer_MathJs @genType -let evaluate: string => result +type expressionValue = Reducer_Expression.expressionValue + +@genType +let evaluate: string => result let parse: string => result diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res index 4f57bc2c..666f5476 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res @@ -1,3 +1,4 @@ +@genType type errorValue = | REArrayIndexNotFound(string, int) | REFunctionExpected(string) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.resi b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.resi index 8b09c516..2a6db9bd 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.resi +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.resi @@ -1,7 +1,8 @@ module Result = Belt.Result module T = Reducer_Expression_T type expression = T.expression -type expressionValue = ReducerInterface.ExpressionValue.expressionValue +@genType +type expressionValue = ReducerInterface_ExpressionValue.expressionValue type t = expression let toString: T.expression => Js.String.t let toStringResult: result => string diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res index bfb79df1..8842ce8f 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res @@ -5,6 +5,7 @@ module Extra_Array = Reducer_Extra_Array module ErrorValue = Reducer_ErrorValue +@genType type rec expressionValue = | EvBool(bool) | EvNumber(float) diff --git a/packages/squiggle-lang/src/rescript/TypescriptInterface.res b/packages/squiggle-lang/src/rescript/TypescriptInterface.res index 6fe6f3d4..c52dd8a7 100644 --- a/packages/squiggle-lang/src/rescript/TypescriptInterface.res +++ b/packages/squiggle-lang/src/rescript/TypescriptInterface.res @@ -8,20 +8,31 @@ The below few seem to work fine. In the future there's definitely more work to d */ @genType -type env = DistributionOperation.env +type samplingParams = DistributionOperation.env @genType type genericDist = GenericDist_Types.genericDist @genType -type error = GenericDist_Types.error +type distributionError = GenericDist_Types.error @genType -type resultDist = result -@genType -type resultFloat = result -@genType -type resultString = result +type resultDist = result @genType -let makeSampleSetDist = SampleSetDist.make \ No newline at end of file +type resultFloat = result + +@genType +type resultString = result + +@genType +let makeSampleSetDist = SampleSetDist.make + +@genType +let evaluate = Reducer.evaluate + +@genType +type expressionValue = Reducer_Expression.expressionValue + +@genType +type errorValue = Reducer_ErrorValue.errorValue diff --git a/packages/squiggle-lang/src/rescript/shims/Js.shim.ts b/packages/squiggle-lang/src/rescript/shims/Js.shim.ts new file mode 100644 index 00000000..c4f41786 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/shims/Js.shim.ts @@ -0,0 +1 @@ +export type Dict_t = { [key: string]: T }