string LookupVarName(Expr var) { if (__lookupVarName == null) return var.ToString(); else return __lookupVarName(var); }
internal string DescribeExpr1(Expr term) { if (z3p.IsVar(term)) return LookupVarName(term); var kind = term.ASTKind; if (kind == Z3_ast_kind.Z3_NUMERAL_AST) { int code = (int)z3p.GetNumeralUInt(term); //???TBD??? if (CSmode) { return DisplayNumber(code); } if (charSort == null || !charSort.Equals(z3p.GetSort(term)) || code < 32 || code > 126) { return DisplayNumber(code); } else { char c = (char)code; return string.Format("'{0}'", Escaper.Escape(c)); } } else if (kind == Z3_ast_kind.Z3_APP_AST) { #region function application FuncDecl decl = z3p.GetAppDecl(term); var dkind = decl.DeclKind; Expr[] subterms = z3p.GetAppArgs(term); Expr[] terms; if (dkind == Z3_decl_kind.Z3_OP_NOT) { #region negation //there must be a single argument if (subterms[0].Equals(z3p.True)) return falseName; else if (subterms[0].Equals(z3p.False)) return trueName; else return "!" + DescribeExpr(subterms[0]) + ""; #endregion } else if(dkind == Z3_decl_kind.Z3_OP_DT_CONSTRUCTOR){ string str; // Input is a list of bitvectors: output corresponding string if (IsCocreteCharacterList(term, out str)) return str; string res = decl.Name + "("; if (subterms.Length > 0) res += DescribeExpr(subterms[0]); for (int i = 1; i < subterms.Length; i++) { res += ","; res += DescribeExpr(subterms[i]); } res += ")"; return res; } else if (dkind == Z3_decl_kind.Z3_OP_EXTRACT) { //there must be exactly one argument if (subterms.Length != 1) throw new AutomataException(AutomataExceptionKind.UnExpectedNrOfOperands); var declparams = decl.Parameters; int k = declparams[0].Int; int m = declparams[1].Int; //see first if subterms[0] is fixed numeric string s1 = DescribeExpr(subterms[0]); int _nr = 0; if (TryGetNumber(s1, out _nr)) { int mask = 0; for (int i = m; i <= k; i++) { mask = mask | (1 << i); } int _res = (_nr & mask) >> m; return DisplayNumber(_res); } int mask_k_m = (1 << (k - m + 1)) - 1; string res2; if (m == 0) //no need to shift left res2 = string.Format("({0}&{1})", s1, string.Format("0x{0:X}", mask_k_m)); else //shift left m bits res2 = string.Format("(({0}>>{1})&{2})", s1, m, string.Format("0x{0:X}", mask_k_m)); return res2; } else if (IsConcat(term, out terms)) { string result = DescribeExpr(terms[0]); for (int i = 1; i < terms.Length; ++i) { string s2 = DescribeExpr(terms[i]); uint sz = ((BitVecSort)(terms[i].Sort)).Size; result = ShiftLeftAndBitOr(result, s2, sz); } return result; } else if (IsInfixOperator(dkind)) { if (IsDisjOrConj(dkind)) { #region conjunction or disjunction may take any nr of arguments string[] descr = Array.ConvertAll(subterms, DescribeExpr); if (descr.Length == 0) return (dkind == Z3_decl_kind.Z3_OP_AND ? trueName : falseName); else if (descr.Length == 1) return descr[0]; else { List<string> simplified = new List<string>(); foreach (var x in descr) if (x == (dkind == Z3_decl_kind.Z3_OP_AND ? falseName : trueName)) return (dkind == Z3_decl_kind.Z3_OP_AND ? falseName : trueName); else if (x != (dkind == Z3_decl_kind.Z3_OP_AND ? trueName : falseName)) simplified.Add(x); if (simplified.Count == 0) return (dkind == Z3_decl_kind.Z3_OP_AND ? trueName : falseName); if (simplified.Count == 1) return simplified[0]; string s = "(" + simplified[0]; for (int i = 1; i < simplified.Count; i++) s += (DescribeInfixOperator(dkind) + simplified[i]); s += ")"; return s; } #endregion } //else if (dkind == Z3_decl_kind.Z3_OP_BShl || dkind == Z3_decl_kind.Z3_OP_BLShr) //{ // #region special binary infix operators with fixed second argument // //there must be exactly one argument // if (subterms.Length != 1) // throw new AutomataException(AutomataExceptionKind.UnExpectedNrOfOperands); // IParameter[] declparams = z3p.z3.GetDeclParameters(decl); // int k = int.Parse(declparams[0].ToString()); // string s1 = DescribeExpr(subterms[0]); // return string.Format("({0}{1}{2})", s1, DescribeInfixOperator(dkind), k); // #endregion //} else if (IsBitDisjOrConj(dkind)) { if (subterms.Length < 2) throw new AutomataException(AutomataExceptionKind.UnExpectedNrOfOperands); string res = "(" + DescribeExpr(subterms[0]); for (int i = 1; i < subterms.Length; i++) res = res + DescribeInfixOperator(dkind) + DescribeExpr(subterms[i]); res += ")"; return res; } else { #region binary infix operators //there must be exactly two arguments if (subterms.Length < 2) throw new AutomataException(AutomataExceptionKind.UnExpectedNrOfOperands); string[] subs = Array.ConvertAll(subterms, DescribeExpr); string res = subs[0]; for (int i = 1; i < subs.Length; i++) res = string.Format("({0}{1}{2})", res, DescribeInfixOperator(dkind), subs[i]); if (subterms[0].Sort is BitVecSort && (dkind == Z3_decl_kind.Z3_OP_BADD || dkind == Z3_decl_kind.Z3_OP_BMUL)) { uint sz = (subterms[0].Sort as BitVecSort).Size; if (sz < (uint)z3p.Encoding) { int mask = ~(-1 << (int)sz); string maskStr = Escaper.EscapeHex(mask); res = string.Format("({0}{1}{2})", res, DescribeInfixOperator(Z3_decl_kind.Z3_OP_BAND), maskStr); } } return res; #endregion } } else if (dkind == Z3_decl_kind.Z3_OP_FALSE) return falseName; //false else if (dkind == Z3_decl_kind.Z3_OP_TRUE) return trueName; //true else if (dkind == Z3_decl_kind.Z3_OP_ITE) { #region if-then-else term string cond = DescribeExpr(subterms[0]); string trueCase = DescribeExpr(subterms[1]); string falseCase = DescribeExpr(subterms[2]); if (cond == trueName) return trueCase; else if (cond == falseCase) return falseCase; else { if (!CSmode) return string.Format("ite({0},{1},{2})", EliminateOuterParanthesis(cond), EliminateOuterParanthesis(trueCase), EliminateOuterParanthesis(falseCase)); else return string.Format("({0} ? {1} : {2})", EliminateOuterParanthesis(cond), EliminateOuterParanthesis(trueCase), EliminateOuterParanthesis(falseCase)); } #endregion } else if (dkind == Z3_decl_kind.Z3_OP_UNINTERPRETED) { #region function symbols, such as declared constants, Skolem functions, tuples, Lists, etc. string f = z3p.GetDeclShortName(decl); string f_fullname = z3p.GetDeclName(decl); uint[] ps = z3p.GetDeclParameters(decl); int arity = subterms.Length; if (f.Equals("T0")) //the default empty tuple return "T()"; if (f.Equals("hex")) //compute the hexadacimal digit encoder { if (ps.Length > 1) throw new AutomataException(AutomataExceptionKind.InternalError); uint k = (ps.Length == 0 ? 0 : ps[0]); string c = (k == 0 ? DescribeExpr(subterms[0]) : string.Format("({0}>>{1})", DescribeExpr(subterms[0]), k * 4)); string res = (CSmode ? string.Format("(({0}&0xF)+(({0}&0xF)<=9 ? 48 : 55))", c) : string.Format("(({0}&0xF)+ite(({0}&0xF)<=9, 48, 55))", c)); return res; } string tupleConstructorName = Z3Provider.tupleSortNamePrefix + arity.ToString(); bool isTupleConstr = false; if (f.Equals(tupleConstructorName)) { isTupleConstr = true; f = ""; //ignore the tuple constructor } if (f.StartsWith(".")) //tuple projection: use postfix notation return string.Format("{0}{1}", DescribeExpr(subterms[0]), f); string str = null; if (IsCocreteCharacterList(term, out str)) return str; if (f == "bvurem_i") { return string.Format("({0}%{1})", DescribeExpr(subterms[0]), DescribeExpr(subterms[1])); } if (f == "bvudiv_i") { return string.Format("({0}/{1})", DescribeExpr(subterms[0]), DescribeExpr(subterms[1])); } if (subterms.Length == 0) return f; else { string s0 = (isTupleConstr ? "T(" : f + "("); string s1 = (isTupleConstr ? ")" : ")"); for (int j = 0; j < ps.Length; j++) { s0 += (j > 0 ? "," : ""); s0 += ps[j]; } if (ps.Length > 0 && subterms.Length > 0) s0 += ","; string s = s0 + EliminateOuterParanthesis(DescribeExpr(subterms[0])); for (int i = 1; i < subterms.Length; i++) s += ("," + EliminateOuterParanthesis(DescribeExpr(subterms[i]))); return s + s1; } #endregion } else if (dkind == Z3_decl_kind.Z3_OP_DT_ACCESSOR) { return string.Format("{0}.{1}", DescribeExpr(subterms[0]), z3p.GetDeclShortName(decl)); } else return term.ToString(); //throw new ArgumentException(string.Format("unexpected function declaration kind {0}", dkind), "term"); #endregion } else { throw new AutomataException(AutomataExceptionKind.UnexpectedExprKindInPrettyPrinter); } }
public static void CheckString(Expr e, string s) { if (e.ToString() != s) throw new TestFailedException("strings don't match"); }