Gradually adding more functions to Functions.re

This commit is contained in:
Ozzie Gooen 2020-08-10 22:06:31 +01:00
parent 5d7ffdf2bc
commit f3841a961c
5 changed files with 92 additions and 66 deletions

View File

@ -31,7 +31,7 @@ export class CodeEditor extends React.Component {
}} }}
setOptions={{ setOptions={{
enableBasicAutocompletion: false, enableBasicAutocompletion: false,
enableLiveAutocompletion: false, enableLiveAutocompletion: true,
enableSnippets: true, enableSnippets: true,
}} }}
/> />

View File

@ -95,12 +95,14 @@ module VerticalScaling = {
let operationToLeaf = let operationToLeaf =
(evaluationParams: evaluationParams, scaleOp, t, scaleBy) => { (evaluationParams: evaluationParams, scaleOp, t, scaleBy) => {
// scaleBy has to be a single float, otherwise we'll return an error. // scaleBy has to be a single float, otherwise we'll return an error.
let fn = (secondary,main) => Operation.Scale.toFn(scaleOp)(main, secondary); let fn = (secondary, main) =>
Operation.Scale.toFn(scaleOp, main, secondary);
let integralSumCacheFn = Operation.Scale.toIntegralSumCacheFn(scaleOp); let integralSumCacheFn = Operation.Scale.toIntegralSumCacheFn(scaleOp);
let integralCacheFn = Operation.Scale.toIntegralCacheFn(scaleOp); let integralCacheFn = Operation.Scale.toIntegralCacheFn(scaleOp);
let renderedShape = Render.render(evaluationParams, t); let renderedShape = Render.render(evaluationParams, t);
let s = switch (renderedShape, scaleBy) { let s =
switch (renderedShape, scaleBy) {
| (Ok(`RenderedDist(rs)), `SymbolicDist(`Float(scaleBy))) => | (Ok(`RenderedDist(rs)), `SymbolicDist(`Float(scaleBy))) =>
Ok( Ok(
`RenderedDist( `RenderedDist(
@ -265,9 +267,7 @@ module FloatFromDist = {
// TODO: This forces things to be floats // TODO: This forces things to be floats
let callableFunction = (evaluationParams, name, args) => { let callableFunction = (evaluationParams, name, args) => {
args args
|> E.A.fmap(a => |> E.A.fmap(a => evaluationParams.evaluateNode(evaluationParams, a))
Render.render(evaluationParams, a) |> E.R.bind(_, Render.toFloat)
)
|> E.A.R.firstErrorOrOpen |> E.A.R.firstErrorOrOpen
|> E.R.bind(_, Functions.fnn(evaluationParams, name)); |> E.R.bind(_, Functions.fnn(evaluationParams, name));
}; };

View File

@ -31,6 +31,10 @@ module ExpressionTree = {
| `FunctionCall(string, array(node)) | `FunctionCall(string, array(node))
]; ];
// Have nil as option // Have nil as option
let getFloat = (node:node) => node |> fun
| `RenderedDist(Discrete({xyShape: {xs: [|x|], ys: [|1.0|]}})) => Some(x)
| `SymbolicDist(`Float(x)) => Some(x)
| _ => None
type samplingInputs = { type samplingInputs = {
sampleCount: int, sampleCount: int,
@ -87,6 +91,7 @@ module ExpressionTree = {
|> evaluationParams.evaluateNode(evaluationParams) |> evaluationParams.evaluateNode(evaluationParams)
|> E.R.bind(_, fn(evaluationParams)); |> E.R.bind(_, fn(evaluationParams));
module Render = { module Render = {
type t = node; type t = node;

View File

@ -1,21 +1,17 @@
type node = ExpressionTypes.ExpressionTree.node; type node = ExpressionTypes.ExpressionTree.node;
let toOkSym = r => Ok(`SymbolicDist(r)); let toOkSym = r => Ok(`SymbolicDist(r));
let getFloat = ExpressionTypes.ExpressionTree.getFloat;
let twoFloats = (fn, n1: node, n2: node): result(node, string) => let twoFloats = (fn, n1: node, n2: node): result(node, string) =>
switch (n1, n2) { switch (getFloat(n1), getFloat(n2)) {
| (`SymbolicDist(`Float(a)), `SymbolicDist(`Float(b))) => fn(a, b) | (Some(a), Some(b)) => fn(a, b)
| _ => Error("Variables have wrong type") | _ => Error("Function needed two floats, missing them.")
}; };
let threeFloats = (fn, n1: node, n2: node, n3: node): result(node, string) => let threeFloats = (fn, n1: node, n2: node, n3: node): result(node, string) =>
switch (n1, n2, n3) { switch (getFloat(n1), getFloat(n2), getFloat(n3)) {
| ( | (Some(a), Some(b), Some(c)) => fn(a, b, c)
`SymbolicDist(`Float(a)),
`SymbolicDist(`Float(b)),
`SymbolicDist(`Float(c)),
) =>
fn(a, b, c)
| _ => Error("Variables have wrong type") | _ => Error("Variables have wrong type")
}; };
@ -35,18 +31,15 @@ let apply3 = (fn, args: array(node)): result(node, string) =>
| _ => Error("Needs 3 args") | _ => Error("Needs 3 args")
}; };
let to_: (float, float) => result(node, string) = (low, high) => switch(low,high){ let to_: (float, float) => result(node, string) =
| (low,high) (low, high) =>
when low <= 0.0 && low < high => { switch (low, high) {
Ok(`SymbolicDist(SymbolicDist.Normal.from90PercentCI(low, high))); | (low, high) when low <= 0.0 && low < high =>
} Ok(`SymbolicDist(SymbolicDist.Normal.from90PercentCI(low, high)))
| (low,high) | (low, high) when low < high =>
when low < high => { Ok(`SymbolicDist(SymbolicDist.Lognormal.from90PercentCI(low, high)))
Ok(`SymbolicDist(SymbolicDist.Lognormal.from90PercentCI(low, high))); | (low, high) => Error("Low value must be less than high value.")
} };
| (low,high) =>
Error("Low value must be less than high value.")
}
// Possible setup: // Possible setup:
// let normal = {"inputs": [`float, `float], "outputs": [`float]}; // let normal = {"inputs": [`float, `float], "outputs": [`float]};
@ -86,16 +79,57 @@ let fnn =
| _ => Error("Needs 3 valid arguments") | _ => Error("Needs 3 valid arguments")
} }
| ("triangular", _) => | ("triangular", _) =>
switch (args) { switch (args |> E.A.fmap(getFloat)) {
| [| | [|Some(a), Some(b), Some(c)|] =>
`SymbolicDist(`Float(a)),
`SymbolicDist(`Float(b)),
`SymbolicDist(`Float(c)),
|] =>
SymbolicDist.Triangular.make(a, b, c) SymbolicDist.Triangular.make(a, b, c)
|> E.R.fmap(r => `SymbolicDist(r)) |> E.R.fmap(r => `SymbolicDist(r))
| _ => Error("Needs 3 valid arguments") | _ => Error("Needs 3 valid arguments")
} }
| ("to", _) => apply2(twoFloats(to_), args) | ("to", _) => apply2(twoFloats(to_), args)
| ("pdf", _) => switch(args){
| [|fst,snd|] => {
switch(PTypes.SamplingDistribution.renderIfIsNotSamplingDistribution(evaluationParams,fst),getFloat(snd)){
| (Ok(fst), Some(flt)) => Ok(`FloatFromDist(`Pdf(flt), fst))
| _ => Error("Incorrect arguments")
}
}
| _ => Error("Needs two args")
}
| ("inv", _) => switch(args){
| [|fst,snd|] => {
switch(PTypes.SamplingDistribution.renderIfIsNotSamplingDistribution(evaluationParams,fst),getFloat(snd)){
| (Ok(fst), Some(flt)) => Ok(`FloatFromDist(`Inv(flt), fst))
| _ => Error("Incorrect arguments")
}
}
| _ => Error("Needs two args")
}
| ("cdf", _) => switch(args){
| [|fst,snd|] => {
switch(PTypes.SamplingDistribution.renderIfIsNotSamplingDistribution(evaluationParams,fst),getFloat(snd)){
| (Ok(fst), Some(flt)) => Ok(`FloatFromDist(`Cdf(flt), fst))
| _ => Error("Incorrect arguments")
}
}
| _ => Error("Needs two args")
}
| ("mean", _) => switch(args){
| [|fst|] => {
switch(PTypes.SamplingDistribution.renderIfIsNotSamplingDistribution(evaluationParams,fst)){
| (Ok(fst)) => Ok(`FloatFromDist(`Mean,fst))
| _ => Error("Incorrect arguments")
}
}
| _ => Error("Needs two args")
}
| ("sample", _) => switch(args){
| [|fst|] => {
switch(PTypes.SamplingDistribution.renderIfIsNotSamplingDistribution(evaluationParams,fst)){
| (Ok(fst)) => Ok(`FloatFromDist(`Sample,fst))
| _ => Error("Incorrect arguments")
}
}
| _ => Error("Needs two args")
}
| _ => Error("Function " ++ name ++ " not found") | _ => Error("Function " ++ name ++ " not found")
}; };

