温馨提示:本文翻译自stackoverflow.com,查看原文请点击:其他 - How to swap three by three elements in a prolog list?
list prolog bioinformatics swap dcg

其他 - 如何在序言列表中交换三乘三元素?

发布于 2020-03-31 23:41:56

我正在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]
.
.
.

这是我到目前为止所拥有的:

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).

输出为:

| ?- 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.

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

查看更多

提问者
RobertM
被浏览
109
false 2020-02-03 03:21

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

:- set_prolog_flag(double_quotes, chars).

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

现在进行交换。最简单的方法是首先草绘所需内容:

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

... Triple2 ... Triple1 ...  is the NewSequence

两个序列的...相同。所有这些都可以使用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].

每当您不信任DCG定义时,请尝试使用phrase/2喜欢

?- phrase(triple(T1), Bs).
T1 = Bs, Bs = [_A,_B,_C].

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

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

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

samelength([], []).
samelength([_|Xs], [_|Ys]) :-
   samelength(Xs, Ys).

并添加samelength(OldSequence, NewSeqence)为第一个目标。现在,tripleswap/2终止如果samelength/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.

自1980年代以来,BTW,被用于分子生物学。从...开始

David B. Searls,《使用定句从句研究DNA的语言学》,NACLP,1989年

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