Функция Маккарти 91 - McCarthy 91 function
Эта статья включает Список ссылок, связанное чтение или внешняя ссылка, но его источники остаются неясными, потому что в нем отсутствует встроенные цитаты.Октябрь 2015) (Узнайте, как и когда удалить этот шаблон сообщения) ( |
В Функция Маккарти 91 это рекурсивная функция, определяемый специалист в области информатики Джон Маккарти как тестовый пример для формальная проверка в Информатика.
Функция Маккарти 91 определяется как
Результаты оценки функции представлены как M(п) = 91 для всех целочисленных аргументов п ≤ 100 и M(п) = п - 10 для п > 100. Действительно, результат M (101) также равен 91 (101 - 10 = 91). Все результаты M (n) после n = 101 непрерывно увеличиваются на 1, например М (102) = 92, М (103) = 93.
История
Функция 91 была введена в статьях, опубликованных Зохар Манна, Амир Пнуели и Джон Маккарти в 1970 году. Эти документы представляли ранние разработки в направлении применения формальные методы к проверка программы. Функция 91 была выбрана как вложенно-рекурсивная (в отличие от одиночная рекурсия, например, определение посредством ). Пример был популяризирован книгой Манна, Математическая теория вычислений (1974). По мере развития области формальных методов этот пример неоднократно появлялся в исследовательской литературе. В частности, он рассматривается как «сложная проблема» для автоматизированной верификации программ.
Легче рассуждать о хвостовой рекурсивный поток управления, это эквивалент (внешне равный ) определение:
В качестве одного из примеров, используемых для демонстрации таких рассуждений, книга Манна включает хвостовой рекурсивный алгоритм, эквивалентный вложенной рекурсивной функции 91. Многие документы, в которых сообщается об «автоматической проверке» (или доказательство прекращения ) функции 91 обрабатывает только хвостовую рекурсивную версию.
Это эквивалент взаимно хвостово-рекурсивное определение:
Формальный вывод взаимно хвостовой рекурсивной версии от вложенной рекурсивной версии был дан в статье 1980 г. Митчелл Палочка, основанный на использовании продолжения.
Примеры
Пример А:
M (99) = M (M (110)), поскольку 99 ≤ 100 = M (100), поскольку 110> 100 = M (M (111)), поскольку 100 ≤ 100 = M (101), поскольку 111> 100 = 91, поскольку 101 > 100
Пример Б:
M (87) = M (M (98)) = M (M (M (109))) = M (M (99)) = M (M (M (110))) = M (M (100)) = M (M (M (111))) = M (M (101)) = M (91) = M (M (102)) = M (92) = M (M (103)) = M (93) .... Шаблон продолжает увеличиваться до M (99), M (100) и M (101), точно так же, как мы видели в примере A) = M (101), поскольку 111> 100 = 91, поскольку 101> 100
Код
Вот реализация алгоритма вложенной рекурсии в Лисп:
(defun mc91 (п) (cond ((<= п 100) (mc91 (mc91 (+ п 11)))) (т (- п 10))))
Вот реализация алгоритма вложенной рекурсии в Haskell:
mc91 п | п > 100 = п - 10 | иначе = mc91 $ mc91 $ п + 11
Вот реализация алгоритма вложенной рекурсии в OCaml:
позволять rec mc91 п = если п > 100 тогда п - 10 еще mc91 (mc91 (п + 11))
Вот реализация алгоритма хвостовой рекурсии в OCaml:
позволять mc91 п = позволять rec вспомогательный п c = если c = 0 тогда п еще если п > 100 тогда вспомогательный (п - 10) (c - 1) еще вспомогательный (п + 11) (c + 1) в вспомогательный п 1
Вот реализация алгоритма вложенной рекурсии в Python:
def mc91(п: int) -> int: "" "Функция Маккарти 91." "" если п > 100: возвращаться п - 10 еще: возвращаться mc91(mc91(п + 11))
Вот реализация алгоритма вложенной рекурсии в C:
int mc91(int п){ если (п > 100) { возвращаться п - 10; } еще { возвращаться mc91(mc91(п + 11)); }}
Вот реализация алгоритма хвостовой рекурсии в C:
int mc91(int п){ mc91taux(п, 1);}int mc91taux(int п, int c){ если (c != 0) { если (п > 100) { возвращаться mc91taux(п - 10, c - 1); } еще { возвращаться mc91taux(п + 11, c + 1); } } еще { возвращаться п; }}
Доказательство
Вот доказательство того, что
который предоставляет эквивалентный нерекурсивный алгоритм для вычисления .
За п > 100 равенство следует из определения . За п ≤ 100, а сильная индукция вниз от 100 можно использовать.
Для 90 ≤ п ≤ 100,
M (n) = M (M (n + 11)), по определению = M (n + 11-10), поскольку n + 11> 100 = M (n + 1)
Так M(п) = M(101) = 91 для 90 ≤ п ≤ 100, что можно использовать как базовый вариант.
Для шага индукции пусть п ≤ 89 и предположим M(я) = 91 для всех п < я ≤ 100, тогда
M (n) = M (M (n + 11)), по определению = M (91), по гипотезе, поскольку nЭто доказывает M(п) = 91 для всех п ≤ 100, включая отрицательные значения.
Обобщение Кнута
Дональд Кнут обобщил функцию 91 для включения дополнительных параметров.[1] Джон Коулз разработал формальное доказательство тотальности обобщенной функции Кнута, используя ACL2 средство доказательства теорем.[2]
Рекомендации
- ^ Кнут, Дональд Э. (1991). "Учебные примеры рекурсии". Искусственный интеллект и математическая теория вычислений. arXiv:cs / 9301113. Bibcode:1993cs ........ 1113K.
- ^ Коулз, Джон (2013) [2000]. «Обобщение Кнута 91 функции Маккарти». В Kaufmann, M .; Manolios, P .; Стротер Мур, Дж. (Ред.). Компьютерное мышление: тематические исследования ACL2. Kluwer Academic. С. 283–299. ISBN 9781475731880.
- Манна, Зоар; Пнуэли, Амир (июль 1970 г.). «Формализация свойств функциональных программ». Журнал ACM. 17 (3): 555–569. Дои:10.1145/321592.321606.
- Манна, Зоар; Маккарти, Джон (1970). «Свойства программ и частичная функциональная логика». Машинный интеллект. 5. OCLC 35422131.
- Манна, Зохар (1974). Математическая теория вычислений (4-е изд.). Макгроу-Хилл. ISBN 9780070399105.
- Палочка, Митчелл (январь 1980 г.). «Стратегии трансформации программ, основанные на продолжении». Журнал ACM. 27 (1): 164–180. Дои:10.1145/322169.322183.