2012-09-17 35 views
1

我正在使用Z3和C-API。我想了解如何理解如何在C-API中使用策略和目標。我檢查了Z3的例子,但找不到適合我的例子。Z3使用目標和策略

我有我的C-API僞代碼如下 -

contextId = mk_context(); 
solverId = Z3_mk_solver(contextId); 
Z3_solver_inc_ref(contextId, solverId); 
... 
then some assertions like x > 0, y > 0 and so on.. 
... 
// now comes the final goal 
mygoal = Z3_mk_less_than(contextId, ...) // x < 50 
Z3_solver_assert (contextId, solverId, mygoal) 
... 
// finally check 
Z3_solver_check(contextId, solverId) 
Z3_reset_memory(); 
Z3_del_context(contextId); 
Z3_solver_dec_ref(contextId, solverId); 

現在我想一些戰術應用到mygoal。 但是,我無法弄清楚C-API應該如何遵循。 我查了文檔,但找不到這樣的例子。

我試過的是使用Z3_goal_assert(); API。但它不能以某種方式工作。 有人能給我一個C-API的簡單例子嗎?

更新:我嘗試了下面的C代碼,但它不起作用。 在函數調用Z3_tactic_apply(),求解拋出這樣的錯誤 -

pure virtual method called 
terminate called without an active exception 

代碼海賊王:

goalId = Z3_mk_goal();  
Z3_goal_inc_ref(context, goalId); 

assertionVector = Z3_solver_get_assertions (context, solver); 
int vectorSize = Z3_ast_vector_size(assertionVector); 

for(int i=0;i<vectorSize;i++)  
    Z3_goal_assert(context, goalId, Z3_ast_vector_get(context, assertionVector, i)); 

Z3_goal_assert(context, goalId, Z3_mk_eq(context, totalProcDecl, Z3_mk_int(context, numProcessors, int_sort))); 
Z3_goal_assert(context, goalId, Z3_mk_eq(contextlatencyDecl, Z3_mk_int(context, latencyConstraint, int_sort))); 

// This is what I am trying to apply 
// (check-sat-using (then (! simplify :arith-lhs true) solve-eqs lia2pb pb2bv bit-blast sat)) 

tactic0 = Z3_mk_tactic (context, "simplify"); 
Z3_tactic_inc_ref (context,tactic0); 

tactic1 = Z3_mk_tactic (context, "solve-eqs"); 
Z3_tactic_inc_ref (context, tactic1); 

tactic2 = Z3_mk_tactic (context, "lia2pb"); 
Z3_tactic_inc_ref (context, tactic2); 

tactic3 = Z3_mk_tactic (context, "pb2bv"); 
Z3_tactic_inc_ref (context, tactic3); 

tactic4 = Z3_mk_tactic (context, "bit-blast"); 
Z3_tactic_inc_ref (context, tactic4); 

tactic5 = Z3_mk_tactic (context, "sat"); 
Z3_tactic_inc_ref (context, tactic5); 

temp = Z3_tactic_and_then (context, tactic0, tactic1); 
temp = Z3_tactic_and_then (context, temp, tactic2); 
temp = Z3_tactic_and_then (context, temp, tactic3); 
temp = Z3_tactic_and_then (context, temp, tactic4); 
temp = Z3_tactic_and_then (context, temp, tactic5); 

result = Z3_tactic_apply (context, temp, goalId); 
printf("Result : %s\n", Z3_apply_result_to_string (context, result)); 

// Finished Solving. 
Z3_goal_dec_ref (context, goalId); 
Z3_tactic_dec_ref (context, tactic0); 
Z3_tactic_dec_ref (context, tactic1); 
Z3_tactic_dec_ref (context, tactic2); 
Z3_tactic_dec_ref (context, tactic3); 
Z3_tactic_dec_ref (context, tactic4); 
Z3_tactic_dec_ref (context, tactic5); 

我也試着多一個選擇添加參數來簡化策略。

tactic0_without_param = Z3_mk_tactic (context, "simplify"); 
Z3_tactic_inc_ref (context,tactic0_without_param); 

paramsId = Z3_mk_params(context); 
Z3_params_inc_ref(context, paramsId); 
Z3_params_set_bool (context, p, paramsId, Z3_mk_string_symbol(context, ":arith-lhs"), true); 
tactic0 = Z3_tactic_using_params (context, tactic0, paramsId); 

但是再次不起作用。

謝謝。

回答

2

Z3 4.x帶有C++頭文件,使Z3 C API更易於使用(文件include/z3++.h)。 它也有一個基於C++的示例(文件examples/c++/example.cpp)。這個文件包含許多使用策略對象的例子。

也就是說,戰術應該適用於目標。爲了方便起見,我們還提供了一個API,根據策略Z3_mk_solver_from_tactic創建求解器。該API返回的求解器對象將嘗試使用給定的策略來解決可滿足性查詢。

+0

假設我有一些斷言。我想解決這個問題,有時甚至沒有策略。我究竟應該如何實現這一目標?我可以爲他們兩個使用相同的求解器嗎? – Raj

+1

是的,我們可以將'Solver'對象中的斷言轉換爲'Goal'對象。這裏是一個關於如何做的例子:http://rise4fun.com/Z3Py/4j5 當我們將它轉​​換成一個'Goal'對象後,我們可以使用策略來解決它。 –

+0

親愛的Leo,我添加了一個C代碼,它可能會嘗試與您的Python代碼做同樣的事情。但它不起作用;你能幫我解決嗎?謝謝。 – Raj