![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
А вот, кстати, при проверке лямбда-калькуляторов, написанных студентами, возникла такая задачка.
Пускай мы реализовали на Хаскелле лямбда-термы
Если мы теперь хотим реализовать многошаговую бета-редукцию до нормальной формы, мы можем итерировать, делая шаг редукции до тех пор, пока терм не перестанет меняться. Ну, например, так
Не видите ли вы червоточины в этой схеме?
Пускай мы реализовали на Хаскелле лямбда-термы
data Term = Var String | App Term Term | Lam String Termпроверку их альфа-эквивалентности (можно и точное совпадение, для наших целей не важно):
alphaEq :: Term -> Term -> Boolи одношаговую бета-редукцию (нормальную, для определенности, хотя это тоже не важно):
reduce :: Term -> TermВ последнем случае при отсутствии редексов просто возвращается исходный терм.
Если мы теперь хотим реализовать многошаговую бета-редукцию до нормальной формы, мы можем итерировать, делая шаг редукции до тех пор, пока терм не перестанет меняться. Ну, например, так
reduceToNF :: Term -> [Term] reduceToNF = unfoldr step where step t = let next = reduсe t in if t `alphaEq` next then Nothing else Just (t, next)
Не видите ли вы червоточины в этой схеме?
no subject
Date: 2013-03-28 03:17 pm (UTC)Что он не равен сам себе?!
no subject
Date: 2013-03-28 03:22 pm (UTC)Просто функция reduceToNF названа неправильно.
Из неподвижной точки r == reduce r не следует, что это нормальная форма (импликация там в обратную сторону, из нормальности следует неподвижность).
Отсюда, таки, мораль! reduce должна возвращать монаду - Maybe или [], по вкусу. Смысл которой - "мне удалось что-то внутри редуцировать".
Тогда и reduceToNF будет простой донельзя: unfoldr reduceMaybe.
И проверка альфа-эквивалентности не нужна.
no subject
Date: 2013-03-28 05:50 pm (UTC)ни о чём не говорит. (\x -> x x)(\x -> x x) мне всегда удастся что-то внутри редуцировать.
no subject
Date: 2013-03-28 06:05 pm (UTC)А вот в этом списке уже можно будет отдельными силами выявить циклы длиной 1, 2, сколько угодно.
Потому как
(\x->x x)(\x->x x)
ничем не лучше вышеупомянутогоfixY (\z x y -> y x z)
Или вдруг коварный Денис предложит студентам написать на лямбда-исчислении и на числах Чёрча вычислитель 3x+1. Который для крендильона первых натуральных чисел циклится с периодом 3 (1-4-2-1), но до конца в этом никто не уверен.
Кстати, Денис! Тема же для студней, э? :))
no subject
Date: 2013-03-28 06:10 pm (UTC)no subject
Date: 2013-03-28 06:20 pm (UTC)Тогда мне нужно перестать думать, что reduceToNF задумано было как останавливающаяся, когда обнаружен цикл. Наоборот, факт, что оно останавливается на (\x -> x x)(\x -> x x) и есть баг.
no subject
Date: 2013-03-29 01:44 pm (UTC)no subject
Date: 2013-03-29 01:44 pm (UTC)