我用MATLAB 脚本语言编写了一个简单的脑筋急转弯解释器。它被提供随机 bf 程序来执行(作为遗传算法项目的一部分)。我面临的问题是,程序在相当多的情况下都会出现无限循环,因此 GA 会卡在这一点上。
因此,我需要一种机制来检测无限循环并避免在 bf 中执行该代码。
一个明显的(微不足道的)案例是当我有
[]
我可以检测到这一点并拒绝运行该程序。
对于非平凡的情况,我发现基本思想是:确定循环的一次迭代如何改变当前单元格。如果变化是负的,我们最终会达到 0,所以这是一个有限循环。否则,如果更改为非负数,则为无限循环。
在单个循环的情况下实现这一点很容易,但是对于嵌套循环,它变得非常复杂。例如,(以下(1)指的是单元格1的内容等)
++++ Put 4 in 1st cell (1)
>+++ Put 3 in (2)
<[ While( (1) is non zero)
-- Decrease (1) by 2
>[ While( (2) is non zero)
- Decrement (2)
<+ Increment (1)
>]
(2) would be 0 at this point
+++ Increase (2) by 3 making (2) = 3
<] (1) was decreased by 2 and then increased by 3, so net effect is increment
因此代码不断运行。然而,在单元格 1 上对 + 和 - 的数量进行简单检查会说 - 的数量更多,因此不会检测到无限循环。
给定 bf 中任意数量的循环的任意嵌套,谁能想到一个检测无限循环的好算法?
编辑:我确实知道停止问题通常是无法解决的,但我不确定是否不存在特殊情况例外。就像,也许 Matlab 可以充当超级图灵机,能够确定 bf 程序的停止。我可能大错特错,但如果是这样,我想确切地知道如何以及为什么。
第二次编辑:我写了我声称的无限循环检测器。它可能会遗漏一些边缘情况(或者不太可能,以某种方式逃脱图灵先生的魔掌),但到目前为止似乎对我有用。以伪代码形式,这里是:
subroutine bfexec(bfprogram)
begin
Looping through the bfprogram,
If(current character is '[')
Find the corresponding ']'
Store the code between the two brackets in, say, 'subprog'
Save the value of the current cell in oldval
Call bfexec recursively with subprog
Save the value of the current cell in newval
If(newval >= oldval)
Raise an 'infinite loop' error and exit
EndIf
/* Do other character's processings */
EndIf
EndLoop
end