到目前为止,所介绍的事实、查询以及规则都使用的是最简单的数据结构。谓词的参数都是原子或者整数,这些都是Prolog的基本组成元素。例如我们所使用过的原子有:

office, apple flashlight, nani

通过把这些最简单的数据组合起来,可以生成复杂的数据类型,我们称之为结构。结构由结构名和一定数量的参数组成。这与以前所学过的目标和事实是一样的。

functor(arg1,arg2,...)

结构的参数可以是简单的数据类型或者是另一个结构。现在在游戏中的物品都是由原子表示的,例如,desk、apple。但是使用结构可以更好的表达这些东西。下面的结构描述了物品的颜色、大小以及重量。

object(candle, red, small, 1).
object(apple, red, small, 1).
object(apple, green, small, 1).
object(table, blue, big, 50).

这些结构可以直接取代原来的location/2中的参数。但是这里我们再定义一个谓词location_s/2。注意,虽然定义的结构较为复杂,但是它仍然是location_s/2的一个参数。

location_s(object(candle, red, small, 1), kitchen).
location_s(object(apple, red, small, 1), kitchen).
location_s(object(apple, green, small, 1), kitchen).
location_s(object(table, blue, big, 50), kitchen).

Prolog的变量是没有数据类型之分的,所以它可以很容易的绑定为结构,如同它绑定为原子一样。事实上,原子就是没有参数的最简单的结构。因此可以有如下的询问。

?- location_s(X, kitchen).
X = object(candle, red, small, 1) ;
X = object(apple, red, small, 1) ;
X = object(apple, green, small, 1) ;
X = object(table, blue, big, 50) ;
no

我们还可以让变量绑定为结构中的某些参数,下面的询问可以找出厨房中所有红色的东西。

?- location_s(object(X, red, S, W), kitchen).
X = candle
S = small
W = 1 ;

X = apple
S = small
W = 1 ;

no

如果不关心大小和重量,可以使用下面的询问,其中变量‘_’是匿名变量。

?- location_s(object(X, red, _, _), kitchen).
X = candle ;
X = apple ;
no

使用这些结构,可以使得游戏更加真实。例如,我们可以修改以前所编写的can_take/1谓词,使得只有较轻的物品才能被玩家携带。

can_take_s(Thing) :-
here(Room),
location_s(object(Thing, _, small,_), Room).

同时,也可以把不能拿取某物品的原因说得更详细一些,现在有两个拿不了物品的原因。为了让Prolog在回溯时不把两个原因同时显示出来,我们为每个原因建立一条子句。这里要用到内部谓词not/1,它的参数是一个目标,如果此目标失败,则它成功;目标成功则它失败。例如,

?- not( room(office) ).
no

?- not( location(cabbage, 'living room') )
yes

注意,在Prolog中的not的意思是:不能通过当前数据库中的事实和规则推出查询的目标。下面是使用not重新编写的can_take_s/1。

can_take_s(Thing) :-
here(Room),
location_s(object(Thing, _, small, _), Room).
can_take_s(Thing) :-
here(Room),
location_s(object(Thing, _, big, _), Room),
write('The '), write(Thing),
write(' is too big to carry.'), nl,
fail.
can_take_s(Thing) :-
here(Room),
not (location_s(object(Thing, _, _, _), Room)),
write('There is no '), write(Thing), write(' here.'), nl,
fail.
下面来试试功能,假设玩家在厨房里。

?- can_take_s(candle).
yes

?- can_take_s(table).
The table is too big to carry.
no

?- can_take_s(desk).
There is no desk here.
no

原来的list_things/1谓词也可以加上一些功能,下面的list_things_s/1不但可以列出房间中的物品,还可以给出它们的描述。

list_things_s(Place) :-
location_s(object(Thing, Color, Size, Weight),Place),
write('A '),write(Size),tab(1),
write(Color),tab(1),
write(Thing), write(', weighing '),
write(Weight), write(' pounds'), nl,
fail.
list_things_s(_)

它的回答令人满意多了。

?- list_things_s(kitchen).
A small red candle, weighing 1 pounds
A small red apple, weighing 1 pounds
A small green apple, weighing 1 pounds
A big blue table, weighing 50 pounds
yes

如果你觉得使用1 pounds不太准确的话,我们可以再使用另一个谓词来解决此问题。

write_weight(1) :- write('1 pound').
write_weight(W) :- W > 1, write(W), write(' pounds').

下面试试看

?- write_weight(4).
4 pounds
yes

?- write_weight(1).
1 pound
yes

第一个子句中不需要使用W=1这样的判断,我们可以直接把1写到谓词的参数中,因为只有为1时是使用单数,其他情况下都使用复数。第二个子句中需要加入W>1,要不然当重量为1时两条子句就同时满足。

结构可以任意的嵌套,下面使用dimension结构来描述物体的长、宽、高。

object(desk, brown, dimension(6,3,3), 90).

当然,也可以这样来表达物品的特性

object(desk, color(brown), size(large), weight(90))

下面是针对它的一条查询。

location_s(object(X, _, size(large), _), office).

