private Tuple <bool, bool> preCheckConfigReqOne(Configuration config)
        {
            bool hasAllConfigs = true;
            bool hasAtLeastOne = false;

            foreach (BinaryOption bo in leftHandSide.participatingBoolOptions.Union(rightHandSide.participatingBoolOptions))
            {
                if (!config.BinaryOptions.ContainsKey(bo))
                {
                    hasAllConfigs = false;
                }
                else if (config.BinaryOptions.ContainsKey(bo))
                {
                    hasAtLeastOne = true;
                }
            }

            foreach (NumericOption no in leftHandSide.participatingNumOptions.Union(rightHandSide.participatingNumOptions))
            {
                InfluenceFunction func = new InfluenceFunction(no.ToString(), GlobalState.varModel);
                if (!config.NumericOptions.ContainsKey(no))
                {
                    hasAllConfigs = false;
                }
                else if (func.eval(config) == 0)
                {
                    hasAllConfigs = false;
                }
                else if (config.NumericOptions.ContainsKey(no))
                {
                    hasAtLeastOne = true;
                }
            }
            return(Tuple.Create(hasAllConfigs, hasAtLeastOne));
        }
        /// <summary>
        /// Creates a new mixed constraint between boolean and numeric options and literals.
        /// </summary>
        /// <param name="unparsedExpr">The expression of the constraint as string.</param>
        /// <param name="varMod">The variability model the constraint applies to.</param>
        /// <param name="requirement">String indicating if the constraints evaluates to
        ///                           to false if not all options are present.</param>
        /// <param name="exprKind">Value indicating if the the expression will be negated.</param>
        public MixedConstraint(String unparsedExpr, VariabilityModel varMod, string requirement, string exprKind = "pos")
            : base(unparsedExpr, varMod)
        {
            if (requirement.Trim().ToLower().Equals(REQUIRE_ALL))
            {
                this.requirement = REQUIRE_ALL;
            }
            else if (requirement.Trim().ToLower().Equals(REQUIRE_NONE))
            {
                this.requirement = REQUIRE_NONE;
            }
            else
            {
                throw new ArgumentException(String.Format("The tag {0} for mixed requirements is not valid.", requirement));
            }

            if (exprKind.Trim().ToLower().Equals(NEGATIVE))
            {
                this.negativeOrPositiveExpr = NEGATIVE;
            }
            else if (exprKind.Trim().ToLower().Equals(POSITIVE))
            {
                this.negativeOrPositiveExpr = POSITIVE;
            }
            else
            {
                throw new ArgumentException(String.Format("The expression kind {0} is not valid. Expression can either be neg or pos.", exprKind));
            }

            String[] parts = base.ToString().Split(new string[] { ">", "<", "=", "<=", ">=" }, StringSplitOptions.None);
            leftHandSide  = new InfluenceFunction(parts[0], varMod);
            rightHandSide = new InfluenceFunction(parts[parts.Length - 1], varMod);
            var           = varMod;
        }
 /// <summary>
 /// Computes the influence of all configuration options based on the measurements of the given result db. It uses linear programming (simplex) and is an exact algorithm.
 /// </summary>
 /// <param name="nfp">The non-funcitonal property for which the influences of configuration options are to be computed. If null, we use the property of the global model.</param>
 /// <param name="infModel">The influence model containing options and interactions. The state of the model will be changed by the result of the process</param>
 /// <param name="db">The result database containing the measurements.</param>
 /// <returns>A map of binary options to their computed influences.</returns>
 public Dictionary<BinaryOption, double> computeOptionInfluences(NFProperty nfp, InfluenceModel infModel, ResultDB db)
 {
     List<BinaryOption> variables = infModel.Vm.BinaryOptions;
     List<double> results = new List<double>();
     List<List<BinaryOption>> configurations = new List<List<BinaryOption>>();
     foreach (Configuration c in db.Configurations)
     {
         configurations.Add(c.getBinaryOptions(BinaryOption.BinaryValue.Selected));
         if (nfp != null)
             results.Add(c.GetNFPValue(nfp));
         else
             results.Add(c.GetNFPValue());
     }
     List<String> errorEqs = new List<string>();
     Dictionary<String, double> faultRates = new Dictionary<string, double>();
     List<int> indexOfErrorMeasurements = new List<int>();
     Dictionary<String, double> featureValuedAsStrings = solve(variables, results, configurations, infModel.InteractionInfluence.Keys.ToList());
     foreach (String current in featureValuedAsStrings.Keys)
     {
         BinaryOption temp = infModel.Vm.getBinaryOption(current);
         this.featureValues[temp] = featureValuedAsStrings[current];
         InfluenceFunction influence = new InfluenceFunction(temp.Name + " + " + featureValuedAsStrings[current].ToString(),infModel.Vm);
         if (infModel.BinaryOptionsInfluence.Keys.Contains(temp))
             infModel.BinaryOptionsInfluence[temp] = influence;
         else
             infModel.BinaryOptionsInfluence.Add(temp, influence);
     }
     return this.featureValues;
 }
