如何编写所有可计算函数的枚举?

时间:2009-11-25 14:54:31

标签: language-agnostic math functional-programming theory computation-theory

动机:我希望能够在没有一阶函数的语言中使用玩具函数式编程,使用自然数而不是函数。

通用函数是函数f:N - > (N - > N),等价于f:N * N - > N枚举所有可能的可计算函数。换句话说,有一个数字k使得f(k)是平方函数,有一个数字j使得f(j)是第n个素数函数等。

要编写这样的函数,可以使用任何图灵完备语言(编程语言编译器,lambda演算,图灵机..​​....)并枚举所有程序。我不仅要考虑评估,还要考虑添加,构图,曲线等功能。例如,给定两个函数f的指数,g我想知道函数f + g的索引是什么,或者f由g组成。这将允许“玩具功能编程”。

编写此类代码库的好方法是什么?我不是在寻找一个极简主义的Turing tarpit,它很难计算10的阶乘,也不想编写高级编译器。它应该有一些基本的功能,如添加和写循环的可能性,但不多。

欢迎使用所有高级语言的解决方案。 Pseudocode,Haskell和Python是首选。您可以假设任意精度算术。

澄清:枚举函数将包含所有partial recursive (computable)个函数 - 这包括不停止某些输入的函数。在这种情况下,通用功能将悬而未决;当然这是不可避免的。另请参见:m-递归函数 - http://en.wikipedia.org/wiki/Μ-recursive_function

7 个答案:

答案 0 :(得分:9)

你想要的是一名翻译。

首先,任何具有所需属性的枚举都不适合您想要在前2 ^ 32或前2 ^ 64整数中操作的有趣函数。所以你需要更大的整数,在内存中分配并通过指针引用。

为什么不在任何现有语法中使用代表程序的字符数组(字符串)呢? 将这样的字符串视为整数,如果这让你开心的话。计算f1()+f2()的函数的数量是由(f1的表示),“+”和(f2的表示)构成的字符串。你明白了......

这种方法没有的是函数表示的唯一性,这可能隐含在你的问题中(我不确定)。我可以肯定的是,表示的单一性与在函数表示上进行简单甚至可计算的组合操作是不相容的 - 例如,如果不是这种情况,就会有一个简单的解决Halting问题的方法。 p>

答案 1 :(得分:1)

虽然用某种语言枚举所有可能的表达式并不太难,但您无法将这些限制在那些表示终止函数的表达式中。 / p>

但是如果你对终止不感兴趣,那么使用组合器(有一些算术原语用于实用)可能是最好的方法,因为你避免以这种方式引入变量名。

答案 2 :(得分:1)

正如Pascal所说,你想要的是一个翻译,但是你可以做得更好:直接使用处理器作为翻译。

将数字N(例如,作为一些大的int数组)直接输入缓冲区并将此缓冲区作为machinecode执行。

对于计算机能够执行的每个可能的功能,存在N.不幸的是。并非每个N都是有效的程序(这不是请求)或终止程序(这是不可能的)。

另一方面,此功能将产生诸如魔兽世界,包括Service Pack 6和Windows 9的Microsoft Office 17之类的宝石。

答案 3 :(得分:0)

不是一个简单的问题。我想你必须从函数发生器开始,它能够逐个生成所有函数。这将导致枚举。

因为你必须处理多个无穷无尽的维度......让我们考虑一下。

让我们将问题减少到具有n个参数的函数和基本操作+, - ,*,/。
让我们只用一个操作构建所有函数:

a + a
a + b
a - a
a - b
a * a
a * b
a / a
a / b

我想很容易看出其中一些函数更有意义,因为其他函数可能相等,但至少它是一个可以通过循环生成的映射。

现在在下一次迭代中,可以轻松添加到这些函数中的每一个

  • 所有操作中已存在的参数之一
  • 包含所有操作的第三个参数

之后你有一个很大的功能列表,你可以重复第二步。

因为这是一个估计所有更复杂函数的函数,比如sin和log(泰勒系列),所以这些函数空间也应该包含这些函数。

这有帮助吗?随意编辑这篇文章!

重新阅读你的帖子。如果你想枚举所有程序功能而不只是数字一次,我想它会更复杂。我想通过压缩函数源并将zip文件视为一个大数字来处理映射“function< - > number”是有意义的。反过来说,你可以尝试解压缩任何数字,看看它是否创建了一个有用的功能:-)但我猜你会有很多甚至不是zip文件的数字。

但它会满足你的要求,即每个函数都有一个代表它的数字: - )

答案 4 :(得分:0)

您可以使用任何编程语言,以便确定某个程序是否是程序,并按字典顺序列出所有程序。为了避免至少一点组合爆炸,您可以以标准化形式分配用户定义的名称(变量,函数等)。显然,这会产生大量的功能,而且要找出哪些功能实际上并不容易。任何自动修剪方法都会排除你实际想要的某些功能,或者无法将组合爆炸修剪得足够有用,或两者兼而有之。

另一个缺点是从数字到函数很难:找到一个更好的查找函数433,457,175,432,167,463的方法比列举大约四百万亿个函数更难。

另一种方法是通过将符号映射到数字来将函数编码为数字,并有效地连接它们。

假设符号是+, - ,:=,==,<,if,then,endif,do,end_do_condition,enddo和语句分隔符。这是11个符号,没有变量,对于一个非常小的集合,不包括函数调用之类的东西,并且要求你自己繁殖和除法。 (我不确定这会在没有逻辑运算符的情况下工作。)添加五个变量名,并且你有一个带有4位字符的编程语言。这意味着最多16个字符将适合64位无符号整数。

一旦你得到了这个,函数之间的所有可能的关系都可以表示为算术关系,但是一个非常复杂的关系在实践中变得非常复杂。

简而言之,虽然这在理论上是可行的,但在实践中它会非常笨拙。用你选择的非功能语言为函数式语言编写解释器可能会更容易。

答案 5 :(得分:0)

  

要编写这样的功能,可以采取   任何图灵完整的语言   (编程语言编译器,lambda   微积分,图灵机..​​....)和   枚举所有程序

我不太确定这是否可以完成......感觉它违背了图灵教会的论点。为了枚举所有程序,首先你需要一个算法来确定哪些程序是有效的,哪些程序不是,这是不可能的......除非你不关心它并允许用你的语言编写错误的程序。

但也许正式系统的Godelization可以帮助你...我会尝试使用Lisp,因为数据代码可以提供很多帮助。

答案 6 :(得分:0)

不确定我理解。但有一件事 - 你无法枚举所有可能的可计算函数。简短的回答:因为否则会有一个通用的杀毒软件。答案很长:因为如果有这样的枚举,你在该集合中也会有计算枚举本身的函数。就像罗素的悖论一样。

你问题的另一个答案是 - 你想要“列出”所有可能的可计算函数;为此,您可能希望将它们表示为素数,并将它们的组合用作乘法。这将保证唯一性。分解将为您提供相反的功能。