Beispiel #1
0
        public override List <TmsConstraint> GetTmsConstraints(ConfigurationConstraint constraint, Edge edge)
        {
            List <TmsConstraint> result    = new List <TmsConstraint>();
            RelationFamily       relFamily = constraint.AllowedRelations[0].RelationFamily;

            if (!(edge is MetricEdge))
            {
                edge.Network.SturcturalReasonerLog.AddItem(LogType.Warning, string.Format("Edge {0} is not a metric edge. The requested TMS constraints will not be added.", edge.GetUId()));
            }
            else if (!edge.Constraints.Contains(constraint))
            {
                edge.Network.SturcturalReasonerLog.AddItem(LogType.Warning, string.Format("The constraint {0} is not found in the edge {1}. The requested TMS constraints will not be added.", constraint.DomainConstraint.Name, edge.GetUId()));
            }
            else if (relFamily != StructuralRelationsManager.GetRelationFamily(RelationFamilyNames.MetricRelationsName))
            {
                edge.Network.SturcturalReasonerLog.AddItem(LogType.Warning, string.Format("The constraint {0} is qualitative while the needed relation for edge {1} is metric. The requested TMS constraints will not be added.", constraint.DomainConstraint.Name, edge.GetUId()));
            }
            else
            {
                string        dVarA         = edge.EndNode.GetDVarName();
                string        dVarMetric    = (constraint.RelationParts[1] as MetricRelationPart).GetDVarName();
                TmsConstraint tmsConstraint = new TmsConstraint();

                tmsConstraint.ConstraintType = TmsManager.CTNameGreaterThan;
                tmsConstraint.VariableTuple  = new List <string>()
                {
                    dVarA, dVarMetric, constraint.GetSatDVarName()
                };

                result.Add(tmsConstraint);
            }

            return(result);
        }
Beispiel #2
0
        /// <summary>
        /// Cretes a new domain constraint which constraints the possible relations between the matched components.
        /// If only one relation is given as parameter it will be treaten as required.
        /// If a list is given, then one of the relations must hold (not all).
        /// All of the relations must be from the same relation family.
        /// </summary>
        /// <param name="name">The unique name of the domain constraint.</param>
        /// <param name="allowedRelations">The list of allowed relations between the components. It is an OR list.</param>
        /// <param name="canBeViolated">Set to true for soft constraint, false for hard constraint</param>
        public DomainConstraint(string name, List <BinaryRelation> allowedRelations, bool canBeViolated)
        {
            this.DomainRelationParts = new List <IDomainRelationPart>();
            this.allowedRelations    = new List <BinaryRelation>();

            // Check if more than one relation families or relation without family exist in the list, which is prohibited
            if (allowedRelations.Any(x => x.RelationFamily == null) || allowedRelations.GroupBy(x => x.RelationFamily).Count() > 1)
            {
                throw new ArgumentException("All relations must be from the same relation family!");
            }
            if (allowedRelations.Count > 1 && allowedRelations[0].RelationFamily == StructuralRelationsManager.GetRelationFamily(RelationFamilyNames.MetricRelationsName))
            {
                throw new ArgumentException("Metric relations cannot be used in a combination (no ORs)!");
            }
            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentNullException("The name of the domain constraint is required!");
            }
            else
            {
                this.allowedRelations = allowedRelations;
                this.Name             = name;
                this.CanBeViolated    = canBeViolated;
            }
        }
Beispiel #3
0
        private void CreateNoGapsConstr()
        {
            string           domainConstraintName = "No position gaps";
            BinaryRelation   relation;
            ComponentFilter  comp1Filter;
            GKOAttribute     attribute;
            DomainConstraint domConstraint;

            // For all components / no filter
            comp1Filter = new ComponentFilter()
            {
                Filter = null,
                ComponentTypeFilter = null
            };
            // For the "Position" attribute
            attribute = this.KnowledgeBase.Attributes[7];
            // Less than relations must apply
            relation = StructuralRelationsManager.GetRelation(RelationFamilyNames.MetricRelationsName, MetricRelationNames.LessOrEqualsN);

            // Creating the domain constraint
            domConstraint = new DomainConstraint(domainConstraintName, relation, false);
            domConstraint.DomainRelationParts.Add(new AttributeDomainRelationPart(comp1Filter, attribute));
            domConstraint.DomainRelationParts.Add(new MetricDomainRelationPart(SpecialMetricValue.ComponentsCount));

            this.DomainConstraints.Add(domConstraint);
        }
