Z3 используя цели и тактику

Я использую Z3 с C-API. Я пытаюсь понять, как понять, как использовать тактику и цель в C-API. Проверял на примерах 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);

Теперь я хочу применить некоторые тактики к моей цели. Однако я не могу понять, как именно должен следовать 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);

Но опять не работает.

Спасибо.


c z3
person Raj    schedule 17.09.2012    source источник


Ответы (1)


Z3 4.x поставляется с заголовочными файлами C++, которые значительно упрощают использование Z3 C API (файл include/z3++.h). Там же есть пример на C++ (файл examples/c++/example.cpp). Этот файл содержит множество примеров использования тактических объектов.

При этом к целям следует применять тактику. Для удобства мы также предоставляем API, который создает решатель из тактики Z3_mk_solver_from_tactic. Объект решателя, возвращаемый этим API, попытается решить запрос на выполнимость, используя заданную тактику.

person Leonardo de Moura    schedule 17.09.2012
comment
предположим, у меня есть некоторые утверждения. Я хотел бы решить то же самое иногда с тактикой, а иногда без тактики. Как именно я должен этого добиться? Могу ли я использовать один и тот же решатель для них обоих? - person Raj; 17.09.2012
comment
Да, мы можем преобразовать утверждения в объекте Solver в объект Goal. Вот пример того, как это сделать: rise4fun.com/Z3Py/4j5 После преобразования в объект Goal, мы можем решить его с помощью тактики. - person Leonardo de Moura; 18.09.2012
comment
Дорогой Лео, я добавил код C, который, возможно, пытается сделать то же самое, что и ваш код Python. Но это не работает; не могли бы вы помочь мне с этим? Спасибо. - person Raj; 18.09.2012
comment
В коде вашего вопроса есть несколько отсутствующих вызовов Z3_*_inc_ref. В принципе, вы должны вызывать этот тип API для каждого объекта, возвращаемого Z3. Ошибка, которую вы получаете, связана с нарушением доступа к памяти. Я настоятельно рекомендую вам использовать объекты-оболочки C++ в include/z3++.h. Они будут автоматически управлять счетчиками ссылок для вас. Примеры в examples/c++/example.cpp также очень полезны и иллюстрируют, как использовать эту оболочку. Другой вариант — API .Net или Python Z3. - person Leonardo de Moura; 18.09.2012
comment
Я вызываю Z3 из Java, используя JNI API. Поэтому я думаю, что для меня переход на C++ API займет некоторое время. Далее, я не уверен, решит ли это проблему? - person Raj; 18.09.2012
comment
API Z3_tactic_apply возвращает Z3_apply_result. При преобразовании и печати в строку он говорит false. Значит ли это, что это UNSAT? Также есть ли эквивалент в C-API для check-sat-using? Спасибо ! - person Raj; 18.09.2012
comment
Понимаю. Если вы используете Z3 из Java, то использование C++ API не сильно поможет. Я думаю, что управлять счетчиками ссылок вручную сложно. Можно ли использовать подход, аналогичный тому, что используется в API-интерфейсе Python для Z3. Исходный код API-обертки Python включен в дистрибутив Z3 (каталог python). - person Leonardo de Moura; 18.09.2012
comment
Что касается Z3_apply_result to_string API, он возвращает строку, начинающуюся с (goals. Затем он включает строковое представление каждой подцели. Если одна цель невыполнима, то она будет напечатана как false. - person Leonardo de Moura; 18.09.2012
comment
Что касается check-sat-using, вы можете использовать API Z3_mk_solver_from_tactic для преобразования тактики в объект Z3_solver. Вот как реализован check-sat-using. - person Leonardo de Moura; 18.09.2012