パートA:基本的な命題論理
このモジュールでは、z3を使用して基本的な命題論理の問題を解決する方法を学びます。
提案の声明:
ブール型の2つの命題を宣言できます。もちろん、これら2つの命題にはtrueまたはfalseの2つの値があります。命題PとQを次のように宣言します。
P = Bool('P')
Q = Bool('Q')
または、短い形式を使用できます。
P, Q = Bools('P Q')
接続詞を使用して命題を作成します。
Z3は、接続詞/ \(And)、\ /(Or)、〜(Not)、->(Implies)などをサポートします。lispスタイルで抽象構文木を書くことで命題を作成できます。たとえば、この論理和は次のとおりです。
P \ / Q(接続詞\ /はZ3でOrとして記述されます)は、ASTでは次のように記述されます。
F = Or(P, Q)
解決の使用:
例A-1: z3での最も簡単な使用法は、命題をz3に直接記述し、solve()関数を呼び出して充足可能性をチェックすることです。このsolve()関数は、命題の充足可能性をチェックするソルバーインスタンスを作成し、出力します。命題が満たされる場合のモデルの場合、コードは次のとおりです。
F = Or(P, Q)
solve(F)
上記の呼び出しにより、z3の出力は次のようになります。
[P=True, Q=False]
このモデルは、命題Fを満たす命題PとQの結果です。明らかに、これはいくつかの可能なモデルの1つにすぎません。
例A-2:次の命題のように、すべての命題が充足可能であるとは限りません。
F = And(P, Not(P))
solve(F)
Z3は以下を出力します:
no solution
これは、命題Fが満たされないこと、つまり、Pの値が何であっても、命題Fを確立できないことを示しています。
より多くの解決策を得る:
例A-1の質問例を見てみましょう。
F = Or(P, Q)
solve(F)
デフォルトでは、Z3は真理値表の最初の行のみを出力します。
P Q P\/Q
-----------------
t t t
t f t
f t t
f f f
つまり、Z3を使用して命題の充足可能性をテストし、1行の出力で十分です。しかし、数行を出力したい場合はどうでしょうか。ここに秘訣があります。答えが得られたら、その答えを否定し、元の命題と組み合わせて、その充足可能性を確認します。上記の例の場合:
F = Or(P, Q) # 命题F
solve(F) #输出一个结果
F = And(F, Not(And(P, Not(Q)))) # 对答案进行否定(Not)、然后与原命题F结合(And)
solve(F)
F = And(F, Not(And(Not(P), Q))) # 对答案进行否定(Not)、然后与原命题F结合(And)
solve(F)
F = And(F, Not(And(P, Q))) # 对答案进行否定(Not)、然后与原命题F结合(And)
solve(F)
出力には、3つの可能な解決策が含まれます。
[P = True, Q = False]
[P = False, Q = True]
[P = True, Q = True]
no solution
演習1:
Question: (P /\ Q) \/ R
P, Q, R =Bools('P Q R') # Exercise1
F = Or((And(P, Q)), R)
solve(F)
演習1-2:
質問:P \ /(Q \ / R)
P, Q, R = Bools('P Q R') # exercise1-2
F = Or(P, Or(Q, R))
solve(F)
演習1-3:
質問:(P \ / Q)/ \(Q / \ R)/ \(P / \ 〜R) P、Q、R = Bools( 'PQ R')#exercise1-3 S = And(P、Not( R)) M = And(Q、R) N = Or(P、Q) F = And(N、And(M、S)) solve(F)
输出:no solution
演習1-4:
質問: (P / \ 〜S / \ R)/ \(R / \(〜P \ /(S / \ 〜Q)))
P、Q、R、S = Bools( 'PQR S') #左 A = And(Not(S)、R) B = And(P、A) #右 C = And(S、Not(Q)) D = Or(Not(P)、C) E = And(R、D) #左右 F = And(B、E) solve(F)
输出: no solution
演習1-4:
質問:すべての結果を出力します(P / \ Q)\ / R
#中科大软院-形式手法ノート-プライベートメッセージ交換