MOLD:形态描述语言
第2章 MOLD:形态描述语言
UML 作为已被理解的形态变换之一部分 · MOLD = UML 加扩展 · 作为 16 维向量的 MOVE · 六个主要面 · 备用图 · 模型即代码
2章 1. UML 作为已被理解的形态变换之一部分
20 世纪 90 年代,一群面向对象编程的开发者面临这样的任务:描述复杂的软件系统——其中类的数量达到数百,而类与类之间关系的数量则达到数千。代码的文本表示已无法胜任:程序员看得见个别的类,却看不见系统。回应是制定一种统一的图形建模语言——UML(Unified Modeling Language),在十年代末整合了若干已有的记号法的经验。
UML 围绕“多重投影”的思想构建起来。一个复杂的系统并不由单一一张图来描述——它被投影到若干不同的表示上,每一个表示都凸显某一确定的方面。类图表示类型的静态结构。时序图表示消息交换的时间动态。状态图表示实体的生命周期。部署图表示在物理节点上的分布。每一张图单独来看都是简单而清楚的;它们的总和给出对系统的完整描述。截至 2005 年 UML 2.0 标准化之时,规范中已纳入了 14 种类型的图。
从本书的视角看,UML 不只是一种工程记号法,而是对形态变换的理解之一已被记录下来的片段。UML 的作者们寻找一种方式来描述由相互作用的实体所构成的复杂系统,并独立地达到了进化在数十亿年中所选择的同一些范畴——类、组件、连接、活动、状态。这一巧合不是偶然的:两种过程——UML 建模与 GTR0 的进化训练——所解决的是同一项任务:描述由许多相互作用的元素以特征性关系构成的结构。
然而 UML 止步于描述这一阶段。类图描述类,但不创建类。活动图描述行为,但不执行行为。UML 模型作为图纸而存在——一种静态描述,程序员随后将其翻译为可执行代码。在模型与代码之间保留着一道缝隙,各种代码生成技术(MDA、可执行 UML)试图弥合这道缝隙,但都没有取得决定性的成功。
Gativus 以另一种方式消除这一缝隙。不是通过从模型生成代码,而是通过模型与运行中网络的结构性同一化。UML 模型在 Gativus 架构中不是对未来系统的描述,而是已存在系统的两种形式之一——它在个体发生空间中卷起的形式。把模型展开为运行中网络,不是由编译器执行,而是由形态发生 RTR0 执行。我们将在 2.6 节回到这一解决方案。
2章 2. MOLD:在记号法上是 UML,在语义上是 Gativus
MOLD(MOrphology Language Description)——Gativus 的形态形式描述语言。MOLD 所依据的一项原则性决定是:此语言从 UML 继承记号法,但不继承语义。各种图的名称、图形元素、线条类型、实体的标记方式——都取自 UML 并保留视觉上的相似性。所标记之物的含义——则由 Gativus 的架构所确定,并不必与 UML 中同样构造的含义一致。
这一决定服务于一项教学目的。三十年来,UML 已成为工程沟通的事实上的标准;Gativus 的相当一部分受众对其记号法是熟悉的。使用熟悉的视觉语言显著降低了进入Gativus 架构的门槛。看到一张 MOLD 图的读者认得出记号法,因而可以专注于所描述的是什么,而不被它是如何画出来的所分心。
a) 从 UML 继承下来的内容
MOLD 保留投影的多重性。对一个 Gativus 机体的完整描述被分配到若干张图中,每张图凸显一个方面。各张图的名称按照 Gativus 记号法(GNOT)的规则缩写为四个字符,并与 UML 的名称相对应:类图——CLSS,组件图——COMP,通信图——COMM,活动图——ACTD,如此等等。
MOLD 保留基本视觉元素。类用带分区的矩形表示。节点用立方体或三维矩形表示。连接用带不同箭头的箭头表示。状态用圆角矩形表示。活动用带圆角的形体表示。任何用过 UML 的人都能立刻辨认出这些元素。
MOLD 保留各图相互一致的原则。出现在多张图中的实体,标示的是同一实在。在 CLSS 中提及、在 COMP 中放置、在 COMM 中连接的同一个类——是同一个对象,在三种不同的表示上被投影出来。
b) 在 MOLD 中添加的内容
MOLD 以若干原则性的构造扩展了 UML,以反映 Gativus 架构的特性。
作为头等实体的连接器。在 UML 中,实体之间的连接通常是一条带有标注的线。在 Gativus 中,连接器是独立的数据单元:有类型的、有唯一地址的接入点,具有状态(PEND、ACTV)以及自身的生命周期。MOLD 显式地表示连接器——作为组件躯体上的插针与插座,伸出于方块的边界之外。这与 GNOT 记号法以及在 GNET 中所描述的 NDDI 节点架构是相一致的。
经由 CONT 对连接进行类型化。Gativus 中的每一个关系都有一个 CONT(Connector Type)类型,用以决定连接器的兼容性。一种类型的连接器在物理上无法连接到另一种类型的连接器——这是一项结构性约束,类似于电子学中不同标准接插件之间的不兼容。MOLD 通过在图上对插针和插座的形状与颜色进行类型化,反映了这一点。
作为资源向量的 AVEC。在 UML 中,资源是间接被提到的(通过部署图),但没有形式化的表示。在 Gativus 中,资源与权限是一个本质性的方面——它们决定了某个节点是否可以被创建出来。MOLD 引入了一张独立的资源图 RSRC,把 AVEC 在功能性器官之间的分配加以形式化。
D 层次与 G 层次的区分。节点的结构代码(D 区段、目标代码、基因)与动态关系(G 层次、突触、表达)在性质上是有原则区别的,尽管它们在同一基底上实现。MOLD 把这两个方面分配到不同的图上,并对 D 关系与 G 关系使用不同的图形约定。
关键期的时间维度。形态发生有一个有限的活动窗口:关键期关闭之后,新节点的创建与新的 G 关系的建立都会急剧减少。MOLD 在活动图上通过形态发生、成熟与运行各模式之间的显式过渡,把这一方面记录下来。
c) 不被继承的内容
MOLD 不继承 UML 的语义——后者是基于面向对象编程范式的。UML 中的类是通过调用构造函数来创建对象的模板。MOLD 中的类是通过 NRGN 程序来创建 NDDI 节点的模板,而 NRGN 与构造函数的调用有本质性的差别。UML 中的方法是在对象上被调用的函数。在 MOLD 中,消息与活动之间的对应是通过 A 区段以及对 V 组件变化的反应来中介的。
这些语义上的差别并不破坏使用 UML 记号法的可能性:它们只是改变了解释。图看起来像 UML,但描述的是 Gativus 的结构。
2章 3. 作为 16 维向量的 MOVE
在 Gativus 中,对机体的完整描述被形式化为 MOVE(MOrphology VEctor)——一个 16 维空间中的向量,其每一维坐标都对应 MOLD 的一种图。维数 16 由 UML 2.0 的图的数量(14)加上 Gativus 特有的两种扩展(SPCE、RSRC)所决定。
一个具体的机体由全部 16 维坐标的值——即每一相应图的内容——所描述。并非每一维坐标对每一个机体都必然被填满:对于简单的功能性器官,几张支撑性的图就足够了,而对于完整的主观现实网络,全部的图都会被启用。未被填满的坐标意味着相应方面对该机体而言并非特殊。
a) 支撑立方体:六张主要图
在 16 维坐标中,有六维实际上用于 Gativus 每一个机体的描述,并构成支撑集合。其几何类比是一个具有六个面的立方体,每一面对应一张图。这一类比使用了已经为 NDDI 记号法(由各区段组成的多面体)所熟悉的视觉手法,并提供了一个直觉清楚的心智模型。
六张主要图:
名称 |
图 |
UML 对应 |
内容 |
CLSS |
类 |
Class diagram |
NDDI 节点类型及其区段 |
COMP |
组件 |
Component diagram |
类型在器官中的分组 |
COMM |
通信 |
Communication diagram |
连接模板 |
ACTD |
活动 |
Activity diagram |
形态发生程序 |
SPCE |
部署 |
Deployment diagram(扩展) |
在 GATE 上的分布 |
RSRC |
资源 |
(Gativus 扩展) |
AVEC 预算与配额 |
这一集合足以描述 Gativus 绝大多数功能性器官。六张支撑图各自的详细内容见 2.4 节。
b) 备用坐标
其余十维坐标对应于 UML 中的那些图,它们在当前的 Gativus 架构中或者较少被使用,或者尚没有特定的含义。这些坐标被保留下来——每一维在 MOLD 记号法中都被固定为一个四字符的名称,但其详细语义对未来的扩展保持开放。其中哪些会被沿用、哪些会被淘汰,将由工程实践来决定。备用图列于 2.5 节。
c) MOVE 的参数化
MOVE 的一项原则性属性是参数化。向量并不在数量术语下包含绝对值。它不指示“恰好创建十万个 A 类节点”,而是描述规则与比例:“类 A——本器官的主群体”、“类 B——支持性群体,比 A 小十倍”、“A 与 B 之间的连接——稠密,B 与 C 之间——稀疏”。
展开的具体规模并非由 MOVE 自身决定,而由形态发生发生之时可用的 AVEC 资源决定。同一个 MOVE 在具有不同资源的不同平台上被展开,将给出在功能上相同、但在数量上不同的器官。这是与生物变异性的直接类比:同一份 DNA 在不同的营养与环境条件下被执行,将给出同一物种但大小不同的个体。Gativus 把这一属性作为本质性的属性继承下来。
参数化赋予 MOVE 以紧凑性。几千字节的描述能够在展开时产生数百万个节点,因为规则比结果更紧凑。运行中网络的具体拓扑没有被记录在 MOVE 之中——它在 SYGA 时通过对伙伴的自主搜索而被计算出来,在形态发生完成之前,它不存在于任何地方。
2章 4. 六个主要面
下文描述 MOLD 的六张支撑图。每一张图都获得一项简要刻画:它描述什么、哪些实体是其基本元素、其记号法是什么样子。使用这些图的程序的详细描述见第 3–5 章。
a) CLSS——类图
描述某机体中存在的 NDDI 节点的类型。类是节点的结构模板,固定下其区段集合(根据层次的不同为 V、A、S、G、T、C、L、M),连接器的类型(指明 CONT),以及与 ROOT 仓库中实现节点逻辑的 D 组件之间的 d 关系。
在图上,类以类似 UML 的方式表示:一个带三个区段的矩形。上部——类的名称。中间——按组件构成的组成(例如 V[3]、A[2]、L[1])。下部——连接器的列表及其 CONT 类型。类与类之间的连接标示继承与组合关系;它们对 D 区段的优化是本质性的,而不指定具体节点之间的连接。
CLSS 是各张图中最基础的一张。它确定了在机体中可以存在哪些节点。没有 CLSS,其余各张图都失去对象:COMM 无法确定不存在的类型之间的连接,COMP 无法对未定义的实体进行分组。
b) COMP——组件图
描述类在功能性器官中的分组。一个 Gativus 机体包含若干个器官——空间域、对象域、符号域、叙事域、价值论域,等等。每一个器官实现其自身的功能,并由若干类的节点以确定的比例组成。
在图上,组件表示为一个带有显式边界的容器。容器内部——属于该器官的类。容器之间的连接标示器官间的接口——也就是一个器官的节点经由哪些类型的连接器与另一器官的节点交互。
COMP 回答的问题是:机体由什么构成。在形态发生的架构中,它确定了 MOVE 从 GATE 向 ANOD 委派时的拆分:每一个 ANOD 接收 MOVE 的一个片段,与一个组件相关。这一点在第 5 章中详细考察。
c) COMM——通信图
描述类与类之间的连接模板——节点在运行中网络中与谁、以何种方式进行通信。它是 MOLD 各图中最有体量的一张:一个发达机体中连接模板的数量以数十计,而类的数量则以个位数或数十计。
每一个模板描述一种关系:哪种类型的节点与哪种类型的节点相连接,经由哪种连接器,以何种拓扑(点对点、多对一、多对多),以何种密度,带或不带传送确认。在形态发生时,一个模板会产生数千乃至数百万个具体的连接——而 MOVE 的大小并不增长。
模板分为确定性的与自主的。确定性模板显式地固定了具体类与具体类之间的连接,在形态发生时经由 SYGD 实现。自主模板只描述连接器的类型,把对伙伴的搜索留到 SYGA 阶段。这一区分在第 4 章中详细描述。
d) ACTD——活动图
描述形态发生与运行的程序方面:各阶段的序列、状态之间的过渡、检查点。在这里记录如下过程:萌发(解析——神经发生——突触发生——成熟——验证——过渡的序列),OPNG → OPN 的变换,关键期的关闭。
在活动图上使用标准的 UML 元素:动作节点(圆角矩形)、决策节点(菱形)、同步节点(平行线)、初始与最终状态。Gativus 中的 ACTD 在本质上依赖于并行性:形态发生的各阶段在时间上是重叠的,而不是顺序进行的,图必须把这一点反映出来。
ACTD 是静态结构(CLSS、COMP、COMM)与生命周期时间动态之间的桥梁。没有它,就无法描述类是以何种顺序被创建的、确定性连接是何时被建立的、对伙伴的自主搜索是何时被启动的、器官是何时进入运行模式的。
e) SPCE——部署图
描述机体节点在 GATE 平台上的物理分布。一个机体可以分布在若干平台上——例如,不同的功能性器官可以驻留在具有不同资源的不同物理设备上。SPCE 把这一分布加以形式化。
在部署图上,GATE 表示为部署节点(UML 记号法中的三维方块),其内部放置着类或组件。GATE 之间的连接标示跨平台关系所经由的网络路由。SPCE 是 UML deployment diagram 的部分扩展:基本元素被继承,但语义被适配于 Gativus 的架构。
SPCE 具有本质性的实际意义:不同的功能性器官有不同的资源需求,而将它们最优地分布在物理平台上,是网络初始化时的一项任务。价值论域与符号域所需的资源明显多于空间域,可以放置在具有相应参数的独立 GATE 上。
f) RSRC——资源图
描述 AVEC 与其他资源预算在功能性器官与类之间的分配。这是 Gativus 的一种完整扩展,在 UML 中没有直接的对应。RSRC 把 UML 中位于模型之外的内容加以形式化:每一个器官中允许创建多少节点、突触发生的配额是多少、应用了哪些安全策略。
在资源图上,基本元素是资源节点(被表示为带计数器的风格化钱包或容器)与委派流(被表示为带有数量标注的箭头)。AVEC 从 ROOT 到 GATE、从 GATE 到 ANOD、从 ANOD 到下属节点的委派,显式地以所委派池的大小予以表示。
RSRC 在原则上恰恰为 Gativus 所必需,因为在此架构中资源限制不是辅助性的方面,而是一种结构性机制。功能性器官的大小不由 MOVE 中的某个值确定,而由 AVEC 经由 RSRC 的分配确定。没有 RSRC,就无法描述同一 MOVE 的不同实例之间在器官大小上的变异性。
2章 5. 十张备用图
六张支撑图覆盖了对 Gativus 机体进行描述的主要方面。MOVE 其余的十维坐标被保留给具有 UML 2.0 类比的图,或保留给 Gativus 未来扩展所特有的图。每一维都在 MOLD 记号法中固定为一个四字符的名称;其中大多数的详细语义保持开放,将随工程实践而得到精化。
现在保留这些名称而不完整地阐发其语义,具有一项具体的意义:它固定了名称空间,防止后续扩展时的冲突。哪些备用图将作为 MOVE 的独立坐标得到沿用,哪些将保持未被使用或与已有的图合并——将由建造首批可工作机体的实践来决定。
当前的备用图列表:
名称 |
UML 对应 |
在 Gativus 中可能的角色 |
SEQU |
Sequence diagram |
类与类之间交换的时间展开 |
STAT |
State machine |
节点或连接器的生命周期 |
USEC |
Use case |
外部交互场景 |
OBJC |
Object diagram |
某具体配置的快照 |
PACK |
Package diagram |
类按层次的分组 |
TIME |
Timing diagram |
流的时间特性 |
INTR |
Interaction overview |
场景概览 |
PROF |
Profile diagram |
原型与元数据 |
CMPS |
Composite structure |
类的内部组成 |
RSV1 |
(备用) |
为未来保留 |
关于最重要的几张备用图,几点说明。SEQU(Sequence diagram)看来是被提升到支撑集合中的天然候选:消息交换的时间序列对描述 SYGN 协议与神经发生而言是原则性的。或许,在本书的后续修订版中,SEQU 将转入支撑图之列。STAT(State machine)与 ACTD 紧密相关,可以与之合并,或者反过来,被划出为一张专门的图,用以描述连接器的生命周期(PEND → ACTV)。
其余备用图对 Gativus 的有用性不太明显。UML 中的 USEC 与 OBJC 分别描述与外界的交互以及具体的配置——这两个方面在 Gativus 中以另外的方式表达:外部交互经由 SPCE 与 RSRC,配置经由运行中网络的状态。或许这些 MOVE 坐标在大多数描述中将保持未被填满。
2章 6. UML 模型即 MOVE:模型即代码
MOLD 架构的一项原则性后果涉及模型与运行中系统的关系。在传统编程中,UML 模型是一份静态图纸,程序员据此写出可执行代码。在模型与代码之间保留着一道缝隙:模型中的变更并不会自动导致代码中的变更,而保持两者一致需要持续的努力。代码生成技术(MDA——Model-Driven Architecture,可执行 UML)曾试图弥合这道缝隙,但未能完全成功:自动生成的代码或者效率不够,或者需要手工修订——这又把不一致的问题带了回来。
Gativus 以另一种方式解决这一问题——不是通过生成,而是通过结构性同一化。按照 MOLD 规则编制的 UML 模型,就是 MOVE。被放入节点的 M 区段后,它在激活时启动 RTR0。并不发生代码生成:ROOT 仓库中的 D 组件已经包含了相应类的可执行逻辑,而 MOVE 在展开时只是指明使用哪些 D 组件、以何种数量、以何种连接方式。
这一解决方案在若干点上与 MDA 有根本的不同。不发生代码生成,因而不存在生成代码质量的问题——执行的是已被训练的 D 组件,而不是模型的机器翻译。模型与运行中网络的一致性不是由某个同步过程来维持,而是由结构性同一性来维持——展开是 MOVE 的函数,MOVE 的任何变更都在下一次萌发时直接反映在运行中网络上。修改模型不需要额外的编译步骤:MOVE 的新版本只是被展开为一个新的机体。
a) 这对开发者意味着什么
对于在 Gativus 上工作的工程师而言,描述机体就是在可视化编辑器中构建 MOLD 模型。现有的 UML 建模工具(IDE 插件、专用环境)可以在不改变界面原则的前提下被适配为 MOLD:同样的图、同样的记号法、同样的编辑手法。数十年来在 UML 工作中所积累的工程技能可以直接迁移。
差别在执行阶段显现。完成的 MOLD 模型并不被编译为代码——它被打包为 MOVE 并放入 GERM。被放置在具有充分 AVEC 的 GATE 平台上之后,GERM 自主地启动萌发。结果是一张运行中网络,在结构上对应于模型,但在细节上是各具特点的(具体的 UNON、具体的 SYGA 连接、具体的初始状态)。
b) 模型与运行中网络之间的双射
模型与 MOVE 的结构性同一化,闭合了第 1 章所描述的 Gativus 两种空间之间的双射。运行中网络中的每一个节点,在 M 区段中都有一个个体发生对偶——一条引用 CLSS 图中某个类的记录。CLSS 中的每一个类,不仅存在于模型中,也存在于运行中网络中,作为真实节点的类型。COMM 中的每一种关系,在已建立的连接器中都有真实的体现。
这一双射允许运行中网络中的节点经由 m 关系调用其自身的描述并对之进行分析。达到成熟的网络可以把自身的 MOLD 模型用作推理的对象——例如用于设计下一版本的机体。在极限情况下,这给出一个闭合的循环:其中运行中网络参与了通过 DTR0 对其自身结构的封装,产生一个新的 MOVE,后者在下一次展开时创建出新一代的机体。这一方面属于在 GTOM 中所描述的递归模式。
2章 7. 向第 3 章的过渡
本章引入了 MOLD——Gativus 的形态形式描述语言,它建立在 UML 记号法的基础上,并以反映架构特性的构造加以扩展。MOVE 被定义为一个 16 维向量,其各维坐标对应于 MOLD 的诸图。六张支撑图(CLSS、COMP、COMM、ACTD、SPCE、RSRC)被实质性地加以描述;十张备用图被列出,并附以关于其可能角色的初步标注。
原则性的架构决定——模型即代码——消除了对传统编程而言所特有的描述与执行之间的断裂。按照 MOVE 规则编制的 MOLD 模型,经由 RTR0 被展开为一张运行中网络,而无需中间的代码生成。
保持敞开的是关于 MOVE 作为 Gativus 网络中之对象之地位的问题。MOVE 是一个节点的组件、一项数字资产,还是一种双重性质的实体?这一问题——是下一章的对象。第 3 章把 GERM 作为种子的容器加以考察,考察它与 MOVE 及 OPNG 的联系,并解决在网络节点之间传递描述的机制问题。
目录
