一个Fuxi语言的专家系统
Fuxi是一种多范型(multi-paradigm)程序设计语言,它结合了面向对象、函数型、逻辑型语言等语言技术。作为一种支持逻辑编程的语言,我们首先想到的就是能否用Fuxi语言编写专家系统。这里我们介绍一个Fuxi语言编写的专家系统程序。
import fuxi.*
class Attr
{
public String has
public String att
public Attr( String has, String att ) =
{
this.has := has
this.att := att
}
}
public active class Expert : Applet
{
Attr[] m_xPositive = []
Attr[] m_xNegative = []
/* CLAUSE #0 */
remember( String X, String Y, "y" ) = m_xPositive.insert( -1,
Attr( X, Y ) )
remember( String X, String Y, "n" ) = m_xNegative.insert( -1,
Attr( X, Y ) )
/* CLAUSE #1 */
ask( String X, String Y ) =
let
{
String Reply = Console.Readln()
}
in
{
Console.Print( "所猜的动物" + X + Y + "吗?
" )
remember( X, Y, Reply )
Reply == "y"
}
/* CLAUSE #2 */
positive( String X, String Y ) <- !m_xPositive.scan(x){ x.has
!= X || x.att != Y }
positive( String X, String Y ) <-
{
m_xNegative.scan(x){ x.has != X ||
x.att != Y }
ask( X, Y )
}
/* CLAUSE #3 */
negative( String X, String Y ) <- !m_xNegative.scan(x){ x.has
!= X || x.att != Y }
negative( String X, String Y ) <-
{
m_xPositive.scan(x){ x.has != X ||
x.att != Y }
!ask( X, Y )
}
/* CLAUSE #4 */
it_is( "哺乳动物" ) <- positive( "有", "毛发" )
it_is( "哺乳动物" ) <- positive( "有", "奶" )
it_is( "鸟" ) <- positive( "有", "羽毛" )
it_is( "鸟" ) <- { positive( "会", "飞" ), positive( "会", "下蛋" )
}
it_is( "食肉动物" ) <- positive( "会", "吃肉" )
it_is( "食肉动物" ) <-
{
positive( "有", "犬齿" ),
positive( "有", "爪" ),
positive( "有", "眼盯前方" )
}
it_is( "有蹄类动物" ) <- { it_is( "哺乳动物" ), positive( "有", "蹄" ) }
it_is( "有蹄类动物" ) <- { it_is( "哺乳动物" ), positive( "是", "嚼食动物"
) }
/* CLAUSE #5 */
protected aninal_is( String ) <- bool
animal_is( "豹" ) <-
{
it_is( "哺乳动物" ),
it_is( "食肉动物" ), positive( "是", "黄褐色的" ),
positive( "有", "黑色斑点"
)
}
animal_is( "虎" ) <-
{
it_is( "哺乳动物" ), it_is(
"食肉动物" ), positive( "是", "黄褐色的" ),
positive( "有", "黑色条纹" )
}
animal_is( "长颈鹿" ) <-
{
it_is( "有蹄类动物" ), positive(
"有", "长脖子" ), positive( "有", "长腿" ),
positive(
"有", "黑色斑点" )
}
animal_is( "斑马" ) <- {it_is( "有蹄类动物" ), positive( "有", "黑色条纹"
) }
animal_is( "鸵鸟" ) <-
{
it_is( "鸟" ), negative(
"会", "飞" ), positive( "有", "长脖子" ),
positive( "有", "长腿" ),
positive( "是", "黑白色的" )
}
animal_is( "企鹅" ) <-
{
it_is( "鸟" ), negative(
"会", "飞" ), positive( "会", "游泳" ),
positive( "是", "黑白色的" )
}
animal_is( "信天翁" ) <- it_is( "鸟" ) && positive( "善", "飞" )
/* CLAUSE #6 */
run() <-
let
{
String X
}
in
{
animal_is(X)
Console.Println( "您所猜的动物可能是 " + X + " 。" )
}
run() <- Console.Println( "很抱歉,我不知道您所猜的动物。" )
public Activate( ) = run()
}
这是一个关于动物的专家系统,采用程序提问、用户回答的方式进行人机会话,完成推理过程。类Expert包括两个属性Attr的表,分别表示正、负属性,用于记录推理的中间状态。
以下是一组会话过程:
所猜的动物有毛发吗?y
所猜的动物会吃肉吗?n
所猜的动物有犬齿吗?n
所猜的动物有蹄吗?y
所猜的动物有长脖子吗?y
所猜的动物有长腿吗?y
所猜的动物有黑色斑点吗?y
您所猜的动物可能是 长颈鹿。
1. 推理规则的表达
专家系统就是一个基于规则的推理系统,那么Fuxi是如何表示这些推理规则的呢?
Fuxi是一个纯面向对象的语言,所有的数据成员和方法都封装在类中。类是Fuxi语言的最小编程单位,一个程序至少包含一个类。推理规则是作为方法封装在类中的。Fuxi的方法分为函数、谓词和触发器三种,模式匹配的方法定义让Fuxi将它们统一到了一起。
具有相同签名的逻辑规则被聚集在一个谓词中。例如,例子中的“animal_is”就是一个谓词,它将7个animal_is规则组合在一起。规则的定义形式如下:
<规则名>(<模式>) <- <谓词或逻辑函数调用> && .... && <谓词或逻辑函数调用>
上式也称为Horn-表达式。
由于在实际编程过程中,采用&&来串接许多个谓词显得很麻烦,缺少美感。因此,我们导入了一个“语法糖块”——表达式系列。将多个谓词或函数调用用{}扩起来形成一个表达式系列,各表达式之间采用‘,’连接(‘,’也可以省略),这样程序就显得简洁了。例如,
{
it_is( "鸟" ), negative( "会", "飞" ), positive( "有",
"长脖子" ),
positive( "有", "长腿" ), positive( "是", "黑白色的" )
}
完全等价于
it_is( "鸟" ) && negative( "会", "飞" ) && positive( "有", "长脖子" ) &&
positive( "有", "长腿" ) && positive( "是", "黑白色的" )
2. 规则的扩展
Fuxi是面向对象的编程语言,对规则的扩展是通过派生类的方式来实现的。在派生类中,我们可以添加新的规则。和JAVA等不同,Fuxi的派生类的方法不是override基类中的方法,而是extend基类中方法。JAVA的函数只有一个模式、一个规则,其模式相当于Fuxi方法中的通配模式,因此JAVA的派生类只是override而不是extend基类方法。在这点上,Fuxi明显优越于JAVA。例如,我们可以定义一个MoreExpert类来扩充Expert中的aminal_is。
class MoreExpert?: Expert
{
protected animal_is("鳄鱼") <- ...
animal_is("熊猫") <- ...
}
此时,MoreExpert中的animal_is谓词继承了Expert中animal_is的全部规则,还增加了两条新的规则。
|