Краткий пример экспоненциальной стоимости вывода типа ML

11

Мне стало известно, что стоимость вывода типа в функциональном языке, таком как OCaml, может быть очень высокой. Утверждение состоит в том, что существует последовательность выражений, такая, что для каждого выражения длина соответствующего типа экспоненциально зависит от длины выражения.

Я разработал последовательность ниже. Мой вопрос: знаете ли вы последовательность с более краткими выражениями, которая достигает тех же типов?

# fun a -> a;;
- : 'a -> 'a = <fun>
# fun b a -> b a;;
- : ('a -> 'b) -> 'a -> 'b = <fun>
# fun c b a -> c b (b a);;
- : (('a -> 'b) -> 'b -> 'c) -> ('a -> 'b) -> 'a -> 'c = <fun>
# fun d c b a -> d c b (c b (b a));;
- : ((('a -> 'b) -> 'b -> 'c) -> ('a -> 'b) -> 'c -> 'd) ->
   (('a -> 'b) -> 'b -> 'c) -> ('a -> 'b) -> 'a -> 'd
= <fun>
# fun e d c b a -> e d c b (d c b (c b (b a)));;
- : (((('a -> 'b) -> 'b -> 'c) -> ('a -> 'b) -> 'c -> 'd) ->
    (('a -> 'b) -> 'b -> 'c) -> ('a -> 'b) -> 'd -> 'e) ->
   ((('a -> 'b) -> 'b -> 'c) -> ('a -> 'b) -> 'c -> 'd) ->
   (('a -> 'b) -> 'b -> 'c) -> ('a -> 'b) -> 'a -> 'e
= <fun>
# fun f e d c b a -> f e d c b (e d c b (d c b (c b (b a))));;
- : ((((('a -> 'b) -> 'b -> 'c) -> ('a -> 'b) -> 'c -> 'd) ->
     (('a -> 'b) -> 'b -> 'c) -> ('a -> 'b) -> 'd -> 'e) ->
    ((('a -> 'b) -> 'b -> 'c) -> ('a -> 'b) -> 'c -> 'd) ->
    (('a -> 'b) -> 'b -> 'c) -> ('a -> 'b) -> 'e -> 'f) ->
   (((('a -> 'b) -> 'b -> 'c) -> ('a -> 'b) -> 'c -> 'd) ->
    (('a -> 'b) -> 'b -> 'c) -> ('a -> 'b) -> 'd -> 'e) ->
   ((('a -> 'b) -> 'b -> 'c) -> ('a -> 'b) -> 'c -> 'd) ->
   (('a -> 'b) -> 'b -> 'c) -> ('a -> 'b) -> 'a -> 'f
= <fun>
mrrusof
источник

Ответы:

14

В этом ответе я остановлюсь на ключевом фрагменте языка ML, только лямбда-исчисление и полиморфизм letследуют за Хиндли-Милнером . Полный язык OCaml имеет дополнительные функции, такие как полиморфизм строк (который, если я правильно помню, не меняет теоретическую сложность, но при котором реальные программы имеют тенденцию иметь более крупные типы) и модульную систему (которую, если вы будете достаточно сильно выкалывать, может не быть -отключение в патологических случаях с использованием абстрактных подписей).

Наихудшая временная сложность для решения, имеет ли тип основная ML-программа, представляет собой простую экспоненту в размере программы. Классические ссылки на этот результат - [KTU90] и [M90]. Более элементарное, но менее полное лечение дано в [S95].

Максимальный размер типа типа основной ML-программы фактически вдвое меньше экспоненциального размера программы. Если средство проверки типа должно печатать тип программы, время может, следовательно, быть двукратно экспоненциальным; его можно вернуть к простой экспоненте, определив аббревиатуры для повторяющихся частей дерева. Это может соответствовать разделению частей дерева типов в реализации.

Ваш пример показывает экспоненциальный рост типа. Однако обратите внимание, что можно дать представление типа в линейном размере, используя сокращения для повторяющихся частей типа. Это может соответствовать разделению частей дерева типов в реализации. Например:

# fun d c b a -> d c b (c b (b a));;
t2 -> t2
where t2 = (t1 -> 'b -> 'c) -> t1 -> 'a -> 'd
where t1 = 'a -> 'b

Вот концептуально более простой пример: размер типа пары (x,x)в два раза больше размера типа x, поэтому, если вы составите pairфункцию раз, вы получите тип размера .NΘ(2N)

# let pair x f = f x x;;
# let pairN x = pair (pair (pair … (pair x)…));;
'a -> tN
where tN = (tN-1 -> tN-1 -> 'bN) -> 'bN
…
where t2 = (t1 -> t1 -> 'b2) -> 'b2
where t1 = ('a -> 'a -> 'b1) -> 'b1

Вводя вложенные полиморфные letопределения, размер типа снова увеличивается экспоненциально; на этот раз никакое количество обмена не сможет сбить экспоненциальный рост.

# let pair x f = f x x;;
# let f1 x = pair x in
  let f2 x = f1 (f1 x) in
  let f3 x = f2 (f2 x) in
  fun z -> f3 (fun x -> x) z;;

Ссылки

[KTU90] Kfoury, J .; Tiuryn; Urzyczyn, P. (1990). Msgstr "Типизация ML завершена dexptime". Конспект лекций в области компьютерных наук. CAAP '90 431: 206-220. [ Springer ] [ Google ]

[M90] Mairson, Harry G. (1990). «Решение о типизации ML завершено в течение детерминированного экспоненциального времени». Материалы 17-го симпозиума ACM SIGPLAN-SIGACT по принципам языков программирования. POPL '90 (ACM): 382–401. [ ACM ]

[P04] Бенджамин С. Пирс. Продвинутые темы по типам и языкам программирования. MIT Press, 2004. [ Амазонка ]

[PR04] Франсуа Поттье и Дидье Реми. «Сущность ML Type Inference». Глава 10 в [P04]. [ pdf ]

[S95] Майкл И. Шварцбах. Полиморфный вывод типа. БРИКС ЛС-95-3, июнь 1995 года. Ps

Жиль "ТАК - перестань быть злым"
источник
так в принципе, «композиционная» природа выражений типов в сочетании с выводом типов является корнем проблемы?
Didierc
1
@didierc Я не понимаю твой комментарий. Многие вещи композиционные. В некотором смысле, фундаментальная причина заключается в том, что из базовых операций дублирования объекта (ограничение, что два типа одинаковы) и спаривания ( ->оператор) вы можете сделать экспоненциальный рост (дерево Фибоначчи).
Жиль "ТАК - перестань быть злым"
Да, я думаю, это то, что я имел в виду: алгебра типов по определению является композиционной (вы использовали термины «составить парную функцию» в своем ответе, это, вероятно, где я выбрал слово), в том смысле, что выражения типа строятся из меньшие выражения и операторы, и каждая новая композиция выражений масштабирует размер выражения как минимум в 2 раза (при более сложных полиморфных типах - триадных или более, коэффициент больше).
Didierc