Beispiel #4
0
        private void CreateDifferentPositionsConstr()
        {
            string           domainConstraintName = "All with different positions";
            BinaryRelation   relation;
            ComponentFilter  comp1Filter;
            ComponentFilter  comp2Filter;
            GKOAttribute     attribute;
            DomainConstraint domConstraint;

            // For all components / no filter
            comp1Filter = new ComponentFilter()
            {
                Filter = null,
                ComponentTypeFilter = null
            };
            comp2Filter = new ComponentFilter()
            {
                Filter = null,
                ComponentTypeFilter = null
            };
            // For the "Position" attribute
            attribute = this.KnowledgeBase.Attributes[7];
            // Not equals relations must apply
            relation = StructuralRelationsManager.GetRelation(RelationFamilyNames.MetricRelationsName, MetricRelationNames.NotEquals);

            // Creating the domain constraint
            domConstraint = new DomainConstraint(domainConstraintName, relation, false);
            domConstraint.DomainRelationParts.Add(new AttributeDomainRelationPart(comp1Filter, attribute));
            domConstraint.DomainRelationParts.Add(new AttributeDomainRelationPart(comp2Filter, attribute));

            this.DomainConstraints.Add(domConstraint);
        }
Beispiel #5
0
        /// <summary>
        /// Creates a domain constraint restricting an attribute to be greater than the MetricDomain max value - 1
        /// </summary>
        /// <returns></returns>
        public static DomainConstraint MaxValueConstraint(GKOAttribute attribute, GKOIntDomain metricDomain)
        {
            BinaryRelation   lessOrEquals  = StructuralRelationsManager.GetRelation(RelationFamilyNames.MetricRelationsName, MetricRelationNames.LessOrEqualsN);
            DomainConstraint maxConstraint = new DomainConstraint("Metric max value constraint", lessOrEquals, false);

            maxConstraint.DomainRelationParts.Add(new AttributeDomainRelationPart(new ComponentFilter(), attribute));
            maxConstraint.DomainRelationParts.Add(new MetricDomainRelationPart(metricDomain.MaxValue, metricDomain));

            return(maxConstraint);
        }
Beispiel #6
0
        private void Create6thBefore10th()
        {
            string           domainConstraintName = "Every 6th Before every 10th";
            BinaryRelation   relation;
            ComponentFilter  comp1Filter;
            ComponentFilter  comp2Filter;
            GKOAttribute     attribute;
            DomainConstraint domConstraint;

            // For all components / no filter
            comp1Filter = new ComponentFilter()
            {
                Filter = null,
                ComponentTypeFilter = null,
                AttributeFilters    = new List <AttributeFilter>()
                {
                    new AttributeFilter(this.KnowledgeBase.Attributes[3], new List <string>()
                    {
                        true.ToString()
                    })
                }
            };
            comp2Filter = new ComponentFilter()
            {
                Filter = null,
                ComponentTypeFilter = null,
                AttributeFilters    = new List <AttributeFilter>()
                {
                    new AttributeFilter(this.KnowledgeBase.Attributes[0], new List <string>()
                    {
                        true.ToString()
                    }),
                    new AttributeFilter(this.KnowledgeBase.Attributes[2], new List <string>()
                    {
                        true.ToString()
                    }),
                }
            };
            // For the "Position" attribute
            attribute = this.KnowledgeBase.Attributes[7];
            // Not equals relations must apply
            relation = StructuralRelationsManager.GetRelation(RelationFamilyNames.MetricRelationsName, MetricRelationNames.GreaterThan);

            // Creating the domain constraint
            domConstraint = new DomainConstraint(domainConstraintName, relation, false);
            domConstraint.DomainRelationParts.Add(new AttributeDomainRelationPart(comp1Filter, attribute));
            domConstraint.DomainRelationParts.Add(new AttributeDomainRelationPart(comp2Filter, attribute));
            //domConstraint.DomainRelationParts.Add(new MetricDomainRelationPart(SpecialMetricValue.ComponentsCount));

            this.DomainConstraints.Add(domConstraint);
        }
