Перевод / Лес
Оригинал:research.Google/pubs/universal483…
Али Месба / Эндрю Райс / Эмили Джонстон, Ник Глориозо и Эдвард Афтандилиан
Опубликовано в: Труды 27-й совместной европейской конференции ACM по программной инженерии и симпозиума по основам программной инженерии (ESEC/FSE '19)
Резюме
Разработчики часто тратят много времени на исправление ошибок компиляции кода. После наблюдения мы обнаружили, что процесс исправления ошибок следовал определенной схеме и был очень механическим. Мы предлагаем новый метод, который автоматически изучает эти шаблоны с помощью глубоких нейронных сетей и предлагает исправления для самых трудоемких ошибок компиляции.
Мы описываем, как собрать все ошибки сборки Google и код, который их вызвал, чтобы в конечном итоге превратить их в успешные сборки. Мы генерируем diff абстрактного синтаксического дерева (AST) из изменений кода, конвертируем его в DSL, называемый Delta, который описывает модификации кода, необходимые для успешной компиляции. Затем скомпилируйте диагностическую информацию (в качестве источника) и дельта-модификацию, устраняющую диагностическую ошибку (в качестве цели), в нейронную сеть машинного перевода для обучения.
Наша система DeepDelta исправила 19 314 из 38 788 ошибок компиляции (50% правильных ошибок) для двух наиболее распространенных и трудоемких ошибок компиляции Java (т. е. отсутствующие символы и несоответствия сигнатур методов). Средняя вероятность того, что правильный ремонт попадет в тройку лучших предложений по ремонту, составляет 86%.
Ключевые слова
Ошибки компиляции, исправления программы, нейронный машинный перевод
1 Введение
Преимущество использования скомпилированного языка программирования заключается в том, что ошибки программирования обнаруживаются во время компиляции, а не во время выполнения. Неудачные сборки обычно приводят к циклу редактирования-компиляции, когда разработчикам предлагается постоянно пытаться устранить диагностические ошибки и перекомпилировать, повторяя процесс.
Предыдущее крупномасштабное исследование показало, что профессиональные разработчики создают код в среднем от 7 до 10 раз в день. Исследования показали, что ошибки компиляции во время сборки являются распространенными и дорогостоящими, требуя от разработчиков много времени и усилий для их исправления. Ошибки компиляции во время сборки появляются, когда разработчики компилируют код с помощью систем управления сборкой, таких как Bazel, Gradle или Maven.
Наша цель — помочь разработчикам автоматически исправлять ошибки сборки. Предыдущие исследования в области автоматизированного исправления программ были сосредоточены на поиске исправлений в случае сбоя тестов с помощью фиксированных шаблонов и методов на основе поиска. В этой статье мы предлагаем новый метод под названием DeepDelta для автоматического исправления ошибок компиляции во время сборки.
Мы считаем, что в поведении разработчиков, модифицирующих код для устранения ошибок компилятора, существуют некоторые общие закономерности. Такие шаблоны можно изучать автоматически, извлекая изменения абстрактного синтаксического дерева (AST) между неудачными и разрешенными моментальными снимками кода и передавая их в глубокие нейронные сети в качестве абстрактных функций.
В этой статье сделан следующий вклад:
- Мы провели обширное исследование ошибок компиляции и соответствующих исправлений, чтобы найти наиболее распространенные и дорогостоящие типы ошибок на практике. Наш набор данных состоит из 300 миллионов строк кода, внесенных разработчиками в код, измененный в тысячах проектов Java в Google. Наше исследование показывает, что 51% диагностик компилятора связаны с неспособностью компилятора разрешить определенный символ, что также является самой дорогой категорией ошибок для исправления.
- Мы моделируем процесс автоматического исправления как проблему нейронного машинного перевода (NMT), где источник проблемы содержит информацию о сбое, а цель — набор изменений AST, которые устраняют сбой, выраженный в DSL под названием Delta.
- Мы представляем метод экземпляра под названием DeepDelta, который автоматически генерирует исходные и целевые функции из исторических данных разработчиков и изучает на практике шаблоны исправления для двух наиболее распространенных и дорогостоящих ошибок компиляции Java.
- Мы демонстрируем эффективность этой методики посредством обширной эмпирической оценки 38 788 необнаруженных ошибок компиляции в коде Google. Результаты оценки показывают, что DeepDelta имеет вероятность 47%-50% создать полностью правильное исправление. Существует вероятность 85%-87%, что правильный ремонт будет в трех лучших предложениях по ремонту.
2 Собрать ошибки компиляции
Первым шагом, необходимым для изучения режима исправления, является получение данных разработчика, связанных с ошибками компиляции. Мы собираем эти данные в течение нашего повседневного цикла разработки в Google, а также используем этот набор данных для характеристики реальной распространенности и стоимости различных ошибок компиляции.
2.1 Сбор данных
Каждая сборка, инициированная разработчиком, автоматически регистрируется Google с подробной информацией о каждой сборке, включая всю диагностику компилятора (т. е. подробную информацию об ошибках) и моментальный снимок построенного кода.
Для этого исследования мы собирали журналы сборки за два месяца, с 23 января 2018 г. по 23 марта 2018 г. Собранные журналы затем разбираются и анализируются, чтобы понять наиболее распространенные ошибки сборки на практике. Хотя наша среда диагностики сборки не зависит от языка, в этой статье мы сосредоточимся только на ошибках сборки, связанных с проектами Java.
2.2 Виды диагностики
Мы группируем сообщения об ошибках компилятора по типу диагностики. Типы диагностики представляют ошибки с одной и той же причиной. Компилятор вставит конкретное имя в шаблон сообщения об ошибке, например, javac использует шаблон ""{0} является абстрактным; не может быть создан" при попытке создать экземпляр абстрактного класса и использует ключ abstract.cant.be. Мы создали парсер, который отображает конкретные сообщения об ошибках из журнала сборки обратно в шаблоны сообщений, которые их создали (см. Таблицу 2).
2.3 От диагноза к разрешению
Неудачные сборки могут содержать множество диагностических данных. Некоторые из этих диагнозов являются новыми, а некоторые могут быть такими же, как и в исторической сборке. Итак, сначала мы решили преобразовать последовательности сборки, содержащие определенные диагностические данные, в _восстановительные сеансы_.
Определение 1 Сеанс разрешения (RS).диагностика сборкиСеанс восстановления (RS) относится к последовательности из более чем двух последовательных сборок,
, Для выполнения условий:
существует
Впервые введен в , в
решается впервые в и строит
и построить
Интервал времени не превышает заданного времени T.
Цель использования сеанса исправления — зафиксировать период времени, который разработчик использовал для решения диагностических проблем. Поэтому мы определяем временное окно T как один час. Это окно расшифровывается как «окно переключения задач», т.е. если разработчик не выполняет сборку за время T, то, скорее всего, он уже занят другими делами. Например, пойти на обед или уйти с работы.
Мы количественно оцениваем затраты разработчиков на основе времени, необходимого для решения конкретного диагноза. чтобы диагностироватьи его ремонтная сессия
Например, пусть |
|для
количество диагнозов, производимых сборкой, которую мы называем
_Активная диагностика_ включена. Предполагать
строить
начальное время,
для сборки
время завершить. Таким образом, мы получаем понятие активной стоимости ремонта следующим образом:
Определение 2 Стоимость активного разрешения (ARC).диагнозСтоимость активного ремонта (ARC) для
) (исключая саму сборку), деленное на количество диагностик для промежуточного процесса сборки, для которого он восстановил сеанс:
На рис. 1 показан наш процесс построения сеанса восстановления. Как показано на рис. 1а, D1 и D2 впервые появились в сборке 1, а D3 — в сборке 2. Мы считаем исчезновение диагностического сообщения из сборки решенным (см. определение 1), поскольку D3 больше не появляется в сборке 4, поэтому его сеанс восстановления включает сборки 2–4, как показано на рис. 1b.
Рис. 1. Сеанс восстановления сборки
2.4 Наборы данных и открытия
Таблица 1 суммирует наш набор данных, в котором мы обработали в общей сложности 4,8 миллиона сборок, из которых 1 миллион завершился неудачно, что составляет около 20% всех неудачных сборок.
Таблица 1 Набор данных
Напомним, что сбой сборки может содержать несколько ошибок компиляции, т.е. диагностики. Эти сбои сборки содержали в общей сложности 3,3 миллиона диагностических данных, из которых мы смогли получить 1,9 миллиона сеансов восстановления. Для оставшихся 1,5 млн диагностических сообщений мы не нашли сеанса исправления, вероятно, из-за того, что разработчики отказались от изменений или между сборками прошло больше часа.
Таблица 2. Топ-10 типов диагностики, отсортированных по стоимости упреждающего ремонта
В таблице 2 перечислены первые десять ошибок, отнимающих больше всего времени и наиболее часто встречающихся в нашем наборе данных. В таблице показаны тип диагностики, стоимость упреждающего ремонта (средняя, минимальная и максимальная), количество последующих сборок, которые решили проблему с этой диагностикой (средняя, минимальная и максимальная), доля и количество каждого типа диагностики, упреждающий ремонт относительно общей стоимости и текстовое описание типа диагностики.
Всего существует 1 853 417 диагностических средств компиляции, которые затем исправляются в сеансе восстановления. Из таблицы видно, что 51% (949 325) диагностик связаны с неспособностью компилятора разрешить символ, то есть тип диагностики cant.resolve, а сообщение об ошибке — «не удается найти символ». По сравнению с результатами опроса 2014 года разработчики сталкиваются с растущим числом отсутствующих символов. Второй тип диагностики в таблице — ошибки cant.apply.symbol, на долю которых приходится 8% от общего числа. cant.apply.symbol возникает, когда компилятор не может найти объявление метода для данного типа.
Для каждого типа диагностики мы также рассчитали относительную стоимость ошибок сборки: количество экземпляров диагностики сборки, умноженное на среднюю стоимость упреждающего ремонта. Два месяца измельчения данных, общая стоимость которых достигает 57 215 441 секунды. Это означает, что за два месяца разработчикам потребовалось около 21 месяца, чтобы исправить ошибки сборки. Из них cant.resolve остается наиболее трудоемким типом диагностики, на который приходится 47% общих затрат на упреждающий ремонт (~ 10 месяцев). cant.apply.symbol составляет 11% от общей стоимости упреждающего ремонта (~ 2 месяца). Одни только эти две ошибки уже составляют 58% от общего затраченного времени, что составляет около года человеко-часов разработчиков в нашем наборе данных.
3 Запуск примера
Учитывая повсеместное распространение и стоимость cant.resolve и cant.apply.symbol на практике, мы фокусируем наше предложение по исправлению на этих двух типах ошибок сборки. Но наш метод достаточно общий, чтобы его можно было применять к произвольным типам диагностики с небольшими модификациями. В этой статье в качестве рабочего примера используется cant.resolve. Компилятор должен распознать идентификатор, прежде чем он сможет его использовать. Несоответствия между определением идентификатора и его использованием, включая случай, когда идентификатор не может быть найден, являются основной причиной этой ошибки сборки. Это может произойти, например, когда отсутствует зависимость (например, в другой библиотеке), отсутствует импорт или символ имеет неправильное имя.
В качестве примера возьмем следующий фрагмент кода:
import java.util.List;
class Service {
List <String > names () {
return ImmutableList.of( pub , sub );
}
}
Когда этот код будет построен, компилятор сообщит о следующей ошибке:
Service.java: 4: ошибка: не удается найти символ символ: переменная ImmutableList
Разработчик забыл импортировать пакет для ImmutableList (из библиотеки Google Guava), поэтому компилятор не смог разрешить символ. Разработчик должен найти правильный пакет для символа и добавить соответствующий оператор импорта, чтобы устранить эту ошибку:
import java.util.List;
+++ import com.google.common.collect.ImmutableList;
class Service {
List <String > names () {
return ImmutableList.of( pub , sub );
}
}
Поскольку ImmutableList определен в другом проекте, также объявите зависимость от системы сборки. При использовании системы сборки Bazel исправление может состоять в том, чтобы удалить существующую ссылку на базовый пакет Guava и вместо этого добавить пакет сбора:
java_library(
name = Service ,
srcs = [
Service.java ,
],
deps = [
--- "//java/com/google/common/base",
+++ "//java/com/google/common/collect",
],
...
)
4 Узнайте об изменениях исправления
После сбора диагностической информации и построения сеанса восстановления мы вводим сеанс восстановления в часть обнаружения решения. Целью этого шага является систематическое изучение того, как разработчики изменили свой исходный код для устранения ошибок сборки.
4.1 Получение снимков кода
В Google изменения кода разработчиков автоматически сохраняются в облаке с помощью IDE в виде временных снимков. Это означает, что полная запись изменений кода поддерживается с использованием извлекаемого идентификатора моментального снимка. Это позволяет нам сделать шаг назад и получить моментальный снимок кода в определенный момент времени для конкретной сборки.
Для каждого сеанса восстановления сборки мы сначала извлекаем идентификаторы моментальных снимков первой и последней сборок. Первый соответствует моментальному снимку кода, вызвавшему диагностику, а второй соответствует моментальному снимку кода, разрешающему диагностику.
Затем мы используем идентификатор моментального снимка, чтобы запросить облачный сервер моментальных снимков, чтобы получить определенный код, соответствующий моменту времени.
4.2 Сравнение различий ТЧА
На данный момент у нас есть два снимка кода для каждого сеанса исправления, в состоянии ошибки и в состоянии исправления. Чтобы понять, как разработчики могут модифицировать свой код для устранения ошибок сборки, мы сравнили различия кода в ошибочном и фиксированном состояниях.
Традиционным методом обнаружения изменений исходного кода является сравнение строк Unix (diff), при котором изменения подсчитываются только на уровне детализации добавлений и удалений в тексте на уровне строк. Это заставляет diff зависеть от формата исходного кода. Хотя сравнение строк является популярным методом человеческого сравнения, например, при проверке кода, сложно автоматически вывести синтаксические изменения в коде из различий текстовых строк.
Для анализа изменений кода на уровне синтаксиса мы используем древовидный подход к сравнениям различий. Мы анализируем моментальный снимок ошибки и моментальный снимок восстановления для каждого сеанса исправления, чтобы создать соответствующее абстрактное синтаксическое дерево (AST). В этом проекте мы создали парсеры для языков сборки Java и Bazel, хотя можно легко добавить поддержку других языков.
Затем AST ошибочных и восстановленных моментальных снимков помещаются в алгоритм сравнения дерева.
Определение 3 Абстрактное дерево синтаксиса Diff AST Diff.Учитывая два AST: источники цель
, AST Diff – это
превратиться в
Набор операций смены узла.
Алгоритм сравнения AST сначала пытается сравнить метки узлов, тем самым распространяя исходный AST.Каждый узел на карте сопоставляется с целевым AST.
на узле. Если он обнаруживает несовпадающий узел, он вычисляет короткий путь редактирования, который может быть
преобразовать в
. Поиск кратчайшего пути редактирования является NP-сложной задачей, поэтому можно использовать некоторые методы для вычисления
прибыть
преобразование . Конечным результатом вычисления разницы дерева является набор операций изменения, представляющих собой перемещение, обновление, удаление или вставку узлов в исходном и целевом AST:
- переехать:
Узел (и его дочерние элементы) на:
был перемещен в другое место
- обновить:
Значение того же узла в () равно:
изменить на
- Удалить::
Узел (и его дочерние элементы) на:
]() устранен
- вставлять:
Добавлен:
Узлы, которых нет на
На рис. 2 показан AST из нашего примера (см. раздел 3), на рис. а — начальное состояние ошибки, а на рис. b — AST, исправленное после того, как разработчик добавил оператор импорта.
Рис. 2 Изменения Java AST
Изменения узлов, обнаруженные алгоритмом AST diff, показаны серым цветом на рис. 2. При выполнении сравнения AST в примере обнаружен узел IMPORT, вставленный в корневой узел COMPILATION_UNIT. Полное имя пакета ImmutableList также вставляется в качестве дочернего узла во вновь добавленный узел IMPORT. Для файлов сборки обнаруженным действием изменения является обновление зависимостей (deps), т. е. обновление универсального базового пакета до универсального пакета сбора.
4.3 Исправление изменений
Мы считаем, что в практике разработчиков по устранению ошибок сборки есть повторяющиеся шаблоны. Мы можем автоматически вывести эти шаблоны из исправительных изменений и использовать их для помощи в разработке.
Определение 4 Изменение разрешения (RC).Исправление (RC) относится к разнице AST между ошибочным моментальным снимком и ремонтным моментальным снимком в сеансе восстановления.
5 Исправление ошибок сборки
Недавние исследования показали, что модели, изначально предназначенные для анализа естественного языка, такие как модели n-грамм, также могут быть эффективны при выводе исходного кода. Это известно как _гипотеза естественности_ языков программирования, означающая, что большие наборы кодов имеют общее сходство с текстом на естественном языке, поскольку кодирование также представляет собой общение между людьми. Следуя этой гипотезе, мы утверждаем, что вероятностные модели машинного обучения, которые обрабатывают естественный язык, также могут использоваться для помощи в программировании.
В частности, наша идея состоит в том, чтобы рассматривать задачу предоставления предложений по ремонту как проблему нейронного машинного перевода (NMT). В нашем случае цель состоит не в том, чтобы перевести один естественный язык на другой, а в том, чтобы «перевести» заданную диагностическую функцию сборки исходного кода в функцию исправления и изменения, которая решает диагностическую проблему.
5.1 Извлечение признаков
Мы генерируем собственные значения на основе каждого изменения ремонта, т. е. сборки диагностики и правок, которые ремонтируют диагностику. Мы используем сгенерированные функции в качестве входных данных для нейронной сети, чтобы изучить шаблоны перехода между диагностикой и ремонтом.
Для каждого изменения отрисовки в сеансе отрисовки мы отдельно генерируем исходную и целевую функции. Пара исходно-целевых функций может отражать информацию об ошибках сборки и соответствующие фиксированные изменения AST.
исходная функция. Исходные характеристики связаны с типами диагностики зданий и их текстовыми описаниями. Они могут быть включены в сигнатуру источника любого типа диагностики, независимо от самой диагностической информации.
Чтобы предоставить больше контекста для алгоритма машинного обучения, мы можем дополнительно добавить диагностическую информацию к исходным функциям. Например, для cant.resolve мы анализируем моментальный снимок кода с сообщением об ошибке в AST, находим отсутствующие символы в AST на основе такой информации, как метки и местоположения, предоставленные компилятором, а затем просматриваем дерево, чтобы получить его путь AST. .
Рис. 3. Путь AST к ImmutableList
Определение 5 Путь абстрактного синтаксического дерева Путь AST (AP).отсутствующий символПуть AST кода ошибки — от корневого узла к AST кода ошибки.
Последовательность узлов родительского узла .
На рис. 3 показаны пути AST для отсутствующих символов в нашем рабочем примере. Результаты оценки показывают, что использование пути AST может повысить точность результатов на 15-20%. Пути AST предоставляют глубоким нейронным сетям контекстную информацию об отсутствующих символах, например, является ли символ локальной переменной в методе или переменной класса.
В дополнение к пути AST символа мы добавляем его тип узла, метку и его дочерние элементы (например, параметр типа вызова метода) к исходному объекту. В работающем примере исходные функции включают в себя:
- Тип диагностики: компилятор.err.cant.resolve
- Диагностический текст: не удается найти символ
- Путь AST: COMPILATION_UNIT CLASS METHOD RETURN METHOD_INVOCATION of
- Тип символа: ИДЕНТИФИКАТОР
- Метка символа: ImmutableList
Для ошибок cant.apply.symbol мы дополняем исходные характеристики тремя типами данных: ожидаемыми, найденными и причиной. Ожидаемые данные — это ожидаемый тип, выведенный компилятором, данные обнаружения показывают тип, найденный в коде, а данные причины — буквальное описание символа, который компилятор не смог применить.
целевая функция. Целевые функции содержат информацию об изменениях исправления, т. е. изменениях AST, сделанных для исправления кода, который не удалось скомпилировать.
Чтобы зафиксировать функции, которые фиксируют изменения, мы определяем предметно-ориентированный язык (DSL) под названием Delta. Грамматика Delta основана на определении спецификации парсера EBNF, как показано в листинге 1.
Каждая дельта-функция начинается с типа измененного файла (например, JAVAFILE или BUILDFILE), за которым следует последовательность действий по изменению. Каждая операция изменения содержит тип изменения AST (например, INSERT, UPDATE), а также тип и значение измененного узла AST. Для типов изменений INSERT, DELETE и MOVE также включается родительский узел измененного узла, чтобы предоставить больше контекстной информации, такой как относительная близость измененного узла. Для UPDATE будет извлечено значение до и после изменения узла.
В нашем примере целевые подписи fix-change для файлов Java и файлов сборки показаны в листинге 2 и листинге 3 соответственно.
Листинг 3. Пример файла сборки Delta
генерация признаков. После извлечения функций мы отдельно анализируем исходные и целевые функции, чтобы сгенерировать два соответствующих словаря топовых | V | высокочастотных токенов. Например, поскольку термин COMPILATION_UNIT является корневым узлом пути AST, он часто появляется в исходных функциях. Таким образом, слово instance появится в исходном словаре. Аналогично, пример слова BUILDFILE появляется во многих целевых функциях и, следовательно, также присутствует в целевом словаре. Эти высокочастотные слова используются для встраивания при обучении и выводе, то есть слова в словаре сопоставляются с реальным вектором для обучения, а во время вывода векторизованное представление результата сопоставляется обратно со словарем.
Наконец, набор данных о функциях случайным образом делится на три части в соответствии с пропорциями 70%, 15% и 15%, которые используются для обучения, онлайн-оценки модели и автономной оценки модели для невидимых функций.
5.2 Обучение фиксации шаблона изменений
Глубокие модели NMT недавно добились многообещающих результатов в области перевода на естественный язык. Используя настройку кодера-декодера для преобразования исходной функции x в целевую функцию y, также известную как seq2seq, NMT получает результат путем моделирования и изучения условной вероятности p(y|x) этого процесса. Кодер отвечает за выражение каждой исходной функции x без каких-либо прогнозов. Декодер предсказывает следующее слово в последовательности на основе выражения источника, в результате чего получается перевод y.
Наша глубокая нейронная сеть (DNN) построена на TensorFlow и состоит из 1024-элементной глубокой нейронной сети обратной связи LSTM (RNN) с 4 слоями кодировщика и 4 слоями декодера. Кодировщик Мы выбираем кодировщик Google Neural Machine Translation (GNMT), который состоит из 1 двунаправленного слоя и 3 однонаправленных слоев.
Мы представляем алгоритм стохастического градиентного спуска (SGD) как итерационный метод со скоростью обучения 1,0. Чтобы уменьшить переоснащение, мы установили значение отсева 0,2. То есть, случайно игнорируя часть нейронов, выпадение может предотвратить совместную адаптацию обучающей выборки. LSTM хорошо работают с входными последовательностями короткой и средней длины, но плохо справляются с длинными текстами. Attention Mechanism хорошо решает это ограничение, расширяя диапазон внимания сети. Так как последовательность функций для изменения отрисовки может быть длинной, мы используем стандартное внимание Багданау.
5.3 Вывод рекомендаций по ремонту
Весь процесс конвейеризирован в последовательных зависимостях, включая создание сеансов исправления, исправление изменений и значений функций, а также обучение модели. Таким образом, весь наш процесс обучения автоматизирован и повторяем.
После завершения обучения модели загрузите ее на сервер для прогнозирования исправления запросов. Модели могут генерировать большое количество переводов для произвольных входных данных. В нашей настройке NMT поиск переводов осуществляется с использованием поиска луча, нового алгоритма поиска, который сочетает в себе время перевода и точность. На вход модели подается исходный признак x, характеризующий ошибку компиляции, а на выходе предлагается последовательность n {} возвращается в виде . каждый
представляет собой другое предложение по исправлению для x, состоящее из ряда исправлений.
6 Оценка
Мы эмпирически оцениваем влияние Delta на две наиболее распространенные и трудоемкие ошибки компиляции, cant.resolve и cant.apply.symbol.
6.1 Генерация данных
Набор данных, который мы использовали для обучения и оценки, представлен в разделе 2.4 и содержит данные сборки, собранные Google за двухмесячный период.
Сначала мы вычисляем разницу AST между ошибочным кодом и разрешенным кодом для всех зеленых одиночных сеансов разрешения. Затем ограничьте количество изменений AST от 0 до 6, так как большее количество изменений часто содержит рефакторинг, а более ранние исследования показали, что исправления обычно содержат менее 6 изменений. Всего мы насчитали 110 219 зеленых сеансов с одним решением, охватывающих 37 867 файлов Java и 7011 файлов сборки.
Поскольку мы имеем дело с большой базой бизнес-кода, мы устанавливаем верхний и нижний регистр |V| для исходного и целевого словарей равными 30 000. Этап генерации признаков дает два словаря исходного и целевого, каждый из которых содержит до 30 000 различных слов. cant.resolve и cant.apply.symbol дали 265 456 и 25 201 исходных/целевых признаков соответственно. Как показано в Таблице 3, эти собственные значения перемешиваются случайным образом и делятся на три части, а именно обучающий набор (для обучения), проверочный набор (для онлайн-оценки во время обучения) и тестовый набор (для автономной оценки модели). Каждое разнообразие содержит пары исходных/целевых признаков.
Таблица 3 Сгенерированные собственные значения
6.2 Обучение
Мы отдельно извлекаем функции и обучаем модели для cant.resolve и cant.apply.symbol, чтобы сравнить производительность DeepDelta при различных типах диагностики. В дополнение к настройке DNN, описанной в разделе 5.2, мы также настраиваем сеть следующим образом: максимальная длина последовательности как для источника, так и для цели установлена на 100, размер пакета — 128, количество шагов обучения — 100 000, и вывод Алгоритм настроен на генерацию 10 рекомендаций одновременно (см. раздел 5.3).
Мы передаем исходные/целевые функции обучающего набора, а также словарный запас в нейронную сеть для обучения модели. Модель сначала выполняет встраивание исходных/целевых токенов, которое предоставляет исходный и целевой словари, чтобы гарантировать, что каждый токен не повторяется. Мы также передаем набор проверки в сеть для проверки во время обучения. Модели обучались на внутренних облачных узлах Google с графическими процессорами.
6.3 Метод оценки
Мы оцениваем с помощью тестового набора, который также содержит исходные/целевые функции. Это данные, которых модель не коснулась. Мы оцениваем каждый тип диагностики отдельно, получаем исходные признаки каждых данных в тестовом наборе, вводим их на сервер логических выводов и получаем предложения по исправлению. Целевые характеристики тестового набора данных, то есть схемы отрисовки, фактически выполненные разработчиками, служат эталоном оценки для 10 предложений по отрисовке, сгенерированных DeepDelta.
Мы используем следующие показатели для оценки эффекта предложений по ремонту.
недоумение: недоумение показывает, насколько хорошо модель предсказывает выборку, а низкое недоумение (одна цифра) указывает на то, что модель хорошо предсказывает заданную последовательность.
BLEU: BELU — это общепринятая метрика, используемая для оценки качества предложений машинного перевода. Практика показывает, что она имеет хорошую корреляцию с человеческим суждением. BELU использует модель n-грамм для вычисления соответствия между входными и выходными предложениями на основе слов и их порядка. Значение индикатора BELU находится в диапазоне 1-100. Оценка 25-40 за перевод на естественный язык считается высокой оценкой.
синтаксическая проверка: Для проверки синтаксической корректности мы сгенерировали лексер и парсер из дельта-грамматики через ANTLR4. Мы передаем предложения по исправлению в разностный синтаксический анализатор/анализатор, чтобы мы могли оценить, соответствуют ли предложения, данные моделью, ожидаемому синтаксису изменения исправления. Результатом является логическое значение, т. е. совпадение или ошибка.
правильность исправления: исправление считается правильным, если хотя бы одно из 10 рекомендованных исправлений является действительным и точно соответствует исправлению, созданному вручную разработчиком (т. е. эталону целевой функции для тестового набора). При сравнении предлагаемого исправления с эталоном мы используем сравнение текстовых строк на равенство.
Правильно установленный рейтинг: Ранжирование правильных предложений по ремонту во всем списке предложений по ремонту, указывающее на способность модели генерировать правильный ремонт. Чем выше ранг, тем быстрее может быть применено исправление. Когда DeepDelta генерирует правильное предложение по исправлению, мы отмечаем его позицию в списке из 10 предложений по исправлению.
6.4 Результаты
В таблице 4 представлены результаты для двух оцениваемых нами диагностических типов. В таблице показаны недоумение и оценка BLEU для каждого типа диагностики, количество неудачных компиляций в наборе тестов, количество сгенерированных рекомендаций (10 на каждую неудачную компиляцию), средний процент действительных рекомендаций с правильными исправлениями в первой тройке. процент в предложении.
Таблица 4 Результаты
Растерянность и оценка BLEU: Как упоминалось ранее, модель преследует низкую степень недоумения (однозначные числа) и высокую оценку BLEU (25–40). Таблица 4 показывает, что наша модель достигла низкого уровня недоумения 1,8 и 8,5 для двух диагностических типов cant.resolve и cant.apply.symbol соответственно. Оценка BLEU также высока: 42 балла для cant.resolve и 43 балла для cant.apply.symbol.
проверять: На рисунке 4 показано распределение действительных предложений по 10 сгенерированным предложениям для каждого отказа в виде гистограммы. Наша проверка синтаксиса Delta показывает, что 71% предложенных исправлений для ошибок cant.resolve действительны. Для ошибок cant.apply.symbol, поскольку изменения кода синтаксически проще (например, изменения параметров метода), процент допустимых предложений выше — 98 %. Как видно, большинство сгенерированных последовательностей операторов верны. Мы обсудим основные причины недействительных рекомендаций в разделе 7.
Рис. 4. Распределение действительных предложений среди 10 предложений по исправлению одной ошибки сборки
правильность: Таблица 4 показывает, что в нашем тестовом наборе 18 051 (50%) из 36 101 ошибок, о которых сообщает cant.resolve, были получены правильные предложения по исправлению, то есть одно из 10 предложений по исправлению в отчете об ошибках точно соответствует исправлению вручную разработчиком. cant.apply.symbol также получил аналогичный показатель правильности, то есть 1263 из 2687 правильных (47%).
ранжирование: в тех случаях, когда дается правильное предложение по исправлению, мы оцениваем позицию правильного предложения в списке предложений. На рисунке 5 показано распределение правильных предложений среди 10 предложений по ремонту. Данные показывают, что большинство правильных предложений приходят первыми. 85% правильных исправлений для cant.resolve находятся в первой тройке, а для cant.apply.symbol — 87%.
Рисунок 5 Распределение мест правильного ремонта
7 Анализ и риск
правильность: DeepDelta предложил правильное исправление примерно для половины сбоев сборки при тестировании. Правильные исправления — это не просто двоичный вывод, а сложные последовательности AST, изменяющие код. По сравнению с идеальным уровнем исправления грамматических ошибок в 27%, наш показатель 50% исправлений на практике весьма впечатляет. Этот относительно высокий уровень точности можно объяснить следующими характеристиками набора данных и метода:
- Действительно, существуют некоторые общие закономерности в том, как разработчики устраняют сбои сборки, которые DeepDelta может извлечь из исправления изменений.
- Наш целевой язык Delta хорошо структурирован, поэтому модель может изучать закономерности систематическим образом.
неверная последовательность: мы исследовали основные причины недействительных предложений, которые можно свести к следующим:
- Неизвестные токены: токены, появляющиеся в рекомендуемой целевой последовательности. Предсказания модели получают векторизованное вложение, которое затем декодер пытается преобразовать в примеры слов. Иногда векторы встраивания настолько далеки от действительных токенов в данном словаре, что не могут сопоставляться с высокочастотными токенами. Это может произойти, когда среди паттернов, изученных моделью, не появляется ошибочный паттерн восстановления, или когда словарь не содержит слова (поскольку оно не входит в число высокочастотных слов).
- Неполная последовательность: в результирующей последовательности операторов отсутствует часть последовательности дельта-синтаксиса. Эта проблема особенно характерна для более длинных последовательностей (более 90 токенов), что приводит к выпадению слов в конце последовательности.
Обобщение: эти результаты и методы могут не распространяться на другие среды разработки, например, на широко используемые IDE, где разные среды могут иметь разные типы общей диагностики. Хотя все наши наборы данных принадлежат одной компании, почти все проекты находятся в большом репозитории исходного кода Google. Итак, наш набор данных:
- Охватывает более 10 000 проектов Java, 300 миллионов строк кода. Многие из них являются проектами с открытым исходным кодом, хотя это только данные проектов разработки под руководством Google.
- Изменения кода, сделанные тысячами профессиональных разработчиков со всего мира, из всех слоев общества, с использованием около 5 редакторов/IDE.
- Содержит 110 219 ошибок компиляции сборки и их исправления, собранные за двухмесячный период, более 37 867 файлов Java и 7011 файлов сборки.
Таким образом, у нас есть основания полагать, что наши методы исправления программ могут быть распространены на любую другую подобную среду разработки, если существует некоторая закономерность в том, как разработчики обращаются с диагностическими типами. Даже если наше изучение модели и предлагаемые исправления неприменимы в других репозиториях и системах сборки, сама методика является общей и применима к другим репозиториям исходного кода и системам сборки. Например, предположим, что мы хотим добавить зависимость внешнего проекта в файл сборки Bazel, операция, которая также широко распространена в других системах сборки. Пока предоставляются синтаксические анализаторы для анализа других типов файлов конфигурации сборки (например, файлы POM для Maven, build.gradle для Gradle), наша система может научиться правильно добавлять зависимости.
Самый распространенный способ ремонта: мы можем использовать сгенерированные собственные значения, чтобы изучить, как разработчики устраняют ошибки компиляции. Мы заботимся об изменении схемы, поэтому мы абстрагируем имя идентификатора, заменяя имя идентификатора (например, «ImmutableList») постоянной строкой (т. е. «{X}») в целевом объекте. Эти абстрактные функции затем векторизируются с использованием модели word2vec с токенизатором n-грамм. Затем введите вектор признаков в алгоритм k-средних для кластеризации и установите k=20. Общие шаблоны cant.resolve, появляющиеся в шести крупнейших кластерах, приведены в таблице 5, которая содержит описания шаблонов, шаблоны исправлений и конкретные примеры для каждого кластера.
воспроизводимость: Наш набор данных содержит AST проприетарных кодов, но они не публикуются. Наш набор данных уникален, потому что он содержит моментальные снимки незавершенного кода, а не только зафиксированного кода. Эта детальность является ключом к жизнеспособности всего подхода. Мы еще не нашли каких-либо наборов данных с открытым исходным кодом, в которых содержится подробная информация о таких ошибках/исправлениях. Наш успех можно воспроизвести, если мы сможем собирать подробные записи о действиях разработчиков и использовать спецификацию языка Delta и библиотеку TensorFlow NMT с открытым исходным кодом.
Тип диагноза: В нашем исследовании для диагностики использовались только Java-проекты. Но эта методика общая, разница только в АСТ. Единственная часть, зависящая от языка, — это синтаксический анализатор, используемый для построения AST. Мы можем поддерживать другие языки, просто реализовав парсер.
В этой статье мы сосредоточимся только на двух типах ошибок (cant.resolve и cant.apply.symbol) по двум причинам: во-первых, эти две ошибки составляют подавляющее большинство ошибок компиляции Java, с которыми сталкиваются разработчики Google, число которых приходится на 59 %, а стоимость ремонта составила 58 % (табл. 2). Наши данные показывают, что независимо от сложности исправления (R1) разработчики тратят много времени на исправление вручную. Автоматизация исправлений позволяет разработчикам сосредоточиться на других проблемах. Во-вторых, добавление новых типов ошибок требует сбора соответствующих данных разработчика и переобучения модели, что занимает много времени.
Наши результаты показывают, что DeepDelta хорошо работает для обоих типов ошибок с разными режимами исправления. Мы ожидаем, что то же самое будет работать и с другими типами ошибок сборки, и намерены расширить поддержку других типов. В настоящее время мы не нашли других инструментов для исправления ошибок компиляции Java, которые можно было бы использовать для сравнения.Наиболее похожим исследованием является статья об исправлении синтаксических ошибок (только одного типа) в языке C [18]. .
Анализируемый AST: Наше исследование основано на сравнении различий AST, поэтому код, который дает сбой, должен поддерживать синтаксический анализ AST. Код всегда анализируется до уникального AST для ошибок отсутствия символов, но не обязательно для других типов диагностики. Дизайн синтаксического анализатора можно оптимизировать, чтобы избежать быстрых сбоев и вместо этого использовать восстановление после синтаксических ошибок. Если вы имеете дело с неполными AST, возможно, вам придется перейти на этот тип синтаксического анализатора.
8 планов на будущее
Преобразование программы Delta в модификацию кода: Дельта-программа — это, по сути, разница между двумя версиями одной и той же программы, и DeepDelta прогнозирует разницу на основе диагностических входных данных. Для дельта-программы, заданной прогнозом, мы также применяем ее к неизвестной программе, особенно для того, чтобы знать, где внести изменения. Здесь мы кратко опишем идею решения этой проблемы, используя в качестве примеров несколько распространенных дельта-изменений.
Взгляните на общие шаблоны изменений исправления для cant.resolve, показанные в таблице 5. Для «Добавить отсутствующий оператор импорта» и «Удалить импорт» нам не нужна информация о местоположении, поскольку импорт должен находиться в определенном месте в исходном файле Java. Для «вызов метода изменения» и «изменить отсутствующий символ» мы знаем из диагностического текста, где находится отсутствующий символ, поэтому мы можем изменить код там. Для «Добавить отсутствующие зависимости сборки» и «Изменить зависимости сборки» мы знаем, какое правило сборки вызывает ошибку, поэтому мы можем внести изменения в его список зависимостей.
Как правило, мы можем найти разумные места изменения кода на основе конструкций (только одно синтаксически допустимое место изменения) или информации о местоположении в диагностическом тексте.
Внедрить инструменты исправления кода: Мы намерены интегрировать DeepDelta в среду разработки нашей компании (т.е. Google) разработчиков. Для этого мы проверяем предложение по исправлению, прежде чем применять его к пользовательскому коду. Мы собираемся создать приложение, которое попытается применить предложенные исправления к моментальному снимку кода и выполнить сборку. Затем мы можем отбросить исправления, которые не компилируются, и предоставить пользователю только приемлемые исправления. Здесь также есть несколько интересных взаимодействий, чтобы обеспечить простоту использования инструмента.
9 Связанные исследования
Извлечь режим изменения: Ранее мы также упоминали об извлечении шаблонов изменений из кода. Однако большинство существующих методов требуют предопределенных правил или вмешательства человека для извлечения закономерностей. Флури и Галл [14] определили 41 базовый тип изменений Java и использовали алгоритм иерархической кластеризации для изучения сложных изменений. Pan [37] использует Unix diffs для создания базы данных основных изменений и использует Datalog для ручного указания правил для более сложных типов изменений.
Liveshits и Zimmerman [26] предложили подход к изучению паттернов использования API путем анализа правил ассоциации на основе истории кода двух проектов Java, и они использовали эти паттерны для обнаружения конфликтов. Ким и др. [25] вручную изучают написанные человеком исправления и извлекают шесть распространенных шаблонов восстановления в Java, которые они затем используют для автоматического исправления программ.
Ханам и др. [19] предлагают полуавтоматический подход к обнаружению шаблонов исправления ошибок, они извлекают изменения AST языковой конструкции, которые разрешают ошибки времени выполнения в виде векторов признаков, используют кластеризацию для группировки и ранжирования их в шаблоны исправления, а затем вручную проверьте класс clusters., чтобы получить режим исправления ошибок. В то время как наш метод не требует вмешательства человека, а также может изучать _неизвестные_ шаблоны ремонтных изменений.
Синтетическое преобразование на примере: Другая родственная область исследований — это методы транскодирования, такие как LASE [33], Genesis [27], NoFAQ [8] и REFAZER [41], которые могут извлекать и синтаксически преобразовывать примеры. Эти методы также могут быть применены для исправления программ. В отличие от нашей работы, они оперируют одним примером или небольшим количеством примеров, эффект извлечения паттерна из большого количества примеров неизвестен, и неясно, как его применять в сценарии процедурного ремонта.
Программа авто ремонт: Наше исследование относится к области автоматического исправления программ, то есть исправления ошибок с помощью автоматизированных методов. Программные исправления теперь применяются в различных областях, таких как структуры данных [11, 12], пользовательские интерфейсы [49] и исходные коды на различных языках программирования, таких как C [16, 24, 29], Java [10, 25], JavaScript [36] и PHP [42] (лучшие языки).
На практике методы поиска исправлений имеют много недостатков. Во-первых, им обычно требуются предопределенные шаблоны шаблонов ошибок, и они не могут изучать новые шаблоны. Во-вторых, процесс генерации исправлений требует поиска в огромном программном пространстве, что может быть дорогостоящим, поскольку для устранения ошибки генерируются тысячи исправлений. Наконец, исследования показали, что они дают много ложных срабатываний, то есть ситуаций, когда тесты не могут быть исправлены чаще, чем фактические ошибки.
Машинное обучение для восстановления программ: Алламанис и др. [2] представляют всесторонний обзор последних достижений в методах анализа исходного кода с использованием машинного обучения. [47] предложили метод прогнозирования отказов, в котором они предоставляли абстрактные семантические характеристики кода нейронной сети для классификации. [40] использовали нейронные сети для завершения отсутствующих вызовов API в коде. Зайдель и др. [43] достигли локализации ошибок целевого типа с помощью метода классификации обучения с учителем.
[18] предложил метод машинного обучения seq2seq для исправления синтаксических ошибок в языке C. Основное отличие от нашей работы заключается в том, что они выложили в сеть весь исходный код багги и исправленной версии и добились 27% исправлений. Принимая во внимание, что мы фокусируемся только на изучении особенностей сбоя и соответствующих изменений AST для устранения этого сбоя, что позволяет нам достичь более высокого уровня точности (50%). Они нацелены на синтаксические ошибки в C, а мы нацелены на ошибки компиляции во время сборки в Java. Кроме того, в их тестовых образцах использовались небольшие студенческие задания, тогда как наши оценки основывались на больших объемах реальных данных разработчиков.
В нашей статье впервые рассматриваются ошибки компиляции путем изучения закономерностей изменений AST. Связанные исследования ошибок сборки [20, 31] отличаются от наших: они сосредоточены только на файлах сборки, тогда как мы нацелены как на Java, так и на файлы сборки; они используют предопределенные шаблоны исправлений, в то время как мы изучаем шаблоны исправлений; и в более широком масштабе, [31] и [20] использовали 37 и 175 ошибок соответственно, в то время как мы использовали 38 788 ошибок для оценки алгоритма DeepDelta.
10 Резюме
В этой статье мы рассмотрели ошибки сборки и то, как разработчики могут изменить свой код, чтобы устранить их вручную. Мы демонстрируем, что в таких изменениях кода есть закономерность. Мы предлагаем общую методику извлечения различий AST из ошибочных и исправленных версий для изучения шаблонов изменения кода. Мы определяем автоматическое восстановление программы как проблему машинного перевода.
В нашей методике DeepDelta используется глубокая нейронная сеть, чтобы рекомендовать исправленные изменения AST на основе входных данных для построения диагноза. Наша оценка обширных реальных данных разработчиков Google показывает, что DeepDelta создает до 50 % правильных исправлений для обоих типов диагностики компиляции, при этом правильное исправление находится в тройке лучших исправлений в 85–87 % случаев.
В настоящее время наша система поддерживает исправление двух наиболее трудоемких типов диагностики: cant.resolve и cant.apply.symbol. Мы планируем расширить поддержку других типов диагностики.
коммерческое время
imgcook фокусируется на визуальных черновиках в форме Sketch, PSD, статических изображений и т. д. в качестве входных данных и генерирует удобный интерфейсный код одним щелчком мыши с помощью интеллектуальной технологии, включая код представления, привязку полей данных, код компонентов и некоторую бизнес-логику. код. Мы ожидаем, что imgcook (шеф-повар по изображениям) будет использовать интеллектуальные средства, чтобы стать фронтенд-инженером уровня P5, добиться высокой степени восстановления при минимальных ограничениях на эскизы дизайна, повысить производительность интерфейса и помочь интерфейсу и дизайнеры эффективно сотрудничают, позволяя вам сосредоточиться на более сложных вещах!
Добро пожаловать к нам:[Социальный рекрутинг/Школьный рекрутмент] [Ханчжоу] [Технологический отдел Alibaba — Channel и D2C Intelligence] Вербовка переднего плана: В данный момент это должен быть я!
использованная литература
Примечания: сохранены только статьи, упомянутые в соответствующем исследовании, а остальные опущены.
[2] Милтиадис Алламанис, Эрл Т. Барр, Премкумар Деванбу и Чарльз Саттон, 2017 г. Обзор
Machine Learning for Big Code and Naturalness. arXiv preprint arXiv:1709.06182 (2017).
[10] Фавио ДеМарко, Джифэн Суан, Даниэль Ле Берре и Мартин Монперрус, 2014 г. Автоматическое исправление багги, если условия и отсутствующие предварительные условия с помощью SMT, В материалах 6-го Международного семинара по ограничениям в тестировании, проверке и анализе программного обеспечения, 30–30. 39.
[11] Брайан Демски и Мартин Ринар, 2005 г. Восстановление структуры данных с использованием целенаправленных рассуждений, Материалы Международной конференции по программной инженерии (ICSE), 176–185.
[12] Бассем Элькарабли, Иван Гарсия, Юк Лай Суен и Сарфраз Хуршид, 2007 г. Восстановление сложных структур данных на основе утверждений, Материалы двадцать второй международной конференции IEEE/ACM по автоматизированной разработке программного обеспечения, ACM, 64–73.
[14] Beat Fluri и Harald C Gall, 2006 г. Классификация типов изменений для квалификации взаимосвязей изменений, In Program Comprehension, 2006 г. ICPC, 2006 г. 14-я Международная конференция IEEE по IEEE, 35–45.
[16] К. Ле Гу, Т. Нгуен, С. Форрест и В. Веймер, 2012 г. GenProg: универсальный метод автоматического восстановления программного обеспечения, IEEE Transactions on Software Engineering 38, 1 (январь 2012 г.), 54–72.сделать i.org/10.1109/ts E…
[18] Рахул Гупта, Сохам Пал, Адитья Канаде и Шириш Шеваде, 2017. DeepFix: исправление распространенных ошибок языка C с помощью глубокого обучения.. В материалах конференции по искусственному интеллекту (AAAI), 1345–1351.
[19] Куинн Ханам, Фернандо С. де М. Брито и Али Месба, 2016 г. Обнаружение шаблонов ошибок в JavaScript, Материалы 24-го Международного симпозиума ACM SIGSOFT по основам разработки программного обеспечения (FSE) 2016 г. ACM, 144–156.
[20] Foyzul Hassan и Xiaoyin Wang, 2018. HireBuild: автоматический подход к восстановлению сценариев сборки на основе истории, 40-я Международная конференция IEEE/ACM по программной инженерии (ICSE), 2018 г., IEEE, 1078–1089.
[24] Ю. Ке, К. Т. Столи, К. Л. Гоуз и Ю. Брун, 2015. Восстановление программ с помощью семантического поиска кода, Материалы Международной конференции по автоматизированной разработке программного обеспечения (ASE), IEEE Computer Society, 295–306.сделать i.org/10.1109/как E…
[25] Донгсун Ким, Джэчан Нам, Джэу Сонг и Сунхун Ким, 2013 г. Автоматическое создание исправлений, извлеченное из написанных человеком исправлений, Материалы Международной конференции по программной инженерии (ICSE), 802–811.
[26] Бенджамин Лившиц и Томас Циммерманн, 2005 г. DynaMine: Поиск распространенных шаблонов ошибок с помощью историй изменений программного обеспечения для майнинга, В ACM SIGSOFT Software Engineering Notes, Vol.30, ACM, 296–305.
[27] Фан Лонг, Питер Амидон и Мартин Ринар, 2017. Автоматический вывод преобразований кода для генерации исправлений, В материалах 11-го Совместного совещания по основам программной инженерии, ACM, 727–739.
[29] Фан Лонг и Мартин Ринард, 2016 г. Анализ пространств поиска для создания и проверки систем генерации исправлений, Материалы Международной конференции по программной инженерии (ICSE), ACM, Нью-Йорк, США, 702–713 .сделать i.org/10.1145/288…
[31] Кристиан Мачо, Шейн Макинтош и Мартин Пинцгер, 2018 г. Автоматическое исправление поломки сборки, связанной с зависимостями, В 2018 г. 25-я Международная конференция IEEE по анализу, эволюции и реинжинирингу программного обеспечения (SANER), IEEE, 106–117.
[33] Na Meng, Miryung Kim, and Kathryn S McKinley. 2013. LASE: Locating and Applying Systematic Edits by Learning from Examples. IEEE Press.
[36] Фролин Окариза, Картик Паттабираман и Али Месбах, 2014 г. Вейовис: предложения по устранению ошибок JavaScript, Материалы Международной конференции по программной инженерии (ICSE), ACM, 837–847.
[37] Кай Пан, Сунхун Ким и Э. Джеймс Уайтхед, 2009 г. На пути к пониманию шаблонов исправления ошибок, Эмпирическая разработка программного обеспечения 14, 3 (2009), 286–315.
[40] Веселин Райчев, Мартин Вечев и Эран Яхав, 2014. Завершение кода с помощью статистических языковых моделей, В уведомлениях Acm Sigplan, том 49, ACM, 419–428.
[41] Реудизмам Ролим, Густаво Соареш, Лорис Д'Антони, Александр Полозов, Сумит Гулвани, Рохит Гейи, Рио Судзуки и Бьорн Хартманн, 2017. Изучение преобразований синтаксических программ на примерах, Материалы 39-й Международной конференции по программной инженерии. IEEE Press, 404–415.
[42] Hesam Samimi, Max Schäfer, Shay Artzi, Todd Millstein, Frank Tip и Laurie Hendren, 2012. Автоматическое исправление ошибок генерации HTML в приложениях PHP с помощью решения строковых ограничений, Материалы Международной конференции по программной инженерии (ICSE). IEEE, 277–287.
[47] Сонг Ван, Тайюэ Лю и Лин Тан, 2016. Автоматическое изучение семантических функций для прогнозирования дефектов, Материалы Международной конференции по программной инженерии (ICSE), ACM, 297–308.