Что, если бы ДНК была языком программирования?

Начнем с немного непристойной шутки.

Мама: Я думаю, пришло время, чтобы птицы и пчелы поговорили с нашим сыном.
Папа: ты уверен?
Мама: да, ты можешь это сделать?
Папа: а, ладно.
Отец идет к сыну.
Папа: ты помнишь, что мы делали с теми проститутками?
Сын: да….
Папа: ну , то же самое и с птицами, и с пчелами.
— (Источник неизвестен.)

Я начинаю с этой шутки, потому что во многом она отражает этот пост.

Предположим, у вас есть программная система, которая выполняется по требованию. Ваш код находится на диске, и каждый раз, когда его нужно выполнить, код копируется в память и выполняется там. (Эта система не так воображаема, как может показаться. Подобные системы уже существуют и довольно популярны. Многие поставщики облачного программного обеспечения предоставляют это как услуги бессерверных вычислений. Некоторые известные примеры: AWS Lambda, Облачные функции Google. , Azure Functions, Alibaba Cloud Function Compute и openstack Qinling.)

Теперь существует вероятность возникновения ошибки каждый раз, когда код копируется с диска в память, и если есть ошибка копирования, ожидаем ли мы, что программа (а) по-прежнему будет работать, и если она запустится (б ) дать правильный вывод?

Большинство из нас, имеющих хоть какой-то опыт в области компьютерного программирования, ожидают, что ответы на оба вопроса таковы: маловероятно, что программа (а) по-прежнему будет работать успешно, а если она запустится, (б) маловероятно, что она выдаст правильный результат. Возникает закономерный вопрос: зачем обсуждать что-то настолько тривиальное? Ответ, как и в случае с птицами и пчелами выше, заключается в том, что то же самое и в биологии. Однако в биологии это ожидание считается спорным.

В этом контексте, наша повестка дня в деталях. Во-первых, очень краткий обзор Нейтральной теории молекулярной эволюции, а затем программные симуляции, иллюстрирующие теорию. Затем мы рассмотрим некоторые следствия наших открытий и их эквиваленты в биологии. Таким образом, мы начинаем с теории биологии, исследуем ее с помощью программирования и, используя эти результаты, ищем подтверждающие доказательства в биологии.

(В исследованиях вы можете найти что угодно, если знаете, что ищете. И наоборот, если вы ищете что-то без теории, вы либо ничего не найдете, либо слишком много — ни то, ни другое не хорошо. Философ Иммануил Кант прекрасно описал это: "понятия без восприятий пусты, восприятия без понятий слепы", Критика чистого разума (1781 г.) Этот пост, я надеюсь, также проиллюстрирует точку зрения Канта.)

Нейтральная теория молекулярной эволюции

Нейтральная теория молекулярной эволюции была впервые опубликована Мотоо Кимурой в 1968 году в журнале Nature¹. Кимура (1924–1994) был научным сотрудником Японского национального института генетики. В нем он говорит: Многие мутации, связанные [в молекулярной биологии], должны быть нейтральными. Другими словами, они должны иметь нулевой эффект для организма. Статья Кимуры занимала всего 3 страницы с двумя выводами: (1) скорость мутаций у млекопитающих была довольно высокой. Поскольку большинство мутаций вредны для организма, высокая частота мутаций должна означать, что (2) большинство мутаций не имеет значения (нейтрально) в отношении приспособленности организма. Говоря более техническими словами Кимуры, очень высокую скорость замены нуклеотидов, которую я подсчитал, можно согласовать с пределом, установленным замещающей нагрузкой, только если предположить, что большинство мутаций, вызванных заменой нуклеотидов, почти нейтральны в естественном отборе.

Мы будем использовать идеи Кимуры в качестве основы для этого поста. Мы будем сравнивать операции ДНК и клетки с языком программирования и интерпретатором времени выполнения соответственно. Мутации — это ошибки, закравшиеся в код.

