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