Angluins L*算法 学习笔记
简介:
这个算法的目标:构造DFA或者Mealy automate,使之同一个Black system吻合。这个算法假定了一个“teacher”的角色,他是先知,知道这个黑盒SUL的一切。在构造过程中我们可以问老师二种类型的问题。一是称为membership query成员查询, 对于构造Mealy automate来说就是输入某个字串,SUL输出什么?(对于DFA来说,对应于回答这个字串是否被SUL接受,如果接受输出1,否则为0);第二种称为equivalence query(等价查询),即目前构造的DFA或者Mealy自动机和SUL是否等价,如果等价,则Teacher回答yes,否则也返回一个反例字串,来说明他们的不同。
说这个算法前,我先说说我对“Teacher”的理解,默认构造Mealy自动机,举例:一台电视机,把他当做SUL,则你的按键操作(输入)都能得到一个可见的显示效果(输出),所以成员查询是很简单的就能实现;而对于等价查询,只要穷举所有的按键操作的组合,如果都符合,则等价,回答yes,否则就把对应的不同的按键组合返回出去就可以了。所以Teacher这个角色是可行的。【这个算法唯一值得商榷的地方就是他的普适性,这个黑盒子首先要能用DFA或者mealy自动机来表示】
为了清晰的说明算法精髓,先介绍一下几个概念, 一是OT表( observation table),OT表是算法的中间产物,最后算法生成的OT表将直接对应于SUL。OT表行坐标row分二大区域,一个是构造的Mealy自动机的状态S区域,另外一个是SUI,这里的I是指输入基本字的集合(即电视机的单个按键),我们称其为辅助行区域 SUI;而OT表的纵坐标为E,一般就是指基本字的集合,一般为一个字串的后缀;而OT表的内容就是由行r和列e加起来的字串w所对应的SUL的输出T(w),这个通过成员查询可以很方便的求出。 二是关于算法中的二个特别重要的性质,所谓一致性和闭包性,所谓闭包性形象的理解就是辅助行区域T( SUI)在T(S)中,否则就在S域中添加 SUI中不包含在原S域中对应的行标签及其所有前缀;所谓一致性就是指如果S域中二个行标签如果对应的值相同,则其加入同一个基本字a作为后缀,其值也要相同,否则为了区别这两个状态,需要在E中添加这aUe。所谓 Angluins L*算法就是不断的通过询问的方式来更新OT表,使其得到一致性和闭包性并被SUL接受为止。下图为 Angluins L*算法的主体框架图:【初始化的时候,S为空,辅助表为 SUI, E一般取I即输入集合】
L*算法从输出集合中递增的构造一个观察表(observation table)。这个表的行标签被定义为S U S ⋅ I,这里的S指的是非空有限且前缀闭包的语言,表的列标签被定义在一个非空有穷且后缀闭包的语言E上。形式上,一个观察表格可以由三元组(S,E,row)表示,这里的row:S U (S ⋅ I)—>(E)。给定一个前缀w和一个后缀e,row(w)(e)返回的是对应we的成员查询SUL最后的输出。初始阶段,S只包含空字 ε,且E为整个输入集合I.
观察表在重构Mealy machine的过程中的的二个最重要的性质:封闭性和一致性。对于所有的w ∈ S ⋅ I且有如果 w′ ∈ S 有 row(w) = row(w′),我们称观察表(S,E,row)封闭;如果每当对于有些, w2 ∈ S,有row(w1) = row(w2) , 然后对于所有的 a ∈ I,有row(w1a) = row(w2a)我们就称观察表是一致的。
如果一个表示封闭且一致的,则构建者(learner)构造的Mealy machine H = (I, O, Q, q0, δ, λ) with Q = {row(w) | w ∈ S}, q0= row(ε), δ(row(w), a) = row(w ⋅ a), and λ(row(w), a) = row(w)(a).
实例:
下面用一个例子来说算法的运行过程:第一步初始化表OT,如下图,其中的A、B为通过成员查询SUL的输出
然后检查这个OT表的一致性和闭包性,明显都满足,现在就要构造对应的模型了M(S,E,T),具体的构造过程很简单,S域的每一个行标签对应为一个状态【辅助区域可以完全不看了】,然后直接看对应的E区域的列标签(即基本字)所得到的值(即该基本字所对应的输出)
构造好了后,就问Teacher,我这个对否,结果Teacher返回说,不对,字串bba,SUL输出是C,而你输出是A;这个时候,算法就将 bba这个字串及其所有前缀添加进OT表的S域,当然同时要需要更新辅助域,规则就是SUI即可然后重新经过成员查询得到OT表的值,如下图所示:
这个时候明显可以看到,T(SUI)都包含于T(S),所以是闭包的,但是检查一致性的时候发现,在S域T( ε)和T(b)都一样是A B,可是其加上同一个后缀b,这个时候T(b)和T(bb)不同,一个是A B,一个是C B,所以不满足一致性,则需要在E中添加bUe即ba【??按照定义,应该还有bb呀?我的理解是一次只能添加一个,可以是ba,也可以是bb】,然后通过成员查询,得到OT表中所有的值:
明显可以看出该OT表即一致又闭包,这个时候就可以生成模型M(S E T)了,构造方法前面说明了,如下图【其中bba和b可以合成一个状态q1】
通过询问Teacher,M和SUL是否等价,得到yes回答,则将上图作为SUL的等价模型。
扩展:Model Learning
2017年 Communications of the ACM 发表一篇题为《Model Learning》的文章,详细介绍了模型学习及其研究现状和应用。下文选取相关内容作为Angluins L*算法的补充说明。
1987 年,Angluin 发表了一篇研讨论文,她表明可以使用所谓的会员查询(membership query)和等价查询(equivalence queries)来学习到有限自动机。自此之后,尽管提出了更快算法,但最有效的学习算法依然遵循着 Angluin 所提出的 MAT(minimally adequate teacher/最低限度足够的教师)的原则。在 MAT 框架中,学习被看作是一个博弈(game),其中学习器(learner)必须通过询问教师(teacher)来推断一个未知的状态图的行为。在我们的设定中,教师知道状态图,其被称为 Mealy 机(Mealy machine),简称:M。首先介绍一下Meal有机
一开始,学习器只知道 M 的输入 I 和输出 O。学习器的任务是通过两种类型的查询学习 M:
- 使用会员查询 (MQ/membership query):学习器询问输入序列σ ∈ I*对应的输出结果是什么。教师使用输出序列 AM(σ) 来回答。
- 使用等价查询 (EQ/equivalence query):学习器询问一个带有输入 I 和输出 O 的虚拟的 Mealy 机 H 是否正确,即:H 和 M 是否等同。如果情况属实,教师回答「是」。否则教师回答「否」,并提供一个反例σ ∈ I*来区分 H 和 M。
Angluin 的 L*算法能够通过询问会员查询和等价查询的多项式数(多项式数的大小对应于典型的 Mealy 机)来学习 Mealy 机 M。在 Angluin 的算法中我们给 L*做了一个简化,实际的实现中(例如 LearnLib 和 libalf)则包含很多优化。
MAT 框架可以用来学习软硬件组件的黑箱模型。假设我们有一个组件,我们称之为系统学习(SUL),其行为可以由(未知的)Mealy 机 M 描述。我们进一步假设,总是可以使 SUL 回到其初始状态。现在,通过使 SUL 回到初始状态并进一步观察给到 SUL 的输入序列所对应的输出结果可以实现会员查询。等价查询可以通过有限数量的测试查询(TQ/test queries)以使用一致性测试(CT/conformance testing)工具来接近。测试查询询问 SUL 对输入序列的响应,类似于会员查询。如果其中一个测试查询呈现反例,则等价查询的答案为否,否则答案为是。示意图如图 4 所示。在这种方法中,学习者的任务是构造假设,而一致性测试工具的任务是测试这些假设的有效性。由于测试工具只能构造有限数量的查询,因此我们无法确定一个学习模型的正确性。然而,如果我们假定机器 M 的状态数量有界限,则存在有限和完整的一致性测试套件。
扩展:Angluin’s Learning 算法一窥
内容概要:
- 对于特定代码,一些静态或者动态的代码分析技术可以用于主动生成测试套件,但静态分析的过程会受限于当前源代码的语法实现。
- 最合理的办法是:减少向系统询问当前句子是否属于这个状态机,从而生成符合该语言的状态机。
- 经典的 Angluin 算法指出了对于具有如下两个特征的系统,可以自动生成其对应的有限状态机:。
在计算机科学之中,有很多程序、算法都是围绕有限状态机(finite-state machines)来描述。最主要的使用应用场景有如下几个:
描绘工作流式流程或者状态,比如:在通信领域中的利用 SDL 语言来描述 FSM 对象,设计网络通信协议;
正则表达式对字符串进行模式匹配,比如:KMP;
计算机编译器之中的词法分析、语法分析;
一些由简单事件驱动的状态,比如:游戏之中的 NPC 设计等等。
状态机可以应用于模型验证、代码生成、基于模型的测试生成等。
上述场景都要求在当前客观领域内对于目标系统有初步的描绘,比如:在使用正则表达式的时候需要首先协调得到合适的状态转换图来描述当前的需求。
Angluin s 算法之道
在实际系统的迭代过程之中,我们并不一定能合理的对当前实际问题进行合理建模或者对于后续系统当前建模成果已经过时不能够满足迭代过程中的系统需求了。
既然 DFA 存在有限的状态,那么是否我们可以通过更少的人工干预、更多自动化的步骤来生成相应的模型?对于最极端的情况而言,一个模型可以根据其先验条件自动生成,也可以利用自动生成的状态机与当前所处的有效状态进行对比,从而验证当前系统所处的状态是否处于合理的区间之中。对于特定代码,一些静态或者动态的代码分析技术可以用于主动生成测试套件,但静态分析的过程会受限于当前源代码的语法实现。
最合理的办法是:减少向系统询问当前句子是否属于这个状态机,从而生成符合该语言的状态机。这类似于分析代码过程中通过其一系列的输入输出结果、调用路径来理解其功能。
Angluin s 算法为何物?
Angluin s Learning Algorithm 就是根据这样的思想设计的。 经典的 Angluin 算法指出了对于具有如下两个特征的系统,可以自动生成其对应的有限状态机:
一系列可以输入系统的动作;
系统能对于这些特定的行为做出特定响应。
Angluin s Learning Algorithm 之中假定了当前系统中的状态机 DFA A描述并且可以被一系列的状态进行描绘,定义为L(A)。 于是,一个状态机的 learner 通过向 A 发出一系列的请求,比如:发出一些列的提问信息。
membership query(会员查询):向系统请求String message是否属于L(A)
equivalence query(等价查询):通过问题与获得结果生成相应的状态信息结果,或者返回当前所有结果正确的概括
Angluin s Algorithm 的标准行为是通过询问一系列的 membership query 从而建立假定的 DFA 模型,当这个假定的模型逐步稳定下来时则发出 equivalence query 来判断当前的模型是否合理并对模型进行修正,从而通过一系列的步骤得到更新的模型。
在这一过程之中 query 得到的中间结果描述为到集合 to 的一个映射并将其转换为目标状态机。转换过程可以通过定义query 到语法的映射来实现。
在 Angluin’s algorithm 之中保有一个前缀闭集 S 以及后缀闭集 E 持有对应的输入行为。它的初始状态为空,并随算法执行的过程逐步扩张。在一个具有完备性以及一致性的集合O之中,模型 M 代表了状态机的指定状态于集合中的属性相等价。对于集合O而言,若O中元素与状态机元素不完备则在集合 S 增长的过程之中无效的状态被添加。若O不一致,则随着 S 中元素增加,O中状态不一致的类型被替换。
O的状态机演化过程可以用表格的形式来描述,在算法执行的过程之中逐步把横纵坐标所对应的 accepted 或者 rejected 的属性值填充完毕。对于前缀闭集 S 而言,若元素 w 属于L,则所有前缀与 w 一致的元素均属于L。通过这一点,我们可以将冗余的前缀集合进行合并,从而产生最小的状态机:
前缀扩展自 accepted 元素的则标识其为 accepted
前缀扩展自 rejected 元素的则标识其为 rejected
小结
Angluin s Algorithm 中首先对较短的状态进行 query 验证,之后再逐步对更长的状态进行 query 验证,在填充状态表时最差的情况是需要执行。通过后续更多的优化过程,Angluin s Algorithm 可以进一步的优化自动状态机。简而言之,Angluin s Algorithm 是通过一系列的正样本对于有限状态进行描述。
Angluin s Algorithm 的思想如上所述,它对于非有限状态机或者其他的类型能进行进一步的扩展,并且可以较为有效的应用于工程范围中一些系统模型的验证。
参考文献:
[1] Fernandez,J.-C., C. Jard, T. Jeron and C. Viho, An experiment in automatic generation oftest suites for protocols with verification technology, Science of ComputerProgramming 29 (1997).
[2] Berg, Therese, Jonsson, Bengt, Leucker,Martin,等. Insights to Angluin s Learning[J]. Electronic Notes in TheoreticalComputer Science, 2005, 118:3-18.