Prolog实现的Eliza聊天机器人示例代码运行原理咨询
Prolog版Eliza聊天机器人运行原理详解
这个Eliza是基于模式匹配的极简实现,核心逻辑是预定义对话模板→匹配用户输入提取变量→变量回填到回复模板输出,整体运行逻辑拆分如下:
1. 主执行流程
程序入口是eliza/0谓词,执行逻辑为:
- 打印提示符
?,读取用户输入并拆分为单词列表Input - 调用
eliza/1处理输入,通过cut!避免重复回溯处理同一条输入
eliza/1有两个分支逻辑:
- 若输入为
[bye],直接打印告别语结束对话 - 其他输入按如下步骤处理:
- 遍历所有预定义的
pattern(刺激模板, 回复模板)规则 - 调用
match/3将用户输入Input与刺激模板匹配,提取到的占位符内容存入Dictionary字典 - 再次调用
match/3,用存好的字典匹配回复模板,生成最终输出单词列表Output - 调用
reply/1打印输出句子,递归调用eliza进入下一轮对话
- 遍历所有预定义的
2. 核心谓词逻辑拆解
2.1 模板匹配match(Pattern, Dictionary, Target)
三个子句分别处理不同的模板元素:
% 处理数字占位符(模板里的1、2这类标记) match([N|Pattern], Dictionary, Target) :- integer(N), lookup(N, Dictionary, LeftTarget), append(LeftTarget, RightTarget, Target), match(Pattern, Dictionary, RightTarget). % 处理固定单词(模板里的普通文本) match([Word | Pattern], Dictionary, [Word | Target]) :- atom(Word), match(Pattern, Dictionary, Target). % 匹配终止条件:模板为空时目标列表也必须为空 match([], _Dictionary, []).
举个匹配示例:用户输入为[i, am, a, student],匹配刺激模板[i, am, 1]
- 模板第一个元素
i是普通原子,和输入第一个元素i匹配成功,剩余模板为[am, 1],剩余输入为[am, a, student] - 模板第二个元素
am是普通原子,和输入第二个元素am匹配成功,剩余模板为[1],剩余输入为[a, student] - 模板第三个元素
1是数字占位符,将剩余输入[a, student]作为值存入字典的键1的位置,匹配完成
2.2 字典存取lookup(Key, Dict, Value)
是基于列表实现的简易键值对查询工具:
% 字典第一个元素键匹配,直接返回对应值 lookup(Key, [(Key, Value) | _Dict], Value). % 第一个元素键不匹配,递归查询剩余列表 lookup(Key, [(Key1, _Val1) | Dictionary], Value) :- Key \= Key1, lookup(Key, Dictionary, Value).
注意这个谓词是双向工作的:匹配刺激模板时向字典写入占位符对应的值,匹配回复模板时从字典读取值回填到模板中。比如上面的示例,回复模板为[how,long,have,you,been,1,'?'],匹配时会自动把1替换为[a, student],生成输出[how,long,have,you,been,a,student,'?']。
2.3 对话模板pattern(Stimulus, Response)
预定义了6类对话规则,其中有一条带条件的特殊规则:当用户输入中出现important/1定义的亲属关键词(father、mother、son等)时,会触发专属回复,询问该亲属的相关信息。最后一条pattern([1], [please,go,on])是兜底规则,所有未匹配到前面规则的输入都会触发这条回复。
2.4 工具谓词
reply/1:遍历输出单词列表,每个单词后加空格打印,最后换行read_word_list/1:读取用户输入的完整句子,拆分为单词原子列表
内容的提问来源于stack exchange,提问作者JCR
相关产品推荐
相关产品推荐

