Приблизительно в течение года я думал о записи программы, которая пишет программы. Это, прежде всего, было бы игривым осуществлением, которое могло бы преподавать мне некоторые новые понятия. Мое вдохновение прибыло из негэнтропии и способности к порядку появиться из хаоса и нового хаоса для возникновения не в порядке в бесконечной последовательности.
Чтобы быть точнее, программа запустилась бы путем записи короткой случайной строки. Если строковые компиляции программы зарегистрируют его для более позднего сравнения. Если строка не скомпилирует программу, то попытается переписать его, пока она действительно не компилирует. Поскольку больше строк (мини-'бесполезные' программы) зарегистрировано, они могут анализироваться для общих черт и использоваться для генерации грамматики. Эта грамматика может затем быть продвинута для записи большего количества строк, которые имеют более высокую вероятность компиляции, чем чисто случайные строки.
Это - очевидно, больше, чем немного глупый, но я думал, что это будет забава попытаться вырастить программу как это. И как побочный продукт я получаю набор уникальных программ, что я могу визуализировать и назвать искусство.
Я, вероятно, запишу это в Ruby из-за его простого синтаксиса и динамической компиляции, и затем я буду визуализировать в обработке обработки рубина использования.
То, что я хотел бы знать:
Я знаю, что это - не совсем метапрограммирование, и от мало я знаю о AI и порождающих алгоритмах, они обычно - больше цели, ориентированной, чем, что я думаю. То, что было бы оптимально, является программой, которая постоянно переписывает и улучшает себя так, я не имею к ^_^
Найдите «генетическое программирование».
Отредактируйте, чтобы ответить на комментарии:
@chris, @Kasturi: верно. То, что было описано в OP, - это система для вывода грамматики путем попыток грубой силы скомпилировать какой-то конкретный синтаксис, а затем обратно сгенерировать новый конкретный синтаксис из грамматики. Если у вас обязательно будет что-то очень близкое к этому описанию ... лучший совет, который у меня есть, - это изучить создание скрытой марковской модели из конкретного синтаксиса на каком-то языке с очень минимальным синтаксисом. Я бы подумал об использовании минимальной комбинаторной логики (что-то похожее по духу на язык Unlambda).
С другой стороны, генетическое программирование - это метод, имеющий развитую практику и литературу, и он не является «детерминированным», а скорее случайным процессом. Это также довольно широкий термин - возможно, система OP является предельным случаем GP с 0% кроссовером и 100% мутацией.
Вы слышали о нанопонд ? Концепция похожа на вашу. Каждому пикселю дается случайно сгенерированная строка, которая проходит через компилятор. Обычно это не дает никакой действующей программы. Однако время от времени случайно сгенерированная строка каким-то образом будет отформатирована идеально, чтобы иметь возможность воспроизвести себя в соседнем пикселе. Вскоре это превращается в битву за то, какая программа может воспроизводить лучше, чем другая.
То, о чем вы говорите, - это генетический алгоритм, да, но максимизация одного и только одного: способности воспроизводить.
Это основная причина всех естественных негэнтропических явлений: случайно сформированная сложная сущность имеет способность к воспроизводству.
Классические генетические алгоритмы налагают критерии искусственного воспроизводства - программа, которая выполняет работу лучше всего, искусственно выбирается для воспроизведения.
Вы имеете в виду своего рода вычислительный естественный отбор . То есть программы будут развиваться на основе их способности воспроизводить себя , и не более того.
Будет ли это что-то полезное? Возможно нет. Если вы, возможно, не предоставили своим программам доступ к Интернету или какому-либо другому внешнему API, к которому они могут получить произвольный доступ и, возможно, распространить через Интернет.
К сожалению, описанная вами система все еще имеет несколько искусственный критерий воспроизводства: способность компилировать.
Поскольку способность компилировать = способность воспроизводить, вы искусственно настроили свои программы так, чтобы они эволюционировали в сторону компиляции.
Что компилировать? Это не имеет значения, потому что любая компилируемая программа с такой же вероятностью будет воспроизведена, как и предыдущая. Допустим, вы каким-то образом создали программу, которая выводит последовательность Фибоначчи. Или программу, которая могла бы обыграть гроссмейстера по шахматам. Прохладный! К сожалению, это будет воспроизведено? Было бы это особенным?
Вовсе нет; она будет рассматриваться как «пригодная» для воспроизведения, как программа print ('k')
. Я предлагаю, возможно, использовать структуру произвольно запускаемых строк программ, которые имеют доступ к API и могут:
Я думаю, что программа, которая пишет программы, которые могут воспроизводить себя, может дать лучшие результаты, чем программа, которая пишет программы, которые могут компилироваться.
Если только вы не хотите последнего; тогда, возможно, вы могли бы максимизировать длину программы. Но возможность чего-то интересного? Не так много; любая программа, которая «компилирует» с определенной длиной, будет столь же вероятна, как и «воспроизведение».
Другой проект, который вы могли бы сделать, - это работа над чем-то, что меняется от непрохождения определенного модульного теста до прохождения модульного теста.
Например, для данной реализации
def add(a,b)
a
end
вы можете добавить тест
assert_equal 3, Foo.new.add(1,2)
и попросить свою программу попробовать любую комбинацию методов на a
в add
(например, a .- (b)
, a.to_s
, a. + (B)
) до тех пор, пока один из мутантов не пройдет этот тест и существующие тесты.
Вы можете посмотреть на heckle (или Zentest?) Примеры изменения тестируемого кода.
Оптимальной была бы программа что постоянно переписывает и улучшает
Выполните следующие действия:
Ранними, но очень интересными работами в этом направлении были «AM» Дуга Лената («Математик») и Eurisko (обобщение AM).
Эуриско развил набор юеристики, исследуя, как граничные условия влияют на решение проблемы. Он не сгенерировал мусор, а затем попробовал его, скорее, он взял слабый метод решения проблем и обнаружил случаи, когда он мог бы работать намного лучше, и создал исправленную версию решателя проблем.