Arend - bahasa tipe dependen berbasis HoTT (bagian 2)

Pada bagian pertama artikel tentang bahasa Arend, kami memeriksa jenis induktif yang paling sederhana, fungsi rekursif, kelas dan set.

2. Menyortir Daftar di Arend


2.1 Daftar Pesanan di Arend


Kami mendefinisikan jenis daftar yang dipesan sebagai pasangan yang terdiri dari daftar dan bukti pemesanannya. Seperti yang telah kami katakan, dalam Arend, pasangan tergantung didefinisikan menggunakan kata kunci \Sigma . Kami memberikan definisi dari jenis yang Sorted melalui perbandingan dengan sampel, terinspirasi oleh definisi dari artikel yang telah disebutkan tentang daftar dipesan.

 \func SortedList (O : LinearOrder.Dec) => \Sigma (l : List O) (Sorted l) \data Sorted {A : LinearOrder.Dec} (xs : List A) \elim xs | nil => nilSorted | :-: x nil => singletonSorted | :-: x1 (:-: x2 xs) => consSorted ((x1 = x2) || (x1 < x2)) (Sorted (x2 :-: xs)) 

Catatan: Arend dapat secara otomatis menyimpulkan bahwa tipe Sorted terkandung dalam \Prop universe. Ini terjadi karena ketiga pola dalam definisi Sorted adalah saling eksklusif, dan konstruktor yang consSorted memiliki dua parameter, yang keduanya milik \Prop .
Mari kita buktikan beberapa properti yang jelas dari predikat Sorted , katakan bahwa ekor dari daftar yang diurutkan itu sendiri adalah daftar yang dipesan (properti ini akan berguna bagi kita di masa depan).

 \func tail-sorted {O : LinearOrder.Dec} (x : O) (xs : List O) (A : Sorted (x :-: xs)) : Sorted xs \elim xs, A | nil, _ => nilSorted | :-: _ _, consSorted _ xs-sorted => xs-sorted 

Dalam tail-sorted kami menggunakan pencocokan pola pada daftar xs dan predikat Sorted pada saat yang sama, di samping itu, kami menggunakan karakter lewati “_”, yang dapat diganti dengan variabel yang tidak digunakan.

Orang mungkin bertanya apakah mungkin dalam Arend untuk membuktikan properti dari daftar yang dipesan, yang disebutkan dalam bagian 1.3 sebagai contoh dari fakta yang tidak dapat dibuktikan di Agda tanpa anotasi immaterialitas. Ingatlah bahwa properti ini mengklaim bahwa untuk membuktikan kesetaraan dari daftar yang dipesan yang ditentukan melalui pasangan terikat, cukup untuk memeriksa kesetaraan komponen pertama dari pasangan tersebut.

Dikatakan bahwa dalam Arend properti ini mudah diperoleh sebagai konsekuensi dari konstruksi inProp disebutkan di atas dan properti ekstensionalitas untuk pasangan SigmaExt bergantung.

 \func sorted-equality {A : LinearOrder.Dec} (l1 l2 : SortedList A) (P : l1.1 = l2.1) : l1 = l2 => SigmaPropExt Sorted l1 l2 P 

Properti SigmaPropExt terbukti dalam modul Paths dari perpustakaan standar, dan banyak fakta lain dari bab kedua buku HoTT , termasuk properti ekstensionalitas fungsional , juga terbukti di sana.

Operator .n digunakan di Arend untuk mengakses proyektor tipe sigma dengan angka n (dalam kasus kami, tipe sigma adalah SortedList A , dan ekspresi l1.1 berarti komponen pertama dari tipe ini adalah ekspresi dari tipe List A ).

2.2 Implementasi properti "menjadi permutasi"


Sekarang mari kita coba menerapkan fungsi pengurutan daftar di Arend. Secara alami, kami ingin memiliki bukan implementasi sederhana dari algoritma pengurutan, tetapi implementasi bersama dengan bukti dari beberapa properti.

Jelas, algoritma ini harus memiliki setidaknya 2 properti:
1. Hasil algoritma harus berupa daftar yang diurutkan.
2. Daftar yang dihasilkan harus permutasi dari daftar asli.

