Залежні типи над кодованим церковним типом у PTS / CoC


11

Я експериментую з системами чистого типу в лямбда-кубі Барендрегта, конкретно з найбільш потужним, «Калькуляцією конструкцій». Ця система має різновиди *та BOX. Тільки для запису, я нижче використовую конкретний синтаксис Morteінструменту https://github.com/Gabriel439/Haskell-Morte-Library, який близький до класичного обчислення лямбда.

Я бачу, що ми можемо імітувати індуктивні типи за допомогою якогось кодовського кодування (так само ізоморфізм Боема-Берардуччі для алгебраїчних типів даних). Для простого прикладу я використовую type Bool = ∀(t : *) -> t -> t -> tз конструкторами True = λ(t : *) -> λ(x : t) -> λ(y : t) -> xта False = λ(t : *) -> λ(x : t) -> λ(y : t) -> y.

Я бачу, що тип функцій рівня терміна Bool -> Tізоморфний парам типу Product T Tз класичною Product = λ(A : *) -> λ(B : *) -> ∀(t : *) -> (A -> B -> t) -> tпараметричністю модуля за допомогою функції, if : Bool -> λ(t : *) -> t -> t -> tяка насправді є тотожною.

Усі питання нижче стосуватимуться уявлень залежних типів Bool -> *.

  1. Я можу розділитись D : Bool -> *на пару D Trueі D False. Чи є канонічний спосіб створити Dзаново? Я хочу відтворити ізомофізм Bool -> T = Product T Tаналогом функції ifна рівні типу, але я не можу записати цю функцію так просто, як оригінальну, ifтому що ми не можемо передавати види в аргументах, таких як типи.

  2. Для вирішення питання (1) я використовую індуктивний тип з двома конвекторами. Опис високого рівня (стиль Агда) є наступним типом (використовується замість рівня типу if)

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

    із наступним кодуванням в PTS / CoC:

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

    Чи правильне моє кодування вище?

  3. Я можу записати конструктори на BoolDepзразок цього коду для DepTrue : ∀(T : *) -> ∀(F : *) -> T -> BoolDep T F True:

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

але я не можу записати зворотну функцію (або будь-яку функцію у зворотному напрямку). Це можливо? Або я повинен використовувати інше представлення для BoolDepстворення ізоморфізму BoolDep T F True = T?


Товар TTБулТБулТ((т:)(ттт))ТТоварТТ(т:)((ТТт)т)

@ Giorgio Mossa див. Cstheory.stackexchange.com/questions/30923/… - якщо у вас параметричність (не у всіх моделях, а в початковій (синтаксичній)), то у вас є ізоморфізм.
ZeitRaffer

Відповіді:


9

Ви не можете зробити це, використовуючи традиційне кодування Церкви для Bool:

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

... тому що ви не можете написати (корисну) функцію типу:

#Bool → *

Як ви зазначали, причина, як ви зазначали, полягає в тому, що ви не можете передати це *як перший аргумент #Bool, а це, в свою чергу, означає, що Trueі Falseаргументи можуть бути не типовими.

Існує щонайменше три способи вирішити це:

  1. Використовуйте обчислення індуктивних конструкцій. Тоді ви можете узагальнити тип #Bool:

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

    ... і тоді ви будете nотримувати інстанцію 1, а це означає, що ви можете передати його *₀як другий аргумент, який буде перевіряти, оскільки:

    *₀ : *₁
    

    ... тож ви можете використовувати #Boolдля вибору між двома типами.

  2. Додати ще один сорт:

    * : □ : △
    

    Тоді ви б визначили окремий #Bool₂тип на зразок цього:

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

    Це, по суті, особливий випадок обчислення індуктивних конструкцій, але створює менш повторний код, оскільки тепер ми повинні підтримувати два окремі визначення #Bool, по одному для кожного виду, який ми хочемо підтримати.

  3. Кодуйте #Bool₂безпосередньо в обчисленні конструкцій як:

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

Якщо мета полягає у використанні цього безпосередньо в немодифікованому, morteтоді працюватиме лише підхід №3.


Як я бачу, ми не можемо конвертувати # Bool₁ -> # Bool₂, чи не так?
ZeitRaffer

@ZeitRaffer Правильно. Ви не можете перейти з #Bool₁до#Bool₂
Габріель Гонсалес

1
Хм ... IIUC ви називаєте "Обчислення індуктивних конструкцій" числення з нескінченною ієрархією типів, але AFAIK в оригінальному CIC такого не було (він лише додав індуктивні типи до CoC). Можливо, ви думаєте про ЕКЦ Луо (Розширене обчислення конструкцій)?
Стефан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.