직관 론적 유형 이론과 동등한 조합 논리는 무엇입니까?


87

나는 최근에 Haskell과 Agda (종속 형 함수형 프로그래밍 언어)를 특징으로하는 대학 과정을 마쳤고, 이것들의 람다 미적분을 조합 논리로 대체 할 수 있는지 궁금했습니다. Haskell을 사용하면 S 및 K 결합자를 사용하여 가능해 보이므로 포인트가 없습니다. Agda에 해당하는 것이 무엇인지 궁금합니다. 즉, 변수를 사용하지 않고 Agda와 동등한 종속 유형의 함수 프로그래밍 언어를 만들 수 있습니까?

또한 정량화를 결합 자로 대체 할 수 있습니까? 이것이 우연인지 모르겠지만 보편적 인 정량화는 예를 들어 형식 서명을 람다 식처럼 보이게 만듭니다. 의미를 변경하지 않고 형식 서명에서 범용 수량화를 제거하는 방법이 있습니까? 예 :

forall a : Int -> a < 0 -> a + a < a

forall을 사용하지 않고 같은 것을 표현할 수 있습니까?


21
K (쉬움)와 S (보통 털이 많음)에 대해 가능한 가장 의존적 인 유형을 파악하는 것으로 시작합니다. Set과 Pi에 대한 상수를 넣은 다음 기본 (일관되지 않은) Set : Set 시스템을 재구성하는 것이 흥미로울 것입니다. 더 생각하고 싶지만 비행기를 타야합니다.
pigworker

답변:


52

그래서 조금 더 생각하고 진전을 이루었습니다. Martin-Löf의 유쾌하고 단순한 (그러나 일관성이없는) Set : Set시스템을 조합 스타일 로 인코딩하는 첫 번째 찌르기 입니다. 끝내기에 좋은 방법은 아니지만 시작하기 가장 쉬운 곳입니다. 이 유형 이론의 구문은 유형 주석, Pi 유형 및 유니버스 세트가있는 람다 미적분입니다.

목표 유형 이론

완전성을 위해 규칙을 제시하겠습니다. 컨텍스트 유효성은 Sets에 서식하는 새로운 변수를 인접하여 비어있는 상태에서 컨텍스트를 구축 할 수 있다고 말합니다 .

                     G |- valid   G |- S : Set
--------------     ----------------------------- x fresh for G
  . |- valid         G, x:S |- valid

이제 우리는 주어진 문맥에서 용어에 대한 유형을 합성하는 방법과 포함 된 용어의 계산 동작까지 어떤 유형을 변경하는 방법을 말할 수 있습니다.

  G |- valid             G |- S : Set   G |- T : Pi S \ x:S -> Set
------------------     ---------------------------------------------
  G |- Set : Set         G |- Pi S T : Set

  G |- S : Set   G, x:S |- t : T x         G |- f : Pi S T   G |- s : S
------------------------------------     --------------------------------
  G |- \ x:S -> t : Pi S T                 G |- f s : T s

  G |- valid                  G |- s : S   G |- T : Set
-------------- x:S in G     ----------------------------- S ={beta} T
  G |- x : S                  G |- s : T

원본에서 약간의 변형으로 람다를 유일한 바인딩 연산자로 만들었으므로 Pi의 두 번째 인수는 반환 유형이 입력에 의존하는 방식을 계산하는 함수 여야합니다. 관례에 따라 (예를 들어 Agda에서는하지만 슬프게도 Haskell에서는 아님) 람다의 범위가 가능한 한 오른쪽으로 확장되므로, 고차 연산자의 마지막 인수 일 때 추상화를 괄호로 묶지 않은 채로 둘 수 있습니다. Pi와 함께. 귀하의 Agda 유형 (x : S) -> TPi S \ x:S -> T.

( Digression . 추상화 유형 을 합성 할 수 있으려면 람다에 대한 유형 주석이 필요합니다 . 모드 작업 으로 유형 검사 로 전환하는 경우 에도 (\ x -> t) s방법이 없으므로 베타 redex와 같은 유형을 검사 하려면 주석이 필요합니다. 전체에서 부품의 유형을 추측하기 위해 현대 디자이너에게 유형을 확인하고 바로 구문에서 베타 redexes를 제외하도록 조언합니다.)

( Digression .이 시스템은 Set:Set다양한 "거짓말 역설"의 인코딩을 허용하기 때문에 일관성이 없습니다 . Martin-Löf가이 이론을 제안했을 때 Girard는 그에게 일관성없는 시스템 U로 인코딩을 보냈습니다. Hurkens로 인한 후속 역설은 다음과 같습니다. 우리가 알고있는 가장 유독 한 구조.)

