可能重复:
为什么 Lisp 用于人工智能?
什么样的语言适合人工智能开发?
我听说 LISP 和 Prolog 在这个领域被广泛使用。 它们的哪些特性使它们适合人工智能?
回答:
总的来说,我认为在人工智能中“首选”语言的主要特点是它们具有高阶编程以及许多用于抽象的工具。
高阶编程(也称为函数作为一等公民)往往是大多数人工智能语言的一个决定性特征 http://en.wikipedia.org/wiki/Higher-order-programming, 我就是这么看的。 该文章只是一个存根,并且遗漏了 Prolog http://en.wikipedia.org/wiki/Prolog,它允许高阶“谓词”。
但基本上,高阶编程是指你可以像变量一样传递函数。 令人惊讶的是,许多脚本语言也具有作为一等公民的函数。 LISP/Prolog 理所当然是 AI 语言。 但其他一些可能会令人惊讶。 我已经看过几本关于 Python 的人工智能书籍。 其中之一是 http://www.nltk.org/book。 我也看过一些关于 Ruby 和 Perl 的书籍。 如果你更深入地研究 LISP,你会发现它的许多特性与现代脚本语言相似。 然而,LISP 出现在 1958 年……所以它确实遥遥领先于时代。
Java 有 AI 库。 在 Java 中,你可以使用类的方法来某种程度上地破解函数作为一等公民,这比 LISP 更难/更不方便,但并非不可能。 在 C 和 C++ 中,你有函数指针,但同样,它们比 LISP 更麻烦。
一旦你拥有了作为一等公民的函数,你就可以进行比其他方式更通用的编程。 如果没有作为一等公民的函数,你可能需要构造 sum(array)
、product(array)
来执行不同的操作。 但是,借助作为一等公民的函数,你可以计算 accumulate(array, +)
和 accumulate(array, *)
。 你甚至可以执行 accumulate(array, getDataElement, operation)
。 由于人工智能的定义非常模糊,因此这种类型的灵活性非常有帮助。 现在你可以构建更加通用的代码,这些代码更容易以最初甚至没有设想的方式进行扩展。
Lambda(现在到处都是)成为一种节省键入的方式,因此你不必定义每个函数。 在前面的示例中,你可以直接说 accumulate(array, lambda element: return element.GPA, +)
,而不必在某处创建 getDataElement(arrayelement) { return arrayelement.GPA }
。 因此,你不必用大量只被调用一次或两次的函数来污染你的命名空间。
如果你回到 1958 年,你的选择基本上是 LISP、Fortran 或汇编。 与 Fortran 相比,LISP 更加灵活(不幸的是效率也较低),并且提供了更好的抽象手段。 除了作为一等公民的函数外,它还具有动态类型、垃圾回收等(如今任何脚本语言都具有这些功能)。 现在有更多语言可供选择,尽管 LISP 受益于它是第一个并且成为每个人都碰巧用于 AI 的语言。 现在看看 Ruby/Python/Perl/JavaScript/Java/C#/甚至最新的 C 提案标准,你开始看到 LISP 的特性悄悄地渗入(map/reduce、lambdas、垃圾回收等)。 LISP 在 1950 年代遥遥领先于时代。
即使现在,与大多数竞争对手相比,LISP 仍然保留了一些王牌。 LISP 中的宏系统非常先进。 在 C 中,你可以使用库调用或简单的宏(基本上是文本替换)来扩展语言。 在 LISP 中,你可以定义新的语言元素(想想你自己的 if 语句,现在想想你自己的用于定义 GUI 的自定义语言)。 总的来说,LISP 语言仍然提供主流语言尚未赶上的抽象方式。 当然,你可以为 C 定义你自己的自定义编译器并添加你想要的所有语言构造,但实际上没有人这样做。 在 LISP 中,程序员可以通过宏轻松地做到这一点。 此外,LISP 是经过编译的,并且根据编程语言的竞争,它通常比 Perl、Python 和 Ruby 更有效。
Prolog 基本上是一种用于表示事实和规则的逻辑语言。 专家系统是什么,不过是规则和事实的集合。 由于在 Prolog 中表示一堆规则非常方便,因此它与专家系统之间存在明显的协同作用。
现在我认为为每个 AI 问题使用 LISP/Prolog 并不是理所当然的。 事实上,只需看看 Java 可用的众多机器学习/数据挖掘库即可。 但是,当你正在原型设计一个新系统或正在尝试因为你不知道自己在做什么时,使用脚本语言比静态类型语言容易得多。 LISP 是最早拥有我们认为理所当然的所有这些功能的语言。 基本上起初根本没有竞争。
总的来说,学术界似乎非常喜欢函数式语言。 因此,LISP 是一种函数式语言并无坏处。 虽然现在你也有 ML、Haskell、OCaml 等(其中一些语言支持多种范例……)。