Давайте начнем.

Случайные изменения в коде

Давайте рассмотрим простую программу, подобную приведенной ниже. Это на Python 3. Мы проверим теорию Кимуры с помощью симуляций. Мы сведем математику к минимуму и будем полагаться в основном на симуляции.

Приведенный выше код имеет длину 126 символов и использует 17 уникальных символов. Согласно теории Кимуры, мутации происходят, и большинство из них нейтральны. Мы смоделируем его теорию, используя приведенный выше код.

Код из 126 символов подразумевает 126 возможных мест, где могут возникнуть ошибки копирования. Для простоты сделаем следующие предположения:

⒈ ошибки копирования одинаково вероятны в любом месте кода
⒉ все ошибки копирования приводят к добавлению символа в кодовую базу. Например, копирование «𝓍» может привести к «𝓍𝓎» для некоторых символов 𝓍 и 𝓎 части корпуса.
⒊ корпус состоит из следующих 17 символов: буквы s, p, l, i, n, t, e, r, d, f; пробельные символы RETURN и SPACE , соответственно; и специальные символы ", #, :, (, ).
⒋ система начинает с первого вызова метода din. Это эквивалент основного метода. Код, который вызывает din, не показан.

Вероятность какого-либо события – это число возможных способов, которыми это событие может произойти, деленное на общее число возможностей. Наш код состоит из 126 символов, и для каждой ошибки копирования существует 17 возможных вариантов. Это означает, что общее количество возможностей равно 126 * 17 = 2142. (Примечание: мы подсчитываем количество случаев, когда возникает ровно одна ошибка копирования. Мы не учитываем вероятность ровно одной ошибки. Это другая и более сложная проблема.) Программисты ожидают, что большинство программ будут взять такую ​​случайную ошибку копирования не получится, и я согласен. Но есть загвоздка; Ибо в тех программах, которые увенчались успехом, какие мечты могут прийти?

Что такое ошибка?

Давайте также определим, что мы понимаем под ошибкой. Ошибка — это каждый раз, когда программа приводит к исключению и не выполняется до конца. Некоторые программы запустятся, но выведут другой результат. Мы пока проигнорируем их, но вернемся к ним.

Исходя из этих предположений, давайте подсчитаем количество мест в коде, где случайная ошибка вызовет или не приведет к сбою программы, и используем это для расчета вероятности ошибки.

Вместо того, чтобы вручную вычислять успехи/ошибки, генерация всех вариантов программ с ошибками копирования будет 2142 умножить на 2 (= 4284), по одной программе для двух значений предложения if в строке 2. Четыре тысячи программ — это много, поэтому я сократил 17 символов в следующие 7 групп:

⒈ алфавит — любой из s, p, l, i, n, t, e, r, d, f
⒉ двоеточие — :
⒊ двойная кавычка — "
⒋ решетка — #< br /> ⒌ перевод строки — символ \n, представленный здесь символом Unicode, СТРЕЛКА ВНИЗ С НАКОНЕЧНИКОМ ВЛЕВО .
⒍ круглые скобки — любой из (, )
⒎ пробел — символ с кодом ASCII 32, представленный здесь символом Unicode, БЕЛЫЙ КВАДРАТ С ЗАКРУГЛЕННЫМИ УГЛАМИ .

Это приводит нас к 126×7×2=1764 программам. Меньше половины предыдущей оценки. Я сгенерировал и запустил эти 1764 программы Python и свел их результаты в таблицу.

Результаты

Давайте посмотрим на неудачи и успехи. Из 1764 возможных программ у нас 667 успешных и 1097 неудачных. Однако с поправкой на 10 разных алфавитов и 2 разные скобки мы имеем 2693 ошибки и 1591 успех. Это согласуется с нашим первоначальным предположением, что большинство ошибок копирования (также называемых «мутациями») приводят к ошибкам — в данном случае от 63% до 37%.

