/// <summary> /// Creates a new DomainConstraintCombination /// </summary> /// <param name="name">The unique name of the constraint</param> /// <param name="constraints">The domain constraints for which is the combination.</param> /// <param name="type">The combination type</param> /// <param name="canBeViolated"></param> public DomainConstraintCombination(string name, List <DomainConstraint> constraints, DomainConstraintCombinationType type, bool canBeViolated) : base(name, canBeViolated) { if (constraints == null || constraints.Count < 2) { throw new ArgumentException("Domain constraints combination requires at least two constraints to be set!"); } this.Type = type; this.DomainConstraints = new List <DomainConstraint>(); foreach (var constraint in constraints) { DomainConstraint currConstraint = null; if (constraint is ITransformDomainConstraint) { // The ITransformDomainConstraint has to be translated to normal or combination domain constraint currConstraint = (constraint as ITransformDomainConstraint).TransformConstraint(); } else { currConstraint = constraint; } // All of the included constraints should use the same relation family if (DomainConstraints.Count > 0 && currConstraint.RelationFamily != RelationFamily) { throw new ApplicationException("The combination constraint contains constraints with different relation families."); } this.DomainConstraints.Add(currConstraint); } }
/// <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); }
/// <summary> /// Creates a domain constraint restricting that the self edge of a node is restricted to use the equals relation of the family /// </summary> /// <returns></returns> public static DomainConstraint SelfEqualsConstraint(RelationFamily calculus) { DomainConstraint equalsConstraint = new DomainConstraint("Self equals", calculus.EqualsRelation, false); equalsConstraint.DomainRelationParts.Add(new ComponentDomainRelationPart(new ComponentFilter())); equalsConstraint.DomainRelationParts.Add(new ComponentDomainRelationPart(new ComponentFilter() { SameAsDomainRelationPartNr = 1 })); return(equalsConstraint); }
/// <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); }
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)); } }