Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 可以列举计算机程序吗?_Javascript_Algorithm_Language Agnostic_Genetic Programming - Fatal编程技术网

Javascript 可以列举计算机程序吗?

Javascript 可以列举计算机程序吗?,javascript,algorithm,language-agnostic,genetic-programming,Javascript,Algorithm,Language Agnostic,Genetic Programming,假设您必须编写一个程序来测试所有程序,以搜索完成特定任务的程序。例如,考虑这个JavaScript函数: function find_truth(){ for(n=0;;++n){ try { var fn = Function(string(n)); if (fn() == 42) return fn; } catch() { continue;

假设您必须编写一个程序来测试所有程序,以搜索完成特定任务的程序。例如,考虑这个JavaScript函数:

function find_truth(){
    for(n=0;;++n){
        try {
            var fn = Function(string(n));
            if (fn() == 42)
                return fn;
        } catch() {
            continue;
        }
    }
}

只要字符串(n)返回第n个可能的字符串(“a”、“b”、“c”、“aa”、“ab”),该程序最终将输出一个计算结果为
42
的函数。此方法的问题在于,它正在枚举可能是或不可能是有效程序的字符串。我的问题是:是否可以枚举程序本身?如何?

当然可以枚举给定语言中语法有效的所有程序(在静态类型语言中,甚至只有那些进行类型检查的程序):您可以简单地枚举您建议的所有字符串,尝试将每个字符串输入该语言的解析器,然后拒绝无法解析的字符串。所以如果这是你对一个有效程序的定义,那么是的,这是可能的

然而,您的程序不一定会输出一个最终返回42的函数,即使将
string
替换为只返回语法有效程序的函数也是如此。如果返回的函数包含无限循环,它将永远运行,因此您的程序将永远无法尝试其他函数。因此,您可能永远无法访问返回42的函数


为了避免这个问题,您可以说
string(n)
函数应该只生成语法上有效且不包含无限循环的代码(同时仍然能够返回所有这样的函数)。然而,这是不可能的,因为这需要决定停止问题(当然,这是不可判定的)。

这是不可能的。问题是有些程序可能需要很长时间才能完成计算。有些程序可能陷入无限循环。理想情况下,您希望中止运行那些陷入无限循环的程序,而只保留长时间运行的程序。您可以实现一个计时器,但是如果您有一个运行时间比计时器长的程序,但仍然会返回正确的答案,该怎么办

一般来说,判断一个计算机程序是否会终止的唯一方法是运行它并查看,这有可能进入一个无限循环。当然,您可以实现一些启发式方法来识别无限循环的常见形式,但一般来说这是不可能的。这就是我们所知道的

编辑:


我意识到我只是部分回答了你的问题。您询问是否可以枚举程序本身。这当然是可能的。您已经有了按顺序生成所有可能字符串的方法。然后,您可以看到哪些字符串作为javascript程序正确解析,并保留这些字符串。

如前所述,您可以轻松地将“生成所有字符串”程序转换为“生成X语言中的所有有效程序”通过插入语言X的解析器/编译器。通常,如果您可以编写一个程序,该程序将文本作为输入,并返回true/false,指示文本是否表示有效的程序,那么您可以将其用作“生成所有字符串”程序的过滤器

您还可以设计一种编程语言,其中每一个字符串都是一个有效的程序(我想到了perl)

可能更有趣的是,给定一种语言的形式语法,您可以使用它来生成该语言中的程序,而不是解析它们。您只需要对语法进行广度优先遍历,以确保每个有限长的程序都能在有限的时间内到达(如果您进行深度优先遍历,您将发现所有程序都只包含一个变量,该变量的名称是一个更长的“a”序列或其他内容)

不过,在解析编程语言时实际使用的大多数语法并不能直接用于此目的;他们通常有点过分放纵。例如,语法可以将标识符定义为与regex
[\u a-Za-z][0-9\u a-Za-z]*
匹配的任何东西,这允许使用长度无限的变量名,但许多语言实现实际上会阻塞具有千兆字节长变量名的程序。但原则上,您可以找出所有这些类型的gotchas,并编写一个枚举语法,该语法完全涵盖了某些感兴趣的语言中的所有有效程序


这样就可以枚举所有程序。这实际上不足以让您运行
find_truth
程序并找到返回
42
的程序,因为它会无限地计算第一个恰好包含无限循环的程序

但实际上还是有可能做到的!您只需要选择一个顺序来检查所有的可能性,以便最终在某个有限的时间内达到所有目标。你有两个无限的“维度”要搜索;所有程序的枚举,以及每个程序的评估深度。您可以通过执行以下策略来确保覆盖所有基础:

  • 运行所有长度不超过1的程序,最多运行1步
  • 运行所有长度不超过2的程序,最多运行2个步骤
  • 运行所有长度不超过3的程序,最多运行3个步骤
  • 等等。这保证了无论程序的长度和所需的“步骤”数量是多少,您最终都会命中它们,而无需“首先”完成无限量的工作(只要具有所需结果的程序确实存在)

    如果您有无限的存储空间,您可以避免在这些阶段之间重复工作(您存储所有长度为N的程序,这些程序在N个步骤中没有完成,以及它们的状态,然后在下一轮中,您运行新程序,最多N+1个步骤,并为每个步骤运行所有“挂起”程序)。“步骤”的定义无关紧要,只要它不允许无限循环。一些有限数量的字节码,或CPU指令,甚至秒
    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   | ...