【问题标题】:Non-deterministic programming languages非确定性编程语言
【发布时间】:2010-02-02 15:39:35
【问题描述】:

我知道在 Prolog 中你可以做类似的事情

someFunction(List) :- 
    someOtherFunction(X, List)
    doSomethingWith(X)
    % and so on

这不会遍历 List 中的每个元素;相反,它将分支到不同的“机器”(通过使用多个线程、在单个线程上回溯、创建并行宇宙或你有什么)为每个可能的值单独执行的 X 导致 someOtherFunction(X, List) 返回 true!
(我不知道它是如何做到的,但这对问题并不重要)

我的问题是:还有哪些其他非确定性编程语言?似乎非确定性是在具有不可变变量的语言中实现多线程的最简单和最合乎逻辑的方法,但我以前从未见过这样做过 - 为什么这种技术没有更受欢迎?

【问题讨论】:

  • 是的,这与我的上一个问题非常相似:stackoverflow.com/questions/2174535/… 我问了一个新问题,因为显然我最后一个问题的措辞很糟糕;每个人都开始争论 Prolog 的细节,但我并不真正关心 Prolog。
  • 谷歌,主要是帮助。例如:en.wikipedia.org/wiki/Nondeterministic_programming 是我发现的。这有帮助吗?
  • 这给出了几 (3) 个示例,但并没有真正解释为什么在大多数函数式语言中不使用非确定性
  • 这可能有助于询问当您颠倒条款时会发生什么。即someFunction(List) :- doSomethingWith(X), someOtherFunction(X, List) 做什么?有什么不同吗?应该是吗?如果您真的想了解 Prolog 的实际工作原理,我会推荐 The Reasoned Schemer (mitpress.mit.edu/catalog/item/default.asp?ttype=2&tid=10663)。
  • @Nathan: ...它会做什么?它会给出相同的结果,不是吗?只是性能不同?

标签: multithreading functional-programming prolog non-deterministic


【解决方案1】:

Prolog 实际上是确定性的——评估的顺序是规定的,顺序很重要。

为什么不确定性没有更流行?

不确定性不受欢迎,因为它使您更难以推理程序的结果,并且真正的非确定性执行(与语义相反)难以实现。

我所知道的唯一非确定性语言是

  • Dijkstra 的受保护命令演算,他希望永远不会实现

  • 并发 ML,其中通信可能不确定地同步

  • Gerard Holzmann 的 Promela 语言,它是模型检查器 SPIN 的语言

SPIN 确实使用了不确定性,并尽可能探索整个状态空间。

当然,如果线程不同步,任何多线程语言的行为都是不确定的,但这正是难以推理的事情——以及为什么很难实现高效、正确的无锁数据结构。

顺便说一句,如果您希望实现并行性,您可以通过一个简单的map 函数在像 Haskell 这样的纯函数式语言中实现相同的目标。 Google MapReduce 基于函数式语言是有原因的。

【讨论】:

  • 我相信您可以使用map实现同样的事情,但我不确定它是否像您说的那样微不足道。例如,我给出的代码与迭代 List 的元素无关 - someOtherFunction() 可以是任何东西(例如,List 的校验和设置了 X 位)!函数中也有非确定性——在 Prolog 中,你可以编写一个函数的多个定义,并且它们都会被调用(如果有返回 true,则结果为 true)。 为什么使用单独的线程来执行它会很困难?由于所有变量都是不可变的,我们不需要锁,对吧?
  • @Transfinite Numbers,Prolog 是完全确定的。它按照严格规定的顺序探索所有选项。
  • 在纯 Prolog 中,如果您有一个有限的答案集,则顺序无关紧要。该程序将返回相同的答案集,无论您如何排序执行。类似地,在答案集编程 (ASP) 中,Prolog 的扩展允许分离头和约束,但具有更高级别的非确定性。 ASP 可以生成不同的答案集。
【解决方案2】:

Wikipedia article 指向 Amb,它是具有非确定性编程能力的 Scheme 导数。

据我了解,编程语言不这样做的主要原因是因为在确定性机器(就像所有现有计算机一样)上运行非确定性程序本质上是昂贵的。基本上,非确定性图灵机可以在多项式时间内解决复杂问题,而确定性图灵机的多项式算法尚不为人所知。换句话说,非确定性编程无法在现有计算机的上下文中捕捉算法的本质。