View File

@ -236,14 +236,6 @@ module MathAdtToDistDst = {
) )
| ("scaleLog", [|d, `SymbolicDist(`Float(v))|]) => | ("scaleLog", [|d, `SymbolicDist(`Float(v))|]) =>
Ok(`VerticalScaling((`Log, d, `SymbolicDist(`Float(v))))) Ok(`VerticalScaling((`Log, d, `SymbolicDist(`Float(v)))))
| ("pdf", [|d, `SymbolicDist(`Float(v))|]) =>
toOkFloatFromDist((`Pdf(v), d))
| ("cdf", [|d, `SymbolicDist(`Float(v))|]) =>
toOkFloatFromDist((`Cdf(v), d))
| ("inv", [|d, `SymbolicDist(`Float(v))|]) =>
toOkFloatFromDist((`Inv(v), d))
| ("mean", [|d|]) => toOkFloatFromDist((`Mean, d))
| ("sample", [|d|]) => toOkFloatFromDist((`Sample, d))
| _ => Error("This type not currently supported") | _ => Error("This type not currently supported")
} }
}); });
@ -294,12 +286,7 @@ module MathAdtToDistDst = {
| "scaleMultiply" | "scaleMultiply"
| "scaleExp" | "scaleExp"
| "scaleLog" | "scaleLog"
| "truncate" | "truncate" => operationParser(name, parseArgs())
| "mean"
| "inv"
| "sample"
| "cdf"
| "pdf" => operationParser(name, parseArgs())
| name => | name =>
parseArgs() parseArgs()
|> E.R.fmap((args: array(ExpressionTypes.ExpressionTree.node)) => |> E.R.fmap((args: array(ExpressionTypes.ExpressionTree.node)) =>