private void SolveConditionContexts( [NotNull] GraphDataFlowConditionalNode node, [NotNull] LogicExpressionBase expression, [NotNull] GraphNode[] path) { var trueChanges = new List <(ValueVariantBase, IDataValue)>(); var falseChanges = new List <(ValueVariantBase, IDataValue)>(); if (!SolveExpression(node.EnterAnalysisContext, expression, trueChanges, falseChanges)) { Log.Information("Logic: {Operator} -> {Expression}", expression.Operator, expression); } foreach (var grouping in trueChanges.GroupBy(x => x.Item1, x => x.Item2)) { var(variant, dataValue) = (grouping.Key, grouping.ToArray()); var newVariant = variant.Clone(node.EnterAnalysisContext, path); newVariant.Value = ValueUtilities.IterateValues(dataValue, variant.Value, dataValue.Length + 1, ValueUtilities.IterateValuesAndFunc); node.TrueExitAnalysisContext[variant] = newVariant; } foreach (var grouping in falseChanges.GroupBy(x => x.Item1, x => x.Item2)) { var(variant, dataValue) = (grouping.Key, grouping.ToArray()); var newVariant = variant.Clone(node.EnterAnalysisContext, path); newVariant.Value = ValueUtilities.IterateValues(dataValue, variant.Value, dataValue.Length + 1, ValueUtilities.IterateValuesAndFunc); node.FalseExitAnalysisContext[variant] = newVariant; } }
private bool SolveExpression( [NotNull] AnalysisContext context, [NotNull] LogicExpressionBase logicExpressionBase, List <(ValueVariantBase, IDataValue)> trueChanges,
public static ValueInterval ToInterval([NotNull] AnalysisContext context, [NotNull] LogicExpressionBase expression, [NotNull] ILValue lValue) { switch (expression) { case BinaryLogicExpression binaryLogicExpression: if (binaryLogicExpression.Left is OrderedLiteralBase && binaryLogicExpression.Right is Variable) { binaryLogicExpression = binaryLogicExpression.Flip(); } var left = binaryLogicExpression.Left; var right = context[binaryLogicExpression.Right]; if (right == null) { return(null); } ILValue variant = null; OrderedLiteralBase literal = null; switch (left) { case ILValue valueVariantBase: variant = valueVariantBase; break; case OrderedLiteralBase orderedLiteralBase: literal = orderedLiteralBase; break; default: throw new ArgumentOutOfRangeException(nameof(left)); } switch (right) { case ILValue valueVariantBase: variant = valueVariantBase; break; case OrderedLiteralBase orderedLiteralBase: literal = orderedLiteralBase; break; default: throw new ArgumentOutOfRangeException(nameof(right)); } if (variant == null || literal == null) { return(null); } if (Equals(lValue, variant) || variant is IVariantWithStorageVariable variantWithStorage && Equals(variantWithStorage.StorageVariable, lValue)) { return(OperatorToInterval(binaryLogicExpression.Operator, literal, variant.TypeRef)); } else { return(null); }