是的,有一些方法可以做到这一点。几个月前,我做了一个小实验项目来做类似的事情,考虑到它在做什么,它的效果相当好。你给它一个类型和一些要通过的测试,它会搜索一个合适的函数来通过测试。我从来没有投入让它成熟的工作,但你可以看到它确实最终生成了在示例的情况下通过测试的函数。要求类型是该搜索实用性的重要组成部分——它大大减少了需要尝试的程序数量。
在断言什么是可能的和不可能的之前,牢牢掌握这里的理论是很重要的——有很多人会跳到停顿的问题上,告诉你这是不可能的,而事实却更加微妙比起那个来说。
- 您可以轻松地以给定语言生成所有语法有效的程序。天真地,您可以生成所有字符串并过滤掉解析/类型检查的字符串;但有更好的方法。
- 如果语言不完整——例如简单类型的 lambda 演算,或者甚至像 Agda 这样非常强大的东西,你可以枚举所有生成 42 的程序,并且给定任何程序,你可以决定“这会生成 42”或“这确实不生成 42"。(我在实验项目中使用的语言就是这个类)。这里的紧张之处在于,在任何这样的语言中,都会有一些你无法编写的可计算函数。
- 即使语言已经完成,您仍然可以枚举最终生成 42 的所有程序(通过并行运行它们来做到这一点,并在它们完成时报告成功)。
对于图灵完备的语言,你不能做的是确定一个程序绝对不会生成 42——它可能会一直尝试运行,并且在它生成之前你无法判断它是否最终会成功。但是,有些程序可以说会无限循环,但不是全部。因此,如果您有一个程序表,您可能希望在非图灵完备语言的情况下您的枚举器程序是这样的:
Program | P1 | P2 | P3 | P4 | P5 | P6 | P7 | ...
42? | No | No | No | Yes | No | No | No | ...
而在图灵完备的语言中,您的输出(在给定时间)将是这样的:
Program | P1 | P2 | P3 | P4 | P5 | P6 | P7 | ...
42? | No | No | Loop | Yes | No | Dunno | No | ...
后来,“不知道”可能会变成“是”或“否”,或者它可能永远不知道——你只是不知道。
这都是非常理论化的,实际上用图灵完备的语言生成程序来搜索做某件事的程序非常困难并且需要很长时间。当然你也不想一件一件的去做,因为空间太大了;您可能想使用遗传搜索算法或其他东西。
理论中的另一个微妙点:谈论“生成 42”的程序缺少一些重要的细节。通常当我们谈论生成程序时,我们希望它生成某种功能,而不仅仅是输出特定的东西。这是你可能想做的事情变得更加不可能的时候。如果您有无限的可能输入空间——比如说,输入一个数字,那么
- 您通常无法判断程序是否计算给定函数。您无法手动检查每个输入,因为无穷大无法检查。您无法搜索您的函数做正确事情的证据,因为对于任何可计算函数f,对于任何公理系统A,都有计算f的程序,因此A没有证据证明它们计算f。
- 你无法判断一个程序是否会对每个可能的输入给出任何类型的答案。它可能对前 400,000,000 个有效,但在第 400,000,001 个无限循环。
- 同样,您无法判断两个程序是否计算相同的函数(即相同的输入-> 相同的输出)。
你有它,每日剂量的可判定性理论现象学。
如果您有兴趣真正做到这一点,请研究遗传算法,并在您尝试的功能上设置超时和/或使用可判定(非图灵完备)语言。