Exemple #4
0
        /// <summary>
        /// Loads all information about the numeric connfiguration option from the XML file consisting of the variability model.
        /// </summary>
        /// <param name="node">The root note of the numeric configuration option.</param>
        internal new void loadFromXML(XmlElement node)
        {
            base.loadFromXML(node);
            foreach (XmlElement xmlInfo in node.ChildNodes)
            {
                switch (xmlInfo.Name)
                {
                case "minValue":
                    this.min_value = Double.Parse(xmlInfo.InnerText.Replace(',', '.'));
                    break;

                case "maxValue":
                    this.max_value = Double.Parse(xmlInfo.InnerText.Replace(',', '.'));
                    break;

                case "stepFunction":
                    this.stepFunction = new InfluenceFunction(xmlInfo.InnerText.Replace(',', '.'), this);
                    break;

                case "deselectedFlag":
                    this.setOptional(true, Int32.Parse(xmlInfo.InnerText.Replace(',', '.')));
                    break;

                case "values":
                    String[] valueArray       = xmlInfo.InnerText.Replace(',', '.').Split(';');
                    double[] values_As_Double = new double[valueArray.Count()];
                    for (int i = 0; i < valueArray.Count(); i++)
                    {
                        values_As_Double[i] = Convert.ToDouble(valueArray[i]);
                    }
                    SetValues(values_As_Double);
                    break;
                }
            }
        }
        /// <summary>
        /// Creates a new NonBooleanConstraint for a expression. The expression have to consist binary and numeric options and operators such as "+,*,>=,<=,>,<, and =" only. 
        /// Where all binary and numeric options have to be defined in the variability model. 
        /// </summary>
        /// <param name="unparsedExpression"></param>
        /// <param name="varModel"></param>
        public NonBooleanConstraint(String unparsedExpression, VariabilityModel varModel)
        {
            if (unparsedExpression.Contains(">="))
            {
                comparator = ">=";
            }
            else if (unparsedExpression.Contains("<="))
            {
                comparator = "<=";
            }
            else if (unparsedExpression.Contains("="))
            {
                comparator = "=";
            }
            else if (unparsedExpression.Contains(">"))
            {
                comparator = ">";
            }
            else if (unparsedExpression.Contains("<"))
            {
                comparator = "<";
            }

            String[] parts = unparsedExpression.Split(comparator.ToCharArray());
            leftHandSide = new InfluenceFunction(parts[0], varModel);
            rightHandSide = new InfluenceFunction(parts[parts.Length-1], varModel);
        }
        internal void loadFromXML(XmlElement node)
        {
            base.loadFromXML(node);
            foreach (XmlElement xmlInfo in node.ChildNodes)
            {
                switch (xmlInfo.Name)
                {
                case "minValue":
                    this.min_value = Double.Parse(xmlInfo.InnerText.Replace(',', '.'));
                    break;

                case "maxValue":
                    this.max_value = Double.Parse(xmlInfo.InnerText.Replace(',', '.'));
                    break;

                case "defaultValue":
                    this.defaultValue = Double.Parse(xmlInfo.InnerText.Replace(',', '.'));
                    break;

                case "stepFunction":
                    this.stepFunction = new InfluenceFunction(xmlInfo.InnerText.Replace(',', '.'), this);
                    break;
                }
            }
        }
