寻找奇偶数的Prolog约束程序设计

寻找奇偶数的Prolog约束程序设计,prolog,clpfd,constraint-programming,Prolog,Clpfd,Constraint Programming,我需要创建一个谓词: applyConstraints(L) 这就对L中的变量应用了约束,使得L中没有两个连续的元素都是奇数或偶数,我怎么能做到呢?对于固定大小的L,这很简单,但是对于可变大小的L呢? 我需要用SICSTUS PROCOLL CPLFD库来完成。< P> >考虑元素对< /P> applyConstraints([A,B|R]) :- A mod 2 #\= B mod 2, applyConstraints([B|R]). applyConstraints([

我需要创建一个谓词:

applyConstraints(L)
这就对L中的变量应用了约束,使得L中没有两个连续的元素都是奇数或偶数,我怎么能做到呢?对于固定大小的L,这很简单,但是对于可变大小的L呢?
我需要用SICSTUS PROCOLL CPLFD库来完成。

< P> >考虑元素对< /P>
applyConstraints([A,B|R]) :-
    A mod 2 #\= B mod 2,
    applyConstraints([B|R]).
applyConstraints([_]).
测试(使用SWI Prolog库(clpfd),可能需要用Sicstus的对应项替换ins/2)


受@Matscallsson版本的启发,我尝试最小化所涉及的约束变量的数量:

applyConstraints(Xs) :-
   S #\= R,
   applyConstraints(Xs, S, R).

applyConstraints([], _, _).
applyConstraints([X|Xs], S, R) :-
   X mod 2 #= S,
   applyConstraints(Xs, R, S).
编辑:此版本的目标
applyConstraints([])
有一个不容易看到的缺陷。事实上,在SICStus中需要切换到
full_answer
模式,如下所示:

| ?- applyConstraints([]).
yes
| ?- assertz(clpfd:full_answer).
yes
| ?- applyConstraints([]).
clpfd:(_A#\=_B),
_A in inf..sup,
_B in inf..sup ? ;
no
所以我们有一个无用的约束,它可能会消耗资源。 为了克服这一缺陷,需要一些特殊套管:

applyConstraints([]).
applyConstraints([X|Xs]) :-
   X mod 2 #= S,
   S #\= R,
   applyConstraints(Xs, R, S).
注1-在SWI或YAP中,无法直接打开完全应答模式。解决问题的唯一方法是将查询包装在
call\u residence\u vars/2
周围,如下所示:

?- applyConstraints([]).
true.

?- call_residue_vars(applyConstraints([]),RVs).
RVs = [_G794, _G797],
_G794#\=_G797.
注2-得益于@mat,自SWI 7.3以来有类似的功能(请记住,SWI 7需要
——传统的
,以实现兼容性):


(不太清楚“分离”在这种情况下意味着什么,毕竟,剩余目标必须为真,才能使答案为真。因此不涉及分离。)

想象不出比循环更简单的方式……为什么不按照常见的方式编写条款:事实优先。您的写作会导致大量不必要的开销。@false:因为在没有索引的情况下进行匹配?原因:没有索引(在当前的实现中),但也无法为最一般的查询生成答案-这在诊断上下文中通常非常有用。
applyConstraints([])
fails我认为没有必要扔掉原来的一行程序解决方案。当OP谈到可变大小L时,它们可能只是指在编译时不固定。在这里,您可能给出了一个不好的示例,在约束设置阶段显示了一个带有选择点的程序。对于SWI 7.3或更高版本,您可以使用
?-set_prolog_flag(toplevel_residence_vars,true)。
查看所有剩余约束。
applyConstraints([]).
applyConstraints([X|Xs]) :-
   X mod 2 #= S,
   S #\= R,
   applyConstraints(Xs, R, S).
?- applyConstraints([]).
true.

?- call_residue_vars(applyConstraints([]),RVs).
RVs = [_G794, _G797],
_G794#\=_G797.
?- set_prolog_flag(toplevel_residue_vars, true).
true.

?- applyConstraints([]).
% with detached residual goals
_G430#\=_G433.