SCADE 团队于2024年推出了下一代 SCADE 工具 Scade One,工具的建模语言也基于Scade 6 进行了演化。在语言命名方面,并没有复用"Scade"这一标志性的名称,而是使用了新的名字:Swan。在本篇中,将叙述 Swan 语言的原理。更详细的内容,可参考 Scade One 文档中的材料《Introduction to Swan Language Principles》。
Swan 语言是专为安全(Safe)和实时软件所设计的领域特定语言。
反应式系统 (Reactive System)
反应式系统是指能够持续地与其环境交互的系统。这种交互旨在根据来自系统所处环境的信息来控制环境。这里的环境包括系统的使用者、作用于该环境的物理规律,以及与之通信的其他系统。在系统内部包含了反应的功能数学函数。该数学函数根据通过传感器和设备从环境获取的信号,再计算要通过物理执行器反馈给环境的信号。
离散时间响应式系统
在基于计算机的实现中,对信号的处理需要采用离散化的视角。通过离散化,信号被视作序列,信号的时间变量成为该序列的下标。离散响应式系统就是接受若干输入序列,输出对应的输出序列的一种运算。
Swan, 面向时序逻辑的语言
Swan 是一种抽象层次较高的计算机语言,能够定义相互递归的序列。在 Swan 中,这些值序列称为“流”(flow);变量,或更通用地说,表达式,都可以代表一个流。由于语言提供了高度抽象,Swan 程序也常被称为“模型”;建模设计者用 Swan 表达的程序更接近数学模型,而非传统编程语言中的实现细节。
该语言还可视为专用于定义“时序逻辑函数”(sequential logic functions)的语言,即其输出既取决于当前输入,也取决于过去输入的序列。
对流定义,Swan语言支持两种风格:方程式风格(Equational)和图示风格(Diagrammatic)。
比如,定义序列y_n作为给定序列x_n的累计和。在数学上,能定义为如下的递归公式:
y_0 = x_0
y_n = x_n + y_(n-1) for n > 0
使用Swan的方程风格编写流y的序列定义可以是
y = x -> (x + pre y);
若使用图示风格建模,则会是块状图与连线构成的图。
定义序列函数需要语言具备引用输入的过去状态的能力。在上面的例子中,通过延迟算子(pre)来实现。在某些情况下,通过使用状态机来表达序列性会更加便利。Swan 中提供了层次化的状态机,支持块状图和方程组在相同的语义框架下进行混合设计。
从 Swan 模型进行代码生成
在前面叙述中,通过序列的观点构造的系统,仍然是以抽象的视角来表达系统。从实现角度考虑,相对应的程序,是将序列中第n位的输入,和当前状态S_n,计算出输出序列中第n位的输出。这种计算被称为"反应",或者"step", 或者"cycle"。所以在命令式语言(C/C++, Ada)的实现里,程序的形态会是
i_n => [S_n -> S_(n+1)] => o_n
在Swan模型的代码生成中,会将状态结构S_0进行提取,以及从模型中生成f_cycle
step函数。状态的初始值,与将状态重置为初始状态的函数都会被生成。
以静态的方法保证模型的正确性
如同任何一种形式化语言一样,Swan语言具备形式化定义的语法。同时,Swan语言也包含静态的分析阶段,来确保模型的正确性。
- 类型检查确保函数操作的所有操作数,其类型是符合预期的。并且对数组的访问都在长度限制之内。
- 时钟检查确保所有流的消费端与生成端具有相同的节拍。
- 初始化分析确保所有输出不会依赖未初始化的前序(past)状态。
- 因果分析确保每一项流的当前值不会依赖自身。
当模型的正确性被确定了,则可认为模型具备了语义,也就是定义明确的行为,并且可以被进一步的用于其他的处理阶段,比如:仿真、代码生成、形式化验证、覆盖率分析等。
所有实现Swan语言的工具,都需要在这些工具的前端(front-end)去实施上述提到的验证工作。
Swan 的语言特征
这里列举 Swan 语言的主要特征,使读者将 Swan 与其他编程语言比较时,能更好地定位 Swan 语言的位置。
- 数据流。Swan 关注的是流之间的数据依赖关系,模型语句的相对顺序是不重要的。只要运算所需的所有输入值到位,便可立即计算该运算。
- 声明式。Swan 是声明式语言,设计者只需关注“是什么”(What),而无需显式指明“怎么做”(How)。方程式和图示定义了流间关系,语言语义负责调度;任何满足数据依赖的周期内调度均为正确。
- 确定性。正确的 Swan 模型定义了唯一的流到流的函数。对于给定模型和输入序列,输出序列唯一且由语言语义定义。
- 同步性。当前周期的输出基于当前输入和状态计算而来,“同步”指所有这些计算被抽象为瞬时完成。虽然操作间无先后执行顺序,但仍满足数据依赖,且可并行设计与组合而不互相干扰。
- 实时性。上述内容描述的语言构造和静态属性,确保了反应函数能在有界时间资源和有界内存资源内实现。