조합기 구문 및 정규화

어쨌든 두 개의 추가 기호, Pi 및 Set이 있으므로 S, K 및 두 개의 추가 기호를 사용하여 조합 번역을 관리 할 수 ​​있습니다. 저는 우주를 위해 U를 선택하고 제품을 위해 P를 선택했습니다.

이제 유형이 지정되지 않은 조합 구문 (자유 변수 포함)을 정의 할 수 있습니다.

data SKUP = S | K | U | P deriving (Show, Eq)

data Unty a
  = C SKUP
  | Unty a :. Unty a
  | V a
  deriving (Functor, Eq)
infixl 4 :.

a이 구문 에 유형 으로 표현되는 자유 변수를 포함하는 방법을 포함했습니다 . 내 입장에서 반사되는 것 외에도 (이름에 걸 맞는 모든 구문은 return변수 를 포함하고 >>=대체를 수행 하는 무료 모나드 임) 조합 형식에 바인딩하여 용어를 변환하는 과정에서 중간 단계를 나타내는 것이 편리 할 것입니다.

정규화는 다음과 같습니다.

norm :: Unty a -> Unty a
norm (f :. a)  = norm f $. a
norm c         = c

($.) :: Unty a -> Unty a -> Unty a        -- requires first arg in normal form
C S :. f :. a $. g  = f $. g $. (a :. g)  -- S f a g = f g (a g)   share environment
C K :. a $. g       = a                   -- K a g = a             drop environment
n $. g              = n :. norm g         -- guarantees output in normal form
infixl 4 $.

(독자를위한 연습은 정확히 정상적인 형태에 대한 유형을 정의하고 이러한 작업의 유형을 선명하게하는 것입니다.)

유형 이론 표현

이제 유형 이론에 대한 구문을 정의 할 수 있습니다.

data Tm a
  = Var a
  | Lam (Tm a) (Tm (Su a))    -- Lam is the only place where binding happens
  | Tm a :$ Tm a
  | Pi (Tm a) (Tm a)          -- the second arg of Pi is a function computing a Set
  | Set
  deriving (Show, Functor)
infixl 4 :$

data Ze
magic :: Ze -> a
magic x = x `seq` error "Tragic!"

data Su a = Ze | Su a deriving (Show, Functor, Eq)

나는 Bellegarde and Hook 방식으로 de Bruijn 인덱스 표현을 사용합니다 (Bird와 Paterson에 의해 대중화 됨). 유형 Su a에는보다 하나 이상의 요소가 있으며, 새로 바인딩 된 변수로 이전 자유 변수의 이동 된 표현 인 a바인더 아래의 자유 변수 유형으로 사용합니다 .ZeSu xx

용어를 결합 자로 번역

이 작업이 완료되면 대괄호 추상화를 기반으로 일반적인 번역을 얻습니다 .

tm :: Tm a -> Unty a
tm (Var a)    = V a
tm (Lam _ b)  = bra (tm b)
tm (f :$ a)   = tm f :. tm a
tm (Pi a b)   = C P :. tm a :. tm b
tm Set        = C U

bra :: Unty (Su a) -> Unty a               -- binds a variable, building a function
bra (V Ze)      = C S :. C K :. C K        -- the variable itself yields the identity
bra (V (Su x))  = C K :. V x               -- free variables become constants
bra (C c)       = C K :. C c               -- combinators become constant
bra (f :. a)    = C S :. bra f :. bra a    -- S is exactly lifted application

조합기 입력

번역은 우리가 결합자를 사용하는 방법을 보여 주므로 그 유형이 무엇인지에 대한 단서를 제공합니다. U그리고 P단지 설정된 생성자이므로 번역되지 않은 유형을 작성하고 Pi에 대해 "Agda 표기법"을 허용하면

U : Set
P : (A : Set) -> (B : (a : A) -> Set) -> Set

K연결자 일부 유형의 값을 올리 데 사용되는 A일부 다른 타입에 대해 일정한 기능 G.

  G : Set   A : Set
-------------------------------
  K : (a : A) -> (g : G) -> A

S콤비는 모든 부품이 의존 할 수있는시 유형을 통해 리프트 응용 프로그램에 사용됩니다.

  G : Set
  A : (g : G) -> Set
  B : (g : G) -> (a : A g) -> Set
----------------------------------------------------
  S : (f : (g : G) ->    (a : A g) -> B g a   ) ->
      (a : (g : G) ->    A g                  ) ->
           (g : G) ->    B g (a g)

유형을 살펴보면 유형 이론 S상황에 맞는 응용 규칙을 정확하게 설명하는 것을 알 수 있으므로 응용 프로그램 구성을 반영하는 데 적합합니다. 그게 직업입니다!

