엄격한 양성


10

이 참조에서 : 엄격한 양성

엄격한 양성 조건은 다음과 같은 선언을 배제합니다.

data Bad : Set where
 bad : (Bad → Bad) → Bad
         A      B       C
 -- A is in a negative position, B and C are OK

A가 왜 음수입니까? 또한 왜 B가 허용됩니까? C가 허용되는 이유를 이해합니다.


1
왜 이것이 "부정적"이라고 불리는 지 잘 모르겠지만, 그것이 일반적으로 발생하는 오류에 의해 더 잘 알려져 있습니다 A.
wvxvw

그 부분은 임의의 것을 쓸 수 있으므로 계산이 종료되지 않는다는 것을 이해합니다. 감사
Pushpa

1
나는 당신의 질문 의 본문 에서 비 종결을 언급하는 것이 좋은 것이라고 생각합니다 . 귀하의 의견에 따라 답변을 업데이트했습니다.
Anton Trunov

@wvxvw 반드시 컴파일러가 테일 재귀를 구현하는 경우 스택을 폭파하지 않고 영원히 실행될 수는 없습니다. 예를 들어 아래의 OCaml 예제는 스택을 분해하지 않습니다.
Anton Trunov

1
@AntonTrunov는 사이트 이름이 정확하기보다는 말장난에 가깝습니다.
wvxvw

답변:


17

이제 유도 데이터 유형에 대해

대수에서는 연산이 유한 한 수의 인수를 취하는 것이 일반적이며 대부분의 경우 0 (일정), 1 (단항) 또는 2 (이진) 인수가 필요합니다. 데이터 유형의 생성자에 대해 이것을 일반화하는 것이 편리합니다. c데이터 유형의 생성자가 있다고 가정합니다 T.

  • 경우 c상수 우리는 함수로 생각할 수 있습니다 unit -> T동등하거나 (empty -> T) -> T,
  • 경우 c단항 우리가 함수로 생각할 수있는 T -> T, 또는 동등하게 (unit -> T) -> T,
  • 경우 c우리가 함수로 생각할 수 이진 T -> T -> T, 또는 동등 T * T -> T또는 동등 (bool -> T) -> T,
  • 우리는 생성자 원한다면 c일곱 인수를, 우리는 함수로 볼 수있는 일곱 개 요소와 일부 이전에 정의 된 유형입니다.(seven -> T) -> Tseven
  • 또한 c무수히 많은 인수를 취하는 생성자 를 가질 수 있습니다 (nat -> T) -> T.

이 예제는 일반적인 형태의 생성자가

c : (A -> T) -> T

여기서 우리 Aarity 를 호출 하고 의 요소를 생성하기 위해 type의 많은 인수 를 취하는 생성자로 c생각 합니다.cATT

arities 정의해야합니다 여기에 매우 중요한 일입니다 전에 우리는 정의 T, 그렇지 않으면 우리는 생성자가 일을 할 생각 무엇을 말할 수는. 누군가 생성자를 가지려고하면

broken: (T -> T) -> T

그렇다면 "얼마나 많은 논쟁이 필요 broken합니까?" 좋은 대답이 없습니다. " T다수의 인수를 받는다 "는 대답을 시도 할 수도 있지만 T아직 정의되지 않았기 때문에 그렇지 않습니다. 우리는 멋진 고정 소수점 이론을 사용하여 유형 T과 주입 함수 를 찾아서 입체에서 벗어나려고 노력할 수도 (T -> T) -> T있지만 성공할 수도 있지만 유도 원칙을 깨뜨릴 수도 있습니다 T. 따라서 그러한 것을 시도하는 것은 나쁜 생각입니다.

λVλVcB

c : B * (A -> T) -> T

실제로, 많은 생성자는이 방법으로 다시 작성할 수 있습니다, 전부는 아니지만, 우리는 즉 우리가 허용해야, 한 단계를 필요로 A하는 의존B:

c : (∑ (x : B), A x -> T) -> T

이것은 유도 형 생성자의 최종 형태입니다. 또한 W- 타입이 바로 그것입니다. 형식은 매우 일반적이므로 단일 생성자 만 있으면됩니다 c! 실제로 두 가지가 있다면

d' : (∑ (x : B'), A' x -> T) -> T
d'' : (∑ (x : B''), A'' x -> T) -> T

우리는 그것들을 하나로 결합 할 수 있습니다

d : (∑ (x : B), A x -> T) -> T

어디

B := B' + B''
A(inl x) := A' x
A(inr x) := A'' x

그건 그렇고, 우리가 일반적인 형태를 카레하면 우리는 그것이

c : ∏ (x : B), ((A x -> T) -> T)

사람들이 실제로 증거 조수에 적는 것에 더 가깝습니다. 증거 어시스턴트를 사용하면 생성자를 편리한 방식으로 작성할 수 있지만 위의 일반적인 형식 (운동)과 동일합니다.


