1 / 70

第 12 章 Visual Prolog 程序元素

第 12 章 Visual Prolog 程序元素. 12.1 项 12.2 常量 12.3 谓词 12.4 子句 12.5 事实 12.6 评估 12.7 程序段 本章小结 本章习题. 12.1 项. 本章介绍 Visual Prolog 的程序元素,内容包括项( Terms )、常量、谓词、子句、事实、运算、程序段等。. 12.1.1 项的基本概念. 项有两种类型:公式 formulas 和表达式 expressions 。 表达式代表数值,比如数字 7 ;公式代表逻辑声明,比如 “ 数字 7 比数字 3 大 ” 。

kamil
Download Presentation

第 12 章 Visual Prolog 程序元素

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第12章 Visual Prolog程序元素 • 12.1 项 • 12.2 常量 • 12.3 谓词 • 12.4 子句 • 12.5 事实 • 12.6 评估 • 12.7 程序段 • 本章小结 • 本章习题 AI程序设计

  2. 12.1项 • 本章介绍Visual Prolog的程序元素,内容包括项(Terms)、常量、谓词、子句、事实、运算、程序段等。 AI程序设计

  3. 12.1.1项的基本概念 • 项有两种类型:公式formulas和表达式expressions。 • 表达式代表数值,比如数字7;公式代表逻辑声明,比如“数字7比数字3大” 。 • 下面是项的简化定义,其中包括非法的语法结构。例如,! + !的书写形式是不合法的。但是,相信在和语言概念的直觉理解相结合时,使用这样的简化语法表示,在大多数情况下对于类型系统和运算符层次结构的描述更为有利。 AI程序设计

  4. 12.1.1项的基本概念 • term: • (term) •    unaryOperator term •    term binaryOperator term •    literal •    identifier •    qualifiedName •    globalName •    memberAccess •    predicateCall •    cut •    ellipsis •    factvariableAssignment • 文字有通用类型: • literal: • stringLiteral • characterLiteral • integerLiteral • realLiteral • binaryLiteral • cut: • ! AI程序设计

  5. 12.1.1项的基本概念 • 谓词调用 • 一个谓词调用形式如下: • predicateCall: • term(term-comma-sep-list-opt) • 首项必须直接声明调用谓词的名字。就是说,首项必须是一个谓词名,一个限定谓词名或一个成员访问。 • 注意,有些谓词有返回值,有些则没有返回值。如果一个谓词有返回值,这个值就必须在上下文中使用,不能被忽略。 AI程序设计

  6. 12.1.1项的基本概念 • 事实赋值 • 赋值操作符 := 用于向事实变量factVariable赋予一个新值。项term必须被赋于一个适当类型(即与事实变量或子类型相同的类型)的值。 • factVariableAssignment: • factVariable:=term AI程序设计

  7. 12.1.2运算符 • 运算符(Operators)按优先层次进行组织。在规则中,下面各组中的操作符具有相同的优先权,并且上面的操作符比下面的优先级高。就是说,一元加减法要比乘法运算符优先级高,而乘法运算符又比加法运算符高。圆括号可以改变运算优先级。 • unaryOperator: • - + • binaryOperator: •    multiplicationOperator •    additionOperator •    relationOperator •    andOperator •    orOperator AI程序设计

  8. 12.1.2运算符 • 12.1.2.1 算术运算符 • 算术运算符(Arithmetic Operators)用于数字的算术运算。它们是表达式,用表达式作为参数。它们采用根类型作为参数,并返回通用类型的结果。(参见通用类型和根类型)所有的算术操作符都是左结合的(left associative)。 • multiplicationOperator: one of • *   /divmod • additionOperator: one of • +- AI程序设计

  9. 12.1.2运算符 • 12.1.2.2 关系运算符 • 关系运算符(Relational Operators)是公式,用表达式作参数。它们从本质上是无关联的。 • relationOperator: one of • >   <   >  =   <=   <>   ><   = AI程序设计

  10. 12.1.2运算符 • 12.1.2.3 逻辑运算符 • 逻辑运算符(Logical Operators)主要包括逻辑“与(and)”、逻辑“或(or)”及逻辑“非(not)” 运算符等。逻辑“与”运算符andOperator和逻辑“或”运算符orOperator是公式,用公式作参数。它们是左结合的。" ,"和 " and "是同义词," ;" 和" or "也是同义词。 andOperator: one of ,and orOperator: one of ;or AI程序设计

  11. 12.1.2运算符 • 运算符举例: • 以下的项 • 7 + 3 * 5 * 13 + 4 + 3 = X / 6 ; A < 7,  p(X) • 与下面的项含义相同: • ((((7 + ((3 * 5) * 13)) + 4) + 3) = (X / 6)) ; ((A < 7) , p(X)) • 也就是说,项的最外面一层是两个项的“or”,而第一项是一个(=)关系项,第二项是"and"关系项。 AI程序设计

  12. 12.1.3类成员访问 • 类实体通过限定类名的方式进行访问: qualifiedName: identifier::identifier • 这样的限定名像普通的名字一样使用,即如果它是一个谓词,它就可以用于一个参数集。 • 有些名字访问不需要限定,参见有关作用域的内容。 AI程序设计

  13. 12.1.4对象成员访问 • 每当引用一个对象时,都可以访问该对象的对象成员谓词。 memberAccess: term :identifier • (目前,项term必须是一个变量或一个事实变量) • 标识符identifier必须是项term的类型。 • 在一个实现内部,对象成员谓词不需要引用对象就可以被调用,因为"This"已经被包含在其中了。参见有关作用域的内容。 AI程序设计

  14. 12.1.5全局实体的访问 • 存在于Visual Prolog中的仅有的全局实体是类、接口和内部论域、谓词、常量。全局名在任意作用域内都可以直接访问。也可能存在全局名与局域名或输入名重合的情况。在这种情况下,全局实体可以用双冒号‘::’来限定(不带前缀的类名或接口名)。双冒号可以随处使用,但是最重要的用处还是接口名用作形式参数类型说明符的情况。 • globalName: • ::identifier AI程序设计

  15. 12.1.6 论域、算符和常量访问 • 论域、算符和常量都像类成员一样被访问。即便它们在一个接口中被声明。 • 这就是说,当它们要被限定的时候,就总是以类或接口名加双冒号来限定。 AI程序设计

  16. 12.2常量 • 本节介绍常量(Constant)的有关概念,内容包括常量段、常量定义等。 AI程序设计

  17. 12.2.1常量段 • 一个常量段(Constants Section)定义了当前作用域内的常量集。 • constantsSection : • constantsconstantDefinition-dot-term-list-opt AI程序设计

  18. 12.2.2常量定义 • 常量定义(Constant Definitions)声明一个命名的常量,包括它的类型和值。 • constantDefinition : • constantName:typeName=constantValue • constantName : • lowerCaseIdentifier • 常量值constantValue是一个表达式,在编译时间内计算。常量名ConstantName应该是一个小写标识符lowerCaseIdentifier。 • 如果一个类型名typeName论域是一个标准论域,那么它和冒号' : '可以被省略,得到以下简写形式: AI程序设计

  19. 12.2.2常量定义 • constantDefinition : • constantName=constantValue • 以这样的方式定义的常量可以用于所有的上下文中,在这里可以使用与其同一种类的文字。 • 如果类型名typeName被省略,那么常量论域必须明确地被常量值表达式确定。仅在下列内部论域情况下,typeName才能被省略。 • a)数字(整数或实数)常量。在这种情况下,相应的匿名数字论域被采纳为常量(详细情况参见数字论域) • b)二进制常量。 • c)字符串常量。 • d)字符常量。 AI程序设计

  20. 12.3谓词 • 本节介绍谓词(Predicates)的有关概念,内容包括谓词段(Predicates Sections)、构造段(Constructors Sections)、接口谓词(Predicates from Interface)、谓词的元(Arity)等。 AI程序设计

  21. 12.3.1 谓词段 • 谓词段声明当前作用域内的对象或类谓词的集合。 • predicatesSection : •     class-opt predicates predicateDeclaration-dot-term-list-opt • 关键字class只能在类实现内部使用,这是因为在接口中声明的谓词永远是对象谓词;在类声明中声明的谓词永远是类谓词。 AI程序设计

  22. 12.3.1 谓词段 • 谓词声明 • 类声明用于声明作用域中的谓词,在作用域中这些谓词是可见的。当谓词在一个接口定义中被声明时,就是说相应类型的对象必须支持这些谓词。当谓词在类声明中被定义时,就是说该类提供所声明的公用谓词。并且,如果谓词在类的实现中被声明的话,那么该谓词就在局部可用。在所有的情况下,必须存在谓词的相应定义。 • predicateDeclaration : • predicateName:predicateDomain linkName-opt • predicateName:predicateDomainName linkName-opt • linkName : • asstringLiteral • predicateName : • lowerCaseIdentifier • 这里predicateDomainName是在论域段声明的谓词论域名。 AI程序设计

  23. 12.3.1 谓词段 • 一个谓词声明,声明了该谓词的名称以及类型、模式、流(参见谓词论域)和可选的一个连接名。 • 只有类谓词可以有连接名。如果没有声明连接名,那么就从谓词名取连接名,取名的方式取决于调用约定。 • 如果调用约定是apicall,那么as子句中所声明的连接名就可以采用任意方式修饰;如果该修饰不是所要的,则用stdcall代替。 AI程序设计

  24. 12.3.2 构造段 • 构造段声明了构造器的集合。这些构造器属于所出现的构造段的作用域(参见类声明和类实现)。 • constructorsSection : • constructorsconstructorDeclaration-dot-term-list-opt • 构造段只能出现在构造对象的类的声明和实现当中。 AI程序设计

  25. 12.3.2 构造段 • 构造声明 • 构造声明用于声明类的已命名的构造器。 • 实际上,构造器包含两个相关谓词。 •          * 一个类函数,返回一个新的被构建的对象; •          * 一个对象谓词,在初始化继承对象时使用。 • 一个相关的对象谓词构造器用于执行一个对象的初始化。该谓词只能从该类自身的构造器或是该类的继承类的构造器中调用(即基本的类初始化)。 • constructorDeclaration : • constructorName:predicateDomain • 给构造器声明谓词模式是非法的,构造器总是过程模式的。 AI程序设计

  26. 12.3.2 构造段 • 举例 • 考虑下面的类: class test_class : test constructors        new : (integer Argument) . endclass test_class • 相关的类级的谓词形式如下(有以下标志): class predicates        new : (integer) -> test. • 而相关的对象级的谓词形式如下: predicates        new : (integer). AI程序设计

  27. 12.3.2 构造段 • 再考虑下面的实现: implement test2_class inherits test_class clauses        new() :-            test_class::new(7),  % invoke the base class constructor on "This"            p(test_class::new(8)). % create a new object of the base class and pass it to p(...)   ... • 第一次调用test_class::new不返回值,因此这是对构造器的非函数对象的一次调用。就是说,这是基本类构造器"This"的一次调用。 • 第二次调用返回一个值,因此它是对类的构造器的函数调用。就是说,创建了一个新的对象。 AI程序设计

  28. 12.3.3 接口谓词 • 一个接口能够通过在predicates from段声明的谓词来支持另一接口的子 • 集。predicates from 段指定接口和所有支持的谓词。这些谓词以名字或者名 • 字和元数来声明。 • 如果一个接口支持另一个接口的子集,那么它就不是与另外那个接口相关的 • 子类型或超类型。 • 关于predicates from段重要的是,所提及的谓词保留它们的原始接口。因 • 此: • * 来自原始接口的任意谓词不会发生支持冲突; • * 它们能够作为来自原始接口的谓词被继承。 • predicatesFromInterface : • predicatesfrominterfaceNamepredicateNameWithArity-comma-sep-list-opt • predicatesFromInterface只能在接口定义中被使用。 AI程序设计

  29. 12.3.3 接口谓词 • 举例 • interface aaa •    predicates •        ppp : (). •        qqq : (). • end interface aaa • interface bbb •    predicates from aaa •        ppp •    predicates •        rrr : (). • end interface bbb • interface ccc supports aaa, bbb • end interface ccc • 即使aaa和bbb都声明了谓词ppp,但ccc可以不产生任何冲突地支持二者。这是因为ppp在所有情况下都含有aaa,将其作为原始接口。 AI程序设计

  30. 12.3.3 接口谓词 • 举例 • interface aaa • predicates •        ppp : (). •        qqq : (). • endinterface aaa • interface bbb • predicatesfrom aaa •        ppp • predicates •        rrr : (). • endinterface bbb • class aaa_class : aaa • endclass aaa_class • class bbb_class : bbb • endclass bbb_class • implement aaa_class inherits bbb_class • clauses •        qqq(). • endimplement aaa_class aaa_class可以从bbb_class继承ppp,因为ppp在两个类中都含有aaa,并将其作为原始接口。 AI程序设计

  31. 12.3.4 变元 • 使用N个参数的谓词被称为N元谓词(N-ary),或者说该谓词有N个变元。所含变元数不同的谓词,即使它们名称相同,通常也是不同的谓词。 • 在大多数情况下,一个谓词的元数在包含该谓词的上下文中是明显的。但是,在某些情况,比如,接口谓词段predicatesFromInterface段和resolve限定中,变元数并不明显。 • 为了区别predicates from 段和resolve限定中不同变元数的谓词,谓词名可以选择采用带有变元数的声明。 AI程序设计

  32. 12.3.4 变元 • 下列变元数是可能的: • ·       Name/N 指一个普通谓词 (即不是一个函数)的名字,变元个数为N; • ·       Name//N 指一个函数名,变元个数为N; • ·     Name/N... 指一个带N个变元的普通谓词名,后跟一个省略参数 (即个数可改变的参数) • Name//N... 指一个带N个变元的函数名,后跟一个省略参数。 AI程序设计

  33. 12.3.4 变元 • predicateNameWithArity : • predicateNamearity-opt • arity : • /integerLiteral ellipsis-opt • //integerLiteral ellipsis-opt • 在Name/0... 和Name//0... 中,0是可选项,因此它们可以分别写作Name/... 和 Name//...。 • 注意,省略号"…"可以作为最后一个形式参数用于谓词和谓词论域的声明。在这种情况下,就是指所声明的谓词(或谓词论域)的参数个数是可改变的。省略流必须与一个省略参数匹配,因此只能是流模式中的最后一个流。 AI程序设计

  34. 12.4 子句 本节介绍子句(Clauses)的有关内容,包括子句段(Clauses Sections)、目标段(Goal Sections)等。 AI程序设计

  35. 12.4.1 子句段 • 子句段由子句集组成。子句段包括谓词的实现或事实的初始化值。 • 一个单独的子句段可以含有几个谓词和事实的子句。另一方面,同一谓词或事实(同名并变元数相同)的所有子句必须集中在一个子句段中,并且不涉及其它谓词或事实的子句。 • clausesSection : • clausesclause-dot-term-list-opt • 子句用于定义谓词。单一的谓词由一个子句集定义。每个子句依次执行,直到其中一个子句成功,或没有子句可执行为止。如果没有子句成功,该谓词失败。 • 如果一个子句成功,并且在一个谓词的剩余部分有更多相关子句,那么程序控制将在以后回溯到该谓词的子句,以查找其它的解决方案。 AI程序设计

  36. 12.4.1 子句段 • 子句由一个子句头(head)和一个可选的子句体(body)组成。 • clause : • clauseHeadreturnValue-optclauseBody-opt • clauseHead : • lowercaseIdentifier(term-comma-sep-list-opt) • returnValue : • =term • clauseBody : • :-term AI程序设计

  37. 12.4.2 目标段 • 目标段是一个程序的入口。当程序开始执行时,首先从目标段开始执行,目标段被执行完后,程序就退出。 • goalSection : • goalterm. • 目标段由一个子句体组成。目标段定义了它自身的作用域,因此所有的调用都应当包含类的限定符。 • 通常,目标必须是过程模式。 AI程序设计

  38. 12.5 事实 • 本节介绍事实(Facts)的有关内容,包括事实段(Facts Sections)、事实声明(Fact Declarations)、事实变量(Fact Variables)等。 AI程序设计

  39. 12.5.1 事实段 • 一个事实段声明一个由若干事实组成的事实数据库。该事实数据库及事实属于当前作用域。 • 事实数据库可以存在于类级别上,也可以存在于对象级别上。 • 事实段只能在类实现中进行声明。 • factsSection : • class-optfactsfactsSectionName-optfactDeclaration- • dot-term-list-opt • factsSectionName : • -lowerCaseIdentifier AI程序设计

  40. 12.5.2 事实声明 • 事实声明用于声明一个事实数据库的事实。事实声明也是一个事实变量或一个事实算符。 • factDeclaration : • factVariableDeclaration • factFunctorDeclaration • factFunctorDeclaration : • factName:(argument-comma-sep-list-opt)factMode-opt • factName : • lowerCaseIdentifier • 一个事实算符声明缺省为nondeterm事实模式。 AI程序设计

  41. 12.5.2 事实声明 • 一个事实算符可以通过子句段进行初始化。在这种情况下,子句中的值应当是表达式,这些表达式可以在编译时间内进行求值。 • factMode : one of • determnondetermsingle • 如果模式为single,那么一个事实就有一个值并且只有一个值,而且谓词assert会给原来的值赋新的值。谓词retract不用于单个事实。 • 如果模式为nondeterm,那么这一事实就可以有0个、1个或任意其它个值。如果模式为determ,那么事实可以有0或1个值。如果事实有0个值,那么任何读操作都会失败。 AI程序设计

  42. 12.5.3 事实变量 • 一个事实变量与一个一元单个事实算符类似。但是,从语法上讲,它作为可 • 变变量(即以赋值方式)使用。 • factVariableDeclaration : • factVariableName:domaininitialValue-opt • initialValue : • :=constantValue • factVariableName : • lowerCaseIdentifier • 一个常量值constantValue应当是一个项(论域类型的),可以在编译时间求值。 • 只要在一个构造器中将事实变量初始化,那么常量值就可以省略。类事实变量应当总有一个初始的常量值。 AI程序设计

  43. 12.5.3 事实变量 • 注意,关键字erroneous可被用来将其值赋给事实变量。下面两行是有效的: • facts •     thisWin : vpiDomains::windowHandle := erroneous. • clauses •    p() :- thisWin := erroneous. • 用erroneous赋值的基本思想,是为了在某些代码错误地使用了未初始化的事实时,给出一个明确的运行时间错误。 AI程序设计

  44. 12.5.4 事实 • 事实只能在类实现中进行声明,并且以后它们只能从这个实现被引用。因此事实的作用域就是它们被声明的这个实现。但是对象事实的生命期是它所属的对象的生命期。同样地,类事实的生命期是从程序开始到程序结束。 • 举例 • 下面的类声明了一个对象事实objectFact和一个类事实classFact: • implement aaa_class • facts •        objectFact : (integer Value) determ. • classfacts •        classFact : (integer Value) determ. •    ... • end implement aaa_class AI程序设计

  45. 12.6 评估 • 评估(Evaluation)又称为求值运算。Visual Prolog通过执行目标来实现。 • 目标是一个项。本节叙述项和子句的执行或计算是怎样进行的,包括回溯(Backtracking)、谓词调用、合一(unification)、引用论域、匹配、嵌套的函数调用、变量与常量、算术表达式、事实断言与撤消等。 AI程序设计

  46. 12.6 评估 • 12.6.1 回溯 • 12.6.2 谓词调用 • 12.6.3 合一 • 12.6.4 引用论域 • 12.6.5 匹配 • 12.6.6 嵌套的函数调用 • 12.6.7 变量与常量 • 12.6.8 算术表达式 • 12.6.9 事实断言与撤消 • 12.6.10 失败谓词和 • 成功谓词 • 12.6.11 逻辑与 • 12.6.12 逻辑或 • 12.6.13 逻辑非 • 12.6.14 截断 • 12.6.15 谓词finally/2 AI程序设计

  47. 12.6.1 回溯 • 一个Prolog程序的评估或运算是搜索求解的过程。搜索求解的每一步或者成功或者失败。在程序执行的特定点上,有可能不止有一种解决方案。当遇到这样的选择点时,就建立所谓的回溯点。一个回溯点是程序状态的一个记录,即添加一个指针到未执行的选择点。如果它证明了初始的选择不能提供解决方案(即失败),那么程序将回溯到记录过的回溯点,从而恢复程序状态和追踪另一个选择。在下面的部分还将对该机制进行详细描述和解释。 AI程序设计

  48. 12.6.2 谓词调用 • 通过使用参数到一个谓词实现该谓词的调用。该谓词必须有一个流模式,以匹配参数的自由或绑定状态。每个谓词由一个子句集合(或在外部用某种其它语言)定义。 • 当谓词被谓词调用引用时,每个子句依次执行直到它们成功,或直到没有子句可执行为止。如果没有子句成功,那么该谓词失败。 • 如果一个子句成功并且还剩有其他的有关子句,那么程序控制可以在以后回溯到剩余的子句,以搜索其它的解。 AI程序设计

  49. 12.6.2 谓词调用 • 举例 • clauses •    ppp() :- qqq(X), • write(X), fail. •    qqq(1). •    qqq(2). •    qqq(3). 当ppp被调用时,它依次调用qqq。当qqq被调用,它首先建立一个指向第二个子句的回溯点。然后执行第一个子句。因此ppp中的自由变量X与数字1匹配,从而X被绑定为1。 在ppp执行时,X(即1)被写出后,由fail援引回溯点。从而程序控制被设置到qqq中的第二个子句,并且程序状态被设置回qqq首次进入的状态,即ppp 的X不再被绑定。 在qqq中的第二个子句实际执行之前,第三个子句的回溯点已经建立好了。 AI程序设计

  50. 12.6.3 合一 • 当一谓词被调用时,来自调用的参数与每个子句的子句头的项合一。 • 合一是绑定变量的过程,在这一过程中,两项通过尽可能少的绑定达到相等(即为进一步绑定留下尽可能多的开放空间)。 • 变量可以绑定为各种项,包括变量或含有变量的项。 • 合一有时可能有时不可能,也就是说它可能成功也可能失败。 • 变量和与其合一的项是有类型的,一个变量只能被绑定到与它类型相同的项或子类型上。当两个变量互相绑定时,它们就必须是完全相同的类型。 • 如上所述,合一发生在一个谓词调用和子句头之间,也发生在比较两项是否相等之时。 AI程序设计

More Related