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>

답변:


14

이 답변에서는 Hindley-Milnerlet 다음에 람다 미적분과 다형성으로 언어의 핵심 ML 조각을 고수합니다 . 전체 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함수를 번 작성하면 크기 유형이 됩니다.Θ(2)

# 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 .; 티리 엔; Urzyczyn, P. (1990). "ML typability는 dexptime-complete입니다". 컴퓨터 과학 강의 노트. CAAP '90 431 : 206-220. [ 스프링거 ] [ Google ]

[M90] Mairson, Harry G. (1990). "결정적 지수 시간에 대한 ML 유형 결정이 완료되었습니다". 프로그래밍 언어 원칙에 관한 17 회 ACM SIGPLAN-SIGACT 심포지엄의 절차. POPL '90 (ACM) : 382–401. [ ACM ]

[P04] 벤자민시 피어스. 유형 및 프로그래밍 언어의 고급 주제. MIT Press, 2004. [ 아마존 ]

[PR04] François Pottier와 Didier Rémy. "ML 유형 추론의 본질". [P04] 10 장. [ pdf ]

[S95] Michael I. Schwartzbach. 다형성 타입 추론. BRICS LS-95-3, 1995 년 6 월. ps


기본적으로 형식 추론과 결합 된 형식 표현의 "구성 적"특성이 문제의 근본입니까?
didierc 2013

1
@didierc 나는 당신의 의견을 이해하지 못합니다. 많은 것들이 구성 적입니다. 어떤 방식으로, 근본적인 이유는 객체를 복제하는 기본 작업 (두 유형이 동일하다는 제약 조건)과 페어링 ( ->연산자)을 통해 지수 성장 (피보나치 나무)을 만들 수 있기 때문입니다.
Gilles 'SO- 악마 그만해'

그래, 나는 그것이 의미하는 것이라고 생각합니다. 대수 형은 구성에 의해 정의됩니다 (당신은 답에 "쌍 함수 구성"이라는 용어를 사용했습니다. 더 작은 표현과 연산자, 그리고 새로운 표현의 각 구성은 표현 크기를 적어도 요소 2만큼 확장합니다 (더 복잡한 다형성 유형-3가 이상이면 요인이 더 큼).
didierc
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.