Learn Prolog Now 翻译 - 第一章 - 事实,规则和查询 - 第二节, Prolog语法介绍

内容摘要:

原子(Atom)

数字(Numbers)

变量(Variables)

复杂语句(Complex Terms)

通过上一节的学习,我们已经大概熟悉了Prolog的编程思路,这一节我们会回过头,详细学习其中的一些语法细节。首先,问一个基础的问题:我们已经在Prolog程序中看到了很多类型的表达式

(比如,jody,playsAirGuitar(mia),和X),但这些仅仅只是例子,是时候更加深入了,到底事实、规则和查询是由什么构成的?

答案就是语句(terms),在Prolog中一共存在四种类型的语句:原子,数字,变量和复杂语句(或者称为结构)。原子和数字统称为常量,常量和变量统称简单语句。

首先要明确基础的字符的范围:大写字母:A,B,...,Z;小写字母:a,b,...,z;数字:0,1,2,...,9.另外还包括"_",即英文下划线字符;和其他一些特殊英文字符,比如:+,-,*,/,<,>,=,:,.,

&,~;空格也是字符,但是不常用,并且也不可见。字符串是指没有切断的字符序列。

原子(Atoms)

一个原子是以下情况之一:

1. 由字符构成的字符串,其中有效字符包括:大字字母,小写字母,数字,和下划线,并且是小写字母作为头字符。一些例子:butch,big_kahuna_burger,listen2Music,playsAirGuitar。

2. 使用单引号封装的字符序列。比如:‘Vincent‘,‘The Gimp‘,‘Five_Dollar_Shake‘,‘&^%%@# *‘,‘ ‘。被单引号封装的字符序列被称为原子名。注意我们已经使用了空格字符,事实上,

使用单引号封装,其中的一个作用就是可以在原子钟精确地使用类似空格字符这样的特殊字符。

3. 特殊字符组成的字符串。比如:@=,====>,;,:-等都是原子。正如我们看到的,一些特殊原子,比如;(逻辑或),:-(规则中连接头部和主干的符号)已经有预定义的含义。

数字(Numbers)

在典型的Prolog程序中,实数并不是很有用武之地。所以虽然大多数Prolog的实现都支持浮点数,但是本文不讨论。

但是整数(比如:-2,-1,0,1,2,...)却十分有用,比如在计算列表的元素数目之类的工作时候,我们将会在第5章详细介绍。Prolog中数字的表示很简单,没有什么特殊,如下:

23, 1001, 0, -365, 等等。

变量(Variables)

变量是由大写字母,小写字母,数字和下划线组成的字符串,并且头字母必须是大写字母或者下划线。比如:

X, Y, Variable, _tag, X_526, List, List24, _head, Tail, _input, Output

都是Prolog中有效的变量。变量”_“是一个特例,它被称为匿名变量,我们将会在第4章中介绍。

复杂语句(Complex Terms)

常量,数字,和变量都是构建模块,现在我们学习如何将它们组成复杂语句。复杂语句也并称为结构体。

复杂语句由一个函子(functor,也可以理解为函数名)和一个参数序列构成。参数序列放在小括号内,由英文逗号分隔,并且是放在函子后面。请注意函子后面必须紧跟参数序列,中间不能

有空格。函子必须是一个原子,即,变量不能用作函子。另一方面,参数序列可以是任何类型的语句。

从KB1到KB5,我们已经看到了许多复杂语句的例子。比如,playsAirGuitar(jody)就是一个复杂语句,其中playsAirGuitar是函子,jody是参数序列(只有一个参数)。另一个例子是

loves(vincent, mia),loves是函子,vincent和mia是参数序列;再比如一个包含了变量的例子:jealous(marsellus, W)。

但是,复杂语句的定义可以允许更为复杂的情况。事实上,在复杂语句中,也可以内嵌其他复杂语句(就是说,复杂语句允许递归)。比如:

