/// <summary> /// Evaluate the constraint /// </summary> /// <param name="target">The target vector to evaluate.</param> /// <returns></returns> public bool IsValid(Vector target) { if (target == null) { return(false); } return(_constraint.LogicalEvaluate( delegate(ExpressionIdentifier identifier) { Dimension dimension = _dimensions[identifier.Name]; if (dimension.Domain == typeof(int)) { return ExpressionConstant.Constant(target.GetValue <int>((Dimension <int>)dimension)); } else if (dimension.Domain == typeof(bool)) { return ExpressionConstant.Constant(target.GetValue <bool>((Dimension <bool>)dimension)); } else if (dimension.Domain == typeof(string)) { return ExpressionConstant.Constant(target.GetValue <string>((Dimension <string>)dimension)); } else { throw new InvalidOperationException("Invalid type"); } })); }
public override ExpressionConstant Evaluate(Converter <ExpressionIdentifier, ExpressionConstant> convert) { if (_operands.Count >= 3) { throw new InvalidOperationException("Too many operands"); } ExpressionConstant c1 = _operands.Count > 0 ? _operands[0].Evaluate(convert) : null; ExpressionConstant c2 = _operands.Count > 1 ? _operands[1].Evaluate(convert) : null; ExpressionConstant c3 = _operands.Count > 2 ? _operands[2].Evaluate(convert) : null; switch (_op) { // Comparison operators: ==, !=, >, >=, <, <= case OperationCode.Equals: return(new ExpressionConstant(c1.Value == c2.Value)); case OperationCode.NotEquals: return(new ExpressionConstant(c1.Value != c2.Value)); case OperationCode.GreaterThan: if (c1.ConstantType == ConstantType.Int && c2.ConstantType == ConstantType.Int) { return(new ExpressionConstant(c1.Int > c2.Int)); } else { return(new ExpressionConstant(string.Compare(c1.Value, c2.Value, StringComparison.Ordinal) > 0)); } case OperationCode.GreaterThanEqual: if (c1.ConstantType == ConstantType.Int && c2.ConstantType == ConstantType.Int) { return(new ExpressionConstant(c1.Int >= c2.Int)); } else { return(new ExpressionConstant(string.Compare(c1.Value, c2.Value, StringComparison.Ordinal) >= 0)); } case OperationCode.LessThan: if (c1.ConstantType == ConstantType.Int && c2.ConstantType == ConstantType.Int) { return(new ExpressionConstant(c1.Int < c2.Int)); } else { return(new ExpressionConstant(string.Compare(c1.Value, c2.Value, StringComparison.Ordinal) < 0)); } case OperationCode.LessThanEqual: if (c1.ConstantType == ConstantType.Int && c2.ConstantType == ConstantType.Int) { return(new ExpressionConstant(c1.Int <= c2.Int)); } else { return(new ExpressionConstant(string.Compare(c1.Value, c2.Value, StringComparison.Ordinal) <= 0)); } // Multiplicative operators: *, /, % case OperationCode.Multiply: return(new ExpressionConstant(c1.Int * c2.Int)); case OperationCode.Divide: return(new ExpressionConstant(c1.Int / c2.Int)); case OperationCode.Modulo: return(new ExpressionConstant(c1.Int % c2.Int)); // Additive operators: +, - case OperationCode.Add: if (c1.ConstantType == ConstantType.Int && c2.ConstantType == ConstantType.Int) { return(new ExpressionConstant(c1.Int + c2.Int)); } else { return(new ExpressionConstant(c1.Value + c2.Value)); } case OperationCode.Subtract: return(new ExpressionConstant(c1.Int + c2.Int)); case OperationCode.And: return(new ExpressionConstant(c1.Bool & c2.Bool)); case OperationCode.Or: return(new ExpressionConstant(c1.Bool | c2.Bool)); case OperationCode.Xor: return(new ExpressionConstant(c1.Bool | c2.Bool)); case OperationCode.Not: return(new ExpressionConstant(!c1.Bool)); case OperationCode.Conditional: if (c1.Bool) { return(c2); } else { return(c3); } default: throw new InvalidOperationException("Unexpected operator"); } }
/// <summary> /// Evaluate the expression as a boolean using the given function to lookup identifier values. /// </summary> /// <param name="convert">look up an identifer and return the appropriate constant value</param> /// <returns>true if the expression evaluates to true; false otherwise</returns> public bool LogicalEvaluate(Converter <ExpressionIdentifier, ExpressionConstant> convert) { ExpressionConstant e = Evaluate(convert); return(e.Bool); }