Pertama, mari kita coba menerapkan properti "menjadi permutasi" dari daftar di Arend. Untuk melakukan ini, kami menyesuaikan definisi yang diambil dari sini untuk Arend.

 \truncated \data InsertSpec {A : \Set} (xs : List A) (a : A) (ys : List A) : \Prop \elim xs, ys | xs, :-: y ys => insertedHere (a = y) (xs = ys) | :-: x xs, :-: y ys => insertedThere (x = y) (InsertSpec xs a ys) \truncated \data Perm {A : \Set} (xs ys : List A) : \Prop | permInsert (xs' ys' : List A) (a : A) (Perm xs' ys') (InsertSpec xs' a xs) (InsertSpec ys' a ys) | permTrivial (xs = ys) 

Predikat InsertSpec diperkenalkan oleh kami memiliki arti intuisi berikut: InsertSpec xs a ys persis berarti bahwa daftar ys adalah hasil dari memasukkan elemen a di dalam daftar xs (di posisi mana pun). Dengan demikian, InsertSpec dapat diambil sebagai spesifikasi dari fungsi insert.

Jelas bahwa tipe data Perm benar-benar mendefinisikan hubungan "menjadi permutasi": konstruktor permInsert tepat bahwa xs dan ys dapat diijinkan bersama jika xs dan ys diperoleh dengan memasukkan elemen yang sama ke dalam beberapa daftar xs' dan ys' Panjang lebih pendek, yang sudah permutasi satu sama lain.

Untuk definisi kami tentang properti "menjadi permutasi", mudah untuk memverifikasi properti simetri.

 \func Perm-symmetric {A : \Set} {xs ys : List A} (P : Perm xs ys) : Perm ys xs \elim P | permTrivial xs=ys => permTrivial (inv xs=ys) | permInsert perm-xs'-ys' xs-spec ys-spec => permInsert (Perm-symmetric perm-xs'-ys') ys-spec xs-spec 

Properti transitivitas juga puas untuk Perm , tetapi verifikasi jauh lebih rumit. Karena properti ini tidak memainkan peran apa pun dalam penerapan algoritme penyortiran kami, kami serahkan pada pembaca sebagai latihan.

 \func Perm-transitive {A : \Set} (xs ys zs : List A) (P1 : Perm xs ys) (P2 : Perm ys zs) : Perm xs zs => {?} 

2.3 Perubahan tingkat homotopy jika dibandingkan dengan sampel


Sekarang mari kita coba mengimplementasikan fungsi yang memasukkan elemen ke dalam daftar yang diurutkan sehingga daftar yang dihasilkan tetap terurut. Mari kita mulai dengan implementasi naif berikut.

 \func insert {O : LinearOrder.Dec} (xs : List O) (y : O) : List O \elim xs | nil => y :-: nil | :-: x xs' => \case LinearOrder.trichotomy xy \with {  | byLeft x=y => x :-: insert xs' y  | byRight (byLeft x<y) => x :-: insert xs' y  | byRight (byRight y<x) => y :-: x :-: xs' } 

Konstruk \case memungkinkan pencocokan dengan sampel ekspresi arbitrer ( \elim dapat hanya digunakan pada level tertinggi dari definisi fungsi dan hanya untuk parameternya). Jika Anda meminta Arend untuk memeriksa jenis insert , pesan kesalahan berikut akan ditampilkan.

 [ERROR] Data type '||' is truncated to the universe \Prop  which does not fit in the universe of the eliminator type: List OE In: | byLeft x-leq-y => x :-: insert xs' y While processing: insert 

Masalahnya adalah bahwa di kelas LinearOrder.Dec definisi trichotomy diberikan menggunakan operator || , yang, pada gilirannya, ditentukan menggunakan pemotongan proposisional. Seperti yang telah disebutkan, untuk tipe yang dimiliki alam semesta \Prop , pencocokan dengan pola di Arend hanya diperbolehkan jika tipe ekspresi yang dihasilkan itu sendiri merupakan pernyataan (untuk fungsi di atas, hasilnya adalah tipe List OE , dan tipe ini adalah himpunan).

Apakah ada cara untuk mengatasi masalah ini? Cara termudah untuk menyelesaikan ini adalah mengubah definisi properti trikotomi. Pertimbangkan definisi trikotomi berikut, dengan menggunakan tipe yang tidak terpotong Or alih-alih || terpotong :

 \func set-trichotomy {A : StrictPoset} (xy : A) => ((x = y) `Or` (x < y)) `Or` (y < x) 

Apakah definisi ini trichotomy dalam hal apa pun dari definisi trichotomy asli melalui || ? Mengapa kita bahkan menggunakan tipe terpotong proposisi jika hanya mempersulit hidup kita dan mencegah kita menggunakan pencocokan pola?

