机器人搬箱子和斑马问题

实验报告探讨了使用谓词逻辑、Prolog和Python解决机器人搬盒子问题及斑马问题。通过谓词公式、子句集和归结原理,实现了逻辑推理和问题求解。在ModelArts中,用Python进一步实现了斑马问题的逻辑。实验加强了对人工智能算法和搜索策略的理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

理解谓词逻辑知识表示的方法,掌握一阶谓词逻辑知识表示的基本原理,能够利用归结原理求解简单问题。掌握Prolog编程环境,熟悉逻辑推理编写过程。

主要知识点:谓词、原子公式、谓词公式、子句、子句集、空子句、归结原理。

重点:谓词公式、子句集和归结原理的实现。

难点:归结原理的实现。

实验内容:

实验项目1

机器人搬盒子问题:设在一个房间里,有一个机器人ROBOT ,一个壁橱ALCOVE,一个积木块BOX,两个桌子AB。开始时,机器人ROBOT在壁橱ALCOVE旁边,且两手空空,桌子A放着积木块BOX,桌子B是空的。机器人可把积木块BOX从一种状态桌子A上变换成另一种状态桌子B上,然后回到壁橱。用归结原理方法求解该问题?

 

实验要求:

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. 如何将谓词公式转换为子句集?

1)消去蕴含等价式
2)移动否定符号
3)变量标准化
4)消去存在量词
5)化为前束型
6)化为skolem标准型
7)略去全称量词
8)消去合取词,把母式用子句集表示
9)字句变量标准化

2. 谓词公式与子句集等值吗?

1)谓语公式与它的子句集不是总等价的。

2)在谓语公式不可满足的情况下是等价的。

实验步骤:

(一):项目一:

db1f8af96f4440baae13a4e382cc3c48.png

0d8b703310124fd0a13b3137310e87cd.png 

66adf0c03dc84ec099b68a3b1e849cbf.png 

 

4. 用Prolog实现机器人搬盒子的谓词逻辑。

  1. table(a).  
  2. table(b).  
  3. empty(robot).  
  4. at(robot,c).  
  5. on(box,a).  
  6. goto(robort,a):-at(robot,c).  
  7.   
  8. at(robot,a).  
  9. pick(a):-empty(robot),on(box,a),table(a).  
  10.   
  11. on(box,robot).  
  12. empty(a).  
  13. goto(robot,b):--at(robot,a).  
  14.   
  15. at(robot,b).  
  16. set_down(b):-at(robot,b),on(box,robot),table(b).  
  17.   
  18. empty(robot).  
  19. on(box,b).  
  20. at(robot,b).  
  21. goto(robot,c):-at(robot,b),on(box,b).  
  22.   
  23. at(robot,c).  
  24. empty(robot).  
  25. on(box,b).  
  26. finish(box):-on(box,b),at(robot,c),empty(robot).  
  27.  
  28. Student(李云霄,202131090218)

 

