Merge pull request #19 from QURIresearch/naming-refactor

File refactor
This commit is contained in:
Ozzie Gooen 2022-02-15 21:16:10 -05:00 committed by GitHub
commit 45017f3145
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 309 additions and 313 deletions

View File

@ -6,12 +6,12 @@ let makeTest = (~only=false, str, item1, item2) =>
? Only.test(str, () => expect(item1) -> toEqual(item2)) ? Only.test(str, () => expect(item1) -> toEqual(item2))
: test(str, () => expect(item1) -> toEqual(item2)) : test(str, () => expect(item1) -> toEqual(item2))
describe("DistTypes", () => describe("PointSetTypes", () =>
describe("Domain", () => { describe("Domain", () => {
let makeComplete = (yPoint, expectation) => let makeComplete = (yPoint, expectation) =>
makeTest( makeTest(
"With input: " ++ Js.Float.toString(yPoint), "With input: " ++ Js.Float.toString(yPoint),
DistTypes.Domain.yPointToSubYPoint(Complete, yPoint), PointSetTypes.Domain.yPointToSubYPoint(Complete, yPoint),
expectation, expectation,
) )
let makeSingle = (direction: [#left | #right], excludingProbabilityMass, yPoint, expectation) => let makeSingle = (direction: [#left | #right], excludingProbabilityMass, yPoint, expectation) =>
@ -19,7 +19,7 @@ describe("DistTypes", () =>
"Excluding: " ++ "Excluding: " ++
(Js.Float.toString(excludingProbabilityMass) ++ (Js.Float.toString(excludingProbabilityMass) ++
(" and yPoint: " ++ Js.Float.toString(yPoint))), (" and yPoint: " ++ Js.Float.toString(yPoint))),
DistTypes.Domain.yPointToSubYPoint( PointSetTypes.Domain.yPointToSubYPoint(
direction == #left direction == #left
? LeftLimited({xPoint: 3.0, excludingProbabilityMass: excludingProbabilityMass}) ? LeftLimited({xPoint: 3.0, excludingProbabilityMass: excludingProbabilityMass})
: RightLimited({xPoint: 3.0, excludingProbabilityMass: excludingProbabilityMass}), : RightLimited({xPoint: 3.0, excludingProbabilityMass: excludingProbabilityMass}),
@ -28,7 +28,7 @@ describe("DistTypes", () =>
expectation, expectation,
) )
let makeDouble = (domain, yPoint, expectation) => let makeDouble = (domain, yPoint, expectation) =>
makeTest("Excluding: limits", DistTypes.Domain.yPointToSubYPoint(domain, yPoint), expectation) makeTest("Excluding: limits", PointSetTypes.Domain.yPointToSubYPoint(domain, yPoint), expectation)
describe("With Complete Domain", () => { describe("With Complete Domain", () => {
makeComplete(0.0, Some(0.0)) makeComplete(0.0, Some(0.0))

View File

@ -1,7 +1,7 @@
open Jest open Jest
open Expect open Expect
let shape: DistTypes.xyShape = {xs: [1., 4., 8.], ys: [8., 9., 2.]} // let PointSetDist: PointSetTypes.xyPointSetDist = {xs: [1., 4., 8.], ys: [8., 9., 2.]}
// let makeTest = (~only=false, str, item1, item2) => // let makeTest = (~only=false, str, item1, item2) =>
// only // only
@ -21,15 +21,15 @@ let shape: DistTypes.xyShape = {xs: [1., 4., 8.], ys: [8., 9., 2.]}
// expect(item1) |> toBeSoCloseTo(item2, ~digits) // expect(item1) |> toBeSoCloseTo(item2, ~digits)
// ); // );
// describe("Shape", () => { // describe("PointSetDist", () => {
// describe("Continuous", () => { // describe("Continuous", () => {
// open Continuous; // open Continuous;
// let continuous = make(`Linear, shape, None); // let continuous = make(`Linear, PointSetDist, None);
// makeTest("minX", T.minX(continuous), 1.0); // makeTest("minX", T.minX(continuous), 1.0);
// makeTest("maxX", T.maxX(continuous), 8.0); // makeTest("maxX", T.maxX(continuous), 8.0);
// makeTest( // makeTest(
// "mapY", // "mapY",
// T.mapY(r => r *. 2.0, continuous) |> getShape |> (r => r.ys), // T.mapY(r => r *. 2.0, continuous) |> getPointSetDist |> (r => r.ys),
// [|16., 18.0, 4.0|], // [|16., 18.0, 4.0|],
// ); // );
// describe("xToY", () => { // describe("xToY", () => {
@ -57,7 +57,7 @@ let shape: DistTypes.xyShape = {xs: [1., 4., 8.], ys: [8., 9., 2.]}
// ); // );
// }); // });
// describe("when Stepwise", () => { // describe("when Stepwise", () => {
// let continuous = make(`Stepwise, shape, None); // let continuous = make(`Stepwise, PointSetDist, None);
// makeTest( // makeTest(
// "at 4.0", // "at 4.0",
// T.xToY(4., continuous), // T.xToY(4., continuous),
@ -82,7 +82,7 @@ let shape: DistTypes.xyShape = {xs: [1., 4., 8.], ys: [8., 9., 2.]}
// }); // });
// makeTest( // makeTest(
// "integral", // "integral",
// T.Integral.get(~cache=None, continuous) |> getShape, // T.Integral.get(~cache=None, continuous) |> getPointSetDist,
// {xs: [|1.0, 4.0, 8.0|], ys: [|0.0, 25.5, 47.5|]}, // {xs: [|1.0, 4.0, 8.0|], ys: [|0.0, 25.5, 47.5|]},
// ); // );
// makeTest( // makeTest(
@ -90,7 +90,7 @@ let shape: DistTypes.xyShape = {xs: [1., 4., 8.], ys: [8., 9., 2.]}
// { // {
// let continuous = // let continuous =
// make(`Stepwise, {xs: [|1., 4., 8.|], ys: [|0.1, 5., 1.0|]}, None); // make(`Stepwise, {xs: [|1., 4., 8.|], ys: [|0.1, 5., 1.0|]}, None);
// continuous |> toLinear |> E.O.fmap(getShape); // continuous |> toLinear |> E.O.fmap(getPointSetDist);
// }, // },
// Some({ // Some({
// xs: [|1.00007, 1.00007, 4.0, 4.00007, 8.0, 8.00007|], // xs: [|1.00007, 1.00007, 4.0, 4.00007, 8.0, 8.00007|],
@ -101,7 +101,7 @@ let shape: DistTypes.xyShape = {xs: [1., 4., 8.], ys: [8., 9., 2.]}
// "toLinear", // "toLinear",
// { // {
// let continuous = make(`Stepwise, {xs: [|0.0|], ys: [|0.3|]}, None); // let continuous = make(`Stepwise, {xs: [|0.0|], ys: [|0.3|]}, None);
// continuous |> toLinear |> E.O.fmap(getShape); // continuous |> toLinear |> E.O.fmap(getPointSetDist);
// }, // },
// Some({xs: [|0.0|], ys: [|0.3|]}), // Some({xs: [|0.0|], ys: [|0.3|]}),
// ); // );
@ -131,16 +131,16 @@ let shape: DistTypes.xyShape = {xs: [1., 4., 8.], ys: [8., 9., 2.]}
// describe("Discrete", () => { // describe("Discrete", () => {
// open Discrete; // open Discrete;
// let shape: DistTypes.xyShape = { // let PointSetDist: PointSetTypes.xyPointSetDist = {
// xs: [|1., 4., 8.|], // xs: [|1., 4., 8.|],
// ys: [|0.3, 0.5, 0.2|], // ys: [|0.3, 0.5, 0.2|],
// }; // };
// let discrete = make(shape, None); // let discrete = make(PointSetDist, None);
// makeTest("minX", T.minX(discrete), 1.0); // makeTest("minX", T.minX(discrete), 1.0);
// makeTest("maxX", T.maxX(discrete), 8.0); // makeTest("maxX", T.maxX(discrete), 8.0);
// makeTest( // makeTest(
// "mapY", // "mapY",
// T.mapY(r => r *. 2.0, discrete) |> (r => getShape(r).ys), // T.mapY(r => r *. 2.0, discrete) |> (r => getPointSetDist(r).ys),
// [|0.6, 1.0, 0.4|], // [|0.6, 1.0, 0.4|],
// ); // );
// makeTest( // makeTest(
@ -209,11 +209,11 @@ let shape: DistTypes.xyShape = {xs: [1., 4., 8.], ys: [8., 9., 2.]}
// describe("Mixed", () => { // describe("Mixed", () => {
// open Distributions.Mixed; // open Distributions.Mixed;
// let discreteShape: DistTypes.xyShape = { // let discretePointSetDist: PointSetTypes.xyPointSetDist = {
// xs: [|1., 4., 8.|], // xs: [|1., 4., 8.|],
// ys: [|0.3, 0.5, 0.2|], // ys: [|0.3, 0.5, 0.2|],
// }; // };
// let discrete = Discrete.make(discreteShape, None); // let discrete = Discrete.make(discretePointSetDist, None);
// let continuous = // let continuous =
// Continuous.make( // Continuous.make(
// `Linear, // `Linear,
@ -309,11 +309,11 @@ let shape: DistTypes.xyShape = {xs: [1., 4., 8.], ys: [8., 9., 2.]}
// describe("Distplus", () => { // describe("Distplus", () => {
// open DistPlus; // open DistPlus;
// let discreteShape: DistTypes.xyShape = { // let discretePointSetDist: PointSetTypes.xyPointSetDist = {
// xs: [|1., 4., 8.|], // xs: [|1., 4., 8.|],
// ys: [|0.3, 0.5, 0.2|], // ys: [|0.3, 0.5, 0.2|],
// }; // };
// let discrete = Discrete.make(discreteShape, None); // let discrete = Discrete.make(discretePointSetDist, None);
// let continuous = // let continuous =
// Continuous.make( // Continuous.make(
// `Linear, // `Linear,
@ -328,7 +328,7 @@ let shape: DistTypes.xyShape = {xs: [1., 4., 8.], ys: [8., 9., 2.]}
// ); // );
// let distPlus = // let distPlus =
// DistPlus.make( // DistPlus.make(
// ~shape=Mixed(mixed), // ~PointSetDist=Mixed(mixed),
// ~squiggleString=None, // ~squiggleString=None,
// (), // (),
// ); // );
@ -376,38 +376,38 @@ let shape: DistTypes.xyShape = {xs: [1., 4., 8.], ys: [8., 9., 2.]}
// ); // );
// }); // });
// describe("Shape", () => { // describe("PointSetDist", () => {
// let mean = 10.0; // let mean = 10.0;
// let stdev = 4.0; // let stdev = 4.0;
// let variance = stdev ** 2.0; // let variance = stdev ** 2.0;
// let numSamples = 10000; // let numSamples = 10000;
// open Distributions.Shape; // open Distributions.PointSetDist;
// let normal: SymbolicTypes.symbolicDist = `Normal({mean, stdev}); // let normal: SymbolicDistTypes.symbolicDist = `Normal({mean, stdev});
// let normalShape = ExpressionTree.toShape(numSamples, `SymbolicDist(normal)); // let normalPointSetDist = AST.toPointSetDist(numSamples, `SymbolicDist(normal));
// let lognormal = SymbolicDist.Lognormal.fromMeanAndStdev(mean, stdev); // let lognormal = SymbolicDist.Lognormal.fromMeanAndStdev(mean, stdev);
// let lognormalShape = ExpressionTree.toShape(numSamples, `SymbolicDist(lognormal)); // let lognormalPointSetDist = AST.toPointSetDist(numSamples, `SymbolicDist(lognormal));
// makeTestCloseEquality( // makeTestCloseEquality(
// "Mean of a normal", // "Mean of a normal",
// T.mean(normalShape), // T.mean(normalPointSetDist),
// mean, // mean,
// ~digits=2, // ~digits=2,
// ); // );
// makeTestCloseEquality( // makeTestCloseEquality(
// "Variance of a normal", // "Variance of a normal",
// T.variance(normalShape), // T.variance(normalPointSetDist),
// variance, // variance,
// ~digits=1, // ~digits=1,
// ); // );
// makeTestCloseEquality( // makeTestCloseEquality(
// "Mean of a lognormal", // "Mean of a lognormal",
// T.mean(lognormalShape), // T.mean(lognormalPointSetDist),
// mean, // mean,
// ~digits=2, // ~digits=2,
// ); // );
// makeTestCloseEquality( // makeTestCloseEquality(
// "Variance of a lognormal", // "Variance of a lognormal",
// T.variance(lognormalShape), // T.variance(lognormalPointSetDist),
// variance, // variance,
// ~digits=0, // ~digits=0,
// ); // );

View File

@ -10,12 +10,12 @@ let makeTest = (~only=false, str, item1, item2) =>
expect(item1) |> toEqual(item2) expect(item1) |> toEqual(item2)
); );
let evalParams: ExpressionTypes.ExpressionTree.evaluationParams = { let evalParams: ASTTypes.AST.evaluationParams = {
samplingInputs: { samplingInputs: {
sampleCount: 1000, sampleCount: 1000,
outputXYPoints: 10000, outputXYPoints: 10000,
kernelWidth: None, kernelWidth: None,
shapeLength: 1000, PointSetDistLength: 1000,
}, },
environment: environment:
[| [|
@ -25,12 +25,12 @@ let evalParams: ExpressionTypes.ExpressionTree.evaluationParams = {
("T", `SymbolicDist(`Float(1000000000000.0))), ("T", `SymbolicDist(`Float(1000000000000.0))),
|] |]
->Belt.Map.String.fromArray, ->Belt.Map.String.fromArray,
evaluateNode: ExpressionTreeEvaluator.toLeaf, evaluateNode: ASTEvaluator.toLeaf,
}; };
let shape1: DistTypes.xyShape = {xs: [|1., 4., 8.|], ys: [|0.2, 0.4, 0.8|]}; let PointSetDist1: PointSetTypes.xyPointSetDist = {xs: [|1., 4., 8.|], ys: [|0.2, 0.4, 0.8|]};
describe("XYShapes", () => { describe("XYPointSetDists", () => {
describe("logScorePoint", () => { describe("logScorePoint", () => {
makeTest( makeTest(
"When identical", "When identical",

View File

@ -10,12 +10,12 @@ describe("Lodash", () =>
describe("Lodash", () => { describe("Lodash", () => {
makeTest( makeTest(
"split", "split",
SamplesToShape.Internals.T.splitContinuousAndDiscrete([1.432, 1.33455, 2.0]), SampleSet.Internals.T.splitContinuousAndDiscrete([1.432, 1.33455, 2.0]),
([1.432, 1.33455, 2.0], E.FloatFloatMap.empty()), ([1.432, 1.33455, 2.0], E.FloatFloatMap.empty()),
) )
makeTest( makeTest(
"split", "split",
SamplesToShape.Internals.T.splitContinuousAndDiscrete([ SampleSet.Internals.T.splitContinuousAndDiscrete([
1.432, 1.432,
1.33455, 1.33455,
2.0, 2.0,
@ -32,13 +32,13 @@ describe("Lodash", () =>
E.A.concatMany([sorted, sorted, sorted, sorted]) |> Belt.SortArray.stableSortBy(_, compare) E.A.concatMany([sorted, sorted, sorted, sorted]) |> Belt.SortArray.stableSortBy(_, compare)
} }
let (_, discrete) = SamplesToShape.Internals.T.splitContinuousAndDiscrete( let (_, discrete) = SampleSet.Internals.T.splitContinuousAndDiscrete(
makeDuplicatedArray(10), makeDuplicatedArray(10),
) )
let toArr = discrete |> E.FloatFloatMap.toArray let toArr = discrete |> E.FloatFloatMap.toArray
makeTest("splitMedium", toArr |> Belt.Array.length, 10) makeTest("splitMedium", toArr |> Belt.Array.length, 10)
let (c, discrete) = SamplesToShape.Internals.T.splitContinuousAndDiscrete( let (c, discrete) = SampleSet.Internals.T.splitContinuousAndDiscrete(
makeDuplicatedArray(500), makeDuplicatedArray(500),
) )
let toArr = discrete |> E.FloatFloatMap.toArray let toArr = discrete |> E.FloatFloatMap.toArray

View File

@ -6,25 +6,25 @@ let makeTest = (~only=false, str, item1, item2) =>
? Only.test(str, () => expect(item1) -> toEqual(item2)) ? Only.test(str, () => expect(item1) -> toEqual(item2))
: test(str, () => expect(item1) -> toEqual(item2)) : test(str, () => expect(item1) -> toEqual(item2))
let shape1: DistTypes.xyShape = {xs: [1., 4., 8.], ys: [0.2, 0.4, 0.8]} let pointSetDist1: PointSetTypes.xyShape = {xs: [1., 4., 8.], ys: [0.2, 0.4, 0.8]}
let shape2: DistTypes.xyShape = { let pointSetDist2: PointSetTypes.xyShape = {
xs: [1., 5., 10.], xs: [1., 5., 10.],
ys: [0.2, 0.5, 0.8], ys: [0.2, 0.5, 0.8],
} }
let shape3: DistTypes.xyShape = { let pointSetDist3: PointSetTypes.xyShape = {
xs: [1., 20., 50.], xs: [1., 20., 50.],
ys: [0.2, 0.5, 0.8], ys: [0.2, 0.5, 0.8],
} }
describe("XYShapes", () => { describe("XYShapes", () => {
describe("logScorePoint", () => { describe("logScorePoint", () => {
makeTest("When identical", XYShape.logScorePoint(30, shape1, shape1), Some(0.0)) makeTest("When identical", XYShape.logScorePoint(30, pointSetDist1, pointSetDist1), Some(0.0))
makeTest("When similar", XYShape.logScorePoint(30, shape1, shape2), Some(1.658971191043856)) makeTest("When similar", XYShape.logScorePoint(30, pointSetDist1, pointSetDist2), Some(1.658971191043856))
makeTest( makeTest(
"When very different", "When very different",
XYShape.logScorePoint(30, shape1, shape3), XYShape.logScorePoint(30, pointSetDist1, pointSetDist3),
Some(210.3721280423322), Some(210.3721280423322),
) )
}) })
@ -41,7 +41,7 @@ describe("XYShapes", () => {
describe("integrateWithTriangles", () => describe("integrateWithTriangles", () =>
makeTest( makeTest(
"integrates correctly", "integrates correctly",
XYShape.Range.integrateWithTriangles(shape1), XYShape.Range.integrateWithTriangles(pointSetDist1),
Some({ Some({
xs: [1., 4., 8.], xs: [1., 4., 8.],
ys: [0.0, 0.9000000000000001, 3.3000000000000007], ys: [0.0, 0.9000000000000001, 3.3000000000000007],

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,5 +0,0 @@
type t = ExpressionTypes.Program.program
let last = (r: t) => E.A.last(r) |> E.O.toResult("No rendered lines")
// let run = (p:program) => p |> E.A.last |> E.O.fmap(r =>
// )

View File

@ -1,3 +1,3 @@
const ProgramEvaluator = require('../distPlus/ProgramEvaluator.gen.js'); const ProgramEvaluator = require('../rescript/ProgramEvaluator.gen.js');
exports.runMePlease = ProgramEvaluator.runAll exports.runMePlease = ProgramEvaluator.runAll

View File

@ -5,7 +5,7 @@ module Inputs = {
sampleCount: option<int>, sampleCount: option<int>,
outputXYPoints: option<int>, outputXYPoints: option<int>,
kernelWidth: option<float>, kernelWidth: option<float>,
shapeLength: option<int>, pointSetDistLength: option<int>,
} }
} }
let defaultRecommendedLength = 100 let defaultRecommendedLength = 100
@ -14,20 +14,20 @@ module Inputs = {
type inputs = { type inputs = {
squiggleString: string, squiggleString: string,
samplingInputs: SamplingInputs.t, samplingInputs: SamplingInputs.t,
environment: ExpressionTypes.ExpressionTree.environment, environment: ASTTypes.AST.environment,
} }
let empty: SamplingInputs.t = { let empty: SamplingInputs.t = {
sampleCount: None, sampleCount: None,
outputXYPoints: None, outputXYPoints: None,
kernelWidth: None, kernelWidth: None,
shapeLength: None, pointSetDistLength: None,
} }
let make = ( let make = (
~samplingInputs=empty, ~samplingInputs=empty,
~squiggleString, ~squiggleString,
~environment=ExpressionTypes.ExpressionTree.Environment.empty, ~environment=ASTTypes.AST.Environment.empty,
(), (),
): inputs => { ): inputs => {
samplingInputs: samplingInputs, samplingInputs: samplingInputs,
@ -40,8 +40,8 @@ type \"export" = [
| #DistPlus(DistPlus.t) | #DistPlus(DistPlus.t)
| #Float(float) | #Float(float)
| #Function( | #Function(
(array<string>, ExpressionTypes.ExpressionTree.node), (array<string>, ASTTypes.AST.node),
ExpressionTypes.ExpressionTree.environment, ASTTypes.AST.environment,
) )
] ]
@ -53,28 +53,28 @@ module Internals = {
): Inputs.inputs => { ): Inputs.inputs => {
samplingInputs: samplingInputs, samplingInputs: samplingInputs,
squiggleString: squiggleString, squiggleString: squiggleString,
environment: ExpressionTypes.ExpressionTree.Environment.update(environment, str, _ => Some( environment: ASTTypes.AST.Environment.update(environment, str, _ => Some(
node, node,
)), )),
} }
type outputs = { type outputs = {
graph: ExpressionTypes.ExpressionTree.node, graph: ASTTypes.AST.node,
shape: DistTypes.shape, pointSetDist: PointSetTypes.pointSetDist,
} }
let makeOutputs = (graph, shape): outputs => {graph: graph, shape: shape} let makeOutputs = (graph, pointSetDist): outputs => {graph: graph, pointSetDist: pointSetDist}
let makeInputs = (inputs: Inputs.inputs): ExpressionTypes.ExpressionTree.samplingInputs => { let makeInputs = (inputs: Inputs.inputs): ASTTypes.AST.samplingInputs => {
sampleCount: inputs.samplingInputs.sampleCount |> E.O.default(10000), sampleCount: inputs.samplingInputs.sampleCount |> E.O.default(10000),
outputXYPoints: inputs.samplingInputs.outputXYPoints |> E.O.default(10000), outputXYPoints: inputs.samplingInputs.outputXYPoints |> E.O.default(10000),
kernelWidth: inputs.samplingInputs.kernelWidth, kernelWidth: inputs.samplingInputs.kernelWidth,
shapeLength: inputs.samplingInputs.shapeLength |> E.O.default(10000), pointSetDistLength: inputs.samplingInputs.pointSetDistLength |> E.O.default(10000),
} }
let runNode = (inputs, node) => let runNode = (inputs, node) =>
ExpressionTree.toLeaf(makeInputs(inputs), inputs.environment, node) AST.toLeaf(makeInputs(inputs), inputs.environment, node)
let runProgram = (inputs: Inputs.inputs, p: ExpressionTypes.Program.program) => { let runProgram = (inputs: Inputs.inputs, p: ASTTypes.Program.program) => {
let ins = ref(inputs) let ins = ref(inputs)
p p
|> E.A.fmap(x => |> E.A.fmap(x =>
@ -91,14 +91,14 @@ module Internals = {
} }
let inputsToLeaf = (inputs: Inputs.inputs) => let inputsToLeaf = (inputs: Inputs.inputs) =>
MathJsParser.fromString(inputs.squiggleString) |> E.R.bind(_, g => runProgram(inputs, g)) Parser.fromString(inputs.squiggleString) |> E.R.bind(_, g => runProgram(inputs, g))
let outputToDistPlus = (inputs: Inputs.inputs, shape: DistTypes.shape) => let outputToDistPlus = (inputs: Inputs.inputs, pointSetDist: PointSetTypes.pointSetDist) =>
DistPlus.make(~shape, ~squiggleString=Some(inputs.squiggleString), ()) DistPlus.make(~pointSetDist, ~squiggleString=Some(inputs.squiggleString), ())
} }
let renderIfNeeded = (inputs: Inputs.inputs, node: ExpressionTypes.ExpressionTree.node): result< let renderIfNeeded = (inputs: Inputs.inputs, node: ASTTypes.AST.node): result<
ExpressionTypes.ExpressionTree.node, ASTTypes.AST.node,
string, string,
> => > =>
node |> ( node |> (
@ -121,11 +121,11 @@ let renderIfNeeded = (inputs: Inputs.inputs, node: ExpressionTypes.ExpressionTre
} }
) )
// TODO: Consider using ExpressionTypes.ExpressionTree.getFloat or similar in this function // TODO: Consider using ASTTypes.AST.getFloat or similar in this function
let coersionToExportedTypes = ( let coersionToExportedTypes = (
inputs, inputs,
env: ExpressionTypes.ExpressionTree.environment, env: ASTTypes.AST.environment,
node: ExpressionTypes.ExpressionTree.node, node: ASTTypes.AST.node,
): result<\"export", string> => ): result<\"export", string> =>
node node
|> renderIfNeeded(inputs) |> renderIfNeeded(inputs)
@ -135,7 +135,7 @@ let coersionToExportedTypes = (
| #SymbolicDist(#Float(x)) => Ok(#Float(x)) | #SymbolicDist(#Float(x)) => Ok(#Float(x))
| #RenderedDist(n) => Ok(#DistPlus(Internals.outputToDistPlus(inputs, n))) | #RenderedDist(n) => Ok(#DistPlus(Internals.outputToDistPlus(inputs, n)))
| #Function(n) => Ok(#Function(n, env)) | #Function(n) => Ok(#Function(n, env))
| n => Error("Didn't output a rendered distribution. Format:" ++ ExpressionTree.toString(n)) | n => Error("Didn't output a rendered distribution. Format:" ++ AST.toString(n))
} }
) )
@ -160,10 +160,10 @@ let evaluateProgram = (inputs: Inputs.inputs) =>
let evaluateFunction = ( let evaluateFunction = (
inputs: Inputs.inputs, inputs: Inputs.inputs,
fn: (array<string>, ExpressionTypes.ExpressionTree.node), fn: (array<string>, ASTTypes.AST.node),
fnInputs, fnInputs,
) => { ) => {
let output = ExpressionTree.runFunction( let output = AST.runFunction(
Internals.makeInputs(inputs), Internals.makeInputs(inputs),
inputs.environment, inputs.environment,
fnInputs, fnInputs,
@ -179,7 +179,7 @@ let runAll = (squiggleString: string) => {
sampleCount: Some(10000), sampleCount: Some(10000),
outputXYPoints: Some(10000), outputXYPoints: Some(10000),
kernelWidth: None, kernelWidth: None,
shapeLength: Some(1000), pointSetDistLength: Some(1000),
}, },
~squiggleString, ~squiggleString,
~environment=[]->Belt.Map.String.fromArray, ~environment=[]->Belt.Map.String.fromArray,

View File

@ -1,17 +1,19 @@
open ExpressionTypes.ExpressionTree open ASTTypes.AST
let toString = ASTBasic.toString
let toString = ExpressionTreeBasic.toString
let envs = (samplingInputs, environment) => { let envs = (samplingInputs, environment) => {
samplingInputs: samplingInputs, samplingInputs: samplingInputs,
environment: environment, environment: environment,
evaluateNode: ExpressionTreeEvaluator.toLeaf, evaluateNode: ASTEvaluator.toLeaf,
} }
let toLeaf = (samplingInputs, environment, node: node) => let toLeaf = (samplingInputs, environment, node: node) =>
ExpressionTreeEvaluator.toLeaf(envs(samplingInputs, environment), node) ASTEvaluator.toLeaf(envs(samplingInputs, environment), node)
let toShape = (samplingInputs, environment, node: node) =>
let toPointSetDist = (samplingInputs, environment, node: node) =>
switch toLeaf(samplingInputs, environment, node) { switch toLeaf(samplingInputs, environment, node) {
| Ok(#RenderedDist(shape)) => Ok(shape) | Ok(#RenderedDist(pointSetDist)) => Ok(pointSetDist)
| Ok(_) => Error("Rendering failed.") | Ok(_) => Error("Rendering failed.")
| Error(e) => Error(e) | Error(e) => Error(e)
} }

View File

@ -1,4 +1,5 @@
open ExpressionTypes.ExpressionTree open ASTTypes.AST
// This file exists to manage a dependency cycle. It would be good to refactor later.
let rec toString: node => string = x => let rec toString: node => string = x =>
switch x { switch x {

View File

@ -1,5 +1,5 @@
open ExpressionTypes open ASTTypes
open ExpressionTypes.ExpressionTree open ASTTypes.AST
type t = node type t = node
type tResult = node => result<node, string> type tResult = node => result<node, string>
@ -27,7 +27,7 @@ module AlgebraicCombination = {
E.R.merge( E.R.merge(
Render.ensureIsRenderedAndGetShape(evaluationParams, t1), Render.ensureIsRenderedAndGetShape(evaluationParams, t1),
Render.ensureIsRenderedAndGetShape(evaluationParams, t2), Render.ensureIsRenderedAndGetShape(evaluationParams, t2),
) |> E.R.fmap(((a, b)) => #RenderedDist(Shape.combineAlgebraically(algebraicOp, a, b))) ) |> E.R.fmap(((a, b)) => #RenderedDist(PointSetDist.combineAlgebraically(algebraicOp, a, b)))
let nodeScore: node => int = x => let nodeScore: node => int = x =>
switch x { switch x {
@ -56,7 +56,7 @@ module AlgebraicCombination = {
let operationToLeaf = ( let operationToLeaf = (
evaluationParams: evaluationParams, evaluationParams: evaluationParams,
algebraicOp: ExpressionTypes.algebraicOperation, algebraicOp: ASTTypes.algebraicOperation,
t1: t, t1: t,
t2: t, t2: t,
): result<node, string> => ): result<node, string> =>
@ -76,7 +76,7 @@ module PointwiseCombination = {
| (Ok(#RenderedDist(rs1)), Ok(#RenderedDist(rs2))) => | (Ok(#RenderedDist(rs1)), Ok(#RenderedDist(rs2))) =>
Ok( Ok(
#RenderedDist( #RenderedDist(
Shape.combinePointwise( PointSetDist.combinePointwise(
~integralSumCachesFn=(a, b) => Some(a +. b), ~integralSumCachesFn=(a, b) => Some(a +. b),
~integralCachesFn=(a, b) => Some( ~integralCachesFn=(a, b) => Some(
Continuous.combinePointwise(~distributionType=#CDF, \"+.", a, b), Continuous.combinePointwise(~distributionType=#CDF, \"+.", a, b),
@ -94,11 +94,11 @@ module PointwiseCombination = {
let pointwiseCombine = (fn, evaluationParams: evaluationParams, t1: t, t2: t) => let pointwiseCombine = (fn, evaluationParams: evaluationParams, t1: t, t2: t) =>
switch // TODO: construct a function that we can easily sample from, to construct switch // TODO: construct a function that we can easily sample from, to construct
// a RenderedDist. Use the xMin and xMax of the rendered shapes to tell the sampling function where to look. // a RenderedDist. Use the xMin and xMax of the rendered pointSetDists to tell the sampling function where to look.
// TODO: This should work for symbolic distributions too! // TODO: This should work for symbolic distributions too!
(Render.render(evaluationParams, t1), Render.render(evaluationParams, t2)) { (Render.render(evaluationParams, t1), Render.render(evaluationParams, t2)) {
| (Ok(#RenderedDist(rs1)), Ok(#RenderedDist(rs2))) => | (Ok(#RenderedDist(rs1)), Ok(#RenderedDist(rs2))) =>
Ok(#RenderedDist(Shape.combinePointwise(fn, rs1, rs2))) Ok(#RenderedDist(PointSetDist.combinePointwise(fn, rs1, rs2)))
| (Error(e1), _) => Error(e1) | (Error(e1), _) => Error(e1)
| (_, Error(e2)) => Error(e2) | (_, Error(e2)) => Error(e2)
| _ => Error("Pointwise combination: rendering failed.") | _ => Error("Pointwise combination: rendering failed.")
@ -132,7 +132,7 @@ module Truncate = {
switch // TODO: use named args for xMin/xMax in renderToShape; if we're lucky we can at least get the tail switch // TODO: use named args for xMin/xMax in renderToShape; if we're lucky we can at least get the tail
// of a distribution we otherwise wouldn't get at all // of a distribution we otherwise wouldn't get at all
Render.ensureIsRendered(evaluationParams, t) { Render.ensureIsRendered(evaluationParams, t) {
| Ok(#RenderedDist(rs)) => Ok(#RenderedDist(Shape.T.truncate(leftCutoff, rightCutoff, rs))) | Ok(#RenderedDist(rs)) => Ok(#RenderedDist(PointSetDist.T.truncate(leftCutoff, rightCutoff, rs)))
| Error(e) => Error(e) | Error(e) => Error(e)
| _ => Error("Could not truncate distribution.") | _ => Error("Could not truncate distribution.")
} }
@ -158,7 +158,7 @@ module Truncate = {
module Normalize = { module Normalize = {
let rec operationToLeaf = (evaluationParams, t: node): result<node, string> => let rec operationToLeaf = (evaluationParams, t: node): result<node, string> =>
switch t { switch t {
| #RenderedDist(s) => Ok(#RenderedDist(Shape.T.normalize(s))) | #RenderedDist(s) => Ok(#RenderedDist(PointSetDist.T.normalize(s)))
| #SymbolicDist(_) => Ok(t) | #SymbolicDist(_) => Ok(t)
| _ => evaluateAndRetry(evaluationParams, operationToLeaf, t) | _ => evaluateAndRetry(evaluationParams, operationToLeaf, t)
} }
@ -174,9 +174,9 @@ module FunctionCall = {
) )
let _runWithEvaluatedInputs = ( let _runWithEvaluatedInputs = (
evaluationParams: ExpressionTypes.ExpressionTree.evaluationParams, evaluationParams: ASTTypes.AST.evaluationParams,
name, name,
args: array<ExpressionTypes.ExpressionTree.node>, args: array<ASTTypes.AST.node>,
) => ) =>
_runHardcodedFunction(name, evaluationParams, args) |> E.O.default( _runHardcodedFunction(name, evaluationParams, args) |> E.O.default(
_runLocalFunction(name, evaluationParams, args), _runLocalFunction(name, evaluationParams, args),
@ -195,8 +195,8 @@ module Render = {
switch t { switch t {
| #Function(_) => Error("Cannot render a function") | #Function(_) => Error("Cannot render a function")
| #SymbolicDist(d) => | #SymbolicDist(d) =>
Ok(#RenderedDist(SymbolicDist.T.toShape(evaluationParams.samplingInputs.shapeLength, d))) Ok(#RenderedDist(SymbolicDist.T.toPointSetDist(evaluationParams.samplingInputs.pointSetDistLength, d)))
| #RenderedDist(_) as t => Ok(t) // already a rendered shape, we're done here | #RenderedDist(_) as t => Ok(t) // already a rendered pointSetDist, we're done here
| _ => evaluateAndRetry(evaluationParams, operationToLeaf, t) | _ => evaluateAndRetry(evaluationParams, operationToLeaf, t)
} }
} }
@ -208,7 +208,7 @@ module Render = {
This function is used mainly to turn a parse tree into a single RenderedDist This function is used mainly to turn a parse tree into a single RenderedDist
that can then be displayed to the user. */ that can then be displayed to the user. */
let rec toLeaf = ( let rec toLeaf = (
evaluationParams: ExpressionTypes.ExpressionTree.evaluationParams, evaluationParams: ASTTypes.AST.evaluationParams,
node: t, node: t,
): result<t, string> => ): result<t, string> =>
switch node { switch node {
@ -236,7 +236,7 @@ let rec toLeaf = (
|> E.A.R.firstErrorOrOpen |> E.A.R.firstErrorOrOpen
|> E.R.fmap(r => #Hash(r)) |> E.R.fmap(r => #Hash(r))
| #Symbol(r) => | #Symbol(r) =>
ExpressionTypes.ExpressionTree.Environment.get(evaluationParams.environment, r) ASTTypes.AST.Environment.get(evaluationParams.environment, r)
|> E.O.toResult("Undeclared variable " ++ r) |> E.O.toResult("Undeclared variable " ++ r)
|> E.R.bind(_, toLeaf(evaluationParams)) |> E.R.bind(_, toLeaf(evaluationParams))
| #FunctionCall(name, args) => | #FunctionCall(name, args) =>

View File

@ -15,11 +15,11 @@ type distToFloatOperation = [
| #Sample | #Sample
] ]
module ExpressionTree = { module AST = {
type rec hash = array<(string, node)> type rec hash = array<(string, node)>
and node = [ and node = [
| #SymbolicDist(SymbolicTypes.symbolicDist) | #SymbolicDist(SymbolicDistTypes.symbolicDist)
| #RenderedDist(DistTypes.shape) | #RenderedDist(PointSetTypes.pointSetDist)
| #Symbol(string) | #Symbol(string)
| #Hash(hash) | #Hash(hash)
| #Array(array<node>) | #Array(array<node>)
@ -64,7 +64,7 @@ module ExpressionTree = {
sampleCount: int, sampleCount: int,
outputXYPoints: int, outputXYPoints: int,
kernelWidth: option<float>, kernelWidth: option<float>,
shapeLength: int, pointSetDistLength: int,
} }
module SamplingInputs = { module SamplingInputs = {
@ -72,13 +72,13 @@ module ExpressionTree = {
sampleCount: option<int>, sampleCount: option<int>,
outputXYPoints: option<int>, outputXYPoints: option<int>,
kernelWidth: option<float>, kernelWidth: option<float>,
shapeLength: option<int>, pointSetDistLength: option<int>,
} }
let withDefaults = (t: t): samplingInputs => { let withDefaults = (t: t): samplingInputs => {
sampleCount: t.sampleCount |> E.O.default(10000), sampleCount: t.sampleCount |> E.O.default(10000),
outputXYPoints: t.outputXYPoints |> E.O.default(10000), outputXYPoints: t.outputXYPoints |> E.O.default(10000),
kernelWidth: t.kernelWidth, kernelWidth: t.kernelWidth,
shapeLength: t.shapeLength |> E.O.default(10000), pointSetDistLength: t.pointSetDistLength |> E.O.default(10000),
} }
} }
@ -148,7 +148,7 @@ module ExpressionTree = {
| _ => None | _ => None
} }
let _toFloat = (t: DistTypes.shape) => let _toFloat = (t: PointSetTypes.pointSetDist) =>
switch t { switch t {
| Discrete({xyShape: {xs: [x], ys: [1.0]}}) => Some(#SymbolicDist(#Float(x))) | Discrete({xyShape: {xs: [x], ys: [1.0]}}) => Some(#SymbolicDist(#Float(x)))
| _ => None | _ => None
@ -160,15 +160,15 @@ module ExpressionTree = {
} }
type simplificationResult = [ type simplificationResult = [
| #Solution(ExpressionTree.node) | #Solution(AST.node)
| #Error(string) | #Error(string)
| #NoSolution | #NoSolution
] ]
module Program = { module Program = {
type statement = [ type statement = [
| #Assignment(string, ExpressionTree.node) | #Assignment(string, AST.node)
| #Expression(ExpressionTree.node) | #Expression(AST.node)
] ]
type program = array<statement> type program = array<statement>
} }

View File

@ -1,4 +1,4 @@
open ExpressionTypes open ASTTypes
module Algebraic = { module Algebraic = {
type t = algebraicOperation type t = algebraicOperation
@ -103,5 +103,5 @@ module T = {
| #Truncate(lc, rc, t) => truncateToString(lc, rc, nodeToString(t)) | #Truncate(lc, rc, t) => truncateToString(lc, rc, nodeToString(t))
| #Render(t) => nodeToString(t) | #Render(t) => nodeToString(t)
| _ => "" | _ => ""
} // SymbolicDist and RenderedDist are handled in ExpressionTree.toString. } // SymbolicDist and RenderedDist are handled in AST.toString.
} }

View File

@ -1,4 +1,4 @@
open ExpressionTypes.ExpressionTree open ASTTypes.AST
module Function = { module Function = {
type t = (array<string>, node) type t = (array<string>, node)
@ -10,7 +10,7 @@ module Function = {
let argumentNames = ((a, _): t) => a let argumentNames = ((a, _): t) => a
let internals = ((_, b): t) => b let internals = ((_, b): t) => b
let run = ( let run = (
evaluationParams: ExpressionTypes.ExpressionTree.evaluationParams, evaluationParams: ASTTypes.AST.evaluationParams,
args: array<node>, args: array<node>,
t: t, t: t,
) => ) =>
@ -19,10 +19,10 @@ module Function = {
Belt.Array.zip( Belt.Array.zip(
argumentNames(t), argumentNames(t),
args, args,
) |> ExpressionTypes.ExpressionTree.Environment.fromArray ) |> ASTTypes.AST.Environment.fromArray
let newEvaluationParams: ExpressionTypes.ExpressionTree.evaluationParams = { let newEvaluationParams: ASTTypes.AST.evaluationParams = {
samplingInputs: evaluationParams.samplingInputs, samplingInputs: evaluationParams.samplingInputs,
environment: ExpressionTypes.ExpressionTree.Environment.mergeKeepSecond( environment: ASTTypes.AST.Environment.mergeKeepSecond(
evaluationParams.environment, evaluationParams.environment,
newEnvironment, newEnvironment,
), ),
@ -36,8 +36,8 @@ module Function = {
module Primative = { module Primative = {
type t = [ type t = [
| #SymbolicDist(SymbolicTypes.symbolicDist) | #SymbolicDist(SymbolicDistTypes.symbolicDist)
| #RenderedDist(DistTypes.shape) | #RenderedDist(PointSetTypes.pointSetDist)
| #Function(array<string>, node) | #Function(array<string>, node)
] ]
@ -61,8 +61,8 @@ module Primative = {
module SamplingDistribution = { module SamplingDistribution = {
type t = [ type t = [
| #SymbolicDist(SymbolicTypes.symbolicDist) | #SymbolicDist(SymbolicDistTypes.symbolicDist)
| #RenderedDist(DistTypes.shape) | #RenderedDist(PointSetTypes.pointSetDist)
] ]
let isSamplingDistribution: node => bool = x => let isSamplingDistribution: node => bool = x =>
@ -98,7 +98,7 @@ module SamplingDistribution = {
) )
let sampleN = n => let sampleN = n =>
map(~renderedDistFn=Shape.sampleNRendered(n), ~symbolicDistFn=SymbolicDist.T.sampleN(n)) map(~renderedDistFn=PointSetDist.sampleNRendered(n), ~symbolicDistFn=SymbolicDist.T.sampleN(n))
let getCombinationSamples = (n, algebraicOp, t1: node, t2: node) => let getCombinationSamples = (n, algebraicOp, t1: node, t2: node) =>
switch (sampleN(n, t1), sampleN(n, t2)) { switch (sampleN(n, t1), sampleN(n, t2)) {
@ -126,12 +126,13 @@ module SamplingDistribution = {
) )
// todo: This bottom part should probably be somewhere else. // todo: This bottom part should probably be somewhere else.
let shape = // todo: REFACTOR: I'm not sure about the SampleSet line.
let pointSetDist =
samples samples
|> E.O.fmap(SamplesToShape.fromSamples(~samplingInputs=evaluationParams.samplingInputs)) |> E.O.fmap(r => SampleSet.toPointSetDist(~samplingInputs=evaluationParams.samplingInputs, ~samples=r, ()))
|> E.O.bind(_, r => r.shape) |> E.O.bind(_, r => r.pointSetDist)
|> E.O.toResult("No response") |> E.O.toResult("No response")
shape |> E.R.fmap(r => #Normalize(#RenderedDist(r))) pointSetDist |> E.R.fmap(r => #Normalize(#RenderedDist(r)))
}) })
} }
} }

View File

@ -84,13 +84,13 @@ let makeDist = (name, fn) =>
) )
let floatFromDist = ( let floatFromDist = (
distToFloatOp: ExpressionTypes.distToFloatOperation, distToFloatOp: ASTTypes.distToFloatOperation,
t: TypeSystem.samplingDist, t: TypeSystem.samplingDist,
): result<node, string> => ): result<node, string> =>
switch t { switch t {
| #SymbolicDist(s) => | #SymbolicDist(s) =>
SymbolicDist.T.operate(distToFloatOp, s) |> E.R.bind(_, v => Ok(#SymbolicDist(#Float(v)))) SymbolicDist.T.operate(distToFloatOp, s) |> E.R.bind(_, v => Ok(#SymbolicDist(#Float(v))))
| #RenderedDist(rs) => Shape.operate(distToFloatOp, rs) |> (v => Ok(#SymbolicDist(#Float(v)))) | #RenderedDist(rs) => PointSetDist.operate(distToFloatOp, rs) |> (v => Ok(#SymbolicDist(#Float(v))))
} }
let verticalScaling = (scaleOp, rs, scaleBy) => { let verticalScaling = (scaleOp, rs, scaleBy) => {
@ -100,7 +100,7 @@ let verticalScaling = (scaleOp, rs, scaleBy) => {
let integralCacheFn = Operation.Scale.toIntegralCacheFn(scaleOp) let integralCacheFn = Operation.Scale.toIntegralCacheFn(scaleOp)
Ok( Ok(
#RenderedDist( #RenderedDist(
Shape.T.mapY( PointSetDist.T.mapY(
~integralSumCacheFn=integralSumCacheFn(scaleBy), ~integralSumCacheFn=integralSumCacheFn(scaleBy),
~integralCacheFn=integralCacheFn(scaleBy), ~integralCacheFn=integralCacheFn(scaleBy),
~fn=fn(scaleBy), ~fn=fn(scaleBy),
@ -111,7 +111,7 @@ let verticalScaling = (scaleOp, rs, scaleBy) => {
} }
module Multimodal = { module Multimodal = {
let getByNameResult = ExpressionTypes.ExpressionTree.Hash.getByNameResult let getByNameResult = ASTTypes.AST.Hash.getByNameResult
let _paramsToDistsAndWeights = (r: array<typedValue>) => let _paramsToDistsAndWeights = (r: array<typedValue>) =>
switch r { switch r {
@ -209,7 +209,7 @@ let all = [
~run=x => ~run=x =>
switch x { switch x {
| [#SamplingDist(#SymbolicDist(c))] => Ok(#SymbolicDist(c)) | [#SamplingDist(#SymbolicDist(c))] => Ok(#SymbolicDist(c))
| [#SamplingDist(#RenderedDist(c))] => Ok(#RenderedDist(Shape.T.normalize(c))) | [#SamplingDist(#RenderedDist(c))] => Ok(#RenderedDist(PointSetDist.T.normalize(c)))
| e => wrongInputsError(e) | e => wrongInputsError(e)
}, },
(), (),

View File

@ -1,9 +1,9 @@
type node = ExpressionTypes.ExpressionTree.node type node = ASTTypes.AST.node
let getFloat = ExpressionTypes.ExpressionTree.getFloat let getFloat = ASTTypes.AST.getFloat
type samplingDist = [ type samplingDist = [
| #SymbolicDist(SymbolicTypes.symbolicDist) | #SymbolicDist(SymbolicDistTypes.symbolicDist)
| #RenderedDist(DistTypes.shape) | #RenderedDist(PointSetTypes.pointSetDist)
] ]
type rec hashType = array<(string, _type)> type rec hashType = array<(string, _type)>
@ -18,7 +18,7 @@ and _type = [
type rec hashTypedValue = array<(string, typedValue)> type rec hashTypedValue = array<(string, typedValue)>
and typedValue = [ and typedValue = [
| #Float(float) | #Float(float)
| #RenderedDist(DistTypes.shape) | #RenderedDist(PointSetTypes.pointSetDist)
| #SamplingDist(samplingDist) | #SamplingDist(samplingDist)
| #Array(array<typedValue>) | #Array(array<typedValue>)
| #Hash(hashTypedValue) | #Hash(hashTypedValue)
@ -39,7 +39,7 @@ module TypedValue = {
let rec toString: typedValue => string = x => let rec toString: typedValue => string = x =>
switch x { switch x {
| #SamplingDist(_) => "[sampling dist]" | #SamplingDist(_) => "[sampling dist]"
| #RenderedDist(_) => "[rendered Shape]" | #RenderedDist(_) => "[rendered PointSetDist]"
| #Float(f) => "Float: " ++ Js.Float.toString(f) | #Float(f) => "Float: " ++ Js.Float.toString(f)
| #Array(a) => "[" ++ ((a |> E.A.fmap(toString) |> Js.String.concatMany(_, ",")) ++ "]") | #Array(a) => "[" ++ ((a |> E.A.fmap(toString) |> Js.String.concatMany(_, ",")) ++ "]")
| #Hash(v) => | #Hash(v) =>
@ -61,7 +61,7 @@ module TypedValue = {
|> E.A.fmap(((name, t)) => fromNode(t) |> E.R.fmap(r => (name, r))) |> E.A.fmap(((name, t)) => fromNode(t) |> E.R.fmap(r => (name, r)))
|> E.A.R.firstErrorOrOpen |> E.A.R.firstErrorOrOpen
|> E.R.fmap(r => #Hash(r)) |> E.R.fmap(r => #Hash(r))
| e => Error("Wrong type: " ++ ExpressionTreeBasic.toString(e)) | e => Error("Wrong type: " ++ ASTBasic.toString(e))
} }
// todo: Arrays and hashes // todo: Arrays and hashes
@ -78,7 +78,7 @@ module TypedValue = {
node, node,
) |> E.R.bind(_, fromNode) ) |> E.R.bind(_, fromNode)
| (#RenderedDistribution, _) => | (#RenderedDistribution, _) =>
ExpressionTypes.ExpressionTree.Render.render(evaluationParams, node) |> E.R.bind(_, fromNode) ASTTypes.AST.Render.render(evaluationParams, node) |> E.R.bind(_, fromNode)
| (#Array(_type), #Array(b)) => | (#Array(_type), #Array(b)) =>
b b
|> E.A.fmap(fromNodeWithTypeCoercion(evaluationParams, _type)) |> E.A.fmap(fromNodeWithTypeCoercion(evaluationParams, _type))
@ -89,7 +89,7 @@ module TypedValue = {
named |> E.A.fmap(((name, intendedType)) => ( named |> E.A.fmap(((name, intendedType)) => (
name, name,
intendedType, intendedType,
ExpressionTypes.ExpressionTree.Hash.getByName(r, name), ASTTypes.AST.Hash.getByName(r, name),
)) ))
let typedHash = let typedHash =
keyValues keyValues
@ -172,7 +172,7 @@ module Function = {
|> E.A.R.firstErrorOrOpen |> E.A.R.firstErrorOrOpen
let inputsToTypedValues = ( let inputsToTypedValues = (
evaluationParams: ExpressionTypes.ExpressionTree.evaluationParams, evaluationParams: ASTTypes.AST.evaluationParams,
inputNodes: inputNodes, inputNodes: inputNodes,
t: t, t: t,
) => ) =>
@ -181,7 +181,7 @@ module Function = {
) )
let run = ( let run = (
evaluationParams: ExpressionTypes.ExpressionTree.evaluationParams, evaluationParams: ASTTypes.AST.evaluationParams,
inputNodes: inputNodes, inputNodes: inputNodes,
t: t, t: t,
) => ) =>

View File

@ -122,7 +122,7 @@ module MathAdtToDistDst = {
| _ => Error("Lognormal distribution needs either mean and stdev or mu and sigma") | _ => Error("Lognormal distribution needs either mean and stdev or mu and sigma")
} }
| _ => | _ =>
parseArgs() |> E.R.fmap((args: array<ExpressionTypes.ExpressionTree.node>) => parseArgs() |> E.R.fmap((args: array<ASTTypes.AST.node>) =>
#FunctionCall("lognormal", args) #FunctionCall("lognormal", args)
) )
} }
@ -130,8 +130,8 @@ module MathAdtToDistDst = {
// Error("Dotwise exponentiation needs two operands") // Error("Dotwise exponentiation needs two operands")
let operationParser = ( let operationParser = (
name: string, name: string,
args: result<array<ExpressionTypes.ExpressionTree.node>, string>, args: result<array<ASTTypes.AST.node>, string>,
): result<ExpressionTypes.ExpressionTree.node, string> => { ): result<ASTTypes.AST.node, string> => {
let toOkAlgebraic = r => Ok(#AlgebraicCombination(r)) let toOkAlgebraic = r => Ok(#AlgebraicCombination(r))
let toOkPointwise = r => Ok(#PointwiseCombination(r)) let toOkPointwise = r => Ok(#PointwiseCombination(r))
let toOkTruncate = r => Ok(#Truncate(r)) let toOkTruncate = r => Ok(#Truncate(r))
@ -170,12 +170,12 @@ module MathAdtToDistDst = {
let functionParser = ( let functionParser = (
nodeParser: MathJsonToMathJsAdt.arg => Belt.Result.t< nodeParser: MathJsonToMathJsAdt.arg => Belt.Result.t<
ExpressionTypes.ExpressionTree.node, ASTTypes.AST.node,
string, string,
>, >,
name: string, name: string,
args: array<MathJsonToMathJsAdt.arg>, args: array<MathJsonToMathJsAdt.arg>,
): result<ExpressionTypes.ExpressionTree.node, string> => { ): result<ASTTypes.AST.node, string> => {
let parseArray = ags => ags |> E.A.fmap(nodeParser) |> E.A.R.firstErrorOrOpen let parseArray = ags => ags |> E.A.fmap(nodeParser) |> E.A.R.firstErrorOrOpen
let parseArgs = () => parseArray(args) let parseArgs = () => parseArray(args)
switch name { switch name {
@ -212,27 +212,27 @@ module MathAdtToDistDst = {
| (Some(Error(r)), _) => Error(r) | (Some(Error(r)), _) => Error(r)
| (_, Error(r)) => Error(r) | (_, Error(r)) => Error(r)
| (None, Ok(dists)) => | (None, Ok(dists)) =>
let hash: ExpressionTypes.ExpressionTree.node = #FunctionCall( let hash: ASTTypes.AST.node = #FunctionCall(
"multimodal", "multimodal",
[#Hash([("dists", #Array(dists)), ("weights", #Array([]))])], [#Hash([("dists", #Array(dists)), ("weights", #Array([]))])],
) )
Ok(hash) Ok(hash)
| (Some(Ok(weights)), Ok(dists)) => | (Some(Ok(weights)), Ok(dists)) =>
let hash: ExpressionTypes.ExpressionTree.node = #FunctionCall( let hash: ASTTypes.AST.node = #FunctionCall(
"multimodal", "multimodal",
[#Hash([("dists", #Array(dists)), ("weights", #Array(weights))])], [#Hash([("dists", #Array(dists)), ("weights", #Array(weights))])],
) )
Ok(hash) Ok(hash)
} }
| name => | name =>
parseArgs() |> E.R.fmap((args: array<ExpressionTypes.ExpressionTree.node>) => parseArgs() |> E.R.fmap((args: array<ASTTypes.AST.node>) =>
#FunctionCall(name, args) #FunctionCall(name, args)
) )
} }
} }
let rec nodeParser: MathJsonToMathJsAdt.arg => result< let rec nodeParser: MathJsonToMathJsAdt.arg => result<
ExpressionTypes.ExpressionTree.node, ASTTypes.AST.node,
string, string,
> = x => > = x =>
switch x { switch x {
@ -246,7 +246,7 @@ module MathAdtToDistDst = {
// let evaluatedExpression = run(expression); // let evaluatedExpression = run(expression);
// `Function(_ => Ok(evaluatedExpression)); // `Function(_ => Ok(evaluatedExpression));
// } // }
let rec topLevel = (r): result<ExpressionTypes.Program.program, string> => let rec topLevel = (r): result<ASTTypes.Program.program, string> =>
switch r { switch r {
| FunctionAssignment({name, args, expression}) => | FunctionAssignment({name, args, expression}) =>
switch nodeParser(expression) { switch nodeParser(expression) {
@ -267,7 +267,7 @@ module MathAdtToDistDst = {
blocks |> E.A.fmap(b => topLevel(b)) |> E.A.R.firstErrorOrOpen |> E.R.fmap(E.A.concatMany) blocks |> E.A.fmap(b => topLevel(b)) |> E.A.R.firstErrorOrOpen |> E.R.fmap(E.A.concatMany)
} }
let run = (r): result<ExpressionTypes.Program.program, string> => let run = (r): result<ASTTypes.Program.program, string> =>
r |> MathAdtCleaner.run |> topLevel r |> MathAdtCleaner.run |> topLevel
} }

View File

@ -96,10 +96,10 @@ let toDiscretePointMassesFromTriangulars = (
} }
let combineShapesContinuousContinuous = ( let combineShapesContinuousContinuous = (
op: ExpressionTypes.algebraicOperation, op: ASTTypes.algebraicOperation,
s1: DistTypes.xyShape, s1: PointSetTypes.xyShape,
s2: DistTypes.xyShape, s2: PointSetTypes.xyShape,
): DistTypes.xyShape => { ): PointSetTypes.xyShape => {
let t1n = s1 |> XYShape.T.length let t1n = s1 |> XYShape.T.length
let t2n = s2 |> XYShape.T.length let t2n = s2 |> XYShape.T.length
@ -188,7 +188,7 @@ let combineShapesContinuousContinuous = (
{xs: outputXs, ys: outputYs} {xs: outputXs, ys: outputYs}
} }
let toDiscretePointMassesFromDiscrete = (s: DistTypes.xyShape): pointMassesWithMoments => { let toDiscretePointMassesFromDiscrete = (s: PointSetTypes.xyShape): pointMassesWithMoments => {
let {xs, ys}: XYShape.T.t = s let {xs, ys}: XYShape.T.t = s
let n = E.A.length(xs) let n = E.A.length(xs)
@ -200,10 +200,10 @@ let toDiscretePointMassesFromDiscrete = (s: DistTypes.xyShape): pointMassesWithM
} }
let combineShapesContinuousDiscrete = ( let combineShapesContinuousDiscrete = (
op: ExpressionTypes.algebraicOperation, op: ASTTypes.algebraicOperation,
continuousShape: DistTypes.xyShape, continuousShape: PointSetTypes.xyShape,
discreteShape: DistTypes.xyShape, discreteShape: PointSetTypes.xyShape,
): DistTypes.xyShape => { ): PointSetTypes.xyShape => {
let t1n = continuousShape |> XYShape.T.length let t1n = continuousShape |> XYShape.T.length
let t2n = discreteShape |> XYShape.T.length let t2n = discreteShape |> XYShape.T.length

View File

@ -1,6 +1,6 @@
open Distributions open Distributions
type t = DistTypes.continuousShape type t = PointSetTypes.continuousShape
let getShape = (t: t) => t.xyShape let getShape = (t: t) => t.xyShape
let interpolation = (t: t) => t.interpolation let interpolation = (t: t) => t.interpolation
let make = (~interpolation=#Linear, ~integralSumCache=None, ~integralCache=None, xyShape): t => { let make = (~interpolation=#Linear, ~integralSumCache=None, ~integralCache=None, xyShape): t => {
@ -17,10 +17,10 @@ let shapeMap = (fn, {xyShape, interpolation, integralSumCache, integralCache}: t
} }
let lastY = (t: t) => t |> getShape |> XYShape.T.lastY let lastY = (t: t) => t |> getShape |> XYShape.T.lastY
let oShapeMap = (fn, {xyShape, interpolation, integralSumCache, integralCache}: t): option< let oShapeMap = (fn, {xyShape, interpolation, integralSumCache, integralCache}: t): option<
DistTypes.continuousShape, PointSetTypes.continuousShape,
> => fn(xyShape) |> E.O.fmap(make(~interpolation, ~integralSumCache, ~integralCache)) > => fn(xyShape) |> E.O.fmap(make(~interpolation, ~integralSumCache, ~integralCache))
let emptyIntegral: DistTypes.continuousShape = { let emptyIntegral: PointSetTypes.continuousShape = {
xyShape: { xyShape: {
xs: [neg_infinity], xs: [neg_infinity],
ys: [0.0], ys: [0.0],
@ -29,7 +29,7 @@ let emptyIntegral: DistTypes.continuousShape = {
integralSumCache: Some(0.0), integralSumCache: Some(0.0),
integralCache: None, integralCache: None,
} }
let empty: DistTypes.continuousShape = { let empty: PointSetTypes.continuousShape = {
xyShape: XYShape.T.empty, xyShape: XYShape.T.empty,
interpolation: #Linear, interpolation: #Linear,
integralSumCache: Some(0.0), integralSumCache: Some(0.0),
@ -47,11 +47,11 @@ let stepwiseToLinear = (t: t): t =>
let combinePointwise = ( let combinePointwise = (
~integralSumCachesFn=(_, _) => None, ~integralSumCachesFn=(_, _) => None,
~integralCachesFn: (t, t) => option<t>=(_, _) => None, ~integralCachesFn: (t, t) => option<t>=(_, _) => None,
~distributionType: DistTypes.distributionType=#PDF, ~distributionType: PointSetTypes.distributionType=#PDF,
fn: (float, float) => float, fn: (float, float) => float,
t1: DistTypes.continuousShape, t1: PointSetTypes.continuousShape,
t2: DistTypes.continuousShape, t2: PointSetTypes.continuousShape,
): DistTypes.continuousShape => { ): PointSetTypes.continuousShape => {
// If we're adding the distributions, and we know the total of each, then we // If we're adding the distributions, and we know the total of each, then we
// can just sum them up. Otherwise, all bets are off. // can just sum them up. Otherwise, all bets are off.
let combinedIntegralSum = Common.combineIntegralSums( let combinedIntegralSum = Common.combineIntegralSums(
@ -130,19 +130,19 @@ let rec scaleBy = (~scale=1.0, t: t): t => {
} }
module T = Dist({ module T = Dist({
type t = DistTypes.continuousShape type t = PointSetTypes.continuousShape
type integral = DistTypes.continuousShape type integral = PointSetTypes.continuousShape
let minX = shapeFn(XYShape.T.minX) let minX = shapeFn(XYShape.T.minX)
let maxX = shapeFn(XYShape.T.maxX) let maxX = shapeFn(XYShape.T.maxX)
let mapY = mapY let mapY = mapY
let updateIntegralCache = updateIntegralCache let updateIntegralCache = updateIntegralCache
let toDiscreteProbabilityMassFraction = _ => 0.0 let toDiscreteProbabilityMassFraction = _ => 0.0
let toShape = (t: t): DistTypes.shape => Continuous(t) let toPointSetDist = (t: t): PointSetTypes.pointSetDist => Continuous(t)
let xToY = (f, {interpolation, xyShape}: t) => let xToY = (f, {interpolation, xyShape}: t) =>
switch interpolation { switch interpolation {
| #Stepwise => xyShape |> XYShape.XtoY.stepwiseIncremental(f) |> E.O.default(0.0) | #Stepwise => xyShape |> XYShape.XtoY.stepwiseIncremental(f) |> E.O.default(0.0)
| #Linear => xyShape |> XYShape.XtoY.linear(f) | #Linear => xyShape |> XYShape.XtoY.linear(f)
} |> DistTypes.MixedPoint.makeContinuous } |> PointSetTypes.MixedPoint.makeContinuous
let truncate = (leftCutoff: option<float>, rightCutoff: option<float>, t: t) => { let truncate = (leftCutoff: option<float>, rightCutoff: option<float>, t: t) => {
let lc = E.O.default(neg_infinity, leftCutoff) let lc = E.O.default(neg_infinity, leftCutoff)
@ -211,9 +211,9 @@ module T = Dist({
/* This simply creates multiple copies of the continuous distribution, scaled and shifted according to /* This simply creates multiple copies of the continuous distribution, scaled and shifted according to
each discrete data point, and then adds them all together. */ each discrete data point, and then adds them all together. */
let combineAlgebraicallyWithDiscrete = ( let combineAlgebraicallyWithDiscrete = (
op: ExpressionTypes.algebraicOperation, op: ASTTypes.algebraicOperation,
t1: t, t1: t,
t2: DistTypes.discreteShape, t2: PointSetTypes.discreteShape,
) => { ) => {
let t1s = t1 |> getShape let t1s = t1 |> getShape
let t2s = t2.xyShape // TODO would like to use Discrete.getShape here, but current file structure doesn't allow for that let t2s = t2.xyShape // TODO would like to use Discrete.getShape here, but current file structure doesn't allow for that
@ -244,7 +244,7 @@ let combineAlgebraicallyWithDiscrete = (
} }
} }
let combineAlgebraically = (op: ExpressionTypes.algebraicOperation, t1: t, t2: t) => { let combineAlgebraically = (op: ASTTypes.algebraicOperation, t1: t, t2: t) => {
let s1 = t1 |> getShape let s1 = t1 |> getShape
let s2 = t2 |> getShape let s2 = t2 |> getShape
let t1n = s1 |> XYShape.T.length let t1n = s1 |> XYShape.T.length

View File

@ -1,6 +1,6 @@
open Distributions open Distributions
type t = DistTypes.discreteShape type t = PointSetTypes.discreteShape
let make = (~integralSumCache=None, ~integralCache=None, xyShape): t => { let make = (~integralSumCache=None, ~integralCache=None, xyShape): t => {
xyShape: xyShape, xyShape: xyShape,
@ -16,13 +16,13 @@ let getShape = (t: t) => t.xyShape
let oShapeMap = (fn, {xyShape, integralSumCache, integralCache}: t): option<t> => let oShapeMap = (fn, {xyShape, integralSumCache, integralCache}: t): option<t> =>
fn(xyShape) |> E.O.fmap(make(~integralSumCache, ~integralCache)) fn(xyShape) |> E.O.fmap(make(~integralSumCache, ~integralCache))
let emptyIntegral: DistTypes.continuousShape = { let emptyIntegral: PointSetTypes.continuousShape = {
xyShape: {xs: [neg_infinity], ys: [0.0]}, xyShape: {xs: [neg_infinity], ys: [0.0]},
interpolation: #Stepwise, interpolation: #Stepwise,
integralSumCache: Some(0.0), integralSumCache: Some(0.0),
integralCache: None, integralCache: None,
} }
let empty: DistTypes.discreteShape = { let empty: PointSetTypes.discreteShape = {
xyShape: XYShape.T.empty, xyShape: XYShape.T.empty,
integralSumCache: Some(0.0), integralSumCache: Some(0.0),
integralCache: Some(emptyIntegral), integralCache: Some(emptyIntegral),
@ -35,13 +35,13 @@ let lastY = (t: t) => t |> getShape |> XYShape.T.lastY
let combinePointwise = ( let combinePointwise = (
~integralSumCachesFn=(_, _) => None, ~integralSumCachesFn=(_, _) => None,
~integralCachesFn: ( ~integralCachesFn: (
DistTypes.continuousShape, PointSetTypes.continuousShape,
DistTypes.continuousShape, PointSetTypes.continuousShape,
) => option<DistTypes.continuousShape>=(_, _) => None, ) => option<PointSetTypes.continuousShape>=(_, _) => None,
fn, fn,
t1: DistTypes.discreteShape, t1: PointSetTypes.discreteShape,
t2: DistTypes.discreteShape, t2: PointSetTypes.discreteShape,
): DistTypes.discreteShape => { ): PointSetTypes.discreteShape => {
let combinedIntegralSum = Common.combineIntegralSums( let combinedIntegralSum = Common.combineIntegralSums(
integralSumCachesFn, integralSumCachesFn,
t1.integralSumCache, t1.integralSumCache,
@ -67,7 +67,7 @@ let reduce = (
~integralCachesFn=(_, _) => None, ~integralCachesFn=(_, _) => None,
fn, fn,
discreteShapes, discreteShapes,
): DistTypes.discreteShape => ): PointSetTypes.discreteShape =>
discreteShapes |> E.A.fold_left( discreteShapes |> E.A.fold_left(
combinePointwise(~integralSumCachesFn, ~integralCachesFn, fn), combinePointwise(~integralSumCachesFn, ~integralCachesFn, fn),
empty, empty,
@ -85,7 +85,7 @@ let updateIntegralCache = (integralCache, t: t): t => {
/* This multiples all of the data points together and creates a new discrete distribution from the results. /* This multiples all of the data points together and creates a new discrete distribution from the results.
Data points at the same xs get added together. It may be a good idea to downsample t1 and t2 before and/or the result after. */ Data points at the same xs get added together. It may be a good idea to downsample t1 and t2 before and/or the result after. */
let combineAlgebraically = (op: ExpressionTypes.algebraicOperation, t1: t, t2: t): t => { let combineAlgebraically = (op: ASTTypes.algebraicOperation, t1: t, t2: t): t => {
let t1s = t1 |> getShape let t1s = t1 |> getShape
let t2s = t2 |> getShape let t2s = t2 |> getShape
let t1n = t1s |> XYShape.T.length let t1n = t1s |> XYShape.T.length
@ -134,8 +134,8 @@ let scaleBy = (~scale=1.0, t: t): t => {
} }
module T = Dist({ module T = Dist({
type t = DistTypes.discreteShape type t = PointSetTypes.discreteShape
type integral = DistTypes.continuousShape type integral = PointSetTypes.continuousShape
let integral = t => let integral = t =>
switch (getShape(t) |> XYShape.T.isEmpty, t.integralCache) { switch (getShape(t) |> XYShape.T.isEmpty, t.integralCache) {
| (true, _) => emptyIntegral | (true, _) => emptyIntegral
@ -157,7 +157,7 @@ module T = Dist({
let toDiscreteProbabilityMassFraction = _ => 1.0 let toDiscreteProbabilityMassFraction = _ => 1.0
let mapY = mapY let mapY = mapY
let updateIntegralCache = updateIntegralCache let updateIntegralCache = updateIntegralCache
let toShape = (t: t): DistTypes.shape => Discrete(t) let toPointSetDist = (t: t): PointSetTypes.pointSetDist => Discrete(t)
let toContinuous = _ => None let toContinuous = _ => None
let toDiscrete = t => Some(t) let toDiscrete = t => Some(t)
@ -199,7 +199,7 @@ module T = Dist({
|> getShape |> getShape
|> XYShape.XtoY.stepwiseIfAtX(f) |> XYShape.XtoY.stepwiseIfAtX(f)
|> E.O.default(0.0) |> E.O.default(0.0)
|> DistTypes.MixedPoint.makeDiscrete |> PointSetTypes.MixedPoint.makeDiscrete
let integralXtoY = (f, t) => t |> integral |> Continuous.getShape |> XYShape.XtoY.linear(f) let integralXtoY = (f, t) => t |> integral |> Continuous.getShape |> XYShape.XtoY.linear(f)

View File

@ -1,40 +1,40 @@
open DistTypes; open PointSetTypes;
type t = DistTypes.distPlus; type t = PointSetTypes.distPlus;
let shapeIntegral = shape => Shape.T.Integral.get(shape); let pointSetDistIntegral = pointSetDist => PointSetDist.T.Integral.get(pointSetDist);
let make = let make =
( (
~shape, ~pointSetDist,
~squiggleString, ~squiggleString,
~domain=Complete, ~domain=Complete,
~unit=UnspecifiedDistribution, ~unit=UnspecifiedDistribution,
(), (),
) )
: t => { : t => {
let integral = shapeIntegral(shape); let integral = pointSetDistIntegral(pointSetDist);
{shape, domain, integralCache: integral, unit, squiggleString}; {pointSetDist, domain, integralCache: integral, unit, squiggleString};
}; };
let update = let update =
( (
~shape=?, ~pointSetDist=?,
~integralCache=?, ~integralCache=?,
~domain=?, ~domain=?,
~unit=?, ~unit=?,
~squiggleString=?, ~squiggleString=?,
t: t, t: t,
) => { ) => {
shape: E.O.default(t.shape, shape), pointSetDist: E.O.default(t.pointSetDist, pointSetDist),
integralCache: E.O.default(t.integralCache, integralCache), integralCache: E.O.default(t.integralCache, integralCache),
domain: E.O.default(t.domain, domain), domain: E.O.default(t.domain, domain),
unit: E.O.default(t.unit, unit), unit: E.O.default(t.unit, unit),
squiggleString: E.O.default(t.squiggleString, squiggleString), squiggleString: E.O.default(t.squiggleString, squiggleString),
}; };
let updateShape = (shape, t) => { let updateShape = (pointSetDist, t) => {
let integralCache = shapeIntegral(shape); let integralCache = pointSetDistIntegral(pointSetDist);
update(~shape, ~integralCache, t); update(~pointSetDist, ~integralCache, t);
}; };
let domainIncludedProbabilityMass = (t: t) => let domainIncludedProbabilityMass = (t: t) =>
@ -43,87 +43,87 @@ let domainIncludedProbabilityMass = (t: t) =>
let domainIncludedProbabilityMassAdjustment = (t: t, f) => let domainIncludedProbabilityMassAdjustment = (t: t, f) =>
f *. Domain.includedProbabilityMass(t.domain); f *. Domain.includedProbabilityMass(t.domain);
let toShape = ({shape, _}: t) => shape; let toPointSetDist = ({pointSetDist, _}: t) => pointSetDist;
let shapeFn = (fn, {shape}: t) => fn(shape); let pointSetDistFn = (fn, {pointSetDist}: t) => fn(pointSetDist);
module T = module T =
Distributions.Dist({ Distributions.Dist({
type t = DistTypes.distPlus; type t = PointSetTypes.distPlus;
type integral = DistTypes.distPlus; type integral = PointSetTypes.distPlus;
let toShape = toShape; let toPointSetDist = toPointSetDist;
let toContinuous = shapeFn(Shape.T.toContinuous); let toContinuous = pointSetDistFn(PointSetDist.T.toContinuous);
let toDiscrete = shapeFn(Shape.T.toDiscrete); let toDiscrete = pointSetDistFn(PointSetDist.T.toDiscrete);
let normalize = (t: t): t => { let normalize = (t: t): t => {
let normalizedShape = t |> toShape |> Shape.T.normalize; let normalizedShape = t |> toPointSetDist |> PointSetDist.T.normalize;
t |> updateShape(normalizedShape); t |> updateShape(normalizedShape);
}; };
let truncate = (leftCutoff, rightCutoff, t: t): t => { let truncate = (leftCutoff, rightCutoff, t: t): t => {
let truncatedShape = let truncatedShape =
t t
|> toShape |> toPointSetDist
|> Shape.T.truncate(leftCutoff, rightCutoff); |> PointSetDist.T.truncate(leftCutoff, rightCutoff);
t |> updateShape(truncatedShape); t |> updateShape(truncatedShape);
}; };
let xToY = (f, t: t) => let xToY = (f, t: t) =>
t t
|> toShape |> toPointSetDist
|> Shape.T.xToY(f) |> PointSetDist.T.xToY(f)
|> MixedPoint.fmap(domainIncludedProbabilityMassAdjustment(t)); |> MixedPoint.fmap(domainIncludedProbabilityMassAdjustment(t));
let minX = shapeFn(Shape.T.minX); let minX = pointSetDistFn(PointSetDist.T.minX);
let maxX = shapeFn(Shape.T.maxX); let maxX = pointSetDistFn(PointSetDist.T.maxX);
let toDiscreteProbabilityMassFraction = let toDiscreteProbabilityMassFraction =
shapeFn(Shape.T.toDiscreteProbabilityMassFraction); pointSetDistFn(PointSetDist.T.toDiscreteProbabilityMassFraction);
// This bit is kind of awkward, could probably use rethinking. // This bit is kind of awkward, could probably use rethinking.
let integral = (t: t) => let integral = (t: t) =>
updateShape(Continuous(t.integralCache), t); updateShape(Continuous(t.integralCache), t);
let updateIntegralCache = (integralCache: option<DistTypes.continuousShape>, t) => let updateIntegralCache = (integralCache: option<PointSetTypes.continuousShape>, t) =>
update(~integralCache=E.O.default(t.integralCache, integralCache), t); update(~integralCache=E.O.default(t.integralCache, integralCache), t);
let downsample = (i, t): t => let downsample = (i, t): t =>
updateShape(t |> toShape |> Shape.T.downsample(i), t); updateShape(t |> toPointSetDist |> PointSetDist.T.downsample(i), t);
// todo: adjust for limit, maybe? // todo: adjust for limit, maybe?
let mapY = let mapY =
( (
~integralSumCacheFn=previousIntegralSum => None, ~integralSumCacheFn=previousIntegralSum => None,
~integralCacheFn=previousIntegralCache => None, ~integralCacheFn=previousIntegralCache => None,
~fn, ~fn,
{shape, _} as t: t, {pointSetDist, _} as t: t,
) )
: t => : t =>
Shape.T.mapY(~integralSumCacheFn, ~fn, shape) PointSetDist.T.mapY(~integralSumCacheFn, ~fn, pointSetDist)
|> updateShape(_, t); |> updateShape(_, t);
// get the total of everything // get the total of everything
let integralEndY = (t: t) => { let integralEndY = (t: t) => {
Shape.T.Integral.sum( PointSetDist.T.Integral.sum(
toShape(t), toPointSetDist(t),
); );
}; };
// TODO: Fix this below, obviously. Adjust for limits // TODO: Fix this below, obviously. Adjust for limits
let integralXtoY = (f, t: t) => { let integralXtoY = (f, t: t) => {
Shape.T.Integral.xToY( PointSetDist.T.Integral.xToY(
f, f,
toShape(t), toPointSetDist(t),
) )
|> domainIncludedProbabilityMassAdjustment(t); |> domainIncludedProbabilityMassAdjustment(t);
}; };
// TODO: This part is broken when there is a limit, if this is supposed to be taken into account. // TODO: This part is broken when there is a limit, if this is supposed to be taken into account.
let integralYtoX = (f, t: t) => { let integralYtoX = (f, t: t) => {
Shape.T.Integral.yToX(f, toShape(t)); PointSetDist.T.Integral.yToX(f, toPointSetDist(t));
}; };
let mean = (t: t) => { let mean = (t: t) => {
Shape.T.mean(t.shape); PointSetDist.T.mean(t.pointSetDist);
}; };
let variance = (t: t) => Shape.T.variance(t.shape); let variance = (t: t) => PointSetDist.T.variance(t.pointSetDist);
}); });

View File

@ -5,20 +5,20 @@ module type dist = {
let maxX: t => float let maxX: t => float
let mapY: ( let mapY: (
~integralSumCacheFn: float => option<float>=?, ~integralSumCacheFn: float => option<float>=?,
~integralCacheFn: DistTypes.continuousShape => option<DistTypes.continuousShape>=?, ~integralCacheFn: PointSetTypes.continuousShape => option<PointSetTypes.continuousShape>=?,
~fn: float => float, ~fn: float => float,
t, t,
) => t ) => t
let xToY: (float, t) => DistTypes.mixedPoint let xToY: (float, t) => PointSetTypes.mixedPoint
let toShape: t => DistTypes.shape let toPointSetDist: t => PointSetTypes.pointSetDist
let toContinuous: t => option<DistTypes.continuousShape> let toContinuous: t => option<PointSetTypes.continuousShape>
let toDiscrete: t => option<DistTypes.discreteShape> let toDiscrete: t => option<PointSetTypes.discreteShape>
let normalize: t => t let normalize: t => t
let toDiscreteProbabilityMassFraction: t => float let toDiscreteProbabilityMassFraction: t => float
let downsample: (int, t) => t let downsample: (int, t) => t
let truncate: (option<float>, option<float>, t) => t let truncate: (option<float>, option<float>, t) => t
let updateIntegralCache: (option<DistTypes.continuousShape>, t) => t let updateIntegralCache: (option<PointSetTypes.continuousShape>, t) => t
let integral: t => integral let integral: t => integral
let integralEndY: t => float let integralEndY: t => float
@ -39,7 +39,7 @@ module Dist = (T: dist) => {
let mapY = T.mapY let mapY = T.mapY
let xToY = T.xToY let xToY = T.xToY
let downsample = T.downsample let downsample = T.downsample
let toShape = T.toShape let toPointSetDist = T.toPointSetDist
let toDiscreteProbabilityMassFraction = T.toDiscreteProbabilityMassFraction let toDiscreteProbabilityMassFraction = T.toDiscreteProbabilityMassFraction
let toContinuous = T.toContinuous let toContinuous = T.toContinuous
let toDiscrete = T.toDiscrete let toDiscrete = T.toDiscrete
@ -74,11 +74,11 @@ module Common = {
let combineIntegrals = ( let combineIntegrals = (
combineFn: ( combineFn: (
DistTypes.continuousShape, PointSetTypes.continuousShape,
DistTypes.continuousShape, PointSetTypes.continuousShape,
) => option<DistTypes.continuousShape>, ) => option<PointSetTypes.continuousShape>,
t1IntegralCache: option<DistTypes.continuousShape>, t1IntegralCache: option<PointSetTypes.continuousShape>,
t2IntegralCache: option<DistTypes.continuousShape>, t2IntegralCache: option<PointSetTypes.continuousShape>,
) => ) =>
switch (t1IntegralCache, t2IntegralCache) { switch (t1IntegralCache, t2IntegralCache) {
| (None, _) | (None, _)

View File

@ -1,6 +1,6 @@
open Distributions open Distributions
type t = DistTypes.mixedShape type t = PointSetTypes.mixedShape
let make = (~integralSumCache=None, ~integralCache=None, ~continuous, ~discrete): t => { let make = (~integralSumCache=None, ~integralCache=None, ~continuous, ~discrete): t => {
continuous: continuous, continuous: continuous,
discrete: discrete, discrete: discrete,
@ -37,13 +37,13 @@ let updateIntegralCache = (integralCache, t: t): t => {
} }
module T = Dist({ module T = Dist({
type t = DistTypes.mixedShape type t = PointSetTypes.mixedShape
type integral = DistTypes.continuousShape type integral = PointSetTypes.continuousShape
let minX = ({continuous, discrete}: t) => let minX = ({continuous, discrete}: t) =>
min(Continuous.T.minX(continuous), Discrete.T.minX(discrete)) min(Continuous.T.minX(continuous), Discrete.T.minX(discrete))
let maxX = ({continuous, discrete}: t) => let maxX = ({continuous, discrete}: t) =>
max(Continuous.T.maxX(continuous), Discrete.T.maxX(discrete)) max(Continuous.T.maxX(continuous), Discrete.T.maxX(discrete))
let toShape = (t: t): DistTypes.shape => Mixed(t) let toPointSetDist = (t: t): PointSetTypes.pointSetDist => Mixed(t)
let updateIntegralCache = updateIntegralCache let updateIntegralCache = updateIntegralCache
@ -103,7 +103,7 @@ module T = Dist({
let {continuous, discrete}: t = normalize(t) let {continuous, discrete}: t = normalize(t)
let c = Continuous.T.xToY(x, continuous) let c = Continuous.T.xToY(x, continuous)
let d = Discrete.T.xToY(x, discrete) let d = Discrete.T.xToY(x, discrete)
DistTypes.MixedPoint.add(c, d) // "add" here just combines the two values into a single MixedPoint. PointSetTypes.MixedPoint.add(c, d) // "add" here just combines the two values into a single MixedPoint.
} }
let toDiscreteProbabilityMassFraction = ({discrete, continuous}: t) => { let toDiscreteProbabilityMassFraction = ({discrete, continuous}: t) => {
@ -170,13 +170,13 @@ module T = Dist({
~fn, ~fn,
t: t, t: t,
): t => { ): t => {
let yMappedDiscrete: DistTypes.discreteShape = let yMappedDiscrete: PointSetTypes.discreteShape =
t.discrete t.discrete
|> Discrete.T.mapY(~fn) |> Discrete.T.mapY(~fn)
|> Discrete.updateIntegralSumCache(E.O.bind(t.discrete.integralSumCache, integralSumCacheFn)) |> Discrete.updateIntegralSumCache(E.O.bind(t.discrete.integralSumCache, integralSumCacheFn))
|> Discrete.updateIntegralCache(E.O.bind(t.discrete.integralCache, integralCacheFn)) |> Discrete.updateIntegralCache(E.O.bind(t.discrete.integralCache, integralCacheFn))
let yMappedContinuous: DistTypes.continuousShape = let yMappedContinuous: PointSetTypes.continuousShape =
t.continuous t.continuous
|> Continuous.T.mapY(~fn) |> Continuous.T.mapY(~fn)
|> Continuous.updateIntegralSumCache( |> Continuous.updateIntegralSumCache(
@ -227,7 +227,7 @@ module T = Dist({
} }
}) })
let combineAlgebraically = (op: ExpressionTypes.algebraicOperation, t1: t, t2: t): t => { let combineAlgebraically = (op: ASTTypes.algebraicOperation, t1: t, t2: t): t => {
// Discrete convolution can cause a huge increase in the number of samples, // Discrete convolution can cause a huge increase in the number of samples,
// so we'll first downsample. // so we'll first downsample.

View File

@ -9,9 +9,9 @@ type assumptions = {
} }
let buildSimple = ( let buildSimple = (
~continuous: option<DistTypes.continuousShape>, ~continuous: option<PointSetTypes.continuousShape>,
~discrete: option<DistTypes.discreteShape>, ~discrete: option<PointSetTypes.discreteShape>,
): option<DistTypes.shape> => { ): option<PointSetTypes.pointSetDist> => {
let continuous = let continuous =
continuous |> E.O.default(Continuous.make(~integralSumCache=Some(0.0), {xs: [], ys: []})) continuous |> E.O.default(Continuous.make(~integralSumCache=Some(0.0), {xs: [], ys: []}))
let discrete = let discrete =

View File

@ -1,6 +1,6 @@
open Distributions open Distributions
type t = DistTypes.shape type t = PointSetTypes.pointSetDist
let mapToAll = ((fn1, fn2, fn3), t: t) => let mapToAll = ((fn1, fn2, fn3), t: t) =>
switch t { switch t {
| Mixed(m) => fn1(m) | Mixed(m) => fn1(m)
@ -33,49 +33,49 @@ let toMixed = mapToAll((
), ),
)) ))
let combineAlgebraically = (op: ExpressionTypes.algebraicOperation, t1: t, t2: t): t => let combineAlgebraically = (op: ASTTypes.algebraicOperation, t1: t, t2: t): t =>
switch (t1, t2) { switch (t1, t2) {
| (Continuous(m1), Continuous(m2)) => | (Continuous(m1), Continuous(m2)) =>
Continuous.combineAlgebraically(op, m1, m2) |> Continuous.T.toShape Continuous.combineAlgebraically(op, m1, m2) |> Continuous.T.toPointSetDist
| (Continuous(m1), Discrete(m2)) | (Continuous(m1), Discrete(m2))
| (Discrete(m2), Continuous(m1)) => | (Discrete(m2), Continuous(m1)) =>
Continuous.combineAlgebraicallyWithDiscrete(op, m1, m2) |> Continuous.T.toShape Continuous.combineAlgebraicallyWithDiscrete(op, m1, m2) |> Continuous.T.toPointSetDist
| (Discrete(m1), Discrete(m2)) => Discrete.combineAlgebraically(op, m1, m2) |> Discrete.T.toShape | (Discrete(m1), Discrete(m2)) => Discrete.combineAlgebraically(op, m1, m2) |> Discrete.T.toPointSetDist
| (m1, m2) => Mixed.combineAlgebraically(op, toMixed(m1), toMixed(m2)) |> Mixed.T.toShape | (m1, m2) => Mixed.combineAlgebraically(op, toMixed(m1), toMixed(m2)) |> Mixed.T.toPointSetDist
} }
let combinePointwise = ( let combinePointwise = (
~integralSumCachesFn: (float, float) => option<float>=(_, _) => None, ~integralSumCachesFn: (float, float) => option<float>=(_, _) => None,
~integralCachesFn: ( ~integralCachesFn: (
DistTypes.continuousShape, PointSetTypes.continuousShape,
DistTypes.continuousShape, PointSetTypes.continuousShape,
) => option<DistTypes.continuousShape>=(_, _) => None, ) => option<PointSetTypes.continuousShape>=(_, _) => None,
fn, fn,
t1: t, t1: t,
t2: t, t2: t,
) => ) =>
switch (t1, t2) { switch (t1, t2) {
| (Continuous(m1), Continuous(m2)) => | (Continuous(m1), Continuous(m2)) =>
DistTypes.Continuous( PointSetTypes.Continuous(
Continuous.combinePointwise(~integralSumCachesFn, ~integralCachesFn, fn, m1, m2), Continuous.combinePointwise(~integralSumCachesFn, ~integralCachesFn, fn, m1, m2),
) )
| (Discrete(m1), Discrete(m2)) => | (Discrete(m1), Discrete(m2)) =>
DistTypes.Discrete( PointSetTypes.Discrete(
Discrete.combinePointwise(~integralSumCachesFn, ~integralCachesFn, fn, m1, m2), Discrete.combinePointwise(~integralSumCachesFn, ~integralCachesFn, fn, m1, m2),
) )
| (m1, m2) => | (m1, m2) =>
DistTypes.Mixed( PointSetTypes.Mixed(
Mixed.combinePointwise(~integralSumCachesFn, ~integralCachesFn, fn, toMixed(m1), toMixed(m2)), Mixed.combinePointwise(~integralSumCachesFn, ~integralCachesFn, fn, toMixed(m1), toMixed(m2)),
) )
} }
module T = Dist({ module T = Dist({
type t = DistTypes.shape type t = PointSetTypes.pointSetDist
type integral = DistTypes.continuousShape type integral = PointSetTypes.continuousShape
let xToY = (f: float) => mapToAll((Mixed.T.xToY(f), Discrete.T.xToY(f), Continuous.T.xToY(f))) let xToY = (f: float) => mapToAll((Mixed.T.xToY(f), Discrete.T.xToY(f), Continuous.T.xToY(f)))
let toShape = (t: t) => t let toPointSetDist = (t: t) => t
let toContinuous = t => None let toContinuous = t => None
let toDiscrete = t => None let toDiscrete = t => None
@ -163,7 +163,7 @@ module T = Dist({
}) })
let pdf = (f: float, t: t) => { let pdf = (f: float, t: t) => {
let mixedPoint: DistTypes.mixedPoint = T.xToY(f, t) let mixedPoint: PointSetTypes.mixedPoint = T.xToY(f, t)
mixedPoint.continuous +. mixedPoint.discrete mixedPoint.continuous +. mixedPoint.discrete
} }
@ -197,7 +197,7 @@ let sampleNRendered = (n, dist) => {
doN(n, () => sample(distWithUpdatedIntegralCache)) doN(n, () => sample(distWithUpdatedIntegralCache))
} }
let operate = (distToFloatOp: ExpressionTypes.distToFloatOperation, s): float => let operate = (distToFloatOp: ASTTypes.distToFloatOperation, s): float =>
switch distToFloatOp { switch distToFloatOp {
| #Pdf(f) => pdf(f, s) | #Pdf(f) => pdf(f, s)
| #Cdf(f) => pdf(f, s) | #Cdf(f) => pdf(f, s)

View File

@ -50,15 +50,15 @@ type mixedShape = {
integralCache: option<continuousShape>, integralCache: option<continuousShape>,
} }
type shapeMonad<'a, 'b, 'c> = type pointSetDistMonad<'a, 'b, 'c> =
| Mixed('a) | Mixed('a)
| Discrete('b) | Discrete('b)
| Continuous('c) | Continuous('c)
type shape = shapeMonad<mixedShape, discreteShape, continuousShape> type pointSetDist = pointSetDistMonad<mixedShape, discreteShape, continuousShape>
module ShapeMonad = { module ShapeMonad = {
let fmap = (t: shapeMonad<'a, 'b, 'c>, (fn1, fn2, fn3)): shapeMonad<'d, 'e, 'f> => let fmap = (t: pointSetDistMonad<'a, 'b, 'c>, (fn1, fn2, fn3)): pointSetDistMonad<'d, 'e, 'f> =>
switch t { switch t {
| Mixed(m) => Mixed(fn1(m)) | Mixed(m) => Mixed(fn1(m))
| Discrete(m) => Discrete(fn2(m)) | Discrete(m) => Discrete(fn2(m))
@ -68,13 +68,13 @@ module ShapeMonad = {
type generationSource = type generationSource =
| SquiggleString(string) | SquiggleString(string)
| Shape(shape) | Shape(pointSetDist)
type distributionUnit = type distributionUnit =
| UnspecifiedDistribution | UnspecifiedDistribution
type distPlus = { type distPlus = {
shape: shape, pointSetDist: pointSetDist,
domain: domain, domain: domain,
integralCache: continuousShape, integralCache: continuousShape,
unit: distributionUnit, unit: distributionUnit,

View File

@ -1,4 +1,4 @@
open DistTypes open PointSetTypes
let interpolate = (xMin: float, xMax: float, yMin: float, yMax: float, xIntended: float): float => { let interpolate = (xMin: float, xMax: float, yMin: float, yMax: float, xIntended: float): float => {
let minProportion = (xMax -. xIntended) /. (xMax -. xMin) let minProportion = (xMax -. xIntended) /. (xMax -. xMin)
@ -126,8 +126,8 @@ module XtoY = {
/* Returns a between-points-interpolating function that can be used with PointwiseCombination.combine. /* Returns a between-points-interpolating function that can be used with PointwiseCombination.combine.
Interpolation can either be stepwise (using the value on the left) or linear. Extrapolation can be `UseZero or `UseOutermostPoints. */ Interpolation can either be stepwise (using the value on the left) or linear. Extrapolation can be `UseZero or `UseOutermostPoints. */
let continuousInterpolator = ( let continuousInterpolator = (
interpolation: DistTypes.interpolationStrategy, interpolation: PointSetTypes.interpolationStrategy,
extrapolation: DistTypes.extrapolationStrategy, extrapolation: PointSetTypes.extrapolationStrategy,
): interpolator => ): interpolator =>
switch (interpolation, extrapolation) { switch (interpolation, extrapolation) {
| (#Linear, #UseZero) => | (#Linear, #UseZero) =>
@ -395,7 +395,7 @@ module Analysis = {
let integrateContinuousShape = ( let integrateContinuousShape = (
~indefiniteIntegralStepwise=(p, h1) => h1 *. p, ~indefiniteIntegralStepwise=(p, h1) => h1 *. p,
~indefiniteIntegralLinear=(p, a, b) => a *. p +. b *. p ** 2.0 /. 2.0, ~indefiniteIntegralLinear=(p, a, b) => a *. p +. b *. p ** 2.0 /. 2.0,
t: DistTypes.continuousShape, t: PointSetTypes.continuousShape,
): float => { ): float => {
let xs = t.xyShape.xs let xs = t.xyShape.xs
let ys = t.xyShape.ys let ys = t.xyShape.ys
@ -424,7 +424,7 @@ module Analysis = {
}) })
} }
let getMeanOfSquaresContinuousShape = (t: DistTypes.continuousShape) => { let getMeanOfSquaresContinuousShape = (t: PointSetTypes.continuousShape) => {
let indefiniteIntegralLinear = (p, a, b) => a *. p ** 3.0 /. 3.0 +. b *. p ** 4.0 /. 4.0 let indefiniteIntegralLinear = (p, a, b) => a *. p ** 3.0 /. 3.0 +. b *. p ** 4.0 /. 4.0
let indefiniteIntegralStepwise = (p, h1) => h1 *. p ** 3.0 /. 3.0 let indefiniteIntegralStepwise = (p, h1) => h1 *. p ** 3.0 /. 3.0
integrateContinuousShape(~indefiniteIntegralStepwise, ~indefiniteIntegralLinear, t) integrateContinuousShape(~indefiniteIntegralStepwise, ~indefiniteIntegralLinear, t)

View File

@ -15,7 +15,6 @@ const samplesToContinuousPdf = (
return {xs: pdf.map(r => r.x), ys: pdf.map(r => r.y)}; return {xs: pdf.map(r => r.x), ys: pdf.map(r => r.y)};
}; };
module.exports = { module.exports = {
samplesToContinuousPdf, samplesToContinuousPdf,
}; };

View File

@ -11,7 +11,7 @@ module Internals = {
type outputs = { type outputs = {
continuousParseParams: option<samplingStats>, continuousParseParams: option<samplingStats>,
shape: option<DistTypes.shape>, pointSetDist: option<PointSetTypes.pointSetDist>,
} }
} }
@ -22,7 +22,7 @@ module Internals = {
ys: array<float>, ys: array<float>,
} }
let jsToDist = (d: distJs): DistTypes.xyShape => { let jsToDist = (d: distJs): PointSetTypes.xyShape => {
xs: xsGet(d), xs: xsGet(d),
ys: ysGet(d), ys: ysGet(d),
} }
@ -78,15 +78,15 @@ module Internals = {
} }
} }
let toShape = ( let toPointSetDist = (
~samples: Internals.T.t, ~samples: Internals.T.t,
~samplingInputs: ExpressionTypes.ExpressionTree.samplingInputs, ~samplingInputs: ASTTypes.AST.samplingInputs,
(), (),
) => { ) => {
Array.fast_sort(compare, samples) Array.fast_sort(compare, samples)
let (continuousPart, discretePart) = E.A.Sorted.Floats.split(samples) let (continuousPart, discretePart) = E.A.Sorted.Floats.split(samples)
let length = samples |> E.A.length |> float_of_int let length = samples |> E.A.length |> float_of_int
let discrete: DistTypes.discreteShape = let discrete: PointSetTypes.discreteShape =
discretePart discretePart
|> E.FloatFloatMap.fmap(r => r /. length) |> E.FloatFloatMap.fmap(r => r /. length)
|> E.FloatFloatMap.toArray |> E.FloatFloatMap.toArray
@ -127,17 +127,15 @@ let toShape = (
} }
: None : None
let shape = MixedShapeBuilder.buildSimple( let pointSetDist = MixedShapeBuilder.buildSimple(
~continuous=pdf |> E.O.fmap(fst), ~continuous=pdf |> E.O.fmap(fst),
~discrete=Some(discrete), ~discrete=Some(discrete),
) )
let samplesParse: Internals.Types.outputs = { let samplesParse: Internals.Types.outputs = {
continuousParseParams: pdf |> E.O.fmap(snd), continuousParseParams: pdf |> E.O.fmap(snd),
shape: shape, pointSetDist: pointSetDist,
} }
samplesParse samplesParse
} }
let fromSamples = (~samplingInputs, samples) => toShape(~samples, ~samplingInputs, ())

View File

@ -1,4 +1,4 @@
open SymbolicTypes open SymbolicDistTypes
module Normal = { module Normal = {
type t = normal type t = normal
@ -272,7 +272,7 @@ module T = {
| #Float(n) => Float.mean(n) | #Float(n) => Float.mean(n)
} }
let operate = (distToFloatOp: ExpressionTypes.distToFloatOperation, s) => let operate = (distToFloatOp: ASTTypes.distToFloatOperation, s) =>
switch distToFloatOp { switch distToFloatOp {
| #Cdf(f) => Ok(cdf(f, s)) | #Cdf(f) => Ok(cdf(f, s))
| #Pdf(f) => Ok(pdf(f, s)) | #Pdf(f) => Ok(pdf(f, s))
@ -302,7 +302,7 @@ module T = {
let tryAnalyticalSimplification = ( let tryAnalyticalSimplification = (
d1: symbolicDist, d1: symbolicDist,
d2: symbolicDist, d2: symbolicDist,
op: ExpressionTypes.algebraicOperation, op: ASTTypes.algebraicOperation,
): analyticalSimplificationResult => ): analyticalSimplificationResult =>
switch (d1, d2) { switch (d1, d2) {
| (#Float(v1), #Float(v2)) => | (#Float(v1), #Float(v2)) =>
@ -317,7 +317,7 @@ module T = {
| _ => #NoSolution | _ => #NoSolution
} }
let toShape = (sampleCount, d: symbolicDist): DistTypes.shape => let toPointSetDist = (sampleCount, d: symbolicDist): PointSetTypes.pointSetDist =>
switch d { switch d {
| #Float(v) => Discrete(Discrete.make(~integralSumCache=Some(1.0), {xs: [v], ys: [1.0]})) | #Float(v) => Discrete(Discrete.make(~integralSumCache=Some(1.0), {xs: [v], ys: [1.0]}))
| _ => | _ =>