Minor changes to TypeSystem

This commit is contained in:
Ozzie Gooen 2020-11-06 10:43:06 -08:00
parent 7566c59fef
commit cf36594b4a
5 changed files with 74 additions and 62 deletions

View File

@ -197,7 +197,7 @@ module DemoDist = {
) )
|> E.A.R.firstErrorOrOpen; |> E.A.R.firstErrorOrOpen;
switch (results) { switch (results) {
| Ok(dists) => <> <PercentilesChart dists /> </> | Ok(dists) => <PercentilesChart dists />
| Error(r) => r |> R.ste | Error(r) => r |> R.ste
}; };
| 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] [@react.component]
let make = () => { let make = () => {
let (reloader, setReloader) = React.useState(() => 1); let (reloader, setReloader) = React.useState(() => 1);
@ -221,18 +233,7 @@ let make = () => {
~onSubmit=({state}) => {None}, ~onSubmit=({state}) => {None},
~initialState={ ~initialState={
//guesstimatorString: "mm(normal(-10, 2), uniform(18, 25), lognormal({mean: 10, stdev: 8}), triangular(31,40,50))", //guesstimatorString: "mm(normal(-10, 2), uniform(18, 25), lognormal({mean: 10, stdev: 8}), triangular(31,40,50))",
guesstimatorString: " guesstimatorString: "mm(3,4)",
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
",
domainType: "Complete", domainType: "Complete",
xPoint: "50.0", xPoint: "50.0",
xPoint2: "60.0", xPoint2: "60.0",

View File

@ -254,6 +254,7 @@ let rec toLeaf =
node: t, node: t,
) )
: result(t, string) => { : result(t, string) => {
Js.log2("node",node);
switch (node) { switch (node) {
// Leaf nodes just stay leaf nodes // Leaf nodes just stay leaf nodes
| `SymbolicDist(_) | `SymbolicDist(_)

View File

@ -1,7 +1,6 @@
open TypeSystem; open TypeSystem;
let wrongInputsError = r => { let wrongInputsError = r => {
Js.log2("Wrong inputs", r);
Error("Wrong inputs"); Error("Wrong inputs");
}; };
@ -18,8 +17,8 @@ let to_: (float, float) => result(node, string) =
let makeSymbolicFromTwoFloats = (name, fn) => let makeSymbolicFromTwoFloats = (name, fn) =>
Function.make( Function.make(
~name, ~name,
~output=`SamplingDistribution, ~outputType=`SamplingDistribution,
~inputs=[|`Float, `Float|], ~inputTypes=[|`Float, `Float|],
~run= ~run=
fun fun
| [|`Float(a), `Float(b)|] => Ok(`SymbolicDist(fn(a, b))) | [|`Float(a), `Float(b)|] => Ok(`SymbolicDist(fn(a, b)))
@ -29,8 +28,8 @@ let makeSymbolicFromTwoFloats = (name, fn) =>
let makeSymbolicFromOneFloat = (name, fn) => let makeSymbolicFromOneFloat = (name, fn) =>
Function.make( Function.make(
~name, ~name,
~output=`SamplingDistribution, ~outputType=`SamplingDistribution,
~inputs=[|`Float|], ~inputTypes=[|`Float|],
~run= ~run=
fun fun
| [|`Float(a)|] => Ok(`SymbolicDist(fn(a))) | [|`Float(a)|] => Ok(`SymbolicDist(fn(a)))
@ -40,8 +39,8 @@ let makeSymbolicFromOneFloat = (name, fn) =>
let makeDistFloat = (name, fn) => let makeDistFloat = (name, fn) =>
Function.make( Function.make(
~name, ~name,
~output=`SamplingDistribution, ~outputType=`SamplingDistribution,
~inputs=[|`SamplingDistribution, `Float|], ~inputTypes=[|`SamplingDistribution, `Float|],
~run= ~run=
fun fun
| [|`SamplingDist(a), `Float(b)|] => fn(a, b) | [|`SamplingDist(a), `Float(b)|] => fn(a, b)
@ -51,19 +50,19 @@ let makeDistFloat = (name, fn) =>
let makeRenderedDistFloat = (name, fn) => let makeRenderedDistFloat = (name, fn) =>
Function.make( Function.make(
~name, ~name,
~output=`RenderedDistribution, ~outputType=`RenderedDistribution,
~inputs=[|`RenderedDistribution, `Float|], ~inputTypes=[|`RenderedDistribution, `Float|],
~run= ~run=
fun fun
| [|`RenderedDist(a), `Float(b)|] => fn(a, b) | [|`RenderedDist(a), `Float(b)|] => fn(a, b)
| e => wrongInputsError(e), | e => wrongInputsError(e)
); );
let makeDist = (name, fn) => let makeDist = (name, fn) =>
Function.make( Function.make(
~name, ~name,
~output=`SamplingDistribution, ~outputType=`SamplingDistribution,
~inputs=[|`SamplingDistribution|], ~inputTypes=[|`SamplingDistribution|],
~run= ~run=
fun fun
| [|`SamplingDist(a)|] => fn(a) | [|`SamplingDist(a)|] => fn(a)
@ -115,8 +114,8 @@ let functions = [|
makeSymbolicFromOneFloat("exponential", SymbolicDist.Exponential.make), makeSymbolicFromOneFloat("exponential", SymbolicDist.Exponential.make),
Function.make( Function.make(
~name="to", ~name="to",
~output=`SamplingDistribution, ~outputType=`SamplingDistribution,
~inputs=[|`Float, `Float|], ~inputTypes=[|`Float, `Float|],
~run= ~run=
fun fun
| [|`Float(a), `Float(b)|] => to_(a, b) | [|`Float(a), `Float(b)|] => to_(a, b)
@ -124,8 +123,8 @@ let functions = [|
), ),
Function.make( Function.make(
~name="triangular", ~name="triangular",
~output=`SamplingDistribution, ~outputType=`SamplingDistribution,
~inputs=[|`Float, `Float, `Float|], ~inputTypes=[|`Float, `Float, `Float|],
~run= ~run=
fun fun
| [|`Float(a), `Float(b), `Float(c)|] => | [|`Float(a), `Float(b), `Float(c)|] =>
@ -140,8 +139,8 @@ let functions = [|
makeDist("sample", dist => floatFromDist(`Sample, dist)), makeDist("sample", dist => floatFromDist(`Sample, dist)),
Function.make( Function.make(
~name="render", ~name="render",
~output=`RenderedDistribution, ~outputType=`RenderedDistribution,
~inputs=[|`RenderedDistribution|], ~inputTypes=[|`RenderedDistribution|],
~run= ~run=
fun fun
| [|`RenderedDist(c)|] => Ok(`RenderedDist(c)) | [|`RenderedDist(c)|] => Ok(`RenderedDist(c))
@ -149,8 +148,8 @@ let functions = [|
), ),
Function.make( Function.make(
~name="normalize", ~name="normalize",
~output=`SamplingDistribution, ~outputType=`SamplingDistribution,
~inputs=[|`SamplingDistribution|], ~inputTypes=[|`SamplingDistribution|],
~run= ~run=
fun fun
| [|`SamplingDist(`SymbolicDist(c))|] => Ok(`SymbolicDist(c)) | [|`SamplingDist(`SymbolicDist(c))|] => Ok(`SymbolicDist(c))

View File

@ -38,7 +38,13 @@ let fnn =
}); });
Ok(`MultiModal(withWeights)); Ok(`MultiModal(withWeights));
| dists when E.L.length(dists) > 0 => | 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("Needs at least one distribution")
} }
| _ => Error("Function " ++ name ++ " not found") | _ => Error("Function " ++ name ++ " not found")

View File

@ -20,24 +20,25 @@ type tx = [
| `Array(array(tx)) | `Array(array(tx))
| `Named(array((string, tx))) | `Named(array((string, tx)))
]; ];
type fn = { type fn = {
name: string, name: string,
inputs: array(t), inputTypes: array(t),
output: t, outputType: t,
run: array(tx) => result(node, string), run: array(tx) => result(node, string),
}; };
module Function = { module Function = {
let make = (~name, ~inputs, ~output, ~run): fn => { let make = (~name, ~inputTypes, ~outputType, ~run): fn => {
name, name,
inputs, inputTypes,
output, outputType,
run, run,
}; };
}; };
type fns = array(fn); type fns = array(fn);
type inputs = array(node); type inputTypes = array(node);
let rec fromNodeDirect = (node: node): result(tx, string) => let rec fromNodeDirect = (node: node): result(tx, string) =>
switch (ExpressionTypes.ExpressionTree.toFloatIfNeeded(node)) { switch (ExpressionTypes.ExpressionTree.toFloatIfNeeded(node)) {
@ -64,10 +65,7 @@ let compareInput = (evaluationParams, t: t, node) =>
| `Float => | `Float =>
switch (getFloat(node)) { switch (getFloat(node)) {
| Some(a) => Ok(`Float(a)) | Some(a) => Ok(`Float(a))
| _ => | _ => Error("Type Error: Expected float.")
Error(
"Type Error: Expected float."
)
} }
| `SamplingDistribution => | `SamplingDistribution =>
PTypes.SamplingDistribution.renderIfIsNotSamplingDistribution( PTypes.SamplingDistribution.renderIfIsNotSamplingDistribution(
@ -78,50 +76,57 @@ let compareInput = (evaluationParams, t: t, node) =>
| `RenderedDistribution => | `RenderedDistribution =>
ExpressionTypes.ExpressionTree.Render.render(evaluationParams, node) ExpressionTypes.ExpressionTree.Render.render(evaluationParams, node)
|> E.R.bind(_, fromNodeDirect) |> E.R.bind(_, fromNodeDirect)
| _ => Error("Bad input, sorry.") | _ => {
Js.log4("Type error: Expected ", t, ", got ", node);
Error("Bad input, sorry.")}
}; };
let sanatizeInputs = let sanatizeInputs =
( (
evaluationParams: ExpressionTypes.ExpressionTree.evaluationParams, evaluationParams: ExpressionTypes.ExpressionTree.evaluationParams,
inputs: inputs, inputTypes: inputTypes,
t: fn, t: fn,
) => { ) => {
E.A.length(t.inputs) == E.A.length(inputs) E.A.length(t.inputTypes) == E.A.length(inputTypes)
? Belt.Array.zip(t.inputs, inputs) ? Belt.Array.zip(t.inputTypes, inputTypes)
|> E.A.fmap(((def, input)) => |> E.A.fmap(((def, input)) =>
compareInput(evaluationParams, def, input) compareInput(evaluationParams, def, input)
) )
|> (r => {Js.log2("Inputs", r); r})
|> E.A.R.firstErrorOrOpen |> E.A.R.firstErrorOrOpen
: Error( : Error(
"Wrong number of inputs. Expected" "Wrong number of inputs. Expected"
++ (E.A.length(t.inputs) |> E.I.toString) ++ (E.A.length(t.inputTypes) |> E.I.toString)
++ ". Got:" ++ ". Got:"
++ (E.A.length(inputs) |> E.I.toString), ++ (E.A.length(inputTypes) |> E.I.toString),
); );
}; };
let run = let run =
( (
evaluationParams: ExpressionTypes.ExpressionTree.evaluationParams, evaluationParams: ExpressionTypes.ExpressionTree.evaluationParams,
inputs: inputs, inputTypes: inputTypes,
t: fn, t: fn,
) => { ) => {
( let _sanitizedInputs = sanatizeInputs(evaluationParams, inputTypes, t);
switch (sanatizeInputs(evaluationParams, inputs, t)) { _sanitizedInputs |> E.R.bind(_,t.run)
| Ok(inputs) => t.run(inputs)
| Error(r) => Error(r)
}
)
|> ( |> (
fun fun
| Ok(i) => Ok(i) | 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) => let getFn = (fns: fns, n: string) =>
fns |> Belt.Array.getBy(_, ({name}) => name == n); fns |> Belt.Array.getBy(_, ({name}) => name == n);
let getAndRun = (fns: fns, n: string, evaluationParams, inputs) => let getAndRun = (fns: fns, n: string, evaluationParams, inputTypes) =>
getFn(fns, n) |> E.O.fmap(run(evaluationParams, inputs)); getFn(fns, n) |> E.O.fmap(run(evaluationParams, inputTypes));