diff --git a/src/components/DistBuilder.re b/src/components/DistBuilder.re index e1213eec..28510795 100644 --- a/src/components/DistBuilder.re +++ b/src/components/DistBuilder.re @@ -197,7 +197,7 @@ module DemoDist = { ) |> E.A.R.firstErrorOrOpen; switch (results) { - | Ok(dists) => <> + | Ok(dists) => | Error(r) => r |> R.ste }; | Error(r) => r |> R.ste @@ -211,6 +211,18 @@ module DemoDist = { }; }; +// guesstimatorString: " +// us_economy_2018 = (10.5 to 10.6)T +// growth_rate = 1.08 to 1.2 +// us_economy(t) = us_economy_2018 * (growth_rate^t) + +// us_population_2019 = 320M to 330M +// us_population_growth_rate = 1.01 to 1.02 +// us_population(t) = us_population_2019 * (us_population_growth_rate^t) + +// gdp_per_person(t) = us_economy(t)/us_population(t) +// gdp_per_person +// ", [@react.component] let make = () => { let (reloader, setReloader) = React.useState(() => 1); @@ -221,18 +233,7 @@ let make = () => { ~onSubmit=({state}) => {None}, ~initialState={ //guesstimatorString: "mm(normal(-10, 2), uniform(18, 25), lognormal({mean: 10, stdev: 8}), triangular(31,40,50))", - guesstimatorString: " - us_economy_2018 = (10.5 to 10.6)T -growth_rate = 1.08 to 1.2 -us_economy(t) = us_economy_2018 * (growth_rate^t) - -us_population_2019 = 320M to 330M -us_population_growth_rate = 1.01 to 1.02 -us_population(t) = us_population_2019 * (us_population_growth_rate^t) - -gdp_per_person(t) = us_economy(t)/us_population(t) -gdp_per_person -", + guesstimatorString: "mm(3,4)", domainType: "Complete", xPoint: "50.0", xPoint2: "60.0", diff --git a/src/distPlus/expressionTree/ExpressionTreeEvaluator.re b/src/distPlus/expressionTree/ExpressionTreeEvaluator.re index f75254ff..4a650870 100644 --- a/src/distPlus/expressionTree/ExpressionTreeEvaluator.re +++ b/src/distPlus/expressionTree/ExpressionTreeEvaluator.re @@ -254,6 +254,7 @@ let rec toLeaf = node: t, ) : result(t, string) => { + Js.log2("node",node); switch (node) { // Leaf nodes just stay leaf nodes | `SymbolicDist(_) diff --git a/src/distPlus/expressionTree/Fns.re b/src/distPlus/expressionTree/Fns.re index af7a28e4..cbaf375b 100644 --- a/src/distPlus/expressionTree/Fns.re +++ b/src/distPlus/expressionTree/Fns.re @@ -1,7 +1,6 @@ open TypeSystem; let wrongInputsError = r => { - Js.log2("Wrong inputs", r); Error("Wrong inputs"); }; @@ -18,8 +17,8 @@ let to_: (float, float) => result(node, string) = let makeSymbolicFromTwoFloats = (name, fn) => Function.make( ~name, - ~output=`SamplingDistribution, - ~inputs=[|`Float, `Float|], + ~outputType=`SamplingDistribution, + ~inputTypes=[|`Float, `Float|], ~run= fun | [|`Float(a), `Float(b)|] => Ok(`SymbolicDist(fn(a, b))) @@ -29,8 +28,8 @@ let makeSymbolicFromTwoFloats = (name, fn) => let makeSymbolicFromOneFloat = (name, fn) => Function.make( ~name, - ~output=`SamplingDistribution, - ~inputs=[|`Float|], + ~outputType=`SamplingDistribution, + ~inputTypes=[|`Float|], ~run= fun | [|`Float(a)|] => Ok(`SymbolicDist(fn(a))) @@ -40,8 +39,8 @@ let makeSymbolicFromOneFloat = (name, fn) => let makeDistFloat = (name, fn) => Function.make( ~name, - ~output=`SamplingDistribution, - ~inputs=[|`SamplingDistribution, `Float|], + ~outputType=`SamplingDistribution, + ~inputTypes=[|`SamplingDistribution, `Float|], ~run= fun | [|`SamplingDist(a), `Float(b)|] => fn(a, b) @@ -51,19 +50,19 @@ let makeDistFloat = (name, fn) => let makeRenderedDistFloat = (name, fn) => Function.make( ~name, - ~output=`RenderedDistribution, - ~inputs=[|`RenderedDistribution, `Float|], + ~outputType=`RenderedDistribution, + ~inputTypes=[|`RenderedDistribution, `Float|], ~run= fun | [|`RenderedDist(a), `Float(b)|] => fn(a, b) - | e => wrongInputsError(e), + | e => wrongInputsError(e) ); let makeDist = (name, fn) => Function.make( ~name, - ~output=`SamplingDistribution, - ~inputs=[|`SamplingDistribution|], + ~outputType=`SamplingDistribution, + ~inputTypes=[|`SamplingDistribution|], ~run= fun | [|`SamplingDist(a)|] => fn(a) @@ -115,8 +114,8 @@ let functions = [| makeSymbolicFromOneFloat("exponential", SymbolicDist.Exponential.make), Function.make( ~name="to", - ~output=`SamplingDistribution, - ~inputs=[|`Float, `Float|], + ~outputType=`SamplingDistribution, + ~inputTypes=[|`Float, `Float|], ~run= fun | [|`Float(a), `Float(b)|] => to_(a, b) @@ -124,8 +123,8 @@ let functions = [| ), Function.make( ~name="triangular", - ~output=`SamplingDistribution, - ~inputs=[|`Float, `Float, `Float|], + ~outputType=`SamplingDistribution, + ~inputTypes=[|`Float, `Float, `Float|], ~run= fun | [|`Float(a), `Float(b), `Float(c)|] => @@ -140,8 +139,8 @@ let functions = [| makeDist("sample", dist => floatFromDist(`Sample, dist)), Function.make( ~name="render", - ~output=`RenderedDistribution, - ~inputs=[|`RenderedDistribution|], + ~outputType=`RenderedDistribution, + ~inputTypes=[|`RenderedDistribution|], ~run= fun | [|`RenderedDist(c)|] => Ok(`RenderedDist(c)) @@ -149,8 +148,8 @@ let functions = [| ), Function.make( ~name="normalize", - ~output=`SamplingDistribution, - ~inputs=[|`SamplingDistribution|], + ~outputType=`SamplingDistribution, + ~inputTypes=[|`SamplingDistribution|], ~run= fun | [|`SamplingDist(`SymbolicDist(c))|] => Ok(`SymbolicDist(c)) diff --git a/src/distPlus/expressionTree/Functions.re b/src/distPlus/expressionTree/Functions.re index eb127918..a99581ce 100644 --- a/src/distPlus/expressionTree/Functions.re +++ b/src/distPlus/expressionTree/Functions.re @@ -38,7 +38,13 @@ let fnn = }); Ok(`MultiModal(withWeights)); | dists when E.L.length(dists) > 0 => - Ok(`MultiModal(dists |> E.L.toArray |> E.A.fmap(r => (r, 1.0)))) + Ok( + `MultiModal( + dists + |> E.L.toArray + |> E.A.fmap(r => (r, 1.0)), + ), + ) | _ => Error("Needs at least one distribution") } | _ => Error("Function " ++ name ++ " not found") diff --git a/src/distPlus/expressionTree/TypeSystem.re b/src/distPlus/expressionTree/TypeSystem.re index d13e62d6..0ecc070e 100644 --- a/src/distPlus/expressionTree/TypeSystem.re +++ b/src/distPlus/expressionTree/TypeSystem.re @@ -20,24 +20,25 @@ type tx = [ | `Array(array(tx)) | `Named(array((string, tx))) ]; + type fn = { name: string, - inputs: array(t), - output: t, + inputTypes: array(t), + outputType: t, run: array(tx) => result(node, string), }; module Function = { - let make = (~name, ~inputs, ~output, ~run): fn => { + let make = (~name, ~inputTypes, ~outputType, ~run): fn => { name, - inputs, - output, + inputTypes, + outputType, run, }; }; type fns = array(fn); -type inputs = array(node); +type inputTypes = array(node); let rec fromNodeDirect = (node: node): result(tx, string) => switch (ExpressionTypes.ExpressionTree.toFloatIfNeeded(node)) { @@ -64,10 +65,7 @@ let compareInput = (evaluationParams, t: t, node) => | `Float => switch (getFloat(node)) { | Some(a) => Ok(`Float(a)) - | _ => - Error( - "Type Error: Expected float." - ) + | _ => Error("Type Error: Expected float.") } | `SamplingDistribution => PTypes.SamplingDistribution.renderIfIsNotSamplingDistribution( @@ -78,50 +76,57 @@ let compareInput = (evaluationParams, t: t, node) => | `RenderedDistribution => ExpressionTypes.ExpressionTree.Render.render(evaluationParams, node) |> E.R.bind(_, fromNodeDirect) - | _ => Error("Bad input, sorry.") + | _ => { + Js.log4("Type error: Expected ", t, ", got ", node); + Error("Bad input, sorry.")} }; let sanatizeInputs = ( evaluationParams: ExpressionTypes.ExpressionTree.evaluationParams, - inputs: inputs, + inputTypes: inputTypes, t: fn, ) => { - E.A.length(t.inputs) == E.A.length(inputs) - ? Belt.Array.zip(t.inputs, inputs) + E.A.length(t.inputTypes) == E.A.length(inputTypes) + ? Belt.Array.zip(t.inputTypes, inputTypes) |> E.A.fmap(((def, input)) => compareInput(evaluationParams, def, input) ) + |> (r => {Js.log2("Inputs", r); r}) |> E.A.R.firstErrorOrOpen : Error( "Wrong number of inputs. Expected" - ++ (E.A.length(t.inputs) |> E.I.toString) + ++ (E.A.length(t.inputTypes) |> E.I.toString) ++ ". Got:" - ++ (E.A.length(inputs) |> E.I.toString), + ++ (E.A.length(inputTypes) |> E.I.toString), ); }; let run = ( evaluationParams: ExpressionTypes.ExpressionTree.evaluationParams, - inputs: inputs, + inputTypes: inputTypes, t: fn, - ) =>{ - ( - switch (sanatizeInputs(evaluationParams, inputs, t)) { - | Ok(inputs) => t.run(inputs) - | Error(r) => Error(r) - } - ) + ) => { + let _sanitizedInputs = sanatizeInputs(evaluationParams, inputTypes, t); + _sanitizedInputs |> E.R.bind(_,t.run) |> ( fun | Ok(i) => Ok(i) - | Error(r) => {Js.log4("Error", inputs, t, sanatizeInputs(evaluationParams, inputs, t), ); Error("Function " ++ t.name ++ " error: " ++ r)} + | Error(r) => { + Js.log4( + "Error", + inputTypes, + t, + _sanitizedInputs + ); + Error("Function " ++ t.name ++ " error: " ++ r); + } ); - } +}; let getFn = (fns: fns, n: string) => fns |> Belt.Array.getBy(_, ({name}) => name == n); -let getAndRun = (fns: fns, n: string, evaluationParams, inputs) => - getFn(fns, n) |> E.O.fmap(run(evaluationParams, inputs)); +let getAndRun = (fns: fns, n: string, evaluationParams, inputTypes) => + getFn(fns, n) |> E.O.fmap(run(evaluationParams, inputTypes));