本發(fā)明涉及一種自動合成常用循環(huán)的摘要并生成程序規(guī)約的方法,主要解決循環(huán)語句的規(guī)約難以生成的問題,屬于軟件形式化方法領(lǐng)域。
背景技術(shù):
采用定理證明證明軟件的正確性是保障軟件可靠性的有效方法,采用定理證明進(jìn)行驗(yàn)證時(shí),首先通過某種斷言語言來描述程序的形式規(guī)約,然后根據(jù)斷言對程序進(jìn)行邏輯演算生成驗(yàn)證條件,最后借助于定理證明工具來證明驗(yàn)證條件的正確性。對于賦值語句、分支語句和順序語句而言,可以根據(jù)規(guī)則生成其規(guī)約,但是循環(huán)語句非常復(fù)雜,并沒有通用的規(guī)則可以為循環(huán)語句生成規(guī)約,對循環(huán)語句的分析一直是定理證明中的難點(diǎn)問題。
目前對循環(huán)語句的分析主要分為動態(tài)方法和靜態(tài)方法兩類。動態(tài)方法通過運(yùn)行程序跟蹤循環(huán)語句執(zhí)行過程中在特定程序點(diǎn)上變量之間的關(guān)系來發(fā)現(xiàn)循環(huán)不變式等規(guī)約,這類方法依賴于選取的測試用例集,生成的規(guī)約可能是錯誤的,后期需要人工排查。在靜態(tài)方法中,基于迭代不動點(diǎn)的方法通過計(jì)算程序的狀態(tài)轉(zhuǎn)換,當(dāng)發(fā)現(xiàn)程序狀態(tài)不再變化時(shí)認(rèn)為到達(dá)不動點(diǎn)。在這類方法中,計(jì)算過程的收斂是不可判定的,通常需要使用加寬算子、提高抽象力度來加速收斂,需要在效率和精度之間尋找合理的平衡點(diǎn)?;趨?shù)化模板的方法首先要指定目標(biāo)不變式的模板形式,其中模板的參數(shù)未知,然后使用不同的技術(shù)來求解參數(shù)。這類方法需要用戶指定模板的形式,一方面給用戶帶來負(fù)擔(dān),另一方面用戶可以提供的模板有限,這種方法適應(yīng)性不強(qiáng)。而且還受限于約束求解的能力。
技術(shù)實(shí)現(xiàn)要素:
技術(shù)問題:根據(jù)對一些開源軟件的統(tǒng)計(jì)分析,依次遍歷常用數(shù)據(jù)結(jié)構(gòu)的循環(huán)語句出現(xiàn)的頻率高達(dá)百分之八十,因此,本發(fā)明的目標(biāo)是為這類循環(huán)語句自動生成程序規(guī)約來輔助很多實(shí)際程序的驗(yàn)證過程。執(zhí)行一條語句產(chǎn)生的效果是修改有窮多個內(nèi)存中的內(nèi)容而保持其它內(nèi)存中的內(nèi)容不變。因此,本發(fā)明將循環(huán)語句抽象為修改的內(nèi)存以及循環(huán)執(zhí)行結(jié)束以后位于這些內(nèi)存中的新值,然后對抽象出來的信息進(jìn)行分析生成循環(huán)語句的規(guī)約。所生成的規(guī)約可以提高定理證明的自動化程度和效率,減輕驗(yàn)證人員提供規(guī)約的負(fù)擔(dān)。
技術(shù)方案:提出將程序語句修改的內(nèi)存和程序語句執(zhí)行結(jié)束以后存放在這些內(nèi)存中的新值作為該程序語句的摘要,其中內(nèi)存和新值的表達(dá)式都是在語句之前的程序點(diǎn)上進(jìn)行求值的,每一對內(nèi)存和新值的映射稱為摘要中的一個元組。本發(fā)明將修改的內(nèi)存分為兩大類,分別是單一內(nèi)存表達(dá)式以及集合內(nèi)存表達(dá)式,單一內(nèi)存表達(dá)式指的是一個單獨(dú)的內(nèi)存,而集合內(nèi)存表達(dá)式是形如λx.exp[set]的多個內(nèi)存表達(dá)式的集合。基于語句摘要的定義,本發(fā)明給出了自動合成包括操作常用數(shù)據(jù)結(jié)構(gòu)的循環(huán)語句在內(nèi)的程序語句的摘要的方法,然后通過對程序語句的摘要進(jìn)行分析來自動生成程序語句的規(guī)約,包括后置條件、循環(huán)不變式以及最弱前置條件,最后使用定理證明器來證明這些規(guī)約的正確性。本發(fā)明一種自動合成常用循環(huán)的摘要并生成程序規(guī)約的方法,包括以下步驟:
步驟1:對待處理的程序進(jìn)行解析,為其生成抽象語法樹(Abstract Syntax Tree,AST)。
步驟2:對步驟1生成的抽象語法樹進(jìn)行分析,分別生成賦值語句、分支語句、順序語句以及操作常用數(shù)據(jù)結(jié)構(gòu)的循環(huán)語句所修改的內(nèi)存以及這些程序語句執(zhí)行結(jié)束以后位于被修改的內(nèi)存中的新值,被修改的內(nèi)存和新值被視為該程序語句的摘要。
步驟3:通過對步驟2中生成的程序語句的摘要進(jìn)行分析生成相應(yīng)的程序語句的規(guī)約,包括前置條件、后置條件以及循環(huán)不變式。
步驟4:通過定理證明器Z3證明規(guī)約的正確性。
有益效果:本發(fā)明所述的自動合成常用循環(huán)的摘要的方法將程序語句抽象為語句所修改的內(nèi)存以及這些內(nèi)存中的新值,這些被修改的內(nèi)存以及新值可以作為語句低層次的規(guī)約,幫助驗(yàn)證人員理解程序語句的語義。語句摘要的價(jià)值主要分為兩大類:
(1)本發(fā)明根據(jù)循環(huán)語句的摘要可以將循環(huán)語句轉(zhuǎn)換為一系列抽象的賦值語句,從而可以使用分析賦值語句的方法來分析循環(huán)語句。傳統(tǒng)的限定循環(huán)迭代的次數(shù),使用加寬算子等方法是有精度損失的,而本發(fā)明的轉(zhuǎn)換方式是精確的,不會引發(fā)精度問題。
(2)本發(fā)明根據(jù)摘要給出了一種自動生成程序語句的高層次規(guī)約的方法,生成的規(guī)約包括后置條件、循環(huán)不變式以及最弱前置條件,這些規(guī)約可以有效地輔助程序的分析與驗(yàn)證工作,既可以減輕程序驗(yàn)證人員人工提供程序規(guī)約的負(fù)擔(dān)同時(shí)又可以提高驗(yàn)證程序的自動化程度和效率。具體而言,后置條件可以描述程序語句執(zhí)行前后程序狀態(tài)之間的關(guān)系,用于證明程序的性質(zhì),循環(huán)不變式可以有效地輔助證明循環(huán)語句的后置條件以及循環(huán)體內(nèi)部的斷言,最弱前置條件可以用于證明相應(yīng)后置條件的正確性。
附圖說明
圖1是自動合成常用循環(huán)的摘要并生成程序規(guī)約的方法的流程圖。
圖2是本發(fā)明實(shí)施例的循環(huán)程序。
圖3是本發(fā)明實(shí)施例的循環(huán)程序的循環(huán)體的摘要。
圖4是本發(fā)明實(shí)施例的循環(huán)程序的循環(huán)的摘要。
具體實(shí)施方式
下面結(jié)合實(shí)施例和說明書附圖對本發(fā)明做進(jìn)一步說明。
圖1是自動合成常用循環(huán)的摘要并生成程序規(guī)約的方法的流程圖。本實(shí)施例給出了一種自動合成常用循環(huán)的摘要并生成程序規(guī)約的方法。包括如下步驟:1.為待驗(yàn)證的程序生成抽象語法樹;2.分析抽象語法樹生成語句修改的內(nèi)存和新值生成語句的摘要;3.根據(jù)語句的摘要生成語句的規(guī)約;4.驗(yàn)證步驟3中生成的規(guī)約的正確性從而證明程序的性質(zhì)。
本實(shí)施例通過圖2中展示的循環(huán)程序?yàn)槔M(jìn)行詳細(xì)說明。
一.生成抽象語法樹
在具體實(shí)施中,本發(fā)明以C語言編寫的程序作為輸入,使用ANTLR為輸入的程序生成抽象語法樹。
二.合成語句的摘要
本發(fā)明對抽象語法樹進(jìn)行分析生成賦值語句、順序語句、分支語句以及操作常用數(shù)據(jù)結(jié)構(gòu)的循環(huán)語句生成摘要,具體如下:
1.賦值語句:假設(shè)賦值語句為e1=e2,那么該賦值語句修改的內(nèi)存即為e1的內(nèi)存地址,值為e2,其摘要表示為{<&e1,e2>}。
2.順序語句:假設(shè)順序語句為s1;s2,那么該順序語句修改的內(nèi)存即為語句s1修改的內(nèi)存和語句s2修改的內(nèi)存的并集,相應(yīng)的新值為順序語句執(zhí)行結(jié)束以后位于每個內(nèi)存單元中的值在順序語句s1;s2之前的程序點(diǎn)上的等價(jià)的表達(dá)形式。例如,圖2中循環(huán)體是一個包含四條賦值語句的順序語句,該順序語句的摘要如圖3所示。
3.條件語句:假設(shè)條件語句為if c then s1else s2,那么該條件語句修改的內(nèi)存即為then分支s1修改的內(nèi)存和else分支s2修改的內(nèi)存的并集。假設(shè)m表示條件語句修改的一個內(nèi)存,當(dāng)m被then分支修改時(shí),其新值用v1表示,當(dāng)m被else分支修改時(shí),其新值用v2表示,那么條件語句執(zhí)行結(jié)束以后位于內(nèi)存m中的新值分下面三種情況進(jìn)行計(jì)算:
(1)當(dāng)m同時(shí)被then分支和else分支修改時(shí),新值為c?v1:v2
(2)當(dāng)m僅被then分支修改時(shí),新值為c?v1:內(nèi)存中的值在s2之前的程序點(diǎn)上的等價(jià)的表達(dá)形式
(3)當(dāng)m僅被else分支修改時(shí),新值為c?內(nèi)存中的值在s1之前的程序點(diǎn)上的等價(jià)的表達(dá)形式:v2
4.循環(huán)語句:通過將循環(huán)體摘要中的一個元組進(jìn)行形式上的變換來生成循環(huán)語句摘要中的一個元組,假設(shè)<m,v>表示循環(huán)體摘要中的一個元組,根據(jù)m和v的形式分為下面兩種變換方式:
(1)當(dāng)m指向的內(nèi)存不會隨著迭代的執(zhí)行而改變時(shí):
在這種情況下,m也是被循環(huán)所修改的內(nèi)存,當(dāng)循環(huán)執(zhí)行結(jié)束以后位于內(nèi)存m中的新值可以按照如下兩種情況進(jìn)行求值:
a)v沒有被循環(huán)體修改時(shí),新值即為c?v:*m
b)v形如*mope或者eop*m,其中op是+、-、×、÷、∧、∨中的一個操作符,而且e在當(dāng)前迭代中的取值在當(dāng)前迭代開始之前沒有被修改過時(shí),可以通過尋找遞推關(guān)系來計(jì)算新值。例如,根據(jù)圖3中循環(huán)體摘要中的元組<&sum,sum+b[i]>可以生成循環(huán)摘要中的元組
(2)當(dāng)m指向的內(nèi)存隨著迭代的進(jìn)行而改變時(shí):
假設(shè)當(dāng)前迭代修改的內(nèi)存為m',當(dāng)前迭代執(zhí)行結(jié)束以后m'中的新值為v',那么當(dāng)m'和v'在當(dāng)前迭代開始之前沒有被修改過且m'中存放的值在當(dāng)前迭代之后不再被修改時(shí),那么<λx.(m[x/w])[set(w)],v[x/w]>是循環(huán)摘要中的一個元組,其中set(w)表示循環(huán)控制變量w的有效值域。例如,根據(jù)圖3中循環(huán)體摘要中的元組<&b[i],0>可以生成循環(huán)摘要中的元組<λx.(&b[x])[0,99],0>
4.1.循環(huán)體摘要中的某個元組可能并不滿足前面所述的條件,但將該元組中包含的部分子表達(dá)式替換為其對應(yīng)的等價(jià)表達(dá)式往往可以使得沒有滿足的條件變成滿足。例如,圖3中的元組<&a[i],sum+b[i]>就不滿足前面的條件,但是在當(dāng)前迭代開始之前sum的值為b[0]到b[i-1]的和,用這個求和公式替換sum,可以將元組<&a[i],sum+b[i]>替換為元組替換之后的元組滿足前面的條件,因此,可以合成循環(huán)語句摘要的元組
經(jīng)過前面的一系列步驟,就可以根據(jù)圖3中循環(huán)體的摘要生成圖4中循環(huán)的摘要。
三.生成語句的規(guī)約
本發(fā)明對步驟2中合成的語句的摘要進(jìn)行分析生成語句的規(guī)約,包括后置條件、循環(huán)不變式以及最弱前置條件。具體如下:
1.生成后置條件
本發(fā)明通過分析語句摘要中的一個元組<m,v>生成后置條件:
(1)當(dāng)m是單一內(nèi)存表達(dá)式時(shí),后置條件為*m==v@p
(2)當(dāng)m是集合內(nèi)存表達(dá)式且m形如λx.m′[set],后置條件為
2.生成循環(huán)不變式
本發(fā)明通過分析循環(huán)體摘要中的一個元組<m,v>生成循環(huán)不變式:
(1)當(dāng)m在每次迭代中都指向同一個內(nèi)存時(shí)
a)如果v在迭代執(zhí)行過程中不發(fā)生改變,那么循環(huán)不變式*m==v
b)如果v形如*mope或者eop*m,其中op是+、-、×、÷、∧、∨中的一個操作符,那么可以通過尋找遞推關(guān)系生成循環(huán)不變式。例如,根據(jù)圖3中循環(huán)體摘要中的元組<&sum,sum+b[i]>可以生成循環(huán)不變式其中p表示循環(huán)語句之前的程序狀態(tài)的編號。
(2)當(dāng)m是隨著循環(huán)控制變量的不同取值指向不同的內(nèi)存時(shí),本發(fā)明通過對內(nèi)存地址m中的循環(huán)控制變量進(jìn)行局部量化得到循環(huán)不變式。例如,根據(jù)圖3中循環(huán)體摘要中的元組<b[i],0>可以生成循環(huán)不變式
3.生成最弱前置條件
本發(fā)明通過遞歸地計(jì)算后置條件中每個子表達(dá)式位于某程序語句之前的程序狀態(tài)上的等價(jià)的表達(dá)形式來計(jì)算該后置條件關(guān)于該程序語句的最弱前置條件。等價(jià)的表達(dá)形式通過判斷子表示式中涉及到的內(nèi)存是否被程序語句所修改來計(jì)算,而語句摘要中包含了語句修改的內(nèi)存以及內(nèi)存中的新值,因此,本發(fā)明通過計(jì)算每個子表達(dá)式關(guān)于摘要中的每個元組的等價(jià)的表達(dá)形式來計(jì)算該子表達(dá)式關(guān)于語句的等價(jià)的表達(dá)形式。假設(shè)程序語句s之前的程序狀態(tài)用p進(jìn)行編號,s摘要中的元組用<m,v>表示,那么子表達(dá)式*e′關(guān)于元組<m,v>的等價(jià)的表達(dá)形式如下:
(1)當(dāng)m是單一內(nèi)存表達(dá)式時(shí),等價(jià)的表達(dá)形式為(m==e′)?v@p:*(e′@p)
(2)當(dāng)m是集合內(nèi)存表達(dá)式且m形如λx1·(...(λxk·m′[setk])...)[set1],如果存在n個表達(dá)式e1、e2、...、en,使得表達(dá)式e′和將核心m′中的變量x1、x2、...、xn替換為e1、e2、...、en得到的表達(dá)式相同,那么公式e∈m成立當(dāng)且僅當(dāng)對于任意的i=1,2,...,n有ei∈seti成立。在這種情況下,等價(jià)的表達(dá)形式為((e1∈set1)∧(e2∈set2)∧...∧(en∈setn))@p?(v[e1/x1][e2/x2]…[en/xn])@p:*(r′@p)
四.驗(yàn)證規(guī)約的正確性
本發(fā)明通過定理證明器Z3來驗(yàn)證步驟3中所生成的規(guī)約的正確性,保留經(jīng)過證明是正確的規(guī)約。借助步驟4中生成的規(guī)約驗(yàn)證語句的性質(zhì)。
本發(fā)明通過將操作常用數(shù)據(jù)結(jié)構(gòu)的循環(huán)語句轉(zhuǎn)換為一系列抽象的賦值語句,有效地對這類循環(huán)語句進(jìn)行了抽象,使得可以使用賦值語句的分析方法來分析循環(huán)語句。本發(fā)明根據(jù)語句的摘要所生成的程序規(guī)約有效地描述了程序的性質(zhì),尤其是程序執(zhí)行前后程序狀態(tài)之間的關(guān)系,這些規(guī)約高效地輔助了程序的驗(yàn)證過程,提高程序驗(yàn)證的自動化程度和效率,減輕驗(yàn)證人員的負(fù)擔(dān)。
本發(fā)明已以較佳實(shí)施例公開如上,但它們并不是用來限定本發(fā)明,凡不脫離本發(fā)明之精神和范圍內(nèi),自當(dāng)可作各種變化或潤飾,因此本發(fā)明的保護(hù)范圍應(yīng)當(dāng)以本申請的權(quán)利要求保護(hù)范圍所界定的為準(zhǔn)。