5. 用Python或其他编程语言实现该问题的求解。

  1. #定义三个变量(robot_site,is_robot_box,box_site),表示当前状态.  
  2. #系统状态  
  3. state=['robot_site','is_robot_box','box_site']  
  4. num=0  
  5. state_num=[state,num]  
  6. #初始状态  
  7. def initial_state(state):  
  8.    robot_site='c'  
  9.    global num  
  10.    is_robot_box='no'  
  11.    box_site='a'  
  12.    state=[robot_site,is_robot_box,box_site]  
  13.    print("状态:%d 机器人当前位置:%c 机器人是否拿着箱子:%s 箱子所在位置:%s"%(num,state[0],state[1],state[2]))  
  14.    num+=1  
  15.    return state  
  16. #目标状态  
  17. def target_state(state):  
  18.    global num  
  19.    robot_site='c'  
  20.    is_robot_box='no'  
  21.    box_site='b'  
  22.    state=[robot_site,is_robot_box,box_site]  
  23.    return state  
  24. #机器人移动  
  25. def robot_move(state,robot_object_site):  
  26.    global num  
  27.    temp_robot_site=state[0]  
  28.    state[0]=robot_object_site  
  29.    print("状态:%d 机器人从%s移动到了%s"%(num,temp_robot_site,state[0]))  
  30.    num+=1  
  31.    return state  
  32. #机器人搬起箱子  
  33. def pick_up_box(state,is_robot_box,box_site):  
  34.    global num  
  35.    state[1]=is_robot_box  
  36.    state[2]=box_site  
  37.    if(state[1]=='yes'):  
  38.       print('状态:%d 机器人拿起了箱子'%num)  
  39.    num+=1  
  40.    return state  
  41. #机器人放下箱子  
  42. def set_down_box(state,is_robot_box,box_site):  
  43.    global num  
  44.    state[1]=is_robot_box  
  45.    state[2]=box_site  
  46.    if(state[1]=='no'):  
  47.       print('状态:%d 机器人把箱子放在了%c'%(num,state[2]))  
  48.    num+=1  
  49.    return state  
  50. #判断机器人是否完成任务  
  51. def judge_obj(state):  
  52.    state0=target_state(state)  
  53.    if(state[0]==state0[0] and state[1]==state0[1] and state[2]==state0[2]):  
  54.       print('机器人完成任务.\n')  
  55. #作业完成人  
  56. def liyunxiao():  
  57.    print('学号:202131090218')  
  58.    print('姓名:')  
  59. #主程序  
  60. state=['robot_site','is_robot_box','box_site']  
  61. num=1  
  62. robot_object_site='a'  
  63. box_site='robot'  
  64. is_robot_box='yes'  
  65. state=initial_state(state)#状态1  
  66. state=robot_move(state,robot_object_site)#状态2  
  67. box_site='robot'  
  68. is_robot_box='yes'  
  69. state=pick_up_box(state,is_robot_box,box_site)#状态3  
  70. robot_object_site='b'  
  71. state=robot_move(state,robot_object_site)#状态4  
  72. box_site='b'  
  73. is_robot_box='no'  
  74. state=set_down_box(state,is_robot_box,box_site)  
  75. robot_object_site='c'  
  76. state=robot_move(state,robot_object_site)  
  77. judge_obj(state)  
  78. liyunxiao()  

结果:

状态:1

机器人当前位置:c 机器人是否拿着箱子:no 箱子所在位置:a

状态:2

机器人从c移动到了a

状态:3

机器人拿起了箱子

状态:4

机器人从a移动到了b

状态:5

机器人把箱子放在了b

状态:6

机器人从b移动到了c

 

()项目二

1. 用Prolog实现斑马问题的逻辑推理。

  1. /*描述房子的事实:建立五个房间*/  
  2. house(A,[A,_,_,_,_]).  
  3. house(A,[_,A,_,_,_]).   
  4. house(A,[_,_,A,_,_]).   
  5. house(A,[_,_,_,A,_]).   
  6. house(A,[_,_,_,_,A]).   
  7. /*描述房子的事实:建立房间之间的位置关系(left)*/  
  8. left(A,B,[A,B,_,_,_]).   
  9. left(A,B,[_,A,B,_,_]).   
  10. left(A,B,[_,_,A,B,_]).   
  11. left(A,B,[_,_,_,A,B]).   
  12. /*描述房子的事实:标记中间的房间(middle)*/  
  13. middle(A,[_,_,A,_,_]).   
  14. /*描述房子的事实:标记第一个房间(first)*/  
  15. first(A,[A,_,_,_,_]).   
  16. /*描述房子的事实:建立房间之间的邻居关系(neighbor)*/  
  17. neighbor(A,B,[A,B,_,_,_]).   
  18. neighbor(A,B,[_,A,B,_,_]).   
  19. neighbor(A,B,[_,_,A,B,_]).   
  20. neighbor(A,B,[_,_,_,A,B]).   
  21. neighbor(A,B,[B,A,_,_,_]).   
  22. neighbor(A,B,[_,B,A,_,_]).   
  23. neighbor(A,B,[_,_,B,A,_]).   
  24. neighbor(A,B,[_,_,_,B,A]).   
  25. /*建立人的五个属性*/  
  26. people[Country,Pet,Color,Drink,Smoke].   
  27. /*根据题目所给的信息描述房间分配的规则*/  
  28. find(Houses) :-   
  29. house(people(britsh,_,red,_,_), Houses),   
  30. house(people(spain,dog,_,_,_), Houses),   
  31. house(people(japan,_,_,_,congressCigarettes), Houses),   
  32. house(people(ukraine,_,_,tea,_), Houses), house(people(norway,_,_,_,_), Houses),   
  33. first(people(norway,_,_,_,_), Houses),   
  34. left(people(_,_,green,_,_), people(_,_,white,_,_), Houses),   
  35. house(people(_,snail,_,_,winstonCigarettes), Houses),   
  36. house(people(_,_,yellow,_,coorsCigarettes), Houses),   
  37. middle(people(_,_,_,milk,_), Houses),   
  38. house(people(_,_,green,cafe,_), Houses),   
  39. neighbor(people(norway,_,_,_,_), people(_,_,blue,_,_), Houses),   
  40. house(people(_,_,_,orange,luckCigarattes), Houses),   
  41. neighbor(people(_,fox,_,_,_), people(_,_,_,_,chesfieldCigarettes), Houses),   
  42. neighbor(people(_,horse,_,_,_), people(_,_,_,_,coorsCigarettes), Houses),   
  43. house(people(_,zebra,_,_,_), Houses),   
  44. house(people(_,_,_,water,_), Houses).   

 

