2014-04-05 14 views
5

Supponiamo di disporre di 2 array in una formula di cui si desidera verificare l'affidabilità utilizzando z3. Se z3 restituisce sat, voglio leggere la prima matrice nel modello z3 e stamparla piuttosto come una chiave, una coppia di valori e un valore predefinito. Più tardi voglio convertirlo in una mappa e fare ulteriori analisi su di esso. Ecco l'esempio corro:Lettura interp di un array z3 dal modello 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; 
} 

ottengo il seguente output:

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 

Invece se io commento la prima riga e utilizzare il secondo, vale a dire utilizzare il blocco di codice seguente:

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

ottengo l'uscita Cerco:

(key,value): (0,1) 
Default value:1 

Ecco il problema? Come faccio a capire che m.get_func_decl (0) è quello corrispondente a some_array_1? Ad esempio, se uso m.get_func_decl (1), ottengo coppie errate (chiave, valore). Altre parole come posso ottenere un func_interp di un array (definito come z3 expr) da un modello?

risposta

6

La rappresentazione per i modelli di array è davvero un po 'confusa. Il significato di

(define-fun some_array_1() (Array Int Int) 
    (_ as-array k!0)) 

è che il modello di matrice some_array_1 è la funzione k!0 che deve essere interpretato come un array (significato dalla chiamata a as-array. Quest'ultima è una funzione parametrica, che non ha argomenti, pertanto , per ottenere la definizione effettiva della funzione modello per some_array_1, dobbiamo cercare le chiamate di funzione as-array. Nell'esempio dato, possiamo farlo come segue, assicurandoci prima di avere un modello di array nel formato previsto controllando alcune delle asserzioni:

assert(Z3_get_decl_kind(c, some_array_1_eval_func_decl) == Z3_OP_AS_ARRAY); 
assert(Z3_is_app(c, some_array_1_eval)); 
assert(Z3_get_decl_num_parameters(c, some_array_1_eval_func_decl) == 1); 
assert(Z3_get_decl_parameter_kind(c, some_array_1_eval_func_decl, 0) == 
     Z3_PARAMETER_FUNC_DECL); 
func_decl model_fd = func_decl(c, 
        Z3_get_decl_func_decl_parameter(c, some_array_1_eval_func_decl, 0)); 

La dichiarazione di funzione model_fd tiene poi la reale funzione assegnata dal modello (k!0) e si può ottenere l'interpretazione funzione tramite

func_interp fun_interp = m.get_func_interp(model_fd); 
+0

In Java: Expr 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; final FuncDecl arrayInterpretationFuncDecl = arrayEvalFuncDecl.getParameters() [0] .getFuncDecl(); final FuncInterp interpretation = model.getFuncInterp (arrayInterpretationFuncDecl); – lexicalscope

Problemi correlati