Mari kita coba menjawab pertanyaan pertama sebagai permulaan: untuk pesanan StrictPoset ketat StrictPoset perbedaan antara trichotomy dan set-trichotomy sebenarnya tidak sama sekali. Perhatikan bahwa jenis set-trichotomy adalah pernyataan. Fakta ini mengikuti dari fakta bahwa ketiga alternatif dalam definisi trikotomi adalah saling eksklusif karena aksioma keteraturan, dan masing-masing dari ketiga jenis x = y, x < y, y < x sendiri merupakan pernyataan ( x = y adalah pernyataan, jadi seperti dalam definisi kelas BaseSet kami menuntut agar media E ditetapkan!).

 \func set-trichotomy-isProp {A : StrictPoset} (xy : A) (l1 l2 : set-trichotomy xy): l1 = l2 \elim l1, l2 | inl (inl l1), inl (inl l2) => pmap (\lam z => inl (inl z)) (Path.inProp l1 l2) | inl (inr l1), inl (inr l2) => pmap (\lam z => inl (inr z)) (Path.inProp l1 l2) | inr l1, inr l2 => pmap inr (Path.inProp l1 l2) | inl (inl l1), inl (inr l2) => absurd (lt-eq-false l1 l2) | inl (inr l1), inl (inl l2) => absurd (lt-eq-false l2 l1) | inl (inl l1), inr l2 => absurd (lt-eq-false (inv l1) l2) | inr l1, inl (inl l2) => absurd (lt-eq-false (inv l2) l1) | inl (inr l1), inr l2 => absurd (lt-lt-false l1 l2) | inr l1, inl (inr l2) => absurd (lt-lt-false l2 l1) \where {  \func lt-eq-false {A : StrictPoset} {xy : A} (l1 : x = y) (l2 : x < y) : Empty =>    A.<-irreflexive x (transport (x <) (inv l1) l2)  \func lt-lt-false {A : StrictPoset} {xy : A} (l1 : x < y) (l2 : y < x) : Empty =>   A.<-irreflexive x (A.<-transitive _ _ _ l1 l2) } 

Dalam daftar di atas, absurd adalah sebutan untuk prinsip ex falso quodlibet, yang didefinisikan dalam modul Logic . Karena tipe Empty tidak memiliki konstruktor dalam definisi (lihat bagian 1.2), tidak perlu melalui kasus dalam definisi absurd :

 \func absurd {A : \Type} (x : Empty) : A 

Karena kita sekarang tahu bahwa set-trichotomy adalah sebuah pernyataan, kita dapat memperoleh properti set-trichotomy dari properti trichotomy biasa dari pesanan yang dapat ditentukan. Untuk melakukan ini, kita dapat menggunakan konstruksi \return \level , yang memberitahu timer Arend bahwa pada titik ini, pencocokan dengan pola adalah operasi yang diizinkan (dalam hal ini, kita harus menunjukkan bukti bahwa hasil dari fungsi set-trichotomy-property adalah pernyataan).

 \func set-trichotomy-property {A : LinearOrder.Dec} (xy : A) : set-trichotomy xy => \case A.trichotomy xy \return \level (set-trichotomy xy) (set-trichotomy-isProp xy) \with {  | byLeft x=y => inl (inl x=y)  | byRight (byLeft x<y) => inl (inr x<y)  | byRight (byRight y<x) => inr (y<x) } 

Mari kita coba menjawab pertanyaan kedua, yaitu, mengapa, ketika merumuskan sifat-sifat objek matematika, lebih disukai menggunakan konstruksi yang tidak biasa, tetapi secara proposisi terpotong. Pertimbangkan untuk ini sebuah fragmen dari definisi perintah linear non-linear (definisi lengkap Lattice dan TotalOrder dapat ditemukan dalam modul LinearOrder ):

 \class TotalOrder \extends Lattice { | totality (xy : E) : x <= y || y <= x } 

Mari kita coba bayangkan sekarang bagaimana arti dari kelas TotalOrder akan berubah jika kita menulis definisi bidang totalitas melalui konstruksi yang tidak terpotong Or konstruksi.

 \class BadTotalOrder \extends Lattice { | badTotality (xy : E) : (x <= y) `Or` (y <= x) } 

Dalam hal ini, tipe (x <= y) `Or` (y <= x) tidak lagi merupakan pernyataan, karena dalam hal nilai x dan y sama y kedua alternatif dalam definisi badTotality dapat diimplementasikan, dan pilihan cabang kiri atau kanan dalam bukti badTotality benar-benar sewenang-wenang dan tetap pada kebijaksanaan pengguna - tidak ada alasan untuk memilih satu Or konstruktor ke yang lain.

