首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AI中的Lisp :自修改代码和特定领域的抽象级别

AI中的Lisp :自修改代码和特定领域的抽象级别
EN

Stack Overflow用户
提问于 2016-04-05 03:18:47
回答 1查看 1.3K关注 0票数 2

AI是用各种不同的语言实现的,例如Python、C/C++、Java,所以请有人向我解释一下,如何使用Lisp来执行#5 ( Peter Norvig在这里提到):

  1. Lisp允许。一个宏系统,允许开发人员创建一个特定于领域的抽象级别,在其中构建下一个级别。..。今天,(5)是Lisp与其他语言相比最优秀的惟一特性。

来源:https://www.quora.com/Is-it-true-that-Lisp-is-highly-used-programming-language-in-AI

我基本上对创建特定于域的抽象级别的含义感到困惑。请有人提供一个具体的例子/应用,说明这将是什么时候/如何有用,只是笼统地说,它意味着什么?我试着读了http://lambda-the-ultimate.org/node/4765,但并没有真正“了解全局”。然而,我觉得这里有某种魔力,因为Lisp允许您编写其他过程/面向对象/函数式语言不允许您编写的代码。然后我看到了这样一篇文章:https://www.quora.com/Which-programming-language-is-better-for-artificial-intelligence-C-or-C++,上面的答案是:

对于一般人工智能,我会选择两者,并用LISP编程。一个真正的AI会有很多自我修改的代码(你不认为一个真正的AI会把它的程序员写成“最后一个字”,对吧?)

这让我更感兴趣,这让我不禁纳闷:

对于AI来说,拥有“自我检查、自修改代码”(源代码:Why is Lisp used for AI?)到底意味着什么?这听起来很酷(可以说,AI对自己的操作很有自知之明),听起来就像使用Lisp可以让人完成这类事情,其他语言甚至都不会想到它(很抱歉,如果这是天真的快乐,我对Lisp完全没有经验,但我很兴奋地开始了)。我读了一点:What are the uses of self modifying code?,并立刻对特定的人工智能应用程序和未来的自我修改代码的前景产生了兴趣。

不管怎么说,我肯定看到了写自修改代码的能力和能够定制特定研究问题领域的语言(这就是Peter Norvig在他的文章中所暗示的)之间的联系,但我真的很不确定这其中的任何一个真正的含义,我想清楚地理解上面提到的这两个方面(“领域-特定的抽象级别”和“自我检查,自我修改的代码”)的螺母和螺栓(甚至仅仅是本质)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-04-05 12:22:46

Lisp允许。一个宏系统,允许开发人员创建一个特定于领域的抽象级别,在其中构建下一个级别。..。今天,(5)是Lisp与其他语言相比最优秀的惟一特性。

对于堆栈溢出来说,这可能太宽泛了,但是领域特定抽象的概念发生在很多语言中,在公共Lisp中就容易得多了。例如,在C中,当调用open()时,您将得到一个文件描述符。它是一个小整数,但是如果您坚持域模型,您不关心它是一个整数,您关心的是它是一个文件描述符,并且在文件描述符需要的地方使用它是有意义的。但是,它是一个leaky abstraction,因为这些调用往往通过返回负整数来表示错误,因此实际上您必须关心文件描述符是一个整数的事实,这样您就可以可靠地比较结果并确定它是否是一个错误。在C中,您可以定义将某些信息捆绑在一起的结构或记录类型。这提供了稍微高一点的抽象量。

抽象的思想是,您可以考虑应该如何使用某物,以及它所代表的是什么,并从域的角度来思考,而不是从表示的角度考虑。在某种意义上,所有编程语言都支持这一点,但是Common使构建与语言内置类似的语言结构变得更加容易,并有助于避免冗余(且容易出错)样板。

例如,如果您正在编写一个natural deduction style定理证明程序,您将需要定义一组推理规则,并使它们成为一个证明系统。其中一些规则将更加简单,不需要知道当前的证明范围。例如,要检查使用连接消除(来自A∧B、infer A (或B))是否合法,只需检查前提和结论的形式即可。如果没有抽象,您可能需要编写:

代码语言:javascript
复制
(defun check-conjunction-elimination (premises conclusion context)
   (declare (ignore context))
   (and (= (length premises) 1)
        (typep (first premises) 'conjunction)
        (member conclusion (conjunction-conjuncts (first premises))
                :test 'proposition=)))

(register-inference-rule "conjunction elimination" 'check-conjunction-elimination)

有了定义抽象的能力,您就可以编写模式匹配器,将其简化为:

代码语言:javascript
复制
(defun check-conjunction-elimination (premises conclusion context)
   (declare (ignore context))
   (proposition-case (premises conclusion)
     (((and A B) A) t)
     (((and A B) B) t)))

(register-inference-rule "conjunction elimination" 'check-conjunction-elimination)

(当然,有些语言内置了模式匹配(Haskell,Prolog (从某种意义上说)),但重点是模式匹配是一个过程过程,您可以在任何语言中实现它。但是,这是一个代码生成过程,在大多数语言中,您必须在编译期间单独进行代码生成。使用Common,它是语言的一部分。)

您可以将该模式抽象为:

代码语言:javascript
复制
(define-simple-inference-rule "conjunction elimination" (premises conclusion)
  ((and A B) A)
  ((and A B) B)))

你还会生成原始代码。这种抽象节省了大量的空间,这意味着当其他人进来时,他们不需要知道所有的Common,他们只需要知道如何使用define-simple-inference-rule.(当然,这确实增加了一些开销,因为这是他们需要知道如何使用的其他东西。)但这个想法仍然存在:代码对应于你谈论领域的方式,而不是编程语言的工作方式。

至于“自修改代码”,我认为这是一个术语,你会听到比你实际看到更好的使用。在上述宏扩展的意义上,有一种自修改代码(宏扩展代码知道如何“修改”或将代码转换为其他代码,但我不认为这是一个很好的例子)。由于您可以访问eval,所以可以将代码修改为一个对象并对其进行计算,但我认为并不是很多人真正提倡这样做。能够动态地重新定义代码是很方便的,但我想你会再次看到人们在REPL中做的比在程序中做的多得多。

然而,能够返回闭包(越来越多的语言支持的东西)是一个很大的帮助。例如,trace是“某种程度上的”自我修改。您可以这样实现它:

代码语言:javascript
复制
(defmacro trace (name)
  (let ((f (symbol-function name)))
    (setf (symbol-function name)
          (lambda (&rest args)
            (print (list* name args))
            (apply f args)))))

您需要做一些更多的工作来支持untrace,但我认为重点是相当清楚的;您可以在运行时以可预测的方式做一些改变函数行为等的事情。跟踪和日志记录工具是一个简单的例子,但是如果一个系统决定分析一些它知道很重要的方法,它可以动态地决定开始缓存一些结果,或者做其他有趣的事情。这是一种“自我修正”,可能会很有帮助。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36416532

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档