我知道在Prolog你可以做类似
的事情someFunction(List) :-
someOtherFunction(X, List)
doSomethingWith(X)
% and so on
这不会遍历List中的每个元素;相反,它将分支到不同的“机器”(通过使用多个线程,在单个线程上回溯,创建并行Universe或者你是什么),,并为每个可能的值执行单独的执行导致someOtherFunction(X, List)
返回true的X!
(我不知道它是如何做到的,但这对问题并不重要)
我的问题是:还有哪些其他非决定性编程语言?似乎非确定性是在具有不可变变量的语言中实现多线程的简单化和最合理的方式,但我以前从未见过这样做过 - 为什么这种技术不受欢迎?
答案 0 :(得分:16)
Prolog实际上是确定性的 - 评估的顺序是规定的,而且秩序很重要。
为什么非确定性不是更受欢迎?
非确定性是不受欢迎的,因为它更难以推断程序的结果,真正的非确定性执行(与语义相对)很难实现。
我所知道的唯一不确定语言是
Dijkstra的守卫命令演算,他希望永远不会实施
并发ML,其中通信可以不确定地同步
Gerard Holzmann的Promela语言,它是模型检查器SPIN的语言
SPIN确实使用了非确定性,并在可能的情况下探索整个状态空间。
当然,如果线程不同步,任何多线程语言都会表现得不确定,但这正是那种难以推理的事情 - 以及为什么实现高效,正确的无锁数据结构如此困难。
顺便说一句,如果您希望实现并行性,可以通过简单的map
函数在像Haskell这样的纯函数语言中实现相同的功能。 Google MapReduce基于函数式语言是有原因的。
答案 1 :(得分:6)
Wikipedia article指向Amb,这是一种具有非确定性编程能力的Scheme衍生。
据我了解,编程语言不这样做的主要原因是因为在确定性计算机上运行非确定性程序(与所有现有计算机一样)本质上是昂贵的。基本上,非确定性图灵机可以在多项式时间内解决复杂问题,对于该问题,没有用于确定性图灵机的多项式算法。换句话说,非确定性编程无法在现有计算机的上下文中捕获算法的本质。
同样的问题会影响Prolog。任何有效的,或至少效率不高的Prolog应用程序都必须使用“cut”运算符来避免探索指数数量的路径。只要程序员对Prolog解释器如何以确定性和非常程序化的方式探索可能的路径有良好的心理观点,该算子才有效。非常程序化的东西与函数式编程不能很好地混合,因为后者主要是一种根本不考虑程序性的努力。
作为旁注,在确定性和非确定性图灵机之间,存在“量子计算”模型。假设一个量子计算机存在,它并不能完成非确定性图灵机可以做的所有事情,但它可以做的不仅仅是确定性的图灵机。目前有人正在为量子计算机设计编程语言(假设最终将构建量子计算机)。其中一些新语言功能齐全。您可以在此Wikipedia page上找到许多有用的链接。显然,设计量子编程语言,无论是否有效,并使用它,都不容易,当然也不是“简单”。
答案 2 :(得分:4)
基于Occam理论,非确定性语言的一个例子是CSP。 PAR
和ALT
结构的组合可能会在多处理器系统中产生非确定性行为,从而实现fine grain parallel程序。
当使用软通道,即同一处理器上的进程之间的通道时,ALT
的实现将使行为接近确定性†,但是一旦开始使用硬通道(物理的处理器间通信链路)任何决定论的幻觉都会消失。预计不同的远程处理器不会以任何方式同步,甚至可能没有相同的内核或时钟速度。
† ALT
构造通常使用PRI ALT
实现,因此如果您需要公平,则必须公平地编写代码。子>
在推理和证明程序正确时,非决定论被认为是一种劣势,但在许多方面,一旦你接受它,你就会摆脱决定论迫使你推理的许多限制。
只要通信顺序没有导致deadlock,这可以通过应用CSP技术来完成,那么完成任务的确切顺序应该更少而不是你是否及时得到你想要的结果。
可以说,缺乏决定论是阻止军事项目采用Occam和Transputer系统的一个主要因素,当时由Ada主导,在那里准确地知道什么是CPU在每个时钟周期进行的操作被认为是证明系统正确的必要条件。如果没有这个限制,Occam和它运行的Transputer系统(当时唯一具有经过正式验证的IEEE浮点实现的CPU)将非常适合需要高水平处理功能的硬实时军事系统。空间。
答案 3 :(得分:4)
在Prolog中,您可以同时具有非确定性和并发性。非确定性是您在有关示例代码的问题中描述的内容。您可以想象Prolog子句充满了隐式amb语句。鲜为人知的是逻辑编程也支持并发。
历史说:
第一个并发逻辑编程语言是Relational 克拉克和格雷戈里的语言,这是IC-Prolog的一个分支。 更高版本的并发逻辑编程包括Shapiro 并发Prolog和Ueda的守卫Horn Clause语言GHC。 https://en.wikipedia.org/wiki/Concurrent_logic_programming
但是今天我们可能会选择逻辑编程。 Here是通过线程实现findall的示例。这也可以被修改为在集合上执行各种任务,或者甚至可以为分布式人工智能生成代理网络。
答案 4 :(得分:1)
我相信Haskell有能力构建和非确定性机器。 Haskell起初看起来实际上看起来太难和抽象,但它实际上非常强大。
答案 5 :(得分:1)
答案 6 :(得分:1)
有一种非确定性问题的编程语言,称为“控制网络编程”。如果您想了解更多信息,请转至http://controlnetworkprogramming.com。该网站仍在进行中,但您可以阅读有关它的一些信息。
答案 7 :(得分:1)
IBM Research正在开发的Sly编程语言试图在执行某些类型的算法时包含多线程执行中固有的非确定性。看起来非常重要。