Exemplo n.º 1
0
        /// <summary>
        /// Converts a Boolean Expression into a logically equivalent ITE statement that returns
        /// a bitvector instead. If the Expression is not Boolean, it is returned unchanged.
        /// </summary>
        ///
        /// <param name="exprString">SMT-LIB v2.0-compliant string that represents
        /// the Expression to convert.</param>
        /// <param name="exprType">Type of the Expression.</param>
        /// <param name="bitSize">Bit-size of the resulting bitvector.</param>
        /// <returns>Logically equivalent ITE statement if the Expression is Boolean;
        /// unchanged input Expression otherwise.</returns>
        private static string BooleanToIte(string exprString,
                                           ExpressionType exprType, uint bitSize)
        {
            string result = null;

            switch (exprType)
            {
            case ExpressionType.DEFAULT:
                result = exprString;
                break;

            case ExpressionType.BOOLEAN:
                string zeroBv = SmtHelper.MakeConstantBv("0", bitSize);
                string oneBv  = SmtHelper.MakeConstantBv("1", bitSize);
                result = "(ite " + exprString + " " + oneBv + " " + zeroBv + ")";
                break;

            default:
                Trace.Fail("PHOENIX: Unrecognized Expression type: " + exprType.ToString());
                break;
            }

            return(result);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Returns a pair whose first element is a string that complies with the SMT-LIB v2.0
        /// standard and that corresponds to the input Expression, and whose second element
        /// is the type of the Expression.
        /// </summary>
        ///
        /// <param name="expr">Expression to convert.</param>
        /// <returns>Pair whose first element is a string that complies with the SMT-LIB v2.0
        /// standard and that corresponds to the input Expression, and whose second element
        /// is the type of the Expression.</returns>
        private static Pair <string, ExpressionType> ConvertToSmtLib2(Expression expr)
        {
            Pair <string, ExpressionType> result = null;
            string resultString = "";

            OperatorType exprOpType = expr.Op.Type;

            switch (exprOpType)
            {
            case OperatorType.True:
                result = new Pair <string, ExpressionType>("true", ExpressionType.BOOLEAN);
                break;

            case OperatorType.False:
                result = new Pair <string, ExpressionType>("false", ExpressionType.BOOLEAN);
                break;

            case OperatorType.Constant:
                resultString = SmtHelper.MakeConstantBv(expr.Value, expr.BitSize);
                result       = new Pair <string, ExpressionType>(resultString, ExpressionType.DEFAULT);
                break;

            case OperatorType.Variable:
            case OperatorType.ArrayVariable:
                result = new Pair <string, ExpressionType>(expr.Value, ExpressionType.DEFAULT);
                break;

            case OperatorType.ZeroExtend:
            case OperatorType.SignExtend:
                Expression toExtendExpr = expr.GetParameter(0);
                Expression extendByExpr = expr.GetParameter(1);

                Pair <string, ExpressionType> convertedToExtendExpr =
                    SmtHelper.ConvertToSmtLib2(toExtendExpr);
                resultString = "((_ " +
                               (exprOpType == OperatorType.ZeroExtend ? "zero_extend" : "sign_extend") +
                               " " + extendByExpr.Value + ") ";
                resultString += SmtHelper.BooleanToIte(convertedToExtendExpr.First,
                                                       convertedToExtendExpr.Second, toExtendExpr.BitSize) + ")";
                result =
                    new Pair <string, ExpressionType>(resultString, ExpressionType.DEFAULT);
                break;

            case OperatorType.BitExtract:
                Expression toExtractExpr = expr.GetParameter(0);
                Expression lowIndexExpr  = expr.GetParameter(1);
                Expression highIndexExpr = expr.GetParameter(2);

                Pair <string, ExpressionType> convertedToExtractExpr =
                    SmtHelper.ConvertToSmtLib2(toExtractExpr);
                resultString = "((_ extract " + highIndexExpr.Value + " " +
                               lowIndexExpr.Value + ") ";
                resultString += SmtHelper.BooleanToIte(convertedToExtractExpr.First,
                                                       convertedToExtractExpr.Second, toExtractExpr.BitSize) + ")";
                result =
                    new Pair <string, ExpressionType>(resultString, ExpressionType.DEFAULT);
                break;

            case OperatorType.Ite:
                Expression conditionalExpr = expr.GetParameter(0);
                Expression consequentExpr  = expr.GetParameter(1);
                Expression alternateExpr   = expr.GetParameter(2);

                Pair <string, ExpressionType> convertedConditionalExpr =
                    SmtHelper.ConvertToSmtLib2(conditionalExpr);
                Pair <string, ExpressionType> convertedConsequentExpr =
                    SmtHelper.ConvertToSmtLib2(consequentExpr);
                Pair <string, ExpressionType> convertedAlternateExpr =
                    SmtHelper.ConvertToSmtLib2(alternateExpr);

                resultString  = "(ite " + convertedConditionalExpr.First + " ";
                resultString += SmtHelper.BooleanToIte(convertedConsequentExpr.First,
                                                       convertedConsequentExpr.Second, consequentExpr.BitSize) + " ";
                resultString += SmtHelper.BooleanToIte(convertedAlternateExpr.First,
                                                       convertedAlternateExpr.Second, alternateExpr.BitSize) + ")";
                result =
                    new Pair <string, ExpressionType>(resultString, ExpressionType.DEFAULT);
                break;

            case OperatorType.And:
            case OperatorType.Or:
            case OperatorType.Not:
                resultString = SmtHelper.MakeBooleanExpr(expr);
                result       =
                    new Pair <string, ExpressionType>(resultString, ExpressionType.BOOLEAN);
                break;

            case OperatorType.NotEqual:
                Expression firstParam  = expr.GetParameter(0);
                Expression secondParam = expr.GetParameter(1);

                Pair <string, ExpressionType> convertedFirstParam =
                    SmtHelper.ConvertToSmtLib2(firstParam);
                Pair <string, ExpressionType> convertedSecondParam =
                    SmtHelper.ConvertToSmtLib2(secondParam);

                resultString  = "(not (= ";
                resultString += SmtHelper.BooleanToIte(convertedFirstParam.First,
                                                       convertedFirstParam.Second, firstParam.BitSize) + " ";
                resultString += SmtHelper.BooleanToIte(convertedSecondParam.First,
                                                       convertedSecondParam.Second, secondParam.BitSize) + "))";
                result =
                    new Pair <string, ExpressionType>(resultString, ExpressionType.BOOLEAN);
                break;

            default:
                string convertedParams = "";
                foreach (Expression paramExpr in expr.ParameterList)
                {
                    Pair <string, ExpressionType> convertedParam =
                        SmtHelper.ConvertToSmtLib2(paramExpr);
                    convertedParams += " " + SmtHelper.BooleanToIte(convertedParam.First,
                                                                    convertedParam.Second, paramExpr.BitSize);
                }

                OperatorType   opType     = expr.Op.Type;
                ExpressionType resultType = SmtHelper.IsComparisonOp(opType) ?
                                            ExpressionType.BOOLEAN : ExpressionType.DEFAULT;
                string functionForOp = "";

                int numParams = expr.ParameterList.Count;
                switch (numParams)
                {
                case 1:
                    functionForOp = SmtHelper.GetFunctionForUnary(opType);
                    break;

                case 2:
                    functionForOp = SmtHelper.GetFunctionForBinary(opType);
                    break;

                case 3:
                    functionForOp = SmtHelper.GetFunctionForTernary(opType);
                    break;

                default:
                    throw new NotImplementedException("PHOENIX: " +
                                                      "No support for operators with arity " +
                                                      numParams.ToString() + ".");
                }

                resultString = "(" + functionForOp + convertedParams + ")";
                result       = new Pair <string, ExpressionType>(resultString, resultType);
                break;
            }

            Trace.Assert(result != null, "PHOENIX: Result should not be null.");
            return(result);
        }