Exemple #7
0
        /// <summary>
        /// Creates a new NonBooleanConstraint for a expression. The expression have to consist binary and numeric options and operators such as +, *, &lt;=, &lt;, &gt;=, &gt;, and = only.
        /// Where all binary and numeric options have to be defined in the variability model.
        /// </summary>
        /// <param name="unparsedExpression"></param>
        /// <param name="varModel"></param>
        public NonBooleanConstraint(String unparsedExpression, VariabilityModel varModel)
        {
            if (unparsedExpression.Contains(">="))
            {
                comparator = ">=";
            }
            else if (unparsedExpression.Contains("<="))
            {
                comparator = "<=";
            }
            else if (unparsedExpression.Contains("="))
            {
                comparator = "=";
            }
            else if (unparsedExpression.Contains(">"))
            {
                comparator = ">";
            }
            else if (unparsedExpression.Contains("<"))
            {
                comparator = "<";
            }

            String[] parts = unparsedExpression.Split(comparator.ToCharArray());
            leftHandSide  = new InfluenceFunction(parts[0], varModel);
            rightHandSide = new InfluenceFunction(parts[parts.Length - 1], varModel);
        }
        //public void filterFeatureModelToExpression()
        //{
        //    bool actionDone = true;
        //    List<BinaryOption> featuresToRemove = new List<Element>();
        //    foreach (Element feature in this.fm.getAllElements())
        //    {
        //        if (!this.participatingBoolFeatures.Contains(feature))
        //            featuresToRemove.Add(feature);
        //    }
        //    foreach (Element f in featuresToRemove)
        //        this.fm.removeElement(f);

        //    List<NumericOption> numOptionsToRemove = new List<NumericOption>();
        //    foreach (NumericOption no in this.fm.numericOptions)
        //    {
        //        if (!this.participatingNumFeatures.Contains(no))
        //            numOptionsToRemove.Add(no);
        //    }

        //    foreach (NumericOption f in numOptionsToRemove)
        //        this.fm.removeNumericOption(f);
        //}

        /// <summary>
        /// Checks using the ToString method whether this InfluenceFunction is equal to another one
        /// </summary>
        /// <param name="other">The other influence function to be compared with</param>
        /// <returns>True if the same, false otherwise</returns>
        public bool Equals(InfluenceFunction other)
        {
            if (other.ToString() == this.ToString())
            {
                return(true);
            }

            return(false);
        }
        private string replaceDifferentLogParts(string expression)
        {
            while (expression.Contains("log10("))
            {
                expression = InfluenceFunction.replaceLogAndClosingBracket(expression, "log10(", '[', ']');
            }

            return(expression);
        }
        private double evaluationOfRPN(Configuration config)
        {
            int counter = 0;

            Stack <double> stack = new Stack <double>();

            if (expressionArray.Length == 0)
            {
                return(1);
            }

            while (counter < expressionArray.Length)
            {
                string curr = expressionArray[counter];
                counter++;

                if (!InfluenceFunction.isOperatorEval(curr))
                {
                    stack.Push(getValueOfToken(config, curr, varModel));
                }
                else
                {
                    if (curr.Equals("+"))
                    {
                        double rightHandSide = stack.Pop();
                        if (stack.Count == 0)
                        {
                            stack.Push(rightHandSide);
                        }
                        double leftHandSide = stack.Pop();
                        stack.Push(leftHandSide + rightHandSide);
                    }
                    if (curr.Equals("*"))
                    {
                        double rightHandSide = stack.Pop();
                        double leftHandSide  = stack.Pop();
                        stack.Push(leftHandSide * rightHandSide);
                    }
                    // TODO log(0) == ????
                    if (curr.Equals("]"))
                    {
                        double leftHandSide = stack.Pop();
                        if (leftHandSide == 0.0)
                        {
                            stack.Push(0.0);
                        }
                        else
                        {
                            stack.Push(Math.Log(leftHandSide, 10.0));
                        }
                    }
                }
            }

            return(stack.Pop());
        }
        private double evaluationOfRPN(Dictionary <NumericOption, double> config)
        {
            int counter = 0;

            if (expressionArray.Length == 0)
            {
                return(0);
            }

            Stack <double> stack = new Stack <double>();

            while (counter < expressionArray.Length)
            {
                string curr = expressionArray[counter];
                counter++;

                if (!InfluenceFunction.isOperatorEval(curr))
                {
                    stack.Push(getValueOfToken(config, curr, varModel));
                }
                else
                {
                    if (curr.Equals("+"))
                    {
                        if (stack.Count < 2)
                        {
                            Console.WriteLine("Error. Possible reason: name of numeric option does not match the name in the stepsize XML-tag");
                        }

                        double rightHandSide = stack.Pop();
                        double leftHandSide  = stack.Pop();
                        stack.Push(leftHandSide + rightHandSide);
                    }
                    if (curr.Equals("*"))
                    {
                        double rightHandSide = stack.Pop();
                        double leftHandSide  = stack.Pop();
                        stack.Push(leftHandSide * rightHandSide);
                    }
                    if (curr.Equals("]"))
                    {
                        double leftHandSide = stack.Pop();
                        if (leftHandSide == 0.0)
                        {
                            stack.Push(Double.MinValue);
                        }
                        else
                        {
                            stack.Push(Math.Log(leftHandSide, 10.0));
                        }
                    }
                }
            }

            return(stack.Pop());
        }
 /// <summary>
 /// Creates an interaction based on a given influence function. 
 /// </summary>
 /// <param name="f">A influence function consisting of configuration options.</param>
 public Interaction(InfluenceFunction f)
 {
     StringBuilder sb = new StringBuilder();
     foreach (BinaryOption opt in f.participatingBoolOptions)
     {
         sb.Append(opt.Name + "#");
         binaryOptions.Add(opt);
     }
     foreach (NumericOption opt in f.participatingNumOptions)
     {
         sb.Append(opt.Name + "#");
         this.numericOptions.Add(opt);
     }
 }
Exemple #13
0
        /// <summary>
        /// Creates an interaction based on a given influence function.
        /// </summary>
        /// <param name="f">A influence function consisting of configuration options.</param>
        public Interaction(InfluenceFunction f)
        {
            StringBuilder sb = new StringBuilder();

            foreach (BinaryOption opt in f.participatingBoolOptions)
            {
                sb.Append(opt.Name + "#");
                binaryOptions.Add(opt);
            }
            foreach (NumericOption opt in f.participatingNumOptions)
            {
                sb.Append(opt.Name + "#");
                this.numericOptions.Add(opt);
            }
        }
