public static SampleValue MassCompileSample(Symbol outSymbol, SampleValue inSample, Netlist netlist, Style style) { //inSample.Consume(null, 0, null, netlist, style); // this prevents simulating a sample and its massaction version in succession List <ReactionValue> inReactions = inSample.RelevantReactions(netlist, style); CRN inCrn = new CRN(inSample, inReactions); Gui.Log(Environment.NewLine + inCrn.FormatNice(style)); (Lst <Polynomize.ODE> odes, Lst <Polynomize.Equation> eqs) = Polynomize.FromCRN(inCrn); (Lst <Polynomize.PolyODE> polyOdes, Lst <Polynomize.Equation> polyEqs) = Polynomize.PolynomizeODEs(odes, eqs.Reverse(), style); Gui.Log("Polynomize:" + Environment.NewLine + Polynomize.PolyODE.Format(polyOdes, style) + "Initial:" + Environment.NewLine + Polynomize.Equation.Format(polyEqs, style)); (Lst <Polynomize.PolyODE> posOdes, Lst <Polynomize.Equation> posEqs, Dictionary <Symbol, SpeciesFlow> dict, Lst <Positivize.Subst> substs) = Positivize.PositivizeODEs(polyOdes, polyEqs, style); Gui.Log("Positivize:" + Environment.NewLine + Polynomize.PolyODE.Format(posOdes, style) + "Initial:" + Environment.NewLine + Polynomize.Equation.Format(posEqs, style)); Lst <ReactionValue> outReactions = Hungarize.ToReactions(posOdes, style); Gui.Log("Hungarize:" + Environment.NewLine + outReactions.FoldR((r, s) => { return(r.FormatNormal(style) + Environment.NewLine + s); }, "") + "Initial:" + Environment.NewLine + Polynomize.Equation.Format(posEqs, style)); SampleValue outSample = new SampleValue(outSymbol, new StateMap(outSymbol, new List <SpeciesValue> { }, new State(0, lna: inSample.stateMap.state.lna)), new NumberValue(inSample.Volume()), new NumberValue(inSample.Temperature()), produced: true); netlist.Emit(new SampleEntry(outSample)); posOdes.Each(ode => { Flow initFlow = Polynomize.Equation.ToFlow(ode.var, posEqs, style).Normalize(style); double init; if (initFlow is NumberFlow num) { init = num.value; } else { throw new Error("Cannot generate a simulatable sample because initial values contain constants (but the symbolic version has been generated assuming constants are nonnegative)."); } if (init < 0) { throw new Error("Negative initial value of Polynomized ODE for: " + Polynomize.Lookup(ode.var, eqs, style).Format(style) + " = " + init + Environment.NewLine + Polynomize.Equation.Format(eqs, style)); } outSample.stateMap.AddDimensionedSpecies(new SpeciesValue(ode.var.species, -1.0), init, 0.0, "M", outSample.Volume(), style); }); outReactions.Each(reaction => { netlist.Emit(new ReactionEntry(reaction)); }); substs.Each(subst => { ReportEntry report = new ReportEntry(null, OpFlow.Op(subst.plus, "-", subst.minus), null, outSample); outSample.AddReport(report); }); foreach (KeyValuePair <Symbol, SpeciesFlow> keypair in dict) { ReportEntry report = new ReportEntry(null, keypair.Value, null, outSample); outSample.AddReport(report); } ; return(outSample); }
public ValueEnv(string name, Type type, Value value, Netlist netlist, Env next) : this(new Symbol(name), type, value, next) { if (netlist != null) { netlist.Emit(new ValueEntry(this.symbol, type, value)); // also emit the new binding to netlist } }
private static void Execute_Worker(bool doParse, bool doAST, bool doScope, bool autoContinue, bool chartOutput) { KGui.gui.GuiBeginningExecution(); lastExecution = null; KGui.gui.GuiSaveInput(); KGui.gui.GuiOutputClear(); DateTime startTime = DateTime.Now; if (TheParser.Parser().Parse(KGui.gui.GuiInputGetText(), out IReduction root)) { if (doParse) { root.DrawReductionTree(); } else { Netlist netlist = new Netlist(autoContinue); try { Statements statements = Parser.ParseTop(root); if (doAST) { KGui.gui.GuiOutputAppendText(statements.Format()); } else { SampleValue vessel = Vessel(KControls.SelectNoiseSelectedItem != Noise.None); Env initialEnv = new ValueEnv("vessel", Type.Sample, vessel, new BuiltinEnv(new NullEnv())); Scope initialScope = initialEnv.ToScope(); Scope scope = statements.Scope(initialScope); if (doScope) { KGui.gui.GuiOutputAppendText(scope.Format()); } else { Style style = new Style(varchar: scopeVariants ? defaultVarchar : null, new SwapMap(), map: remapVariants ? new AlphaMap() : null, numberFormat: "G4", dataFormat: "full", // we want it full for samples, but maybe only headers for functions/networks? exportTarget: ExportTarget.Standard, traceFull: false, chartOutput: chartOutput); KChartHandler.ChartClear("", "s", "M", style); KChartHandler.LegendUpdate(style); KScoreHandler.ScoreClear(); KControls.ParametersClear(style); KDeviceHandler.Clear(style); KDeviceHandler.Sample(vessel, style); netlist.Emit(new SampleEntry(vessel)); DateTime evalTime = DateTime.Now; lastExecution = new ExecutionInstance(vessel, netlist, style, startTime, evalTime); lastExecution.environment = statements.EvalReject(initialEnv, netlist, style, 0); if (lastExecution.environment == null) { throw new Error("Top level reject"); } lastExecution.EndTime(); if (style.chartOutput) { foreach (ParameterEntry parameter in netlist.Parameters()) { KControls.AddParameter(parameter.symbol.Format(style), (parameter.value as NumberValue).value, parameter.distribution, style); } KGui.gui.GuiParametersUpdate(); // calls back KControls.ParametersUpdate, but only on Win/Mac } KGui.gui.GuiProcessOutput(); } } } catch (ExecutionEnded) { lastExecution.EndTime(); KGui.gui.GuiOutputAppendText(lastExecution.ElapsedTime()); } catch (ConstantEvaluation ex) { string cat = "Does not have a value: "; netlist.Emit(new CommentEntry(cat + ": " + ex.Message)); KGui.gui.GuiInputSetErrorSelection(-1, -1, 0, cat, ex.Message); } catch (Error ex) { netlist.Emit(new CommentEntry(ex.Message)); KGui.gui.GuiInputSetErrorSelection(-1, -1, 0, "Error", ex.Message); try { KGui.gui.GuiProcessOutput(); } catch { }; } catch (StackOverflowException ex) { netlist.Emit(new CommentEntry(ex.Message)); KGui.gui.GuiInputSetErrorSelection(-1, -1, 0, "Stack Overflow", ex.Message); } catch (Exception ex) { string cat = "Something happened"; netlist.Emit(new CommentEntry(cat + ": " + ex.Message)); KGui.gui.GuiInputSetErrorSelection(-1, -1, 0, cat, ex.Message); } } } else { KGui.gui.GuiInputSetErrorSelection(TheParser.Parser().FailLineNumber(), TheParser.Parser().FailColumnNumber(), TheParser.Parser().FailLength(), TheParser.Parser().FailCategory(), TheParser.Parser().FailMessage()); } EndingExecution(); }