如何交换序言列表中的三乘三元素?

Rob*_*rtM 4 swap list bioinformatics prolog dcg

我正在 Prolog 中进行练习,但被卡住了。我需要将列表中的三个相邻项目与另外三个元素交换。

那是:

| ?- swap([c,g,g,a,t,t,g,c,a,a], X).

X = [a,t,t,c,g,g,g,c,a,a]
X = [g,c,a,a,t,t,c,g,g,a]
X = [c,g,g,g,c,a,a,t,t,a]
X = [c,a,a,a,t,t,g,c,g,g]
.
.
.
Run Code Online (Sandbox Code Playgroud)

这是我到目前为止:

swap([H1, H2, H3, H4, H5, H6|T1], X) :-
     X = [H4, H5, H6, H1, H2, H3|T1];
     swap([H2, H3, H4, H5, H6|T1], X);
     swap([H1, H2, H3, H4, H5|T1], X).
Run Code Online (Sandbox Code Playgroud)

这个输出是:

| ?- swap([c,g,g,a,t,t,g,c,a,a], X).

X = [a, t, t, c, g, g, g, c, a, a] ;
X = [t, t, g, g, g, a, c, a, a] ;
X = [t, g, c, g, a, t, a, a] ;
X = [g, c, a, a, t, t, a] ;
X = [c, a, a, t, t, g] ;
X = [c, a, a, a, t, t] ;
X = [g, c, a, g, a, t, a] ;
X = [c, a, a, a, t, g] ;
X = [c, a, a, g, a, t] ;
X = [t, g, c, g, g, a, a, a] ;
X = [g, c, a, g, a, t, a] ;
X = [c, a, a, a, t, g] ;
X = [c, a, a, g, a, t] ;
X = [g, c, a, g, g, a, a] ;
X = [c, a, a, g, a, g] ;
X = [c, a, a, g, g, a] ;
X = [t, t, g, c, g, g, c, a, a] ;
X = [t, g, c, g, g, t, a, a] ;
X = [g, c, a, g, t, t, a] ;
X = [c, a, a, t, t, g] ;
X = [c, a, a, g, t, t] ;
X = [g, c, a, g, g, t, a] ;
X = [c, a, a, g, t, g] ;
X = [c, a, a, g, g, t] ;
X = [t, g, c, c, g, g, a, a] ;
X = [g, c, a, g, g, t, a] ;
X = [c, a, a, g, t, g] ;
X = [c, a, a, g, g, t] ;
X = [g, c, a, c, g, g, a] ;
X = [c, a, a, g, g, g] ;
X = [c, a, a, c, g, g] ;
false.
Run Code Online (Sandbox Code Playgroud)

我唯一的问题是每次递归都会丢失列表的某些部分,我不知道如何将其放回原处。

fal*_*lse 7

您似乎对描述 RNA 序列感兴趣。三元组,这听起来很像反密码子。要使这些序列更具可读性,请使用:

:- set_prolog_flag(double_quotes, chars).
Run Code Online (Sandbox Code Playgroud)

这允许您"attac"代替[a,t,t,a,c]. 看看这个如何获得紧凑的答案。

现在交换。最简单的方法是先勾勒出你想要的:

... Triple1 ... Triple2 ...  is the OldSequence

... Triple2 ... Triple1 ...  is the NewSequence
Run Code Online (Sandbox Code Playgroud)

其中 ... 对于两个序列都是相同的。所有这些都可以使用 DCG 轻松转换。

tripleswap(OldSequence, NewSequence) :-
   dif(T1,T2),
   phrase( ( seq(A), triple(T1), seq(B), triple(T2), seq(C) ), OldSequence),
   phrase( ( seq(A), triple(T2), seq(B), triple(T1), seq(C) ), NewSequence).

seq([]) --> [].
seq([B|Bs]) --> [B], seq(Bs).

triple([A,B,C]) --> [A,B,C].
Run Code Online (Sandbox Code Playgroud)

每当您不信任 DCG 定义时,只需使用phrase/2. 喜欢

?- phrase(triple(T1), Bs).
T1 = Bs, Bs = [_A,_B,_C].
Run Code Online (Sandbox Code Playgroud)

非末端triple//1描述了 3 个元素(大概是核苷酸)的序列。

seq//1 是一个任意长的序列。

存在具有更好终止条件的解决方案,但它们的可读性较差,并且通常需要某些在一般情况下难以维持的假设。这是一个如此简单的改进:

samelength([], []).
samelength([_|Xs], [_|Ys]) :-
   samelength(Xs, Ys).
Run Code Online (Sandbox Code Playgroud)

并添加samelength(OldSequence, NewSeqence)为第一个目标。现在,tripleswap/2终止 iffsamelength/2终止。所以参数之一应该是一个固定长度的列表。

另请注意,我认为"cccccc"没有交换。这就是为什么我添加了dif(T1,T2).

?- tripleswap("cggattgcaa", Bs).
      Bs = "attcgggcaa"
   ;  Bs = "ttgacggcaa"
   ;  Bs = "tgcatcggaa"
   ;  Bs = "gcaattcgga"
   ;  Bs = "caaattgcgg"
   ;  Bs = "cttgggacaa"
   ;  Bs = "ctgctggaaa"
   ;  Bs = "cgcattggaa"
   ;  Bs = "ccaattggga"
   ;  Bs = "cgtgcgataa"
   ;  Bs = "cggcatgata"
   ;  Bs = "cgcaatggat"
   ;  Bs = "cgggcaatta"
   ;  Bs = "cggcaagatt"
   ;  Bs = "cggacaattg"
   ;  false.
Run Code Online (Sandbox Code Playgroud)

顺便说一句,自 1980 年代以来,就用于分子生物学。从...开始

David B. Searls,用定语从句语法研究 DNA 的语言学,NACLP 1989

以及同一作者以及当时罗斯·奥弗贝克(Ross Overbeek)的其他作品。所有这一切都发生在人类基因组计划的曙光中。