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); }