19、并发 Ada 程序的自动验证与时间 Petri 网转换

并发 Ada 程序的自动验证与时间 Petri 网转换

1. 引言

在软件开发中,并发程序的验证是一项极具挑战性的任务。对于并发 Ada 程序而言,其固有的复杂性使得验证工作变得尤为困难。为了应对这一挑战,我们采用高级 Petri 网来进行建模和分析,它不仅具有强大的建模能力,还拥有丰富的理论和实践工具。同时,将时间 Petri 网结构转换为 Ada 95 语句,有助于实现实时系统的代码生成,提高开发效率和可靠性。

2. 并发 Ada 程序的验证流程
2.1 简化步骤

在初始化过程中,会将所有可能阻塞的代码(如入口调用、受保护调用和接受语句)以及可能不终止的代码(如某些循环和递归代码调用)压入栈中。每次迭代时,对节点 x 的分析可能会将节点 y 压入栈。节点 y 被压入的情况如下:
- 当 y 是 x 的父节点时;
- 当 y 对 x 是必要的(例如 x 使用了在 y 中声明的变量);
- 当 y 修改了 x 中使用的变量(例如在保护条件中使用的变量);
- 当 y 修改了 x 中的控制流(例如 y 是返回语句);
- 当 y 创建了包含类型为 x 的任务的变量时;
- 当 y 是对 x 的调用时。

栈为空时,那些对应于身份号码计算且从未被压入的节点可以被移除。不过,该算法可能会保留一些程序的不必要部分,因为有时无法确定一个节点是否必须保留(某些问题是不可判定的,如终止问题)。为避免移除有用部分,存疑时会假设节点必须保留。

2.2 翻译步骤

翻译步骤类似于编译器中的代码生成步骤,但生成的是 Petri 网而非汇编代码。算法由有限数量的规则定义,每个 Ada 构造(表达式、语句、过程等)都有一条规则。

  • 任务令牌 :Ada 代码由 Petri 网表示,其执行由任务令牌(每个任务一个)在网中的移动来体现。简单语句被转换为转换,其执行对应于这些转换的触发。任务令牌携带任务的身份和该任务在给定时间可以访问的局部变量。例如,在任务体中,令牌包含该任务的局部变量;在过程中,包含过程的局部变量和参数(任务的局部变量在过程中不可访问)。调用时,令牌会被复制,一份留在调用者处,包含调用者的局部变量,另一份移动到被调用者处,包含被调用者的局部变量。
  • 数据令牌 :共享数据(受保护或不受保护)由数据令牌表示。与任务令牌不同,这些令牌不与特定任务关联,也不移动,仅表示共享变量的当前值。
  • 任务入口 :任务入口 e 被转换为三个位置。e.queue 模拟该入口的队列,包含等待在此入口进行会合的任务的令牌;e.count 模拟该入口的计数属性(即 e.queue 中的令牌数量);e.return 包含对应于已完成调用的令牌。调用者必须原子地将带有实际参数的令牌存入 e.queue 并增加 e.count,然后在 e.return 中等待结果。被调用者在接受时从 e.queue 中取出令牌时必须减少 e.count。
  • 受保护对象 :每个受保护对象使用两个位置来确保其互斥属性。它们包含匿名令牌,分别作为读锁和写锁。读锁位置为每个执行受保护函数的任务包含一个令牌;写锁位置仅当一个任务正在执行受保护过程或入口时包含一个令牌。进入受保护函数时,写锁位置必须为空;进入受保护过程或入口时,两个位置都必须为空。使用抑制弧来确保这一点。

以下是一个简单的流程图展示翻译步骤:

graph TD;
    A[Ada 代码] --> B[翻译为 Petri 网];
    B --> C[任务令牌移动];
    B --> D[数据令牌表示共享数据];
    B --> E[任务入口转换];
    B --> F[受保护对象处理];
2.3 验证步骤

