Prolog 矩阵列之间的差异和所有_的使用不同

Prolog 矩阵列之间的差异和所有_的使用不同,prolog,sicstus-prolog,clpfd,Prolog,Sicstus Prolog,Clpfd,我试图表达从列表中的一个元素到另一个元素的转换关系。我想说的是,两个任意元素之间应该存在一定的差异 如果我们有名单 X=[X1,X2,X3,...Xn] 其中所有元素都是长度为Y的列表 现在我想表达的是,Xa->Xb中的所有元素都应该与Xa中的元素有所不同 等于或小于1,Xa和Xb是X(a!=b)的任意给定元素 例如:如果Xa=[1,1,1,1],那么Xb可以是[1,1,1,2],因为所有元素都相等或减少,除了一个,最后一个,从1->2开始 为此,我编写了以下谓词: ensure_atlea

我试图表达从列表中的一个元素到另一个元素的转换关系。我想说的是,两个任意元素之间应该存在一定的差异

如果我们有名单

X=[X1,X2,X3,...Xn] 
其中所有元素都是长度为Y的列表

现在我想表达的是,Xa->Xb中的所有元素都应该与Xa中的元素有所不同 等于或小于1,Xa和Xb是X(a!=b)的任意给定元素

例如:如果Xa=[1,1,1,1],那么Xb可以是[1,1,1,2],因为所有元素都相等或减少,除了一个,最后一个,从1->2开始

为此,我编写了以下谓词:

ensure_atleast_n_patterns( ListOfLists, DiffPattern, NoOfAtLeastEqualPatterns ) :-
    ( 
    %Loop through the list to set up the constraint between first
    %element and the rest, move on to next element and and set
    %up constraint from second element on on etc.
    %Ex: if ListOfLists=[X1,X2,X3,X4], the following 'loops' will run:
    %X1-X2, X1-X3,X1-4,X2-X3,X2-X4,X3,X4
    fromto(ListOfLists, [This | Rest], Rest,[_]),
    fromto(0,In1,Out1,PatternCount),
    param([DiffPattern])
    do
        (
            %Compare the difference between two elements:
            foreach( X, Rest ),
            fromto(0,In2,Out2,Sum2),
            param([DiffPattern,This])
            do
                This=[X1,X2,X3,X4,X5],
                X=[Y1,Y2,Y3,Y4,Y5],
                DiffPattern=[P1,P2,P3,P4,P5],
                X1 #< Y1 #<=> R1,
                X2 #< Y2 #<=> R2,
                X3 #< Y3 #<=> R3,
                X4 #< Y4 #<=> R4,
                X5 #< Y5 #<=> R5,
                Result in 0..1,
                (R1 #= P1) #/\ (R2 #= P2) #/\ (R3 #= P3) #/\ (R4 #= P4) #/\ (R5 #= P5) #<=> (Result #=1),
                Out2 #= In2 + Result
        ),
        Out1 #= In1 + Sum2
    ),
    %Count up, and require that this pattern should at least be present
    %NoOfAtLeastEqualPatterns times
    PatternCount #>= NoOfAtLeastEqualPatterns.
但标签上挂着“永远”

我的方法错了吗?有更好的办法解决这个问题吗

测试代码:

  mytest( X ):-
   Tlen = 10,
   Mind = 0,
   Maxd = 20,
   length( X1,Tlen),
   length( X2,Tlen),
   length( X3,Tlen),
   length( X4,Tlen),
   length( X5,Tlen),
   domain(X1, Mind, Maxd),
   domain(X2, Mind, Maxd),
   domain(X3, Mind, Maxd),
   domain(X4, Mind, Maxd),
   domain(X5, Mind, Maxd),

   all_different( X1 ),
   all_different( X2 ),
   all_different( X3 ),
   all_different( X4 ),
   all_different( X5 ),

   X=[X1,X2,X3,X4,X5],

   transpose( X, XT ),

   ensure_atleast_n_patterns( XT, [0,0,0,0,1],1),
   ensure_atleast_n_patterns( XT, [0,0,0,1,0],1),
   ensure_atleast_n_patterns( XT, [0,0,1,0,0],1),
   ensure_atleast_n_patterns( XT, [0,1,0,0,0],1),
   ensure_atleast_n_patterns( XT, [1,0,0,0,0],1).
我是这样运行的:

mytest(X),append(X, X_1), labeling( [], X_1 ).                    

有一件事让我怀疑你的代码没有表达你的想法。你说:“我现在想表达的是Xa->Xb应该有一个区别,其中Xa中的所有元素都等于或小于1,而Xa和Xb是X(a!=b)的任何给定元素”。但是在代码中,你不考虑所有的元素对。你只考虑XB在XA右边某处的配对(Xb是REST元素)。这种不对称性很可能导致很难找到解决方案

然而,这里有一个Tlen=Maxd=5的解决方案:

| ?- mytest([[0,3,4,1,2],[1,2,4,0,3],[1,4,2,0,3],[3,1,4,2,0],[3,4,1,2,0]]).
yes
但由于不对称性,以下操作失败:

| ?- mytest([[0,1,2,3,4],[1,0,3,2,4],[1,0,3,4,2],[3,2,0,1,4],[3,2,0,4,1]]).
no
如果您修复代码,使其考虑所有对(Xa,Xb),那么从任何解决方案中,您都可以通过排列ListofList的元素(XT的行)获得另一个解决方案。通过打破这种解的对称性来减少搜索空间通常是个好主意。您可以通过以下方式实现:

lex_chain(XT),

顺便说一句,我建议使用all_distinct/1而不是all_DISTINCE/1。

有一件事让我怀疑您的代码没有表达您的想法。你说:“我现在想表达的是Xa->Xb应该有一个区别,其中Xa中的所有元素都等于或小于1,而Xa和Xb是X(a!=b)的任何给定元素”。但是在代码中,你不考虑所有的元素对。你只考虑XB在XA右边某处的配对(Xb是REST元素)。这种不对称性很可能导致很难找到解决方案

然而,这里有一个Tlen=Maxd=5的解决方案:

| ?- mytest([[0,3,4,1,2],[1,2,4,0,3],[1,4,2,0,3],[3,1,4,2,0],[3,4,1,2,0]]).
yes
但由于不对称性,以下操作失败:

| ?- mytest([[0,1,2,3,4],[1,0,3,2,4],[1,0,3,4,2],[3,2,0,1,4],[3,2,0,4,1]]).
no
如果您修复代码,使其考虑所有对(Xa,Xb),那么从任何解决方案中,您都可以通过排列ListofList的元素(XT的行)获得另一个解决方案。通过打破这种解的对称性来减少搜索空间通常是个好主意。您可以通过以下方式实现:

lex_chain(XT),
顺便说一下,我建议使用all_distinct/1而不是all_DISTINCE/1