2. 在华为云的ModelArts中用Python实现该问题的求解。

平台展示:

https://authoring-modelarts-cnnorth4.huaweicloud.com/c4f2050c-0934-4284-8c16-dab71aded289/lab

 

 

源代码:

  1. from kanren import *               
  2. from kanren.core import lall     # lall 包用于定义规则  
  3. import time  
  4. #定义 left()函数,用来查找哪个房屋左边  
  5. def left(q, p, list):  
  6.      return membero((q,p), zip(list, list[1:]))  
  7. #定义 next()函数,用来接近谁的房子  
  8. def next(q, p, list):  
  9.     return conde([left(q, p, list)], [left(p, q, list)])  
  10. from kanren import *  
  11. from kanren.core import lall     # lall 包用于定义规则  
  12. import time  
  13.   
  14. #定义 left()函数,用来查找哪个房屋左边  
  15. def left(q, p, list):  
  16.      return membero((q,p), zip(list, list[1:]))  
  17. #定义 next()函数,用来接近谁的房子  
  18. def next(q, p, list):  
  19.     return conde([left(q, p, list)], [left(p, q, list)])  
  20.   
  21. houses = var()  
  22. rules_zebraproblem = lall(  
  23.      (eq, (var(), var(), var(), var(), var()), houses),       # 5 个 var()分别代表人、烟、饮料、动物、屋子颜色  
  24.       # 房子里的每个子成员有五个属性: membero(国家,身份,饮料,宠物,房子)  
  25.      (membero,('英国人', var(), var(), var(), '红色'), houses),          # 1. 英国人住在红色的房子里  
  26.      (membero,('西班牙人', var(), var(), '狗', var()), houses),          # 2. 西班牙人养了一条狗  
  27.          (membero,('日本人', '油漆工', var(), var(), var()), houses),        # 3. 日本人是一个油漆工  
  28.          (membero,('意大利人', var(), '茶', var(), var()), houses),          # 4. 意大利人喜欢喝茶  
  29.         # 5. 挪威人住在左边的第一个房子里  
  30.          (eq,(('挪威人', var(), var(), var(), var()), var(), var(), var(), var()), houses),  
  31.          (left,(var(), var(), var(), var(), '白色'),(var(), var(), var(), var(), '绿色'), houses),    # 6. 绿房子在白房子的右边  
  32.          (membero,(var(), '摄影师', var(), '蜗牛', var()), houses),                     # 7. 摄影师养了一只蜗牛  
  33.          (membero,(var(), '外交官', var(), var(), '黄色'), houses),                     # 8. 外交官住在黄房子里  
  34.          (eq,(var(), var(), (var(), var(), '牛奶', var(), var()), var(), var()), houses),      # 9. 中间那个房子的人喜欢喝牛奶  
  35.          (membero,(var(), var(), '咖啡', var(), '绿色'), houses),                  # 10. 喜欢喝咖啡的人住在绿房子里  
  36.         # 11. 挪威人住在蓝色的房子旁边  
  37.          (next,('挪威人', var(), var(), var(), var()),(var(), var(), var(), var(), '蓝色'), houses),  
  38.          (membero,(var(), '小提琴家', '橘子汁', var(), var()), houses),               # 12. 小提琴家喜欢喝橘子汁  
  39.         # 13. 养狐狸的人所住的房子与医生的房子相邻  
  40.         (next,(var(), var(), var(), '狐狸', var()),(var(), '医生', var(), var(), var()), houses),  
  41.         # 14. 养马的人所住的房子与外交官的房子相邻  
  42.          (next,(var(), var(), var(), '马', var()),(var(), '外交官', var(), var(), var()), houses),  
  43.         (membero,(var(), var(), var(), '斑马', var()), houses),                  # 问题 1. 有人养斑马  
  44.          (membero,(var(), var(), '矿泉水', var(), var()), houses),                   # 问题 2. 有人喜欢喝矿泉水  
  45.     )  
  46.   
  47. # 使用 rules_zebraproblem 约束运行解算器  
  48. solutions = run(0, houses, rules_zebraproblem)  
  49. # 提取解算器的输出  
  50. output = [house for house in solutions[0] if '斑马' in house][0][4]  
  51. print ('\n{}房子里的人养斑马'.format(output))  
  52. output = [house for house in solutions[0] if '矿泉水' in house][0][4]  
  53. print ('\n{}房子里的人喜欢喝矿泉水\n'.format(output))  
  54.   
  55. # 解算器的输出结果展示  
  56. print("所有结果如下:")  
  57. for i in solutions[0]:  
  58.     print(i)  
  59. Print(“swpu,202131090218”)
  60.  

