Пример #1
0
        /// <summary>
        /// Forms the ternary expression "P ? Q : R".
        /// It performs some simplifications:
        /// P ? true : R ==> P || R
        /// P ? Q : true ==> !P || Q
        /// P ? false : R ==> !P && R
        /// P ? Q : false ==> P && Q
        /// </summary>
        /// <param name="P"></param>
        /// <param name="Q"></param>
        /// <param name="R"></param>
        /// <returns></returns>
        private static Expression Ternary(Expression P, Expression Q, Expression R)
        {
            Expression Q_prime = SimplifyLiteral(Q);
            Expression R_prime = SimplifyLiteral(R);
            Expression P_prime = P;

            if (P.Type != null && P.Type != SystemTypes.Boolean)
            {
                P_prime = TypeReconstructorAndExpressionSimplifier.ReconstructBooleanExpression(P);
            }
            if (Q_prime == Literal.True)
            {
                return(new BinaryExpression(P_prime, R, NodeType.LogicalOr, SystemTypes.Boolean));
            }
            else if (R_prime == Literal.True)
            {
                return(new BinaryExpression(new UnaryExpression(P_prime, NodeType.LogicalNot, SystemTypes.Boolean), Q, NodeType.LogicalOr, SystemTypes.Boolean));
            }
            else if (Q_prime == Literal.False)
            {
                return(new BinaryExpression(new UnaryExpression(P_prime, NodeType.LogicalNot, SystemTypes.Boolean), R, NodeType.LogicalAnd, SystemTypes.Boolean));
            }
            else if (R_prime == Literal.False)
            {
                return(new BinaryExpression(P_prime, Q, NodeType.LogicalAnd, SystemTypes.Boolean));
            }
            else
            {
                return(new TernaryExpression(P_prime, Q, R, NodeType.Conditional, Q.Type));
            }
        }
Пример #2
0
        public Expression DecompileBooleanExpression(BlockExpression be)
        {
            if (be == null)
            {
                return(null);
            }
            TypeReconstructorAndExpressionSimplifier tr = new TypeReconstructorAndExpressionSimplifier();

            be = tr.VisitBlockExpression(be) as BlockExpression;
            if (be == null)
            {
                return(null);
            }
            Block b = be.Block;

            #region Make sure the block expression has the right shape
            foreach (Statement s in b.Statements)
            {
                Block b_prime = s as Block;
                Debug.Assert(b_prime != null);
                Debug.Assert(HelperMethods.IsBasicBlock(b_prime));
            }
            #endregion
            Block firstBlock = (Block)b.Statements[0];
            block2Index = new TrivialHashtable(b.Statements.Count);
            blocks      = new BlockList(b.Statements.Count);
            for (int i = 0, n = b.Statements.Count; i < n; i++)
            {
                block2Index[b.Statements[i].UniqueKey] = i;
                blocks.Add(b.Statements[i] as Block);
            }
            Expression e = DecompileBooleanExpression(firstBlock);
            // BUGBUG: this isn't a good place to do this because then it gets done for all contracts,
            // not just postconditions!! Plus, we could just leave Result in the contracts and let the
            // BPL translation recognize it.
            //ReplaceResult repResult = new ReplaceResult(this.localToUseForResult, this.contractNodes.ResultTemplate,
            //  this.contractNodes.ParameterTemplate);
            //e = repResult.VisitExpression(e);
            return(e);
        }
Пример #3
0
        public override Expression VisitUnaryExpression(UnaryExpression unaryExpression)
        {
            unaryExpression.Operand = VisitExpression(unaryExpression.Operand);
            if (unaryExpression.NodeType == NodeType.LogicalNot && unaryExpression.Operand.Type.IsPrimitiveInteger)
            {
                return(new BinaryExpression(unaryExpression.Operand, Literal.Int32Zero, NodeType.Eq, SystemTypes.Boolean));
            }
            if (unaryExpression.Type == null)
            {
                switch (unaryExpression.NodeType)
                {
                case NodeType.LogicalNot:
                    unaryExpression.Operand = TypeReconstructorAndExpressionSimplifier.ReconstructBooleanExpression(unaryExpression.Operand);
                    Debug.Assert(unaryExpression.Operand.Type == SystemTypes.Boolean);
                    unaryExpression.Type = SystemTypes.Boolean;
                    break;

                default:
                    break;
                }
            }
            return(unaryExpression);
        }
Пример #4
0
        private Expression DecompileBooleanExpression(Block b)
        {
            ExpressionList eList = new ExpressionList();
            Expression     e     = null;
            int            i     = 0;

            while (i < b.Statements.Count)
            {
                if (b.Statements[i] is Branch)
                {
                    break;
                }
                Statement s = b.Statements[i];
                i++;
                if (s == null || s.NodeType == NodeType.Nop)
                {
                    continue;
                }
                ExpressionStatement es = s as ExpressionStatement;
                if (es != null)
                {
                    MethodCall mc = es.Expression as MethodCall;
                    if (mc != null)
                    {
                        MemberBinding mb = mc.Callee as MemberBinding;
                        if (mb != null)
                        {
                            Method m = mb.BoundMember as Method;
                            if (m != null)
                            {
                                if (this.contractNodes.IsPlainPrecondition(m) || this.contractNodes.IsPostcondition(m))
                                {
                                    eList.Add(mc.Operands[0]);
                                }
                                else
                                {
                                    eList.Add(es.Expression);
                                }
                            }
                        }
                        else
                        {
                            eList.Add(es.Expression);
                        }
                    }
                    else
                    {
                        eList.Add(SimplifyLiteral(es.Expression));
                    }
                }
            }
            if (i == b.Statements.Count) // no branch at end of block
            {
                return(eList[0]);
            }
            Branch br = b.Statements[b.Statements.Count - 1] as Branch;

            if (br.Condition == null) // unconditional branch
            {
                return(eList[0]);
            }
            e = TypeReconstructorAndExpressionSimplifier.ReconstructBooleanExpression(br.Condition); // should be: e = Combine(e, br.Condition);
            Expression trueBranch  = DecompileBooleanExpression(br.Target);
            Expression falseBranch = DecompileBooleanExpression(blocks[((int)block2Index[b.UniqueKey]) + 1]);
            Expression result      = Ternary(e, trueBranch, falseBranch);

            return(result);
        }