hide(X, father(father(father(butch)))).

就是一个完美的符合定义的复杂语句。它的函子是hide,有两个参数:一个是变量X,另外一个是复杂语句,father(father(father(butch)))。这个复杂语句组成是:函子是father,另外一

个复杂语句,father(father(butch))是其唯一的参数。里层的复杂语句的参数依然是一个复杂语句:father(butch)。但是到了嵌套的最里层,参数就是一个常量:butch。

实际上,这种嵌套(递归结构)使得我们可以自然地描述很多问题,而且这种递归结构和变量合一之间的互相作用,正是Prolog强有力的武器。

复杂语句的参数个数称为元数(arity)。比如,woman(mia)是一个元数为1的复杂语句,loves(vincent, mia)是一个元数为2的复杂语句。

元数对于Prolog很重要。Prolog允许定义函子相同但是元数不同的复杂语句。比如,我们可以定义两个参数的loves谓词,loves(vincent, mia);也可以定义三个参数的loves谓词,loves(

vincent, marsellus, mia)。如果我们这么做了,Prolog会认为这两个谓词是不同的。在第5章中,我们将会看到定义相同函子但是元数不同的具体应用。

当我们需要提及定义的谓词,介绍如何使用它们的时候(比如,在文档中),惯例是”函子/元数“这种形式。回到KB2,我们有三个谓词,之前的表达如下:

  listen2Music

  happy

  playsAirGuitar

使用正式的书写方式如下:

  listen2Music/1

  happy/1

  playsAirGuitar/1

Prolog不会因为定义了两个loves谓词而迷惑,它会区分loves/2和loves/3是不同的谓词。

时间: 2024-10-01 02:33:56

Learn Prolog Now 翻译 - 第一章 - 事实,规则和查询 - 第二节, Prolog语法介绍的相关文章

Learn Prolog Now 翻译 - 第一章 - 事实,规则和查询 - 第一节, 一些简单的例子

 该系列文章是网上的Prolog学习资料:www.learnprolognow.org的中文翻译.希望能够通过翻译此学习资料,达到两个目的:第一.系统学习prolog的知识:第二.提升英文文章理解 和翻译能力. 内容摘要: 给出一些Prolog编程的简单例子: Prolog的基本结构:事实,规则和查询: 环境说明: 本系列文章使用的Prolog运行环境是:SWI-Prolog,官网地址是:http://www.swi-prolog.org. Prolog中只有三种基础结构:事实(facts),规

Learn Prolog Now 翻译 - 第一章 - 事实,规则和查询 - 第三节, 练习题和答案

练习题 1.1 下面的字符序列哪些是原子,哪些是变量,哪些两者都不是? 1. vINCENT 2. Footmassage 3. variable23 4. Variable2000 5. big_kahuna_burger 6. 'big kahuna burger' 7. big kahuna burger 8. 'Jules' 9. _Jules 10. '_Jules' 我的答案: vINCENT,variable23,big_kahuna_burger,'big kahuna burg

Learn Prolog Now 翻译 - 第二章 - 合一和证明搜索 - 第二节, 证明搜索

证明搜索 上一节我们已经学习了合一,本节我们继续学习Prolog是如何通过搜索知识库去决定输入的查询是否能够满足.我们将会学习证明搜索,并通过简单的一个例子去涵盖这个基础的概念. 假设我们有如下的知识库: f(a). f(b). g(a). g(b). h(b). k(X) :- f(X), g(X), h(X). 如果我们查询: ?- k(Y). 这个查询的结果十分明显,即k(b),但是Prolog是如何将其求解出的了?让我们继续看. Prolog读入整个知识库,然后尝试将查询k(Y)和知识库

高项3.7日第一次课,第一章信息化基础知识与第二章信息系统服务管理梳理