Sekarang sudah jelas apa perbedaan antara TotalOrder dan BadTotalOrder . Dua set yang dipesan O1 O2 : TotalOrder selalu sama ketika dimungkinkan untuk membuktikan kesetaraan set O1.E, O2.E dan perintah O1.<, O2.< Diberikan pada mereka (ini adalah properti yang diinginkan). Di sisi lain, untuk O1 O2 : BadTotalOrder untuk membuktikan kesetaraan O1 dan O2 hanya ketika, selain semua elemen x dari E persamaan O1.badTotality xx dan O2.badTotality xx .

Dengan demikian, ternyata kelas BadTotalOrder secara intuitif perlu dipertimbangkan bukan sebagai "himpunan BadTotalOrder linear", tetapi sebagai "himpunan BadTotalOrder linier bersama dengan pilihan untuk setiap elemen x bidang E cabang E cabang kiri atau kanan Or dalam implementasi badTotality xx ".

2.4 Sortir Algoritma


Kami sekarang melanjutkan untuk menerapkan algoritma pengurutan. Mari kita coba untuk memperbaiki implementasi naif dari fungsi insert dari bagian sebelumnya menggunakan properti set-trichotomy-property terbukti (dalam hal ini, karena pengaturan kurung yang lebih sukses dalam definisi set-trichotomy , kami telah mengurangi jumlah kasus yang dipertimbangkan).

 \func insert {O : LinearOrder.Dec} (xs : List O) (y : O) : List O \elim xs | nil => y :-: nil | :-: x xs' => \case set-trichotomy-property xy \with {  | inr y<x => y :-: x :-: xs'  | inl x<=y => x :-: insert xs' y } 

Sekarang mari kita coba mengimplementasikan analog dari definisi ini untuk daftar yang diurutkan. Kami akan menggunakan konstruksi khusus \let … \in , yang memungkinkan kami untuk menambahkan variabel lokal baru ke konteksnya.

 \func insert {O : LinearOrder.Dec} (xs : SortedList O) (y : O) : SortedList O \elim xs | (nil, _) => (y :-: nil, singletonSorted) | (:-: x xs', xs-sorted) => \case set-trichotomy-property xy \with {  | inr y<x => (y :-: x :-: xs', consSorted (byRight y<x) xs-sorted)  | inl x<=y => \let (result, result-sorted) => insert (xs', tail-sorted x xs' xs-sorted) y         \in (x :-: result, {?}) 

Kami meninggalkan di bukti fragmen tidak lengkap (ditunjukkan oleh ekspresi {?} ) Di tempat Anda ingin menunjukkan bahwa daftar x :-: result dipesan. Meskipun dalam konteks terdapat bukti urutan daftar result , tetap bagi kami untuk memverifikasi bahwa x tidak melebihi nilai elemen pertama dari daftar result , yang tidak begitu mudah untuk diikuti dari tempat dalam konteks (untuk melihat semua tempat dalam target saat ini - inilah yang kami sebut cabang perhitungan sekarang - Anda perlu meminta pemeriksaan jenis dari fungsi insert ).

Ternyata insert jauh lebih mudah diimplementasikan jika kita membuktikan urutan daftar yang dihasilkan secara paralel dengan bukti spesifikasi insert . Ubah tanda tangan insert dan tulis bukti spesifikasi ini dalam kasus paling sederhana:

 \func insert {O : LinearOrder.Dec} (xs : SortedList O) (y : O) : \Sigma (ys : SortedList O) (InsertSpec xs.1 y ys.1) \elim xs | (nil, _) => ((y :-: nil, singletonSorted), insertedHere idp idp) | (:-: x xs', xs-sorted) => \case set-trichotomy-property xy \with {  | inr y<x => ((y :-: x :-: xs', consSorted (byRight y<x) xs-sorted), insertedHere idp idp)  | inl x<=y =>   \let ((result, result-sorted), result-spec) => insert (xs', tail-sorted x xs' xs-sorted) y   \in ((x :-: result, {?}), insertedThere idp result-spec) 

