internal TernaryConstraintExpression(ConstraintExpressionNode constraintExpressionModel, EncapsulatedVariableNode expressionNode, Arc leftArc, Arc rightArc) { ExpressionNode = constraintExpressionModel; Node = expressionNode; EncapsulatedVariable = expressionNode.Variable; LeftArc = leftArc; RightArc = rightArc; }
private void ProcessSimpleConstraint(ConstraintExpressionNode constraintExpressionNode) { Constraint newConstraint; var lhsExpr = GetExpressionFrom(constraintExpressionNode.InnerExpression.LeftExpression); if (constraintExpressionNode.InnerExpression.RightExpression.IsExpression) { var rhsExpr = GetExpressionFrom(constraintExpressionNode.InnerExpression.RightExpression); newConstraint = CreateConstraintBy(constraintExpressionNode.InnerExpression.Operator, lhsExpr, rhsExpr); } else if (constraintExpressionNode.InnerExpression.RightExpression.InnerExpression is BucketVariableReferenceExpressionNode) { var rhsExpr = GetExpressionFrom(constraintExpressionNode.InnerExpression.RightExpression); newConstraint = CreateConstraintBy(constraintExpressionNode.InnerExpression.Operator, lhsExpr, rhsExpr); } else if (constraintExpressionNode.InnerExpression.RightExpression.IsVariable) { var rhsVariable = GetVariableFrom(constraintExpressionNode.InnerExpression.RightExpression); newConstraint = CreateConstraintBy(constraintExpressionNode.InnerExpression.Operator, lhsExpr, rhsVariable); } else if (constraintExpressionNode.InnerExpression.RightExpression.InnerExpression is BucketVariableReferenceNode) { var rhsVariable = GetVariableFrom(constraintExpressionNode.InnerExpression.RightExpression); newConstraint = CreateConstraintBy(constraintExpressionNode.InnerExpression.Operator, lhsExpr, rhsVariable); } else if (constraintExpressionNode.InnerExpression.RightExpression.InnerExpression is IntegerLiteralNode) { newConstraint = CreateConstraintBy(constraintExpressionNode.InnerExpression.Operator, lhsExpr, Convert.ToInt32(constraintExpressionNode.InnerExpression.RightExpression.GetLiteral())); } else if (constraintExpressionNode.InnerExpression.RightExpression.InnerExpression is ItemNameNode node) { var lhsVariableName = GetVariableNameFrom(constraintExpressionNode.InnerExpression.LeftExpression); var lhsVariable = this.model.GetVariableByName(lhsVariableName); var range = this.valueMapper.GetDomainValueFor(lhsVariable); var modelValue = GetModelValueFrom(node); var solverValue = range.MapTo(modelValue); newConstraint = CreateConstraintBy(constraintExpressionNode.InnerExpression.Operator, lhsExpr, solverValue); } else if (constraintExpressionNode.InnerExpression.RightExpression.InnerExpression is CharacterLiteralNode literalNode) { var lhsVariableName = GetVariableNameFrom(constraintExpressionNode.InnerExpression.LeftExpression); var lhsVariable = this.model.GetVariableByName(lhsVariableName); var range = this.valueMapper.GetDomainValueFor(lhsVariable); var modelValue = GetModelValueFrom(literalNode); var solverValue = range.MapTo(modelValue); newConstraint = CreateConstraintBy(constraintExpressionNode.InnerExpression.Operator, lhsExpr, solverValue); } else { throw new NotImplementedException("Unknown constraint expression."); } this.solver.Add(newConstraint); }
private IReadOnlyCollection <Arc> BuildBinaryExpression(ConstraintExpressionNode expressionConstraintNode) { var left = CreateNodeFrom(expressionConstraintNode.InnerExpression.LeftExpression); if (!expressionConstraintNode.InnerExpression.RightExpression.IsLiteral) { var right = CreateNodeFrom(expressionConstraintNode.InnerExpression.RightExpression); return(new ReadOnlyCollection <Arc>(new[] { new Arc(left, right, CreateConnectorFrom(left, right, CreateConstraintFrom(expressionConstraintNode))) })); } return(new ReadOnlyCollection <Arc>(new[] { new Arc(left, left, CreateConnectorFrom(left, left, CreateConstraintFrom(expressionConstraintNode))) })); }
/// <summary> /// Build one or more arcs as necessary to represent the expression constraint. /// </summary> /// <param name="expressionConstraintNode">Expression constraint node.</param> /// <returns>One or more arcs</returns> internal IReadOnlyCollection <Arc> Build(ConstraintExpressionNode expressionConstraintNode) { switch (expressionConstraintNode.InnerExpression.Operator) { // Ternary operators case OperatorType.Equals: case OperatorType.NotEqual: return(BuildTernaryExpression(expressionConstraintNode)); // Binary operators default: return(BuildBinaryExpression(expressionConstraintNode)); } }
/// <summary> /// Parse the raw constraint expression. /// </summary> /// <param name="rawExpression">Raw constraint expression.</param> internal void ParseUnit(string rawExpression) { if (!string.IsNullOrWhiteSpace(rawExpression)) { var interpreter = new ConstraintExpressionParser(); var parseResult = interpreter.Parse(rawExpression); if (parseResult.Status == ParseStatus.Success) { Node = parseResult.Root; } } else { Node = null; } }
/// <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)); }
private void ProcessConstraint(ConstraintExpressionNode constraintExpressionNode) { var newArcs = _arcBuilder.Build(constraintExpressionNode); _constraintNetwork.AddArc(newArcs); }
internal BinaryConstraintExpression(ConstraintExpressionNode expressionNode) { Node = expressionNode; }
private BinaryConstraintExpression CreateConstraintFrom(ConstraintExpressionNode binaryExpressionNode) { return(new BinaryConstraintExpression(binaryExpressionNode)); }
public virtual object VisitConstraintExpression(ConstraintExpressionNode constraintExpression, object data) { stackMap.Push(constraintExpression); if (constraintExpression.Expression != null) { constraintExpression.Expression.AcceptVisitor(this, data); } stackMap.Pop(); return null; }