Załóżmy, że mam 2 tablice w formule, której sprawdzalność chcę sprawdzić przy użyciu Z3. Jeśli z3 zwraca sat, chcę przeczytać w pierwszej tablicy w modelu z3 i całkiem wydrukować go jako klucz, parę wartości i wartość domyślną. Później chcę przekonwertować go na mapę i przeprowadzić dalszą analizę. Oto przykład uruchomić:Czytaj func interp tablicy z3 z modelu z3
void find_model_example_arr() {
std::cout << "find_model_example_involving_array\n";
context c;
sort arr_sort = c.array_sort(c.int_sort(), c.int_sort());
expr some_array_1 = c.constant("some_array_1", arr_sort);
expr some_array_2 = c.constant("some_array_2", arr_sort);
solver s(c);
s.add(select(some_array_1, 0) > 0);
s.add(select(some_array_2, 5) < -4);
std::cout << s.check() << "\n";
model m = s.get_model();
std::cout << m << "\n";
expr some_array_1_eval = m.eval(some_array_1);
std::cout << "\nsome_array_1_eval = " << some_array_1_eval << "\n";
func_decl some_array_1_eval_func_decl = some_array_1_eval.decl();
std::cout << "\nThe Z3 expr(fun_decl) for some_array_1_eval is : " << some_array_1_eval_func_decl << "\n";
// ERROR here
func_interp fun_interp = m.get_func_interp(some_array_1_eval_func_decl);
// This works well
//func_interp fun_interp = m.get_func_interp(m.get_func_decl(0));
std::cout << "\nThe Z3 expr(fun_interp) for the array is : " << fun_interp << "\n";
unsigned num_entries = fun_interp.num_entries();
for(unsigned i = 0; i < num_entries; i++)
{
z3::func_entry entry = fun_interp.entry(i);
z3::expr k = entry.arg(0);
z3::expr v = entry.value();
std::cout << "\n(key,value): (" << k << "," << v << ")";
}
z3::expr default_value = fun_interp.else_value();
std::cout << "\nDefault value:" << default_value;
}
pojawia się następujący komunikat:
find_model_example_involving_array
sat
(define-fun some_array_1() (Array Int Int)
(_ as-array k!0))
(define-fun some_array_2() (Array Int Int)
(_ as-array k!1))
(define-fun k!0 ((x!1 Int)) Int
(ite (= x!1 0) 1
1))
(define-fun k!1 ((x!1 Int)) Int
(ite (= x!1 5) (- 5)
(- 5)))
some_array_1_eval = (_ as-array k!0)
The Z3 expr(fun_decl) for some_array_1_eval is :
(declare-fun as-array() (Array Int Int))
unexpected error: invalid argument
Zamiast gdybym wykomentuj pierwszą linię i użyj sekund, czyli za pomocą poniższego fragmentu kodu:
// ERROR here
// func_interp fun_interp = m.get_func_interp(some_array_1_eval_func_decl);
// This works well
func_interp fun_interp = m.get_func_interp(m.get_func_decl(0));
uzyskać wyjście szukam:
(key,value): (0,1)
Default value:1
Oto jednak problem? Jak mogę się dowiedzieć, że m.get_func_decl (0) jest tym, który odpowiada some_array_1? Na przykład, jeśli używam m.get_func_decl (1), otrzymuję błędne pary (klucz, wartość). Czy są inne słowa, w jaki sposób uzyskać func_interp tablicy (zdefiniowanej jako z3 expr) z modelu?
W Java: wyrażenie arrayExpr = ctx.mkArrayConst (...) Expr arrayEval = model.eval (arrayExpr, false); FuncDecl arrayEvalFuncDecl = arrayEval.getFuncDecl(); assert arrayEvalFuncDecl.getDeclKind() == Z3_decl_kind.Z3_OP_AS_ARRAY; assert arrayEval.isApp(); assert arrayEvalFuncDecl.getNumParameters() == 1; assert arrayEvalFuncDecl.getParameters() [0] .getParameterKind() == Z3_parameter_kind.Z3_PARAMETER_FUNC_DECL; końcowa tablica FuncDeclInterpretationFuncDecl = arrayEvalFuncDecl.getParameters() [0] .getFuncDecl(); końcowa interpretacja FuncInterp = model.getFuncInterp (arrayInterpretationFuncDecl); – lexicalscope