Beispiel #7
0
        /// <summary>
        /// Creates a domain constraint restricting the start of an interval to be before (or equal) to its end
        /// </summary>
        /// <param name="startAttribute">The start of interval attribute </param>
        /// <param name="endAttribute">The end of interval attribute </param>
        /// <param name="allowZeroIntervals">Specifies whether to use "Less than" or "Less or equals" relations, which enables/disables the generation of zero-length intervals</param>
        /// <returns></returns>
        public static DomainConstraint IntervalStartBeforeEndConstraint(GKOAttribute startAttribute, GKOAttribute endAttribute, bool allowZeroIntervals)
        {
            BinaryRelation   relation           = StructuralRelationsManager.GetRelation(RelationFamilyNames.MetricRelationsName, allowZeroIntervals ? MetricRelationNames.LessOrEquals : MetricRelationNames.LessThan);
            DomainConstraint intervalConstraint = new DomainConstraint("Interval start/end constraint", relation, false);

            intervalConstraint.DomainRelationParts.Add(new AttributeDomainRelationPart(new ComponentFilter(), startAttribute));
            intervalConstraint.DomainRelationParts.Add(new AttributeDomainRelationPart(
                                                           new ComponentFilter()
            {
                SameAsDomainRelationPartNr = 1
            },
                                                           endAttribute));

            return(intervalConstraint);
        }
Beispiel #8
0
        /// <summary>
        /// Loads the relevant constraint types information
        /// </summary>
        private void CreateConstraintTypes()
        {
            Stopwatch stopwatch         = new Stopwatch();
            int       maxRelationsCount = StructuralRelationsManager.RelationFamilies.Where(x => x != StructuralRelationsManager.MetricRelationsFamily).Max(x => x.Relations.Count);

            this.ConstraintTypes = new Dictionary <string, IConstraintType>();

            stopwatch.Start();
            CreateMetricRelConstrTypes();
            stopwatch.Stop();

            log.AddItem(LogType.Info, String.Format("Generating metric constraint types for the TMS finished ({0} ms)", stopwatch.ElapsedMilliseconds));

            stopwatch.Restart();
            CreateIndividualCTForDomain(this.BoolDomain, false);
            //CreateIndividualCTForDomain(this.CalculiPwSetIxDomain);
            CreateIndividualCTForDomain(this.MetricDomain, false);
            StructuralRelationsManager.CalculiDomains.ForEach(x => CreateIndividualCTForDomain(x, true));
            for (int i = 0; i < Math.Max(maxRelationsCount, StructuralReasonerOptions.DomainConstraintMaximumBranches); i++)
            {
                // Exactly-one-of constraint is used for the calculi and domain constraint combinations
                CreateExactlyOneCT(i + 1);
                // And and Or constraints are used for domain constraint combinations
                if (i < StructuralReasonerOptions.DomainConstraintMaximumBranches)
                {
                    CreateAndCT(i + 1);
                    CreateOrCT(i + 1);
                }
            }
            stopwatch.Stop();

            log.AddItem(LogType.Info, String.Format("Generating 'domains single value', 'and', 'or' and 'exactly one holds' constraint types for the TMS finished ({0} ms)", stopwatch.ElapsedMilliseconds));

            stopwatch.Restart();
            StructuralRelationsManager.GenerateCompositionConstraintTypes().ForEach(x => this.ConstraintTypes.Add(x.Name, x.CreateIConstraintType(cdaStarTms, this.Domains)));
            stopwatch.Stop();

            log.AddItem(LogType.Info, String.Format("Generating qualitative calculi composition constraint types for the TMS finished ({0} ms)", stopwatch.ElapsedMilliseconds));

            //stopwatch.Restart();
            //foreach (var calculus in StructuralRelationsManager.RelationFamilies.Where(x => x != StructuralRelationsManager.MetricRelationsFamily ))
            //{
            //    CreateCTForPowerset(calculus);
            //}

            //stopwatch.Stop();
            //log.AddItem(LogType.Info, String.Format("Generating powerset qualitative calculi constraint types for the TMS finished ({0} ms)", stopwatch.ElapsedMilliseconds));
        }