第一章 信息化的基础知识 1.国家信息化体系要素: 主要包括6要素,信息技术应用(龙头).信息资源(关键).信息网络(必要手段).信息技术产业(基础).信息化人才(成功之本).信息化法规政策和规范(保障). 2.电子政务: 电子政务建设的指导原则: (1)统一规划,加强领导. (2)需求主导,突出重点. (3)统一规划,拉动产业. (4)统一标准,保障安全. 主要任务: (1)电子政务网络由政务内网和政务外网构成,两网之间物理隔离,政务外网与互联网之间逻辑隔离.政务内网主要是副省级以上政务部门的

python 学习第一章(python基础编程第二版)

第一章:基础知识 1.双斜线:实现整除的操作符 >>>1//2 0 就算是浮点数,双斜线也会执行整除 >>>1.0//2.0 0.0 2.幂(乘方)运算符:双星 >>>2**3 8 tip:可以用函数pow代替运算符,pow(2,3) 3.十六进制和八进制 十六进制:前面加0x,第一个是数字0 >>>0xAF 175 八进制:在3.0以上版本的python中加0o,首数字是0,第二个是字母o >>>0o10 8 4.

Java 7 Concurrency Cookbook 翻译 第一章 线程管理之四

七.创建和运行一个后台线程 Java中有一种特别的线程叫做 deamon(后台) 线程.这类线程具有非常低的权限,并且只有在同一个程序中没有其他的正常线程在运行时才会运行.注意:当一个程序中只剩下后台线程时,JVM会终结所有的后台线程并结束程序. 由于这个特性,后台线程一般用于为同一个程序中的其他正常线程提供服务.这种后台线程一般都有一个无限的循环在等待请求服务或者执行请求的任务.由于不知道它们何时可以获得CPU的调用执行,同时在没有其他正常线程的情况下会被JVM终结,所以后台线程不能用于执行重

Java 7 Concurrency Cookbook 翻译 第一章 线程管理之三

五.睡眠和唤醒一个线程 有时,你会想要在一段特定的时间后再去中断线程的运行.举个例子,程序中的一个线程每一分钟检查一次传感器的状态,剩余的时间,线程应该处于空闲的状态.在这段空闲时间里,线程不会使用计算机的任何资源.一分钟后,线程已经准备好了,才让JVM选择调用它继续执行.你可以使用 Thread 类的 sleep() 方法来达到此目的.该方法接受一个 int 类型参数表明线程挂起不运行的毫秒数.当睡眠时间结束,线程转移到可运行状态等待JVM的调度. TimeUnit 枚举类的某个成员同样具有

Java 7 Concurrency Cookbook 翻译 第一章 线程管理之二

三.中断一个线程 一个拥有多个线程的Java程序要结束,需要满足两个条件之一:一是所有的非后台线程都执行结束了:二是某个线程执行了 System.exit() 方法.当你想要终结一个运行中的Java程序或者程序的用户想要取消一个线程正在执行的任务时,你都需要结束一个线程. Java提供中断机制来表明我们想要终止一个线程.这个机制的核心是线程必须要检查自己是否被中断,而且线程自己决定是否响应中断请求.线程可以忽略该中断请求而继续执行. 在本秘诀中,我们将开发一个程序,这个程序创建线程,5秒后使用中

Java 7 Concurrency Cookbook 翻译 第一章 线程管理之六

十一.处理线程组中的未控制异常 每种编程语言一个很重要的特性就是其所提供的用来处理程序中错误情况的机制.Java语言和其他的现代语言一样,是提供了异常机制来处理对象程序中的错误.Java提供了很多的类来对应不同的错误.当Java检查到这些错误时,会抛出对应的异常对象.你可以直接使用那些异常类或者实现自己的异常类来处理程序中出项的错误情况. Java同时提供了捕获和处理异常对象的机制.异常必须被捕获或者重新抛出来.这类异常称为检测异常.还有一类异常不必捕获和处理,称为不检测异常. 在本秘诀中,我们