First attempt at simple working environment
This commit is contained in:
parent
67828cf789
commit
e1374ee69b
|
@ -152,7 +152,7 @@ module DemoDist = {
|
|||
shapeLength: Some(options.downsampleTo |> E.O.default(1000))
|
||||
},
|
||||
~distPlusIngredients,
|
||||
~inputVariables=
|
||||
~environment=
|
||||
[|("p", `SymbolicDist(`Float(1.0)))|]
|
||||
->Belt.Map.String.fromArray,
|
||||
(),
|
||||
|
|
|
@ -393,6 +393,7 @@ module Draw = {
|
|||
let normalShape =
|
||||
ExpressionTree.toShape(
|
||||
{sampleCount: 10000, outputXYPoints: 10000, kernelWidth: None, shapeLength:numSamples},
|
||||
ExpressionTypes.ExpressionTree.Environment.empty,
|
||||
`SymbolicDist(normal),
|
||||
) |> E.R.toExn;
|
||||
let xyShape: Types.xyShape =
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
open ExpressionTypes.ExpressionTree;
|
||||
|
||||
let toLeaf = (samplingInputs, node: node) => {
|
||||
let toLeaf = (samplingInputs, environment, node: node) => {
|
||||
node
|
||||
|> ExpressionTreeEvaluator.toLeaf({
|
||||
samplingInputs,
|
||||
environment,
|
||||
evaluateNode: ExpressionTreeEvaluator.toLeaf,
|
||||
});
|
||||
};
|
||||
|
||||
let toShape = (samplingInputs, node: node) => {
|
||||
let toShape = (samplingInputs, environment, node: node) => {
|
||||
let renderResult =
|
||||
`Render(`Normalize(node))
|
||||
|> toLeaf(samplingInputs);
|
||||
`Render(`Normalize(node)) |> toLeaf(samplingInputs, environment);
|
||||
|
||||
switch (renderResult) {
|
||||
| Ok(`RenderedDist(shape)) => Ok(shape)
|
||||
|
|
|
@ -335,6 +335,7 @@ let toLeaf =
|
|||
| `Normalize(t) => Normalize.operationToLeaf(evaluationParams, t)
|
||||
| `Render(t) => Render.operationToLeaf(evaluationParams, t)
|
||||
| `Function(t) => Ok(`Function(t))
|
||||
| `Symbol(r) => ExpressionTypes.ExpressionTree.Environment.get(evaluationParams.environment, r) |> E.O.toResult("Undeclared variable " ++ r)
|
||||
| `CallableFunction(name, args) =>
|
||||
callableFunction(evaluationParams, name, args)
|
||||
};
|
||||
|
|
|
@ -22,6 +22,7 @@ module ExpressionTree = {
|
|||
| `FloatFromDist(distToFloatOperation, node)
|
||||
| `Function(node => result(node, string))
|
||||
| `CallableFunction(string, array(node))
|
||||
| `Symbol(string)
|
||||
];
|
||||
|
||||
type samplingInputs = {
|
||||
|
@ -31,8 +32,18 @@ module ExpressionTree = {
|
|||
shapeLength: int
|
||||
};
|
||||
|
||||
type environment = Belt.Map.String.t(node);
|
||||
|
||||
module Environment = {
|
||||
type t = environment
|
||||
let empty:t = [||]->Belt.Map.String.fromArray
|
||||
let update = (t,str, fn) => Belt.Map.String.update(t, str, fn)
|
||||
let get = (t,str) => Belt.Map.String.get(t, str)
|
||||
}
|
||||
|
||||
type evaluationParams = {
|
||||
samplingInputs,
|
||||
environment,
|
||||
evaluateNode: (evaluationParams, node) => Belt.Result.t(node, string),
|
||||
};
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ module MathJsonToMathJsAdt = {
|
|||
| Array(array(arg))
|
||||
| Blocks(array(arg))
|
||||
| Object(Js.Dict.t(arg))
|
||||
| Assignment(arg,arg)
|
||||
| Assignment(arg, arg)
|
||||
and fn = {
|
||||
name: string,
|
||||
args: array(arg),
|
||||
|
@ -44,19 +44,17 @@ module MathJsonToMathJsAdt = {
|
|||
let items = field("items", array(run), j);
|
||||
Some(Array(items |> E.A.O.concatSomes));
|
||||
| "SymbolNode" => Some(Symbol(field("name", string, j)))
|
||||
| "AssignmentNode" => {
|
||||
| "AssignmentNode" =>
|
||||
let object_ = j |> field("object", run);
|
||||
let value_ = j |> field("value", run);
|
||||
switch(object_, value_){
|
||||
| (Some(o), Some(v)) => Some(Assignment(o,v))
|
||||
switch (object_, value_) {
|
||||
| (Some(o), Some(v)) => Some(Assignment(o, v))
|
||||
| _ => None
|
||||
}
|
||||
}
|
||||
| "BlockNode" => {
|
||||
};
|
||||
| "BlockNode" =>
|
||||
let block = r => r |> field("node", run);
|
||||
let args = j |> field("blocks", array(block)) |> E.A.O.concatSomes;
|
||||
Some(Blocks(args))
|
||||
}
|
||||
Some(Blocks(args));
|
||||
| n =>
|
||||
Js.log3("Couldn't parse mathjs node", j, n);
|
||||
None;
|
||||
|
@ -68,10 +66,7 @@ module MathAdtToDistDst = {
|
|||
open MathJsonToMathJsAdt;
|
||||
|
||||
let handleSymbol = (inputVars: inputVars, sym) => {
|
||||
switch (Belt.Map.String.get(inputVars, sym)) {
|
||||
| Some(s) => Ok(s)
|
||||
| None => Error("Couldn't find symbol " ++ sym)
|
||||
};
|
||||
Ok(`Symbol(sym))
|
||||
};
|
||||
|
||||
module MathAdtCleaner = {
|
||||
|
@ -100,7 +95,7 @@ module MathAdtToDistDst = {
|
|||
| Symbol(s) => Symbol(s)
|
||||
| Value(v) => Value(v)
|
||||
| Blocks(args) => Blocks(args |> E.A.fmap(run))
|
||||
| Assignment(a,b) => Assignment(a,run(b))
|
||||
| Assignment(a, b) => Assignment(a, run(b))
|
||||
| Object(v) =>
|
||||
Object(
|
||||
v
|
||||
|
@ -122,7 +117,10 @@ module MathAdtToDistDst = {
|
|||
)
|
||||
| (_, _, Ok(mu), Ok(sigma)) =>
|
||||
Ok(`CallableFunction(("lognormal", [|mu, sigma|])))
|
||||
| _ => Error("Lognormal distribution needs either mean and stdev or mu and sigma")
|
||||
| _ =>
|
||||
Error(
|
||||
"Lognormal distribution needs either mean and stdev or mu and sigma",
|
||||
)
|
||||
};
|
||||
| _ =>
|
||||
parseArgs()
|
||||
|
@ -293,25 +291,40 @@ module MathAdtToDistDst = {
|
|||
inputVars =>
|
||||
fun
|
||||
| Value(f) => Ok(`SymbolicDist(`Float(f)))
|
||||
| Symbol(s) => handleSymbol(inputVars, s)
|
||||
| Symbol(sym) => Ok(`Symbol(sym))
|
||||
| Fn({name, args}) =>
|
||||
functionParser(nodeParser(inputVars), name, args)
|
||||
| _ => {
|
||||
Error("This type not currently supported");
|
||||
};
|
||||
|
||||
let rec topLevel = inputVars =>
|
||||
fun
|
||||
| Value(_) as r => nodeParser(inputVars, r)
|
||||
| Fn(_) as r => nodeParser(inputVars, r)
|
||||
let rec topLevel =
|
||||
(inputVars: inputVars, r)
|
||||
: result(ExpressionTypes.Program.program, string) =>
|
||||
switch (r) {
|
||||
| Value(_) as r =>
|
||||
nodeParser(inputVars, r) |> E.R.fmap(r => [|`Expression(r)|])
|
||||
| Fn(_) as r =>
|
||||
nodeParser(inputVars, r) |> E.R.fmap(r => [|`Expression(r)|])
|
||||
| Array(_) => Error("Array not valid as top level")
|
||||
| Symbol(s) => handleSymbol(inputVars, s)
|
||||
| Symbol(s) =>
|
||||
handleSymbol(inputVars, s) |> E.R.fmap(r => [|`Expression(r)|])
|
||||
| Object(_) => Error("Object not valid as top level")
|
||||
| Assignment(_) => Error("Assignment not valid as top level")
|
||||
| Blocks(blocks) => E.A.last(blocks) |> E.O.toResult("no blocks listed") |> E.R.bind(_, topLevel(inputVars))
|
||||
| Assignment(name, value) =>
|
||||
switch (name) {
|
||||
| Symbol(symbol) =>
|
||||
nodeParser(inputVars, value)
|
||||
|> E.R.fmap(r => [|`Assignment((symbol, r))|])
|
||||
| _ => Error("Symbol not a string")
|
||||
}
|
||||
| Blocks(blocks) =>
|
||||
blocks
|
||||
|> E.A.fmap(b => topLevel(inputVars, b))
|
||||
|> E.A.R.firstErrorOrOpen
|
||||
|> E.R.fmap(E.A.concatMany)
|
||||
};
|
||||
|
||||
let run =
|
||||
(inputVars, r): result(ExpressionTypes.ExpressionTree.node, string) =>
|
||||
let run = (inputVars, r): result(ExpressionTypes.Program.program, string) =>
|
||||
r |> MathAdtCleaner.run |> topLevel(inputVars);
|
||||
};
|
||||
|
||||
|
|
|
@ -31,29 +31,31 @@ module Inputs = {
|
|||
unit,
|
||||
};
|
||||
};
|
||||
|
||||
type inputs = {
|
||||
distPlusIngredients: ingredients,
|
||||
samplingInputs: SamplingInputs.t,
|
||||
inputVariables: Belt.Map.String.t(ExpressionTypes.ExpressionTree.node),
|
||||
environment: ExpressionTypes.ExpressionTree.environment
|
||||
};
|
||||
|
||||
let empty: SamplingInputs.t = {
|
||||
sampleCount: None,
|
||||
outputXYPoints: None,
|
||||
kernelWidth: None,
|
||||
shapeLength: None
|
||||
shapeLength: None,
|
||||
};
|
||||
|
||||
let make =
|
||||
(
|
||||
~samplingInputs=empty,
|
||||
~distPlusIngredients,
|
||||
~inputVariables=[||]->Belt.Map.String.fromArray,
|
||||
~environment=ExpressionTypes.ExpressionTree.Environment.empty,
|
||||
(),
|
||||
)
|
||||
: inputs => {
|
||||
distPlusIngredients,
|
||||
samplingInputs,
|
||||
inputVariables,
|
||||
environment,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -61,14 +63,27 @@ module Internals = {
|
|||
type inputs = {
|
||||
samplingInputs: Inputs.SamplingInputs.t,
|
||||
guesstimatorString: string,
|
||||
inputVariables: Belt.Map.String.t(ExpressionTypes.ExpressionTree.node),
|
||||
environment: ExpressionTypes.ExpressionTree.environment,
|
||||
};
|
||||
|
||||
let addVariable =
|
||||
(
|
||||
{samplingInputs, guesstimatorString, environment}: inputs,
|
||||
str,
|
||||
node,
|
||||
)
|
||||
: inputs => {
|
||||
samplingInputs,
|
||||
guesstimatorString,
|
||||
environment:
|
||||
ExpressionTypes.ExpressionTree.Environment.update(environment, str, _ => Some(node))
|
||||
};
|
||||
|
||||
let distPlusRenderInputsToInputs = (inputs: Inputs.inputs): inputs => {
|
||||
{
|
||||
samplingInputs: inputs.samplingInputs,
|
||||
guesstimatorString: inputs.distPlusIngredients.guesstimatorString,
|
||||
inputVariables: inputs.inputVariables,
|
||||
environment: inputs.environment,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -78,27 +93,46 @@ module Internals = {
|
|||
};
|
||||
let makeOutputs = (graph, shape): outputs => {graph, shape};
|
||||
|
||||
let inputsToShape = (inputs: inputs) => {
|
||||
MathJsParser.fromString(inputs.guesstimatorString, inputs.inputVariables)
|
||||
|> E.R.bind(_, g =>
|
||||
let runNode = (inputs, node) => {
|
||||
Js.log2("Inputs", inputs);
|
||||
ExpressionTree.toShape(
|
||||
{
|
||||
sampleCount:
|
||||
inputs.samplingInputs.sampleCount |> E.O.default(10000),
|
||||
sampleCount: inputs.samplingInputs.sampleCount |> E.O.default(10000),
|
||||
outputXYPoints:
|
||||
inputs.samplingInputs.outputXYPoints |> E.O.default(10000),
|
||||
kernelWidth: inputs.samplingInputs.kernelWidth,
|
||||
shapeLength: inputs.samplingInputs.shapeLength |> E.O.default(10000)
|
||||
shapeLength: inputs.samplingInputs.shapeLength |> E.O.default(10000),
|
||||
},
|
||||
g,
|
||||
)
|
||||
|> E.R.fmap(makeOutputs(g))
|
||||
inputs.environment,
|
||||
node,
|
||||
);
|
||||
};
|
||||
|
||||
let outputToDistPlus = (inputs: Inputs.inputs, outputs: outputs) => {
|
||||
let runProgram = (inputs: inputs, p: ExpressionTypes.Program.program) => {
|
||||
let ins = ref(inputs);
|
||||
p
|
||||
|> E.A.fmap(statement =>
|
||||
switch (statement) {
|
||||
| `Assignment(name, node) =>
|
||||
ins := addVariable(ins^, name, node);
|
||||
Js.log4("HIHI", ins, name, node);
|
||||
None;
|
||||
| `Expression(node) => Some(runNode(ins^, node))
|
||||
}
|
||||
)
|
||||
|> E.A.O.concatSomes
|
||||
|> E.A.R.firstErrorOrOpen;
|
||||
};
|
||||
|
||||
let inputsToShape = (inputs: inputs) => {
|
||||
MathJsParser.fromString(inputs.guesstimatorString, inputs.environment)
|
||||
|> E.R.bind(_, g => runProgram(inputs, g))
|
||||
|> E.R.bind(_, r => E.A.last(r) |> E.O.toResult("sdf"));
|
||||
};
|
||||
|
||||
let outputToDistPlus = (inputs: Inputs.inputs, shape: DistTypes.shape) => {
|
||||
DistPlus.make(
|
||||
~shape=outputs.shape,
|
||||
~shape,
|
||||
~domain=inputs.distPlusIngredients.domain,
|
||||
~unit=inputs.distPlusIngredients.unit,
|
||||
~guesstimatorString=Some(inputs.distPlusIngredients.guesstimatorString),
|
||||
|
|
Loading…
Reference in New Issue
Block a user