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