Exemple #14
0
 /// <summary>
 /// Sets the numerical values.
 /// </summary>
 /// <param name="values">The values to set.</param>
 public void SetValues(double[] values)
 {
     this.min_value = values.Min();
     this.max_value = values.Max();
     if (this.values == null)
     {
         this.values = new NumericValues(values);
     }
     else
     {
         this.values.Values = values;
     }
     // Either use values or step function
     this.StepFunction = null;
 }
        private static string replaceLogAndClosingBracket(string expression, string logStart, char newLeftBracket, char newRightBracket)
        {
            string[] parts = expression.Split(new string[] { logStart }, 2, StringSplitOptions.None);
            if (parts.Length == 1)
            {
                return(expression);
            }

            // there is no "log(" in parts[0], as a consequence, we can return this part

            StringBuilder secondPart = new StringBuilder(parts[1]);

            secondPart[InfluenceFunction.findOffsetToClosingBracket(secondPart.ToString())] = newRightBracket;

            return(parts[0] + newLeftBracket + secondPart.ToString());
        }
        /// <summary>
        /// This method creates an influence function that is the combination of the left and the right functions. Both funtions should
        /// be defined over the same variability model. 
        /// </summary>
        /// <param name="left">The first summand of the new influence function.</param>
        /// <param name="right">The second summand of the new influence function.</param>
        /// <returns>The combination of the two influence functions.</returns>
        public static InfluenceFunction combineFunctions(InfluenceFunction left, InfluenceFunction right)
        {
            InfluenceFunction expTree = new InfluenceFunction();
            expTree.noise = left.noise;
            expTree.varModel = left.varModel;
            expTree.wellFormedExpression = left.wellFormedExpression + " * " + right.wellFormedExpression;

            expTree.participatingBoolOptions.UnionWith(left.participatingBoolOptions);
            expTree.participatingBoolOptions.UnionWith(right.participatingBoolOptions);

            expTree.participatingNumOptions.UnionWith(left.participatingNumOptions);
            expTree.participatingNumOptions.UnionWith(right.participatingNumOptions);

            expTree.numberOfParticipatingFeatures = expTree.participatingBoolOptions.Count + expTree.participatingNumOptions.Count;

            expTree.expressionArray = left.expressionArray.ToList().Concat(right.expressionArray.ToList()).Concat(new List<String>() { "*" }).ToArray();

            return expTree;
        }
        internal bool containsParent(InfluenceFunction featureToAdd)
        {
            foreach (BinaryOption binOpt in featureToAdd.participatingBoolOptions)
            {
                if (this.participatingBoolOptions.Contains(binOpt))
                {
                    return(true);
                }
                BinaryOption parent = (BinaryOption)binOpt.Parent;
                while (parent != null && parent != varModel.Root)
                {
                    if (this.participatingBoolOptions.Contains(parent))
                    {
                        return(true);
                    }
                    parent = (BinaryOption)parent.Parent;
                }
            }

            return(false);
        }
        /// <summary>
        /// This method creates an influence function that is the combination of the left and the right functions. Both funtions should
        /// be defined over the same variability model.
        /// </summary>
        /// <param name="left">The first summand of the new influence function.</param>
        /// <param name="right">The second summand of the new influence function.</param>
        /// <returns>The combination of the two influence functions.</returns>
        public static InfluenceFunction combineFunctions(InfluenceFunction left, InfluenceFunction right)
        {
            InfluenceFunction expTree = new InfluenceFunction();

            expTree.noise                = left.noise;
            expTree.varModel             = left.varModel;
            expTree.wellFormedExpression = left.wellFormedExpression + " * " + right.wellFormedExpression;

            expTree.participatingBoolOptions.UnionWith(left.participatingBoolOptions);
            expTree.participatingBoolOptions.UnionWith(right.participatingBoolOptions);

            expTree.participatingNumOptions.UnionWith(left.participatingNumOptions);
            expTree.participatingNumOptions.UnionWith(right.participatingNumOptions);

            expTree.numberOfParticipatingFeatures = expTree.participatingBoolOptions.Count + expTree.participatingNumOptions.Count;

            expTree.expressionArray = left.expressionArray.ToList().Concat(right.expressionArray.ToList()).Concat(new List <String>()
            {
                "*"
            }).ToArray();

            return(expTree);
        }
        /// <summary>
        /// Performs the functionality of one command. If no functionality is found for the command, the command is retuned by this method. 
        /// </summary>
        /// <param name="line">One command with its parameters.</param>
        /// <returns>Returns an empty string if the command could be performed by the method. If the command could not be performed by the method, the original command is returned.</returns>
        public string performOneCommand(string line)
        {
            GlobalState.logInfo.logLine(COMMAND + line);

            // remove comment part of the line (the comment starts with an #)
            line = line.Split(new Char[] { '#' }, 2)[0];
            if (line.Length == 0)
                return "";

            // split line in command and parameters of the command
            string[] components = line.Split(new Char[] { ' ' }, 2);
            string command = components[0];
            string task = "";
            if (components.Length > 1)
                task = components[1];

            string[] taskAsParameter = task.Split(new Char[] { ' ' });

            switch (command.ToLower())
            {
                case COMMAND_START_ALLMEASUREMENTS:
                    {
                        InfluenceModel infMod = new InfluenceModel(GlobalState.varModel, GlobalState.currentNFP);

                        List<Configuration> configurations_Learning = new List<Configuration>();

                        foreach (Configuration config in GlobalState.allMeasurements.Configurations)
                        {
                            if (config.nfpValues.ContainsKey(GlobalState.currentNFP))
                                configurations_Learning.Add(config);
                        }

                        if (configurations_Learning.Count == 0)
                        {
                            GlobalState.logInfo.logLine("The learning set is empty! Cannot start learning!");
                            break;
                        }

                        GlobalState.logInfo.logLine("Learning: " + "NumberOfConfigurationsLearning:" + configurations_Learning.Count);
                        // prepare the machine learning
                        exp = new MachineLearning.Learning.Regression.Learning(configurations_Learning, configurations_Learning);
                        exp.metaModel = infMod;
                        exp.mLsettings = this.mlSettings;
                        exp.learn();
                    }
                    break;

                case COMMAND_TRUEMODEL:
                    StreamReader readModel = new StreamReader(task);
                    String model = readModel.ReadLine().Trim();
                    readModel.Close();
                    this.trueModel = new InfluenceFunction(model.Replace(',', '.'), GlobalState.varModel);
                    NFProperty artificalProp = new NFProperty("artificial");
                    GlobalState.currentNFP = artificalProp;
                    //computeEvaluationDataSetBasedOnTrueModel();
                    break;

                case COMMAND_SUBSCRIPT:
                    {

                        FileInfo fi = new FileInfo(task);
                        StreamReader reader = null;
                        if (!fi.Exists)
                            throw new FileNotFoundException(@"Automation script not found. ", fi.ToString());

                        reader = fi.OpenText();
                        Commands co = new Commands();
                        co.exp = this.exp;

                        while (!reader.EndOfStream)
                        {
                            String oneLine = reader.ReadLine().Trim();
                            co.performOneCommand(oneLine);

                        }
                    }
                    break;
                case COMMAND_EVALUATION_SET:
                    {
                        GlobalState.evalutionSet.Configurations = ConfigurationReader.readConfigurations(task, GlobalState.varModel);
                        GlobalState.logInfo.logLine("Evaluation set loaded.");
                    }
                    break;
                case COMMAND_CLEAR_GLOBAL:
                    SPLConqueror_Core.GlobalState.clear();
                    toSample.Clear();
                    toSampleValidation.Clear();
                    break;
                case COMMAND_CLEAR_SAMPLING:
                    exp.clearSampling();
                    toSample.Clear();
                    toSampleValidation.Clear();
                    break;
                case COMMAND_CLEAR_LEARNING:
                    exp.clear();
                    toSample.Clear();
                    toSampleValidation.Clear();
                    break;
                case COMMAND_LOAD_CONFIGURATIONS:
                    GlobalState.allMeasurements.Configurations = (GlobalState.allMeasurements.Configurations.Union(ConfigurationReader.readConfigurations(task, GlobalState.varModel))).ToList();
                    GlobalState.logInfo.logLine(GlobalState.allMeasurements.Configurations.Count + " configurations loaded.");

                    break;
                case COMMAND_SAMPLE_ALLBINARY:
                    {
                        if (taskAsParameter.Contains(COMMAND_VALIDATION))
                        {
                            this.toSampleValidation.Add(SamplingStrategies.ALLBINARY);
                            this.exp.info.binarySamplings_Validation = "ALLBINARY";
                        }
                        else
                        {
                            this.toSample.Add(SamplingStrategies.ALLBINARY);
                            this.exp.info.binarySamplings_Learning = "ALLBINARY";
                        }

                        break;
                    }
                case COMMAND_ANALYZE_LEARNING:
                    {//TODO: Analyzation is not supported in the case of bagging
                        GlobalState.logInfo.logLine("Models:");
                        if (this.mlSettings.bagging)
                        {
                            for (int i = 0; i < this.exp.models.Count; i++)
                            {
                                FeatureSubsetSelection learnedModel = exp.models[i];
                                if (learnedModel == null)
                                {
                                    GlobalState.logError.logLine("Error... learning was not performed!");
                                    break;
                                }
                                GlobalState.logInfo.logLine("Termination reason: " + learnedModel.LearningHistory.Last().terminationReason);
                                foreach (LearningRound lr in learnedModel.LearningHistory)
                                {
                                    double relativeError = 0;
                                    if (GlobalState.evalutionSet.Configurations.Count > 0)
                                    {
                                        double relativeErro2r = learnedModel.computeError(lr.FeatureSet, GlobalState.evalutionSet.Configurations, out relativeError);
                                    }
                                    else
                                    {
                                        double relativeErro2r = learnedModel.computeError(lr.FeatureSet, GlobalState.allMeasurements.Configurations, out relativeError);
                                    }

                                    GlobalState.logInfo.logLine(lr.ToString() + relativeError);
                                }
                            }
                        }
                        else
                        {
                            FeatureSubsetSelection learnedModel = exp.models[0];
                            if (learnedModel == null)
                            {
                                GlobalState.logError.logLine("Error... learning was not performed!");
                                break;
                            }
                            GlobalState.logInfo.logLine("Termination reason: " + learnedModel.LearningHistory.Last().terminationReason);
                            foreach (LearningRound lr in learnedModel.LearningHistory)
                            {
                                double relativeError = 0;
                                if (GlobalState.evalutionSet.Configurations.Count > 0)
                                {
                                    double relativeErro2r = learnedModel.computeError(lr.FeatureSet, GlobalState.evalutionSet.Configurations, out relativeError);
                                }
                                else
                                {
                                    double relativeErro2r = learnedModel.computeError(lr.FeatureSet, GlobalState.allMeasurements.Configurations, out relativeError);
                                }

                                GlobalState.logInfo.logLine(lr.ToString() + relativeError);
                            }
                        }

                        break;
                    }
                case COMMAND_EXERIMENTALDESIGN:
                    performOneCommand_ExpDesign(task);
                    break;

                case COMMAND_SAMPLING_OPTIONORDER:
                    parseOptionOrder(task);
                    break;

                case COMMAND_VARIABILITYMODEL:
                    GlobalState.varModel = VariabilityModel.loadFromXML(task);
                    if (GlobalState.varModel == null)
                        GlobalState.logError.logLine("No variability model found at " + task);
                    break;
                case COMMAND_SET_NFP:
                    GlobalState.currentNFP = GlobalState.getOrCreateProperty(task.Trim());
                    break;
                case COMMAND_SAMPLE_OPTIONWISE:
                    if (taskAsParameter.Contains(COMMAND_VALIDATION))
                    {
                        this.toSampleValidation.Add(SamplingStrategies.OPTIONWISE);
                        this.exp.info.binarySamplings_Validation = "OPTIONSWISE";
                    }
                    else
                    {
                        this.toSample.Add(SamplingStrategies.OPTIONWISE);
                        this.exp.info.binarySamplings_Learning = "OPTIONSWISE";
                    }
                    break;

                case COMMAND_LOG:

                    string location = task.Trim();
                    GlobalState.logInfo.close();
                    GlobalState.logInfo = new InfoLogger(location);

                    GlobalState.logError.close();
                    GlobalState.logError = new ErrorLogger(location + "_error");
                    break;
                case COMMAND_SET_MLSETTING:
                    this.mlSettings = ML_Settings.readSettings(task);
                    break;
                case COMMAND_LOAD_MLSETTINGS:
                    this.mlSettings = ML_Settings.readSettingsFromFile(task);
                    break;

                case COMMAND_SAMPLE_PAIRWISE:

                    if (taskAsParameter.Contains(COMMAND_VALIDATION))
                    {
                        this.toSampleValidation.Add(SamplingStrategies.PAIRWISE);
                        this.exp.info.binarySamplings_Validation = "PAIRWISE";
                    }
                    else
                    {
                        this.toSample.Add(SamplingStrategies.PAIRWISE);
                        this.exp.info.binarySamplings_Learning = "PAIRWISE";
                    }
                    break;

                case COMMAND_PRINT_MLSETTINGS:
                    GlobalState.logInfo.logLine(this.mlSettings.ToString());
                    break;

                case COMMAND_PRINT_CONFIGURATIONS:
                    {
                       /* List<Dictionary<NumericOption, double>> numericSampling = exp.NumericSelection_Learning;
                        List<List<BinaryOption>> binarySampling = exp.BinarySelections_Learning;

                        List<Configuration> configurations = new List<Configuration>();

                        foreach (Dictionary<NumericOption, double> numeric in numericSampling)
                        {
                            foreach (List<BinaryOption> binary in binarySampling)
                            {
                                Configuration config = Configuration.getConfiguration(binary, numeric);
                                if (!configurations.Contains(config) && GlobalState.varModel.configurationIsValid(config))
                                {
                                    configurations.Add(config);
                                }
                            }
                        }*/

                        var configs = ConfigurationBuilder.buildConfigs(GlobalState.varModel, this.toSample);

                        string[] para = task.Split(new char[] { ' ' });
                        // TODO very error prone..
                        ConfigurationPrinter printer = new ConfigurationPrinter(para[0], para[1], para[2], GlobalState.optionOrder);
                        printer.print(configs);

                        break;
                    }
                case COMMAND_SAMPLE_BINARY_RANDOM:
                    {
                        string[] para = task.Split(new char[] { ' ' });
                        ConfigurationBuilder.binaryThreshold = Convert.ToInt32(para[0]);
                        ConfigurationBuilder.binaryModulu = Convert.ToInt32(para[1]);

                        VariantGenerator vg = new VariantGenerator(null);
                        if (taskAsParameter.Contains(COMMAND_VALIDATION))
                        {
                            this.toSampleValidation.Add(SamplingStrategies.BINARY_RANDOM);
                            this.exp.info.binarySamplings_Validation = "BINARY_RANDOM";
                        }
                        else
                        {
                            this.toSample.Add(SamplingStrategies.BINARY_RANDOM);
                            this.exp.info.binarySamplings_Learning = "BINARY_RANDOM " + task;
                        }
                        break;
                    }
                case COMMAND_START_LEARNING:
                    {
                        InfluenceModel infMod = new InfluenceModel(GlobalState.varModel, GlobalState.currentNFP);
                        List<Configuration> configurationsLearning = buildSet(this.toSample);
                        List<Configuration> configurationsValidation = buildSet(this.toSampleValidation);

                        if (configurationsLearning.Count == 0)
                        {
                            configurationsLearning = configurationsValidation;
                        }

                        if (configurationsLearning.Count == 0)
                        {
                            GlobalState.logInfo.logLine("The learning set is empty! Cannot start learning!");
                            break;
                        }

                        if (configurationsValidation.Count == 0)
                        {
                            configurationsValidation = configurationsLearning;
                        }

                        GlobalState.logInfo.logLine("Learning: " + "NumberOfConfigurationsLearning:" + configurationsLearning.Count + " NumberOfConfigurationsValidation:" + configurationsValidation.Count);
                        //+ " UnionNumberOfConfigurations:" + (configurationsLearning.Union(configurationsValidation)).Count()); too costly to compute

                        // We have to reuse the list of models because of NotifyCollectionChangedEventHandlers that might be attached to the list of models.
                        exp.models.Clear();
                        var mod = exp.models;
                        exp = new MachineLearning.Learning.Regression.Learning(configurationsLearning, configurationsValidation);
                        exp.models = mod;

                        exp.metaModel = infMod;
                        exp.mLsettings = this.mlSettings;
                        exp.learn();
                        GlobalState.logInfo.logLine("Average model: \n" + exp.metaModel.printModelAsFunction());
                        double relativeError = 0;
                        if (GlobalState.evalutionSet.Configurations.Count > 0)
                        {
                            relativeError = FeatureSubsetSelection.computeError(exp.metaModel, GlobalState.evalutionSet.Configurations, ML_Settings.LossFunction.RELATIVE);
                        }
                        else
                        {
                            relativeError = FeatureSubsetSelection.computeError(exp.metaModel, GlobalState.allMeasurements.Configurations, ML_Settings.LossFunction.RELATIVE);
                        }

                        GlobalState.logInfo.logLine("Error :" + relativeError);
                    }
                    break;

                case COMMAND_SAMPLE_NEGATIVE_OPTIONWISE:
                    // TODO there are two different variants in generating NegFW configurations.

                    if (taskAsParameter.Contains(COMMAND_VALIDATION))
                    {
                        this.toSampleValidation.Add(SamplingStrategies.NEGATIVE_OPTIONWISE);
                        this.exp.info.binarySamplings_Validation = "NEGATIVE_OPTIONWISE";
                    }
                    else
                    {
                        this.toSample.Add(SamplingStrategies.NEGATIVE_OPTIONWISE);
                        this.exp.info.binarySamplings_Learning = "NEGATIVE_OPTIONWISE";
                    }
                    break;
                default:
                    return command;
            }
            return "";
        }
        internal void loadFromXML(XmlElement node)
        {
            base.loadFromXML(node);
            foreach (XmlElement xmlInfo in node.ChildNodes)
            {
                switch (xmlInfo.Name)
                {
                    case "minValue":
                        this.min_value = Double.Parse(xmlInfo.InnerText.Replace(',', '.'));
                        break;
                    case "maxValue":
                        this.max_value = Double.Parse(xmlInfo.InnerText.Replace(',', '.'));
                        break;
                    case "defaultValue":
                        this.defaultValue = Double.Parse(xmlInfo.InnerText.Replace(',', '.'));
                        break;
                    case "stepFunction":
                        this.stepFunction = new InfluenceFunction(xmlInfo.InnerText.Replace(',','.'),this);
                        break;
                    case "values":
                        String[] valueArray = xmlInfo.InnerText.Replace(',', '.').Split(';');
                        double[] values_As_Double = new double[valueArray.Count()];
                        for(int i = 0; i < valueArray.Count(); i++){
                            values_As_Double[i] = Convert.ToDouble(valueArray[i]);
                        }
                        this.values = values_As_Double;
                        break;

                }
            }
        }
        /// <summary>
        /// Sets all necessary information and initializes all components.
        /// </summary>
        /// <param name="exp">Loaded expression of the function. Must not be null.</param>
        /// <param name="model">Corresponding variability model of the expression.</param>
        private void loadComponents(string exp, VariabilityModel model)
        {
            if (exp == null)
                throw new ArgumentNullException("Parameter exp may not be null!");
            if (model != null && !checkExpressionCompatibility(exp, model))
            {
                MessageBox.Show(ERROR_EXP_MODEL_INCOMPATIBLE);
                return;
            }

            String optExpression = Regex.Replace(exp, @"\r\n?|\n", "");

            // Test if the loaded expression can be used
            try
            {
                new InfluenceFunction(optExpression);
            } catch
            {
                MessageBox.Show(ERROR_INVALID_EXP);
                return;
            }

            if (originalFunction == null)
                initializeOnce();

            modelLoaded = model != null;
            originalFunction = modelLoaded ? new InfluenceFunction(optExpression, model) : new InfluenceFunction(optExpression);
            currentModel = originalFunction.getVariabilityModel();

            adjustedExpressionTree = originalFunction.getExpressionTree();

            calculateOccurances();

            // Update readFunction-textbox
            getMaxAbstractConstant(originalFunction.ToString());
            updateFunctionTextBox(originalFunctionTextBox, sortExpression(originalFunction.ToString()));

            // Activating all components and returning their original state
            ilFunctionPanel.Scene = new ILScene();
            ilFunctionPanel.Refresh();

            initializeComponents();
            updateAdjustedFunction();
        }
        //public void filterFeatureModelToExpression()
        //{
        //    bool actionDone = true;
        //    List<BinaryOption> featuresToRemove = new List<Element>();
        //    foreach (Element feature in this.fm.getAllElements())
        //    {
        //        if (!this.participatingBoolFeatures.Contains(feature))
        //            featuresToRemove.Add(feature);
        //    }
        //    foreach (Element f in featuresToRemove)
        //        this.fm.removeElement(f);
        //    List<NumericOption> numOptionsToRemove = new List<NumericOption>();
        //    foreach (NumericOption no in this.fm.numericOptions)
        //    {
        //        if (!this.participatingNumFeatures.Contains(no))
        //            numOptionsToRemove.Add(no);
        //    }
        //    foreach (NumericOption f in numOptionsToRemove)
        //        this.fm.removeNumericOption(f);
        //}
        /// <summary>
        /// Checks using the ToString method whether this InfluenceFunction is equal to another one
        /// </summary>
        /// <param name="other">The other influence function to be compared with</param>
        /// <returns>True if the same, false otherwise</returns>
        public bool Equals(InfluenceFunction other)
        {
            if (other.ToString() == this.ToString())
                return true;

            return false;
        }
        internal bool containsParent(InfluenceFunction featureToAdd)
        {
            foreach (BinaryOption binOpt in featureToAdd.participatingBoolOptions)
            {
                if (this.participatingBoolOptions.Contains(binOpt))
                    return true;
                BinaryOption parent = (BinaryOption) binOpt.Parent;
                while (parent != null && parent != varModel.Root)
                {
                    if (this.participatingBoolOptions.Contains(parent))
                        return true;
                    parent = (BinaryOption) parent.Parent;
                }
            }

            return false;
        }
        private double evaluationOfRPN(Configuration config)
        {
            int counter = 0;

            Stack <double> stack = new Stack <double>();

            if (expressionArray.Length == 0)
            {
                return(1);
            }

            while (counter < expressionArray.Length)
            {
                string curr = expressionArray[counter];
                counter++;

                if (!InfluenceFunction.isOperatorEval(curr))
                {
                    stack.Push(getValueOfToken(config, curr, varModel));
                }
                else
                {
                    if (curr.Equals("+"))
                    {
                        double rightHandSide = stack.Pop();
                        if (stack.Count == 0)
                        {
                            stack.Push(rightHandSide);
                        }
                        double leftHandSide = stack.Pop();
                        if (counter < expressionArray.Length && expressionArray[counter].Equals("-"))
                        {
                            stack.Push(leftHandSide - rightHandSide);
                        }
                        else
                        {
                            stack.Push(leftHandSide + rightHandSide);
                        }
                    }
                    if (curr.Equals("-"))
                    {
                        double rightHandSide = stack.Pop();
                        if (stack.Count == 0)
                        {
                            stack.Push(rightHandSide);
                        }
                        double leftHandSide = stack.Pop();
                        if (counter < expressionArray.Length && expressionArray[counter].Equals("-"))
                        {
                            stack.Push(leftHandSide + rightHandSide);
                        }
                        else
                        {
                            stack.Push(leftHandSide - rightHandSide);
                        }
                    }
                    if (curr.Equals("*"))
                    {
                        double rightHandSide = stack.Pop();
                        double leftHandSide  = stack.Pop();
                        stack.Push(leftHandSide * rightHandSide);
                    }
                    if (curr.Equals("/"))
                    {
                        double rightHandSide = stack.Pop();
                        double leftHandSide  = stack.Pop();
                        if (leftHandSide == 0.0 || rightHandSide == 0.0)
                        {
                            stack.Push(0.0);
                        }
                        else
                        {
                            stack.Push(leftHandSide / rightHandSide);
                        }
                    }
                    if (curr.Equals("]"))
                    {
                        double leftHandSide = stack.Pop();
                        if (leftHandSide == 0.0)
                        {
                            GlobalState.logError.log("part of the performance-influence model leads to a NegativeInfinity (compute log(0)) ");
                            stack.Push(0.0);
                        }
                        else
                        {
                            stack.Push(Math.Log(leftHandSide, 10.0));
                        }
                    }
                }
            }

            return(stack.Pop());
        }
        private void parseExpressionToPolnishNotation(String expression)
        {
            Queue <string> queue = new Queue <string>();
            Stack <string> stack = new Stack <string>();

            expression = createWellFormedExpression(expression).Trim();
            this.wellFormedExpression = expression;
            string[] expr = expression.Split(' ');

            for (int i = 0; i < expr.Length; i++)
            {
                string token = expr[i];


                if (InfluenceFunction.isOperator(token))
                {
                    if (stack.Count > 0)
                    {
                        while (stack.Count > 0 && InfluenceFunction.isOperator(stack.Peek()) && InfluenceFunction.operatorHasGreaterPrecedence(stack.Peek(), token))
                        {
                            queue.Enqueue(stack.Pop());
                        }
                    }
                    stack.Push(token);
                    continue;
                }
                else if (token.Equals("("))
                {
                    stack.Push(token);
                }
                else if (token.Equals("["))
                {
                    stack.Push(token);
                }
                else if (token.Equals("{"))
                {
                    stack.Push(token);
                }
                else if (token.Equals("<"))
                {
                    stack.Push(token);
                }

                else if (token.Equals(")"))
                {
                    while (!stack.Peek().Equals("("))
                    {
                        queue.Enqueue(stack.Pop());
                    }
                    stack.Pop();
                    continue;
                }

                else if (token.Equals("]"))
                {
                    while (!stack.Peek().Equals("["))
                    {
                        queue.Enqueue(stack.Pop());
                    }
                    queue.Enqueue("]");
                    stack.Pop();
                    continue;
                }
                // token is number or a feature which has a value
                // features existing in the function but not in the feature model, have to be accepted too
                tokenIsAFeatureOrNumber(token, this.varModel);
                queue.Enqueue(token);
            }

            // stack abbauen
            while (stack.Count > 0)
            {
                queue.Enqueue(stack.Pop());
            }
            expressionArray = queue.ToArray();
        }
 internal void loadFromXML(XmlElement node)
 {
     base.loadFromXML(node);
     foreach (XmlElement xmlInfo in node.ChildNodes)
     {
         switch (xmlInfo.Name)
         {
             case "minValue":
                 this.min_value = Double.Parse(xmlInfo.InnerText.Replace(',', '.'));
                 break;
             case "maxValue":
                 this.max_value = Double.Parse(xmlInfo.InnerText.Replace(',', '.'));
                 break;
             case "defaultValue":
                 this.defaultValue = Double.Parse(xmlInfo.InnerText.Replace(',', '.'));
                 break;
             case "stepFunction":
                 this.stepFunction = new InfluenceFunction(xmlInfo.InnerText.Replace(',','.'),this);
                 break;
         }
     }
 }