Untuk satu fragmen yang dibiarkan tanpa bukti, Arend akan menampilkan nilai konteks berikut:

 Expected type: Sorted (x :-: (insert (\this, tail-sorted x \this \this) \this).1.1) Context:  result-sorted : Sorted (insert (\this, tail-sorted \this \this \this) \this).1.1  xs-sorted : Sorted (x :-: xs')  x : O  x<=y : Or (x = y) (O.< xy)  O : Dec  result : List O  y : O  xs' : List O  result-spec : InsertSpec xs' y (insert (xs', tail-sorted \this xs' \this) y).1.1 

Untuk melengkapi buktinya, kita harus menggunakan kekuatan penuh dari operator \case : kita akan menggunakan pencocokan pola dengan 5 variabel berbeda, dan karena tipe-tipe dari beberapa variabel mungkin bergantung pada nilai-nilai variabel lain, kita akan menggunakan pencocokan pola dependen.

Konstruksi usus besar secara eksplisit menunjukkan bagaimana jenis beberapa variabel yang dibandingkan tergantung pada nilai-nilai variabel lain (dengan demikian, dalam jenis variabel xs-sorted, result-spec dan result-sorted dalam setiap \case bukan xs' dan result akan cocok dengan sampel yang sesuai).

Konstruk \return mengaitkan variabel yang digunakan untuk mencocokkan pola dengan jenis hasil yang diharapkan. Dengan kata lain, dalam target saat ini, dalam setiap \case klausa, sampel yang sesuai akan diganti untuk variabel result . Tanpa konstruksi ini, penggantian seperti itu tidak akan dilakukan, dan tujuan dari semua klausa \case akan bertepatan dengan target menggantikan ekspresi \case itu sendiri.

 \func insert {O : LinearOrder.Dec} (xs : SortedList O) (y : O) : \Sigma (ys : SortedList O) (InsertSpec xs.1 y ys.1) \elim xs  | (nil, _) => ((y :-: nil, singletonSorted), insertedHere idp idp)  | (:-: x xs', xs-sorted) => \case set-trichotomy-property xy \with {   | inr y<x => ((y :-: x :-: xs', consSorted (byRight y<x) xs-sorted), insertedHere idp idp)   | inl x<=y =>     \let ((result, result-sorted), result-spec) => insert (xs', tail-sorted x xs' xs-sorted) y     \in ((x :-: result,       \case result \as result, xs' \as xs', xs-sorted : Sorted (x :-: xs'), result-spec : InsertSpec xs' y result, result-sorted : Sorted result       \return Sorted (x :-: result) \with {        | nil, _, _, _, _ => singletonSorted        | :-: r rs, _, _, insertedHere y=r _, result-sorted => consSorted (transport (\lam z => (x = z) || (x < z)) y=r (Or-to-|| x<=y)) result-sorted        | :-: r rs, :-: x' _, consSorted x<=x' _, insertedThere x2=r _, result-sorted => consSorted (transport (\lam z => (x = z) || (x < z)) x2=r x<=x') result-sorted }), insertedThere idp result-spec) 

Dalam blok kode di atas, argumen kompleks pertama dari konstruktor yang consSorted dalam dua paragraf terakhir dari perbandingan pola layak mendapatkan komentar tambahan. Untuk memahami apa arti kedua ekspresi ini, kami menggantinya dengan ekspresi {?} Dan meminta timer Arend untuk menentukan target di kedua posisi.

Anda dapat melihat bahwa di sana dan di sana target saat ini adalah tipe (x = r) || O.< xr (x = r) || O.< xr . Selain itu, dalam konteks tujuan pertama, ada premis

 x<=y : Or (x = y) (O.< xy) y=r : y = r 

dan dalam konteks premis kedua

 x<=x' : (x = x') || O.< xx' x2=r : x' = r. 

Secara intuitif jelas: untuk membuktikan tujuan pertama, cukup untuk mengganti variabel r ke dalam pernyataan yang benar Or (x = y) (O.< xy) , dan kemudian beralih ke tipe terpotong proposisi || menggunakan fungsi Or-to-|| didefinisikan dalam Bagian 1.3 . Untuk membuktikan tujuan kedua, cukup gantikan (x = x') || O.< x x' (x = x') || O.< x x' bukan variabel x' variabel r .

Untuk memformalkan operasi substitusi ekspresi yang dijelaskan, fungsi transport khusus ada di perpustakaan Arend standar. Pertimbangkan tanda tangannya:

 \func transport {A : \Type} (B : A -> \Type) {aa' : A} (p : a = a') (b : B a) : B a' 

Dalam kasus kami, alih-alih variabel A kita perlu mengganti tipe OE (dapat dihilangkan secara eksplisit jika argumen transport lainnya ditentukan), dan alih-alih B ekspresi \lam (z : O) => (x = z) || (x < z) \lam (z : O) => (x = z) || (x < z) .

Implementasi algoritma penyisipan penyisipan bersama dengan spesifikasi tidak lagi menyebabkan kesulitan khusus: untuk menyortir daftar x :-: xs' , pertama-tama kita menyortir ujung daftar xs' menggunakan panggilan rekursif untuk insertSort , dan kemudian memasukkan elemen x di dalam daftar ini sambil menjaga pesanan untuk membantu akses ke fungsi insert sudah diterapkan.

 \func insertSort {O : LinearOrder.Dec} (xs : List O) : \Sigma (result : SortedList O) (Perm xs result.1) \elim xs | nil => ((nil, nilSorted), permTrivial idp) | :-: x xs' => \let | (ys, perm-xs'-ys) => insertSort xs'                      | (zs, zs-spec) => insert ys x                  \in (zs, permInsert perm-xs'-ys (insertedHere idp idp) zs-spec) 

Kami memenuhi tujuan awal dan menerapkan pengurutan daftar di Arend. Seluruh kode Arend yang diberikan dalam paragraf ini dapat diunduh dalam satu file dari sini .

Orang mungkin bertanya bagaimana kita harus mengubah implementasi dari fungsi insert jika alih- LinearOrder.Dec perintah LinearOrder.Dec ketat kita menggunakan perintah LinearOrder.Dec yang tidak ketat? Seperti yang kita ingat, dalam definisi fungsi totalitas, penggunaan operasi terpotong || cukup signifikan, yaitu definisi ini tidak setara dengan definisi di mana alih-alih || digunakan oleh Or .

Jawaban untuk pertanyaan ini adalah sebagai berikut: masih dimungkinkan untuk membuat analog insert untuk TotalOrder , namun, untuk ini kita harus membuktikan bahwa jenis fungsi insert adalah pernyataan (ini akan memungkinkan kita dalam definisi insert untuk membuat perbandingan dengan sampel sesuai dengan totality xy pernyataan).

Dengan kata lain, kita harus membuktikan bahwa hanya ada satu daftar terurut hingga kesetaraan, yang merupakan hasil dari memasukkan elemen y ke dalam daftar berurutan xs . Sangat mudah untuk melihat bahwa ini adalah fakta yang benar, tetapi bukti formalnya tidak lagi sepele. Kami meninggalkan verifikasi fakta ini sebagai latihan untuk pembaca yang tertarik.

3. Pengamatan penutup


Dalam pengantar ini, kami berkenalan dengan konstruksi utama bahasa Arend, dan juga belajar bagaimana menggunakan mekanisme kelas. Kami berhasil menerapkan algoritma paling sederhana beserta bukti spesifikasinya. Jadi, kami telah menunjukkan bahwa Arend cukup cocok untuk menyelesaikan masalah "sehari-hari", seperti, misalnya, verifikasi program.

Kami telah menyebutkan jauh dari semua fitur dan fitur Arend. Sebagai contoh, kami hampir tidak mengatakan apa pun tentang tipe dengan kondisi yang memungkinkan Anda untuk "merekatkan" berbagai konstruktor tipe dengan beberapa nilai parameter khusus untuk konstruktor ini. Misalnya, implementasi tipe integer di Arend diberikan menggunakan tipe dengan ketentuan sebagai berikut:

 \data Int | pos Nat | neg Nat \with { zero => pos zero } 

Definisi ini mengatakan bahwa bilangan bulat terdiri dari dua salinan dari tipe bilangan alami, di mana nol "positif" dan "negatif" diidentifikasi. Definisi seperti itu jauh lebih nyaman daripada definisi dari perpustakaan Coq standar, di mana "salinan negatif" dari bilangan asli harus "digeser oleh satu" sehingga salinan ini tidak berpotongan (itu jauh lebih nyaman ketika neg 1 notasi berarti angka -1, tidak -2) .

Kami tidak mengatakan apa-apa tentang algoritma untuk memperoleh tingkat predikatif dan homotopi di kelas dan instance mereka. Kami juga hampir tidak menyebutkan jenis interval I , meskipun memainkan peran kunci dalam teori jenis dengan interval, yang merupakan dasar logis dari Arend. Untuk memahami betapa pentingnya jenis ini, cukup untuk menyebutkan bahwa dalam jenis Arend, kesetaraan didefinisikan melalui konsep interval. , , , (.. ).

: , HoTT JetBrains Research.

Source: https://habr.com/ru/post/id470632/


All Articles