/// <summary> /// Parses a z3 solution into a configuration. /// This method also supports numeric variables. /// </summary> /// <param name="variables">List of all variables in the z3 context.</param> /// <param name="model">Solution of the context.</param> /// <param name="termToOption">Map from variables to binary options.</param> /// <param name="optionsToConsider">The options that are considered for the solution.</param> /// <returns>Configuration parsed from the solution.</returns> public static Tuple <List <BinaryOption>, Dictionary <NumericOption, double> > RetrieveConfiguration( List <Expr> variables, Model model, Dictionary <Expr, ConfigurationOption> termToOption, List <ConfigurationOption> optionsToConsider = null) { List <BinaryOption> binOpts = new List <BinaryOption>(); Dictionary <NumericOption, double> config = new Dictionary <NumericOption, double>(); foreach (Expr variable in variables) { if (optionsToConsider != null && !optionsToConsider.Contains(termToOption[variable])) { continue; } Expr allocation = model.Eval(variable, completion: true); if (allocation.GetType() == typeof(BoolExpr)) { BoolExpr boolExpr = (BoolExpr)allocation; if (boolExpr.IsTrue) { binOpts.Add((BinaryOption)termToOption[variable]); } } else { // In this case, we have a numeric variable FPNum fpNum = (FPNum)allocation; config.Add((NumericOption)termToOption[variable], Z3Solver.lookUpNumericValue(fpNum.ToString())); } } return(new Tuple <List <BinaryOption>, Dictionary <NumericOption, double> >(binOpts, config)); }