通过翻译步骤获得的有色 Petri 网可以使用与 Petri 网验证相关的经典技术进行分析。在原型中,主要验证死锁的不存在和公平性,并正在开发接口以获取用时态逻辑表达的属性。为应对可达标记集的复杂性问题,结合了两种验证技术:
- 缩减技术 :将网转换为更小但等效的网。可应用的缩减取决于用户要检查的属性。在原型中已实现了主要的缩减。
- 可达性图分析 :直接分析可达性图,或使用顽固集或睡眠集技术,通过部分顺序状态空间缩减来解决状态空间爆炸问题。原型通过与 prod 工具的接口使用这些技术。

这两种技术是互补的。缩减技术利用网的局部结构将其转换为更小的网,可显著减小网的规模,但产生的新网仍需分析;可达性图分析在模型较小时对验证一般属性非常有效,但在大型模型上使用时,即使有高级优化,图的规模仍然很大。先使用缩减技术,再进行可达性图分析,能够对大型模型验证一般属性。

以著名的就餐哲学家问题为例:
- 未使用缩减技术时,5 个哲学家的可达性图有 6874 个节点和 30120 条弧。使用睡眠集和顽固集技术后,规模限制为 126 个节点和 152 条箭头。
- 先使用结构缩减技术后,可达性图变为 32 个节点和 120 条弧。再使用睡眠集和顽固集技术,规模进一步缩减到 22 个节点和 48 条箭头。

3. 示例:就餐哲学家问题

以下是一个就餐哲学家问题的 Ada 并发程序示例:

with Common; -- some basic definitions
use Common;

procedure Main is
    type Id is mod 5;
    type Tforks is array (Id) of boolean;

    protected type resource_server is
        entry Get1 (Id);
        entry Get2 (Id);
        procedure Release (x : in Id);
    private
        Resource:Tforks:=(others=>true);
    end;

    protected type number_server is
        procedure get (x : out Id);
    private
        num : Id := 0;
    end;

    task type philo;
    type Tphilo is array (Id) of philo;

    Server : resource_server;
    Number : number_server;
    Philos : Tphilo;

protected body number_server is
    procedure get (x : out Id) is
    begin
        x := num; num := num + 1;
    end;
end;

protected body resource_server is
    entry Get1(for X in Id) when Resource(x) is
    begin
        Resource(x) := false;
    end;
    entry Get2(for X in Id) when Resource(X+1) is
    begin
        Resource(X+1) := false;
    end;
    procedure Release(X : in Id) is
    begin
        Resource(x) := true; Resource(x+1) := true;
    end;
end;

task body philo is
    ego : Id;
begin
    number.get(ego);
    loop
        put_id(ego); Put_String("is thinking");
        Server.Get1(ego);
        Server.Get2(ego);
        put_id(ego);Put_String("is eating");
        Server.Release(ego);
    end loop;
end;

begin -- of procedure Main
    null;
end;

简化步骤后,除所有 Put 指令被移除,程序基本相同。翻译步骤生成的高级网由 54 个位置和 45 个转换组成(9 个位置和 5 个转换因未使用而在清理步骤中被抑制)。

为检测死锁,对网应用结构缩减,可合并 17 个转换(所有缩减实现后,还能自动合并 17 个转换)。缩减后的网(由 37 个位置和 28 个转换组成)被转移到 prod 工具,使用“即时”选项(一旦发现死锁就停止图的构建),几秒内就能找到死锁。工具产生的结果显示了死锁发生的状态:

Server_RW207: <.0.>
Server_ResourceTT208: <.0,0.>+<.1,0.>+<.2,0.>+<.3,0.>+<.4,0.>
Server_Get1_count212: <.0.>
Server_Get2_count223: <.5.>
Server_Get2_queue225: <.1,4.>+<.2,3.>+<.3,2.>+<.4,1.>+<.5,0.>
PhilosTT_wait355: <.0,5,0.>+<.1,4,1.>+<.2,3,2.>+<.3,2,3.>+<.4,1,4.>

在该状态下,所有 Philos 任务都在调用受保护对象 Server 的入口 Get2,入口 Get2 的变量计数为 5,没有可用资源,所有哲学家都在等待 Get2 调用的返回。

4. 时间 Petri 网结构转换为 Ada 95 语句
4.1 转换目的