그런 다음 폐쇄 된 항목에만 적용됩니다.

  f : Pi A B
  a : A
--------------
  f a : B a

하지만 걸림돌이 있습니다. 나는 결합 유형 이론이 아닌 일반 유형 이론에서 결합 자의 유형을 작성했습니다. 다행히 번역을 할 기계가 있습니다.

조합형 시스템

---------
  U : U

---------------------------------------------------------
  P : PU(S(S(KP)(S(S(KP)(SKK))(S(KK)(KU))))(S(KK)(KU)))

  G : U
  A : U
-----------------------------------------
  K : P[A](S(S(KP)(K[G]))(S(KK)(K[A])))

  G : U
  A : P[G](KU)
  B : P[G](S(S(KP)(S(K[A])(SKK)))(S(KK)(KU)))
--------------------------------------------------------------------------------------
  S : P(P[G](S(S(KP)(S(K[A])(SKK)))(S(S(KS)(S(S(KS)(S(KK)(K[B])))(S(KK)(SKK))))
      (S(S(KS)(KK))(KK)))))(S(S(KP)(S(S(KP)(K[G]))(S(S(KS)(S(KK)(K[A])))
      (S(S(KS)(KK))(KK)))))(S(S(KS)(S(S(KS)(S(KK)(KP)))(S(KK)(K[G]))))
      (S(S(KS)(S(S(KS)(S(KK)(KS)))(S(S(KS)(S(S(KS)(S(KK)(KS)))
      (S(S(KS)(S(KK)(KK)))(S(KK)(K[B])))))(S(S(KS)(S(S(KS)(S(KK)(KS)))(S(KK)(KK))))
      (S(KK)(KK))))))(S(S(KS)(S(S(KS)(S(KK)(KS)))(S(S(KS)(S(KK)(KK)))
      (S(S(KS)(KK))(KK)))))(S(S(KS)(S(S(KS)(S(KK)(KS)))(S(KK)(KK))))(S(KK)(KK)))))))

  M : A   B : U
----------------- A ={norm} B
  M : B

그래서 여러분은 읽을 수없는 모든 영광 속에 그것을 가지고 있습니다 : Set:Set!

여전히 약간의 문제가 있습니다. 시스템의 구문은 당신에게 추측 할 수있는 방법을 제공하지 않습니다 G, A그리고 B매개 변수 S와 유사위한 K단지 용어에서. 이에 따라 우리는 알고리즘 적으로 타이핑 파생을 검증 할 수 있지만 원래 시스템에서 할 수있는 것처럼 결합 자 용어를 타입 체크 할 수는 없습니다. 작동 할 수있는 것은 S 및 K 사용에 대한 유형 주석을 포함하도록 유형 검사기에 입력을 요구하여 효과적으로 파생을 기록하는 것입니다. 하지만 그것은 또 다른 웜 캔입니다 ...

시작하기에 충분히 열성적 이었다면이 곳은 멈출 수있는 좋은 장소입니다. 나머지는 "비하인드 스토리"입니다.

결합기 유형 생성

나는 관련 유형 이론 용어에서 대괄호 추상화 번역을 사용하여 이러한 조합 유형을 생성했습니다. 내가 어떻게했는지 보여주고이 게시물이 무의미하지 않게 만들기 위해 내 장비를 제공하겠습니다.

다음과 같이 매개 변수에 대해 완전히 추상화 된 결합기 유형을 작성할 수 있습니다. 필자 pil는 Pi와 lambda를 결합하여 도메인 유형을 반복하지 않는 편리한 함수를 사용하고, Haskell의 함수 공간을 사용하여 변수를 바인딩 할 수 있습니다. 아마도 다음을 거의 읽을 수있을 것입니다!

pTy :: Tm a
pTy = fmap magic $
  pil Set $ \ _A -> pil (pil _A $ \ _ -> Set) $ \ _B -> Set

kTy :: Tm a
kTy = fmap magic $
  pil Set $ \ _G -> pil Set $ \ _A -> pil _A $ \ a -> pil _G $ \ g -> _A

sTy :: Tm a
sTy = fmap magic $
  pil Set $ \ _G ->
  pil (pil _G $ \ g -> Set) $ \ _A ->
  pil (pil _G $ \ g -> pil (_A :$ g) $ \ _ -> Set) $ \ _B ->
  pil (pil _G $ \ g -> pil (_A :$ g) $ \ a -> _B :$ g :$ a) $ \ f ->
  pil (pil _G $ \ g -> _A :$ g) $ \ a ->
  pil _G $ \ g -> _B :$ g :$ (a :$ g)

