CN102037447A - 基于通知的约束集翻译以实现命令性执行 - Google Patents
基于通知的约束集翻译以实现命令性执行 Download PDFInfo
- Publication number
- CN102037447A CN102037447A CN2009801189183A CN200980118918A CN102037447A CN 102037447 A CN102037447 A CN 102037447A CN 2009801189183 A CN2009801189183 A CN 2009801189183A CN 200980118918 A CN200980118918 A CN 200980118918A CN 102037447 A CN102037447 A CN 102037447A
- Authority
- CN
- China
- Prior art keywords
- constraint
- input
- data member
- trigger
- commanding
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Granted
Links
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/40—Transformation of program code
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/40—Transformation of program code
- G06F8/41—Compilation
- G06F8/43—Checking; Contextual analysis
- G06F8/436—Semantic checking
- G06F8/437—Type checking
Landscapes
- Engineering & Computer Science (AREA)
- General Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Software Systems (AREA)
- Physics & Mathematics (AREA)
- General Physics & Mathematics (AREA)
- Computational Linguistics (AREA)
- Stored Programmes (AREA)
- Devices For Executing Special Programs (AREA)
Abstract
提供一种方法,该方法基于对每个约束集的可实例化对象的定义将约束集声明翻译成命令性代码序列,在状态修改时插入对通知回调机制的调用,并将约束上下文中的调用定义为命令性代码序列,该命令性代码序列响应于这些回调采取动作以维持这些约束。
Description
发明领域
本发明涉及计算机语言的自动翻译。
背景
在计算机技术的发展中,已开发了各种编程范例。这些范例中的两个范例是命令性编程和声明性编程。命令性编程需要提供逐步的命令性指令(例如设定等于2、增量c、调用过程f()),程序员将这些命令性指令组合起来以解决感兴趣的问题。声明性编程需要提供顶层信息(例如一组要强制实施的逻辑约束),该顶层信息经常以更透明地涉及感兴趣的问题的方式来指定。命令性编程往往提供改善的执行性能,但命令性程序可能非常复杂并且难以开发和维护。声明性程序往往相对容易开发和维护,但声明性编程也往往提供相对糟糕和/或受限制的执行性能(例如缓慢的执行和/或无通用性)。命令性和声明性范例的这些优缺点是业内公知的。
由于计算机的底层硬件模型是命令性的,并且处理器执行被动存储器上的命令性指令,因此最早的编程语言(例如汇编语言)是命令性的,且今日广泛使用的许多语言(例如C、C++)仍旧主要是命令性的。当前,声明性语言(例如Prolog、Haskell、Siri和ThingLab)往往是研究语言而不是商用开发语言。
在实践中,计算机语言可包括命令性和声明性两种范例的元素,尽管将任何特定语言归类为主要是命令性或主要是声明性很少会是不确定的。例如,C++提供类、虚函数和继承,这允许单段代码在各种对象类型上操作同时仅按照这些类型的某一基类来表达。这是C++的声明性方面,但C++语言本身主要是命令性的。
尽管纯粹的声明性语言尚未表现出通用性,然而在受限域内已获得令人印象深刻的结果。例如,SQL是涉及关系型数据库的查询和更新的受限域声明性语言。例如,查询是由定义“命中”的属性来指定的,而非命令性地指定如何定位这些记录。SQL在数据库应用中具有广泛商业用途。另一受限域语言是JavaFX,它包括SQL类触发机制以声明要在值改变时调用的过程。该工具明显受限于仅允许在当前上下文中定义数据元素上的触发条件。这些JaVaFX触发器也类似于AspectJ和其它所谓面向方面的编程语言中的“连接点”。这些连接点允许在对象初始化、字段读写和异常处理程序期间在过程的开始和结束时调用代码。
受限域声明性语言的另一示例是用来向解析器生成器指定语法的语言。该语法被指定为声明性产生规则。解析器生成器将程序作为这些产生规则的集合翻译成实现针对所指定的语法的解析器的命令性代码。在指定语法来识别明显是声明性的,这依赖于语言翻译器来确定如何实现解析器。这种声明性方法已被证明在语言翻译器生成中具有重大价值,这避免了手动实现解析器的耗时且易于出错的任务。然而,编译器或解释器的其余部分是以单独的命令性编程语言来实现的,这导致与共同使用两种不同语言和翻译器相关联的问题。
在某些情形下,由声明性编程提供的有益结果已推动了各种在单个通用编程语言中提供两种范例的主要优点的尝试。迄今为止的方法主要侧重于将命令性编程结构映射到声明性模型(例如在Kaleidoscope’90中的运行时约束解算器)。另一示例是C++的Turtle库,其中Turtle语言的约束模型被结合到C++中。然而,这些方法看来不能解决纯声明性编程模型的固有低效率的问题。
因此,提供对命令性和声明性结构两者进行更为高效和系统的使用的通用编程将是本领域的进步。
概述
根据本发明的各实施例,声明性编程的所选方面被纳入到另外的命令性框架中。具体地,提供对约束的声明性指定。本发明的各实施例的其它重要方面包括在程序单元不需要事先知道其数据成员中的哪一些服从约束的情形下在翻译时对约束的自动求解以及对程序单元的单独翻译。在实践感兴趣的许多情形下,以声明性方式指定的约束可在编译时由编译器来求解以提供包括用于强制实施约束的自动提供的命令性代码的命令性程序表示。如此,命令性编程所特有的效率不会因为添加了对约束的声明性指定而受到明显危及。贯穿本申请,“翻译”包括“编译”和“解释”,并且对“编译”等的引用可与对“解释”等的引用互换,除非另外专门有说明。
参照附图开始对本发明的各实施例的一些基本的概述是有益的。图1示出已知编程结构的伪代码示例。在该例中,程序单元102包括准声明性语句“do A if X changes(如果X改变则进行A)”。作为该语句的结果,当程序员(例如在“set X(设定X)”行内)更改X时,则该语言自动提供代码以在“set X”指令后立即“do A(进行A)”。在所有附图中,由语言自动提供的代码由虚线包围。图1的示例类似于一些已知的编程结构(例如JavaFX的触发器)。
从概念上说,图1结构的实现是相对直接的。具体地,当声明性语句如图所示地处于与正被改变的输入相同的程序单元和相同的上下文中时,则执行A的代码可由编译器在更改X的每一行之后立即自动插入。然而,存在对这种结构麻烦的概念方面。具体地,该例中的A可以是任意命令性代码,这能造成状态的任意改变(即任意的副作用)。因此,这些结构具有复杂化软件开发的可能性。获得相同公认的另一方法是观察到“do A”本质上是命令性的,因此语句“do A if X changes”不是纯声明性的。
由本发明的各实施例提供的主要能力在两个显著方面与图1的示例存在区别。第一方面是专门针对作为声明性语句的约束的情形。由于约束是纯声明性结构,这消除了前述概念上的困难。第二方面是显著增强了自动命令性代码生成能力以适应约束处于与其对应的数据成员不同的上下文和/或不同的程序单元中的情形。
图2示出相对于图1的这两种改变的示例。在图2的示例中,第一程序单元202包括约束的声明性指定(即“enforce Y=f(X)(强制实施Y=f(X))”行)以及在约束范围之内和约束范围之外对X的改变的实例。第二程序单元204也包括对X的改变的实例。本发明的各实施例对于对X的改变的所有实例自动提供如图所示的“update Y(更新Y)”的命令性代码。此外,程序单元204可被单独编译而不必事先知晓其哪些数据成员是约束的输入或服从约束。该顶层功能由通知反应器结构提供,其在图2中示意地表示为206。在实现结构206时,用于通知和反应的代码在从输入源程序自动派生的中间表示中自动生成。该中间表示的进一步处理提供输出代码,该输出代码包括自动生成的用于强制实施约束的命令性结构,由此减轻程序员的那个负担。
图3a-5的示例示出应用于一具体示例的前述过程的步骤。更具体地,根据本发明的一个实施例的用于将包括约束的输入代码自动翻译成计算机可执行输出程序表示的方法示出于图3a-5b的示例中。
该方法的第一步骤是提供以也提供对约束的声明性指定的命令性编程语言表达的输入源程序,其中输入源程序包括根据所述编程语言指定的一个或多个约束。在该例中,图3a-b示出输入源程序的两个代码段,其中图3a的代码段可处于与图3b的代码段不同的上下文中,并且还可处于单独编译的程序单元中。附图和下面的示例中采用C++式伪代码,但本发明的实践不依赖于语言句法的细节。图3a的代码段包括类F的定义,F的实例F1和F2的声明以及对F1.X的赋值。图3b的代码段包括约束集CS的定义和对F2.Y的赋值。约束集CS包括若干约束:tot等于F1.X+F1.Y;tot2等于F1.X+F2.Y;而F1.X等于F2.X*F2.Y。还指定如果F1.X改变则F2.Y保持不变(F2.Y fixed if F1.X changes)。约束是约束数据成员(例如tot、tot2、F1、F2)的关系。约束集CS还提供对哪些约束数据成员是输入和/或输出的标识。这里tot、tot2专门为输出,而F1和F2可以既是输入又是输出。约束输入的标识可以是显式的(如前所述)和/或隐式的。输入可基于其在约束指定内的位置而隐式地标识(例如在等式约束的右手侧的数据成员可隐式地被视为约束输入)。
该方法的第二步骤是自动提供约束的约束表示。每个约束表示包括一个或多个约束反应器对象以在实例化时注册输入改变通知。约束反应器对象包括用于强制实施约束的命令式过程,并且在相应约束表示的范围内是可访问的。在这里和本申请全文中,“包含代码”意指文字内联代码包括和/或(例如使用指针)直接提供对范围外代码的范围内访问。对于该例的约束表示示出于图4b中,其中如前所述虚线围住自动提供的代码。
在该例中,类CS的实例cs是约束表示,而FR1和FR2分别为约束反应器对象F1Reactor和F2Reactor的实例。F1Reactor包括用于在F1改变时强制实施约束的代码(即,真正的更新过程)。更具体地,如果F1.X改变,则F1Reactor中的onX()过程根据约束命令性地更新tot、tot2和F2.X。如果F1.Y改变,则F1Reactor中的onY()过程命令性地更新tot。同样,F2Reactor包括用于在F2改变时强制实施约束的代码。在该例中,F1Reactor和F2Reactor被包含在类CS中,该类CS被实例化为cs。该实例化为FR1和FR2提供对输入F1和F2的指针访问。如本例所示那样将约束分组成若干约束集是优选但非必须的。在这些情形下,对约束集的每个输入通常存在一个反应器,每个反应器可包括从多个约束派生的命令性语句,并存在与每个输入约束集(例如图3b上的约束集CS)对应的一个约束集对象表示(例如图4b上的类CS)。
该方法的第三步骤是,对输入源程序的一些或全部程序数据成员中的每一个自动地提供相应的通知代码,以提供改变通知并调节约束表示对输入改变通知的注册,其中相应通知代码在相应程序数据成员的范围内是可访问的。在该例中,图4a示出该自动提供的通知代码的一部分。将子类Notifiee(被通知者)插入类F内,其中Notifiee包括用于对其输入的改变的虚更新过程(即virtual onX()、virtual onY()和virtual onZ())、指向该实例的指针(即fp)以及当改变发生时拟通知的约束反应器对象的实例列表(即notifieelist(被通知者列表))。在翻译期间,自动管理被通知者列表以使每个数据成员具有全部完整列表和仅那些该数据成员是其输入的反应器实例。当且仅当相应数据成员改变时,才调用虚更新程序。通常为全部数据成员提供通知能力,即使没有相关约束(例如F1.Z、F2.Z没有约束)。这较为有利地避免了特定类中的哪些数据成员被涉及在约束中的任何先验知识的要求。在一些情形下,可能需要有选择地对一些数据成员禁用通知。如果对作为约束输入的数据成员禁用通知,则生成翻译错误。
本方法的第四步骤在命令性输出程序表示中实例化通知代码和约束表示,以使对约束输入的改变自动导致命令性约束驱动的更新,并将该命令性输出程序表示作为输出提供。例如,该命令性输出程序表示可通过编译被进一步处理成低级机器语言。
在图4a-b中,一个重要的细节是F1Reactor和F2Reactor类型是从F::Notifiee类型派生的。如此,调用虚更新过程(例如F1::Notifiee中的virtual onX())通过类型继承自动导致调用正确的反应器(FR1::on(X))中的正确的约束更新过程。该例的代码的操作示出于图5a-b的代码段中。在图5a中,向将赋值提供给F1.X的程序员自动补充虚线中所示的过程调用集。同样,在图5b中,对F2.Y的赋值同样被自动补充虚线中所示的过程调用集。
更具体地,改变图5a中的F1.X造成对反应器实例FR1的onX过程作出调用。该FR1.onX()过程根据约束更新tot、tot2和F2.X(通过执行赋值tot=F1.X+F1.Y、tot2=F1.X+F2.Y和F2.X=F1.X/F2.Y)。对F2.X的更新自动地导致对反应器实例FR2的onX()过程作出调用。该FR2.onX()过程通过执行赋值F1.X=F2.X*F2.Y来更新F1.X。然而,该赋值不实际改变本例中F1.X的值。因此,由于对FR2.onX()的调用不实际改变F1.X,因此约束更新处理在该调用之后终止。为了更清楚地理解,假定在对F1.X最初赋值前(F1.X,F1.Y))=(u,v)且(F2.X,F2.Y)=(w,x)。该第一次赋值给出(F1.X,F1.Y)=(a,v)。对FR1.onX()的调用导致(F2.X,F2.Y)=(a/x,x)。对FR2.onX()的调用设定F1.X=F2.X*F2.Y=a,a是FA.X在计算中的该点处已经有的值。由于F1没有改变,因此不需要另外的通知和反应。
图5b中的赋值F2.Y=b的效果可以用相同的方式来分析。对前一段的记法进行缩写,假设初始状态为F1=(u,v)且F2=(w,x)。将F2改变至(w,b)调用反应器FR2的onY()过程,这将F1改变至to(w*b,v)并将F2“改变”至(w、b),假设对F1的改变是在改变F2之前作出的。由于F2没有真正改变,因此FR1.onX()是由于F2的改变而调用的唯一反应器。该反应器将F2“改变”至(w,b),这不是对F2的值的改变。约束更新由此终止。
在图5b的示例中,如果FR2.onY()在更新F1前更新F2,则获得不同的最终状态。在这种假设下,FR2.onY()的作用是将F2设定为(u/b,b)并将F1“改变”至(u,v)。由于F1没有真正改变,因此FR2.onX()是由于对F2的改变而调用的唯一反应器。FR2.onX()将F1“改变”至(u,v),这不是对F1值的改变。约束更新由此终止。
约束更新处理通常不终止,除非计算达到同时满足所有相关约束的状态。在满足约束的情形下,该状态可以不是唯一指定的。尽管约束驱动的编程的这些方面对底层声明性范例而言是固有的,然而本发明的各实施例的一个重要方面是实践中的实现,将相对简单的约束添加至命令性框架是非常有力的。
约束驱动的编程的一般模型通常将全部约束视作多输入约束(例如a+b+c=0可具有输入a、b和/或c)。在实践感兴趣的许多情形下,多输入约束可被表达为一组单输入约束。这是有益的,因为单输入约束更容易在上述通知反应器框架中实现。例如,约束a+b+c=0可被表达为下面的单输入约束集:c=-a-b(a是输入);a=-b-c(b是输入);以及b=-c-a(c是输入)。这种多输入约束至单输入约束的简化可由程序员提供,或者在足够简单的情形下可自动生成。
注意图3a-5b中的示例包括按照单输入约束表达的多输入约束的实例。更具体地,多输入约束F1.X=F2.X*F2.Y被实现为F2.X=F1.X/F2.Y(F1是输入),F2.X=F1.X/F2.Y(F2是输入),以及F1.X=F2.X*F2.Y(F2是输入)。这种按照单输入约束的特定表示是由如果输入F1.X改变则保持F2.Y固定的指示结合常见的lhs/rhs惯例(例如,左手侧(lhs)上的变量通常因赋值而改变,而右手侧(rhs)上的变量一般不因赋值而改变)来驱动的。与约束复杂度相关的其它考量在详细说明中提供。
前面的说明提供对本发明的典型实施例的主要性能特征和基本实现特征的介绍。为了更好地理解本发明各实施例的一些变例和改进,在下面的概述的其余部分中对其作简单描述。
在一些实施例中,在数据成员中自动提供通知代码包括提供两个或更多个改变通知过程,并提供根据对程序数据成员的改变的性质对要调用这些改变通知过程中的哪一些的选择。例如,假设程序数据成员V是数字数组,并且通过约束,总计等于V的各个元素之和。在一些情形下,对V的改变是涉及其一些或全部元素的一般改变,并且在这样的情形下,总计的完全重计算在更新期间是无法避免的。然而,在其它情况下,对V的改变已知为单元素改变(例如V[3]从4变为6)。在这种情形下,总计可更高效地更新(即,将总计递增2),引起其前一值可被假设为因先验约束驱动更新而是正确的。这种性质的情况可提供给多个改变通知过程(例如,分别用于一般元素和单元素更新的onV()和onV[i]())。在这些通知过程之间进行选择是由对数据成员的改变的性质和改变的情形来驱动的。
存在输入源程序包括能更高效地实现一些更新的约束的情形。更具体地,如果输入源程序包括对与其一些或全部输入处于同一范围的约束的声明性指定,则可通过将范围内命令性代码自动插入到命令性输出程序表示中来在其范围内强制实施该约束。这些约束响应于对范围外输入的改变的强制实施可如上所述地处理。
在实践中,有利的是提供对用以执行每个约束反应器对象的程序控制的线程的选择。今日的编程环境通常提供这种线程选择。
通知和反应机制也能很好地与其它编程方法相组合。例如,结合如上所述的通知,对数据结构的密封以使改变只能通过增变器过程来作出是有益的,这是因为增变器过程可对要求约束驱动的更新的状态作出改变。
约束的概念可扩展至表示专用约束,该表示专用约束涉及具有不同表示的数据成员。这里,表示指的是如何物理地表示数据成员。常见表示包括普通的存储器内、串、未类型化和网络表示。可采用适配器来根据需要将一种表示翻译成另一种表示以监视和强制实施约束。
如前所述的约束驱动的命令性更新具有许多应用。约束可涉及复杂事件(例如交易或贸易)处理。也可采用约束来以声明性方式指定目标编程语言的语法。目标编程语言可以是或可以不是输入编程语言,并且可以是或可以不是在本发明的自动实践实施例中采用的任何中间表示的语言。
本发明的各实施例的约束处理能力可通过提供处理在翻译期间未求解(即,翻译成命令性代码)的约束集的运行时约束引擎来扩展。尽管这在一些情形下可能是有益的,然而常常更为优选的是避免对运行时约束引擎的依赖性以保持命令性编程的效率。
上文描述的通知和反应器机制不限于约束的实现。反应器也可包含任意命令性代码,尽管优选的是这些命令性代码至少为幂等的(即,在相同输入上将其执行两次或更多次具有与对其执行一次相同的效果)以避免意想不到的副作用。因此,本发明的一些实施例除约束外还包括过程触发器(PT)。
在这些情形下,PT根据其编程语言在输入源程序中指定,并且对于每个PT,表示其触发输入。每个PT包括当相应的触发输入改变时要调用一个或多个触发器过程。
每个PT的触发器表示是自动提供的,其中触发器表示包括触发反应器对象以在实例化时注册输入改变通知,触发反应器对象包括相应的触发器过程。通知代码还调节触发器表示对输入改变通知的注册。触发器表示在命令性输出程序表示中被实例化,以使对触发输入的改变自动导致所述触发器过程的执行。如前所述,触发器优选地为幂等的。这些触发器表示和触发反应器对象分别类似于前述的约束表示和约束反应器对象。
基于通知的约束集翻译提供若干重要益处:
1.编程语言中的关系和不变式的简洁表达,如由传统约束编程提供的,但有了谨慎地手动指定的命令性编程的执行效率,匹配硬件命令性执行模型。支持对象关系,应用专用算法、一般约束求解、分析器生成、复杂事件处理、分布式操作和类属接口的自动维护的可扩展性。
2.对显式约束集对约束处理进行的分组、提供受控制的单独调度的线程执行以及立即执行、通知处理共享和每个约束集的共享状态的控制以优化约束处理开销。相反地,约束可被划分成单独的集合以允许作为单独的约束集的并发执行。
3.状态的不同表示之间的约束的可扩展性,包括网络表示、存储表示、类属/无类型标识、串/XML表示等。
4.用于为数据成员的修改以及响应于这些数据成员被修改而进行的约束维护两者自动生成命令性代码序列的统一机制。
在本发明的各实施例中,源自翻译器的约束驱动的执行能够进入无限循环而不是收敛。然而,存在许多方式使命令性程序能够以没有约束的无限循环告终,因此该约束机制不改变命令性编程的这个基本特征。主要目的是通过支持约束来提供命令性程序的更简洁表达,但不更改或对抗命令性程序的基本属性。此外,可获得命令性语言的完整能力以应付该约束实现不合用的情形。最后,在包括约束求解器实现的实施例中,求解器可在其行为优良的情形下调用。
下面给出本发明的各实施例的这些和其它方面的进一步描述。
附图简述
图1示出已知编程结构的一个示例。
图2示出由本发明的一个实施例提供的功能的示例。
图3a-3b示出涉及本发明的一个实施例的示例的输入代码段。
图4a-4b示出与图3a-3b的示例的输入代码段对应的自动生成的表示。
图5a-5b示出与图3a-3b和图4a-4b的示例的输入代码段对应的命令性输出程序表示。
详细说明
在本发明的一个实施例中,编程语言包括用于指定被称为约束集的一组约束的一个或多个结构。“约束”表示需要在所有时间或在特定一个或多个时间保持的数据成员之间的关系的声明性指定。在前一种情形下,约束本质上等同于不变式。后一种情形的一个例子是仅在某一数据成员初始化时保持的关系。另一示例是引用另一对象中的数据成员的约束;该约束仅在该另一对象已知时保持。“主动约束”表示其中当涉及关系的状态改变时采取命令性动作以建立和维持该关系的约束。相比主动约束,被动或检查约束仅仅在检测到关系不保持时生成出错或异常指示。关系的性质可由约束运算符来指示。例如,相等关系可由“=”运算符来表示。
术语“数据成员”用来指定能够存储数据的已命名状态单元。之所以将其称为“成员”是因为它是该名称的某一范围的成员,例如类型、名称空间或过程。该术语也用于C++编程语言中。然而,使用该术语不是将各实施例限于C++的扩展或其任何派生物。
在一个实施例中,编程语言提供面向对象的语言的传统特征,包括类、继承、动态函数(虚函数)分派,另外还用每个数据成员的约束集(constraintSet)结构和约束上下文来扩展。约束集结构可由关键字“constraintSet”指示并可另行遵循语言中的类型指定的句法。数据成员上下文可被表示为以一数据成员的声明之后紧随的一个“{”符号开始并由符号“}”终止。其它实施例可使用不同句法,例如“begin(开始)”和“end(结束)”关键字以及受约束的数据成员的显式指定,而不是如上所述使其隐式地耦合于数据成员的声明。有了约束集,可定义由该集合中的各个约束引用的对象的局部名。在一个实施例中,在约束集中的局部数据成员的声明中的类型指示之前使用“input(输入)”关键字限定词,指示仅用作对该集合中的各约束的输入(只读)的数据成员,如果局部变量仅写入约束集中则使用“output(输出)”,且如果该集合中的各约束可能使该对象既能读出又能写入,则使用“inputOutput(输入输出)”。例如,在示例1中,一个简单的约束集“ReportMaintenance(报表维护)”
------------------------------------------------
constraintSet ReportMaintenance{
input Inventory inventory;
input Accounting accounting;
inputOutput Report report;
report->total=inventory->part{
`isAppliedOnAudit=true;
`isScheduled=false;
}
report->cost=report->total*accounting->avgPrice;
}
例1约束集指定
------------------------------------------------
指定了关于inventroy(目录)中的全部part(部件)和cost(成本)以及集合part的report(报表)之间的约束。(这里,inventory中的“part”数据成员指定对inventory对象中的每个类型part有一条目的集合,每一条目提供了inventory中该类型的part的计数。)当ReportMaintenance约束集被实例化为特定inventory、accounting(记账)和report对象时,根据由这些约束指定的关系来设定total(总计)和cost的受约束的数据成员,并随后当任一引用的数据成员改变时维持该受约束的数据成员。
约束可用其中指定了该约束的一个或多个属性的子上下文来指定,如例1所示。这里,在审计期间应用(AppliedOnAudit)的属性被设为真,使翻译器生成审计代码以检查指定的约束在软件审计期间保持。第二属性“isScheduled(被调度)”被设定为假以指示相关联的约束处理永远被立即调用,而不是在独立线程上调用(如下面描述的那样)。
该例示出约束工具的关键优点。它允许程序员指定report的要求值(即那些需要的值),从而使语义对软件的任何审阅者来说更为清楚。它还减轻了程序员确定软件中输入数据成员改变的全部位置并手动地插入在这些点执行约束维持的代码。如此,避免了对软件的修改无意地增加输入改变而不增加相应的更新代码的问题。它还缓解了程序员编写约束命令性代码以使其对输入改变的全部组合正确地维持这种关系的需要。因此,自动约束驱动的更新降低了软件的开发成本,减少出错可能性并提高了可靠性,并因此提高了可维护性。同时,所得到的实现可与传统命令性实现具有相同的效率。
约束集也可被定义为之前定义的约束集的扩展,如例2所示,其被称为扩展的约束集。
------------------------------------------------
constraintSet ExtendedReportMaintenance ReportMaintenance{
inputOutput Supervisor supervisor;
supervisor->attention = (report->cost >
supervisor->costLimit);
report->cost =report->total*accounting->avgPrice -
accounting->overhead;
}
例2扩展的约束集指定
------------------------------------------------
在本例中,定义附加的inputOutput对象“supervisor”并重新定义report::cost上的约束。
约束集的显式指定允许基于共同输入、共同输出、共同处理优先级分配和例如存储器分配等可能的其他属性来对这些约束进行分组。
下面的说明更详细地描述了约束集的实现以提供声明性指定的关键优势(即指定的简洁性),而没有声明性语言的关键缺陷,即实现的低效率,并且没有约束范围的显著限制,例如仅限于局部实例变量。
A.约束集实现
在一优选实施例中,翻译器生成约束集的内部表示作为具有指定名称的类。例如,例1的约束集的内部表示可使用C++指定为:
------------------------------------------------
class ReportMaintenance:public Fwk::RootConstraintSet{
Thread*thread_;
…
}
例3实现为C++类的约束集
------------------------------------------------
其中基类“Fwk::RootConstraintSet”提供全部约束集所共有的基本功能集。“thread_”数据成员指示与该约束集相关联的过程将要在其上执行的处理资源。这里,标志“…”指示完成该实现所需的C++中的附加实现,这将在下文中描述。C++中所需的公共内容、受保护内容等的表示与指针和“const(常量)”的指示一样为简化目的而被省去。
扩展的约束集可被实现为从对应于它所扩展的约束集的类继承的类,如例4中的C++表示中所示那样。
------------------------------------------------
class ExtendedReportMaintenance:public ReportMaintenance{
…
}
例4使用继承的扩展的约束集实现
------------------------------------------------
在一个实施例中,该实现依赖统一通知机制来确定输入何时改变,这要求处理确保约束集中的各约束被维持。这在下文中描述。
A.0基于通知的约束实现
在一个实施例中,翻译器采用了称为通知工具的统一回调机制,该机制提供了注册要在数据成员被修改时调用的过程的能力。当一对象被指定为约束集中的一个输入时,翻译器定义回调过程,该回调过程在该对象中的数据成员改变时对该约束执行所需处理,并生成将该过程注册来自该对象的回调的命令性指令。
通知工具一般可通过被称为“监听器”设计模式的方式来实现。在一特定实施例中,翻译器为每一对象类型Foo生成用于Foo的回调接口的内部表示,其中对Foo中可充当输入的每个数据成员有一回调原型函数。例如,用于Inventory类型的回调接口的内部表示可使用C++指定为嵌套类Notifiee,如例5所示。
------------------------------------------------
class Inventory{
…
class Notifiee{
public:
virtual void onPart(String key){}
virtual void onPart(){}
};
Notifiee notifieeList;
}
例5作为C++类的通知回调接口
------------------------------------------------
″onPart″虚函数对应于Inventroy类的“part”数据成员并且默认地不做任何事。具有参数的那一个虚函数对应于已知的指定条目改变而另一个则对应于对part集合的未知改变集。
翻译器还将“notifieeList”加至Inventory类型的内部表示,该notifieeList存储Inventory::Notifiee实例的列表。每个这种Notifiee实例也是被定义为Notifiee类型的派生类型的反应器实例,如下文中更详细描述的那样。最后,翻译器在程序的内部表示中可修改数据成员“dm”的每个点处插入其相应的notifieeList上的迭代,从而对于该列表中的每个对象的dm调用“on”虚函数(如果有的话)。例如,对于由“key(关键字)”指定的Inventory::part条目的情形,该插入的代码的内部表示可使用C++如例6那样指定。
------------------------------------------------
for(NotifieeListIterator i=notifieeListIter();i;++i){
i->onPart(key);
}
例6 Inventory::part改变中的通知回调过程
------------------------------------------------
该代码仅在由key指定的part条目已实际改变的情况下被调用。具体地,将该条目设定为其当前值的处理序列不生成通知回调。
为了实现例1的约束集,翻译器自动生成从每个输入的notifiee接口导出的每个输入的内部表示,从而用在数据成员被修改时执行所需命令性动作来强制实施约束集中的约束的函数来替换表现为对约束的输入的每个数据成员的默认空“on”函数。例如,对于输入的inventory::part,该内部表示可使用C++类代码被指定为从Inventory::Notifiee派生的嵌套类,从而覆盖了“onPart”函数以执行所需处理,如例7所示,并重复例3中指定的上下文。
------------------------------------------------
class ReportMaintenance:public Fwk::RootConstraintSet{
Thread*thread_;
Count oldPart_[Key];
class InventoryReactor:public Inventory::Notifiee{
void onPart(Key key){
Count newVal=inventory->part[key];
Count diff=newVal-oldPart[key];
cs_->report->total=cs_->report->total+diff;
oldPart[key]=newVal;
}
void onPart(){
Count sum=0;
if(inventory_){
for(PartIterator i=inventory_->partIter();i;++i){
Count newVal=i.value();
sum+=newVal;
oldPart[i.key]=newVal;
}
}
cs_->report->total=sum;
}
ReportMaintenance*cs_;
Inventory*inventory_;
void inventoryIs(Inventory*inv){
inventory_->notifieeListDel(this);
inventory_=inv;
inventory_->notifieeListInsert(this);
}
};
DataMemberId notifyingDataMember_;
Key notifyingDataMemberKey_;
Inventory * inventory() { return
inventoryReactor_->inventory_;}
void inventoryIs(Inventory*inv){
inventoryReactor_->inventoryIs(inv);
inventoryReactor_->onPart();
}
InventoryReactor*inventoryReactor_;
Report * report;
…
}
例7 Inventory::part输入的内部表示
------------------------------------------------
InventoryReactor类是从Inventory::Notifiee类派生的,这允许其通过类型继承来覆盖或替换″onPart″回调函数的实现。″oldPart″是由翻译器添加并在约束应用中用作优化的关键字索引的数组数据成员,其示出作为约束实现的一部分对约束集添加状态。
在指定的“part”条目改变的情形中,可基于与存储在约束集类中的旧值的差异来高效地更新report中的total。在未指定的对“part”集合的改变的情形下,完全重新计算total,从而刷新该约束集的上下文中的“oldPart”值。翻译器定义InventoryReactor类来包含“inventory”数据成员,该数据成员当被实例化时被初始化以引用相关联的目录。还定义数据成员以对每个集合数据成员指示通知数据成员以及与该通知数据成员相关联的关键字,用来通过后述的已调度通知来存储这些值。
如例7所示,输入被实现为称作“inventoryReactor”的数据成员,该数据成员实际上是包含指向实际Inventory对象的指针的InventoryReactor的实例。在一个实施例中,提供用于访问和修改该输入的函数。具体地,“inventoryIs”函数修改相关联的inventory对象,调用相关联的“onPart()”函数以当inventory对象改变时重新计算report中的total。此外,对InventoryReactor实例中的inventory字段写入的效果是将该反应器实例从当前inventory对象中的notifieeList中移除并将该反应器实例添加至由inventory字段引用的新inventory对象的被通知者列表。(为简化起见,省去在任何情形下对inventory对象为空的考虑。)
对“report”输出的引用通过指向所封装的约束集类实例的反向指针(如“cs_”数据成员所指定的)而在反应器类型中间接地访问,该指针在反应器对象被实例化时被初始化为指向该实例。一个实施例能改为提供对反应器为局部的数据成员,该数据成员参照与用作该反应器的通知对象的输入和输出不同的输入和输出。然而,需要有当例如“report”等实际输入改变时更新该局部数据成员的手段。
例7示出如何通过在与约束集相关联的上下文中提供状态——在本例中为oldPart——来优化约束实现。在其它约束的情形下,例如指定输出为输入的一阶导数的近似值的情形下,约束集可能需要额外状态以执行所要求的计算。
在指定为集合的输入的情形下,相应的内部表示可将反应器类用作集合的条目类型,包括集合实现所需的“next(下一)”指针和key字段。即,使用反应器类来代替用来实现非入侵集合数据结构(例如散列表、树和链表)的“条目”结构,从而相比使用单独的条目对象节省了空间和额外代码。
在一个实施例中,内部表示可包括用于约束集的构造函数过程,该过程用所要求的反应器实例来初始化约束集的状态。具体地,在例7中,该构造函数过程将InventoryReactor实例化以供目录输入并设置InventoryReactor数据成员为指向该反应器实例。
回顾前面的实现,当inventory中的指定part条目改变时,例1中指定的约束集的第一约束如下地维持。改变调用插入该位置的代码以在被通知者列表上迭代,从而用关键字标识该条目来在列表中的每个对象的上下文中调用“onPart”函数。如果ReportMaintenance(报表维护)约束集是用该inventory对象实例化的,则针对该约束集生成的InventoryReactor类的实例存在于该被通知者列表中。当针对该对象调用“onPart”函数时,如例7实现的那样,该函数的反应器实现被调用,这致使report对象中的“total”数据成员被更新。
例1中的第二约束将因对报告总计的改变而被触发。该约束可用类似结构实现,其具有用于report total数据成员以及记账“avgPrice(均价)”数据成员的反应器。因此,对总计的更新致使对反应器的调用,这会造成report中的“cost”数据成员由“onTotal”函数的实现来重新计算。
作为一种优化,一个实施例可对该约束集实现确定更新report->total也必须更新report->cost,并且report->total不得通过其它手段来更新。因此,实现可省去由对report->total的改变驱动的用于report->cost的单独的反应器,并且简单更新report cost,作为如例8中的“onPart”的扩展版本所示出的那样维持报告总计的函数的一部分。
------------------------------------------------
void onPart(Key key){
Count newVal=inventory->part[key];
Count diff=newVal-oldPart[key];
cs->report->total=cs->report->total+diff;
oldPart[key]=newVal;
cs -> report->cost=cs_->report->total*cs->
accounting->avgPrice;
}
例8“onPart”的优化的C++内部表示
------------------------------------------------
这里,该函数实现的最后一行直接更新report“cost”数据成员,而不是依赖于来自“cost”数据成员本身的回调通知。第二约束的实现仍然需要反应器实例对accounting对象中的“avgPrice”数据成员的改变作出反应。
在一些约束集中,多个约束具有一个或多个共同的输入。在该例中,约束集中具有共同输入数据成员“dm”的每个约束的命令性代码可被组合到针对该输入的反应器中定义的回调函数“onDm”的实现内。该命令性代码可通过以约束出现在约束集中的次序使用该数据成员dm对每个约束插入命令性代码来组合。如此,整个约束集的每个实例需要一个回调和反应器。
在优选实施例中,翻译器使用前述技术和例如共有子表达式消除等其它常见的优化来跨约束集中的全部约束实现多个优化以使开销减至最小。
在一特定实施例中,可在constraintSet的范围内指定局部数据成员,并可定义约束以将这些用作输入和/或输出。翻译器可识别何时约束的输入是局部数据成员并使相关联的命令性代码从当前模块中所述数据成员被修改的位置被直接调用。该优化通过通知机制和反应器类型消除了调用命令性代码序列的开销。
通过单独翻译或编译(其是实践编程的标准要求),一个或多个从属数据成员和访问这些数据成员的代码可在单独翻译的模块中实现。该单独翻译的代码无法由当前翻译进程直接修改。具体地,不能将代码加至这些单独的模块以实现约束。使用通知工具,单独翻译的单元提供了单独模块中的任何约束集确定其所依赖的任何数据成员何时改变的手段,而该单独编译的单元在其被翻译时无需知道在程序执行期间要指定和出现哪些约束(如果有的话)。在没有这些约束的情形下更新数据成员dm的额外成本是检查被通知者回调列表以及可能调用空函数的成本。将该数据成员用作输入的一个或多个约束的情形下的成本是调用约束生成的命令性代码以确保该约束不变式仍然保持,即采取任何必要的动作以使约束为真的成本。该处理成本与已由程序员明确地指定该命令性代码的情形相同。实质上,该方法用该通知机制扩展了传统命令性编程的被动存储或状态以支持约束,并与用于合并约束和依赖于约束编程的低效率约束图方法(以及其运行时约束存储和约束求解器)的命令性编程以将命令性编程纳入其中的传统方法形成鲜明对比。
在一个实施例中,通知工具可用该类型的每一数据成员的Notifiee接口、以及每个数据成员的单独的NotifieeList或具有指示每个对象的感兴趣数据成员的一些手段的共享列表来实现。因此,对每个感兴趣数据成员可以有一个反应器对象。这种替代方案相比每个输入对象的反应器减少了对不那么感兴趣的数据成员的回调,但在多个数据成员用于约束集时增加了空间成本和复杂度。
A.1反应器执行
约束集可具有相关联的线程指定,该线程指定规定了用来执行反应器过程的线程。这一指定可导致“thread(线程)”数据成员由翻译器作为约束集实现的一部分来插入,如例3中发生的那样。在一特定实施例中,如果thread数据成员是非空的,则反应器对象在该线程上排队以供后续执行(即,调度)而不是直接调用其“on”函数。反应器包括记录正通知的数据成员以及在集合情形下该数据成员的关键字的单个条目。
在一个实施例中,反应器可任选地在单独的线程上被调度。翻译器为每个通知数据成员生成唯一标识符。它还为具有数据成员标识符参数的反应器类型生成多路分解过程,该过程的实现基于数据成员标识符来选择并为指定的数据成员调用“on”函数。该过程也识别对应于对象范围的专门的“this_”数据成员标识符。当用该值调用时,该过程调用反应器中的每个“on”过程,不传递任何参数。(即,使用集合数据成员,调用无参数“on”函数)。例9中示出支持线程调度的“onPart”函数的反应器实现中的命令性代码。
------------------------------------------------
void onPart(Key key){
if(cs_->thread&&(currentThread!=cs->thread)){
if(isEnqueued()){
notifyingDataMemberIs(this_);
}
else{
cs_->notifyingKeyIs(key);
cs_->thread->enqueueReactor(this,part_);
}
return;
}
Count newVal=inventory->part[key];
Count diff=newVal-oldPart[key];
cs->report->total=cs->report->total+diff;
oldPart[key]=newVal;
cs->report->cost =
cs->report->total*cs->accounting->avgPrice;
}
例9调度“onPart”实现的C++内部表示
------------------------------------------------
如果thread数据成员是非空的并且不是当前线程,则“onPart”调用被推迟以由之后的线程调度执行来执行。为此,反应器本身如果尚未入队则连同通知数据成员的标识符(在本例中为“part”)及其关键字(如果有的话)一起在指定线程上入队。如果反应器已在指定线程上入队,则通知数据成员指示符改变至“this_”以指示对象级通知。随后当调度指定的线程来执行该反应器类型时,该线程调用多路分解过程以将数据成员标识符映射到相关联的“on”函数并执行它。如果通知数据成员被指定为“this_”,则调用每个“on”函数。由于该线程在执行该“on”函数时则为当前线程,因此当由该线程调用时,反应器“on”函数的命令性实现被立即执行。
使用这种机制,可在运行时配置约束集以执行单独调度的通知处理或立即通知,这是通过将thread数据成员设为非空值或将其清零来选择的。例如,在负载下,约束集可动态地分配线程并设定该thread数据成员以使其执行与其输入中的处理并行地发生,这增加了应用程序的并行性和响应时间。另外,应用程序可在足够并行线程可用时使用单独调度的约束执行来基于其执行可用的并行线程的数目在运行时配置。
一般过程触发机制的关键问题源自触发器调用的过程的处理要求。如果触发的过程在与调用该触发器的动作相同的控制线程中执行,则因该处理使动作完成延迟,结果正在执行的整个应用程序任务被延迟,这降低了应用程序性能。在某些情形下,其结果是应用程序无法满足响应要求。替换方案是将触发事件排队以便稍后由单独的控制线程来处理。然而,在负载下,触发器生成速率可能超过处理这些触发事件的速率。在这种情形下,要么队列无限制地增长直到系统存储器溢出,要么队列达到极限并阻塞触发动作或触发事件被丢弃。通常,这些选择方案中没有一个方案是可接受的。第一个方案明显导致系统故障。第二个方案可能造成应用程序阻塞。另外,常见的是许多排队的触发器是冗余的。例如,在网络系统中,链路可快速地向上和向下“抖动”,这造成对应于链路状态改变的触发事件序列。然而,处理经常仅涉及链路的当前状态,而不是整个事件序列。触发机制可包括指示何时如此的选项、合并重复事件和互补事件的选项,但这显著增加了执行成本并且不解决命中队列极限的一般问题。丢弃触发事件的最后一个选项意味着被触发的过程在程序员规定其要被调用的某些情形下不被调用。这种替代方案也导致一般情形下的不正确应用程序行为。缺乏合理语义可能是不在任何通用实践性编程语言中提供触发机制的原因,即使该理念已到处皆是并用于各种专门的语言。例如,JavaFX是针对性能通常不是关键因素的图形用户界面来设计的。
如上所述的基于通知的处理可通过优选实施例的若干关键技术特征来避免一般过程触发机制的这些问题。首先,每一通知的处理动作受约束语义的限制以“确保”约束关系保持,而不执行任意动作。因此,每个“on”函数是幂等的,从而“on”函数的额外调用不造成不正确的行为。其次,当在处理当前一个通知前接收到对反应器对象的第二个通知时,该通知被实质上被折叠成对象通知,这意味着通过将notifyingDataMember(通知数据成员)指示改变为“this_”来改变通知对象的一个或多个数据成员。第三,当分派一线程来执行具有“this_”指示的经调度的通知处理时,该线程调用该反应器中的每一个零参数“on”函数,这确保以该通知对象作为输入的全部约束被维持。第四,如有需要,通知处理从通知对象本身接收通知数据成员的当前值,而不是依赖于排队的值,由此确保当前值的使用。最后,由于通知的谨慎实现,实际上不改变目标数据成员的作为该通知处理的一部分执行的任何更新动作不造成通知。结果,由于当线程被调度时即使实际特定触发事件可能被忘记也执行要求的通知处理的父集,甚至在过载状况下也能(最终)维持约束。此外,由于动作的幂等性,任何额外处理不导致不正确的行为,包括不生成无关系的通知。这种方法具有附加的功效,即响应于改变的多个通知在负载下折叠成单个通知,这相比顺序地处理这些通知的队列允许较少的处理开销。这些技术的组合允许使用通知机制而不引发通用过程触发机制的问题。
在一个实施例中,代表集合的数据成员被认为具有与集合中不存在的关键字对应的每个条目的默认值。因此,添加一条目实质上是将其设定为非默认值,而将其移除是将其重设为默认值。例如,在对象指针的集合中,默认值是空指针。此外,反应器提供指向输入对象的指针,并且集合中改变的条目的关键字被传递给反应器。结果,反应器可确定新的值并且无需将额外信息存储作为通知的一部分,例如是否添加或是删除了条目。一实施例可扩展至以额外空间和代码复杂度为代价在反应器中使用用于通知数据成员和关键字的多个条目,仅当排队数量达到所允许的最大条目数时采用前述折叠的对象通知方法。
一实施例可通过使用立即通知(无线程分派)和简单地将该通知在constraintSet状态下提供的队列中排队来支持应用专用基础下的单独的通知排队。然后可分派单独的线程以处理排队的通知记录,该通知记录应当包括数据成员的标识符和关键字。
遵循前述方法,具有带单个输入的约束的约束集可由以与C++规范相比拟的形式生成该约束集的内部表示的翻译器来实现。翻译器随后可使用公知的技术将该内部表示翻译成可由目标执行环境执行的高效的命令性表示。
A.2处理多输入约束
以最简单形式,约束具有一个输入数据成员。即,存在其改变可能使某一动作变得必须的单个数据成员。例如,a=b的单向约束仅因b改变而被触发。在单输入约束的情形下,存在维持这种约束所需的单个命令性代码序列,即通过b改变的通知而被调用(不包括来自b的初始化)。
然而,在更一般的情形下,约束具有多个输入。例如,例1和例2中的约束集的第二个约束具有两个输入,即report::total和accounting::avgPrice。
在一特定实施例中,翻译器具有其数据成员自变量之一被规定为触发器的约束的内部表示。在处理要翻译的语言并遇到约束集中的多输入约束时,翻译器用多个单触发器约束表示来替换该约束,其中对原始约束集的每一个输入有一个这样的单触发器约束表示。(它能保持原始约束指定以供初始化)然后,后续的翻译处理基于相关联的代码模板和对于单触发器约束的特定数据成员自变量将每个单触发器约束翻译成相关联的代码序列。每个单触发器约束具有指定响应该触发器要调用的命令性代码序列的命令性代码模板。使用术语“代码模板”是因为实际可执行代码可能基于约束数据成员的类型、基数和其它属性而有不同。
注意,所谓的多向约束,即对约束关系改变的左手侧数据成员和右手侧数据成员两者作出响应的约束,作为将左手侧数据成员识别为是输入的多输入约束的另一种情形来处理。即,将其变换为若干单触发器约束。单触发器约束是单向约束的特例。
如之前描述的那样,翻译器可将优化施加于约束集,这可能消除一些单触发器约束,如针对例1中的report::cost约束所描述的那样。
在一些情形下,关联于一个单触发器约束的命令性代码与由同一原始约束生成的其它命令性代码不同。使用一个简单示例,如果约束“total=part1+part2+part3”约束是多向的,则“total”是输入。在“total”改变的情形下,翻译器可能产生例10中的命令性代码的等效物。
------------------------------------------------
part1=total-(part2+part3);
例10由titak更新触发的命令性代码
------------------------------------------------
在一个实施例中,翻译器可用识别并能为多向约束的要求情形产生表达式的知识来编程,从而当指定了无法处理的多向约束时生成输入处理上的错误。程序员然后需要使用更基本的约束和/或命令性编程的组合来实现约束(如果合用的话)。由于翻译器能被编程为识别它所能处理的内容(并因此也识别它无法处理的内容),翻译器不产生作为所指定的约束的不正确实现的执行。此外,由于本文中的主要目的是通过添加约束而非消除除约束外的全部表达手段来提高命令性编程的简洁性,因此本发明的各实施例的优势能由处理多向约束的共同情形的翻译器来实现,这在许多应用中是相对简单的。最后,可指定无法被简化为由其输入触发的一组高效额命令性编程序列的约束集。因此,优选的翻译器实现在这种情形下会产生错误消息,而不是默默地提供对输入和输出空间的耗时的穷尽性搜索。在过度复杂的约束的情形下抛出异常是与本发明的实施例的目的相一致的。
A.3抽象句法树(AST)表示
在一个实施例中,翻译器在其解析其输入时记录被指定为抽象句法树中的节点的每个约束,这类似于传统编译器或解释器中的初值化语句节点,但以指定“触发器”数据成员的能力来扩展。如果约束是如前所述的多输入约束,则后续处理在AST中可修改dm的点处为原始约束的每个触发数据成员dm将单触发器约束节点插入到AST中。例如,在例1的约束集中,将在AST中创建第二约束的初始约束节点以应用于该约束集的初始化中(即构造函数过程),但也可在反应器的“onTotal”和“onAvgPrice”过程的实现中各自复制至report和accounting输入对象中。
翻译器随后遍历AST以完成翻译,这只需要考虑每个过程表示中的单触发器约束指定,从而简化了输出处理。
A.4局部约束实现
在一特例中,约束可按照在与输入相同的上下文中定义的一个或多个输入来表达。在这种情形下,可通过将相关联的命令性代码直接插入到输入修改所在的位置而对这些输入实现约束。在一个实施例中,翻译器标识约束集中具有该相同上下文属性的约束并如所述那样实现、优化。替代地,编程语言可提供与数据成员相关联的声明性上下文以指定这些约束。在例11中,数据成员“total”的声明用声明性约束上下文来扩展。
------------------------------------------------
int total {
=part1+part2+part3;
}
例11局部约束上下文
------------------------------------------------
其中该声明性约束上下文包含指示该total等于数据成员part1、part2和part3的总和的语句(这里,与被称为“total”的数据成员相等基于该上下文被声明为“total”的声明的扩展而是隐式的)。采用这种声明,软件能高效地访问这些part数据成员之和,从而依赖于该约束来确保“total”数据成员在任何时候包含这些part数据成员的最新总和。
对于例11中的约束,针对该编程语言的翻译器插入命令性指令以当实例化时将该数据成员初始化至该总和,并在程序中“part1”、“part2”或“part
3”中的任何一个被修改的每个位置处更新“total”的值。例如,如果“part2”在源代码的第34行被置新值,则翻译器在34行后面插入以下C++类行的等效物。
------------------------------------------------
total=part1+part2+part3;
例12对“total”插入的命令性更新代码
------------------------------------------------
注意,该代码指定命令性语句将“total(总计)”赋值为“part1”、“part2”和“part3”之和。因此,在翻译器是编译器的情形下,该代码是直接可编译的并在约束的静态类型上下文中被优化为机器语言实现。因此,这种实现与提供相同功能的手动指定的命令性指定一样高效。
一个或多个数据成员可使用用于数据成员声明的标准句法,即类型后面跟名称以及没有input、output或inputOutput限定词的其它指定,而被定义为对约束集是局部的。集合中的约束可使用这些局部数据成员中的一个或多个作为输入或输出。在输入的情形下,应用如前所述的局部优化,即直接调用约束命令性处理而不是使用通知机制。
A.5集合数据成员的约束
在一优选实施例中,编程语言允许声明例如“集合”的复杂数据成员,即存储或引用变化数目的其它数据成员的数据成员。例如,存储对由Name(名称)值类型索引的类型Child(子)的对象的引用或指针的被称为“child”的集合数据成员可被声明为:
------------------------------------------------
Child::Ptr child[Name];
例13集合数据成员声明
------------------------------------------------
该声明跟随在用于声明后跟有名称和其它限定词的类型的传统句法之后。该集合方面由指示该集合数据成员由类型“Name”的值来索引的“[Name]”指定的存在来指示。
为了保持底层集合状态的完整性,语言翻译器可生成用于修改集合的一个或多个过程并要求修改该集合的全部软件调用这些过程中的一个而不是直接访问用来实现该集合的数据成员。这些各自被称作“增变器”的修改过程可包括将给定关键字的值插入到集合中的过程、删除指定成员的程序、以及可能递增给定成员的值(在集合成员类型支持递增的情形下)的过程。在该实施例中,翻译器可在这些增变器过程的每一个中插入调用前述通知回调机制的命令性代码,从而避免在应用程序中否则将修改集合的每个点处插入通知代码的需要。同样,翻译器可将与该数据成员相同的范围中指定的约束所要求的命令性代码直接插入到这些增变器的每一个中。如此,这些增变器过程的生成减小了实施例中所需的代码空间,因为其避免了集合增变和约束实现代码的重复。
一支持集合数据成员的实施例可基于集合语义支持具有更复杂语义的约束。例如,前述“child”集合可支持child字段上的约束,即其要求该字段被设定为指向父对象的“parent(父)”字段,如下文指定的。
------------------------------------------------
Child::Ptr child[Name]{
child::parent=this;
}
例14指定为约束的集合反向指针
------------------------------------------------
“this”值表示如C++中的封入的范围对象。该约束指定当child被实例化时将Child的“parent”字段设为实例化父对象,并且当将child对象从该集合中删除时清空该字段。该约束可完全在用于该集合实现的增变器中实现,如果这些过程如前所述是更新该集合的唯一手段的话。
该例示出直接支持例如集合的复杂数据成员的语言如何允许约束以比简单的单元素数据成员具有更复杂的语义。在优选的支持集合的实施例中,语言能支持集合之间的约束。例如,将ChildMonitor视为对来自从如例14中的child类型的对象的改变的回调作出反应的类型。则,ChildMonitor的集合可被声明为与例15中所示的张火丁父对象“parent1”中的Child集合对应。
------------------------------------------------
ChildMonitor childMonitor[Name]{
=parent1::child;
childMonitor::parentMonitor=this;
}
例15指定集合相等性
------------------------------------------------
第一个约束声明的解释是对于作为parent1的“child”集合的成员的每个child对象存在一个“childMonitor”的成员。(在优选实施例中,单独的对“ChildMonitor”的指定而不是将“ChildMonitor::Ptr”指定为该数据成员的类型意味着ChildMonitor实例将被实例化)。
该例还示出可在一个上下文中指定多个约束。在例15中,关联于childMonitor的“parentMonitor”字段被约束为指向childMonitor的范围,这匹配于用于“child”集合的结构。
在指定“child”数据成员是单独翻译的模块的一部分的情形下,翻译器通过生成当修改“child”集合时拟由通知回调机制调用的过程来实现该约束,并且该过程在这种情形下取决于child集合在该次修改中添加了还是删除了条目而添加或删除条目。这种相同实现可在该约束在与“child”相同的编译单元中指定的情形下使用,如果child的范围不包含对“parent1”的直接引用的话。
对集合成员的约束的示例在局部约束上下文中张火丁,而不是为简化起见作为约束集的一部分来指定。然而,这些类型的约束也可在约束集中指定。
A.6扩展的约束集约束实现
在例如例2所示的扩展约束集中,可指定需要覆盖或扩展在原始约束集的实现中采取的动作的一个或多个约束。在该例中,重定义对report::cost的约束,因此响应于report::total和accounting::avgPrice采取的动作必须改变。在这种情形下,翻译器可为其动作需要改变的每个输入生成一反应器类型,该反应器类型是原始constraintSet中的反应器类型的派生类型,它用修改或扩展的实现覆盖了要求改变的函数。例如,对于accounting输入对象的派生反应器类型的内部表示可如例16那样使用C++来指定:
------------------------------------------------
class ExtendedReportMaintenance:public ReportMaintenance{
…
class AccountingReactor : public
ReportMaintenance::AccountingReactor {
void onAvgPrice(){
…
}
void onOverhead(){
…
}
};
};
例16扩展约束集输入实现
------------------------------------------------
此外,用于扩展约束集的构造函数过程实例化这些扩展输入的派生反应器类型。在前面的例子中,accounting输入是使用由ExtendedReportMaintenance::AccountingReactor表示的派生类型来代替在基本约束集中使用的ReportMaintenance::AccountingReactor来实现的。这些过程的每一个的实现中的…由用于为每个相应数据成员通知执行的扩展动作来替换。
扩展约束集可指定具有附加数据成员和附加约束的扩展输入对象,该扩展输入对象将这些附加数据成员用作输入。在这种情形下,C++中的内部表示可以是从基本反应器类和作为输入对象的派生类的notifiee类多重继承的反应器类。派生反应器类因而包含附加“on”函数的实现以及覆盖基本反应器类中的那些函数的实现。在被覆盖的函数的动作是基础反应器中的那些动作的超集的情形下,反应器中的被覆盖的函数可调用基本反应器中的相应函数,这使派生反应器中的动作的重新实现减至最小。
对输入反应器实现和约束集实现两者使用该形式的面向对象的继承,向扩展约束集提供了超过基本约束集的最少机制重复。
B.使用约束的统一代码生成
翻译器应当“理解”它在其中插入实现约束集中的约束的命令性代码段的基本命令性代码的结构。具体地,应当确定每种实现中要添加通知所需的附加处理的正确点。例如,用于集合的插入过程可测试对象何时具有冲突的关键字并返回错误而不是插入对象。应当实现对约束采取动作的指令以在对象实际上未被成功添加至集合或集合中的指定条目已包含该值的情形下使这些指令不被执行(避免关于不作出状态改变的更新动作的通知所需要的)。此外,添加的指令应当在考虑命令性代码所提供的上下文的情况下生成。例如,一定不能引入与那些已由该过程定义的变量冲突的局部变量,但仍然能根据高效约束实现的需要来引入局部变量。出于效率考虑,也应当使用已有的参数和局部变量来访问状态,从而避免重做状态访问、计算和检查基本命令性代码已被执行,例如检查参数为非空的。
在一优选实施例中,每个集合增变器的实现是按照一个或多个约束来指定的。例如,曾变器的动作可被指定为将数据成员约束为该过程的值参数的值。因此,AST中存在与数据成员对应的节点以及与增变器过程对应的节点。约束表达了从增变器节点至数据成员节点的单触发器等同关系。此外,支持前述类属通知回调机制的命令性代码可作为该实现的一部分通过专用约束来生成。因此,增变器的实现是通过生成由增变器节点触发的命令性代码来生成的。注意,该约束一直是由与增变器对应的伪数据成员触发的单触发器约束。
使用这种方法,翻译器因而具有统一代码生成模块,该模块使用允许其遵循前述正确性和效率因素来进行合成的惯例基于约束节点来输出用于增变器的命令性代码段,而不论约束节点是生成增变器的主体还是实现依赖于该集合数据成员的单独的约束。具体地,在约束集中定义的局部数据成员以及访问其值并更新其值的相关联的手段可通过指定为AST内部表示的一部分的单触发器约束来生成。
C.别名数据成员
在一优选实施例中,可使用例17所示的局部约束将一个数据成员定义为另一数据成员的别名。
------------------------------------------------
ChildMonitor::Ptr monitor=childMonitor;
例17使用约束指定别名
------------------------------------------------
翻译器将“monitor”解释为“childMonitor”的别名,其意思是访问“monitor”等效于访问“childMonitor”且“monitor”的状态完全依赖于“childMonitor”。这在“monitor”约束于“childMonitor”的实现的意义上是一种约束。具体地,如果childMonitor数据成员改变,则这种改变反映在monitor数据成员的值中。
在一优选实施例中,访问集合数据成员的被称为访问器的集合过程可通过与前述别名机制相似的约束节点来生成其实现,这进一步提供统一的基于约束的代码生成器模块。别名也可按照例18中所示的表达式来定义。
------------------------------------------------
bool isNullPtr=!ptr;
例18使用约束指定表达式别名
------------------------------------------------
作为(伪)数据成员定义,可使用表达式别名来定义当条件改变时要采取的动作,这与将普通数据成员用作约束输入相同。
在一优选实施例中,事件的复杂组合可使用约束集和表达式别名来指定。这示出于例19中。
------------------------------------------------
constraintSet PortfolioMaintenance{
input MarketTicker tkr;
inputOutput Portfolio pf;
output OrderBook orderBook;
bool overTarget[Symbol]=tkr->price>pf->targetPrice;
bool underLimit[Symbol]=(tkr->price<pf->limitPrice)
&&(currentTime-pf->purchaseTime>minHoldTime);
orderBook->sale=(overTarget||underLimit)?pf->holding:
0;
}
例19将复杂事件处理指定为约束集。
------------------------------------------------
input MarketTicker在证券价格改变时提供通知。Portfolio对象指示当前财产和目标价格以及限价。对overTarget(超出对象)和underLimit(下限)的局部表达式别名的定义是对关于这种具体证券的定货单中的销售条目的约束的输入。在该约束指定中,用于作为集合的输入数据成员的关键字或索引值是隐式的,并且需要跨约束的各输入和输出进行匹配。在例19中,证券的符号用来对portfolio和tkr集合作出索引。使用这种工具,可在命令性语言中将复杂事件处理序列指定为对约束的输入。
D.基于通知的过程触发器
在一优选实施例中,还可提供指定响应于通知来触发的过程的能力,如例20所示。
------------------------------------------------
File::Ptr fileDir[name]{
: handleFile(name);
}
例20指定触发调用应用程序处理
------------------------------------------------
这里,特殊的“:”符号表示当集合“fileDir”改变时要执行下面的语句。这种机制允许应用程序指定要响应于数据成员的改变执行的命令性处理,从而处理了超出语言中可表达为声明性语句的关系的需求。更一般地说,它允许如例21所示在声明性上下文中指定命令性上下文。
------------------------------------------------
File::Ptr fileDir[name]{
:{
//响应于fileDir改变执行命令性处理
…
}
例21在声明性上下文内指定命令性处理
------------------------------------------------
在该例中,由“…”表示的任意命令性代码被指定为响应于“fileDir”数据成员改变而被调用。为了适应通知工具的受限语义,该过程应当被写成幂等的(即,对于约束来说,在同一输入执行该过程多次完全等效于对该过程的一次执行)而不是采取完全任意的动作。
过程触发器可在表达式别名中指定,以使其仅当表达式为真或非零时被调用。语言翻译器插入在作为表达式的一部分的数据成员改变时调用的命令性代码,并当表达式求值为真或非零时调用该过程。
该机制展示出过程触发机制也被支持作为用来指定和实现约束集的语言和机制的扩展,虽然受到通知工具的面向约束的语义所限制。
E.使用约束的检验
在一优选实施例中,检验约束可通过生成命令性代码来提供,该命令性代码在数据成员的修改发生前检验针对该修改所指定的关系,并且如果修改可能造成违背指定关系则抛出异常。该异常确保修改不发生,假设诸如C++、Java和C#等其中错误是通过抛出异常来处理的现代编程语言。因此,维持这种关系的命令性代码抛出异常。检验约束的指定可如例22那样完成,在这种情形下将speed(速度)数据成员局限为在0和100之间的范围内。
------------------------------------------------
MilesPerHour speed{
check speed>=0&&speed<=100;
}
例22指定使用约束的检验
------------------------------------------------
在一优选实施例中,检验形式的约束的实现利用统一的基于约束的生成,从而方便了如检验约束语义所要求的那样在修改发生前插入检验约束代码。即,统一的基于约束的生成可确定命令性代码中与增变器相关联的点以插入执行检验的附加命令性代码。
F.使用约束的初始化
在一优选实施例中,将初始化作为约束的特定情形来处理,从而生成仅在初始化数据成员时将数据成员设定为指定值的代码。这在例23中示出,其中将“speed(速度)”数据成员初始化为“initialSpeed(初始速度)”。
------------------------------------------------
MilesPerHour speed{
`default=initialSpeed;
}
例23指定使用约束的初始化
------------------------------------------------
前缀“`”用来表示数据成员的属性。“default(默认)”属性对应于数据成员的初始值。
G.使用约束来指定数据成员属性
在一优选实施例中,数据成员可具有包括前面指定的初始值或默认值的众多属性。例如,集合数据成员可具有“ordering(排序)”属性,该属性可具有值“unordered(无序)”、“by insertion(按插入)”或“by key(按关键字)”。类似于前面提供的初始化的指定,与数据成员相关联的局部约束声明性上下文可用来指定这些属性,如例24所示。
------------------------------------------------
File::Ptr fileDir[name]{
`ordering=fileDirOrdering;
}
例24通过约束指定属性
------------------------------------------------
在这种情形下,如果fileDirOrdering(文件目录排序)是数据成员,则翻译器插入基于fileDirOrdering数据成员的改变根据需要改变“fileDir(文件目录)”的实现的命令性代码。在这些示例中,属性名之前放置“`”以表示这是声明性范围的数据成员的属性,而不是对另一数据成员的引用。
在一优选实施例中,数据成员的属性默认地被设为最常见的适用值以使显式指定属性值的需要减至最小。在一优选实施例中,翻译器允许在单个局部约束上下文中指定多个约束,包括不同数据成员属性,同时如果这些指定的约束具有一个或多个冲突则检测这些约束间的逻辑冲突。
H.使用约束的解析器生成器
在一优选实施例中,约束集数据成员可使用一个或多个约束定义为其它数据成员的与或树的别名。其它数据成员可以是相似的别名。这种形式的复杂别名可视为语法中的非终止符号。这种性质的复杂别名的指定通过例25所示的约束示出。
------------------------------------------------
bool typeDecl=″type″name’{’bodyNode’}’|″type″name’;’
{
:handleType();
}
例25将语言语法规则指定为约束
------------------------------------------------
这里,由空格分开的数据成员名称或文字被视为串联或联接,而特殊符号“|”表示“或”连接或分离。在例25中,数据别名“typeDecl(类型声明)”被定义为串“type(类型)”后跟名称数据别名,然后是文字字符“{”,然后是bodyNode(主体节点)数据别名,之后是文字字符“}”或串“type(类型)”,然后是名称数据别名,最后是文字字符“;”。
这种约束指定使语言翻译器插入处理响应于第一条件和第二条件的回调的代码,这进而被结构化为检测对应于每个数据别名的数据成员序列的状态和处理。然后当该“typeDecl”别名数据成员被识别为真时调用“handleType(处理类型)”过程。
语法中的终止符号被指定为按照常量或文字定义的别名,如例26所示。
------------------------------------------------
bool newToken=inputStream->token==″new″;
例26指定语法中的终止符号
------------------------------------------------
这里,当输入令牌被设定为串“new(新)”时“newToken(新令牌)”为真。
用于解析器的constraintSet具有一个输入,即例26中使用的“inputStream(输入流)”对象。其它约束通常按照约束集中定义的表达式别名来定义。
使用这种机制,应用程序可指定形成描述语言句法的“语法”的约束集。具体地说,每个“令牌”事件或基本事件对应于一个表达式别名,该表达式别名对应于变得与文字值相等的数据成员。每个“非终止符”对应于其它表达式别名。可通过附加约束或使用过程触发器来将进一步的处理附加于这些非终止符。使用这种工具,翻译器可在命令性编程语言中提供解析器生成器的能力。即,该翻译器可将约束集翻译成内部语言语法表示并随后使用业内公知的技术以供解析器生成器生成用于实现高效解析器的命令性代码。这种方法允许在一种编程语言中指定语言翻译器以易于指定和维护,同时仍然提供语法的声明性指定和所需解析器代码的自动生成的优势。即,在通常使用单独的解析器生成器来完成这个任务的编译器和解释器的上下文中,约束集机制允许编程语言在命令性编程语言中(即在单个编程环境中)包含解析器生成器的能力。
H.约束异常通知
在一具体实施例中,当还原约束关系的动作失败时,翻译器可生成通知。例如,例27中对于非否定“difference(差异)”数据成员的约束在count1小于count2时不能得到维持。
------------------------------------------------
NonNegative difference{
=obja->count1-objb->count2;
}
例27
------------------------------------------------
因此,翻译器生成在这种情形下调用通知机制的命令性代码。应用程序可使用与count1小于count2对应的表达式别名来指定命令性处理在这种情形下执行,这调用普通的约束过程或依赖于该表达式别名的或过程触发器。因此,它可使拟调用的动作对故障作出反应以维持原始约束,这有可能撤销对引发故障的状态的改变。
I.应用程序定义的约束运算器
在一特定实施例中,应用程序定义的约束运算器可用名称和参数输入和输出的列表来定义。当翻译器遇到应用程序定义的约束运算器时,如其名称指定的那样,它生成将约束运算器实例化为对象的指令,并将自变量输入连接到参数输入且将自变量输出连接到参数输出。应用程序定义的约束可对应于具有输入接口和输出接口以及两者间的专门的应用专用处理的对象,这可能由耦合于命令性编程的过程触发机制来提供。使用这种机制,可使用简洁的约束指定来调用任意专门算法,而翻译器和编程语言不需要包含所有可能的应用专用算法。
在一个实施例中,约束运算器实现可以按类型参数化的形式来指定,即C++术语中的模板。这被称为约束运算器模板。在这种情形下,输入和输出被映射到自变量输入和输出的特定类型。结果,同一约束运算器可用于不同类型,只要它们包括所需的数据成员。
在一个实施例中,可使用与由应用程序定义的约束模板使用的相同的基本机制来定义与传统约束编程对应的专门的运行时约束集。具体地,当翻译中遇到被指定为运行时约束集的约束集时,插入代码以实例化与该约束集对应的约束存储对象以及类似于用于应用程序定义的约束的特定约束对象,但其指定关系作为输入自变量。在运行时,当该对象被实例化时,它将与该约束相关联的关系表达式记录在相关联的运行时约束存储中。它进一步向通知工具注册其从属数据成员。然后当添加或移除约束或当存储中的一个或多个约束的从属数据成员被修改时在该约束存储上调用约束求解器。因此,该工具提供传统的通用约束求解器方法,但局限于以这种形式指定的约束子集,而且是由通知机制调用而不需要将每个赋值或增变器动作实现为约束的附加。
这些工具允许应用程序超出翻译器直接支持的“内置”约束以利用专门的应用专用算法,该算法对通用约束求解器具有优越的性能并且在例如各种组合数学和优化问题等没有更好的算法已知的情形下仍然使用通用约束求解器。相反地,人们可将该通知机制视为允许使用通用约束求解器而无需改变命令性存储模型使其超出提供通知工具,并进一步允许在优选命令性解法已知的情形下的优化,如应用专用约束运算器和(语言)内置约束运算器所指定的那样。
由约束指定的可能关系可根据其触发属性、状态量和时间分量来分类。多触发器约束的处理之前已描述过。状态关系可用约束集本地的所声明的数据成员来处理。时间属性可使用前面描述的线程机制或类似的处理控制工具通过对通知和来自该通知的命令性动作的结果执行之间的这些对象中的一个引入调度延时来实现。这些能力与对所有基本运算器和这些运算器的合成的支持一起提供全面的约束能力。
J.表示专用约束
在许多应用中,需要在状态的普通存储器内表示和例如符串表示、未类型化表示和网络表示等其它表示之间实现一组约束。例如,需要适配器以在实际编程语言的未类型化编程环境(例如脚本语言、命令行接口或图形用户接口)与常见的强类型化环境之间接口。具体地,命令行解释器或图形接口提供依照串或指向例如用户接口框架对象等不是与内部应用程序对象一致地类型化的对象的指针的输入指定。该适配器需要采用数据成员、关键字和值的串指定,并使实际的强类型化的应用程序对象与这些值一致或抛出异常。(由于对每个应用程序对象存在一个适配器对象,所以应用对象隐含在适配器对象中。)
在一优选实施例中,翻译器允许指定表示作为指定约束的一部分。表示的一个示例是输入或输出的特定网络协议表示。该表示可由关于输入或输出或关于特定约束的限定词来指定。默认表示是普通的存储器内表示。
在一优选实施例中,翻译器还支持将每个表示的扩展模块添加至翻译器,该模块处理与该特定表示相关联的约束的翻译。当翻译器遇到具有非默认表示的约束时,它调用相关联的表示模块来翻译该约束。
在分布式操作的情形下,为网络表示提供表示模块,该模块处理每种类型的约束集,该约束集将数据成员约束到在指定为该约束集的一部分的网络输入输出连接中的表示。所得的命令性代码维持该类型的数据成员与网络表示一致,这通过经由网络连接将一类型的实例连接到另一实例确保了这两个实例保持一致。具体地,对于需要通过网络访问的每种类型T,翻译器生成一种适配器类型,该适配器类型通过经由网络连接传送对类型T的对象的更新来对该更新作出反应,并同样能接收这一更新并将其变换成对同一类型的对象的调用,从而根据该更新来设定该对象的状态。此外,使用对象范围通知来使得整个对象状态通过网络来传送,以在网络故障或设置初始化时处理连接的重新同步。
在其中真实对象在一端而同一类型的“代理”对象在另一端的网络连接的每一侧上使用该机制,代理对象被约束以维持与真实对象相同的状态值。此外,其行为可与真实对象完全相同,包括在远程节点生成通知以调用约束,从而允许如章节K中描述的分布式约束的实现。
在一个实施例中,另一种表示对应于未类型化表示。约束集因而可使用通过该表示标识指定的约束来指定普通的类型化表示和该未类型化表示之间的关系。具体地,在未类型化表示中指定的数据成员可通过约束在修改时调用命令性处理以将未类型化值转换成适当的类型化值(带有适当的检验和错误通知),并随后对相应的类型化数据成员执行更新。
在一优选实施例中,翻译器在给定表示的指示的情况下为应用程序定义的类型自动生成约束集。具体地,对于应用程序定义的类型的每个数据成员,表示模块将等同约束添加至其输入为该数据成员且其输出为目标表示对象(例如网络表示情况下的网络流)的约束集。
K.分布式约束集
在分布式应用中,约束集可指定在系统的不同节点上实现的输入和输出。在一个实施例中,对要被指定为约束集的输入或输出的每个远程对象创建一代理。该约束集然后用指向这些(代理)对象的每一个的指针来实例化。如之前所述地,代理对象是使用基于表示的约束实现的。结果,当远程对象被更新时,该更新被传播至每个代理对象,这使导致通知的生成,与局部对象相同。该通知如同对于局部对象一样调用约束处理。如果约束处理修改这些代理对象中的一个,则更新被传回真实对象并生成对代理对象的本地客户机的通知。
使用该实施例,约束集可在分布式应用程序中相对于其输入和输出两者都是远程的节点上实例化和执行,而在命令性处理中没有变化并对该约束处理具有高效执行。
前面的描述是示例性的而非限定性的。本领域内工作人员也很清楚如何在各类似情形中实现本发明各实施例的原理。具体地,提供用于如前所述地从输入源程序中的约束指定自动生成中间通知和反应器表示的代码可通过编程语言变换领域公知的方法来实现,并且因此在本文中不予说明。
Claims (18)
1.一种将包含约束的输入代码自动翻译成计算机可执行命令性输出程序表示的方法,所述方法包括:
提供输入源程序,其中所述输入源程序以另外提供对约束的声明性指定的编程语言来表达,并且所述输入源程序包括根据所述编程语言指定的一个或多个约束;
其中所述一个或多个约束中的每一个指定约束数据成员的关系;
提供所述约束数据成员中的哪一些是约束输入的标识;
为所述约束自动提供约束表示;
其中每个所述约束表示包括在实例化时注册输入改变通知的一个或多个相应的约束反应器对象,所述约束反应器对象具有用于强制实施所述约束的命令性过程,并且所述相应的约束反应器对象在所述相应的约束表示的范围内是可访问的;
对所述输入源程序的一些或全部程序数据成员的每一个,自动地提供相应的通知代码,以提供改变通知并调整约束表示对输入改变通知的注册,并且其中所述相应的通知代码在所述相应程序数据成员的范围内是可访问的;
在所述命令性输出程序表示中实例化所述约束表示,籍此对约束输入的改变自动导致命令性约束驱动的更新;以及
将所述命令性输出程序表示作为输出来提供。
2.如权利要求1所述的方法,其特征在于:
所述输入源代码程序中的所述约束被组织成约束集,每个约束集包括一个或多个约束;
其中每个所述约束集还包括对所包含的约束中的哪些约束数据成员是约束输入的显式和/或隐式标识;以及
其中所述相应的约束表示包括与每个所述约束集对应的约束集对象表示。
3.如权利要求1所述的方法,其特征在于,所述提供相应的通知代码以提供改变通知包括对每个所述程序数据成员自动定义虚更新过程,其中所述虚更新过程在相应的程序数据成员改变的情形下被调用。
4.如权利要求3所述的方法,其特征在于,所述提供相应的约束表示包括对每个所述约束的输入的改变自动定义真实更新过程。
5.如权利要求4所述的方法,其特征在于,所述自动实例化所述通知代码和所述约束表示包括通过类型继承将所述虚更新过程的调用映射至所述真实更新过程的相应调用。
6.如权利要求1所述的方法,其特征在于,所述自动实例化所述通知代码和所述约束表示包括:
对同样作为一个或多个约束表示实例的输入的每个程序数据成员,构造所述一个或多个约束表示实例的约束反应器对象实例的被通知者列表,其中所述每个被通知者列表在与所述每个程序数据成员相同的范围内是可访问的。
7.如权利要求1所述的方法,其特征在于,所述约束中的至少一个是具有两个或更多个输入约束数据成员的多输入约束,并所述方法进一步包括将所述多输入约束表达为一组单输入约束,每个单输入约束具有正好一个输入约束数据成员。
8.如权利要求1所述的方法,其特征在于,对于所述程序数据成员中的一个或多个,所述自动提供相应的通知代码包括为所述相应的程序数据成员提供两个或更多个改变通知过程,并提供取决于对所述相应的程序数据成员的改变的性质和/或环境对要调用所述两个或更多个改变通知过程中的哪一个的选择。
9.如权利要求1所述的方法,其特征在于,所述约束中的一个或多个在与一个或多个其相应的输入相同的范围内指定,并所述方法进一步包括将范围内命令性代码插入到所述命令性输出程序表示中以强制实施所述一个或多个所述约束。
10.如权利要求1所述的方法,其特征在于,所述约束表示中的至少一个提供对用于执行其每一个相应的约束反应器对象的程序控制线程的选择。
11.如权利要求1所述的方法,其特征在于,所述自动提供相应的通知代码包括将所述程序数据成员的修改代码自动封装在包含通知代码的相应的增变器过程中。
12.如权利要求1所述的方法,其特征在于,所述约束中的至少一个是与具有不同表示的约束数据成员有关的表示专用约束。
13.如权利要求1所述的方法,其特征在于,所述约束中的一个或多个与复杂事件处理有关。
14.如权利要求1所述的方法,其特征在于,还包括提供运行时约束引擎以处理在翻译期间中未被求解的约束集。
15.如权利要求1所述的方法,其特征在于,所述约束以声明性术语指定目标编程语言的语法。
16.如权利要求1所述的方法,其特征在于,所述约束中的至少一个位于第一程序单元中,而其对应的约束输入中的至少一个能在第二程序单元中改变,并且所述第一和第二程序单元是单独翻译的。
17.如权利要求16所述的方法,其特征在于,所述第二程序单元可被单独翻译而无需知道其程序数据成员中的哪一些是约束输入。
18.如权利要求1所述的方法,其特征在于,所述编程语言提供了对过程触发器的指定,并且所述方法进一步包括:
提供根据所述输入源程序中的所述编程语言指定的一个或多个过程触发器;
对每个所述过程触发器,提供所述程序数据成员中的哪一些是所述过程触发器的触发输入的标识;
其中所述一个或多个过程触发器中的每一个包括当相应的触发输入改变时拟调用的一个或多个触发器过程;
对于每一所述过程触发器,自动提供相应的触发器表示;
其中每个所述触发器表示包括在实例化时注册输入改变通知的一个或多个相应的触发反应器对象,所述触发反应器对象包括所述一个或多个触发器过程,并且所述相应的触发反应器对象在所述相应的触发器表示的范围内是可访问的;
其中所述通知代码还调节触发器表示对输入改变通知的注册登记;在所述命令性输出程序表示中实例化所述触发器表示,籍此对触发输入的改变自动导致所述触发器过程的执行。
Applications Claiming Priority (3)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
US12/154,399 | 2008-05-21 | ||
US12/154,399 US8850409B2 (en) | 2008-05-21 | 2008-05-21 | Notification-based constraint set translation to imperative execution |
PCT/US2009/003079 WO2009142716A1 (en) | 2008-05-21 | 2009-05-18 | Notificaton-based constraint set translation to imperative execution |
Publications (2)
Publication Number | Publication Date |
---|---|
CN102037447A true CN102037447A (zh) | 2011-04-27 |
CN102037447B CN102037447B (zh) | 2014-11-26 |
Family
ID=40823577
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN200980118918.3A Active CN102037447B (zh) | 2008-05-21 | 2009-05-18 | 基于通知的约束集翻译以实现命令性执行 |
Country Status (3)
Country | Link |
---|---|
US (2) | US8850409B2 (zh) |
CN (1) | CN102037447B (zh) |
WO (1) | WO2009142716A1 (zh) |
Cited By (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN104111858A (zh) * | 2013-04-22 | 2014-10-22 | 横河电机株式会社 | 事件分析器和计算机可读存储介质 |
CN105453097A (zh) * | 2013-05-31 | 2016-03-30 | 微软技术许可有限责任公司 | 受约束驱动程序平台在用户模式下在沙箱中运行驱动程序 |
CN111950646A (zh) * | 2020-08-20 | 2020-11-17 | 北京环境特性研究所 | 电磁图像的层次化知识模型构建方法及目标识别方法 |
Families Citing this family (61)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US8676841B2 (en) | 2008-08-29 | 2014-03-18 | Oracle International Corporation | Detection of recurring non-occurrences of events using pattern matching |
US8805887B2 (en) * | 2008-10-03 | 2014-08-12 | Microsoft Corporation | Packaging system to facilitate declarative model-driven development |
US8214795B2 (en) * | 2008-11-26 | 2012-07-03 | Optumsoft, Inc. | Efficient automated translation of procedures in constraint-based language |
US8935293B2 (en) | 2009-03-02 | 2015-01-13 | Oracle International Corporation | Framework for dynamically generating tuple and page classes |
US8527458B2 (en) | 2009-08-03 | 2013-09-03 | Oracle International Corporation | Logging framework for a data stream processing server |
US8959106B2 (en) | 2009-12-28 | 2015-02-17 | Oracle International Corporation | Class loading using java data cartridges |
US9430494B2 (en) | 2009-12-28 | 2016-08-30 | Oracle International Corporation | Spatial data cartridge for event processing systems |
US9305057B2 (en) | 2009-12-28 | 2016-04-05 | Oracle International Corporation | Extensible indexing framework using data cartridges |
US9430222B2 (en) * | 2010-05-24 | 2016-08-30 | Oracle International Corporation | Controlling a running application for live scene graph editing |
US8713049B2 (en) * | 2010-09-17 | 2014-04-29 | Oracle International Corporation | Support for a parameterized query/view in complex event processing |
US9189280B2 (en) | 2010-11-18 | 2015-11-17 | Oracle International Corporation | Tracking large numbers of moving objects in an event processing system |
US8990416B2 (en) | 2011-05-06 | 2015-03-24 | Oracle International Corporation | Support for a new insert stream (ISTREAM) operation in complex event processing (CEP) |
US9329975B2 (en) | 2011-07-07 | 2016-05-03 | Oracle International Corporation | Continuous query language (CQL) debugger in complex event processing (CEP) |
US9733901B2 (en) * | 2011-07-26 | 2017-08-15 | International Business Machines Corporation | Domain specific language design |
US8683443B2 (en) * | 2011-08-25 | 2014-03-25 | Salesforce.Com, Inc. | Streamlined methodology for resolving software integration conflicts |
US20130110879A1 (en) * | 2011-10-28 | 2013-05-02 | Microsoft Corporation | Declarative support for reference data in relational databases |
US9009183B2 (en) * | 2011-11-03 | 2015-04-14 | Microsoft Technology Licensing, Llc | Transformation of a system change set from machine-consumable form to a form that is readily consumable by a human |
US9141351B2 (en) * | 2012-05-01 | 2015-09-22 | Oracle International Corporation | Indicators for resources with idempotent close methods in software programs |
US9276942B2 (en) | 2012-09-07 | 2016-03-01 | Oracle International Corporation | Multi-tenancy identity management system |
US10148530B2 (en) | 2012-09-07 | 2018-12-04 | Oracle International Corporation | Rule based subscription cloning |
US9621435B2 (en) | 2012-09-07 | 2017-04-11 | Oracle International Corporation | Declarative and extensible model for provisioning of cloud based services |
US9667470B2 (en) | 2012-09-07 | 2017-05-30 | Oracle International Corporation | Failure handling in the execution flow of provisioning operations in a cloud environment |
US9542400B2 (en) | 2012-09-07 | 2017-01-10 | Oracle International Corporation | Service archive support |
US9203866B2 (en) | 2012-09-07 | 2015-12-01 | Oracle International Corporation | Overage framework for cloud services |
US9467355B2 (en) | 2012-09-07 | 2016-10-11 | Oracle International Corporation | Service association model |
US9563663B2 (en) | 2012-09-28 | 2017-02-07 | Oracle International Corporation | Fast path evaluation of Boolean predicates |
US9262479B2 (en) | 2012-09-28 | 2016-02-16 | Oracle International Corporation | Join operations for continuous queries over archived views |
US10956422B2 (en) | 2012-12-05 | 2021-03-23 | Oracle International Corporation | Integrating event processing with map-reduce |
US9098587B2 (en) | 2013-01-15 | 2015-08-04 | Oracle International Corporation | Variable duration non-event pattern matching |
US10298444B2 (en) | 2013-01-15 | 2019-05-21 | Oracle International Corporation | Variable duration windows on continuous data streams |
US20140214396A1 (en) * | 2013-01-28 | 2014-07-31 | International Business Machines Corporation | Specification properties creation for a visual model of a system |
US9047249B2 (en) | 2013-02-19 | 2015-06-02 | Oracle International Corporation | Handling faults in a continuous event processing (CEP) system |
US9390135B2 (en) | 2013-02-19 | 2016-07-12 | Oracle International Corporation | Executing continuous event processing (CEP) queries in parallel |
US9401854B2 (en) * | 2013-05-08 | 2016-07-26 | Arista Networks, Inc. | System and method for slow link flap detection |
US9418113B2 (en) | 2013-05-30 | 2016-08-16 | Oracle International Corporation | Value based windows on relations in continuous data streams |
US10268638B2 (en) * | 2013-11-27 | 2019-04-23 | Paraccel Llc | Limiting plan choice for database queries using plan constraints |
US9934279B2 (en) | 2013-12-05 | 2018-04-03 | Oracle International Corporation | Pattern matching across multiple input data streams |
US9262156B2 (en) * | 2014-02-12 | 2016-02-16 | International Business Machines Corporation | Methods for transparent management of context and state in an asynchronous callback flow |
US9244978B2 (en) | 2014-06-11 | 2016-01-26 | Oracle International Corporation | Custom partitioning of a data stream |
US9712645B2 (en) | 2014-06-26 | 2017-07-18 | Oracle International Corporation | Embedded event processing |
US9886486B2 (en) | 2014-09-24 | 2018-02-06 | Oracle International Corporation | Enriching events with dynamically typed big data for event processing |
US10120907B2 (en) | 2014-09-24 | 2018-11-06 | Oracle International Corporation | Scaling event processing using distributed flows and map-reduce operations |
WO2017018901A1 (en) | 2015-07-24 | 2017-02-02 | Oracle International Corporation | Visually exploring and analyzing event streams |
US10142174B2 (en) | 2015-08-25 | 2018-11-27 | Oracle International Corporation | Service deployment infrastructure request provisioning |
US9715375B1 (en) * | 2016-01-27 | 2017-07-25 | International Business Machines Corporation | Parallel compilation of software application |
US10536476B2 (en) | 2016-07-21 | 2020-01-14 | Sap Se | Realtime triggering framework |
US10482241B2 (en) | 2016-08-24 | 2019-11-19 | Sap Se | Visualization of data distributed in multiple dimensions |
US10542016B2 (en) | 2016-08-31 | 2020-01-21 | Sap Se | Location enrichment in enterprise threat detection |
US10673879B2 (en) | 2016-09-23 | 2020-06-02 | Sap Se | Snapshot of a forensic investigation for enterprise threat detection |
US10630705B2 (en) | 2016-09-23 | 2020-04-21 | Sap Se | Real-time push API for log events in enterprise threat detection |
US10534908B2 (en) | 2016-12-06 | 2020-01-14 | Sap Se | Alerts based on entities in security information and event management products |
US10530792B2 (en) | 2016-12-15 | 2020-01-07 | Sap Se | Using frequency analysis in enterprise threat detection to detect intrusions in a computer system |
US10534907B2 (en) | 2016-12-15 | 2020-01-14 | Sap Se | Providing semantic connectivity between a java application server and enterprise threat detection system using a J2EE data |
US11470094B2 (en) | 2016-12-16 | 2022-10-11 | Sap Se | Bi-directional content replication logic for enterprise threat detection |
US10552605B2 (en) | 2016-12-16 | 2020-02-04 | Sap Se | Anomaly detection in enterprise threat detection |
US10764306B2 (en) | 2016-12-19 | 2020-09-01 | Sap Se | Distributing cloud-computing platform content to enterprise threat detection systems |
US20180232468A1 (en) * | 2017-02-16 | 2018-08-16 | Wipro Limited | METHODS AND SYSTEMS FOR TIMING CONSTRAINT GENERATION IN IP/SoC DESIGN |
US10275223B2 (en) * | 2017-06-22 | 2019-04-30 | International Business Machines Corporation | Distributed key-value consistency and mapping |
US10530794B2 (en) | 2017-06-30 | 2020-01-07 | Sap Se | Pattern creation in enterprise threat detection |
US10681064B2 (en) | 2017-12-19 | 2020-06-09 | Sap Se | Analysis of complex relationships among information technology security-relevant entities using a network graph |
US10986111B2 (en) | 2017-12-19 | 2021-04-20 | Sap Se | Displaying a series of events along a time axis in enterprise threat detection |
Family Cites Families (11)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US5133075A (en) * | 1988-12-19 | 1992-07-21 | Hewlett-Packard Company | Method of monitoring changes in attribute values of object in an object-oriented database |
US6272672B1 (en) * | 1995-09-06 | 2001-08-07 | Melvin E. Conway | Dataflow processing with events |
US5819281A (en) * | 1996-02-26 | 1998-10-06 | Electronic Data Systems Corporation | Notification of aspect value change in object-oriented programming |
US6681383B1 (en) * | 2000-04-04 | 2004-01-20 | Sosy, Inc. | Automatic software production system |
US7669226B2 (en) * | 2004-07-30 | 2010-02-23 | International Business Machines Corporation | Generic declarative authorization scheme for Java |
US7890439B2 (en) * | 2006-12-15 | 2011-02-15 | Microsoft Corporation | Tuning of problem solvers |
US20080183538A1 (en) * | 2007-01-30 | 2008-07-31 | Microsoft Corporation | Allocating Resources to Tasks in Workflows |
US8180658B2 (en) * | 2007-01-30 | 2012-05-15 | Microsoft Corporation | Exploitation of workflow solution spaces to account for changes to resources |
US20080184250A1 (en) * | 2007-01-30 | 2008-07-31 | Microsoft Corporation | Synchronizing Workflows |
US9158519B2 (en) * | 2008-05-21 | 2015-10-13 | Optumsoft, Inc. | Dynamic collection attribute-based computer programming language methods |
US8214795B2 (en) * | 2008-11-26 | 2012-07-03 | Optumsoft, Inc. | Efficient automated translation of procedures in constraint-based language |
-
2008
- 2008-05-21 US US12/154,399 patent/US8850409B2/en active Active
-
2009
- 2009-05-18 WO PCT/US2009/003079 patent/WO2009142716A1/en active Application Filing
- 2009-05-18 CN CN200980118918.3A patent/CN102037447B/zh active Active
-
2014
- 2014-08-21 US US14/465,720 patent/US9411563B2/en active Active
Non-Patent Citations (1)
Title |
---|
GUS LOPEZ等: ""Implementing Constraint Imperative Programming Languages:The Kaleidoscope’93 Virtual Machine"", 《PROCEEDINGS OF OOPSLA’94》 * |
Cited By (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN104111858A (zh) * | 2013-04-22 | 2014-10-22 | 横河电机株式会社 | 事件分析器和计算机可读存储介质 |
CN104111858B (zh) * | 2013-04-22 | 2018-05-11 | 横河电机株式会社 | 事件分析器和计算机可读存储介质 |
CN105453097A (zh) * | 2013-05-31 | 2016-03-30 | 微软技术许可有限责任公司 | 受约束驱动程序平台在用户模式下在沙箱中运行驱动程序 |
CN105453097B (zh) * | 2013-05-31 | 2018-05-29 | 微软技术许可有限责任公司 | 受约束驱动程序平台在用户模式下在沙箱中运行驱动程序 |
CN111950646A (zh) * | 2020-08-20 | 2020-11-17 | 北京环境特性研究所 | 电磁图像的层次化知识模型构建方法及目标识别方法 |
Also Published As
Publication number | Publication date |
---|---|
US8850409B2 (en) | 2014-09-30 |
CN102037447B (zh) | 2014-11-26 |
US9411563B2 (en) | 2016-08-09 |
US20140366008A1 (en) | 2014-12-11 |
US20090293046A1 (en) | 2009-11-26 |
WO2009142716A1 (en) | 2009-11-26 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN102037447B (zh) | 基于通知的约束集翻译以实现命令性执行 | |
CN102227712B (zh) | 基于约束的语言中过程的高效自动翻译 | |
JP5354602B2 (ja) | プロデューサグラフ指向のプログラミング及び実行 | |
JP5354601B2 (ja) | プロデューサグラフ指向のプログラミングフレームワークにおけるパラレル化及びインスツルメンテーション | |
JP5354603B2 (ja) | シナリオサポートを伴うプロデューサグラフ指向のプログラミングフレームワーク | |
US8042091B2 (en) | Automatic composition of model transformations | |
Nagy et al. | Composing aspects at shared join points | |
US7162502B2 (en) | Systems and methods that synchronize data with representations of the data | |
CN102037446A (zh) | 基于动态集合属性的计算机编程语言方法 | |
US20050108684A1 (en) | Method and system for generating an application object repository from application framework metadata | |
Strommer et al. | A framework for model transformation by-example: Concepts and tool support | |
Sunitha et al. | Object constraint language for code generation from activity models | |
CN111176658B (zh) | 基于元对象机制的AADL到Simulink模型自动转换方法 | |
Chen et al. | Modelling with relational calculus of object and component systems-rCOS | |
BOUSETTA et al. | Generating operations specification from domain class diagram using transition state diagram | |
Schöne et al. | Incremental causal connection for self-adaptive systems based on relational reference attribute grammars | |
Bräuer et al. | Model-level integration of the OCL standard library using a pivot model with generics support | |
Petrosino et al. | Cross-Paradigm Interoperability Between Jadescript and Java. | |
de Oliveira et al. | MetaJ: An Extensible Environment for Metaprogramming in Java. | |
Gargantini et al. | Metamodelling a formal method: applying mde to abstract state machines | |
Merino | ProcessJ: The JVMCSP Code Generator | |
Kegel et al. | Deep models@ run. time for user-driven flexible systems | |
Flake | UML-based Specification of State Oriented Real Time Properties | |
Bracker | Unified notions of generalised monads and applicative functors. | |
Christen et al. | Virtual Machines and Hypergraph Data/Code Models: Graph-Theoretic Representations of Lambda-Style Calculi |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
C06 | Publication | ||
PB01 | Publication | ||
C10 | Entry into substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
C14 | Grant of patent or utility model | ||
GR01 | Patent grant |