Ejemplo n.º 1
0
        public INumericalAbstractDomain <Variable, Expression> RemoveRedundanciesWith(
            INumericalAbstractDomain <Variable, Expression> oracle)
        {
            var result = new SimpleDisequalities <Variable, Expression>(decoder, encoder);

            if (encoder != null)
            {
                foreach (var x_pair in Elements)
                {
                    SetOfConstraints <Rational> k = x_pair.Value;

                    if (k.IsBottom || k.IsTop)
                    {
                        result[x_pair.Key] = k;
                    }
                    else
                    {
                        Expression xExp = encoder.VariableFor(x_pair.Key);
                        foreach (Rational exp in k.Values)
                        {
                            Expression notEq = encoder.CompoundExpressionFor(ExpressionType.Bool, ExpressionOperator.NotEqual, xExp,
                                                                             exp.ToExpression(encoder));

                            FlatAbstractDomain <bool> check = oracle.CheckIfHolds(notEq);

                            if (check.IsBottom || check.IsTop || !check.BoxedElement)
                            {
                                // If it is not implied by the oracle, we give up
                                result = result.TestTrue(notEq);
                            }
                        }
                    }
                }
            }

            return(result);
        }
        private static ProofOutcome SimplifyInternal <Local, Parameter, Method, Field, Property, Event, Type, Attribute, Assembly, Expression, Variable, LogOptions>
        (
            BoxedExpression exp,
            INumericalAbstractDomain <BoxedVariable <Variable>, BoxedExpression> oracle,
            IMethodDriver <Local, Parameter, Method, Field, Property, Event, Type, Attribute, Assembly, Expression, Variable, LogOptions> mdriver,
            out BoxedExpression simplified
        )
            where Expression : IEquatable <Expression>
            where Variable : IEquatable <Variable>
            where LogOptions : IFrameworkLogOptions
            where Type : IEquatable <Type>
        {
            BinaryOperator  bop;
            BoxedExpression left, right;

            if (exp.IsBinaryExpression(out bop, out left, out right))
            {
                BoxedExpression simplifiedLeft, simplifiedRight;
                switch (bop)
                {
                case BinaryOperator.LogicalAnd:
                {
                    var tLeft = SimplifyInternal(left, oracle, mdriver, out simplifiedLeft);
                    if (tLeft == ProofOutcome.False)
                    {
                        simplified = BoxedExpression.Const(0, mdriver.MetaDataDecoder.System_Boolean, mdriver.MetaDataDecoder);
                        return(ProofOutcome.False);
                    }

                    var tRight = SimplifyInternal(right, oracle, mdriver, out simplifiedRight);
                    if (tRight == ProofOutcome.False)
                    {
                        simplified = BoxedExpression.Const(0, mdriver.MetaDataDecoder.System_Boolean, mdriver.MetaDataDecoder);
                        return(ProofOutcome.False);
                    }

                    if (tLeft == ProofOutcome.True)
                    {
                        simplified = simplifiedRight;
                        return(tRight);
                    }

                    if (tRight == ProofOutcome.True)
                    {
                        simplified = simplifiedLeft;
                        return(tLeft);
                    }

                    simplified = BoxedExpression.BinaryLogicalAnd(simplifiedLeft, simplifiedRight);
                    return(ProofOutcome.Top);
                }

                case BinaryOperator.LogicalOr:
                {
                    var tLeft = SimplifyInternal(left, oracle, mdriver, out simplifiedLeft);
                    if (tLeft == ProofOutcome.True)
                    {
                        simplified = BoxedExpression.Const(1, mdriver.MetaDataDecoder.System_Boolean, mdriver.MetaDataDecoder);
                        return(ProofOutcome.True);
                    }

                    var tRight = SimplifyInternal(right, oracle, mdriver, out simplifiedRight);
                    if (tRight == ProofOutcome.True)
                    {
                        simplified = BoxedExpression.Const(1, mdriver.MetaDataDecoder.System_Boolean, mdriver.MetaDataDecoder);
                        return(ProofOutcome.True);
                    }

                    if (tLeft == ProofOutcome.False)
                    {
                        simplified = simplifiedRight;
                        return(tRight);
                    }

                    if (tRight == ProofOutcome.False)
                    {
                        simplified = simplifiedLeft;
                        return(tLeft);
                    }

                    simplified = BoxedExpression.BinaryLogicalOr(simplifiedLeft, simplifiedRight);
                    return(ProofOutcome.Top);
                }

                case BinaryOperator.Ceq:
                {
                    var r = oracle.CheckIfEqual(left, right);

                    return(ProcessOutcome(r, exp, mdriver, out simplified));
                }

                case BinaryOperator.Cge:
                case BinaryOperator.Cge_Un:
                {
                    var r = oracle.CheckIfLessEqualThan(right, left);

                    return(ProcessOutcome(r, exp, mdriver, out simplified));
                }

                case BinaryOperator.Cgt:
                case BinaryOperator.Cgt_Un:
                {
                    var r = oracle.CheckIfLessThan(right, left);

                    return(ProcessOutcome(r, exp, mdriver, out simplified));
                }

                case BinaryOperator.Cle:
                case BinaryOperator.Cle_Un:
                {
                    var r = oracle.CheckIfLessEqualThan(left, right);

                    return(ProcessOutcome(r, exp, mdriver, out simplified));
                }

                case BinaryOperator.Clt:
                case BinaryOperator.Clt_Un:
                {
                    var r = oracle.CheckIfLessThan(left, right);

                    return(ProcessOutcome(r, exp, mdriver, out simplified));
                }

                case BinaryOperator.Cne_Un:
                {
                    var r1 = oracle.CheckIfLessThan(left, right);

                    if (r1.IsNormal())
                    {
                        simplified = BoxedExpression.Const(1, mdriver.MetaDataDecoder.System_Boolean, mdriver.MetaDataDecoder);
                        return(ProofOutcome.True);
                    }

                    var r2 = oracle.CheckIfLessThan(right, left);
                    if (r2.IsNormal())
                    {
                        simplified = BoxedExpression.Const(1, mdriver.MetaDataDecoder.System_Boolean, mdriver.MetaDataDecoder);
                        return(ProofOutcome.True);
                    }

                    simplified = exp;
                    return(ProofOutcome.Top);
                }
                }
            }

            if (exp.IsUnary)
            {
                var r = oracle.CheckIfHolds(exp);
                if (r.IsTrue())
                {
                    simplified = BoxedExpression.Const(1, mdriver.MetaDataDecoder.System_Boolean, mdriver.MetaDataDecoder);
                    return(ProofOutcome.True);
                }
                if (r.IsFalse())
                {
                    simplified = BoxedExpression.Const(0, mdriver.MetaDataDecoder.System_Boolean, mdriver.MetaDataDecoder);
                    return(ProofOutcome.False);
                }
            }

            simplified = exp;
            return(ProofOutcome.Top);
        }