4.3在SCHEME的演变--未确定的计算

4.3在SCHEME的演变--未确定的计算

在这部分中,我们扩展scheme的评估器,支持一种编程范式,叫做非确定性计算。
通过构建到评估器中一个工具以支持自动化搜索。这是一个对语言的更深层的改变。
比4.2部分中延迟评估的介绍的改变更大。

非确定性计算,像流处理一样,对于生成和测试应用程序来说是很用的。
考虑一下开始于两个正整数的列表的任务,找到一个整数的数对,一个元素来自于第一个列表,
一个来自于第二个列表,它们的和是一个素数。我们已经看到了在2.2.3部分的有限序列操作
和 3.5.3部分的有限流 是如何处理这个任务的。我们的方法是生成一个所有的可能的数对,再过虑这个数对的列表,
选择出符合条件的数对。正如在第二章中,我们实际产生了数对的全部的序列,或者是在第三章中,
交互的生成和过滤。 对于计算是如何被组织起来的必须的景象 来说是非实质性的。

非确定性方法进化了另一番景象。简单地想象一下,我们选择了(以某种方式)第一个列表中的一个数,
和第二个列表中的一个数,并且要求它们的和是素数。这能被表示成如下的程序:

(define (prime-sum-pair list1 list2)
    (let ((a (an-element-of list1))
          (b (an-element-of list2))
         )
        (require (prime? (+ a b)))
        (list a b)
    )
)

它看起来好像是仅仅重述了问题,并没有指定特定的方式来解决它。
然而,这是一个合法的非确定性的程序。

这里的关键性的思想是在非确定性的语言中,表达式能有多个可能的值。
例如,an-element-of可能返回给出列表中的任何一个元素。我们的非确定性程序
评估器将自动化选择一个可选的值,并追踪选择。如果一个接下来的需求没有
满足,解释器将选择一个不同的选择,它将保持新的选择,直到解释成功或者
我们运行完成所有的选择。正如推迟的解释器把程序员从值如何被推迟与强制的
细节中解放出来,非确定性的程序解释器把程序员从如何做选择的细节中解放出来。

非确定性解释与流处理所引入的时间的不同的映像的比较是指令性的。
当从时间而来的可能的答案的流被汇编,当实际的流的元素被生成,流处理
使用推迟解释来解构了时间。解释器支持这种幻像,即在一个非时间的序列中,
所有的可能的值都呈现在我们的面前。使用非确定性的解释,一个表达式
表示了可能的情况的集合的探索,一些可能的情况陷入了列胡同,其它的
有可用的值。非确定性程序解释器支持了这种幻像,时间的分支,即我们的程序
有不同的可能的执行历史。当我们到达了一个死胡同,我们能重新访问到一个之
前的选择点,并且执行一个不同的分支。

非确定性的程序解释器实现了如下的被叫做amb的解释器,因为它基于
一个新的标识符叫做amb.在amb解释器的驱动循环中,我们能写出
如上的定义(使用了prime? ,an-element-of,require程序)
并且运行程序如下:

;;;  Amb-eval input:
(prime-sum-pair  '(1 3 5 8)  '(20 35 110))
;;;  Staring a new problem
;;; Amb-Eval value:
(3  20)

解释器重复地从列表中选择元素,直到做出一个成功的选择,
得到了返回值。

4.3.1部分介绍了AMB并且解释了通过解释器
自动搜索机制,它如何支持非确定性。 4.3.2
部分表示了非确定性程序的例子。 4.3.3部分给出了
通过修改普通的scheme解释器,如何实现AMB解释器的细节。

猜你喜欢

转载自blog.csdn.net/gggwfn1982/article/details/82948925
4.3