Существуют ли программы, которые итеративно пишут новые программы?

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

чтобы быть более конкретным, программа начнется с написания короткой случайной строки. Если строка компилируется, программы будут регистрировать ее позже сравнение. Если строка не компилируется, программа попытается переписать ее, пока она не компилируется. Поскольку регистрируется больше строк (мини - "бесполезных" программ), их можно проанализировать на сходство и использовать для создания грамматики. Затем эта грамматика может быть использована для записи большего количества строк, которые имеют более высокую вероятность компиляции, чем чисто случайные строки.

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

Я, вероятно, напишу это в Ruby из-за его простого синтаксиса и динамической компиляции, а затем я визуализирую в обработке с помощью ruby-processing.

Что я хотел бы знать:

  • есть ли название для этого типа программирования?
  • что в настоящее время существует в этой области?
  • кто является основными участниками?
  • бонус! - Каким образом я могу процедурно присвоить значение выходным программам за пределами компиляций (y/n)?
    возможно, я захочу расширить функциональность этой программы для создания программы на основе параметров, но я хочу, чтобы программа определяла эти параметры путем запуска программ, которые компилируют и присваивают значение выходным программам. Этот вопрос, вероятно, более вовлечен, чем разумно для бонуса, но если вы можете придумать простой способ сделать что-то подобное менее чем за 23 строки или одну гиперссылка, пожалуйста, добавьте ее в ответ.

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

6 ответов


посмотрите " генетическое программирование."

Edit, чтобы ответить на комментарии:

@chris, @Kasturi: верно. То, что было описано в OP,-это система вывода грамматики путем попыток грубой силы сделать компиляцию некоторого конкретного синтаксиса, а затем обратно генерировать новый конкретный синтаксис из грамматики. Если у вас обязательно будет что-то очень похожее на это описание... лучший совет, который у меня есть, - изучить построение скрытой модели Маркова из конкретного синтаксиса в некоторых язык с минимальным синтаксисом. Я бы рассмотрел использование минимальной комбинаторной логики (что-то сродни по духу языку Unlambda).


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

что вы говорите о генетическом алгоритме, да, но максимизация одной вещи и только одной вещи:способности к воспроизведению.

это существенное происхождение все естественно-природное явление negentropic: случайным образом формируется сложный организм имеет способность к размножению.

классические генетические алгоритмы вводят критерии искусственного воспроизводства -- программа, которая делает работу лучше всего, искусственно выбрана для воспроизведения.

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

это создаст что-то полезное? А может, и нет. Если вы, возможно, не предоставили своим программам доступ к интернету или какому-либо другому внешнему API, к которому они могут получить случайный доступ и, возможно, распространиться по интернету.

к сожалению, ваша описанная система все еще имеет несколько искусственный критерии воспроизведения: возможность компиляции.

поскольку способность компилировать = способность воспроизводить, вы искусственно настроили свои программы на эволюцию в сторону компиляции.

компиляции чего? Это не имеет значения, потому что любая программа, которая компилируется, с такой же вероятностью воспроизводится, как и последняя. Предположим, вы каким-то образом создали программу, которая выведет последовательность Фибоначчи. Или программа, которая может победить гроссмейстера. Круто! К сожалению, будет ли она воспроизведена? Будет ли он особенным?

совсем нет; он будет рассматриваться как "пригодный" для воспроизведения как программа print('k')

Я предлагаю, возможно, работать с фреймворком случайно запущенных строк программ, имеющих доступ к API, которые могут:

  • чтение/запись на жесткий диск, и вдруг, у вас есть программы, которые могут писать случайные строки Как программ, себя.
  • Удалить / Изменить другие файлы на жестком диске; это позволяет, возможно, программам конкурировать между собой. Ваш API может быть сконструирован так, что файл может быть удален только в том случае, если "сила" (произвольное значение...возможно, длина символа) программы сильнее, чем файл.
  • запускать другие скрипты на жестком диске...может быть, даже те, что пишут сами!--35-->
  • доступ к интернету; к веб-серверу? Возможность писать / прикреплять/отправлять / читать электронные письма?

Я думаю, что программа, которая пишет программы, которые могут воспроизводить сами могли дают лучшие результаты, чем программа, которая пишет программы, которые могут компилироваться.

Если вы не хотите только последнего; тогда, возможно, вы могли бы максимизировать длину программы. Но возможность того, что произойдет что-то интересное? Не так много; любая программа, которая " компилируется "с определенной длиной, будет так же вероятна, как и"воспроизведение".


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

например, при реализации

def add(a,b)
  a
end

вы можете добавить тест

assert_equal 3, Foo.new.add(1,2)

и попросите вашу программу попробовать любую комбинацию методов на a внутри add (например, a.-(b), a.to_s, a.+(b)), пока один из мутантов не пройдет этот тест и существующие тесты.

вы можете посмотреть на прикалываться (или Zentest?) примеры изменения тестируемого кода.



что было бы оптимальным-это программа что постоянно переписывает и улучшает сам так мне не надо

выполните следующие действия:

  1. написать генератор псевдослучайных чисел на ассемблере. (реальный режим)
  2. изменить программу, чтобы она записывала (например) 64k случайных чисел и делала далекий JMP до первого байта.
  3. (необязательно) создайте драйвер для таймера сторожевой собаки, чтобы предотвратить бесконечные петли
  4. нагрузка на загрузчик какого-то устройства.
  5. получить несколько компьютеров. Настройте так, что если они утроят ошибку, они перезагрузятся и загрузятся с загрузчика вашего устройства
  6. загрузите компьютеры и подождите несколько десятилетий (или веков, что угодно), чтобы он произвел что-то полезное
  7. профит!

ранними, но очень интересными работами в этом направлении были "AM" Дуга Лената (математик) и Эуриско (обобщение AM).

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