prolog中的模式

prolog中的模式,prolog,cycle,Prolog,Cycle,取所有长度为N的不同位模式,并将它们按循环排列,以便每个 模式在N-1位中与其两个相邻模式重叠。然后 将循环展平为序言列表 编写一个谓词模式(N,L),返回包含所有位的位列表 长度N>0的图案遵循上述规则。注意,有多种可能的方法 解决。你只需要制作一个 ?- pattern(1, L). L = [0,1] ?- pattern(2, L). L = [0,0,1,1] ?- pattern(3, L). L = [0,0,0,1,1,1,0,1] 阿巴斯·阿尔卡欣(Abbas Alkahim

取所有长度为N的不同位模式,并将它们按循环排列,以便每个 模式在N-1位中与其两个相邻模式重叠。然后 将循环展平为序言列表

编写一个谓词
模式(N,L)
,返回包含所有位的位列表 长度N>0的图案遵循上述规则。注意,有多种可能的方法 解决。你只需要制作一个

?- pattern(1, L).
L = [0,1]
?- pattern(2, L).
L = [0,0,1,1]
?- pattern(3, L).
L = [0,0,0,1,1,1,0,1]

阿巴斯·阿尔卡欣(Abbas Alkahim)在书中给出了一种简洁的生成方法

它可能适合于Prolog实现,但需要稍加修改。将他的方法称为偏好相反算法,对于图案长度N,概述的步骤如下:

  • 将列表的前N个“位”设置为0
  • 对于下一个“位”,考虑与前面一个相反的奇偶性。
  • 如果产生的N位模式以前在列表中不存在,则将该位邻接到列表的末尾并继续。(返回到步骤2)
  • 另一方面,如果该模式确实存在,请尝试下一个等于前一个的奇偶校验位
  • 如果该N位模式不存在,则将该位邻接到列表的末尾并继续。(返回到步骤2)
  • 否则就停止
  • 这将产生一个序列,该序列包含长度为N的所有二进制模式(n1模式除外),并以N-11模式和N-10模式终止。要获得完整的De Bruijn序列,用单个1条目替换最后的N-10(此时序列应环绕到长度为2^N的循环)

    对于Prolog实现,我怀疑如果将位添加到列表的开头,而不是末尾,事情会进展得最容易。无论如何,我会尝试一下,让你知道它是否像我希望的那样好用


    我昨晚编写了代码,今天早上进行了测试,首先尝试相反的奇偶校验位,然后在列表的开头添加位。N=1的情况看起来有点反常,在努力编写了与N>1相同的代码之后,我回到了只返回N=1的[1,0]

    另一个很好的练习是编写代码,使用技术将位添加到序列的末尾


    添加:(代码)

    下面是一个实现,它通过在列表前面添加条目来构建表示De Bruijn序列的列表,确定性谓词binaryDeBruijnSeq/2将(绑定的)正整数N作为模式长度,并将所述列表作为第二个参数返回:

    /*
       Prolog implementation of PreferOpposite
         "A Simple Combinatorial Algorithm
              for De Bruijn Sequences"
                 by Abbas Alkahim:
       http://duch.mimuw.edu.pl/~rytter/TEACHING/TEKSTY/PreferOpposite.pdf
    
       Construct binary De Bruijn sequence for all N bit patterns
       (a list construed as cycle) by adding to front of list:
    
        1.  If N = 1, return [1,0]; otherwise begin the sequence
            with N zeros.
        2.  For next bit, first try one of parity opposite to the
            previous one, then try one of the same parity, so that
            an N bit pattern not already found results.  Repeat.
        3.  When no further bits can be added, the final N-1 bits
            will be zeros.  Replace them with a single one bit.
    */
    binaryDeBruijnSeq(1,[1,0]).
    binaryDeBruijnSeq(N,[1|ZeroStrip]) :-
        N > 1,
        zeroNFill(N,ZeroNBits),
        accrueDeBruijn(ZeroNBits,ZeroNBits,Accrue),
        zeroStrip(Accrue,ZeroStrip).
    
    zeroNFill(0,[ ]).
    zeroNFill(N,[0|Fill]) :-
        N > 0,
        M is N-1,
        zeroNFill(M,Fill).
    
    accrueDeBruijn(NBits,SoFar,Final) :-
        NBits = [Bit|_],
        shorten(NBits,Short),
        Opp is 1 - Bit,
        not(alreadyFound([Opp|Short],SoFar)),
        !,
        accrueDeBruijn([Opp|Short],[Opp|SoFar],Final).
    accrueDeBruijn(NBits,SoFar,Final) :-
        NBits = [Bit|_],
        shorten(NBits,Short),
        not(alreadyFound([Bit|Short],SoFar)),
        !,
        accrueDeBruijn([Bit|Short],[Bit|SoFar],Final).
    accrueDeBruijn(_,Final,Final).
    
    shorten([_],[ ]) :- !.
    shorten([H|T],[H|S]) :- shorten(T,S).
    
    /* alreadyFound(NBits,DeBruijn) */
    alreadyFound(NBits,DeBruijn) :-
        initialSeq(NBits,DeBruijn).
    alreadyFound(NBits,[_|DeBruijn]) :-
        alreadyFound(NBits,DeBruijn).
    
    initialSeq([ ],_).
    initialSeq([H|T],[H|L]) :-
        initialSeq(T,L).
    
    zeroStrip([0|T],S) :- !, zeroStrip(T,S).
    zeroStrip(S,S).
    
    下面是我后续练习的代码,pattern/2,它通过添加到尾部来构建列表。即使考虑到谓词initialSeq/2是从上面重用的,结果实现也稍微紧凑一些:

    /* follow-up, build De Bruijn sequence by adding to tail */
    pattern(1,[0,1]).
    pattern(N,DeBruijn) :-
        N > 1,
        zeroNFront(N,[1|X],DeBruijn),
        DeBruijn = [0|NBits],
        patternAux(N,DeBruijn,NBits,[1|X],1),
        !.
    
    zeroNFront(0,Last,Last).
    zeroNFront(N,List,Last) :-
        N > 0,
        M is N-1,
        zeroNFront(M,[0|List],Last).
    
    patternAux(N,DeBruijn,_,[1,1],C) :-
        C is N-1,
        !.
    patternAux(N,DeBruijn,NBits,[Bit|X],C) :-
        Opp is 1-Bit,
        X = [Opp|Y],
        NBits = [_|MBits],
        not(alreadyFoundAux(DeBruijn,MBits,Y)),
        patternAux(N,DeBruijn,MBits,[Opp|Y],Opp).
    patternAux(N,DeBruijn,NBits,[Bit|X],C) :-
        X = [Bit|Y],
        NBits = [_|MBits],
        ( Bit = 1 -> D is C+1 ; D = 0 ),
        patternAux(N,DeBruijn,MBits,[Bit|Y],D).
    
    alreadyFoundAux(L,L,[ ]) :- !, fail.
    alreadyFoundAux(K,L,[ ]) :-
        initialSeq(L,K).
    alreadyFoundAux([_|K],L,Y) :-
        alreadyFoundAux(K,L,Y).
    

    注意:对于相同的N,binaryDeBruijnSeq/2的结果将是模式/2

    的反向列表,这看起来很像家庭作业。你已经做了什么,你被困在哪里了,你的问题是什么?没有打电话吗?您是否在生成循环或将其展平到列表中时遇到问题?