Jira 自动化语言编码双计数器机器:实现加法与斐波那契数列运算,具备图灵完备性
尼古拉斯·塞里奥(Nicolas Seriot)
[计算]> Jira 具备图灵完备性
工程界一直有传闻称,[Jira](https://www.atlassian.com/software/jira)(Atlassian 的项目跟踪工具)具有 [图灵完备性](https://esolangs.org/wiki/Turing-complete)。不过,现有的说法只是模糊地指向自动化功能,却没有给出具体的归约证明。本文将提供证明,并附上设置说明和执行跟踪记录。
映射计算模型
[明斯基寄存器机](https://esolangs.org/wiki/Minsky_machine) 仅需两个无界计数器和一组有限的带标签指令,即 `INC r; goto S` 和 `DEC r; if r == 0 goto S else goto S'`。通俗来讲,就是“将寄存器 R 加 1,然后跳转到状态 S”以及“将寄存器 R 减 1,如果 R 等于 0 则跳转到零状态 S,否则跳转到非零状态 S'”。
一个将寄存器 A 的值加到寄存器 B 的明斯基程序如下:
1. DEC A; if A == 0 goto 3 else goto 2
2. INC B; goto 1
3. HALT
1967 年,[明斯基](https://en.wikipedia.org/wiki/Marvin_Minsky) 证明了这个模型具有图灵完备性。所以,在 Jira 的自动化语言中实现该模型就能完成归约证明。以下是该模型在 Jira 中的映射方式:
| 明斯基机 | Jira |
| 寄存器 A | 类型为 **Bug** 的关联问题数量 |
| 寄存器 B | 类型为 **Task** 的关联问题数量 |
| 程序计数器 | 单个 **Epic** 问题的状态 |
| 调度表 | Jira 自动化规则,每个指令状态对应一条规则 |
| 时钟 | 自动化触发的状态转换,或超过链式上限后的外部重新触发 |
Epic 的状态编码了当前指令。[自动化规则](https://support.atlassian.com/cloud-automation/docs/create-and-edit-jira-automation-rules/) 会检查关联问题的数量,并决定下一个状态。`INC` 和 `DEC` 操作通过创建和删除相应类型的关联问题来实现。条件分支则通过 [JQL 条件规则](https://support.atlassian.com/cloud-automation/docs/jira-automation-conditions/) 来实现。
实现加法运算
下面是一个使用一个 Epic、五个关联问题以及每个指令状态对应一条自动化规则(空间设置 > 自动化)的最小可行实现。
- 创建工作流:创建一个 Jira 工作流,包含初始状态 `BACKLOG`,以及 `TODO`、`DEV` 和 `PROD` 状态,且任何状态都可以转换到其他状态。同时,创建一个状态为 `BACKLOG` 的 Epic。
- 创建 `TODO` 状态的规则:`DEC A; if A=0 halt, else goto DEV.` 触发条件为 Epic 状态变为 `TODO`。若至少存在一个关联的 Bug,则删除一个 Bug,将 Epic 状态转换为 `DEV`;否则,将 Epic 状态转换为 `PROD`(停止)。
- 创建 `DEV` 状态的规则:`INC B; goto TODO.` 触发条件为 Epic 状态变为 `DEV`。创建一个新的 Task,并将其关联到 Epic,然后将 Epic 状态转换为 `TODO`。这两条规则都启用了 _"允许规则触发其他规则"_。
下面的截图展示了这两条规则与 Epic 工作流的关联。
- 初始化寄存器:将 2 个 Bug(A = 2)和 3 个 Task(B = 3)关联到 Epic。
- 启动机器:将 Epic 状态转换为 `TODO` 以启动级联操作。经过五次状态转换:
(2,3) TODO →
(1,3) DEV →
(1,4) TODO →
(0,4) DEV →
(0,5) TODO →
(0,5) PROD_记录于真实的 `*.atlassian.net` 实例。_
最终,Epic 处于 `PROD` 状态,关联 0 个 Bug 和 5 个 Task,成功实现了 2 + 3 = 5 的加法运算。
三状态实现斐波那契数列
上述归约足以证明 Jira 具有图灵完备性。此外,Jira 的自动化语言还能简化明斯基机的操作。“转换问题类型”可以立即更改问题的类型,例如 Bug 转换为 Story,Story 转换为 Task 等。
`CONVERT` 操作可表示为 `DEC` + `INC`,它虽未扩展 Jira 的计算能力,但能显著缩小任何移动循环的调度表,使非平凡程序更易于处理。
斐波那契数列 `(A, B) → (B, A+B)` 可通过三个状态和三个寄存器(A = Bug,B = Task,C = Story)来实现,使用 `TODO`、`QA`(添加到工作流中)和 `DEV` 作为三个指令状态:
TODO:
if any linked Task exists:
CONVERT Task → Story
INC Bug
transition to TODO
else:
transition to QA
QA:
if any linked Bug exists:
CONVERT Bug → Task
transition to QA
else:
transition to DEV
DEV:
if any linked Story exists:
CONVERT Story → Bug
transition to DEV
else:
transition to TODO初始状态为 A = 1,B = 1,C = 0。斐波那契数列 1, 1, 2, 3, 5, 8, 13, … 会在 B(Task 数量)中出现。
与加法运算机器不同,斐波那契数列机器没有停止状态,它会一直运行,直到达到 Jira Cloud 的链式深度上限(10 次触发),此时操作人员可以重新触发 Epic 以继续运行,只需编辑一次状态即可重新启动级联操作。归约证明仍然成立,只不过需要人工提供下一个时钟信号。Jira Data Center 通过 `automation.rule.execution.timeout` 及相关可配置属性提供了相同的功能。
结论
在无限制的问题创建和规则执行条件下,Jira 的自动化语言可以编码一个双计数器机器。由于所有物理计算机都是有限的,Jira Cloud 的有限配额并不影响这个构造的有效性。按照标准惯例,Jira 具备图灵完备性。
所以,如果复杂的 Jira 自动化操作感觉像是程序,那是因为它们确实就是程序。
