/// <summary>
        /// Finds the TMS decision variables needed for the current constraint tree (including branches) which are not part of the utility function.
        /// Note: It DOES generate variables for the included configuration constraints
        /// </summary>
        /// <returns></returns>
        internal List <TmsDecisionVariable> GetNonUtilityDecisionVariables()
        {
            List <TmsDecisionVariable> variables = new List <TmsDecisionVariable>();

            // When the current tree is not the root then add its decision variables as non-utility ones
            if (this.Parent != null)
            {
                List <string>     currentDVarNames = this.GetSatDVarNames();
                GKODomainAbstract boolDomain       = TmsManager.GenerateBoolDomain();

                foreach (var var in currentDVarNames)
                {
                    variables.Add(new TmsDecisionVariable(boolDomain, var));
                }
            }

            // Adding the variables from the branches
            if (this.IsCombination)
            {
                foreach (var branch in this.ConstraintBranches)
                {
                    variables.AddRange(branch.GetNonUtilityDecisionVariables());
                }
            }

            return(TmsDecisionVariable.GetDistinctVariables(variables, false));
        }
        /// <summary>
        /// Generates TmsConstraints for the current constraint tree (including branches).
        /// Note: It does not generate constraints for the included configuration constraints, rather it only deals with branch combination logic
        /// </summary>
        /// <returns></returns>
        public List <TmsConstraint> GenerateTmsConstraints()
        {
            List <TmsConstraint> constraints = new List <TmsConstraint>();

            // Only trees with branches generate constraints. The configuration constraints are not processed in this function
            if (this.IsCombination)
            {
                GKODomainAbstract boolDomain = TmsManager.GenerateBoolDomain();
                IEnumerable <IEnumerable <string> > constraintDescriptions = this.GetSatDVarParts();

                // Adding the constraints from each branch
                foreach (var branch in this.ConstraintBranches)
                {
                    constraints.AddRange(branch.GenerateTmsConstraints());
                }

                // Generating the TMS constraints for the current level
                foreach (var constraintDescription in constraintDescriptions)
                {
                    TmsConstraint constraint      = new TmsConstraint();
                    string        currentDvarName = this.GetSatDVarName(constraintDescription);

                    // The first elements of the constraint are the decision variables of the branches
                    constraint.VariableTuple = constraintDescription.ToList();
                    // The last element is the decision variable of the constraint represented by the current tree
                    constraint.VariableTuple.Add(currentDvarName);

                    switch (this.CombinationType)
                    {
                    case DomainConstraintCombinationType.And:
                        constraint.ConstraintType = constraintDescription.Count().GetAndCTName();
                        break;

                    case DomainConstraintCombinationType.Or:
                        constraint.ConstraintType = constraintDescription.Count().GetOrCTName();
                        break;

                    case DomainConstraintCombinationType.ExactlyOne:
                        constraint.ConstraintType = constraintDescription.Count().GetExactlyOneCTName();
                        break;

                    default:
                        throw new Exception("The chosen constraint combination type is not recognized!");
                    }

                    constraints.Add(constraint);

                    // This prohibits the constraint to be violated if it is hard constraint
                    if (!this.DerivedFrom.CanBeViolated)
                    {
                        constraints.Add(TmsConstraint.GenerateSingleValueConstraint(boolDomain, currentDvarName, TmsManager.TrueValue));
                    }
                }
            }

            return(constraints);
        }
        /// <summary>
        /// Finds the TMS decision variables needed for the current constraint tree (branches are not relevant) which are not part of the utility function.
        /// Note: It DOES generate the satisfaction decision variables for the included configuration constraints
        /// </summary>
        /// <returns></returns>
        internal List <TmsDecisionVariable> GetUtilityDecisionVariables()
        {
            List <TmsDecisionVariable> variables = new List <TmsDecisionVariable>();

            // Only when the current tree is the root its variables are considered utility ones
            if (this.Parent == null)
            {
                List <string>     currentDVarNames = this.GetSatDVarNames();
                GKODomainAbstract boolDomain       = TmsManager.GenerateBoolDomain();

                foreach (var var in currentDVarNames)
                {
                    variables.Add(new TmsDecisionVariable(boolDomain, var)
                    {
                        UtilityFactor = 1
                    });
                }
            }

            return(TmsDecisionVariable.GetDistinctVariables(variables, true));
        }
 /// <summary>
 /// Creates a TMS domain out of the current domain
 /// </summary>
 /// <param name="domain"></param>
 /// <param name="cdaStarTms">The CS3 instance where to create the domain</param>
 /// <returns></returns>
 public static IDomain CreateIDomain(this GKODomainAbstract domain, ICDAStar cdaStarTms)
 {
     return(cdaStarTms.DefDomain(domain.Name, domain.GetValues().ToArray()));
 }
 /// <summary>
 /// Finds the name of the constraint type which includes only one variable from a domain
 /// </summary>
 /// <param name="domain">The domain</param>
 /// <param name="value">The value of the domain which is (the only one) included in the constraint type</param>
 /// <returns>The TMS name of the constraint type</returns>
 public static string GetIndividualValueCTName(this GKODomainAbstract domain, string value)
 {
     return(string.Format("Domain_{0}-val_{1}", domain.Name, value));
 }