Pekerjaan apa
Jika Anda mencari definisi fixpoint pada daftar di dalam definisi fixpoint pada pohon, hasilnya diketik dengan baik. Ini adalah prinsip umum ketika Anda memiliki rekursi bersarang dalam tipe induktif, yaitu ketika rekursi melalui konstruktor suka list
.
Fixpoint size (t : LTree) : nat :=
let size_l := (fix size_l (l : list LTree) : nat :=
match l with
| nil => 0
| h::r => size h + size_l r
end) in
match t with Node l =>
1 + size_l l
end.
Atau jika Anda lebih suka menulis ini lebih singkat:
Fixpoint size (t : LTree) : nat :=
match t with Node l =>
1 + (fix size_l (l : list LTree) : nat :=
match l with
| nil => 0
| h::r => size h + size_l r
end) l
end.
(Saya tidak tahu dari siapa saya mendengarnya dari awal; ini tentu saja ditemukan secara independen berkali-kali.)
Predikat rekursi umum
Secara umum, Anda dapat mendefinisikan prinsip induksi "benar" LTree
secara manual. Prinsip induksi yang dihasilkan secara otomatis LTree_rect
menghilangkan hipotesis dalam daftar, karena generator prinsip induksi hanya memahami kejadian non-bersarang yang benar-benar positif dari tipe induktif.
LTree_rect =
fun (P : LTree -> Type) (f : forall l : list LTree, P (Node l)) (l : LTree) =>
match l as l0 return (P l0) with
| Node x => f x
end
: forall P : LTree -> Type,
(forall l : list LTree, P (Node l)) -> forall l : LTree, P l
Mari kita tambahkan hipotesis induksi pada daftar. Untuk memenuhinya dalam panggilan rekursif, kami memanggil prinsip induksi daftar dan memberikannya prinsip induksi pohon pada pohon kecil di dalam daftar.
Fixpoint LTree_rect_nest (P : LTree -> Type) (Q : list LTree -> Type)
(f : forall l, Q l -> P (Node l))
(g : Q nil) (h : forall t l, P t -> Q l -> Q (cons t l))
(t : LTree) :=
match t as t0 return (P t0) with
| Node l => f l (list_rect Q g (fun u r => h u r (LTree_rect_nest P Q f g h u)) l)
end.
Mengapa
Jawaban untuk alasan terletak pada aturan yang tepat untuk menerima fungsi rekursif. Aturan-aturan ini sangat halus, karena ada keseimbangan yang rumit antara memungkinkan kasus-kasus yang kompleks (seperti yang ini, dengan rekursi bersarang dalam tipe data) dan tidak sehat. The referensi Coq panduan memperkenalkan bahasa (kalkulus konstruksi induktif, yang merupakan bahasa bukti Coq), sebagian besar dengan definisi formal yang tepat, tetapi jika Anda ingin aturan yang tepat tentang induksi dan coinduction Anda akan perlu pergi ke makalah penelitian, tentang topik ini Eduardo Giménez [1].
Fix
F i x fsaya{ f1: A1: = t1;f2: A2: = t2}
Γ1Γ2= ( x : L T r e e )= ( l : l i s tL T r e e )SEBUAH1SEBUAH2= n a t= n a tt1t2= c a s e ( x , L T r e e , λ y. g1( f2y) )= c a s e ( l , l i s tL T e r e ,λ hr . g2( f1h ) ( f2r ) )
fjtsayafsaya
- i = 1j = 2
l
t
size
- i = 2j = 1
h
l
size_l
- i = 2j = 2
r
l
size_l
Alasan mengapa h
secara struktural lebih kecil daripada l
menurut penerjemah Coq tidak jelas bagi saya. Sejauh yang saya mengerti dari diskusi pada daftar Coq-club [1] [2], ini adalah batasan dalam juru bahasa, yang pada prinsipnya dapat diangkat, tetapi dengan sangat hati-hati untuk menghindari memperkenalkan ketidakkonsistenan.
Referensi
Cocorico, Coq wiki nonterminating: Saling Induksi
Milis Coq-Club:
Tim Pengembangan Coq. Asisten Bukti Coq: Manual Referensi . Versi 8.3 (2010). [ web ] ch. 4 .
Eduardo Giménez. Mengkodifikasi definisi yang dijaga dengan skema rekursif . Dalam Types'94: Jenis untuk Bukti dan Program , LNCS 996. Springer-Verlag, 1994. doi: 10.1007 / 3-540-60579-7_3 [ Springer ]
Eduardo Giménez. Definisi Rekursif Struktural dalam Teori Tipe . Dalam ICALP'98: Prosiding Kolokium Internasional ke 25 tentang Automata, Bahasa dan Pemrograman. Springer-Verlag, 1998. [ PDF ]