将用时间 Petri 网建模的实时系统实现为 Ada 95 语句,旨在利用 Ada 95 的任务和实时特性,实现实时系统的代码生成。

4.2 转换方法

使用 Ada 95 任务语句的模型,通过缩减规则对语句模型进行缩减,使其在建模系统的网中可识别。这样可以构建 Ada 95 任务语句缩减模型的目录,用于将网结构转换为 Ada 程序。

4.3 转换意义

实时系统的设计、分析和实现复杂度高,尤其是考虑可靠性时。使用形式化方法和自动工具进行代码生成,不仅能减少编码错误,还能降低开发成本。时间 Petri 网适合建模实时系统,因为它能自然地模拟并发、资源共享、同步等。

5. 总结

通过上述方法,我们可以对并发 Ada 程序进行自动验证,并将时间 Petri 网结构转换为 Ada 95 语句,实现实时系统的代码生成。目前开发的工具能自动化验证的不同步骤(简化、翻译和分析),初步结果表明,未来有望验证现实的并发 Ada 程序。但为验证该方法,还需扩展工具接受的 Ada 语言子集,并完善验证技术的实现。

以下是一个总结表格:
|步骤|描述|
| ---- | ---- |
|简化步骤|压入可能阻塞和不终止的代码,移除不必要节点|
|翻译步骤|将 Ada 代码转换为 Petri 网,处理任务令牌、数据令牌、任务入口和受保护对象|
|验证步骤|结合缩减技术和可达性图分析,验证死锁和公平性|
|转换步骤|将时间 Petri 网结构转换为 Ada 95 语句,实现实时系统代码生成|

并发 Ada 程序的自动验证与时间 Petri 网转换(下半部分)

6. 关键技术点分析
6.1 简化步骤中的节点处理

在简化步骤中,节点的压入和移除规则是核心。对于可能阻塞和不终止的代码进行压入操作,这是为了确保后续分析的完整性。而节点的移除需要谨慎,因为有些问题(如终止问题)是不可判定的。以下是节点压入的具体规则表格:
|压入条件|说明|
| ---- | ---- |
|y 是 x 的父节点|节点的层级关系决定了父节点可能对其子节点有影响|
|y 对 x 是必要的|例如 x 使用了在 y 中声明的变量,y 的存在对 x 的执行至关重要|
|y 修改了 x 中使用的变量|如在保护条件中使用的变量被 y 修改,会影响 x 的执行|
|y 修改了 x 中的控制流|例如 y 是返回语句,会改变 x 的执行流程|
|y 创建了包含类型为 x 的任务的变量|这种情况下 y 与 x 有紧密的关联|
|y 是对 x 的调用|函数或过程的调用关系使得 y 对 x 的执行有直接影响|

6.2 翻译步骤中的元素对应

翻译步骤将 Ada 代码转换为 Petri 网,涉及多个元素的对应关系。任务令牌、数据令牌、任务入口和受保护对象的处理方式各有特点。下面是这些元素的对应关系表格:
|Ada 元素|Petri 网对应元素|说明|
| ---- | ---- | ---- |
|Ada 代码|Petri 网|整体的代码转换为网结构|
|简单语句|转换|语句的执行对应转换的触发|
|任务|任务令牌|携带任务身份和局部变量|
|共享数据|数据令牌|表示共享变量的当前值|
|任务入口|三个位置(e.queue、e.count、e.return)|模拟入口的队列、计数和返回情况|
|受保护对象|两个位置(读锁和写锁)|确保互斥属性|

6.3 验证步骤中的技术互补

验证步骤中,缩减技术和可达性图分析技术是互补的。缩减技术可以减小网的规模,但新网仍需分析;可达性图分析在小模型上对验证一般属性有效,但在大模型上存在规模问题。以下是这两种技术的对比表格:
|技术|优点|缺点|适用场景|
| ---- | ---- | ---- | ---- |
|缩减技术|显著减小网的规模,复杂度仅取决于网的弧数|产生的新网仍需分析|大型模型的初步处理|
|可达性图分析|对小模型验证一般属性非常有效|即使有优化,大模型的图规模仍然很大|小型模型的验证|

