使用RETE算法的模块系统,有四个入口,分别是添加事实(add-wme)、去除事实(remove-wme)、添加规则(add-production)、去除规则(remove-production)。
上面的主要介绍了建立rete网络后添加事实的过程。下面先具体介绍alpha网络的建立和添加事实的过程,然后再介绍另外三个过程。
4.4 Alpha网络
当事实添加到工作内存后,alpha网络对事实进行必要的类型检测并把事实存放到相应的alpha内存里。有几种方法来寻找合适的alpha内存节点。
4.4.1 数据流网络
最直接的方式就是使用一个简单的数据流网络。
下图就是一个采用数据流网络建立的alpha网络。
上面的alpha网络仅仅检测条件中的常量,如attribute项上的常量有on,color,left-of;value项上的常量red maize blue green white。
4.4.2 带Hashing的数据流网络
上面的数据流网络的一个最大的缺点就是,当某个节点的扇出(fan-out)很大时,将会做大量的无用功(wasted work)。比如上图中对颜色的测试,某些专家系统可能含有大量的颜色,那么将会有大量的比较操作,从而造成匹配操作变慢。
一个解决这个问题的方法就是对于那些带有很大扇出的节点,采用hash表(或者平衡二叉树)来判断。
从上面的讨论可知,alpha网络非常有效,随着事实集合的变化,alpha网络可以几乎可以马上作出相应处理。Beta节点的处理占到了整个系统匹配的绝大部分时间。所以一般研究的都针对网络中的beta节点进行。
4.5 内存节点
Alpha内存存储事实集合,beta内存存储tokens(tokens指规则中已经匹配好的事实绑定)。
4.5.1 事实集合的结构
事实集合最简单的结构是采用链表结构。但是为了获得更高的效率,一般也给每个事实内存加上索引(indexing)。最常用的索引方法是采用Hash表。也可以采用树,但在多数rete算法实现上并不常用,(Barachini,1991)发现Hash表一般比非平衡二叉树的性能好。索引方法的缺点有两个:添加删除元素费时,降低了节点的复用度。所以索引方法在那些节点内存中并不包含很多元素的系统中不适用。
4.5.2 Token的结构
可以使用数组或链表来存储token。使用数组需要更多的空间,同时需要更多的时间来创建token。但是,拥有更快的访问速度。通常,选择的标准在于使用链表时访问某个元素的用的时间是否可以承受。
4.6 连接节点(Join node)
当一个连接节点的alpha内存中加入一个事实时,将引发此连接节点的right activation,当一个连接结点的beta内存中加入一个token时,将引发此连接节点的left activation。
连接节点的数据结构包括:指向其alpha内存和beta内存的指针,变量连接检测的说明,指向子节点的指针。
当一个连接节点的alpha内存中加入某个事实时,引发right activation。此处,因为right activation 的顺序不同,有可能产生冗余tokens(即在同一个beta内存里存储有两个或以上的相同的token)。结果这个问题的方法有:每次在beta内存中加入一个新的token时,都检测是否已存在相同的token。这个方法的缺点就是使系统的处理速度变慢。另外一个较好的方法是把right activation的顺序确定下来。
4.7 去除事实(Removals of facts)
当某个事实从工作内存总删除时,需要更新含有此事实的alpha内存和beta内存,有以下几种方法。
在原始的rete算法中,删除操作和添加操作采用同一种方式。称此方式为rematch-based removal。主要思想是给每个添加或删除操作一个tag,用来表明此操作是添加事实或删除事实。删除操作的具体执行过程同上面讨论的添加一个事实的过程类似。此方法与其他方法相比,速度较慢。因为删除操作与添加操作的工作量几乎相同。在添加事实过程中所获得的信息并没有在执行删除操作时加以利用。下面有三种改进的算法。
在scan-based removal中,当一个连接节点的alpha内存中的某个事实w被去除时,把w传给此连接节点的输出内存,在此内存中寻找最后一个元素为w的tokens,将这些tokens删除,并且把这些tokens传给此连接节点的子节点。在在子节点中做类似删除操作。(Scales,1986)通过使用此方法代替原有方法,获得28%的加速。(Barachini,1991)获得了10%的加速。
在list-base removal和tree-based removal中使用了这样一个原理,即给事实集合以及tokens的数据结构上增添额外的指针,当某个事实被删除时,可以沿着这些指针删除需要删除的元素。
在list-based removal(Scales ,1986)中,把每个事实w上添加一个包含此事实的tokens的链表。当w被删除时,只要沿着此链表删除这些tokens。缺点就是需要大量的空间来存储链表,同时在创建一个新token时也可能花费大量的额外时间。
在tree-base removal中,在每个事实w上添加一个链表,这些链表指向把w作为最后一个元素的tokens。同时,在每个tokens上,添加一个指向此tokens的子节点的链表。当w被删除时,遍历以tokens为根的子树,删除子树上的所有元素。当然,这些额外指针将占用更多内存,同时,建立这些指针也耗费时间。经验表明,采用此方法比原始方法要节省时间。