Beispiel #9
0
        public ConfigurationConstraint GetInverseConstraint(ConfigurationConstraint constraint)
        {
            ConfigurationConstraint inverseConstraint = new ConfigurationConstraint(constraint.DomainConstraint);
            List <IRelationPart>    relationParts     = new List <IRelationPart>();

            inverseConstraint.AllowedRelations = new List <BinaryRelation>()
            {
                StructuralRelationsManager.GetRelation(RelationFamilyNames.MetricRelationsName, MetricRelationNames.GreaterOrEquals)
            };

            relationParts.Add(constraint.RelationParts[1]);
            relationParts.Add(constraint.RelationParts[0]);

            inverseConstraint.SetRelationParts(relationParts);

            return(inverseConstraint);
        }
Beispiel #10
0
        public DomainConstraint TransformConstraint()
        {
            DomainConstraint    metricDomainConstraint = null;
            QualitativeRelation requiredRelation       = this.allowedRelations[0] as QualitativeRelation;

            // The metric relations that might be needed
            BinaryRelation lessThanRelation    = StructuralRelationsManager.GetRelation(RelationFamilyNames.MetricRelationsName, MetricRelationNames.LessThan);
            BinaryRelation greaterThanRelation = StructuralRelationsManager.GetRelation(RelationFamilyNames.MetricRelationsName, MetricRelationNames.GreaterThan);
            BinaryRelation equalsRelation      = StructuralRelationsManager.GetRelation(RelationFamilyNames.MetricRelationsName, MetricRelationNames.Equals);

            switch (requiredRelation.Name)
            {
            case PointsAlgebraRelationNames.After:
                // A After B	 |  A.Attr > B.Attr
                metricDomainConstraint = new DomainConstraint(this.Name, greaterThanRelation, this.CanBeViolated);
                break;

            case PointsAlgebraRelationNames.Before:
                // A Before B	 |  A.Attr < B.Attr
                metricDomainConstraint = new DomainConstraint(this.Name, lessThanRelation, this.CanBeViolated);
                break;

            case PointsAlgebraRelationNames.Equals:
                // A Equals B	 |  A.Attr = B.Attr
                metricDomainConstraint = new DomainConstraint(this.Name, equalsRelation, this.CanBeViolated);
                break;
            }

            // Setting the relation parts
            if (metricDomainConstraint != null)
            {
                AttributeDomainRelationPart attrComp1Part = this.GenerateRelationPart(this.DomainRelationParts[0], this.Comp1Attribute);
                AttributeDomainRelationPart attrComp2Part = this.GenerateRelationPart(this.DomainRelationParts[1], this.Comp2Attribute);

                metricDomainConstraint.DomainRelationParts = new List <IDomainRelationPart>()
                {
                    attrComp1Part, attrComp2Part
                };
            }

            return(metricDomainConstraint);
        }
        public DomainConstraint TransformConstraint()
        {
            List <DomainConstraint> metricDomainConstraints = new List <DomainConstraint>();
            DomainConstraint        constr1          = null;
            DomainConstraint        constr2          = null;
            QualitativeRelation     requiredRelation = this.allowedRelations[0] as QualitativeRelation;

            // The metric relations that might be needed
            BinaryRelation lessThanRelation    = StructuralRelationsManager.GetRelation(RelationFamilyNames.MetricRelationsName, MetricRelationNames.LessThan);
            BinaryRelation greaterThanRelation = StructuralRelationsManager.GetRelation(RelationFamilyNames.MetricRelationsName, MetricRelationNames.GreaterThan);
            BinaryRelation equalsRelation      = StructuralRelationsManager.GetRelation(RelationFamilyNames.MetricRelationsName, MetricRelationNames.Equals);

            // The attribute domain relation parts that might be needed
            AttributeDomainRelationPart attrComp1IntervalStart = this.GenerateRelationPart(this.DomainRelationParts[0], this.Comp1IntervalStart);
            AttributeDomainRelationPart attrComp1IntervalEnd   = this.GenerateRelationPart(this.DomainRelationParts[0], this.Comp1IntervalEnd);
            AttributeDomainRelationPart attrComp2IntervalStart = this.GenerateRelationPart(this.DomainRelationParts[1], this.Comp2IntervalStart);
            AttributeDomainRelationPart attrComp2IntervalEnd   = this.GenerateRelationPart(this.DomainRelationParts[1], this.Comp2IntervalEnd);

            #region IA to Metric
            switch (requiredRelation.Name)
            {
            case IntervalAlgebraRelationNames.After:
                // A After B	 |  A.Start > B.End
                constr1 = new DomainConstraint(this.Name, greaterThanRelation, this.CanBeViolated);
                constr1.DomainRelationParts = new List <IDomainRelationPart>()
                {
                    attrComp1IntervalStart, attrComp2IntervalEnd
                };

                metricDomainConstraints.Add(constr1);
                break;

            case IntervalAlgebraRelationNames.Before:
                // A Before B
                //      A.End < B.Start
                constr1 = new DomainConstraint(this.Name, lessThanRelation, this.CanBeViolated);
                constr1.DomainRelationParts = new List <IDomainRelationPart>()
                {
                    attrComp1IntervalEnd, attrComp2IntervalStart
                };

                metricDomainConstraints.Add(constr1);
                break;

            case IntervalAlgebraRelationNames.During:
                // A During B
                //      A.Start > B.Start
                //      A.End < B.End
                constr1 = new DomainConstraint(this.Name + "_part1", greaterThanRelation, this.CanBeViolated);
                constr1.DomainRelationParts = new List <IDomainRelationPart>()
                {
                    attrComp1IntervalStart, attrComp2IntervalStart
                };
                constr2 = new DomainConstraint(this.Name + "_part2", lessThanRelation, this.CanBeViolated);
                constr2.DomainRelationParts = new List <IDomainRelationPart>()
                {
                    attrComp1IntervalEnd, attrComp2IntervalEnd
                };

                metricDomainConstraints.Add(constr1);
                metricDomainConstraints.Add(constr2);
                break;

            case IntervalAlgebraRelationNames.Equals:
                // A Equals B
                //      A.Start = B.Start
                //      A.End = B.End
                constr1 = new DomainConstraint(this.Name + "_part1", equalsRelation, this.CanBeViolated);
                constr1.DomainRelationParts = new List <IDomainRelationPart>()
                {
                    attrComp1IntervalStart, attrComp2IntervalStart
                };
                constr2 = new DomainConstraint(this.Name + "_part2", equalsRelation, this.CanBeViolated);
                constr2.DomainRelationParts = new List <IDomainRelationPart>()
                {
                    attrComp1IntervalEnd, attrComp2IntervalEnd
                };

                metricDomainConstraints.Add(constr1);
                metricDomainConstraints.Add(constr2);
                break;

            case IntervalAlgebraRelationNames.FinishedBy:
                // A Finished-by B
                //      A.End = B.End
                //      A.Start < B.Start
                constr1 = new DomainConstraint(this.Name + "_part1", equalsRelation, this.CanBeViolated);
                constr1.DomainRelationParts = new List <IDomainRelationPart>()
                {
                    attrComp1IntervalEnd, attrComp2IntervalEnd
                };
                constr2 = new DomainConstraint(this.Name + "_part2", lessThanRelation, this.CanBeViolated);
                constr2.DomainRelationParts = new List <IDomainRelationPart>()
                {
                    attrComp1IntervalStart, attrComp2IntervalStart
                };

                metricDomainConstraints.Add(constr1);
                metricDomainConstraints.Add(constr2);
                break;

            case IntervalAlgebraRelationNames.Finishes:
                // A Finishes B
                //      A.End = B.End
                //      A.Start > B.Start
                constr1 = new DomainConstraint(this.Name + "_part1", equalsRelation, this.CanBeViolated);
                constr1.DomainRelationParts = new List <IDomainRelationPart>()
                {
                    attrComp1IntervalEnd, attrComp2IntervalEnd
                };
                constr2 = new DomainConstraint(this.Name + "_part2", greaterThanRelation, this.CanBeViolated);
                constr2.DomainRelationParts = new List <IDomainRelationPart>()
                {
                    attrComp1IntervalStart, attrComp2IntervalStart
                };

                metricDomainConstraints.Add(constr1);
                metricDomainConstraints.Add(constr2);
                break;

            case IntervalAlgebraRelationNames.Includes:
                // A Includes B
                //      A.Start < B.Start
                //      A.End > B.End
                constr1 = new DomainConstraint(this.Name + "_part1", lessThanRelation, this.CanBeViolated);
                constr1.DomainRelationParts = new List <IDomainRelationPart>()
                {
                    attrComp1IntervalStart, attrComp2IntervalStart
                };
                constr2 = new DomainConstraint(this.Name + "_part2", greaterThanRelation, this.CanBeViolated);
                constr2.DomainRelationParts = new List <IDomainRelationPart>()
                {
                    attrComp1IntervalEnd, attrComp2IntervalEnd
                };

                metricDomainConstraints.Add(constr1);
                metricDomainConstraints.Add(constr2);
                break;

            case IntervalAlgebraRelationNames.Meets:
                // A Meets B
                //      A.End = B.Start
                constr1 = new DomainConstraint(this.Name, equalsRelation, this.CanBeViolated);
                constr1.DomainRelationParts = new List <IDomainRelationPart>()
                {
                    attrComp1IntervalEnd, attrComp2IntervalStart
                };

                metricDomainConstraints.Add(constr1);
                break;

            case IntervalAlgebraRelationNames.MetBy:
                // A Met-by B
                //      A.Start = B.End
                constr1 = new DomainConstraint(this.Name, equalsRelation, this.CanBeViolated);
                constr1.DomainRelationParts = new List <IDomainRelationPart>()
                {
                    attrComp1IntervalStart, attrComp2IntervalEnd
                };

                metricDomainConstraints.Add(constr1);
                break;

            case IntervalAlgebraRelationNames.OverlappedBy:
                // A Overlapped-by B
                //      A.End > B.End
                //      A.Start < B.End
                constr1 = new DomainConstraint(this.Name + "_part1", greaterThanRelation, this.CanBeViolated);
                constr1.DomainRelationParts = new List <IDomainRelationPart>()
                {
                    attrComp1IntervalEnd, attrComp2IntervalEnd
                };
                constr2 = new DomainConstraint(this.Name + "_part2", lessThanRelation, this.CanBeViolated);
                constr2.DomainRelationParts = new List <IDomainRelationPart>()
                {
                    attrComp1IntervalStart, attrComp2IntervalEnd
                };

                metricDomainConstraints.Add(constr1);
                metricDomainConstraints.Add(constr2);
                break;

            case IntervalAlgebraRelationNames.Overlaps:
                // A Overlaps B
                //      A.End < B.End
                //      A.End > B.Start
                constr1 = new DomainConstraint(this.Name + "_part1", lessThanRelation, this.CanBeViolated);
                constr1.DomainRelationParts = new List <IDomainRelationPart>()
                {
                    attrComp1IntervalEnd, attrComp2IntervalEnd
                };
                constr2 = new DomainConstraint(this.Name + "_part2", greaterThanRelation, this.CanBeViolated);
                constr2.DomainRelationParts = new List <IDomainRelationPart>()
                {
                    attrComp1IntervalEnd, attrComp2IntervalStart
                };

                metricDomainConstraints.Add(constr1);
                metricDomainConstraints.Add(constr2);
                break;

            case IntervalAlgebraRelationNames.StartedBy:
                // A Started-by B
                //      A.Start = B.Start
                //      A.End > B.End
                constr1 = new DomainConstraint(this.Name + "_part1", equalsRelation, this.CanBeViolated);
                constr1.DomainRelationParts = new List <IDomainRelationPart>()
                {
                    attrComp1IntervalStart, attrComp2IntervalStart
                };
                constr2 = new DomainConstraint(this.Name + "_part2", greaterThanRelation, this.CanBeViolated);
                constr2.DomainRelationParts = new List <IDomainRelationPart>()
                {
                    attrComp1IntervalEnd, attrComp2IntervalEnd
                };

                metricDomainConstraints.Add(constr1);
                metricDomainConstraints.Add(constr2);
                break;

            case IntervalAlgebraRelationNames.Starts:
                //A Starts B
                //    A.Start = B.Start
                //    A.End < B.End
                constr1 = new DomainConstraint(this.Name + "_part1", equalsRelation, this.CanBeViolated);
                constr1.DomainRelationParts = new List <IDomainRelationPart>()
                {
                    attrComp1IntervalStart, attrComp2IntervalStart
                };
                constr2 = new DomainConstraint(this.Name + "_part2", lessThanRelation, this.CanBeViolated);
                constr2.DomainRelationParts = new List <IDomainRelationPart>()
                {
                    attrComp1IntervalEnd, attrComp2IntervalEnd
                };

                metricDomainConstraints.Add(constr1);
                metricDomainConstraints.Add(constr2);
                break;
            }
            #endregion

            if (metricDomainConstraints.Count == 0)
            {
                // The mapping was not found so return null
                return(null);
            }
            else if (metricDomainConstraints.Count == 1)
            {
                // If only one domain constraint can represent the IA then just return it
                return(metricDomainConstraints[0]);
            }
            else
            {
                // If the IA constraint has to be expressed with two metric constraints then use domain constraints combination
                return(new DomainConstraintCombination(this.Name, metricDomainConstraints, DomainConstraintCombinationType.And, this.CanBeViolated));
            }
        }
        /// <summary>
        /// ! Use this only once (not for every relation) per edge constraint !
        /// </summary>
        /// <param name="constraint"></param>
        /// <param name="edge"></param>
        /// <returns></returns>
        public override List <TmsConstraint> GetTmsConstraints(ConfigurationConstraint constraint, Edge edge)
        {
            ////OLD: Rem: Qualitative relations use composition constraints and constraint limiting the allowed relations between components, hence there are no constraints implied by a single relation
            //throw new NotSupportedException("A single qualitative relation do not imply a constraint!");

            List <TmsConstraint> result    = new List <TmsConstraint>();
            RelationFamily       relFamily = constraint.AllowedRelations[0].RelationFamily;

            if (!(edge is QualitativeEdge))
            {
                edge.Network.SturcturalReasonerLog.AddItem(LogType.Warning, string.Format("Edge {0} is not a qualitative edge. The requested TMS constraints will not be added.", edge.GetUId()));
            }
            else if (!edge.Constraints.Contains(constraint))
            {
                edge.Network.SturcturalReasonerLog.AddItem(LogType.Warning, string.Format("The constraint {0} is not found in the edge {1}. The requested TMS constraints will not be added.", constraint.DomainConstraint.Name, edge.GetUId()));
            }
            else if (relFamily == StructuralRelationsManager.GetRelationFamily(RelationFamilyNames.MetricRelationsName))
            {
                edge.Network.SturcturalReasonerLog.AddItem(LogType.Warning, string.Format("The constraint {0} is metric while the needed relation for edge {1} is qualitative. The requested TMS constraints will not be added.", constraint.DomainConstraint.Name, edge.GetUId()));
            }
            else
            {
                QualitativeEdge qualEdge                  = (QualitativeEdge)edge;
                GKODomain       calculusDomain            = StructuralRelationsManager.GetDomain(constraint.AllowedRelations[0].RelationFamily.GetTmsRelationsDomainName());
                TmsConstraint   exactlyOneHoldsConstraint = new TmsConstraint();
                List <string>   relDvars                  = new List <string>(); // holds all relation variables
                GKODomain       boolDomain                = TmsManager.GenerateBoolDomain();
                string          dVarSat = constraint.GetSatDVarName();

                // This will create a constraint saying that the edge dvar is matching the chosen relation and the relation's dvar is TRUE, or if they are not matching and the relation's dvar is FALSE
                foreach (var relation in constraint.AllowedRelations)
                {
                    TmsConstraint tmsConstraint      = new TmsConstraint();
                    string        edgeDVar           = qualEdge.GetDVarName();
                    string        edgeRelDVar        = qualEdge.GetDVarName((QualitativeRelation)relation);
                    string        constraintTypeName = calculusDomain.GetIndividualValueCTName(relation.Name);

                    relDvars.Add(edgeRelDVar);

                    tmsConstraint.ConstraintType = constraintTypeName;
                    tmsConstraint.VariableTuple  = new List <string>()
                    {
                        edgeDVar, edgeRelDVar
                    };

                    result.Add(tmsConstraint);
                }

                // This will create the constraint saying that one of the relation dvars has to be set
                // This works because the calculi are JEPD
                exactlyOneHoldsConstraint.ConstraintType = relDvars.Count.GetExactlyOneCTName();
                exactlyOneHoldsConstraint.VariableTuple  = new List <string>(relDvars);
                exactlyOneHoldsConstraint.VariableTuple.Add(dVarSat);

                // This prohibits the constraint to be violated
                if (!constraint.CanBeViolated)
                {
                    result.Add(TmsConstraint.GenerateSingleValueConstraint(boolDomain, dVarSat, TmsManager.TrueValue));
                }

                result.Add(exactlyOneHoldsConstraint);
            }

            return(result);
        }