我会尽量简短地回答这个问题,因为search/6 是您可以在 ECLiPSe 系统中找到的最复杂的谓词之一。
不过,最好在 ECLiPSe 用户邮件列表中询问任何更详细的后续问题。
search/6 谓词是一个通用谓词,用于控制对 CLP 问题解决方案的搜索。它允许用户控制搜索树的形状(变量沿分支的顺序、分支的顺序以及访问的搜索树的部分)。谓词有 6 个参数:search(+L, ++Arg, ++Select, +Choice, ++Method, +Option)。 (+和++表示参数的模式)
前两个参数一起出现。 L 是变量列表或术语列表。如果是前者,则Arg必须为0,如果是后者,则Arg表示在搜索过程中应该实例化的变量的位置,例如:
search([A,B],0,input_order,indomain,complete,[]).
或
search([p(1,A),p(2,B)],2,input_order,indomain,complete,[]).
在这两种情况下,变量 A 和 B 在搜索过程中都会被实例化。
第三个参数是selection方法。 search/6使用此方法从L列表中选择下一个变量进行实例化。
最简单的选项是input_order:搜索只是迭代列表中的变量。在上面的例子中,它会先实例化A,然后再实例化B。其他选项考虑域大小和/或附加到变量的约束数量,并相应地进行选择。例如,first_fail 选择具有最小域的变量。如果A 的当前域是[1,2,3] 并且B 具有域[1,3],那么B 将首先被选中并实例化。如果多个变量具有相同的最小域大小,则将按输入顺序选择其中的第一个。考虑域大小的选择方法实现了动态变量排序,因为域大小会在搜索过程中发生变化(缩小),具体取决于约束实现的传播量。
其他选择方法现在应该是不言自明的。
也可以定义自己的选择方法,前提是实现它的谓词具有 arity 2,即有两个参数。谓词必须将变量作为输入并计算一些标准值。将选择具有最小标准值的变量。
第四个参数是choice方法。一旦选择了一个变量,choice 方法将控制在搜索期间尝试其域中的值的顺序。
最简单的选项是indomain,它按升序选择变量当前域中的值。即,如果变量A 具有域[1,3,5],则搜索将首先将A 绑定到1,在回溯时将其绑定到3,最后绑定到5。indomain_middle 将从3 开始,然后是1,然后5.
更复杂的选择方法(即,除了indomain)将删除回溯时的尝试值,即基本上添加额外的约束,如A#\=1。这将导致额外的传播,从而可以更早地检测到不可行性。您可以在问题中链接到的search/6 文档中看到运行 n-queens 示例时的效果。
同样,也可以定义自己的选择方法。谓词的元数必须为 1 或 3。如果元数为 1,则谓词将一个变量作为输入并将其绑定到一个值(或做出改变变量域的其他选择)。如果 arity 为 3,那么您可以使用这两个附加参数来传递一些您可以用来做出选择的状态信息。
第五个参数是search方法。这控制了搜索应该探索的搜索树部分的大小(而选择方法控制变量沿树分支的顺序,选择方法控制搜索树中分支的顺序)。
最简单的选项是complete,它从左到右搜索树,直到树用尽。所有其他选项(除了对称性破坏)都是不完整的搜索方法,即搜索树中会有未探索的分支。如果解决方案在这样一个未探索分支的叶子上,那么它将找不到。您必须确保选择和选择方法以不完整搜索方法能够找到解决方案的方式塑造搜索树。例如,选项bbs 限制了搜索期间可以进行的回溯的数量。如果该数字用完,则搜索将停止。
对称性破坏只会排除在某些方面与其他分支等效(对称)的分支。
第六个参数是可能的附加选项列表,在search/6 文档中进行了描述。通常,您不需要它们。