我正在尝试学习基本的Prolog。我已经阅读了一些关于列表,变量和if /和逻辑的基本结构的基础教程。我试图帮助学习其中一些项目是为了匹配DNA序列。
基本上我希望它能匹配DNA序列的反向赞美。
示例输出如下所示:
?- dnamatch([t, t, a, c],[g, t, a, a]).
true
虽然它最有可能相对简单,但是Prolog的新版本我正在考虑它。
我首先定义了DNA对的基本匹配规则:
pair(a,t).
pair(g,c).
etc...
然后我会尝试以某种方式将其实现到列表中,但我不确定如何使这个逻辑适用于更长的序列列表。我不确定我的尝试开始是否是正确的方法。任何帮助将不胜感激。
答案 0 :(得分:6)
由于您的关系是描述列表,您可以选择使用DCG。您可以像这样描述互补核碱基:
complementary(t) --> % thymine is complementary to
[a]. % adenine
complementary(a) --> % adenine is complementary to
[t]. % thymine
complementary(g) --> % guanine is complementary to
[c]. % cytosine
complementary(c) --> % cytosine is complementary to
[g]. % guanine
这对应于你的谓词对/ 2。要以相反的顺序描述键合序列,您可以这样继续:
bond([]) --> % the empty sequence
[]. % doesn't bond
bond([A|As]) --> % the sequence [A|As] bonds with
bond(As), % a bonding sequence to As (in reverse order)
complementary(A). % followed by the complementary nucleobase of A
通过首先写入递归目标然后将描述互补核碱基的目标写入列表头部的目标来实现相反的顺序。您可以使用短语/ 2进行查询,如下所示:
?- phrase(bond([t,t,a,c]),S).
S = [g,t,a,a]
或者您可以使用包含短语/ 2的单个目标的包装谓词:
seq_complseq(D,M) :-
phrase(bond(D),M).
然后查询它:
?- seq_complseq([t,t,a,c],C).
C = [g,t,a,a]
我发现使用DCG的列表描述比相应的谓词版本更容易阅读。当然,以相反顺序描述互补序列是相对容易的任务。但是,一旦你想要描述更复杂的结构,比如说cloverleaf structure tRNA的{{3}} DCG就派上用场了。
答案 1 :(得分:1)
答案 2 :(得分:1)
如果你想避免穿越两次,你也可以这样做吗?
rev_comp(DNA, RC) :-
rev_comp(DNA, [], RC).
rev_comp([], RC, RC).
rev_comp([X|Xs], RC0, RC) :-
pair(X, Y),
rev_comp(Xs, [Y|RC0], RC).
然后:
?- rev_comp([t,c,g,a], RC).
RC = [t, c, g, a].
这只是reverse
和maplist
的手工编码合并。这值得么?也许,也许不是。可能不是。
既然我已经考虑了一下,你也可以用foldl
进行反转,但现在你真的想要反转,所以它比烦人更有用。
rev_comp([], []).
rev_comp([X|Xs], Ys) :-
pair(X, Y),
foldl(rc, Xs, [Y], Ys).
rc(X, Ys, [Y|Ys]) :- pair(X, Y).
但这比上面的解决方案更不明显,上面的解决方案仍然不如solution by @Capellic那么明显,所以也许你可以查看我写的代码,但请不要写这样的代码,除非你当然回答问题Stackoverflow,想要看起来聪明或留下深刻印象的女孩,请求你帮助大学锻炼。