На практике для большинства таких задач оптимизации требуется своего рода внешний драйвер повторения до максимума/минимума поверх решателя SMT. Также возможны количественные подходы, которые могут использовать определенные возможности решателей SMT, но на практике такие ограничения оказываются слишком жесткими для базового решателя. В частности, см. это обсуждение: Как оптимизировать часть кода в Z3? (связано с PI_NON_NESTED_ARITH_WEIGHT)
При этом большинство языковых привязок высокого уровня включают в себя необходимые механизмы для упрощения вашей жизни. Например, если вы используете библиотеку Haskell SBV для сценария z3, вы можете иметь:
Prelude> import Data.SBV
Prelude Data.SBV> maximize Quantified head 2 (\[x, y] -> x.==3 &&& y.>=1)
Just [3,1]
Prelude Data.SBV> maximize Quantified (head . tail) 2 (\[x, y] -> x.==3 &&& y.>=1)
Nothing
Prelude Data.SBV> minimize Quantified head 2 (\[x, y] -> x.==3 &&& y.>=1)
Just [3,1]
Prelude Data.SBV> minimize Quantified (head . tail) 2 (\[x, y] -> x.==3 &&& y.>=1)
Just [3,1]
Первый результат утверждает, что x=3, y=1 максимизирует x по отношению к предикату x==3 && y>=1. Второй результат говорит о том, что не существует значения, максимизирующего y относительно того же предиката. Третий вызов говорит, что x=3,y=1 минимизирует предикат относительно x. Четвертый вызов говорит, что x=3,y=1 минимизирует предикат относительно y. (См. http://hackage.haskell.org/packages/archive/sbv/0.9.24/doc/html/Data-SBV.html#g:34 для подробностей.)
Вы также можете использовать опцию «Итеративная» (вместо количественной), чтобы библиотека выполняла итеративную оптимизацию вместо использования квантификаторов. Эти два метода не эквивалентны, так как последний может застрять в локальных минимумах/максимумах, но итерационные подходы могут решить проблемы, когда количественная версия слишком велика для решения SMT.
person
alias
schedule
30.01.2012