Тест на мужчину или мальчика - Man or boy test
В тест на мужчину или мальчика был предложен компьютерным ученым Дональд Кнут как средство оценки реализации АЛГОЛ 60 язык программирования. Целью теста было выявить компиляторы что правильно реализовано "рекурсия и нелокальные ссылки "от тех, кто этого не сделал.
Существует довольно много трансляторов ALGOL60, которые были разработаны для правильной обработки рекурсии и нелокальных ссылок, и я подумал, что, возможно, небольшая тестовая программа может оказаться полезной. Поэтому я написал следующую простую процедуру, которая может отделить компиляторов-мужчин от компиляторов-мальчиков.
Пример Кнута
В АЛГОЛ 60:
начинать настоящий процедура А(k, x1, x2, x3, x4, x5); ценить k; целое число k; настоящий x1, x2, x3, x4, x5; начинать настоящий процедура B; начинать k := k - 1; B := А := А(k, B, x1, x2, x3, x4) конец; если k ≤ 0 тогда А := x4 + x5 еще B конец нереальный(1,А(10, 1, -1, -1, 1, 0))конец
Это создает дерево B фреймы вызова, которые относятся друг к другу и к содержащему А кадры вызова, каждый из которых имеет свою копию k который меняется каждый раз, когда связанный B называется. Пытаться проработать это на бумаге, вероятно, бесполезно, но для k= 10, правильный ответ -67, несмотря на то, что в исходной статье Кнут предположил, что это будет -121. Обзорный доклад Чарльз Х. Линдси упомянутые в справочных материалах содержат таблицу для различных начальных значений. Даже современные машины быстро заканчиваются. куча место для больших значений k, которые приведены в таблице ниже (OEIS: A132343).[2]
k | |
---|---|
0 | 1 |
1 | 0 |
2 | −2 |
3 | 0 |
4 | 1 |
5 | 0 |
6 | 1 |
7 | −1 |
8 | −10 |
9 | −30 |
10 | −67 |
11 | −138 |
12 | −291 |
13 | −642 |
14 | −1,446 |
15 | −3,250 |
16 | −7,244 |
17 | −16,065 |
18 | −35,601 |
19 | −78,985 |
20 | −175,416 |
21 | −389,695 |
22 | −865,609 |
23 | −1,922,362 |
24 | −4,268,854 |
25 | −9,479,595 |
26 | −21,051,458 |
Объяснение
В этой программе используются три функции Algol, которые может быть сложно правильно реализовать в компиляторе:
- Вложенная функция определения: С B определяется в местном контексте А, тело B имеет доступ к символам, которые являются локальными для А - в первую очередь k который он изменяет, но также x1, x2, x3, x4, и x5. Это просто в потомке Алгола Паскаль, но невозможно в другом крупном потомке Алгола C (без ручного моделирования механизма с помощью оператора адресации C, передавая указатели на локальные переменные между функциями).
- Ссылки на функции: The B в рекурсивном вызове А (к, В, х1, х2, х3, х4) это не призыв к B, но ссылка на B, который будет вызываться только когда k больше нуля. Это просто в стандартном Паскале (ISO 7185 ), а также в C. Некоторые варианты Паскаля (например, более старые версии Турбо Паскаль ) не поддерживают ссылки на процедуры, но если набор функций, на которые можно ссылаться, известен заранее (в этой программе это только B), это можно обойти.
- Дуализм констант / функций: The x1 через x5 параметры А могут быть числовыми константами или ссылками на функцию B - в х4 + х5 выражение должно быть подготовлено для обработки обоих случаев, как если бы формальные параметры x4 и x5 был заменен соответствующим фактическим параметром (позвонить по имени ). Вероятно, это больше проблема в статически типизированный языков, чем в языках с динамической типизацией, но стандартный обходной путь - переинтерпретировать константы 1, 0 и −1 в основном вызове А как функции без аргументов, возвращающие эти значения.
Однако тест не об этом; они просто предварительные условия для того, чтобы тест был хоть сколько-нибудь значимым. Что это за тест о есть ли разные ссылки на B решиться на правильный экземпляр B - тот, у которого есть доступ к тому же А-локальные символы как B который создал ссылку. Компилятор "мальчик" может, например, вместо этого скомпилировать программу так, чтобы B всегда обращается к самому верхнему А кадр вызова.
Смотрите также
Рекомендации
- ^ Дональд Кнут (Июль 1964 г.). "Мужчина или мальчик?". Получено 25 декабря, 2009.
- ^ Посмотрите производительность и память на странице Rosetta Code Man или Boy.
внешняя ссылка
- "Мужчина или мальчик", Бюллетень Алгола 17, п. 7 (доступно на chilton-computing.org )
- Тест на мужчину или мальчика примеры на многих языках программирования