结果:

挪威人

外交官

矿泉水

狐狸

黄色

意大利人

医生

蓝色

英国人

摄影师

牛奶

蜗牛

红色

西班牙人

小提琴家

橘子汁

白色

日本人

油漆工

咖啡

斑马'

绿色

 

实验总结

在本次实验中,运用prolog代码可以帮助我们解决生活中一些实在的逻辑问题,在完成实验的过程中,学习如何运用prolog,python以及这些编程语言的逻辑函数库kanren,可以帮助我们解决很多实际问题,在培养逻辑编程,解决逻辑问题方面有很大的提升,也是对自己编程能力和解决问题能力的一种提升。在本次实验中,我们学习和实践了两个经典的人工智能案例:机器人搬箱子问题和爱因斯坦逻辑难题(斑马问题)。这两个实验涉及到搜索算法、专家系统等多种人工智能技术,以及相关编程语言和框架的使用。对于机器人搬箱子问题,我们首先用谓词公式表示问题的初始状态、目标状态以及机器人操作,然后将其转换为子句集,并利用归结原理对子句集进行归结。我们还用 Prolog 实现机器人搬箱子的谓词逻辑,并用 Python 或其他编程语言实现了该问题的求解。通过这个实验,我们深入研究了搜索算法和蚁群算法的原理和应用,对基于规则的机器人行走路径规划模型有了更深入的理解。在斑马问题实验中,我们使用 Prolog 实现了逻辑推理,也在华为云的 ModelArts 中用 Python 实现了该问题的求解。为我们提供了一个综合性的应用案例,在实验过程中,我们还掌握了谓词逻辑的基本概念、知识表示与推理、归结原理等重要技术。通过两个实验项目的学习和实践,我们对人工智能算法和技术有了更深入的认识,同时也培养了团队协作和问题解决能力。这次实验的成功也为我们今后更深入地学习和应用人工智能提供了坚实的基础和经验。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

恶心猫charming

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值