Entry tags:
Трудности с простыми лямбда-калькуляторами
А вот, кстати, при проверке лямбда-калькуляторов, написанных студентами, возникла такая задачка.
Пускай мы реализовали на Хаскелле лямбда-термы
Если мы теперь хотим реализовать многошаговую бета-редукцию до нормальной формы, мы можем итерировать, делая шаг редукции до тех пор, пока терм не перестанет меняться. Ну, например, так
Не видите ли вы червоточины в этой схеме?
Пускай мы реализовали на Хаскелле лямбда-термы
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
А вот в этом списке уже можно будет отдельными силами выявить циклы длиной 1, 2, сколько угодно.
Потому как
(\x->x x)(\x->x x)
ничем не лучше вышеупомянутогоfixY (\z x y -> y x z)
Или вдруг коварный Денис предложит студентам написать на лямбда-исчислении и на числах Чёрча вычислитель 3x+1. Который для крендильона первых натуральных чисел циклится с периодом 3 (1-4-2-1), но до конца в этом никто не уверен.
Кстати, Денис! Тема же для студней, э? :))
no subject
no subject
Тогда мне нужно перестать думать, что reduceToNF задумано было как останавливающаяся, когда обнаружен цикл. Наоборот, факт, что оно останавливается на (\x -> x x)(\x -> x x) и есть баг.
no subject