이러한 정의를 통해 관련 공개 하위 용어를 추출 하여 번역을 실행했습니다.

Bruijn 인코딩 툴킷

빌드하는 방법은 다음과 같습니다 pil. 첫째, Fin변수에 사용되는 ite 세트 의 클래스를 정의 합니다. 이러한 모든 집합에는 위 집합에 대한 생성자 보존 emb테두리와 새 top요소가 있으며이를 구분할 수 있습니다. embd함수는 값이의 이미지에 있는지 여부를 알려줍니다 emb.

class Fin x where
  top :: Su x
  emb :: x -> Su x
  embd :: Su x -> Maybe x

우리가 할 수있는, 물론, 인스턴스화 Fin에 대한 ZeSuc

instance Fin Ze where
  top = Ze              -- Ze is the only, so the highest
  emb = magic
  embd _ = Nothing      -- there was nothing to embed

instance Fin x => Fin (Su x) where
  top = Su top          -- the highest is one higher
  emb Ze     = Ze            -- emb preserves Ze
  emb (Su x) = Su (emb x)    -- and Su
  embd Ze      = Just Ze           -- Ze is definitely embedded
  embd (Su x)  = fmap Su (embd x)  -- otherwise, wait and see

이제 약화 작업으로 작 거나 같음을 정의 할 수 있습니다 .

class (Fin x, Fin y) => Le x y where
  wk :: x -> y

wk기능 요소 삽입한다 x은 AS 최대 의 요소 y에 추가 것들이되도록, y작은, 따라서 더 로컬 바인딩 브루 인덱스 조건 데있다.

instance Fin y => Le Ze y where
  wk = magic    -- nothing to embed

instance Le x y => Le (Su x) (Su y) where
  wk x = case embd x of
    Nothing  -> top          -- top maps to top
    Just y   -> emb (wk y)   -- embedded gets weakened and embedded

그리고 일단 분류를 마치면, 나머지는 랭크 n skullduggery가 처리합니다.

lam :: forall x. Tm x -> ((forall y. Le (Su x) y => Tm y) -> Tm (Su x)) -> Tm x
lam s f = Lam s (f (Var (wk (Ze :: Su x))))
pil :: forall x. Tm x -> ((forall y . Le (Su x) y => Tm y) -> Tm (Su x)) -> Tm x
pil s f = Pi s (lam s f)

고차 함수는 변수를 나타내는 용어를 제공 할뿐만 아니라 변수가 표시되는 모든 범위에서 변수의 올바른 표현이 되는 오버로드 된 것을 제공합니다 . 즉, 유형별로 다른 스코프를 구별하는 문제가 발생한다는 사실 은 하스켈 유형 검사기가 de Bruijn 표현으로의 변환에 필요한 이동을 계산하기에 충분한 정보를 제공합니다. 개를 키우고 짖는 이유는 무엇입니까?


이것은 매우 어리석은 일이지만 F콤비 네이터 를 추가하면이 그림이 어떻게 바뀌 나요? F다르게 첫 번째 인자에 따라 행위 : 경우 A원자이고, M그리고 N이용하며 PQ그 다음에, 복합체이다 FAMN -> M하고 F(PQ)MN -> NPQ. 이것은 SK(I)미적분 으로 표현할 수 없지만로 표현할 K수 있습니다 FF. 이것으로 포인트 프리 MLTT를 연장 할 수 있습니까?
kram1032

이 대괄호 추상화 절차에 문제가 있다고 확신합니다. 특히 "결합자가 상수가되는"부분은 λx.c를 결합 자 c ∈ {S, K, U, P}에 대해 Kc로 변환합니다. 문제는 이러한 결합자가 다형성이고 x에 의존하는 유형에서 사용될 수 있다는 것입니다. 이러한 유형은이 번역으로 보존 될 수 없습니다. 구체적인 예로, λ (A : Set) → λ (a : A) → a유형 이라는 용어 (A : Set) → (a : A) → A는로 번역되며 S(S(KS)(KK))(KK)두 번째 인수의 유형이 첫 번째 인수에 종속되는 유형에서는 사용할 수 없습니다.
Anders Kaseorg

8

"Bracket Abstraction"은 어떤 상황에서는 종속 유형에도 작동한다고 생각합니다. 다음 문서의 섹션 5에서 몇 가지 K 및 S 유형을 찾을 수 있습니다.

터무니 없지만 의미있는 우연의 일치
종속 유형 안전 구문 및 평가
Conor McBride, University of Strathclyde, 2010

람다 식을 조합 식으로 변환하는 것은 자연 추론 증명을 Hilbert 스타일 증명으로 변환하는 것과 대략적으로 일치합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.