Compare commits
2 Commits
develop
...
new-ts-int
Author | SHA1 | Date | |
---|---|---|---|
|
6637db4154 | ||
|
25a6c374d1 |
|
@ -1,34 +1,16 @@
|
||||||
import { run } from '../src/js/index';
|
import { run, exportToString } from '../src/js/index';
|
||||||
|
|
||||||
let testRun = (x: string) => {
|
let testRun = (expression: string): string => exportToString(run(expression)[0])
|
||||||
let result = run(x)
|
|
||||||
if(result.tag == 'Ok'){
|
let runTest = (expression: string, expected: string) => test(expression, () => expect(testRun(expression)).toEqual(expected))
|
||||||
return { tag: 'Ok', value: result.value.exports }
|
|
||||||
}
|
let runErrorTest = (expression: string, expected: string) => test(`${expression} will error`, () => expect(() => testRun(expression)).toThrowError(expected))
|
||||||
else {
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
describe("Simple calculations and results", () => {
|
describe("Simple calculations and results", () => {
|
||||||
test("mean(normal(5,2))", () => {
|
runTest("mean(normal(5,2))", "5")
|
||||||
expect(testRun("mean(normal(5,2))")).toEqual({ tag: 'Ok', value: [ { NAME: 'Float', VAL: 5 } ] })
|
runTest("10 + 10", "20")
|
||||||
})
|
|
||||||
test("10+10", () => {
|
|
||||||
let foo = testRun("10 + 10")
|
|
||||||
expect(foo).toEqual({ tag: 'Ok', value: [ { NAME: 'Float', VAL: 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", () => {
|
describe("Log function", () => {
|
||||||
test("mm(0,0,[0,0,0])", () => {
|
runTest("log(1)", "0")
|
||||||
let foo = testRun("mm(0,0,[0,0,0])")
|
})
|
||||||
expect(foo).toEqual({ "tag": "Error", "value": "Function multimodal error: Too many weights provided" })
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ open Jest
|
||||||
open Expect
|
open Expect
|
||||||
|
|
||||||
let expectEvalToBe = (expr: string, answer: string) =>
|
let expectEvalToBe = (expr: string, answer: string) =>
|
||||||
Reducer.eval(expr)->ExpressionValue.toStringResult->expect->toBe(answer)
|
Reducer.evaluate(expr)->ExpressionValue.toStringResult->expect->toBe(answer)
|
||||||
|
|
||||||
describe("builtin", () => {
|
describe("builtin", () => {
|
||||||
// All MathJs operators and functions are available for string, number and boolean
|
// All MathJs operators and functions are available for string, number and boolean
|
||||||
|
|
|
@ -8,7 +8,7 @@ let expectParseToBe = (expr: string, answer: string) =>
|
||||||
Reducer.parse(expr)->Expression.toStringResult->expect->toBe(answer)
|
Reducer.parse(expr)->Expression.toStringResult->expect->toBe(answer)
|
||||||
|
|
||||||
let expectEvalToBe = (expr: string, answer: string) =>
|
let expectEvalToBe = (expr: string, answer: string) =>
|
||||||
Reducer.eval(expr)->ExpressionValue.toStringResult->expect->toBe(answer)
|
Reducer.evaluate(expr)->ExpressionValue.toStringResult->expect->toBe(answer)
|
||||||
|
|
||||||
// Current configuration does not ignore this file so we have to have a test
|
// Current configuration does not ignore this file so we have to have a test
|
||||||
test("test helpers", () => expect(1)->toBe(1))
|
test("test helpers", () => expect(1)->toBe(1))
|
||||||
|
|
|
@ -33,7 +33,9 @@
|
||||||
"gentypeconfig": {
|
"gentypeconfig": {
|
||||||
"language": "typescript",
|
"language": "typescript",
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"shims": {},
|
"shims": {
|
||||||
|
"Js": "Js"
|
||||||
|
},
|
||||||
"debug": {
|
"debug": {
|
||||||
"all": false,
|
"all": false,
|
||||||
"basic": false
|
"basic": false
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
import {runAll} from '../rescript/ProgramEvaluator.gen';
|
import * as _ from 'lodash';
|
||||||
import type { Inputs_SamplingInputs_t as SamplingInputs, exportEnv, exportType, exportDistribution} from '../rescript/ProgramEvaluator.gen';
|
import {evaluate} from '../rescript/Reducer/Reducer.gen';
|
||||||
export type { SamplingInputs, exportEnv, exportDistribution }
|
import type { expressionValue } from '../rescript/Reducer/Reducer_Expression/Reducer_Expression.gen';
|
||||||
export type {t as DistPlus} from '../rescript/OldInterpreter/DistPlus.gen';
|
import type { pointSetDist } from '../rescript/Distributions/PointSetDist/PointSetTypes.gen';
|
||||||
|
import type { genericDist } from '../rescript/Distributions/GenericDist/GenericDist_Types.gen';
|
||||||
|
import { errorToString } from '../rescript/Reducer/Reducer_ErrorValue.gen';
|
||||||
|
import { toPointSet, inv } from '../rescript/Distributions/GenericDist/GenericDist.gen';
|
||||||
|
import type { Inputs_SamplingInputs_t as SamplingInputs, exportEnv, exportDistribution} from '../rescript/ProgramEvaluator.gen';
|
||||||
|
export type { SamplingInputs, exportEnv, exportDistribution, tsExport }
|
||||||
|
|
||||||
export let defaultSamplingInputs : SamplingInputs = {
|
export let defaultSamplingInputs : SamplingInputs = {
|
||||||
sampleCount : 10000,
|
sampleCount : 10000,
|
||||||
|
@ -9,9 +14,140 @@ export let defaultSamplingInputs : SamplingInputs = {
|
||||||
pointDistLength : 1000
|
pointDistLength : 1000
|
||||||
}
|
}
|
||||||
|
|
||||||
export function run(squiggleString : string, samplingInputs? : SamplingInputs, environment?: exportEnv) : { tag: "Ok"; value: exportType }
|
type taggedOption<tag,value> = {
|
||||||
| { tag: "Error"; value: string } {
|
tag: tag,
|
||||||
let si : SamplingInputs = samplingInputs ? samplingInputs : defaultSamplingInputs
|
value: value
|
||||||
let env : exportEnv = environment ? environment : []
|
}
|
||||||
return runAll(squiggleString, si, env)
|
|
||||||
|
function tagOption<T, V>(tag : T, value: V): taggedOption<T,V> {
|
||||||
|
return { tag: tag, value: value};
|
||||||
|
}
|
||||||
|
type tsExport = taggedOption<"string", string> | taggedOption<"symbol", string> | taggedOption<"number", number> | taggedOption<"boolean", boolean> | taggedOption<"distribution", Distribution> | taggedOption<"array", tsExport[]> | taggedOption<"record", {[key: string]: tsExport}> | taggedOption<"function", (x: number) => tsExport>
|
||||||
|
|
||||||
|
// This is here mainly for testing purposes
|
||||||
|
export function exportToString(result : tsExport) : string{
|
||||||
|
if(result.tag === "string"){
|
||||||
|
return `"${result.value}"`
|
||||||
|
}
|
||||||
|
else if(result.tag === "boolean"){
|
||||||
|
return `${result.value}`
|
||||||
|
}
|
||||||
|
else if(result.tag === "array"){
|
||||||
|
return `[${result.value.map(exportToString).join(", ")}]`
|
||||||
|
}
|
||||||
|
else if(result.tag === "distribution"){
|
||||||
|
return result.value.toString()
|
||||||
|
}
|
||||||
|
else if(result.tag === "number"){
|
||||||
|
return `${result.value}`
|
||||||
|
}
|
||||||
|
else if(result.tag === "symbol"){
|
||||||
|
return `${result.value}`
|
||||||
|
}
|
||||||
|
else if(result.tag === "record"){
|
||||||
|
return `${_.mapValues(result.value, exportToString)}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function expressionValueToValue(value : expressionValue, samplingInputs: SamplingInputs) : tsExport {
|
||||||
|
if(value.tag == "EvArray"){
|
||||||
|
return tagOption("array", value.value.map((val) => expressionValueToValue(val,samplingInputs)));
|
||||||
|
}else if (value.tag == "EvBool"){
|
||||||
|
return tagOption("boolean", value.value)
|
||||||
|
}
|
||||||
|
else if(value.tag == "EvDistribution"){
|
||||||
|
return tagOption("distribution", new Distribution(value.value, samplingInputs));
|
||||||
|
}
|
||||||
|
else if(value.tag == "EvNumber"){
|
||||||
|
return tagOption("number", value.value);
|
||||||
|
}
|
||||||
|
else if(value.tag == "EvString"){
|
||||||
|
return tagOption("string", value.value);
|
||||||
|
}
|
||||||
|
else if(value.tag == "EvSymbol"){
|
||||||
|
return tagOption("symbol", value.value);
|
||||||
|
}
|
||||||
|
else if(value.tag == "EvRecord"){
|
||||||
|
return tagOption("record", _.mapValues(value.value, (val) => expressionValueToValue(val, samplingInputs)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function run(squiggleString : string, samplingInputs : SamplingInputs = defaultSamplingInputs, _environment?: exportEnv): tsExport[] {
|
||||||
|
let result = evaluate(squiggleString);
|
||||||
|
if(result.tag == "Ok"){
|
||||||
|
return [expressionValueToValue(result.value, samplingInputs)];
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
throw Error(errorToString(result.value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Distribution {
|
||||||
|
dist: genericDist
|
||||||
|
samplingInputs : SamplingInputs
|
||||||
|
constructor(dist : genericDist, samplingInputs: SamplingInputs){
|
||||||
|
this.dist = dist;
|
||||||
|
this.samplingInputs = samplingInputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
pointShape() {
|
||||||
|
let pointSet = toPointSet({xyPointLength: this.samplingInputs.outputXYPoints, sampleCount: this.samplingInputs.sampleCount}, this.dist)
|
||||||
|
if(pointSet.tag == "Ok"){
|
||||||
|
return new Shape(pointSet.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inv(x: number): number{
|
||||||
|
let result= inv(this.dist, x)
|
||||||
|
if (result.tag == "Ok") {
|
||||||
|
return result.value;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw Error(result.value.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toString(): string {
|
||||||
|
return "Todo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type point = { x: number, y: number, cdf: number}
|
||||||
|
class Shape {
|
||||||
|
shape : pointSetDist
|
||||||
|
constructor(shape : pointSetDist){
|
||||||
|
this.shape = shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
discretePoints(): point[]{
|
||||||
|
let discreteShape = undefined;
|
||||||
|
if(this.shape.tag == "Discrete"){
|
||||||
|
discreteShape = this.shape.value;
|
||||||
|
} else if (this.shape.tag == "Mixed"){
|
||||||
|
discreteShape = this.shape.value.discrete;
|
||||||
|
}
|
||||||
|
if(discreteShape !== undefined) {
|
||||||
|
return _.zipWith(discreteShape.xyShape.xs, discreteShape.xyShape.ys, discreteShape.integralCache.xyShape.ys, (x, y, c) => ({x, y, cdf: c}))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
continuousPoints(): point[]{
|
||||||
|
let continuousShape = undefined;
|
||||||
|
console.log(this.shape.tag)
|
||||||
|
if(this.shape.tag == "Continuous"){
|
||||||
|
continuousShape = this.shape.value;
|
||||||
|
} else if (this.shape.tag == "Mixed"){
|
||||||
|
continuousShape = this.shape.value.continuous;
|
||||||
|
}
|
||||||
|
if(continuousShape !== undefined) {
|
||||||
|
return _.zipWith(continuousShape.xyShape.xs, continuousShape.xyShape.ys, continuousShape.integralCache.xyShape.ys, (x, y, c) => ({x, y, cdf: c}))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,13 @@ let sampleN = (t: t, n) =>
|
||||||
| SampleSet(_) => Error(GenericDist_Types.NotYetImplemented)
|
| SampleSet(_) => Error(GenericDist_Types.NotYetImplemented)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let inv = (t: t, x: float): result<float, error> =>
|
||||||
|
switch t {
|
||||||
|
| PointSet(r) => Ok(PointSetDist.inv(x, r))
|
||||||
|
| Symbolic(r) => Ok(SymbolicDist.T.inv(x, r))
|
||||||
|
| SampleSet(_) => Error(GenericDist_Types.NotYetImplemented)
|
||||||
|
}
|
||||||
|
|
||||||
let fromFloat = (f: float): t => Symbolic(SymbolicDist.Float.make(f))
|
let fromFloat = (f: float): t => Symbolic(SymbolicDist.Float.make(f))
|
||||||
|
|
||||||
let toString = (t: t) =>
|
let toString = (t: t) =>
|
||||||
|
|
|
@ -7,6 +7,9 @@ type pointwiseAddFn = (t, t) => result<t, error>
|
||||||
|
|
||||||
let sampleN: (t, int) => result<array<float>, error>
|
let sampleN: (t, int) => result<array<float>, error>
|
||||||
|
|
||||||
|
@genType
|
||||||
|
let inv : (t, float) => result<float, error>
|
||||||
|
|
||||||
let fromFloat: float => t
|
let fromFloat: float => t
|
||||||
|
|
||||||
let toString: t => string
|
let toString: t => string
|
||||||
|
@ -19,6 +22,7 @@ let toFloatOperation: (
|
||||||
~distToFloatOperation: Operation.distToFloatOperation,
|
~distToFloatOperation: Operation.distToFloatOperation,
|
||||||
) => result<float, error>
|
) => result<float, error>
|
||||||
|
|
||||||
|
@genType
|
||||||
let toPointSet: (
|
let toPointSet: (
|
||||||
~xyPointLength: int,
|
~xyPointLength: int,
|
||||||
~sampleCount: int,
|
~sampleCount: int,
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
|
@genType
|
||||||
type genericDist =
|
type genericDist =
|
||||||
| PointSet(PointSetTypes.pointSetDist)
|
| PointSet(PointSetTypes.pointSetDist)
|
||||||
| SampleSet(SampleSet.t)
|
| SampleSet(SampleSet.t)
|
||||||
| Symbolic(SymbolicDistTypes.symbolicDist)
|
| Symbolic(SymbolicDistTypes.symbolicDist)
|
||||||
|
|
||||||
|
@genType
|
||||||
type error =
|
type error =
|
||||||
| NotYetImplemented
|
| NotYetImplemented
|
||||||
| Unreachable
|
| Unreachable
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
@genType
|
||||||
type t = array<float>
|
type t = array<float>
|
||||||
|
|
||||||
// TODO: Refactor to raise correct error when not enough samples
|
// TODO: Refactor to raise correct error when not enough samples
|
||||||
|
@ -142,4 +143,4 @@ let toPointSetDist = (
|
||||||
}
|
}
|
||||||
|
|
||||||
samplesParse
|
samplesParse
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,5 +5,5 @@ module Extra = Reducer_Extra
|
||||||
module Js = Reducer_Js
|
module Js = Reducer_Js
|
||||||
module MathJs = Reducer_MathJs
|
module MathJs = Reducer_MathJs
|
||||||
|
|
||||||
let eval = Expression.eval
|
let evaluate = Expression.eval
|
||||||
let parse = Expression.parse
|
let parse = Expression.parse
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
module Dispatch = Reducer_Dispatch
|
module Dispatch = Reducer_Dispatch
|
||||||
|
@genType
|
||||||
module ErrorValue = Reducer_ErrorValue
|
module ErrorValue = Reducer_ErrorValue
|
||||||
|
@genType
|
||||||
module Expression = Reducer_Expression
|
module Expression = Reducer_Expression
|
||||||
module Extra = Reducer_Extra
|
module Extra = Reducer_Extra
|
||||||
module Js = Reducer_Js
|
module Js = Reducer_Js
|
||||||
module MathJs = Reducer_MathJs
|
module MathJs = Reducer_MathJs
|
||||||
let eval: string => result<Expression.expressionValue, ErrorValue.errorValue>
|
@genType
|
||||||
|
let evaluate: string => result<Reducer_Expression.expressionValue, Reducer_ErrorValue.errorValue>
|
||||||
let parse: string => result<Expression.expression, ErrorValue.errorValue>
|
let parse: string => result<Expression.expression, ErrorValue.errorValue>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
@genType
|
||||||
type errorValue =
|
type errorValue =
|
||||||
| REArrayIndexNotFound(string, int)
|
| REArrayIndexNotFound(string, int)
|
||||||
| REFunctionExpected(string)
|
| REFunctionExpected(string)
|
||||||
|
@ -7,6 +8,7 @@ type errorValue =
|
||||||
|
|
||||||
type t = errorValue
|
type t = errorValue
|
||||||
|
|
||||||
|
@genType
|
||||||
let errorToString = err =>
|
let errorToString = err =>
|
||||||
switch err {
|
switch err {
|
||||||
| REArrayIndexNotFound(msg, index) => `${msg}: ${Js.String.make(index)}`
|
| REArrayIndexNotFound(msg, index) => `${msg}: ${Js.String.make(index)}`
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
module Result = Belt.Result
|
module Result = Belt.Result
|
||||||
module T = Reducer_Expression_T
|
module T = Reducer_Expression_T
|
||||||
type expression = T.expression
|
type expression = T.expression
|
||||||
type expressionValue = ReducerInterface.ExpressionValue.expressionValue
|
@genType
|
||||||
|
type expressionValue = ReducerInterface_ExpressionValue.expressionValue
|
||||||
type t = expression
|
type t = expression
|
||||||
let toString: T.expression => Js.String.t
|
let toString: T.expression => Js.String.t
|
||||||
let toStringResult: result<T.expression, 'a> => string
|
let toStringResult: result<T.expression, 'a> => string
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
module Extra_Array = Reducer_Extra_Array
|
module Extra_Array = Reducer_Extra_Array
|
||||||
module ErrorValue = Reducer_ErrorValue
|
module ErrorValue = Reducer_ErrorValue
|
||||||
|
|
||||||
|
@genType
|
||||||
type rec expressionValue =
|
type rec expressionValue =
|
||||||
| EvBool(bool)
|
| EvBool(bool)
|
||||||
| EvNumber(float)
|
| EvNumber(float)
|
||||||
|
|
1
packages/squiggle-lang/src/rescript/shims/Js.shim.ts
Normal file
1
packages/squiggle-lang/src/rescript/shims/Js.shim.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export type Dict_t<T> = {[key: string]: T}
|
Loading…
Reference in New Issue
Block a user