実際には、このような最適化問題のほとんどは、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==3 && y>=1 に関して x を最大化します。2 番目の結果は、同じ述語に関して y を最大化する値がないことを示しています。3 番目の呼び出しでは、x=3,y=1 が x に関する述語を最小化します。4 番目の呼び出しでは、x=3,y=1 が y に関して述語を最小化します。(詳細については、 http://hackage.haskell.org/packages/archive/sbv/0.9.24/doc/html/Data-SBV.html#g:34を参照してください。)
オプション "Iterative" (Quantified の代わりに) を使用して、量指定子を使用する代わりに、ライブラリに反復的に最適化を実行させることもできます。これら 2 つの手法は同等ではありません。後者は極小値/極大値にとらわれる可能性があるためです。ただし、定量化されたバージョンが SMT ソルバーで処理するには多すぎる場合、反復的なアプローチによって問題が解決される可能性があります。