Các loại phụ thuộc so với loại được mã hóa trong Giáo hội trong PTS / CoC


11

Tôi đang thử nghiệm các hệ thống loại thuần túy trong khối lambda của Barendregt, đặc biệt với hệ thống mạnh nhất, Giải tích các công trình. Hệ thống này có các loại *BOX. Chỉ để ghi lại, bên dưới tôi đang sử dụng cú pháp cụ thể của Mortecông cụ https://github.com/Gabriel439/Haskell-Morte-L Library gần với phép tính lambda cổ điển.

Tôi thấy chúng ta có thể mô phỏng các kiểu quy nạp bằng một số loại mã hóa giống như Giáo hội (hay còn gọi là đẳng cấu Boehm-Berarducci cho các kiểu dữ liệu đại số). Đối với một ví dụ đơn giản, tôi sử dụng kiểu Bool = ∀(t : *) -> t -> t -> tvới các hàm tạo True = λ(t : *) -> λ(x : t) -> λ(y : t) -> xFalse = λ(t : *) -> λ(x : t) -> λ(y : t) -> y.

Tôi thấy rằng loại hàm cấp độ hạn Bool -> Tlà đẳng cấu với các cặp loại Product T TProduct = λ(A : *) -> λ(B : *) -> ∀(t : *) -> (A -> B -> t) -> ttham số modulo cổ điển bằng phương tiện của hàm if : Bool -> λ(t : *) -> t -> t -> ttrong thực tế là nhận dạng.

Tất cả các câu hỏi dưới đây sẽ là về đại diện của các loại phụ thuộc Bool -> *.

  1. Tôi có thể chia D : Bool -> *thành cặp D TrueD False. Có cách nào hợp quy để tạo Dlại không? Tôi muốn tái tạo isomosphism Bool -> T = Product T Tbằng một dạng tương tự của hàm ifở cấp độ loại nhưng tôi không thể viết hàm này đơn giản như ban đầu ifvì chúng ta không thể truyền các loại trong các đối số như các loại.

  2. Tôi sử dụng một loại quy nạp có hai cuộn cảm để giải câu hỏi (1). Mô tả cấp độ cao (kiểu Agda) là loại sau (được sử dụng thay cho cấp độ loại if)

    data BoolDep (T : *) (F : *) : Bool -> * where
      DepTrue : T -> BoolDep T F True
      DepFalse : F -> BoolDep T F False
    

    với mã hóa sau trong PTS / CoC:

    λ(T : *) -> λ(F : *) -> λ(bool : Bool ) ->
    ∀(P : Bool -> *) ->
    ∀(DepTrue : T -> P True ) ->
    ∀(DepFalse : F -> P False ) ->
    P bool
    

    Là mã hóa của tôi ở trên là chính xác?

  3. Tôi có thể viết ra các hàm tạo BoolDepnhư mã này cho DepTrue : ∀(T : *) -> ∀(F : *) -> T -> BoolDep T F True:

    λ(T : *) ->  λ(F : *) ->  λ(arg : T ) ->
    λ(P : Bool -> *) ->
    λ(DepTrue : T -> P True ) ->
    λ(DepFalse : F -> P False ) ->
    DepTrue arg
    

nhưng tôi không thể viết ra hàm nghịch đảo (hoặc bất kỳ hàm nào theo hướng ngược lại). Có thể không? Hay tôi nên sử dụng một đại diện khác BoolDepđể tạo ra một đẳng cấu BoolDep T F True = T?


Product T TBoolTBoolT((t:)(ttt))TProductTT(t:)((TTt)t)

@Giorgio Mossa xem cstheory.stackexchange.com/questions/30923/iêu - nếu bạn có tham số (không phải trong tất cả các mô hình nhưng trong mô hình (cú pháp) ban đầu) thì bạn có cấu trúc đẳng cấu.
ZeitRaffer

Câu trả lời:


9

Bạn không thể làm điều này bằng cách sử dụng mã hóa Giáo hội truyền thống cho Bool:

#Bool = ∀(Bool : *) → ∀(True : Bool) → ∀(False : Bool) → Bool

... bởi vì bạn không thể viết một hàm (hữu ích) loại:

#Bool → *

Lý do tại sao, như bạn đã lưu ý, là bạn không thể chuyển qua *làm đối số đầu tiên #Bool, điều này có nghĩa là các đối số TrueFalsecó thể không phải là loại.

Có ít nhất ba cách bạn có thể giải quyết điều này:

  1. Sử dụng phép tính của các công trình quy nạp. Sau đó, bạn có thể khái quát loại #Boolđể:

    #Bool = ∀(n : Nat) → ∀(Bool : *ₙ) → ∀(True : Bool) → ∀(False : Bool) → Bool
    

    ... và sau đó bạn sẽ nhanh chóng nđến 1, đó có nghĩa là bạn có thể vượt qua trong *₀như là đối số thứ hai, trong đó sẽ gõ kiểm tra bởi vì:

    *₀ : *₁
    

    ... vì vậy sau đó bạn có thể sử dụng #Boolđể chọn giữa hai loại.

  2. Thêm một loại nữa:

    * : □ : △
    

    Sau đó, bạn sẽ xác định một #Bool₂loại riêng như thế này:

    #Bool₂ = ∀(Bool : □) → ∀(True : Bool) → ∀(False : Bool) → Bool
    

    Đây thực chất là một trường hợp đặc biệt của Công trình tính toán quy nạp, nhưng tạo ra mã ít sử dụng lại vì hiện tại chúng tôi phải duy trì hai định nghĩa riêng biệt #Bool, một định nghĩa cho mỗi loại mà chúng tôi muốn hỗ trợ.

  3. Mã hóa #Bool₂trực tiếp trong Tính toán công trình như:

    #Bool₂ = ∀(True : *) → ∀(False : *) → *
    

Nếu mục tiêu là sử dụng điều này trực tiếp trong phạm vi chưa sửa đổi mortethì chỉ có cách tiếp cận # 3 sẽ hoạt động.


Như tôi có thể thấy, chúng ta không thể chuyển đổi # Bool₁ -> # Bool₂, phải không?
ZeitRaffer

@ZeitRaffer Đúng vậy. Bạn không thể chuyển đổi từ #Bool₁sang#Bool₂
Gabriel Gonzalez

1
Hmm ... IIUC bạn gọi là "Tính toán của các công trình quy nạp" là một phép tính với hệ thống phân cấp vô hạn của các loại, nhưng AFAIK CIC ban đầu không có một thứ như vậy (nó chỉ thêm các loại quy nạp vào CoC). Bạn có thể nghĩ về ECC của Luo (Tính toán mở rộng của các công trình)?
Stefan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.