List 如何在prolog列表中交换三乘三的元素?
我在用Prolog做练习,我被卡住了。 我需要用另外三个元素交换列表中的三个相邻项 即:List 如何在prolog列表中交换三乘三的元素?,list,prolog,bioinformatics,swap,dcg,List,Prolog,Bioinformatics,Swap,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] . . . 这就是我到目前为止所做的: swap([H1, H2, H3, H4, H5, H6|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 = [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.
我唯一的问题是,每次递归都会丢失列表中的一部分,我不知道如何将其放回去。基本上,这可以分为两个子问题:
swap(L, X) :-
swap1(L, S1, S2, T, X, Q),
swap2(T, S1, S2, Q).
其中,L
是我们需要执行交换的列表,X
是与结果统一的列表,S1
和S2
是我们选择交换的序列,T
是第一次选择后的剩余元素,Q
是要交换的列表第二个序列后的部分
因此,第一个swap1
可以实现为:
swap1([A1, A2, A3|T], [A1, A2, A3], [B1, B2, B3], T, [B1, B2, B3|Q], Q).
swap1([A1|T], A, B, R, [A1|Rest], S) :-
swap1(T, A, B, R, Rest, S).
对于给定的样本列表,这将产生:
?- swap1([c,g,g,a,t,t,g,c,a,a], A, [B1, B2, B3], T, X, R).
A = [c, g, g],
T = [a, t, t, g, c, a, a],
X = [B1, B2, B3|R] ;
A = [g, g, a],
T = [t, t, g, c, a, a],
X = [c, B1, B2, B3|R] ;
A = [g, a, t],
T = [t, g, c, a, a],
X = [c, g, B1, B2, B3|R] ;
A = [a, t, t],
T = [g, c, a, a],
X = [c, g, g, B1, B2, B3|R] ;
A = [t, t, g],
T = [c, a, a],
X = [c, g, g, a, B1, B2, B3|R] ;
A = [t, g, c],
T = [a, a],
X = [c, g, g, a, t, B1, B2, B3|R] ;
A = [g, c, a],
T = [a],
X = [c, g, g, a, t, t, B1, B2, B3|...] ;
A = [c, a, a],
T = [],
X = [c, g, g, a, t, t, g, B1, B2|...] ;
false.
因此,本文提出了八种方法来选择可用于交换的三个相邻序列
然后,第二次交换需要在剩余列表中找到三个相邻的元素进行交换,并将由swap1/6
拾取的元素放在从中拾取元素的位置,如:
swap2([B1,B2,B3|R], [A1,A2,A3], [B1, B2, B3], [A1,A2,A3|R]).
swap2([B1|R], As, Bs, [B1|T]) :-
swap2(R, As, Bs, T).
对于给定的样本数据,这为我们提供了:
?- 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, a, c, g, g, c, a, a] ;
X = [t, g, c, a, t, c, g, g, a, a] ;
X = [g, c, a, a, t, t, c, g, g, a] ;
X = [c, a, a, a, t, t, g, c, g, g] ;
X = [c, t, t, g, g, g, a, c, a, a] ;
X = [c, t, g, c, t, g, g, a, a, a] ;
X = [c, g, c, a, t, t, g, g, a, a] ;
X = [c, c, a, a, t, t, g, g, g, a] ;
X = [c, g, t, g, c, g, a, t, a, a] ;
X = [c, g, g, c, a, t, g, a, t, a] ;
X = [c, g, c, a, a, t, g, g, a, t] ;
X = [c, g, g, g, c, a, a, t, t, a] ;
X = [c, g, g, c, a, a, g, a, t, t] ;
X = [c, g, g, a, c, a, a, t, t, g] ;
false.
?-交换([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,a,c,g,g,c,a,a];
X=[t,g,c,a,t,c,g,g,a,a];
X=[g,c,a,a,t,t,c,g,g,a];
X=[c,a,a,a,t,t,g,c,g,g];
X=[c,t,t,g,g,a,c,a,a];
X=[c,t,g,c,t,g,g,a,a];
X=[c,g,c,a,t,t,g,g,a,a];
X=[c,c,a,a,t,t,g,g,g,a];
X=[c,g,t,g,c,g,a,t,a];
X=[c,g,g,c,a,t,g,a,t,a];
X=[c,g,c,a,a,t,g,g,a,t];
X=[c,g,g,g,c,a,a,t,t,a];
X=[c,g,g,c,a,a,g,a,t,t];
X=[c,g,g,a,c,a,a,t,t,g];
错误。
这里,交换的位置用黑体字书写。您似乎对描述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).
并添加samelelength(OldSequence,NewSeqence)
作为第一个目标。现在,tripleswap/2
终止iffsamelelength/2
终止。所以其中一个参数应该是一个固定长度的列表
还请注意,我认为“cccccc”
没有互换。这就是为什么我添加了dif(T1,T2)
顺便说一句,自20世纪80年代以来,s就被用于分子生物学。从
David B.Searls,《用定分句语法研究DNA语言学》,NACLP 1989
而同一作者和罗斯的其他作品也在那个时候超额完成了。所有这一切都发生在世纪之初。我认为排列/2将有助于: 交换(Es,Sw):-三元组(Es,Ts),置换(Ts,Sw0),附加(Sw0,Sw)。 三元组([A,B,C|Es],[A,B,C]| Ts]):-!,三元组(Es,Ts)。 三元组([],[]):-!。 三元组(R,[R])。 屈服
?- swap([c,g,g, a,t,t, g,c,a], X).
X = [c, g, g, a, t, t, g, c, a] ;
X = [c, g, g, g, c, a, a, t, t] ;
X = [a, t, t, c, g, g, g, c, a] ;
X = [a, t, t, g, c, a, c, g, g] ;
X = [g, c, a, c, g, g, a, t, t] ;
X = [g, c, a, a, t, t, c, g, g] ;
false.
注意:triples/2允许尾部不包含三重数据,但您可以删除此功能(可能不需要),只需删除最后一个子句:
triples(R[R])。%放下这个
那么这些削减就没用了,干脆放弃吧:
triples([],[])。%对于本例中的样式,请移到第一个子句
三元组([A,B,C|Es],[A,B,C]| Ts]):-三元组(Es,Ts)。
您好,谢谢您的帮助。这个练习是关于研究两个物种的接近程度。我成功地完成了练习的第一步(用另外两个相同类型的相邻核苷酸交换另两个,例如:[c,g,g,t]=[c,a,a,a,t]。这是第二部分。我是prolog新手,所以我不知道可以用DCG完成。你能解释一下“triple([a,B,c])-->[a,B,c]”是如何翻译成的吗?
?- swap([c,g,g, a,t,t, g,c,a], X).
X = [c, g, g, a, t, t, g, c, a] ;
X = [c, g, g, g, c, a, a, t, t] ;
X = [a, t, t, c, g, g, g, c, a] ;
X = [a, t, t, g, c, a, c, g, g] ;
X = [g, c, a, c, g, g, a, t, t] ;
X = [g, c, a, a, t, t, c, g, g] ;
false.