私は、マイクロソフトのSMTソルバーであるZ3で帰納的事実を証明しようとしています。Z3ガイド(セクション8:データ型)で説明されているように、Z3は一般にこの機能を提供しないことを知っていますが、事実を証明したいドメインを制約すると、これが可能になるようです。次の例を考えてみましょう。
(declare-fun p (Int) Bool)
(assert (p 0))
(assert (forall ((x Int))
(=>
(and (> x 0) (<= x 20))
(= (p (- x 1)) (p x) ))))
(assert (not (p 20)))
(check-sat)
ソルバーは、で正しく応答します。unsat
これは、それが有効であることを意味し(p 20)
ます。問題は、この制約をさらに緩和すると(20
前の例では、20より大きい整数に置き換えます)、ソルバーが。で応答することunknown
です。
元の問題を解決するのにZ3に時間がかからないので、これは奇妙だと思いますが、上限を1つ上げると、突然不可能になります。次のように、数量詞にパターンを追加しようとしました。
(declare-fun p (Int) Bool)
(assert (p 0))
(assert (forall ((x Int))
(! (=>
(and (> x 0) (<= x 40))
(= (p (- x 1)) (p x) )) :pattern ((<= x 40)))))
(assert (not (p 40)))
(check-sat)
どちらがうまくいくように見えますが、現在の上限は40です。これは、Z3を使用してそのような事実を証明できない方がよいということですか、それとも問題を誤って定式化したのでしょうか。