#include "unboxery.h" #ifdef USE_GLASGOW_HACKS module Main(mainPrimIO) where import PreludeGlaST #else module Main(main) where #endif import Types import RA import RC import RG import RU #ifdef USE_UNBOXED_FLOATS -- EASY WAY: --atan2Float# :: Float# -> Float# -> Float# --atan2Float# x y = case atan2 (F# x) (F# y) of { F# z -> z } atan2Float# :: Float# -> Float# -> Float# atan2Float# y x = if x `geFloat#` 0.0# then if y `eqFloat#` 0.0# then 0.0# else atanFloat# (y `divideFloat#` x) else if x `ltFloat#` 0.0# then if y `eqFloat#` 0.0# then pi# else atanFloat# (y `divideFloat#` x) `plusFloat#` pi# else if y `gtFloat#` 0.0# then pi# `divideFloat#` 2.0# else negpi# `divideFloat#` 2.0# where pi# = 3.1415926536# negpi# = -3.1415926536# #endif -- File: "nucleic2.m" -- -- Author: Marc Feeley (feeley@iro.umontreal.ca) -- -- Last modified: June 6, 1994 -- -- This program is a modified version of the program described in the paper: -- -- M. Feeley, M. Turcotte, G. Lapalme, "Using Multilisp for Solving -- Constraint Satisfaction Problems: an Application to Nucleic Acid 3D -- Structure Determination" published in the journal "Lisp and Symbolic -- Computation". -- -- The differences between this program and the original are described in -- the paper: -- -- "???" published in the "Journal of Functional Programming". -- -- POINTS ------------------------------------------------------------------ pt_sub (Pt x1 y1 z1) (Pt x2 y2 z2) = Pt (x1 _SUB_ x2) (y1 _SUB_ y2) (z1 _SUB_ z2) pt_dist (Pt x1 y1 z1) (Pt x2 y2 z2) = _SQRT_ ((dx _MUL_ dx) _ADD_ (dy _MUL_ dy) _ADD_ (dz _MUL_ dz)) where dx = x1 _SUB_ x2 dy = y1 _SUB_ y2 dz = z1 _SUB_ z2 pt_phi (Pt x y z) = _ATAN2_ ((_COS_ b _MUL_ z) _ADD_ (_SIN_ b _MUL_ x)) y where b = _ATAN2_ x z pt_theta (Pt x y z) = _ATAN2_ x z -- -- COORDINATE TRANSFORMATIONS ---------------------------------------------- -- The notation for the transformations follows "Paul, R.P. (1981) Robot -- Manipulators. MIT Press." with the exception that our transformation -- matrices don't have the perspective terms and are the transpose of -- Paul's one. See also "M\"antyl\"a, M. (1985) An Introduction to -- Solid Modeling, Computer Science Press" Appendix A. -- -- The components of a transformation matrix are named like this: -- -- a b c -- d e f -- g h i -- tx ty tz -- -- The components tx, ty, and tz are the translation vector. tfo_id = Tfo FL_LIT(1.0) FL_LIT(0.0) FL_LIT(0.0) FL_LIT(0.0) FL_LIT(1.0) FL_LIT(0.0) FL_LIT(0.0) FL_LIT(0.0) FL_LIT(1.0) FL_LIT(0.0) FL_LIT(0.0) FL_LIT(0.0) -- The function "tfo-apply" multiplies a transformation matrix, tfo, by a -- point vector, p. The result is a new point. tfo_apply (Tfo a b c d e f g h i tx ty tz) (Pt x y z) = Pt ((x _MUL_ a) _ADD_ (y _MUL_ d) _ADD_ (z _MUL_ g) _ADD_ tx) ((x _MUL_ b) _ADD_ (y _MUL_ e) _ADD_ (z _MUL_ h) _ADD_ ty) ((x _MUL_ c) _ADD_ (y _MUL_ f) _ADD_ (z _MUL_ i) _ADD_ tz) -- The function "tfo-combine" multiplies two transformation matrices A and B. -- The result is a new matrix which cumulates the transformations described -- by A and B. tfo_combine (Tfo a_a a_b a_c a_d a_e a_f a_g a_h a_i a_tx a_ty a_tz) (Tfo b_a b_b b_c b_d b_e b_f b_g b_h b_i b_tx b_ty b_tz) = Tfo ((a_a _MUL_ b_a) _ADD_ (a_b _MUL_ b_d) _ADD_ (a_c _MUL_ b_g)) ((a_a _MUL_ b_b) _ADD_ (a_b _MUL_ b_e) _ADD_ (a_c _MUL_ b_h)) ((a_a _MUL_ b_c) _ADD_ (a_b _MUL_ b_f) _ADD_ (a_c _MUL_ b_i)) ((a_d _MUL_ b_a) _ADD_ (a_e _MUL_ b_d) _ADD_ (a_f _MUL_ b_g)) ((a_d _MUL_ b_b) _ADD_ (a_e _MUL_ b_e) _ADD_ (a_f _MUL_ b_h)) ((a_d _MUL_ b_c) _ADD_ (a_e _MUL_ b_f) _ADD_ (a_f _MUL_ b_i)) ((a_g _MUL_ b_a) _ADD_ (a_h _MUL_ b_d) _ADD_ (a_i _MUL_ b_g)) ((a_g _MUL_ b_b) _ADD_ (a_h _MUL_ b_e) _ADD_ (a_i _MUL_ b_h)) ((a_g _MUL_ b_c) _ADD_ (a_h _MUL_ b_f) _ADD_ (a_i _MUL_ b_i)) ((a_tx _MUL_ b_a) _ADD_ (a_ty _MUL_ b_d) _ADD_ (a_tz _MUL_ b_g) _ADD_ b_tx) ((a_tx _MUL_ b_b) _ADD_ (a_ty _MUL_ b_e) _ADD_ (a_tz _MUL_ b_h) _ADD_ b_ty) ((a_tx _MUL_ b_c) _ADD_ (a_ty _MUL_ b_f) _ADD_ (a_tz _MUL_ b_i) _ADD_ b_tz) -- The function "tfo-inv-ortho" computes the inverse of a homogeneous -- transformation matrix. tfo_inv_ortho (Tfo a b c d e f g h i tx ty tz) = Tfo a d g b e h c f i (_NEG_ ((a _MUL_ tx) _ADD_ (b _MUL_ ty) _ADD_ (c _MUL_ tz))) (_NEG_ ((d _MUL_ tx) _ADD_ (e _MUL_ ty) _ADD_ (f _MUL_ tz))) (_NEG_ ((g _MUL_ tx) _ADD_ (h _MUL_ ty) _ADD_ (i _MUL_ tz))) -- Given three points p1, p2, and p3, the function "tfo-align" computes -- a transformation matrix such that point p1 gets mapped to (0,0,0), p2 gets -- mapped to the Y axis and p3 gets mapped to the YZ plane. tfo_align (Pt x1 y1 z1) (Pt x2 y2 z2) (Pt x3 y3 z3) = Tfo ((cost _MUL_ cosr) _SUB_ (cospsint _MUL_ sinr)) sinpsint ((cost _MUL_ sinr) _ADD_ (cospsint _MUL_ cosr)) (sinp _MUL_ sinr) cosp (_NEG_ (sinp _MUL_ cosr)) ((_NEG_ (sint _MUL_ cosr)) _SUB_ (cospcost _MUL_ sinr)) sinpcost ((_NEG_ (sint _MUL_ sinr)) _ADD_ (cospcost _MUL_ cosr)) ((x _MUL_ cosr) _SUB_ (z _MUL_ sinr)) y ((x _MUL_ sinr) _ADD_ (z _MUL_ cosr)) where x31 = x3 _SUB_ x1 y31 = y3 _SUB_ y1 z31 = z3 _SUB_ z1 rotpy = pt_sub (Pt x2 y2 z2) (Pt x1 y1 z1) phi = pt_phi rotpy theta = pt_theta rotpy sinp = _SIN_ phi sint = _SIN_ theta cosp = _COS_ phi cost = _COS_ theta sinpsint = sinp _MUL_ sint sinpcost = sinp _MUL_ cost cospsint = cosp _MUL_ sint cospcost = cosp _MUL_ cost rotpz = Pt ((cost _MUL_ x31) _SUB_ (sint _MUL_ z31)) ((sinpsint _MUL_ x31) _ADD_ (cosp _MUL_ y31) _ADD_ (sinpcost _MUL_ z31)) ((cospsint _MUL_ x31) _ADD_ (_NEG_ (sinp _MUL_ y31)) _ADD_ (cospcost _MUL_ z31)) rho = pt_theta rotpz cosr = _COS_ rho sinr = _SIN_ rho x = ((_NEG_ (x1 _MUL_ cost)) _ADD_ (z1 _MUL_ sint)) y = (((_NEG_ (x1 _MUL_ sinpsint)) _SUB_ (y1 _MUL_ cosp)) _SUB_ (z1 _MUL_ sinpcost)) z = (((_NEG_ (x1 _MUL_ cospsint)) _ADD_ (y1 _MUL_ sinp)) _SUB_ (z1 _MUL_ cospcost)) -- -- NUCLEIC ACID CONFORMATIONS DATA BASE ------------------------------------ -- Numbering of atoms follows the paper: -- -- IUPAC-IUB Joint Commission on Biochemical Nomenclature (JCBN) -- (1983) Abbreviations and Symbols for the Description of -- Conformations of Polynucleotide Chains. Eur. J. Biochem 131, -- 9-15. -- Define part common to all 4 nucleotide types. -- dgf_base_tfo ; defines the standard position for wc and wc_dumas -- p_o3XXX_275_tfo ; defines the standard position for the connect function -- p_o3XXX_180_tfo -- p_o3XXX_60_tfo -- p o1p o2p o5XXX c5XXX h5XXX h5XXXXXX c4XXX h4XXX o4XXX c1XXX h1XXX c2XXX h2XXXXXX o2XXX h2XXX c3XXX -- h3XXX o3XXX n1 n3 c2 c4 c5 c6 is_A (Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo p o1p o2p o5XXX c5XXX h5XXX h5XXXXXX c4XXX h4XXX o4XXX c1XXX h1XXX c2XXX h2XXXXXX o2XXX h2XXX c3XXX h3XXX o3XXX n1 n3 c2 c4 c5 c6 (A n6 n7 n9 c8 h2 h61 h62 h8)) = True is_A x = False is_C (Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo p o1p o2p o5XXX c5XXX h5XXX h5XXXXXX c4XXX h4XXX o4XXX c1XXX h1XXX c2XXX h2XXXXXX o2XXX h2XXX c3XXX h3XXX o3XXX n1 n3 c2 c4 c5 c6 (C n4 o2 h41 h42 h5 h6)) = True is_C x = False is_G (Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo p o1p o2p o5XXX c5XXX h5XXX h5XXXXXX c4XXX h4XXX o4XXX c1XXX h1XXX c2XXX h2XXXXXX o2XXX h2XXX c3XXX h3XXX o3XXX n1 n3 c2 c4 c5 c6 (G n2 n7 n9 c8 o6 h1 h21 h22 h8)) = True is_G x = False nuc_C1XXX (Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo p o1p o2p o5XXX c5XXX h5XXX h5XXXXXX c4XXX h4XXX o4XXX c1XXX h1XXX c2XXX h2XXXXXX o2XXX h2XXX c3XXX h3XXX o3XXX n1 n3 c2 c4 c5 c6 x) = c1XXX nuc_C2 (Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo p o1p o2p o5XXX c5XXX h5XXX h5XXXXXX c4XXX h4XXX o4XXX c1XXX h1XXX c2XXX h2XXXXXX o2XXX h2XXX c3XXX h3XXX o3XXX n1 n3 c2 c4 c5 c6 x) = c2 nuc_C3XXX (Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo p o1p o2p o5XXX c5XXX h5XXX h5XXXXXX c4XXX h4XXX o4XXX c1XXX h1XXX c2XXX h2XXXXXX o2XXX h2XXX c3XXX h3XXX o3XXX n1 n3 c2 c4 c5 c6 x) = c3XXX nuc_C4 (Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo p o1p o2p o5XXX c5XXX h5XXX h5XXXXXX c4XXX h4XXX o4XXX c1XXX h1XXX c2XXX h2XXXXXX o2XXX h2XXX c3XXX h3XXX o3XXX n1 n3 c2 c4 c5 c6 x) = c4 nuc_C4XXX (Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo p o1p o2p o5XXX c5XXX h5XXX h5XXXXXX c4XXX h4XXX o4XXX c1XXX h1XXX c2XXX h2XXXXXX o2XXX h2XXX c3XXX h3XXX o3XXX n1 n3 c2 c4 c5 c6 x) = c4XXX nuc_N1 (Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo p o1p o2p o5XXX c5XXX h5XXX h5XXXXXX c4XXX h4XXX o4XXX c1XXX h1XXX c2XXX h2XXXXXX o2XXX h2XXX c3XXX h3XXX o3XXX n1 n3 c2 c4 c5 c6 x) = n1 nuc_O3XXX (Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo p o1p o2p o5XXX c5XXX h5XXX h5XXXXXX c4XXX h4XXX o4XXX c1XXX h1XXX c2XXX h2XXXXXX o2XXX h2XXX c3XXX h3XXX o3XXX n1 n3 c2 c4 c5 c6 x) = o3XXX nuc_P (Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo p o1p o2p o5XXX c5XXX h5XXX h5XXXXXX c4XXX h4XXX o4XXX c1XXX h1XXX c2XXX h2XXXXXX o2XXX h2XXX c3XXX h3XXX o3XXX n1 n3 c2 c4 c5 c6 x) = p nuc_dgf_base_tfo (Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo p o1p o2p o5XXX c5XXX h5XXX h5XXXXXX c4XXX h4XXX o4XXX c1XXX h1XXX c2XXX h2XXXXXX o2XXX h2XXX c3XXX h3XXX o3XXX n1 n3 c2 c4 c5 c6 x) = dgf_base_tfo nuc_p_o3XXX_180_tfo (Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo p o1p o2p o5XXX c5XXX h5XXX h5XXXXXX c4XXX h4XXX o4XXX c1XXX h1XXX c2XXX h2XXXXXX o2XXX h2XXX c3XXX h3XXX o3XXX n1 n3 c2 c4 c5 c6 x) = p_o3XXX_180_tfo nuc_p_o3XXX_275_tfo (Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo p o1p o2p o5XXX c5XXX h5XXX h5XXXXXX c4XXX h4XXX o4XXX c1XXX h1XXX c2XXX h2XXXXXX o2XXX h2XXX c3XXX h3XXX o3XXX n1 n3 c2 c4 c5 c6 x) = p_o3XXX_275_tfo nuc_p_o3XXX_60_tfo (Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo p o1p o2p o5XXX c5XXX h5XXX h5XXXXXX c4XXX h4XXX o4XXX c1XXX h1XXX c2XXX h2XXXXXX o2XXX h2XXX c3XXX h3XXX o3XXX n1 n3 c2 c4 c5 c6 x) = p_o3XXX_60_tfo rA_N9 (Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo p o1p o2p o5XXX c5XXX h5XXX h5XXXXXX c4XXX h4XXX o4XXX c1XXX h1XXX c2XXX h2XXXXXX o2XXX h2XXX c3XXX h3XXX o3XXX n1 n3 c2 c4 c5 c6 (A n6 n7 n9 c8 h2 h61 h62 h8)) = n9 rG_N9 (Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo p o1p o2p o5XXX c5XXX h5XXX h5XXXXXX c4XXX h4XXX o4XXX c1XXX h1XXX c2XXX h2XXXXXX o2XXX h2XXX c3XXX h3XXX o3XXX n1 n3 c2 c4 c5 c6 (G n2 n7 n9 c8 o6 h1 h21 h22 h8)) = n9 -- Define remaining atoms for each nucleotide type. -- Database of nucleotide conformations: -- -- PARTIAL INSTANTIATIONS -------------------------------------------------- data Var = Var INT_TY Tfo Nuc -- If you want lazy computation, comment the next two definitions and -- uncomment the alternative definitions that follow. #ifdef USE_HARTEL_LAZINESS mk_var i t n = Var i t (make_relative_nuc t n) absolute_pos (Var i t n) p = p #else mk_var i t n = Var i t n absolute_pos (Var i t n) p = tfo_apply t p #endif atom_pos atom v@(Var i t n) = absolute_pos v (atom n) get_var id (v@(Var i t n):lst) = if i _EQ_INT_ id then v else get_var id lst make_relative_nuc t (Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo p o1p o2p o5XXX c5XXX h5XXX h5XXXXXX c4XXX h4XXX o4XXX c1XXX h1XXX c2XXX h2XXXXXX o2XXX h2XXX c3XXX h3XXX o3XXX n1 n3 c2 c4 c5 c6 (A n6 n7 n9 c8 h2 h61 h62 h8)) = Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo (tfo_apply t p) (tfo_apply t o1p) (tfo_apply t o2p) (tfo_apply t o5XXX) (tfo_apply t c5XXX) (tfo_apply t h5XXX) (tfo_apply t h5XXXXXX) (tfo_apply t c4XXX) (tfo_apply t h4XXX) (tfo_apply t o4XXX) (tfo_apply t c1XXX) (tfo_apply t h1XXX) (tfo_apply t c2XXX) (tfo_apply t h2XXXXXX) (tfo_apply t o2XXX) (tfo_apply t h2XXX) (tfo_apply t c3XXX) (tfo_apply t h3XXX) (tfo_apply t o3XXX) (tfo_apply t n1) (tfo_apply t n3) (tfo_apply t c2) (tfo_apply t c4) (tfo_apply t c5) (tfo_apply t c6) (A (tfo_apply t n6) (tfo_apply t n7) (tfo_apply t n9) (tfo_apply t c8) (tfo_apply t h2) (tfo_apply t h61) (tfo_apply t h62) (tfo_apply t h8) ) make_relative_nuc t (Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo p o1p o2p o5XXX c5XXX h5XXX h5XXXXXX c4XXX h4XXX o4XXX c1XXX h1XXX c2XXX h2XXXXXX o2XXX h2XXX c3XXX h3XXX o3XXX n1 n3 c2 c4 c5 c6 (C n4 o2 h41 h42 h5 h6)) = Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo (tfo_apply t p) (tfo_apply t o1p) (tfo_apply t o2p) (tfo_apply t o5XXX) (tfo_apply t c5XXX) (tfo_apply t h5XXX) (tfo_apply t h5XXXXXX) (tfo_apply t c4XXX) (tfo_apply t h4XXX) (tfo_apply t o4XXX) (tfo_apply t c1XXX) (tfo_apply t h1XXX) (tfo_apply t c2XXX) (tfo_apply t h2XXXXXX) (tfo_apply t o2XXX) (tfo_apply t h2XXX) (tfo_apply t c3XXX) (tfo_apply t h3XXX) (tfo_apply t o3XXX) (tfo_apply t n1) (tfo_apply t n3) (tfo_apply t c2) (tfo_apply t c4) (tfo_apply t c5) (tfo_apply t c6) (C (tfo_apply t n4) (tfo_apply t o2) (tfo_apply t h41) (tfo_apply t h42) (tfo_apply t h5) (tfo_apply t h6) ) make_relative_nuc t (Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo p o1p o2p o5XXX c5XXX h5XXX h5XXXXXX c4XXX h4XXX o4XXX c1XXX h1XXX c2XXX h2XXXXXX o2XXX h2XXX c3XXX h3XXX o3XXX n1 n3 c2 c4 c5 c6 (G n2 n7 n9 c8 o6 h1 h21 h22 h8)) = Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo (tfo_apply t p) (tfo_apply t o1p) (tfo_apply t o2p) (tfo_apply t o5XXX) (tfo_apply t c5XXX) (tfo_apply t h5XXX) (tfo_apply t h5XXXXXX) (tfo_apply t c4XXX) (tfo_apply t h4XXX) (tfo_apply t o4XXX) (tfo_apply t c1XXX) (tfo_apply t h1XXX) (tfo_apply t c2XXX) (tfo_apply t h2XXXXXX) (tfo_apply t o2XXX) (tfo_apply t h2XXX) (tfo_apply t c3XXX) (tfo_apply t h3XXX) (tfo_apply t o3XXX) (tfo_apply t n1) (tfo_apply t n3) (tfo_apply t c2) (tfo_apply t c4) (tfo_apply t c5) (tfo_apply t c6) (G (tfo_apply t n2) (tfo_apply t n7) (tfo_apply t n9) (tfo_apply t c8) (tfo_apply t o6) (tfo_apply t h1) (tfo_apply t h21) (tfo_apply t h22) (tfo_apply t h8) ) make_relative_nuc t (Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo p o1p o2p o5XXX c5XXX h5XXX h5XXXXXX c4XXX h4XXX o4XXX c1XXX h1XXX c2XXX h2XXXXXX o2XXX h2XXX c3XXX h3XXX o3XXX n1 n3 c2 c4 c5 c6 (U o2 o4 h3 h5 h6)) = Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo (tfo_apply t p) (tfo_apply t o1p) (tfo_apply t o2p) (tfo_apply t o5XXX) (tfo_apply t c5XXX) (tfo_apply t h5XXX) (tfo_apply t h5XXXXXX) (tfo_apply t c4XXX) (tfo_apply t h4XXX) (tfo_apply t o4XXX) (tfo_apply t c1XXX) (tfo_apply t h1XXX) (tfo_apply t c2XXX) (tfo_apply t h2XXXXXX) (tfo_apply t o2XXX) (tfo_apply t h2XXX) (tfo_apply t c3XXX) (tfo_apply t h3XXX) (tfo_apply t o3XXX) (tfo_apply t n1) (tfo_apply t n3) (tfo_apply t c2) (tfo_apply t c4) (tfo_apply t c5) (tfo_apply t c6) (U (tfo_apply t o2) (tfo_apply t o4) (tfo_apply t h3) (tfo_apply t h5) (tfo_apply t h6) ) -- -- SEARCH ------------------------------------------------------------------ -- Sequential backtracking algorithm search partial_inst [] constraint = [partial_inst] search partial_inst (h:t) constraint = try_assignments (h partial_inst) where try_assignments [] = [] try_assignments (v:vs) | constraint v partial_inst = (search (v:partial_inst) t constraint) ++ (try_assignments vs) | otherwise = try_assignments vs -- -- DOMAINS ----------------------------------------------------------------- -- Primary structure: strand A CUGCCACGUCUG, strand B CAGACGUGGCAG -- -- Secondary structure: strand A CUGCCACGUCUG -- ------------ -- GACGGUGCAGAC strand B -- -- Tertiary structure: -- -- 5XXX end of strand A C1----G12 3XXX end of strand B -- U2-------A11 -- G3-------C10 -- C4-----G9 -- C5---G8 -- A6 -- G6-C7 -- C5----G8 -- A4-------U9 -- G3--------C10 -- A2-------U11 -- 5' end of strand B C1----G12 3' end of strand A -- -- "helix", "stacked" and "connected" describe the spatial relationship -- between two consecutive nucleotides. E.g. the nucleotides C1 and U2 -- from the strand A. -- -- "wc" (stands for Watson-Crick and is a type of base-pairing), -- and "wc-dumas" describe the spatial relationship between -- nucleotides from two chains that are growing in opposite directions. -- E.g. the nucleotides C1 from strand A and G12 from strand B. -- Dynamic Domains -- Given, -- "ref" a nucleotide which is already positioned, -- "nuc" the nucleotide to be placed, -- and "tfo" a transformation matrix which expresses the desired -- relationship between "ref" and "nuc", -- the function "dgf-base" computes the transformation matrix that -- places the nucleotide "nuc" in the given relationship to "ref". dgf_base tfo v@(Var i t n) nuc = tfo_combine (nuc_dgf_base_tfo nuc) (tfo_combine tfo (tfo_inv_ortho x)) where x | is_A n = tfo_align (atom_pos nuc_C1XXX v) (atom_pos rA_N9 v) (atom_pos nuc_C4 v) | is_C n = tfo_align (atom_pos nuc_C1XXX v) (atom_pos nuc_N1 v) (atom_pos nuc_C2 v) | is_G n = tfo_align (atom_pos nuc_C1XXX v) (atom_pos rG_N9 v) (atom_pos nuc_C4 v) | otherwise = tfo_align (atom_pos nuc_C1XXX v) (atom_pos nuc_N1 v) (atom_pos nuc_C2 v) -- Placement of first nucleotide. reference nuc i partial_inst = [ mk_var i tfo_id nuc ] -- The transformation matrix for wc is from: -- -- Chandrasekaran R. et al (1989) A Re-Examination of the Crystal -- Structure of A-DNA Using Fiber Diffraction Data. J. Biomol. -- Struct. & Dynamics 6(6):1189-1202. wc_tfo = Tfo FL_LIT(-1.0000) FL_LIT(0.0028) FL_LIT(-0.0019) FL_LIT(0.0028) FL_LIT(0.3468) FL_LIT(-0.9379) FL_LIT(-0.0019) FL_LIT(-0.9379) FL_LIT(-0.3468) FL_LIT(-0.0080) FL_LIT(6.0730) FL_LIT(8.7208) wc nuc i j partial_inst = [ mk_var i (dgf_base wc_tfo (get_var j partial_inst) nuc) nuc ] wc_dumas_tfo = Tfo FL_LIT(-0.9737) FL_LIT(-0.1834) FL_LIT(0.1352) FL_LIT(-0.1779) FL_LIT(0.2417) FL_LIT(-0.9539) FL_LIT(0.1422) FL_LIT(-0.9529) FL_LIT(-0.2679) FL_LIT(0.4837) FL_LIT(6.2649) FL_LIT(8.0285) wc_dumas nuc i j partial_inst = [ mk_var i (dgf_base wc_dumas_tfo (get_var j partial_inst) nuc) nuc ] helix5XXX_tfo = Tfo FL_LIT(0.9886) FL_LIT(-0.0961) FL_LIT(0.1156) FL_LIT(0.1424) FL_LIT(0.8452) FL_LIT(-0.5152) FL_LIT(-0.0482) FL_LIT(0.5258) FL_LIT(0.8492) FL_LIT(-3.8737) FL_LIT(0.5480) FL_LIT(3.8024) helix5XXX nuc i j partial_inst = [ mk_var i (dgf_base helix5XXX_tfo (get_var j partial_inst) nuc) nuc ] helix3XXX_tfo = Tfo FL_LIT(0.9886) FL_LIT(0.1424) FL_LIT(-0.0482) FL_LIT(-0.0961) FL_LIT(0.8452) FL_LIT(0.5258) FL_LIT(0.1156) FL_LIT(-0.5152) FL_LIT(0.8492) FL_LIT(3.4426) FL_LIT(2.0474) FL_LIT(-3.7042) helix3XXX nuc i j partial_inst = [ mk_var i (dgf_base helix3XXX_tfo (get_var j partial_inst) nuc) nuc ] g37_a38_tfo = Tfo FL_LIT(0.9991) FL_LIT(0.0164) FL_LIT(-0.0387) FL_LIT(-0.0375) FL_LIT(0.7616) FL_LIT(-0.6470) FL_LIT(0.0189) FL_LIT(0.6478) FL_LIT(0.7615) FL_LIT(-3.3018) FL_LIT(0.9975) FL_LIT(2.5585) g37_a38 nuc i j partial_inst = mk_var i (dgf_base g37_a38_tfo (get_var j partial_inst) nuc) nuc stacked5XXX nuc i j partial_inst = (g37_a38 nuc i j partial_inst) : (helix5XXX nuc i j partial_inst) a38_g37_tfo = Tfo FL_LIT(0.9991) FL_LIT(-0.0375) FL_LIT(0.0189) FL_LIT(0.0164) FL_LIT(0.7616) FL_LIT(0.6478) FL_LIT(-0.0387) FL_LIT(-0.6470) FL_LIT(0.7615) FL_LIT(3.3819) FL_LIT(0.7718) FL_LIT(-2.5321) a38_g37 nuc i j partial_inst = mk_var i (dgf_base a38_g37_tfo (get_var j partial_inst) nuc) nuc stacked3XXX nuc i j partial_inst = a38_g37 nuc i j partial_inst : helix3XXX nuc i j partial_inst p_o3XXX nucs i j partial_inst = generate [] nucs where ref = get_var j partial_inst align = tfo_inv_ortho (tfo_align (atom_pos nuc_O3XXX ref) (atom_pos nuc_C3XXX ref) (atom_pos nuc_C4XXX ref)) generate domains [] = domains generate domains (n:ns) = generate ((mk_var i (tfo_combine (nuc_p_o3XXX_60_tfo n) align) n): (mk_var i (tfo_combine (nuc_p_o3XXX_180_tfo n) align) n): (mk_var i (tfo_combine (nuc_p_o3XXX_275_tfo n) align) n):domains) ns -- -- PROBLEM STATEMENT ------------------------------------------------------- -- Define anticodon problem -- Science 253:1255 Figure 3a, 3b and 3c anticodon_domains = [ reference rC INT_LIT(27), helix5XXX rC INT_LIT(28) INT_LIT(27), helix5XXX rA INT_LIT(29) INT_LIT(28), helix5XXX rG INT_LIT(30) INT_LIT(29), helix5XXX rA INT_LIT(31) INT_LIT(30), wc rU INT_LIT(39) INT_LIT(31), helix5XXX rC INT_LIT(40) INT_LIT(39), helix5XXX rU INT_LIT(41) INT_LIT(40), helix5XXX rG INT_LIT(42) INT_LIT(41), helix5XXX rG INT_LIT(43) INT_LIT(42), stacked3XXX rA INT_LIT(38) INT_LIT(39), stacked3XXX rG INT_LIT(37) INT_LIT(38), stacked3XXX rA INT_LIT(36) INT_LIT(37), stacked3XXX rA INT_LIT(35) INT_LIT(36), stacked3XXX rG INT_LIT(34) INT_LIT(35), -- <-. Distance p_o3XXX rCs INT_LIT(32) INT_LIT(31), -- | Constraint p_o3XXX rUs INT_LIT(33) INT_LIT(32) -- <-XXX 3.0 Angstroms ] -- Anticodon constraint anticodon_constraint v@(Var INT_LIT(33) t n) partial_inst = dist INT_LIT(34) _LE_FLT_ FL_LIT(3.0) where dist j = pt_dist p o3XXX where p = atom_pos nuc_P (get_var j partial_inst) o3XXX = atom_pos nuc_O3XXX v anticodon_constraint _ _ = True anticodon = search [] anticodon_domains anticodon_constraint -- Define pseudoknot problem -- Science 253:1255 Figure 4a and 4b pseudoknot_domains = [ reference rA INT_LIT(23), wc_dumas rU INT_LIT(8) INT_LIT(23), helix3XXX rG INT_LIT(22) INT_LIT(23), wc_dumas rC INT_LIT(9) INT_LIT(22), helix3XXX rG INT_LIT(21) INT_LIT(22), wc_dumas rC INT_LIT(10) INT_LIT(21), helix3XXX rC INT_LIT(20) INT_LIT(21), wc_dumas rG INT_LIT(11) INT_LIT(20), helix3XXX rU'{-'-} INT_LIT(19) INT_LIT(20), -- <-. wc_dumas rA INT_LIT(12) INT_LIT(19), -- | Distance -- -- | Constraint -- Helix 1 -- | 4.0 Angstroms helix3XXX rC INT_LIT(3) INT_LIT(19), -- | wc_dumas rG INT_LIT(13) INT_LIT(3), -- | helix3XXX rC INT_LIT(2) INT_LIT(3), -- | wc_dumas rG INT_LIT(14) INT_LIT(2), -- | helix3XXX rC INT_LIT(1) INT_LIT(2), -- | wc_dumas rG'{-'-} INT_LIT(15) INT_LIT(1), -- | -- -- | -- L2 LOOP -- | p_o3XXX rUs INT_LIT(16) INT_LIT(15), -- | p_o3XXX rCs INT_LIT(17) INT_LIT(16), -- | p_o3XXX rAs INT_LIT(18) INT_LIT(17), -- <-XXX -- -- L1 LOOP helix3XXX rU INT_LIT(7) INT_LIT(8), -- <-. p_o3XXX rCs INT_LIT(4) INT_LIT(3), -- | Constraint stacked5XXX rU INT_LIT(5) INT_LIT(4), -- | 4.5 Angstroms stacked5XXX rC INT_LIT(6) INT_LIT(5) -- <-XXX ] -- Pseudoknot constraint pseudoknot_constraint v@(Var i t n) partial_inst | i _EQ_INT_ INT_LIT(18) = dist INT_LIT(19) _LE_FLT_ FL_LIT(4.0) | i _EQ_INT_ INT_LIT(6) = dist INT_LIT(7) _LE_FLT_ FL_LIT(4.5) | otherwise = True where dist j = pt_dist p o3XXX where p = atom_pos nuc_P (get_var j partial_inst) o3XXX = atom_pos nuc_O3XXX v pseudoknot = search [] pseudoknot_domains pseudoknot_constraint -- -- TESTING ----------------------------------------------------------------- list_of_atoms n = list_of_common_atoms n ++ list_of_specific_atoms n list_of_common_atoms (Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo p o1p o2p o5XXX c5XXX h5XXX h5XXXXXX c4XXX h4XXX o4XXX c1XXX h1XXX c2XXX h2XXXXXX o2XXX h2XXX c3XXX h3XXX o3XXX n1 n3 c2 c4 c5 c6 x) = [p,o1p,o2p,o5XXX,c5XXX,h5XXX,h5XXXXXX,c4XXX,h4XXX,o4XXX,c1XXX,h1XXX,c2XXX,h2XXXXXX,o2XXX,h2XXX,c3XXX, h3XXX,o3XXX,n1,n3,c2,c4,c5,c6] list_of_specific_atoms (Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo p o1p o2p o5XXX c5XXX h5XXX h5XXXXXX c4XXX h4XXX o4XXX c1XXX h1XXX c2XXX h2XXXXXX o2XXX h2XXX c3XXX h3XXX o3XXX n1 n3 c2 c4 c5 c6 (A n6 n7 n9 c8 h2 h61 h62 h8)) = [n6,n7,n9,c8,h2,h61,h62,h8] list_of_specific_atoms (Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo p o1p o2p o5XXX c5XXX h5XXX h5XXXXXX c4XXX h4XXX o4XXX c1XXX h1XXX c2XXX h2XXXXXX o2XXX h2XXX c3XXX h3XXX o3XXX n1 n3 c2 c4 c5 c6 (C n4 o2 h41 h42 h5 h6)) = [n4,o2,h41,h42,h5,h6] list_of_specific_atoms (Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo p o1p o2p o5XXX c5XXX h5XXX h5XXXXXX c4XXX h4XXX o4XXX c1XXX h1XXX c2XXX h2XXXXXX o2XXX h2XXX c3XXX h3XXX o3XXX n1 n3 c2 c4 c5 c6 (G n2 n7 n9 c8 o6 h1 h21 h22 h8)) = [n2,n7,n9,c8,o6,h1,h21,h22,h8] list_of_specific_atoms (Nuc dgf_base_tfo p_o3XXX_275_tfo p_o3XXX_180_tfo p_o3XXX_60_tfo p o1p o2p o5XXX c5XXX h5XXX h5XXXXXX c4XXX h4XXX o4XXX c1XXX h1XXX c2XXX h2XXXXXX o2XXX h2XXX c3XXX h3XXX o3XXX n1 n3 c2 c4 c5 c6 (U o2 o4 h3 h5 h6)) = [o2,o4,h3,h5,h6] var_most_distant_atom v@(Var i t n) #ifdef USE_GLASGOW_HACKS = maximum_map distance (list_of_atoms n) #else = maximum (map distance (list_of_atoms n)) #endif #ifdef USE_UNBOXED_FLOATS -- partain: can't do lazy pattern-match if x y z are unboxed... where distance p = case (absolute_pos v p) of { Pt x y z -> _SQRT_ ((x _MUL_ x) _ADD_ (y _MUL_ y) _ADD_ (z _MUL_ z)) } #else -- original (partain) where distance p = BOX_FLOAT(_SQRT_ ((x _MUL_ x) _ADD_ (y _MUL_ y) _ADD_ (z _MUL_ z))) where Pt x y z = absolute_pos v p #endif #ifdef USE_GLASGOW_HACKS sol_most_distant_atom s = maximum_map var_most_distant_atom s most_distant_atom sols = maximum_map sol_most_distant_atom sols #else sol_most_distant_atom s = maximum (map var_most_distant_atom s) most_distant_atom sols = maximum (map sol_most_distant_atom sols) #endif #ifdef USE_GLASGOW_HACKS maximum_map :: (a->Float#) -> [a]->Float# maximum_map f (h:t) = max f t (f h) where max f (x:xs) m = max f xs (let fx = f x in if fx `gtFloat#` m then fx else m) max f [] m = m max :: (a->Float#) -> [a] -> Float# -> Float# #endif check = length pseudoknot -- To run program, evaluate: run -- Printing is slow because of the way the Prelude's structured. -- We use direct C Calls and monadic IO instead #ifdef USE_GLASGOW_HACKS mainPrimIO = let most_distant = most_distant_atom pseudoknot in _ccall_ printf ``"%f\n"'' (F# most_distant) `seqPrimIO` returnPrimIO () #else main = print ({-run=-} most_distant_atom pseudoknot) #endif