Ne çalışıyor
Düzeltme noktası tanımını, ağaçlardaki düzeltme noktası tanımının içindeki listelere yerleştirirseniz, sonuç iyi yazılır. Bu, özyinelemeli bir türde özyinelemeyi iç içe geçirdiğinizde, yani özyineleme gibi bir yapıcıdan geçtiğinde genel bir ilkedir 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.
Veya bunu daha ters yazmayı tercih ediyorsanız:
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.
(İlk başta kimi duyduğum hakkında hiçbir fikrim yok; bu kesinlikle birçok kez bağımsız olarak keşfedildi.)
Genel özyineleme yüklemi
Daha genel olarak, “uygun” indüksiyon prensibini LTree
manuel olarak tanımlayabilirsiniz . Otomatik olarak oluşturulan indüksiyon prensibi LTree_rect
listedeki hipotezi atlar, çünkü indüksiyon prensibi jeneratörü sadece endüktif tipin iç içe olmayan kesinlikle pozitif oluşumlarını anlar.
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
Listelere indüksiyon hipotezini ekleyelim. Özyinelemeli çağrıda yerine getirmek için, liste indüksiyon prensibi olarak adlandırırız ve onu listenin içindeki küçük ağaç üzerinde ağaç indüksiyon prensibine geçiririz.
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.
Niye ya
Nedeninin cevabı, özyinelemeli işlevleri kabul etmek için kesin kurallarda yatmaktadır. Bu kurallar ince performans gösterir, çünkü karmaşık vakalara izin verilmesi (bu gibi, veri tipinde iç içe özyineleme ile) ve sessizlik arasında hassas bir denge vardır. Coq referans kılavuzu tanıttı dil çoğunlukla resmen kesin olarak tanımlanmasıyla birlikte, ancak (Coq kanıtı dildir endüktif inşaatlar hesabı,) sen araştırma makaleleri gitmek gerek edeceğiz indüksiyon ve coinduction ilişkin kesin kurallar istiyorsanız, bu konuda Eduardo Giménez'nin [1].
Coq kılavuzundan başlayarak, Fix
kuralın gösterilmesinde, düzeltme noktası tanımına sahibizFixfi{f1:A1:=t1;f2:A2:=t2}
Γ1Γ2=(x:LTree)=(l:listLTree)A1A2=nat=natt1t2=case(x,LTree,λy.g1(f2y))=case(l,listLTree,λhr.g2(f1h)(f2r))
fjtifi
- i=1j=2
l
t
size
- i=2j=1
h
l
size_l
- i=2j=2
r
l
size_l
Coq yorumlayıcısına göre h
yapısal olarak daha küçük olmamasının sebebi l
benim için net değil. Coq-club listesindeki tartışmalardan anladığım kadarıyla [1] [2], bu, prensipte kaldırılabilecek bir tutarsızlıktır, ancak tutarsızlık getirmekten kaçınmak için çok dikkatli bir şekilde.
Referanslar
Cocorico, bitmeyen Coq wiki: Karşılıklı Tümevarım
Coq-Club posta listesi:
Coq Geliştirme Ekibi. Coq Proof Assistant: Referans Kılavuzu . Sürüm 8.3 (2010). [ web ] ch. 4 .
Eduardo Giménez. Korumalı tanımların özyinelemeli şemalarla kodlanması . Gelen Types'94: Düzeltmeler ve Programlar türleri , LNCS 996, Springer-Verlag, 1994, doi: 10.1007 / 3-540-60579-7_3 [ Springer ]
Eduardo Giménez. Tip Teorisinde Yapısal Özyinelemeli Tanımlar . In ICALP'98: Tutanakları 25 Özdevinir, Dil ve Programlama Uluslararası Kolokyumu arasında. Springer-Verlag, 1998. [ PDF ]