实 验 报 告
理解谓词逻辑知识表示的方法,掌握一阶谓词逻辑知识表示的基本原理,能够利用归结原理求解简单问题。掌握Prolog编程环境,熟悉逻辑推理编写过程。
主要知识点:谓词、原子公式、谓词公式、子句、子句集、空子句、归结原理。
重点:谓词公式、子句集和归结原理的实现。
难点:归结原理的实现。
实验内容:
实验项目1:
机器人搬盒子问题:设在一个房间里,有一个机器人ROBOT ,一个壁橱ALCOVE,一个积木块BOX,两个桌子A和B。开始时,机器人ROBOT在壁橱ALCOVE旁边,且两手空空,桌子A放着积木块BOX,桌子B是空的。机器人可把积木块BOX从一种状态桌子A上变换成另一种状态桌子B上,然后回到壁橱。用归结原理方法求解该问题?
文章来源地址https://www.toymoban.com/news/detail-717351.html
实验要求:
1.用谓词公式表示问题的初始状态、目标状态以及机器人操作;
2.将谓词公式转换为子句集;
3. 利用归结原理对子句集中的子句进行归结。
4. 用Prolog实现机器人搬盒子的谓词逻辑。
5. 用Python或其他编程语言实现该问题的求解。
实验项目2:
爱因斯坦逻辑难题(斑马问题):5个不同国家且工作各不相同的人分别住在一条街上的5所房子里,每所房子的颜色不同,每个人都有自己养的不同宠物,喜欢喝不同的饮料。根据以下信息,你能告诉我哪所房子里的人养斑马,哪所房子里的人喜欢喝矿泉水吗?
1. 英国人住在红色的房子里
2. 西班牙人养了一条狗
3. 日本人是一个油漆工
4. 意大利人喜欢喝茶
5. 挪威人住在左边的第一个房子里
6. 绿房子在白房子的右边
7. 摄影师养了一只蜗牛
8. 外交官住在黄房子里
9.
实验要求:
1. 用Prolog实现斑马问题的逻辑推理。
2. 在华为云的ModelArts中用Python实现该问题的求解。
思考题:
- 如何将谓词公式转换为子句集?
1)消去蕴含等价式
2)移动否定符号
3)变量标准化
4)消去存在量词
5)化为前束型
6)化为skolem标准型
7)略去全称量词
8)消去合取词,把母式用子句集表示
9)字句变量标准化
2. 谓词公式与子句集等值吗?
1)谓语公式与它的子句集不是总等价的。
2)在谓语公式不可满足的情况下是等价的。
实验步骤:
(一):项目一:
4. 用Prolog实现机器人搬盒子的谓词逻辑。
- table(a).
- table(b).
- empty(robot).
- at(robot,c).
- on(box,a).
- goto(robort,a):-at(robot,c).
- at(robot,a).
- pick(a):-empty(robot),on(box,a),table(a).
- on(box,robot).
- empty(a).
- goto(robot,b):--at(robot,a).
- at(robot,b).
- set_down(b):-at(robot,b),on(box,robot),table(b).
- empty(robot).
- on(box,b).
- at(robot,b).
- goto(robot,c):-at(robot,b),on(box,b).
- at(robot,c).
- empty(robot).
- on(box,b).
- finish(box):-on(box,b),at(robot,c),empty(robot).
- Student(李云霄,202131090218)
5. 用Python或其他编程语言实现该问题的求解。
- #定义三个变量(robot_site,is_robot_box,box_site),表示当前状态.
- #系统状态
- state=['robot_site','is_robot_box','box_site']
- num=0
- state_num=[state,num]
- #初始状态
- def initial_state(state):
- robot_site='c'
- global num
- is_robot_box='no'
- box_site='a'
- state=[robot_site,is_robot_box,box_site]
- print("状态:%d 机器人当前位置:%c 机器人是否拿着箱子:%s 箱子所在位置:%s"%(num,state[0],state[1],state[2]))
- num+=1
- return state
- #目标状态
- def target_state(state):
- global num
- robot_site='c'
- is_robot_box='no'
- box_site='b'
- state=[robot_site,is_robot_box,box_site]
- return state
- #机器人移动
- def robot_move(state,robot_object_site):
- global num
- temp_robot_site=state[0]
- state[0]=robot_object_site
- print("状态:%d 机器人从%s移动到了%s"%(num,temp_robot_site,state[0]))
- num+=1
- return state
- #机器人搬起箱子
- def pick_up_box(state,is_robot_box,box_site):
- global num
- state[1]=is_robot_box
- state[2]=box_site
- if(state[1]=='yes'):
- print('状态:%d 机器人拿起了箱子'%num)
- num+=1
- return state
- #机器人放下箱子
- def set_down_box(state,is_robot_box,box_site):
- global num
- state[1]=is_robot_box
- state[2]=box_site
- if(state[1]=='no'):
- print('状态:%d 机器人把箱子放在了%c'%(num,state[2]))
- num+=1
- return state
- #判断机器人是否完成任务
- def judge_obj(state):
- state0=target_state(state)
- if(state[0]==state0[0] and state[1]==state0[1] and state[2]==state0[2]):
- print('机器人完成任务.\n')
- #作业完成人
- def liyunxiao():
- print('学号:202131090218')
- print('姓名:')
- #主程序
- state=['robot_site','is_robot_box','box_site']
- num=1
- robot_object_site='a'
- box_site='robot'
- is_robot_box='yes'
- state=initial_state(state)#状态1
- state=robot_move(state,robot_object_site)#状态2
- box_site='robot'
- is_robot_box='yes'
- state=pick_up_box(state,is_robot_box,box_site)#状态3
- robot_object_site='b'
- state=robot_move(state,robot_object_site)#状态4
- box_site='b'
- is_robot_box='no'
- state=set_down_box(state,is_robot_box,box_site)
- robot_object_site='c'
- state=robot_move(state,robot_object_site)
- judge_obj(state)
- liyunxiao()
结果:
状态:1 |
机器人当前位置:c 机器人是否拿着箱子:no 箱子所在位置:a |
状态:2 |
机器人从c移动到了a |
状态:3 |
机器人拿起了箱子 |
状态:4 |
机器人从a移动到了b |
状态:5 |
机器人把箱子放在了b |
状态:6 |
机器人从b移动到了c |
(二)项目二
1. 用Prolog实现斑马问题的逻辑推理。
- /*描述房子的事实:建立五个房间*/
- house(A,[A,_,_,_,_]).
- house(A,[_,A,_,_,_]).
- house(A,[_,_,A,_,_]).
- house(A,[_,_,_,A,_]).
- house(A,[_,_,_,_,A]).
- /*描述房子的事实:建立房间之间的位置关系(left)*/
- left(A,B,[A,B,_,_,_]).
- left(A,B,[_,A,B,_,_]).
- left(A,B,[_,_,A,B,_]).
- left(A,B,[_,_,_,A,B]).
- /*描述房子的事实:标记中间的房间(middle)*/
- middle(A,[_,_,A,_,_]).
- /*描述房子的事实:标记第一个房间(first)*/
- first(A,[A,_,_,_,_]).
- /*描述房子的事实:建立房间之间的邻居关系(neighbor)*/
- neighbor(A,B,[A,B,_,_,_]).
- neighbor(A,B,[_,A,B,_,_]).
- neighbor(A,B,[_,_,A,B,_]).
- neighbor(A,B,[_,_,_,A,B]).
- neighbor(A,B,[B,A,_,_,_]).
- neighbor(A,B,[_,B,A,_,_]).
- neighbor(A,B,[_,_,B,A,_]).
- neighbor(A,B,[_,_,_,B,A]).
- /*建立人的五个属性*/
- people[Country,Pet,Color,Drink,Smoke].
- /*根据题目所给的信息描述房间分配的规则*/
- find(Houses) :-
- house(people(britsh,_,red,_,_), Houses),
- house(people(spain,dog,_,_,_), Houses),
- house(people(japan,_,_,_,congressCigarettes), Houses),
- house(people(ukraine,_,_,tea,_), Houses), house(people(norway,_,_,_,_), Houses),
- first(people(norway,_,_,_,_), Houses),
- left(people(_,_,green,_,_), people(_,_,white,_,_), Houses),
- house(people(_,snail,_,_,winstonCigarettes), Houses),
- house(people(_,_,yellow,_,coorsCigarettes), Houses),
- middle(people(_,_,_,milk,_), Houses),
- house(people(_,_,green,cafe,_), Houses),
- neighbor(people(norway,_,_,_,_), people(_,_,blue,_,_), Houses),
- house(people(_,_,_,orange,luckCigarattes), Houses),
- neighbor(people(_,fox,_,_,_), people(_,_,_,_,chesfieldCigarettes), Houses),
- neighbor(people(_,horse,_,_,_), people(_,_,_,_,coorsCigarettes), Houses),
- house(people(_,zebra,_,_,_), Houses),
- house(people(_,_,_,water,_), Houses).
2. 在华为云的ModelArts中用Python实现该问题的求解。
平台展示:
https://authoring-modelarts-cnnorth4.huaweicloud.com/c4f2050c-0934-4284-8c16-dab71aded289/lab
源代码:
- from kanren import *
- from kanren.core import lall # lall 包用于定义规则
- import time
- #定义 left()函数,用来查找哪个房屋左边
- def left(q, p, list):
- return membero((q,p), zip(list, list[1:]))
- #定义 next()函数,用来接近谁的房子
- def next(q, p, list):
- return conde([left(q, p, list)], [left(p, q, list)])
- from kanren import *
- from kanren.core import lall # lall 包用于定义规则
- import time
- #定义 left()函数,用来查找哪个房屋左边
- def left(q, p, list):
- return membero((q,p), zip(list, list[1:]))
- #定义 next()函数,用来接近谁的房子
- def next(q, p, list):
- return conde([left(q, p, list)], [left(p, q, list)])
- houses = var()
- rules_zebraproblem = lall(
- (eq, (var(), var(), var(), var(), var()), houses), # 5 个 var()分别代表人、烟、饮料、动物、屋子颜色
- # 房子里的每个子成员有五个属性: membero(国家,身份,饮料,宠物,房子)
- (membero,('英国人', var(), var(), var(), '红色'), houses), # 1. 英国人住在红色的房子里
- (membero,('西班牙人', var(), var(), '狗', var()), houses), # 2. 西班牙人养了一条狗
- (membero,('日本人', '油漆工', var(), var(), var()), houses), # 3. 日本人是一个油漆工
- (membero,('意大利人', var(), '茶', var(), var()), houses), # 4. 意大利人喜欢喝茶
- # 5. 挪威人住在左边的第一个房子里
- (eq,(('挪威人', var(), var(), var(), var()), var(), var(), var(), var()), houses),
- (left,(var(), var(), var(), var(), '白色'),(var(), var(), var(), var(), '绿色'), houses), # 6. 绿房子在白房子的右边
- (membero,(var(), '摄影师', var(), '蜗牛', var()), houses), # 7. 摄影师养了一只蜗牛
- (membero,(var(), '外交官', var(), var(), '黄色'), houses), # 8. 外交官住在黄房子里
- (eq,(var(), var(), (var(), var(), '牛奶', var(), var()), var(), var()), houses), # 9. 中间那个房子的人喜欢喝牛奶
- (membero,(var(), var(), '咖啡', var(), '绿色'), houses), # 10. 喜欢喝咖啡的人住在绿房子里
- # 11. 挪威人住在蓝色的房子旁边
- (next,('挪威人', var(), var(), var(), var()),(var(), var(), var(), var(), '蓝色'), houses),
- (membero,(var(), '小提琴家', '橘子汁', var(), var()), houses), # 12. 小提琴家喜欢喝橘子汁
- # 13. 养狐狸的人所住的房子与医生的房子相邻
- (next,(var(), var(), var(), '狐狸', var()),(var(), '医生', var(), var(), var()), houses),
- # 14. 养马的人所住的房子与外交官的房子相邻
- (next,(var(), var(), var(), '马', var()),(var(), '外交官', var(), var(), var()), houses),
- (membero,(var(), var(), var(), '斑马', var()), houses), # 问题 1. 有人养斑马
- (membero,(var(), var(), '矿泉水', var(), var()), houses), # 问题 2. 有人喜欢喝矿泉水
- )
- # 使用 rules_zebraproblem 约束运行解算器
- solutions = run(0, houses, rules_zebraproblem)
- # 提取解算器的输出
- output = [house for house in solutions[0] if '斑马' in house][0][4]
- print ('\n{}房子里的人养斑马'.format(output))
- output = [house for house in solutions[0] if '矿泉水' in house][0][4]
- print ('\n{}房子里的人喜欢喝矿泉水\n'.format(output))
- # 解算器的输出结果展示
- print("所有结果如下:")
- for i in solutions[0]:
- print(i)
- Print(“swpu,202131090218”)
结果:
挪威人 |
外交官 |
矿泉水 |
狐狸 |
黄色 |
意大利人 |
医生 |
茶 |
马 |
蓝色 |
英国人 |
摄影师 |
牛奶 |
蜗牛 |
红色 |
西班牙人 |
小提琴家 |
橘子汁 |
狗 |
白色 |
日本人 |
油漆工 |
咖啡 |
斑马' |
绿色 |
实验总结
在本次实验中,运用prolog代码可以帮助我们解决生活中一些实在的逻辑问题,在完成实验的过程中,学习如何运用prolog,python以及这些编程语言的逻辑函数库kanren,可以帮助我们解决很多实际问题,在培养逻辑编程,解决逻辑问题方面有很大的提升,也是对自己编程能力和解决问题能力的一种提升。在本次实验中,我们学习和实践了两个经典的人工智能案例:机器人搬箱子问题和爱因斯坦逻辑难题(斑马问题)。这两个实验涉及到搜索算法、专家系统等多种人工智能技术,以及相关编程语言和框架的使用。对于机器人搬箱子问题,我们首先用谓词公式表示问题的初始状态、目标状态以及机器人操作,然后将其转换为子句集,并利用归结原理对子句集进行归结。我们还用 Prolog 实现机器人搬箱子的谓词逻辑,并用 Python 或其他编程语言实现了该问题的求解。通过这个实验,我们深入研究了搜索算法和蚁群算法的原理和应用,对基于规则的机器人行走路径规划模型有了更深入的理解。在斑马问题实验中,我们使用 Prolog 实现了逻辑推理,也在华为云的 ModelArts 中用 Python 实现了该问题的求解。为我们提供了一个综合性的应用案例,在实验过程中,我们还掌握了谓词逻辑的基本概念、知识表示与推理、归结原理等重要技术。通过两个实验项目的学习和实践,我们对人工智能算法和技术有了更深入的认识,同时也培养了团队协作和问题解决能力。这次实验的成功也为我们今后更深入地学习和应用人工智能提供了坚实的基础和经验。文章来源:https://www.toymoban.com/news/detail-717351.html
到了这里,关于人工智能导论第一次实验——机器人搬箱子,斑马问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!