разкриване на разликата между слаби променливи и оригинални променливи в Z3

Опитвам се да създам нов вид изрязване, за да заменя изрязванията на gomory, внедрени в Z3. Проектирах моя разрез да работи с първоначалното ограничение, въведено от потребителя. За съжаление открих, че Z3 предварителната обработка на ограниченията добавя променливи за отслабване и променя структурата на ограниченията. Мога да адаптирам алгоритъма си, за да работи със структурата на ограничения Z3 и променливите за отслабване, но важна част от алгоритъма изисква да се знае кои променливи са променливи за застой и кои са оригинални променливи. Не можах да намеря нищо в изходния код на Z3, което да ми помогне да направя това. Опитах също да потърся онлайн решение, но не можах да намеря нищо.

Някой знае ли как може да стане това?

Благодаря


z3
person omerkatz    schedule 09.04.2013    source източник
comment
Добавяте ли своите съкращения, преди да извикате Z3? Или модифицирате класа theory_arith? Разгледахте ли файла src/smt/theory_arith_int.h?   -  person Leonardo de Moura    schedule 09.04.2013
comment
Опитвам се да модифицирам класа thoery_arith. Вече проучих файла 'src/smt/theory_srith_int.h' и кода в него, който генерира gomory cuts, но не намерих отговор на моя проблем в този файл   -  person omerkatz    schedule 09.04.2013


Отговори (1)


В метода mk_gomory_cut(row const & r) във файл src/smt/theory_arith_int.h, r е ред от симплексната таблица. Освен това базовата променлива x_i е цяло число, но е присвоена на нецелочислена стойност.

Итераторът it се използва за обхождане на записите в реда. Всеки запис е по същество двойка a_ij и x_j, където a_ij е число, а x_j е (теоретична) променлива.

Theory_arith е плъгин за решаващия инструмент, дефиниран във файла src/smt/smt_context.h. Този софтуер за решаване комбинира много теоретични плъгини като theory_arith. Той поддържа картографиране от изрази към теоретични променливи. Това съпоставяне се съхранява в обект, наречен enode.

Методът get_enode(v) извлича енода, свързан с теоретичната променлива v. Освен това get_enode(v)->get_owner() връща израза, свързан с теоретичната променлива v.

Сега да предположим, че искаме да проверим дали една теоретична променлива v е застой или не. Първо, можем да извлечем свързания израз, като използваме:

   app * t = to_app(get_enode(v)->get_owner())

Използвах to_app, защото теоретичните добавки обработват само основни термини (т.е. не съдържат свободни променливи). Променливата v е застой, ако t е съставен аритметичен термин като (+ a b) или (* a b c). Това означава, че слабината е по същество „име“ за съставен аритметичен термин. Можем да тестваме това с помощта на:

  t->get_family_id() == get_id()

Ако този израз се изчисли на true, тогава t е съставен аритметичен член и следователно v е пропуск.

Забележка: get_id() е метод на theory_arith. Всъщност всеки теоретичен плъгин има този метод.

person Leonardo de Moura    schedule 09.04.2013