На изображении ниже представлены неудачи и успехи для каждой категории. Он показывает, сколько неудач/успехов было у нас после вставки символа данной категории в каждое из 126 мест в коде. Например, следующее является ошибкой: вставка ( в позицию 2 в коде, de(f din(n):, и следующее является успешным: вставка ( в позицию 50, ## re(set. В первом случае программа завершается с ошибкой SyntaxError: unmatched ')', во втором случае программа завершается на основе значения n.

Здесь не так уж много сюрпризов. Как и следовало ожидать, скобки, двойные кавычки и алфавиты наименее прощают ошибки копирования — (87 %, 76 % и 62 % соответственно). Добавление случайных открывающих или закрывающих скобок — это гарантированный способ полностью испортить ваш анализатор. Вот почему большинство редакторов выделяют их цветом. Сначала я был удивлен высоким уровнем ошибок новых строк (63%), но это ожидаемо, учитывая, что мы выбрали Python.

Пробелы наиболее устойчивы к ошибкам копирования. Неудачи только в 33% случаев. Если есть одна категория, которая действительно меня удивила, так это символ Двоеточие. Подробнее см. в §Приложении I.

Поскольку просто данные и таблицы скучны, я проиллюстрировал проблему ниже с помощью анимированных GIF-файлов и более подробно рассмотрел несколько категорий. Первый пример относится к категории Алфавит. Мы обсудим его вместе с категориями Пробел и Хэш. Для анимированных изображений других категорий см. §Приложение I.

𝓐буквенные ошибки часто приводят к сбоям (в 62 % случаев). Любые изменения ключевого слова Python естественным образом приводят к ошибкам, поэтому изменение def, if, else всегда завершается ошибкой. Точно так же ошибки, которые вызывают проблемы с токенизацией, такие как (a n, также вызывают проблемы.

Есть только 3 случая, когда ошибки не возникают, а именно:
⒈ Изменение находится в строке comment, такой как строка 7.
⒉ Изменение находится в строке, как и в строках 9, 11 и 13.
⒊ Изменение изменяет токен, который никогда не выполняется, поскольку он не является частью исполнительной вилки. Таким образом, когда n не является (технически говоря) и вызывает выполнение ответвления else, изменения разрешены. Например, посмотрите на строку 3: когда n=0 любая часть функции rest может быть изменена (например, frest) или принята поддельный аргумент (например, rest(i)) без немедленных последствий. Мы вернемся к этому позже.

𝓢шаги как ошибка копирования

Добавление пробелов не вызывает много ошибок в программе. На самом деле, он самый щадящий в нашей выборке (только 33% программ терпят неудачу).

Пробелы прощают в следующих случаях. (В другом языке это может быть даже более снисходительно.)
⒈ Между любыми двумя отдельными токенами и не влияет на правила отступа Python.
⒉ В конце любой строки, как его последний токен.
⒉⒈ В пустой строке
⒊ Внутри строки
⒋ В строке комментария, например, в строке 7.

𝓗ошибки копирования пепла
Рассмотрим еще одну категорию, хэшсимвол, #, а потом немного пофилософствуем, т.е. сделать некоторые прогнозы.

Хэш в Python указывает на начало комментария. Интерпретатор Python игнорирует все, начиная с хэша и заканчивая концом строки. Таким образом, как и следовало ожидать, в нем также будет меньше ошибок, и это подтверждается данными (46% или 47% в зависимости от n).

Ошибки копирования хэша прощаются в следующих случаях:
⒈ В качестве последнего токена в любой строке, т. е. в конце строки
⒈⒈ На пустой строке
⒉ В строке комментария
⒊ Внутри строки
⒋ Подобно Alphabet-error-3 (см. выше), неработающие вилки могут быть изменены без немедленных последствий. (Подобно, но не точно. См. изображение, чтобы отметить различия.)

Следствия

Напомним, что мы сравнили код с ДНК, и тогда интерпретатор Python становится ячейкой. Тогда успех или неудача программ становится естественным отбором. Суть естественного отбора в том, что это крайний случай предвзятости выжившего. Кто выживает, тот добивается успеха. (Хотя, конечно, в нашем примере, а возможно, и в эволюции в выживших нет ничего особенного.)

Следствие 1: Нейтральная теория подтверждена

Во-первых, мы будем смотреть только на выживших. В конце концов, как гласит клише, мертвецы не рассказывают сказки. Мы будем придерживаться 7 категорий и по одному образцу из каждой.

645 программ работают с некоторыми выводами. Из этих 645 программ 288 печатают tridnt при вводе n=1 и 287 печатают lensed при вводе n=0. 70 строк имеют вывод отличный от нормы. Я включаю выходные данные с начальными или конечными пробелами, отличными от нормы, например, "lensed " и " tridnt". Напомним, что у нас было 667 успешных программ. 22 программы вообще не выводились.

Из 667 успешных программ в общей сложности 575 программ дали тот же результат, что и исходная программа, даже с одной ошибкой копирования. Это 86%.

Повторяя слова Кимуры, «большинство мутаций, вызванных заменой нуклеотидов, почти нейтральны».

Следствие 2: Должны быть части ДНК, которые претерпевают больше мутаций, чем другие.

Это потребует небольшой доработки. Давайте рассмотрим ошибки построчно. Я привел эту статистику ниже. В таблице показано количество сбоев, обнаруженных на линии. Для простоты я суммировал неудачи и успехи по обоим значениям n.

Наблюдая за таблицами, мы видим, что строки комментариев наиболее устойчивы к ошибкам копирования. В текущем коде более 7 категорий, 9 символов и 2 значения (всего 126) хэш-строка успешна на 86% (108 успехов против 18 неудач).

Таким образом, мы можем разумно предположить, что любая строка, получившая символ comment и сохранившаяся, станет устойчивым местом для будущих случайных изменений. Помните, мы заботимся только о выживших.

Доказательства
Я искал в Google следующий термин некоторые части ДНК имеют больше мутаций, и Google привел меня к статье 2004 года. Оказывается, это комментарий к технической статье, опубликованной в техническом журнале PLoS Biology. В статье говорится: [c] Соотнося частоту мутаций генов с их расположением в геноме, [исследователи] Джеффри Чуанг и Хао Ли… подтверждают, что региональные скорости мутаций действительно существуют. Статья доступна по ссылке https://www.ncbi.nlm.nih.gov/pmc/articles/PMC340953/.

Следствие 3: большая часть ДНК не должна ничего делать

Согласно следствию 2, если изменения накапливаются в строках комментариев, из этого должно следовать, что эти части ДНК ничего не делают. И поскольку изменения в этих локусах будут накапливаться, будут большие участки ДНК, которые ничего не делают.

Доказательства
Я набрал в Google запрос Большинство ДНК ничего не делает и нашел ссылку на статью 2015 года в Нью-Йорк Таймс, написанную ведущим научным журналистом Карлом Циммером. Статья достаточно метко озаглавлена: Большая часть нашей ДНК — мусор?. В нем Циммер говорит, что подавляющее большинство его ДНК — грубо говоря — мусор. Статья доступна по адресу https://www.nytimes.com/2015/03/08/magazine/is-most-of-our-dna-garbage.html.

Примечание. Похоже, наука еще далеко не устоялась. Вышеупомянутая статья обсуждает вопросы в некоторых деталях. Что бы это ни стоило, я придерживаюсь стороны мусорной ДНК.

Следствие 4: участки ДНК не изменятся.

Это обратная сторона следствия 3. Из экспериментов видно, что есть части кода, которые не допускают изменений, независимо от значения 𝓃. Например, def, if и else неприкосновенны.

Доказательства
К счастью для меня, мне не пришлось гуглить это. Предыдущих двух ссылок было достаточно. Сказали соответственно:

  1. «Гены холодных регионов… как правило, очень консервативны и очень мало меняются с тех пор, как они впервые эволюционировали». и
  2. «За миллионы лет основные гены не сильно изменились, в то время как мусорная ДНК вобрала в себя множество безвредных мутаций».

Следствие 5: Новые фенотипы возникают, когда некодирующие участки становятся кодирующими участками.

Это немного необычно и весьма спекулятивно. (Возможно, мне не следует называть это следствием….) Позвольте мне уточнить.

Предположим, наш код находится в следующем состоянии. Мы исключили большую часть кода, потому что он не имеет отношения к нашему текущему обсуждению.

Часть, о которой мы заботимся, - это раздел комментариев. Почти все изменения, которые там произойдут, будут нейтральными.

Теперь предположим, что в этом нейтральном сайте произошла серия мутаций. Путь к этой возможности не имеет значения, нас в основном интересует конечное состояние, которое в нашем примере, наконец, читается как print("instill") #"de f)t:).

Теперь предположим, что есть стиль Коломбо, еще одна мутация, которая вставляет новую строку сразу после первого #. Это поместит код в следующее состояние:

И точно так же у нас есть оператор print в новой строке, обеспечивающий новое поведение.

Доказательства
У меня их нет, и я тоже не гуглил. Когда они объявят, что какая-то команда получит за это Нобелевскую премию, я заявлю свои законные права.

Это действительно кажется возможным, хотя даже найти доказательства в этом направлении было бы сложно. И даже если по моей теории эволюция действительно развивалась, нам остается неизвестным следующее: какова вероятность таких изменений? вполне возможно, что даже при накоплении изменений в этих направлениях организм не успевает сделать это из-за фатальной мутации в каком-то другомкодирующем сайте. (Это классическая история: «Однажды я иду по Елисейским полям и вижу через дорогу старого друга. Рядом нет машин, и я ничем другим не занят, поэтому, будучи рациональным, я начинаю переходить улицу. Тем временем на высоте 33 000 футов грузовая дверь падает с пролетающего мимо авиалайнера 2, и, прежде чем я доберусь до другой стороны улицы, я расплющен». ²)

Остановлю аналогии после еще одного примера. Мы начали с того, что будем копировать код каждый раз, когда нам нужно выполнить нашу программу. Это, безусловно, верно для ДНК. Рассмотрим два вопроса, вытекающих из этого факта: ⑴ сколько раз код копируется в любом случае? и ⑵ есть ли последствия ошибок копирования?

⒈ Сколько казней?

В течение средней продолжительности человеческой жизни клетки внутри тела в совокупности проходят примерно 10¹⁶ циклов роста и деления ⁴ говорится в учебнике. 10¹⁶ — ошеломляюще большое число. Представьте себе все песчинки в мире сегодня. Это всего лишь в сотню раз больше, чем количество клеточных делений, через которые мы пройдем за свою жизнь. Срок службы более 75 лет, что соответствует 4000 копий в секунду.

⒉ Последствия ошибки копирования

случайные ошибки, возникающие при репликации ДНК в нормальных стволовых клетках, являются основным фактором, способствующим развитию рака, — говорят два исследователя, Кристиан Томасетти и Берт Фогельштейн,в ведущем исследовательском журнале Science⁵. Их статья доступна по адресу https://science.sciencemag.org/content/347/6217/78.

Давайте теперь рассмотрим некоторые аспекты, которые не обсуждались, некоторые места, где я, возможно, ошибаюсь, некоторые части, где аналогия с языком программирования не очень подходит.

Нерассмотренные аспекты

Хотя эта дискуссия, на мой взгляд, зашла довольно далеко в представлении эволюции в том виде, в каком она происходит на самом деле, в ней отсутствуют некоторые аспекты. Это те области, которые мы обсуждаем здесь. Во-первых, наш анализ чисто синтаксический, а не семантический. Во-вторых, мы рассмотрели только изменения в ДНК, а не в самом клеточном механизме. Из двух первое, я думаю, невозможно предсказать даже в биологии, но я забегаю вперед.

Синтаксический, а не семантический

Наш анализ был чисто синтаксическим — мы не обсуждаем что что-либо означает, а только то, как они взаимодействуют друг с другом и что они делают. Например, что вообще вычисляют эти программы? что означает, что программа, которая ранее печатала dissent, теперь печатает dissent↲instill? что на самом деле представляет n, аргумент основной функции? какова его истинная частота появления? Это действительно интересные вопросы, потому что, безусловно, для организма именно эти успешные мутанты продолжают формировать новые варианты и опираться на процесс, который мы называем эволюцией.

Тройная спираль

В своей одноименной книге 2002 года молекулярный биолог Ричард Левонтин указывает, что абсурдно говорить исключительно о ДНК и генах, потому что молекула сама по себе ничего не может вам сказать. Молекула ДНК действует согласованно с клеткой. Вместе они образуют организм. (Возможно, когда-нибудь биотехнологии дойдут до стадии, когда ДНК можно будет фиксировать в той или иной форме, и у нас будут разные клетки, интерпретирующие их по-разному.)

В этом посте я сохранил to код и ДНК. Но кто знает, какие изменения могут (а может быть, уже произошли) произойти из-за изменений в самой клетке. В великой научно-фантастической новелле Роберта Льюиса Стивенсона Странная история доктора Джекила и мистера Хайда (1886 г.)³ доктор Джекил готовит зелье, которое превращает его в мистера Хайда. Позже он не может воссоздать это зелье, потому что, как оказалось, его исходные ингредиенты содержали некую «неизвестную примесь, которая придавала зелью эффективность». Точно так же, кто знает, развилась ли какая-то черта вида из-за того, что обычная в остальном цепочка ДНК была просто плохо интерпретирована клеткой.

𝒯его хорошее место, чтобы остановиться. Я мог бы продолжать, и идеи двигаются в моем направлении, но нельзя кайфовать от собственных запасов.

Приложение I: Анимации всех категорий

Сноски

¹ Мотоо Кимура, Скорость эволюции на молекулярном уровне, доступ по адресу https://authors.library.caltech.edu/5456/1/hrst.mit.edu/hrs/evolution/public/papers/kimura1968/kimura1968. пдф.

² Эта блестящая шутка взята из главного учебника по искусственному интеллекту Искусственный интеллект: современный подход, 2-е издание (2003 г.) Стюарта Рассела и Питера Норвига. Их книга в настоящее время находится в четвертом издании. Сайт книги http://aima.cs.berkeley.edu/. В их шутке есть сноска, отсылающая к следующей статье Washington Post: Новые дверные защелки необходимы для самолетов Boeing 747 Jumbo Jets, написанной Нелл Хендерсон 24 августа 1989 года. Статья доступна по адресу https: //www.washingtonpost.com/archive/politics/1989/08/24/new-door-latches-urged-for-boeing-747-jumbo-jets/4ea406f5-dfa5-4b66-83e6-54555e850ef9/.

³ Книга Роберта Льюиса Стивенсона Странная история доктора Джекила и мистера Хайда доступна по адресу https://www.gutenberg.org/files/43/43-h/43-h.htm. .

Количество клеточных делений за среднюю продолжительность жизни человека https://bionumbers.hms.harvard.edu/bionumber.aspx?s=n&v=10&id=100379. Ссылка цитирует книгу Р. Вайнберга Биология рака, 2-е издание, 2014 г.

Варьирование риска развития рака между тканями можно объяснить количеством делений стволовых клеток Кристиана Томасетти и Берта Фогельштейна, доступное на https://science.sciencemag.org/content/347/6217/78. Опубликовано в журнале Science 2 января 2015 г.