7. 实际应用案例分析 - 就餐哲学家问题

就餐哲学家问题是一个经典的并发问题,通过这个案例可以更直观地看到上述技术的应用效果。

7.1 未优化前的状态

未使用缩减技术时,5 个哲学家的可达性图有 6874 个节点和 30120 条弧。这表明在没有进行任何优化的情况下,图的规模非常大,分析起来会非常困难。

7.2 使用睡眠集和顽固集技术

使用睡眠集和顽固集技术后,规模限制为 126 个节点和 152 条箭头。这说明这些技术能够有效地减少状态空间,提高分析效率。

7.3 先使用结构缩减技术

先使用结构缩减技术后,可达性图变为 32 个节点和 120 条弧。再使用睡眠集和顽固集技术,规模进一步缩减到 22 个节点和 48 条箭头。这一系列的优化过程展示了不同技术结合使用的优势。

以下是就餐哲学家问题优化过程的流程图:

graph TD;
    A[未优化的可达性图] --> B[使用睡眠集和顽固集技术];
    A --> C[使用结构缩减技术];
    C --> D[再使用睡眠集和顽固集技术];
    B --> E[规模限制为 126 节点和 152 箭头];
    D --> F[规模缩减到 22 节点和 48 箭头];
8. 时间 Petri 网转换为 Ada 95 语句的操作流程

将时间 Petri 网结构转换为 Ada 95 语句,有明确的操作流程。

8.1 准备工作
  • 确定要建模的实时系统,明确其功能和需求。
  • 选择合适的时间 Petri 网模型来表示该系统。
8.2 模型缩减
  • 使用缩减规则对 Ada 95 任务语句的模型进行缩减。
  • 确保缩减后的模型在建模系统的网中可识别。
8.3 构建目录
  • 构建 Ada 95 任务语句缩减模型的目录。
  • 该目录用于后续将网结构转换为 Ada 程序。
8.4 转换操作
  • 根据目录,将时间 Petri 网的结构转换为 Ada 95 语句。
  • 检查转换后的代码,确保其符合 Ada 95 的语法和实时系统的需求。

以下是转换操作流程的表格:
|步骤|操作内容|
| ---- | ---- |
|准备工作|确定系统,选择时间 Petri 网模型|
|模型缩减|使用规则缩减任务语句模型|
|构建目录|构建缩减模型目录|
|转换操作|根据目录转换为 Ada 95 语句并检查|

9. 未来展望

虽然目前已经取得了一些成果,开发的工具能够自动化验证的不同步骤,但仍有一些工作需要进一步完善。

9.1 扩展 Ada 语言子集

需要扩展工具接受的 Ada 语言子集,以支持更多复杂的 Ada 程序验证。这样可以提高工具的通用性和实用性。

9.2 完善验证技术

进一步完善验证技术的实现,特别是对于一些复杂属性的验证。例如,目前主要验证死锁和公平性,未来可以扩展到更多时态逻辑表达的属性。

9.3 实现结果自动报告

实现将验证结果自动报告到 Ada 代码中的功能。目前结果还不能自动报告,通过命名约定和翻译步骤中的链接,有望实现这一功能,提高验证的效率和用户体验。

10. 总结与建议
10.1 总结

通过对并发 Ada 程序的自动验证和时间 Petri 网结构转换为 Ada 95 语句的研究,我们可以看到这些技术在实时系统开发中的重要性。简化、翻译、验证和转换步骤相互配合,能够有效地处理并发 Ada 程序,并实现实时系统的代码生成。

10.2 建议
  • 在实际应用中,优先使用缩减技术对模型进行初步处理,然后结合可达性图分析进行详细验证。
  • 对于时间 Petri 网转换为 Ada 95 语句,严格按照操作流程进行,确保转换的准确性。
  • 持续关注技术的发展,及时扩展工具的功能,以适应不断变化的需求。

通过以上的分析和总结,我们可以更好地掌握并发 Ada 程序的自动验证和时间 Petri 网转换的技术,为实时系统的开发提供有力支持。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值