Mam ten sam problem. Bardziej szczegółowo, to potrzebne funkcje:
Z3_ast Z3_mk_bvredxnor(Z3_context ctx, Z3_ast t)
który wykonuje XNOR nad wszystkimi bitami o bitvector podanym w argumencie funkcji i zwraca bitvector długości 1.
Ponieważ ta funkcja nie jest dostępna istnieje w API, zacząłem używać:
Z3_ast mk_bvredxnor(Z3_context ctx, Z3_ast t)
{
size_t i;
size_t s = Z3_get_bv_sort_size(ctx,Z3_get_sort(ctx,t));
Z3_ast ret = Z3_mk_extract(ctx,0,0,t);
for(i=1;i<s;i++)
ret = Z3_mk_bvxnor(ctx,ret,Z3_mk_extract(ctx,i,i,t));
return ret;
}
Następnie, próbując zdebugować moje ograniczenia był koszmar.
Więc wymyśliłem:
Z3_func_decl getBvredxnorDecl(Z3_context ctx, int size)
{
static bool sizes[64]={0};
static Z3_func_decl declTab[64]={0};
if(sizes[size])
return declTab[size];
Z3_sort bv_size = Z3_mk_bv_sort(ctx, size);
Z3_sort bv1 = Z3_mk_bv_sort(ctx, 1);
stringstream buff;
buff << "bvredxnor" << size;
Z3_symbol var_name = Z3_mk_string_symbol(ctx,"X");
Z3_symbol func_name = Z3_mk_string_symbol(ctx, buff.str().c_str());
Z3_func_decl bvredxnorDecl = Z3_mk_func_decl(ctx,
func_name,
1,
&bv_size,
bv1);
declTab[size]=bvredxnorDecl;
Z3_ast b = Z3_mk_bound(ctx,0,bv_size); /* bounded variable */
Z3_ast bvredxnorApp = Z3_mk_app(ctx,bvredxnorDecl, 1, &b);
Z3_pattern pattern = Z3_mk_pattern(ctx,1,&bvredxnorApp);
Z3_ast bvredxnor_def = mk_bvredxnor(ctx,b);
Z3_ast def = Z3_mk_eq(ctx,bvredxnorApp,bvredxnor_def);
Z3_ast axiom = Z3_mk_forall(ctx,0,1,&pattern,1,&bv_size,&name,def);
Z3_assert_cnstr(ctx,axiom);
return bvredxnorDecl;
}
Z3_ast bvredxnor(Z3_context ctx, Z3_ast t)
{
int size = Z3_get_bv_sort_size(ctx,Z3_get_sort(ctx,t));
return Z3_mk_app(ctx,getBvredxnorDecl(ctx,size),1, &t);
}
żadnych uwag do poprawy byłoby to mile widziane. W tym czasie, to rozwiązuje problem miałem here
robi trick, ale complexify mojego modelu ...
Również zastanawiam
- Ponieważ to wszystko zrobić programowo, I załóżmy, że MACRO_FINDER = TRUE nie będzie miało żadnego wpływu (ponieważ jest to krok przetwarzania).
- Ponieważ MBQI jest domyślnie włączony, nie ma potrzeby go aktywować, prawda?
Dziękuję za szczegółową odpowiedź. Korzystanie z uniwersalnego kwantyfikatora jest zdecydowanie fajną sztuczką. Zastanawiam się nad kosztami stosowania uniwersalnych kwantyfikatorów i funkcji niezinterpretowanych. Moje ograniczenia w postaci skwantyfikowanych LIA teraz zamieniają się w kwantyfikowane formuły UFLIA. Czy ta zmiana mocno wpłynęła na czas rozwiązania Z3? – pad
Tak, formuła będzie w 'UFLIA', ale jest w rozstrzygającym fragmencie UFLIA. Jeśli użyjesz opcji 1 ('MACRO_FINDER = true'), wpływ na wydajność powinien być bardzo mały. Z3 wykryje te kwantyfikatory jako makra i wyeliminuje kwantyfikatory i wszystkie wystąpienia pomocniczych funkcji niezinterpretowanych. Zatem po wstępnym przetworzeniu wynikowy problem będzie w 'QF_LIA'. Wpływ wydajności opcji 2 ('MBQI') nie jest jasny, w niektórych problemach Z3 może być szybszy, ale w innych znacznie wolniejszy. –
Dzięki! Dla wyjaśnienia, moje oryginalne formuły są LIA z kwantyfikatorami i chcę użyć eliminacji kwantyfikatorów LIA, aby je rozwiązać. Opcja 1 wydaje mi się bardziej interesująca i wkrótce będę z nią eksperymentować. – pad