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;
switch (results) {
| Ok(dists) => <> <PercentilesChart dists /> </>
| Ok(dists) => <PercentilesChart 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",

View File

@ -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(_)

View File

@ -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))

View File

@ -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")

View File

@ -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));