微步和宏步语义等价性证明
在编程语义的研究中,微步和宏步语义的等价性证明是一个重要的课题。本文将深入探讨相关概念,包括不同类型的语义定义、面临的问题以及解决方法。
1. 暂停和中止的变体
暂停和中止的变体在暂停或中止时的数据操作上有所不同。强变体在中止或暂停时会忽略所有数据操作,而弱变体则会执行所有这些操作。此外,还有即时变体,它们在开始时会额外考虑条件 σ,这些可以根据其他变体来定义。
local x in S end
和
local y : α in S end
语句分别用于定义局部事件和局部状态变量。它们的行为类似于 S,但变量 x 或 y 的作用域仅限于 S,即局部变量在局部语句外部不可见。为避免一些问题,本文不考虑局部声明。
Quartz 允许我们在控制流到达特定位置时设置断言。
now σ
要求 σ 在当前宏步中必须成立,
during S holds σ
则表示在控制流处于 S 内部时,σ 必须成立。如果条件 σ 不成立,则不会继续执行,此时行为未定义。
2. 基于控制流谓词的语义
硬件设计师常用的一种技术是将控制流和数据流分离。Quartz 的语义就是基于这种分离来定义的,其中控制流的定义基于控制流谓词
enter (S)
、
move (S)
和
term (S)
,它们分别描述了语句 S 的进入条件、内部移动条件和终止条件。语句的数据流由其受保护命令定义。
以下是一些具体的控制流谓词:
-
in (S)
:是 S 中出现的暂停标签的析取。当且仅当在某个时间点,控制流位于 S 内部的某个位置时,
in (S)
成立。
-
inst (S)
:当且仅当如果现在启动 S,控制流不能停留在 S 中时成立,这意味着在该时间点 S 的执行将是即时的。
-
enter (S)
:描述了如果现在启动 S,控制流在下一个时间点将位于何处。
-
term (S)
:描述了控制流当前位于 S 内部且想要离开 S 的所有条件。但需要注意的是,由于 S 可能同时被进入(例如通过周围的循环语句),控制流在下一个时间点可能仍在 S 中。
-
move (S)
:描述了所有内部移动,即从 S 内部的某个位置到 S 内部另一个位置的所有可能转换。
-
guardcmd (ϕ, S)
:是一组形式为
(γ, C)
的对,其中 C 是一个数据操作语句(即发射或赋值)。
(γ, C)
的含义是,只要保护条件 γ 成立,C 就会立即执行。
这些控制流谓词依赖于时间,类型为
N → B
。它们都可以通过对 Quartz 语句集的简单原始递归定义来定义。
3. 基于硬件电路的语义
将同步程序转换为方程系统,可直接解释为硬件电路,这是当前主流编译技术(包括软件和硬件)的基本方法。这种想法由来已久,并且已经定义了许多变体。与控制流谓词类似,这种语义只考虑宏步。生成的硬件电路是同步的,在每个时钟周期执行程序的一个宏步。
暂停语句对应于触发器,微步则用组合逻辑门实现。如果要生成软件,软件基本上是特定硬件电路的模拟器,它为触发器保存局部变量,并根据当前输入和触发器的当前值计算当前输出以及触发器的下一个值。需要注意的是,软件可以操作包括指针结构在内的任意数据类型,而纯硬件设计则无法做到这一点。
4. 基于进程代数规则的语义
Esterel 的原始语义由结构操作语义(SOS)给出,其规则形式为
S D, b −−−−→ E S′
,其中 S 和 S′ 是语句,D 是动作(发射或赋值),b 是布尔值(完成标志),E 是当前环境。这些规则描述了微步的执行,并通过完成标志 b 指示宏步的开始和结束。
以下是一些具体的规则示例:
- 条件语句的启动规则:
S1 D1, b1 −−−−−→ E S′ 1
E |= σ
if σ then S1 else S2 end D1, b1 −−−−−→ E S′ 1
S2 D2, b2 −−−−−→ E S′ 2
E ̸|= σ
if σ then S1 else S2 end D2, b2 −−−−−→ E S′ 2
- 序列语句的规则:
S1 D1, false −−−−−−−→ E S′ 1
S2 D2, b2 −−−−−→ E S′ 2
S1; S2 D1 ∪D2, b2 −−−−−−−−−→ E S′ 2
S1 D1, true −−−−−−−→ E nothing
S1; S2 D1, true −−−−−−−→ E S2
S1 D1, true −−−−−−−→ E S′ 1
S′ 1 ̸= nothing
S1; S2 D1, true −−−−−−−→ E S′ 1; S2
然而,SOS 规则存在问题。它们通过递归定义描述程序的潜在无限执行,这在循环规则中会导致问题。例如,对于
while σ do S end
循环:
E ̸|= σ
while σ do S end {}, false −−−−−−−→ E nothing
E |= σ
S D, true −−−−−−→ E S′
S′ ̸= nothing
while σ do S end D, true −−−−−−→ E S′; while σ do S end
循环体不能是即时的,否则程序将在一个宏步中执行无限多个微步,这对于同步程序来说是不可能的。此外,SOS 规则不允许通过简单的原始递归定义,因此不能直接用于语言的嵌入。
下面是一个简单的 mermaid 流程图,展示了基于进程代数规则语义中条件语句的执行流程:
graph TD;
A[开始] --> B{σ 是否成立?};
B -- 是 --> C[执行 S1];
B -- 否 --> D[执行 S2];
C --> E[结束];
D --> E;
5. SOS 规则的暂停集编码
为了解决 SOS 规则的问题,可以采用暂停集编码。之前的 SOS 规则形式为
S D, b −−−−→ E S′
,而现在可以通过收集当前控制流所在的暂停语句的标签来编码当前控制流位置,规则形式变为
(S, E) ▷H D −−→H′
。
其含义是:如果控制流当前位于标签包含在 H 中的暂停语句处,那么在环境 E 的宏步执行中,将调用收集在 D 中的数据操作动作,然后停止在标签包含在 H′ 中的暂停语句处。当且仅当 H′ 为空时,执行完成一个宏步,因此在暂停集编码的 SOS 规则中不再需要完成标志。
经过暂停集编码后,SOS 规则现在通过对暂停集的递归定义,变成了原始递归规则。例如,循环规则现在如下:
E |= σ
(S, E) ▷{} D −−→H
(while σ do S end, E) ▷{} D −−→H (enter loop)
E ̸|= σ
(while σ do S end, E) ▷{} {} −−→{} (bypas loop)
(S, E) ▷H D −−→H′
H ̸= {}
H′ ̸= {}
(while σ do S end, E) ▷H D −−→H′ (start loop)
H ̸= {}
(S, E) ▷H D −−→{}
E |= σ
(S, E) ▷{} D′ −−−→H′
(while σ do S end, E) ▷H D ∪D′ −−−−−−→H′ (reenter loop)
H ̸= {}
(S, E) ▷H D −−→{}
E ̸|= σ
(while σ do S end, E) ▷H D −−→{} (exit loop)
这样得到的转换系统的节点用暂停集(即程序标签集的子集)标记。一个有 n 个暂停语句的程序在转换系统中最多有 2n 个可达状态,这保证了 SOS 规则的递归总是会终止。
6. 实现中的技术问题及解决方法
在 HOL 中使用暂停集编码的 SOS 规则来定义 Quartz 的语义时,存在一个问题。现有的嵌入不使用元变量,Quartz 程序中的事件、状态变量、位置变量和其他表达式直接取自 HOL,这使得暂停语句的标签是 HOL 类型为
N → B
的匿名函数。如果两个不同暂停语句的标签在同一时间点都处于活动状态,就无法区分它们。
为了解决这个问题,我们通过简单的从左到右遍历程序,为每个暂停语句分配一个唯一的编号(索引)。暂停集现在由相应的索引组成,而不是匿名标签。在从一个子语句转移到另一个子语句时,可能需要对相应的索引集进行加减偏移操作。为了方便,我们还使用列表而不是集合来表示索引,这样可以使用简单的列表长度归纳法。
以下是一些使用的缩写:
-
H ↑p:= MAP (λx.x + p) H
-
H ↓p:= MAP (λx.x − p) H
-
H |b a:= FILTER (λx.a ≤ x ∧ x ≤ b) H
程序中的变量和数据表达式仍然取自 HOL,类型为 α 的数据表达式是 HOL 类型为
N → α
的项,因此不需要显式考虑环境 E,而是用时间点 t 来代替。例如,
E |= σ
被替换为
σ(t)
。
我们还定义了一些重要的函数和谓词:
-
NP(P)
:程序 P 中暂停语句的数量。
-
InHS(H, P)
:当且仅当暂停集 H 包含对应于程序 P 中暂停语句的索引时成立。
-
NextHS(H, t, P)
:表示 SOS 规则的控制流部分,通过对语句集的原始递归定义:
– NextHS(H, t, nothing) = []
– NextHS(H, t, emit x) = []
– NextHS(H, t, emit next(x)) = []
– NextHS(H, t, y := τ) = []
– NextHS(H, t, y := next(τ)) = []
– NextHS(H, t, ℓ: pause) = if MEM(1, H) then [] else [1]
– NextHS(H, t, if σ then P else Q end) = ...
– NextHS(H, t, P; Q) = ...
– NextHS(H, t, P ∥Q) = ...
– NextHS(H, t, do P while σ) = ...
– NextHS(H, t, [weak] suspend P when σ) = ...
– NextHS(H, t, [weak] abort P when σ) = ...
– NextHS(H, t, now σ) = []
– NextHS(H, t, during P holds σ) = NextHS(H, t, P)
NextHS(H, t, S)
是 HOL 中暂停集编码的 SOS 规则定义的一部分,它反映了 SOS 语义的控制流部分。添加数据部分(即要执行的动作集 D)相对简单。并且,
NextHS(H, t, S)
是根据当前暂停集和变量值确定性计算的,这显示了控制流的确定性。
通过以下定义将暂停集转换为控制流条件:
HSLoc(H, P, t) := ∧ ℓ∈H∩labels(P ) ℓ(t) ∧ ∧ ℓ∈labels(P )\H ¬ℓ(t)
只有 1 到
NP(P)
之间的索引对
HSLoc(H, P, t)
是相关的,
NextHS(H, t, P)
也只依赖于 H 的相关索引。
为了建立语义之间的等价性,还需要一些其他属性。例如,
DisjointHS(H, S)
表示暂停集 H 不包含条件语句或序列语句的直接子语句的索引,因为控制流不可能同时处于条件语句或序列语句的两个子语句中。我们证明了这个属性是 SOS 规则的不变量。
NoInstantLoop(S)
表示 S 不包含具有即时体的循环。
基于这些定义,我们证明了以下定理:
-
定理 1(控制流谓词的正确性)
:对于 Quartz 语句 S,以下事实成立:
1.
inst (S) (t) ⇔ (NextHS([], t, S) = [])
:一个语句在时间点 t 执行时间为零(即时执行)当且仅当从空暂停集开始的 SOS 规则得到的下一个暂停集为空。
2.
¬inst (S) (t) ⊢ (enter (S) (t) ⇔ HSLoc(NextHS([], t, S), S, t + 1))
:进入谓词涵盖了从空暂停集可达的非空暂停集。
3.
NoInstantLoop(S),
DisjointHS(H, S),
HSLoc(H, S, t)
⊢ term (S) (t) ⇔ InHS(H, S) ∧ (NextHS(H, t, S) = [])
NoInstantLoop(S),
DisjointHS(H, S),
HSLoc(H, S, t)
⊢ move (S) (t) ⇔
InHS(H, S) ∧
InHS(NextHS(H, t, S), S) ∧
HSLoc(NextHS(H, t, S), S, t + 1)
这些定理证明了控制流谓词定义的正确性,为微步和宏步语义的等价性证明提供了重要依据。通过以上的方法和证明,我们在解决语义定义和实现问题的同时,也为进一步的研究和应用奠定了基础。
微步和宏步语义等价性证明(续)
6. 实现中的技术问题及解决方法(续)
我们已经了解到通过为暂停语句分配唯一索引、使用列表表示索引集以及定义相关函数和谓词等方法来解决在 HOL 中使用暂停集编码的 SOS 规则定义 Quartz 语义时遇到的问题。接下来,我们更深入地探讨这些定义和定理的意义及作用。
下面通过一个表格来总结之前定义的重要函数和谓词:
| 函数/谓词 | 含义 |
| ---- | ---- |
|
NP(P)
| 程序 P 中暂停语句的数量 |
|
InHS(H, P)
| 暂停集 H 包含对应程序 P 中暂停语句的索引时成立 |
|
NextHS(H, t, P)
| SOS 规则的控制流部分,根据当前暂停集和时间计算下一个暂停集 |
|
HSLoc(H, P, t)
| 将暂停集转换为控制流条件 |
|
DisjointHS(H, S)
| 暂停集 H 不包含条件或序列子语句的索引,是 SOS 规则的不变量 |
|
NoInstantLoop(S)
| 语句 S 不包含具有即时体的循环 |
这些函数和谓词相互协作,共同构建了一个完整的语义体系。例如,
NextHS(H, t, P)
用于确定控制流的转移,而
HSLoc(H, P, t)
则将暂停集信息转换为更直观的控制流条件。
为了更清晰地展示控制流的转移过程,我们再给出一个 mermaid 流程图,描述
NextHS(H, t, P)
在不同语句类型下的计算流程:
graph TD;
A[开始] --> B{语句类型};
B -- nothing --> C[NextHS = []];
B -- emit x --> C;
B -- emit next(x) --> C;
B -- y := τ --> C;
B -- y := next(τ) --> C;
B -- ℓ: pause --> D{MEM(1, H)?};
D -- 是 --> C;
D -- 否 --> E[NextHS = [1]];
B -- if σ then P else Q end --> F[复杂计算];
B -- P; Q --> F;
B -- P ∥Q --> F;
B -- do P while σ --> F;
B -- [weak] suspend P when σ --> F;
B -- [weak] abort P when σ --> F;
B -- now σ --> C;
B -- during P holds σ --> G[NextHS = NextHS(H, t, P)];
C --> H[结束];
E --> H;
F --> H;
G --> H;
7. 语义等价性的深入分析
我们已经证明了控制流谓词的正确性定理,这些定理是微步和宏步语义等价性证明的关键。下面我们对这些定理进行更深入的分析。
-
inst (S) (t) ⇔ (NextHS([], t, S) = []):这个定理表明了即时执行和暂停集的关系。如果一个语句在时间点 t 是即时执行的,那么从空暂停集开始,经过 SOS 规则计算得到的下一个暂停集为空。反之,如果下一个暂停集为空,那么该语句在这个时间点是即时执行的。这为判断语句是否即时执行提供了一个明确的方法。 -
¬inst (S) (t) ⊢ (enter (S) (t) ⇔ HSLoc(NextHS([], t, S), S, t + 1)):当语句不是即时执行时,进入谓词和控制流条件之间存在等价关系。进入谓词描述了控制流进入语句的条件,而通过NextHS计算得到的暂停集转换为控制流条件后,可以准确地判断进入的情况。 -
NoInstantLoop(S), DisjointHS(H, S), HSLoc(H, S, t) ⊢ term (S) (t) ⇔ InHS(H, S) ∧ (NextHS(H, t, S) = []):在满足无即时循环、暂停集不冲突和控制流条件的前提下,终止谓词和暂停集信息相关。当控制流在语句内部且下一个暂停集为空时,语句终止。 -
NoInstantLoop(S), DisjointHS(H, S), HSLoc(H, S, t) ⊢ move (S) (t) ⇔ (InHS(H, S) ∧ InHS(NextHS(H, t, S), S) ∧ HSLoc(NextHS(H, t, S), S, t + 1)):同样在特定条件下,内部移动谓词和控制流的转移情况相关。只有当控制流在语句内部,且下一个暂停集也在语句内部,并且满足相应的控制流条件时,才会发生内部移动。
这些定理的证明,使得我们能够从不同的角度来理解和描述程序的语义。无论是从控制流谓词的角度,还是从暂停集编码的 SOS 规则的角度,都能得到一致的结果,从而证明了微步和宏步语义的等价性。
8. 总结与展望
通过对暂停和中止变体、不同语义定义(基于控制流谓词、硬件电路、进程代数规则)、SOS 规则的问题及解决方法(暂停集编码)以及相关函数和谓词的研究,我们建立了一个完整的语义体系,并证明了微步和宏步语义的等价性。
这个语义体系的建立具有重要的意义。在硬件设计方面,基于硬件电路的语义可以直接将同步程序转换为硬件电路,为硬件实现提供了理论支持。在软件实现方面,通过模拟硬件电路的方式,可以生成相应的软件。而暂停集编码的 SOS 规则解决了传统 SOS 规则在递归定义和语言嵌入方面的问题,使得语义定义更加清晰和可操作。
未来,我们可以基于这个语义体系进行更多的研究。例如,进一步优化语义的实现,提高计算效率;探索更多的应用场景,将这种语义体系应用到更复杂的系统中;还可以研究如何将这种语义体系与其他编程语言或系统进行集成,实现更广泛的功能。
总之,微步和宏步语义等价性的证明为编程语义的研究和应用打开了新的局面,为后续的工作奠定了坚实的基础。
微步与宏步语义等价性证明研究
超级会员免费看
23

被折叠的 条评论
为什么被折叠?