1
점심을 먹은 후에 Andrej에게 다시 한번 감사드립니다. 이것은 내가 소화하기 가장 어려운 일이 될 것입니다. 건배.
Pushpa

9

첫 번째 항목은 Bad함수 인수를 나타 내기 때문에 '음수'라고합니다. 즉, 함수 화살표의 왼쪽에 있습니다 ( Philip Wadler가 무료재귀 유형 참조 ). '부정적 위치'라는 용어의 원점은 역 분산 의 개념에서 비롯된 것 같습니다 ( '콘트라'는 반대를 의미합니다).

유형을 사용하여 종료되지 않는 프로그램을 작성할 수 있기 때문에 유형이 음의 위치에 정의되어서는 안됩니다. 즉, 강력한 정규화가 존재하지 않습니다 (아래에 자세히 설명되어 있음). 그건 그렇고, 이것이 '엄격 양성'이라는 규칙의 이름에 대한 이유입니다. 우리는 부정적인 입장을 허용하지 않습니다.

우리는 Bad종료가 발생 하지 않기 때문에 두 번째 발생을 허용하고 재귀 데이터 유형의 Bad어느 시점에서 ( 생성자의 마지막 화살표 앞에 ) 정의되는 유형 ( )을 사용하려고합니다 .

다음 정의가 엄격한 양성 규칙을 위반 하지 않는다는 것을 이해하는 것이 중요합니다 .

data Good : Set where
  good : Good → Good → Good

이 규칙은 생성자 인수 ( Good이 경우 모두)에만 적용되며 생성자 자체에는 적용되지 않습니다 (Adam Chlipala의 " 종속적 유형을 사용한 인증 된 프로그래밍 "참조).

엄격한 양성을 위반하는 또 다른 예 :

data Strange : Set where
  strange : ((Bool → Strange) → (ℕ → Strange)) → Strange
                       ^^     ^
            this Strange is   ...this arrow
            to the left of... 

부정적인 위치에 대한 이 답변 을 확인할 수도 있습니다 .


비 종료에 대한 추가 정보 ... 참조한 페이지에 설명이 포함되어 있습니다 (Haskell의 예와 함께).

엄격하지 않은 선언은이를 사용하여 종료되지 않는 함수를 작성할 수 있으므로 거부됩니다. 위에서 잘못된 데이터 유형을 사용하여 루핑 정의를 작성하는 방법을 보려면 BadInHaskell을 참조하십시오 .

다음은 Ocaml의 유사한 예제로, 재귀를 직접 사용하여 (!)없이 재귀 동작을 구현하는 방법을 보여줍니다 .

type boxed_fun =
  | Box of (boxed_fun -> boxed_fun)

(* (!) in Ocaml the 'let' construct does not permit recursion;
   one have to use the 'let rec' construct to bring 
   the name of the function under definition into scope
*)
let nonTerminating (bf:boxed_fun) : boxed_fun =
  match bf with
    Box f -> f bf

let loop = nonTerminating (Box nonTerminating)

nonTerminating함수는 인수에서 함수를 "풀고"원래 인수에이를 적용합니다. 여기서 중요한 것은 대부분의 유형 시스템이 함수를 자신에게 전달하는 것을 허용하지 않으므로 f f유형 f검사기를 충족시킬 유형이 없기 때문에 유형 검사 와 같은 용어 는 유형 검사를하지 않습니다 . 유형 시스템이 도입 된 이유 중 하나는 자체 응용 프로그램을 비활성화하는 것입니다 ( 여기 참조 ).

위에서 소개 한 것과 같은 랩핑 데이터 유형을 사용하여 불일치로가는 길에서이로드 블록을 우회 할 수 있습니다.

비 종료 계산이 논리 시스템에 불일치를 초래한다고 덧붙이고 싶습니다. Agda 및 Coq의 경우 False유도 데이터 유형에 생성자가 없으므로 False 유형의 증명 용어를 작성할 수 없습니다. 그러나 경우 비 종료 계산이 허용 된 하나의 예를 들어 이런 식으로 (COQ)에 그것을 할 수 있습니다 :

Fixpoint loop (n : nat) : False = loop n

그런 다음 loop 0typecheck giving loop 0 : False을 입력하므로 Curry-Howard 서신에서 이는 잘못된 제안을 증명했음을 의미합니다.

Upshot : 귀납적 정의에 대한 엄격한 양성 규칙은 논리에 비참한 비 종료 계산을 방지합니다.


이제 혼란 스러워요. 특수 데이터 양호 : 양호 위치 : 양호 → 양호 →. 우리는 이해하고 한 시간 후에 다시 시도합니다 /
Pushpa

규칙은 생성자 자체에는 적용되지 않으며 인수에만 적용됩니다. 즉 생성자 정의의 최상위 레벨에있는 화살표는 중요하지 않습니다. 또한 다른 (간접적) 위반 예제를 추가했습니다.
Anton Trunov
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.