Minor changes to TypeSystem
This commit is contained in:
parent
7566c59fef
commit
cf36594b4a
|
@ -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",
|
||||||
|
|
|
@ -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(_)
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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));
|
||||||
|
|
Loading…
Reference in New Issue
Block a user