用SMT solver驗證程序等價
過去十年,SMT(Satisfiability modulo theories)求解器在形式化方法、程序語言、軟體工程、以及計算機安全、計算機系統等領域得到了廣泛應用。。
本文以「驗證程序等價性」的例子,介紹SMT 求解器的簡單運用。 這裡將等價性定義為「給定相同合法輸入,有相同輸出「。考慮如下2個函數:
int power3_A(int in) {n int i, out_a;n out_a = in; n for (i = 0; i < 2; i++) n out_a = out_a * in;n return out_a;n}nnint power3_B(int in) {n int out_b;n out_b = (in * in) * in; n return out_b; n}n
如何證明power3_A, power3_B幹了同一件事情?一個傳統方法是寫測試用例,但是這2個程序的輸入int型整數取值範圍很大....
我們考慮基於形式邏輯的程序驗證。這個例子比較簡單,可以對power3_A做循環展開,然後用邏輯公式分別編碼power3_A, power3_B的程序語義(需要引入中間變數)。以上兩個程序分別編碼為 ,也就是
和
下面是證明「給定相同輸入,有相同輸出」。 等價性就轉化為判斷以下公式是永真的(VALID)
而要證明任意命題 永真,可以對 取反,然後證明 不可滿足(unsatisfiable)。
於是問題轉化為了判斷公式的可滿足性。SMT solver可以接受特定問題域公式如實數方程約束,判斷其可滿足性。我們需要建模整數(32位/64位)和乘法*,正巧很多SMT solver支持的bit-vector theory剛好適合。
附上代碼,使用z3 SMT solver的Python API的
from z3 import *n# 創建solver和邏輯變數nsolver = Solver()nout0a, out1a, out2a, out0b, In = BitVecs("out0a out1a out2a out0b In", 32)nn# 編碼A程序語義nfa = And(out0a == In, out1a == out0a * In, out2a == out1a * In)nn# 編碼B程序語義nfb = (out0b == In * In * In)nn# 證明程序等價,需要證明G永真(VALID)nG = Implies(And(fa, fb), out2a == out0b)nn# 轉化為可滿足性問題:將G取反後判斷其是否不可滿足(UNSAT)nsolver.add(Not(G))nprint solver.check()n
附錄:「假如我想使用SMT solver娛樂甚至做一些研究,「
- 需要學習數理邏輯么? 不需要
- 需要懂得SAT問題么? 不需要
- 需要了解CSP求解么?不需要
- 需要接觸符號計算么? 不需要
- ...
推薦閱讀:
※還在下圍棋?足球賽才是人工智慧進擊人類的真正目標
※「人工智慧入門」為什麼大家都在談論 AI?
※《人工智慧》第二周問題集2 tree search & graph search
※小雅音箱音樂功能設計、語音助手及知識圖譜 | AI產品經理閉門會第2期乾貨分享
※助理來也胡一川:深度學習在智能助理中的應用