IC3算法中的get_state, get_predecessor, generalize

IC3算法中的get_state, get_predecessor, generalize

在上一篇“IC3算法简析”中出现了几个函数,它们能确保IC3算法的高效实现,分别是:

  • get_state()
  • get_predecessor()
  • generalize()

get_state()

\(get\_state(F[k] \land \neg P)\)函数的直观含义是“计算公式\(F[k]\)所表示的状态集合与\(\neg P\)所表示的坏态集合的交集”。
使用\(get\_state(F[k] \land \neg P)\)之前,应该确保\(F[k] \land \neg P\)是可满足的,也就是说公式\(F[k]\)所表示的状态集合与\(\neg P\)所表示的坏态集合存在交集。
使用一个cube来表示该交集,即有\(c = get\_state(F[k] \land \neg P)\) ,该cube也被称为counterexample
因为\(c\)(cube/公式)表示的集合是\(F[k]\)\(\neg P\)的交集,因此有\(c\models F[k]\land \neg P\)可满足。只需找到一个\(c\),当\(c\)满足时,\(F[k]\land \neg P\)也满足。

如何获取counterexample \(c\)

在上面说到,要确保\(F[k] \land \neg P\)是可满足的。
检查公式的满足性,需要调用SAT求解器。
\(F[k] \land \neg P\)可满足,则\(is\_sat(F[k] \land \neg P)\)返回sat。
同时SAT求解器可以返回一种“该公式可满足情况下每个变量的赋值情况”。
例如: \(is\_sat( x_1\land \neg x_2)\)是可满足的,SAT求解器还可以返回\([ x_1 == True, x_2 == False]\)(公式满足时每个变量的赋值情况,也被称为model
根据model,构造一个cube: 如果变量\(x_i\)\(True\),则构造文字(literal)\(x_i\);如果变量\(x_i\)\(False\),则构造文字(literal)\(\neg x_i\),再将所有构造的文字(literal)进行合取(\(\land\))。
例如,根据上述例子中的model可以构造的\(cube\)\(x_1\land \neg x_2\)
同理,对于\(is\_sat(F[k] \land \neg P)\)也可以如此构造一个对应的cube, 把这个得到cube作为\(c\)
这样的\(c\)包含所有状态变量,因此只能表示一个状态(亦即这种简单方法构造的\(cube\)只是所求交集中的一个)。
\(get\_state()\)位于while循环中,可以循环地求出交集中的所有状态。

get_predecessor()

\(rec\_block()\)函数中,如果删除坏态集合\(s\)之后,序列条件4:

\[ F[i-1]\land \neg s \land T \models F[i]' \land \neg s' \]

不能够成立,即\(is\_sat(F[i-1]\ \land\ \neg s\ \land\ T\ \land\ s')\)可满足。
说明在(\(F[i-1] \land \neg s\))所表示的状态集合中,还有一部分状态\(q\)无法一步迁移到(\(F[i]\ \land\ \neg s\)
这部分状态需要继续调用\(rec\_block()\)函数进行删除(blocking)。
如何获取这一部分状态\(q\)
简单的办法是:参考上述\(get\_model()\)方法中获取状态集合的做法。
因为\(is\_sat(F[i-1]\ \land\ \neg s\ \land\ T\ \land\ s')\)可满足
则必有公式\(F[i-1]\ \land\ \neg s\)所表示的状态集合中的一个状态\(c\)使得上述公式满足。
因此,可以取\(is\_sat(F[i-1]\ \land\ \neg s\ \land\ T\ \land\ s')\)公式满足的情况下的状态变量的一种赋值情况。
又因为该状态\(c\)位于公式\(F[i-1]\ \land\ \neg s\)所表示的集合中,所以\(c\)只含有公式\(F[i-1]\ \land\ \neg s\)所包含的状态变量。
所以在取得\(is\_sat(F[i-1]\ \land\ \neg s \land\ T\ \land\ s')\)sat model后,还要去除\(s'\)中的变量,即去除带prime符号的后继变量。
最后得到的\(c\)也只含有一个状态,但\(get\_predecessor()\)位于while循环中,故可以循环地去除\(q\)中的所有状态。

generalize()

inductive clause generalization

\(\neg g=generalize(\neg s,\ i)\)的作用是:计算出一个\(clause\)\(\neg g\)。这个\(\neg g\)中所包含的文字(literal)是\(\neg s\)所包含文字的子集,而且将\(\neg g\)添加到\(F[1],\dots, F[i]\)中之后,新的frame序列仍然能够满足序列条件(4)。
\(generalize\)的作用是将原本只包含很少状态(例如,一个状态)的\(cube\)规约到包含较多状态的\(cube\)(同时满足序列条件),例如上述两个函数中,求得最后的\(c\)之后,可以使用类似于\(generalize\)的过程进行处理。
generalize过程已经有多种版本的实现。

  1. Minimal inductive clause (MIC)-based inductive generalization
    A. R. Bradley and Z. Manna, “Checking safety by inductive generalization of counterexamples to induction,” in Proc. Int. Conf. Formal Methods Comput.-Aided Design (FMCAD), Austin, TX, USA, 2007, pp. 173–180.

  2. Iterative inductive generalization algorithm
    N. Eén, A. Mishchenko, and R. K. Brayton, “Efficient implementation of property directed reachability,” inProc. Int. Conf. Formal Methods Comput.-Aided Design (FMCAD), Austin, TX, USA, 2011,pp. 125–134.

  3. Counterexamples to generalization (CTG)-based inductive generalization
    Z. Hassan, A. R. Bradley, and F. Somenzi, “Better generalization in IC3,” in Proc. Int. Conf. Formal Methods Comput.-Aided Design (FMCAD), Portland, OR, USA, Oct. 2013, pp. 157–164.

  4. simple generalization
    一种简单的实现如下:

clause generalize(!s, i):
    cls = !s   
    for each l in !s do:
        trycls = the clause obtained by deleting l from cls
	if is_sat(I=>trycls) and is_sat(F[j-1] & T & trycls => trycls'):
	    cls = trycls
    return cls

可以看到,\(generalize\)算法尝试对\(\neg s\)中的文字(literal)逐个去除
同时确保序列条件能够得到满足。
其中\(is\_sat(I\Longrightarrow trycls)\)是保证序列条件3能够满足。

posted @ 2020-12-13 17:28  bacmive  阅读(476)  评论(0编辑  收藏  举报