/// <summary> /// Returns a SMT-LIB v2.0-compliant string that corresponds to /// the input Boolean Expression. /// </summary> /// /// <param name="expr">Boolean Expression.</param> /// <returns>SMT-LIB v2.0-compliant string that corresponds to /// the input Boolean Expression.</returns> private static string MakeBooleanExpr(Expression expr) { string result = null; OperatorType exprOpType = expr.Op.Type; switch (exprOpType) { case OperatorType.And: case OperatorType.Or: Expression firstExpr = expr.GetParameter(0); Expression secondExpr = expr.GetParameter(1); Pair <string, ExpressionType> convertedFirstExpr = SmtHelper.ConvertToSmtLib2(firstExpr); Pair <string, ExpressionType> convertedSecondExpr = SmtHelper.ConvertToSmtLib2(secondExpr); result = "(" + ((exprOpType == OperatorType.And) ? "and" : "or") + " " + convertedFirstExpr.First + " " + convertedSecondExpr.First + ")"; break; case OperatorType.Not: Expression toNotExpr = expr.GetParameter(0); Pair <string, ExpressionType> convertToNotExpr = SmtHelper.ConvertToSmtLib2(toNotExpr); result = "(not " + convertToNotExpr.First + ")"; break; } Trace.Assert(result != null, "PHOENIX: Could not convert Boolean Expression: " + expr.ToString()); return(result); }
/// <summary> /// Returns a string that complies with the SMT-LIB v2.0 standard and that corresponds /// to a query that checks the feasibility of the conditions along the input Path. /// </summary> /// /// <param name="path">Path to convert.</param> /// <returns>String that complies with the SMT-LIB v2.0 standard and that corresponds to /// a query that checks the feasibility of the conditions along the input Path.</returns> public static string ConvertToSmtLib2Query(Path path) { string result = ""; /* Add the command to initialize the solver with the QF_AUFBV logic. */ result += "(set-logic QF_AUFBV)" + "\n"; /* Add declarations for the Boolean constraint variables. */ string identConstraint = path.Config.IDENT_CONSTRAINT; uint constraintNum; for (constraintNum = 0; constraintNum < path.Conditions.Count; constraintNum++) { result += "(declare-fun "; result += identConstraint + constraintNum.ToString() + " "; result += "() Bool)" + "\n"; } /* Add declarations for the variables. */ foreach (Expression varExpr in path.Variables) { result += MakeVariableBv(varExpr.Value, varExpr.BitSize) + "\n"; } /* Add declarations for the array variables. */ foreach (Expression arrayVarExpr in path.ArrayVariables) { result += MakeArrayVarBv(arrayVarExpr.Value, path.ArrayDimensions[arrayVarExpr], path) + "\n"; } /* Assert the conditions along the input Path. */ constraintNum = 0; foreach (Pair <Expression, uint> conditionPair in path.Conditions) { Pair <string, ExpressionType> convertedCondition = SmtHelper.ConvertToSmtLib2(conditionPair.First); result += "(assert (= "; result += identConstraint + constraintNum.ToString() + " "; result += convertedCondition.First + "))" + "\n"; constraintNum++; } /* Assert that the Boolean constraint variables are all true. */ result += "(assert (and"; for (constraintNum = 0; constraintNum < path.Conditions.Count; constraintNum++) { result += " " + identConstraint + constraintNum.ToString(); } result += "))" + "\n"; /* Finish the query. */ result += "(check-sat)" + "\n"; result += "(exit)" + "\n"; return(result); }
/// <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); }