同样的问题也会影响 Prolog。任何高效的,或者至少不是非常低效的 Prolog 应用程序都必须使用“cut”运算符来避免探索指数数量的路径。该操作符只有在程序员对 Prolog 解释器如何以确定性和非常程序化的方式探索可能的路径有良好的头脑时才起作用。非常程序化的东西不能很好地与函数式编程混合,因为后者主要是一种根本不按程序思考的努力。

附带说明,在确定性和非确定性图灵机之间,存在“量子计算”模型。假设量子计算机存在,它不会做非确定性图灵机所能做的所有事情,但它可以做的不仅仅是确定性图灵机。有人目前正​​在为量子计算机设计编程语言(假设最终将建造一台量子计算机)。其中一些新语言是功能性的。您可以在此Wikipedia page 上找到许多有用的链接。显然,设计和使用一种量子编程语言,不管是功能性的还是非功能性的,并不容易,当然也不“简单”。

【讨论】:

    【解决方案3】:

    非确定性语言的一个例子是Occam,它基于CSP 理论。 PARALT 构造的组合可以在多处理器系统中产生不确定的行为,实现 fine grain parallel 程序。

    当使用软通道时,即同一处理器上的进程之间的通道,ALT 的实现将使行为接近确定性,但是一旦您开始使用硬通道(物理处理器外的通信链接)任何确定论的幻觉都消失了。预计不同的远程处理器不会以任何方式同步,它们甚至可能没有相同的内核或时钟速度。

    ALT 构造通常使用PRI ALT 来实现,因此如果您需要公平,则必须明确编码。


    在推理和证明程序正确时,不确定性被视为劣势,但在许多方面,一旦您接受了它,您就可以摆脱确定性对推理施加的许多限制。

    只要通信的顺序不会导致deadlock,这可以通过应用 CSP 技术来完成,那么完成事情的精确顺序就应该是否重要及时得到你想要的结果。

    可以说,这种缺乏确定性是阻止在军事项目中采用 Occam 和 Transputer 系统的主要因素,当时由 Ada 主导,在那里准确地知道 CPU 在每个时钟上都在做什么循环被认为是证明系统正确的必要条件。如果没有这个限制,Occam 和运行它的 Transputer 系统(当时唯一具有正式证明的 IEEE 浮点实现的 CPU)将非常适合需要高水平处理功能的硬实时军事系统。空间。

    【讨论】:

      【解决方案4】:

      在 Prolog 中,您可以同时拥有非确定性和并发性。非确定性是您在有关示例代码的问题中所描述的。你可以想象一个 Prolog 子句充满了隐含的amb 语句。鲜为人知的是,逻辑编程也支持并发。

      历史说:

      第一个并发逻辑编程语言是关系型 克拉克和格雷戈里的语言,它是 IC-Prolog 的一个分支。 更高版本的并发逻辑编程包括夏皮罗的 并发 Prolog 和 Ueda 的 Guarded Horn Clause 语言 GHC。 https://en.wikipedia.org/wiki/Concurrent_logic_programming

      但是今天我们可能只是在逻辑编程中进行操作。 Here 是通过线程实现 findall 的示例。这也可以修改为在集合上执行各种任务,甚至可以生成面向分布式人工智能的代理网络。

      【讨论】:

        【解决方案5】:

        我相信 Haskell 有能力构建非确定性机器。 Haskell 乍一看似乎太难和太抽象,不适合实际使用,但实际上它非常强大。

        【讨论】:

          【解决方案6】:

          有一种用于解决非确定性问题的编程语言,称为“控制网络编程”。如果您想了解更多信息,请访问http://controlnetworkprogramming.com。该网站仍在进行中,但您可以阅读一些有关它的信息。

          【讨论】:

            【解决方案7】:

            Java 2K

            注意:在您单击链接并感到失望之前:这是一种esoteric 语言,与并行性无关。

            【讨论】:

            • 当我说“非确定性”时,我的意思是程序采用每条路径。从这个意义上说,这个程序不是非确定性的,即使它绝对不是确定性的。
            【解决方案8】:

            IBM Research 正在开发的Sly 编程语言试图将多线程执行中固有的非确定性包含在某些类型算法的执行中。不过,看起来这是一项正在进行中的工作。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2019-08-08
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-09-07
              • 2011-05-06
              • 1970-01-01
              相关资源
              最近更新 更多