F# 语言的 Eliza 式聊天机器人,供娱乐






4.33/5 (2投票s)
Eliza 聊天机器人(用 F# 编写,用于学习函数式编程语言,随 Visual Studio 2010 一起提供)。
引言
这是一个非常简单的 Eliza 式聊天机器人。我称之为 Meliza Sharp。我编写它是为了好玩,同时学习 Visual Studio 2010 附带的 F# 语言。市面上有一些用 LISP 编写的非常好的 Eliza 聊天机器人实现,如果你想自己做一个聊天机器人,可以搜索一下。
Meliza 思考代码
Meliza 算法基于规则和模式匹配。这是 F# 的强大功能之一。
以下函数定义了模式标识符:Wish
、Positive
、Negative
和 None
,以及 input
字符串何时会匹配这些模式标识符。
如果 input
字符串与 "want"
、"desire"
或 "need"
匹配,则 input
将匹配 Wish
模式标识符。
如果 input
字符串与 "certainly"
、"yes"
、"ok"
或 "right"
匹配,则 input
将匹配 Positive
模式标识符。其余模式标识符以此类推。
这就是 F# 开发者所说的“主动识别器”。主动识别器充当一种判别器,将输入分成不同的类别,在这种情况下,分成不同的“对话主题”。
// Define an active recognizer for keywords
// that express desire, positive and negative statements.
let (|Wish|Positive|Negative|None|) input =
match input with
| "want" | "desire" | "need"
-> Wish
| "certainly" | "yes" | "true" | "ok" | "right"
-> Positive
| "not" | "no" | "don't" | "false" | "wrong"
-> Negative
| _ -> None
在这个另一个函数中,异常处理 try ... with
结构充当一个条件。只有当转换 Convert.ToDouble(input)
成功时,才可能匹配 input
字符串和 Number
模式标识符。
// Define an active recognizer for numbers
// If the conversion suceeds it is a Number
// else it is None
let (|Number|None|) (input:string) =
try let value = Convert.ToDouble(input)
Number
with
| _ -> None
一旦定义了所有我们希望用于匹配字符串标记的主动识别器,我们就创建递归的 response
函数,该函数将字符串的第一个 token
和其余部分作为参数。
我们搜索 token
与上述主动识别器是否匹配。也就是说,我们找出 token
falls into 哪个已定义的类别或“主题”。
如果我们发现 token 属于预定义的类别之一,则通过调用相应的响应函数来返回该类别的响应。这将结束递归过程。
如果与 | None when (str.IndexOf(" ") > 0)
匹配,我们则递归地将下一个 token 和字符串的其余部分传递给 response 函数。也就是说,我们还没有找到当前 token 的类别,并且字符串中还有更多的 token,因此我们使用下一个 token 和剩余的字符串 str
调用 response 函数,以进行递归处理。
如果与 | None when (str.IndexOf(" ") < 0)
匹配,也就是说,我们还没有找到当前 token 的类别,并且字符串中没有更多的 token 了,我们使用下一个 token 和空字符串的其余部分调用 response 函数。
when
语句设置了一个守卫或条件,以限制 token
与 None
匹配的可能性。
// main recursive response function
// find the first match with a key token
// and return a response acordingly
let rec response (token: string) (str: string) =
match token with
| Hello
-> hello_response ()
| Bye
-> good_bye_response ()
| Personal
-> personal_response str
| Question
-> question_response str
| Answer
-> answer_response str
| Wish
-> wish_response str
| Negative
-> negative_response str
| Positive
-> positive_response str
| Math
-> math_response str
| ""
-> none_response str
| None when (str.IndexOf(" ") > 0)
-> response (str.Substring(0,str.IndexOf(" ")))
(str.Substring(str.IndexOf(" ")+1))
| None when (str.IndexOf(" ") < 0)
-> response str ""
| None
-> math_response str
最后,我们创建一组函数,这些函数会随机选择响应,这些响应基于 response 函数和主动模式所识别的“主题”。
这里有两个例子
// Select possible responses based on random number for hello 'subject'
let hello_response () =
let n = rand.Next(10)
match n with
| 0 -> "How do you do."
| 1 -> "Is nice talking to you."
| 2 -> "Tell me something new."
| 3 -> "Nice to meet you."
| 4 -> "My pleasure."
| 5 -> "Hi."
| 6 -> "Hello."
| 7 -> "Good day."
| 8 -> "Salutation!"
| 9 -> "Welcome!"
// Select possible responses based on random number for Good bye 'subject'
let good_bye_response () =
let n = rand.Next(10)
match n with
| 0 -> "Talk to you soon."
| 1 -> "It was nice talking to you."
| 2 -> "Good bye."
| 3 -> "Stay a bit longer."
| 4 -> "Adios amigo."
| 5 -> "Bye."
| 6 -> "Adios."
| 7 -> "See you."
| 8 -> "Please don't go"
| 9 -> "Why are you leaving me alone?"
如何创建 Visual F# 应用程序和 Windows 窗体
- 文件 -> 新建 -> 项目
创建新的 Eliza Visual F# 应用程序。
添加 Windows 组件引用
- 在解决方案资源管理器中,右键单击“引用” -> “添加引用...”
- 单击“.NET”选项卡,然后从列表中选择
System.Drawing
和System.Windows.Form
。 - 单击“确定”按钮。
设计窗体
Visual Studio 中没有 F# 的窗体设计器,所以我建议使用其他 .NET 语言(如 VB.NET)的设计器。
- 关闭解决方案,或打开另一个 Visual Studio 实例。
- 文件 -> 新建 -> 项目
创建一个新的临时 Visual Basic Windows 窗体应用程序。
- 从工具箱将一个
TextBox
拖到窗体上。 - 在窗体上右键单击 TextBox -> “属性”。
- 将
Name
属性设置为text_box
。 - 将
Dock
属性设置为Bottom
。 - 将另一个
TextBox
从工具箱拖到窗体上。 - 在窗体上右键单击
TextBox
-> “属性”。 - 将
Name
属性设置为conversation_box
。 - 将
Dock
属性设置为Fill
。 - 将
Multiline
属性设置为True
。 - 保存临时项目。
将代码翻译成 F#
- 打开 Eliza 项目。
- 转到“文件”->“打开”->“文件...”
- 浏览到项目文件夹,临时项目,打开 Form1.Designer.vb 文件。
- 浏览到
Private Sub InitializeComponent()
;在 Form1.Designer.vb 中,有我们必须为窗体设置的属性。
添加创建窗体的代码
// Create a main form, you can create a form using // the form designer, in another language like Vb .Net // then open the file Form1.Designer.vb and voila! // there is the code you can translate into F# let main_form title = // text box let text_box = new TextBox() text_box.Dock <- DockStyle.Bottom // conversation box let conversation_text = new TextBox() conversation_text.Dock <- DockStyle.Fill conversation_text.Multiline <- true conversation_text.WordWrap <- false conversation_text.Font <- new Font(string("Arial"),float32(10)) conversation_text.ReadOnly <- true // main form let form = new Form(Text=title, Visible=true) form.Size <- new Size(512, 512) form.Controls.Add(conversation_text) form.Controls.Add(text_box) // Message handler for Key Down event text_box.KeyDown.Add(enter_message text_box conversation_text) // let gotfocus = text_box.Focus() // form.KeyDown.Add(fun e -> if e.KeyCode = Keys.Escape then form.Close()); form
构建并运行应用程序。
- 打开 Eliza 项目。
- 转到“项目”->“Eliza 属性...”
- 在“应用程序”选项卡中,将“输出类型”设置为“Windows 应用程序”。
- 按 F5 键 ;-)
关注点
就是这样!
历史
刚刚发布。