private static void RemoveTernaryValuesInconsistentWithBinaryConstraint(TernaryConstraintExpressionSolution constraintExpressionSolution, int variableIndex, DomainRange variableDomain) { var valueSetsToRemove = new List <ValueSet>(); foreach (var valueSet in constraintExpressionSolution.DomainValue.GetSets()) { // Make sure the set does not violate the domain values var variableValue = valueSet.GetAt(variableIndex - 1); if (variableDomain.PossibleValues.All(value => value != variableValue)) { valueSetsToRemove.Add(valueSet); } } if (valueSetsToRemove.Any()) { constraintExpressionSolution.DomainValue.RemoveSets(valueSetsToRemove); } }
/// <summary> /// Build one or more arcs from the ternary constraint expression. /// </summary> /// <remarks> /// There will be more than one arc because binarization of the expression requires introducing an /// encapsulated variable between the two variables involved in the expression. /// </remarks> /// <param name="expressionConstraintNode">Expression constraint abstract syntax tree.</param> /// <returns>One or more arcs.</returns> private IReadOnlyCollection <Arc> BuildTernaryExpression(ConstraintExpressionNode expressionConstraintNode) { var arcAccumulator = new List <Arc>(); if (!expressionConstraintNode.InnerExpression.RightExpression.IsLiteral) { var left = CreateNodeFrom(expressionConstraintNode.InnerExpression.LeftExpression); var right = CreateNodeFrom(expressionConstraintNode.InnerExpression.RightExpression); var encapsulatedVariable = new EncapsulatedVariable("U"); var encapsulatedVariableNode = new EncapsulatedVariableNode(encapsulatedVariable); var arc1 = new Arc(left, encapsulatedVariableNode, new EncapsulatedVariableConnector(left, encapsulatedVariableNode, new EncapsulatedSelector(1))); arcAccumulator.Add(arc1); var arc2 = new Arc(right, encapsulatedVariableNode, new EncapsulatedVariableConnector(encapsulatedVariableNode, right, new EncapsulatedSelector(2))); arcAccumulator.Add(arc2); var ternaryConstraintExpression = new TernaryConstraintExpression(expressionConstraintNode, encapsulatedVariableNode, arc1, arc2); var encapsulatedVariableDomainValue = ComputeEncapsulatedDomain(ternaryConstraintExpression); encapsulatedVariable.DomainValue = encapsulatedVariableDomainValue; var expressionSolution = new TernaryConstraintExpressionSolution(ternaryConstraintExpression, encapsulatedVariableDomainValue); _modelSolverMap.AddTernaryExpressionSolution(expressionSolution); } else { var left = CreateNodeFrom(expressionConstraintNode.InnerExpression.LeftExpression); var encapsulatedVariable = new EncapsulatedVariable("U"); var encapsulatedVariableNode = new EncapsulatedVariableNode(encapsulatedVariable); var arc1 = new Arc(left, encapsulatedVariableNode, new EncapsulatedVariableConnector(left, encapsulatedVariableNode, new EncapsulatedSelector(1))); arcAccumulator.Add(arc1); var ternaryConstraintExpression = new TernaryConstraintExpression(expressionConstraintNode, encapsulatedVariableNode, arc1, arc1); var encapsulatedVariableDomainValue = ComputeEncapsulatedDomain(ternaryConstraintExpression); encapsulatedVariable.DomainValue = encapsulatedVariableDomainValue; var expressionSolution = new TernaryConstraintExpressionSolution(ternaryConstraintExpression, encapsulatedVariableDomainValue); _modelSolverMap.AddTernaryExpressionSolution(expressionSolution); } return(new ReadOnlyCollection <Arc>(arcAccumulator)); }
internal void AddTernaryExpressionSolution(TernaryConstraintExpressionSolution solution) { _ternarySolutions.Add(solution); }