private bool ReviseLeft(VariableNode leftNode, VariableNode rightNode, BinaryConstraintExpression expression) { var leftDomainRange = leftNode.Variable.Domain; IReadOnlyCollection <int> rightPossibleValues; if (!expression.Node.InnerExpression.RightExpression.IsLiteral) { rightPossibleValues = rightNode.Variable.Domain.PossibleValues; } else { var lhsVariable = _modelSolverMap.GetModelVariableByName(leftNode.Variable.Name); var range = _valueMapper.GetDomainValueFor(lhsVariable); var modelValue = expression.Node.InnerExpression.RightExpression.GetLiteral(); var solverValue = range.MapTo(modelValue); rightPossibleValues = new ReadOnlyCollection <int>(new List <int> { solverValue }); } var valueEvaluator = new LeftValueEvaluator(rightPossibleValues, expression); var valuesToRemove = new List <int>(); var expressionEvaluator = new ExpressionEvaluator(); foreach (var possibleValue in leftDomainRange.PossibleValues) { var evaluatedPossibleValue = expressionEvaluator.Evaluate(expression.Node.InnerExpression.LeftExpression, possibleValue); if (!valueEvaluator.EvaluateLeft(evaluatedPossibleValue)) { valuesToRemove.Add(possibleValue); } } leftDomainRange.RemoveAll(valuesToRemove); return(valuesToRemove.Any()); }
internal EncapsulatedVariableDomainValue Compute(TernaryConstraintExpression ternaryConstraint) { var valueSetAccumulator = new List <ValueSet>(); var leftSource = ternaryConstraint.GetLeftSource(); var leftPossibleValues = leftSource.PossibleValues; var expression = ternaryConstraint.ExpressionNode; IReadOnlyCollection <int> rightPossibleValues; if (!expression.InnerExpression.RightExpression.IsLiteral) { var rightSource = ternaryConstraint.GetRightSource(); rightPossibleValues = new ReadOnlyCollection <int>(rightSource.PossibleValues.ToList()); } else { var lhsVariable = _modelSolverMap.GetModelVariableByName(leftSource.VariableName); var range = _valueMapper.GetDomainValueFor(lhsVariable); var modelValue = expression.InnerExpression.RightExpression.GetLiteral(); var solverValue = range.MapTo(modelValue); rightPossibleValues = new ReadOnlyCollection <int>(new List <int> { solverValue }); } foreach (var leftPossibleValue in leftPossibleValues) { foreach (var rightPossibleValue in rightPossibleValues) { switch (ternaryConstraint.ExpressionNode.InnerExpression.Operator) { case OperatorType.Equals: if (leftPossibleValue == rightPossibleValue) { if (!expression.InnerExpression.RightExpression.IsLiteral) { var rightSource = ternaryConstraint.GetRightSource(); var valueSet = new ValueSet(new[] { new Value(_modelSolverMap.GetSolverVariableByName(leftSource.VariableName), leftPossibleValue), new Value(_modelSolverMap.GetSolverVariableByName(rightSource.VariableName), rightPossibleValue) }); valueSetAccumulator.Add(valueSet); } else { var valueSet = new ValueSet(new[] { new Value(_modelSolverMap.GetSolverVariableByName(leftSource.VariableName), leftPossibleValue) }); valueSetAccumulator.Add(valueSet); } } break; case OperatorType.NotEqual: if (leftPossibleValue != rightPossibleValue) { if (!expression.InnerExpression.RightExpression.IsLiteral) { var rightSource = ternaryConstraint.GetRightSource(); var valueSet = new ValueSet(new[] { new Value(_modelSolverMap.GetSolverVariableByName(leftSource.VariableName), leftPossibleValue), new Value(_modelSolverMap.GetSolverVariableByName(rightSource.VariableName), rightPossibleValue) }); valueSetAccumulator.Add(valueSet); } else { var valueSet = new ValueSet(new[] { new Value(_modelSolverMap.GetSolverVariableByName(leftSource.VariableName), leftPossibleValue) }); valueSetAccumulator.Add(valueSet); } } break; default: throw new NotImplementedException(); } } } return(new EncapsulatedVariableDomainValue(ternaryConstraint.EncapsulatedVariable, valueSetAccumulator)); }