有人可以解释这个Prolog代码

时间:2016-01-21 21:06:52

标签: list prolog

aminoseq(X) :-
   aminoseq(X, []).

aminoseq([], X) :-
   print(X).
aminoseq([A|B], X) :-
   aminotodna(A, Y),
   append(X, Y, Z),
   aminoseq(B, Z).

此Prolog代码允许用户输入列表并将该列表与预设的aminotodna列表组合并显示两个结果。我不明白哪一部分做了什么...我想知道将来的工作。 任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:2)

首先,aminoseq/1调用aminoseq/2,暗示aminoseq/2的第二个参数是某种状态变量,其初始值为空列表。

接下来,aminoseq/2以递归方式处理第一个参数,即一个列表。当列表变空时(我假设它是氨基酸列表或其他东西)它只打印第二个参数。这是aminoseq/2的第一个条款。

接下来,aminoseq/2的第二个条款。它试图将氨基酸A(第一个参数列表中的当前第一个项目)转换为其他东西(DNA,我猜)并将其称为Y。然后它将X(当前&#34;状态&#34;参数)附加到Y,给出Z,然后将其与参数列表中的其余项重复。< / p>

我对生物学知之甚少,但我可以猜测,这里要发生的是你想要传递氨基酸列表并找回DNA碱基列表。这不是一种非常有效的方法(特别是,我有点讨厌你在aminoseq/2结束时打印),但它会完成任务。我建议您使用trace/0检查输出,看看Prolog正在尝试做什么。

什么部分正在做什么?所有的实际工作都在aminotodna/2完成,这是从氨基酸到密码子的实际表格。这段代码的其余部分只是管理数据结构,列表。

我会更像这样解决问题:

amino_dna(gly, [g,g,g]).
amino_dna(gly, [g,g,a]).
% ...
amino_dna(lys, [a,a,g]).
% ...
amino_dna(ser, [t,c,g]).
amino_dna(pro, [c,c,c]).

amino_acid_dna_sequence([], []).
amino_acid_dna_sequence([Acid|Acids], [C1,C2,C3|DNA]) :-
    amino_dna(Acid, [C1,C2,C3]),
    amino_acid_dna_sequence(Acids, DNA).

我发现这更直接:少了append/3敲打,没有I / O与逻辑关系的混合。它可以在两个方向上驱动:

?- amino_acid_dna_sequence([lys,ser,pro], X).
X = [a, a, g, t, c, g, c, c, c].

?- amino_acid_dna_sequence([lys,gly,pro], X).
X = [a, a, g, g, g, g, c, c, c] ;
X = [a, a, g, g, g, a, c, c, c].

?- amino_acid_dna_sequence(Aminos, [a,a,g,t,c,g,c,c,c]).
Aminos = [lys, ser, pro] ;
false.

答案 1 :(得分:2)

除了丹尼尔写的(+1)之外,我还有以下两点:

  1. 从关系名称中删除_to_。由于可以在所有方向上使用纯关系,因此使用暗示方向的名称是没有意义的。

  2. 在描述列表时始终考虑使用。它们通常使您的代码更容易阅读,因为它们需要更少的参数和变量名称。

  3. 我因此建议:

    amino_dna(gly) --> [g,g,g].
    amino_dna(gly) --> [g,g,a].
    % ...
    amino_dna(lys) --> [a,a,g].
    % ...
    amino_dna(ser) --> [t,c,g].
    amino_dna(pro) --> [c,c,c].
    
    amino_sequence([]) --> [].
    amino_sequence([Acid|Acids]) -->
        amino_dna(Acid),
        amino_sequence(Acids).
    

    示例查询:

    ?- length(Ls, _), phrase(amino_sequence(As), Ls).
    As = Ls, Ls = [] ;
    As = [gly],
    Ls = [g, g, g] ;
    As = [gly],
    Ls = [g, g, a] ;
    As = [lys],
    Ls = [a, a, g] ;
    As = [ser],
    Ls = [t, c, g] ;
    etc.
    

    请注意使用length/2进行公平查点。