首先,始终尝试内置启发式方法。ff
往往是一个很好的策略。
对于自定义标签策略,通常最简单的方法是首先将域转换为列表,然后重新排序列表,然后简单地使用member/2
新顺序分配域的值。
一个好的建筑黑色是dom_integers/2
,将有限CLP(FD) 域与整数列表相关联:
:- use_module(library(clpfd)).
dom_integers(D, Is) :- phrase(dom_integers_(D), Is).
dom_integers_(I) --> { integer(I) }, [I].
dom_integers_(L..U) --> { numlist(L, U, Is) }, Is.
dom_integers_(D1\/D2) --> dom_integers_(D1), dom_integers_(D2).
您的特定策略很容易在此类有序整数列表上表达,将这些整数与第二个列表相关联,其中值按您描述的顺序出现:
outside_in([]) --> [].
outside_in([I]) --> [I].
outside_in([First|Rest0]) --> [First,Last],
{ append(Rest, [Last], Rest0) },
outside_in(Rest).
示例查询和结果:
?- 短语(outside_in([1,2,3,4]),是)。
是 = [1, 4, 2, 3] ;
错误的。
将其与fd_dom/2
and结合dom_integers/2
,我们得到(除了X
省略的变量的绑定):
?- X in 10..20,
fd_dom(X, Dom),
dom_integers(Dom, Is0),
phrase(outside_in(Is0), Is),
member(X, Is).
X = 10 ;
X = 20 ;
X = 11 ;
X = 19 ;
X = 12 ;
X = 18 ;
etc.
非确定性由 保留member/2
。