要注意变量的位置哟,不要搞混了。

Prolog教程 10相关推荐

  1. [译][Tkinter 教程10] Text 控件

    已获原作者授权. 原系列地址: Python Tkinter 简介及简例 Text 控件用来显示多行文本. Tkinter 的 Text 控件很强大, 很灵活, 可以实现很多功能. 虽然这个控件的主要 ...

  2. 黑马lavarel教程---10、lavarel模型关联

    黑马lavarel教程---10.lavarel模型关联 一.总结 一句话总结: 1.模型关联比较方便,一次定义,后面都可以使用 2.关联关系 使用动态属性进行调用 1.一对多,多对多实例? 一对多: ...

  3. 国二vb计算机过的办法,国二计算机VB教程10.ppt

    国二计算机VB教程10 第10章 键盘与鼠标事件过程 本章内容: 10.1 KeyPress事件 10.2 KeyDown和KeyUp事件 10.3 鼠标事件 10.4 鼠标光标的形状 10.5 拖放 ...

  4. STM32 进阶教程 10 - RAM中调试程序

    前言 在stm32开发过程中,程序调试是一个比较耗时且又重要的问题,特别是在固件代码达到一定的复杂度后,程序下载过程就一个比较耗时过程,同时STM32芯片有FLASH烧写次数有限,像103系列手册中标 ...

  5. STM32 基础系列教程 10 - 单线串口(半双工)

    前言 在工程应用中,很多时间为了方便走线会采用单线串口方案,本节将学习stm32 usart单线串口的使用,学会用使用单线串口收发数据. 示例详解 基于硬件平台: STM32F10C8T6最小系统板, ...

  6. Atitit.5gl 第五代语言编程语言 PROLOG教程  人工智能语言的标准 与实现

    Atitit.5gl 第五代语言编程语言 PROLOG教程  人工智能语言的标准 与实现 1. 第五代语言就是自然语言又被称为知识库语言或人工智能语言,1 2. 人工智能语言特点2 2.1. 试探法2 ...

  7. wcf简单教程(10) ajax调用,wcf简单教程(10) ajax调用

    wcf简单教程(10) ajax调用 [2021-02-11 16:23:59]  简介: php去除nbsp的方法:首先创建一个PHP代码示例文件:然后通过"preg_replace(&q ...

  8. 【iVX 初级工程师培训教程 10篇文拿证】01 了解 iVX 完成新年贺卡

    目录 [iVX 初级工程师培训教程 10篇文拿证]01 了解 iVX 完成新年贺卡 [iVX 初级工程师培训教程 10篇文拿证]02 数值绑定及自适应网站制作 [iVX 初级工程师培训教程 10篇文拿 ...

  9. 【iVX 初级工程师培训教程 10篇文拿证】02 数值绑定及自适应网站制作

    目录 [iVX 初级工程师培训教程 10篇文拿证]01 了解 iVX 完成新年贺卡 [iVX 初级工程师培训教程 10篇文拿证]02 数值绑定及自适应网站制作 [iVX 初级工程师培训教程 10篇文拿 ...

最新文章

  1. 关于Jboss/Tomcat/Jetty的JNDI定义123
  2. 使用Arquillian(远程)测试OpenLiberty
  3. 前端学习(1467):过滤器
  4. 男性最脆弱的五大器官
  5. @Transactional注解的几个参数--事务传播控制--事务隔离级别--异常与回滚
  6. testbench文件显示波形_如何编写testbench的总结(非常实用的总结)
  7. RayData大数据可视化教程(2)——动画制作基础和设置为本地资源库
  8. 万字超详细图文教程:联想G510加装内存条、固态,机械移至光驱位
  9. Mac下遇到的npm install失败问题 err!
  10. 乔布斯斯坦福毕业演讲,这是我听过最精彩的毕业演讲!
  11. 大数据战略能不能打造第二个百度?
  12. 34岁测试工程师面试美团遭拒:只招30岁以下,能加班但工资要求不高的....
  13. 【数据结构】使用队列实现循环调度法
  14. #7 实现指定函数printSize
  15. html5的美食街网站论文,难忘的美食文化街优秀作文600字
  16. 不可错过的五款开源图形处理软件
  17. 企业级的HttpsNginx实战部署
  18. origin调整纵坐标刻度值_微教程:Origin怎样调整坐标轴刻度
  19. 字节码插桩框架ASM(一)
  20. win7滑动关机代码bat_写一行代码实现滑动关机电脑

热门文章

  1. 在Excel中粘贴时怎样跳过隐藏行
  2. MyEclipse10 Servers窗口出现“Could not create the view: An unexpected exception was thrown”解决办法
  3. 机器学习#假设空间与版本空间
  4. 20221210今天的世界发生了什么
  5. 被“豢养”的中国科技
  6. 题解 [CEOI2015 Day2][LuoguP4799]世界冰球锦标赛
  7. 【数据结构】图解七大排序
  8. 奥兰多环球影城“霍格沃茨的黑魔法”声光秀
  9. Excel单元格数值统计
  10. conclution