งานอะไร
หากคุณซ้อนนิยามของ fixpoint บนรายการภายในนิยามของ fixpoint บนแผนผังผลลัพธ์จะถูกพิมพ์อย่างดี 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.
หรือถ้าคุณต้องการที่จะเขียนนี้ยิ่งขึ้น:
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.
(ฉันไม่รู้ว่าใครเป็นคนแรกที่ได้ยินฉันค้นพบสิ่งนี้อย่างอิสระหลายครั้ง)
คำกริยาเรียกซ้ำทั่วไป
โดยทั่วไปคุณสามารถกำหนดหลักการอุปนัย "เหมาะสม" LTree
ด้วยตนเอง หลักการเหนี่ยวนำที่สร้างขึ้นโดยอัตโนมัติLTree_rect
ละเว้นสมมติฐานในรายการเนื่องจากเครื่องกำเนิดหลักการเหนี่ยวนำเข้าใจเฉพาะเหตุการณ์เชิงบวกที่ไม่ซ้อนกันอย่างเคร่งครัดของประเภทอุปนัย
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
ลองเพิ่มสมมติฐานอุปนัยในรายการ เพื่อเติมเต็มในการเรียกซ้ำเราเรียกหลักการเหนี่ยวนำรายการและส่งผ่านหลักการเหนี่ยวนำต้นไม้ในต้นไม้ขนาดเล็กภายในรายการ
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.
ทำไม
คำตอบว่าทำไมอยู่ในกฎที่แม่นยำสำหรับการรับฟังก์ชั่นวนซ้ำ กฎเหล่านี้มีความละเอียดอ่อนเนื่องจากมีความสมดุลที่ละเอียดอ่อนระหว่างการอนุญาตกรณีที่ซับซ้อน (เช่นกรณีนี้โดยมีการเรียกซ้ำแบบซ้อนในประเภทข้อมูล) และไม่ถูกผูกมัด อ้างอิง Coq คู่มือแนะนำภาษา (แคลคูลัสของการก่อสร้างอุปนัยซึ่งเป็นภาษาหลักฐานการ Coq) ส่วนใหญ่กับนิยามอย่างเป็นทางการ แต่ถ้าคุณต้องการกฎระเบียบที่แน่นอนเกี่ยวกับการเหนี่ยวนำและ coinduction คุณจะต้องไปที่งานวิจัยที่ ในหัวข้อนี้ Eduardo Giménez's [1]
Fix
F ฉันx ฉผม{ f1: A1: = t1;ฉ2: A2: = t2}
Γ1Γ2= ( x : L T r e e )= ( l : l ฉันs tL t r e e )A1A2= n a t= n a tเสื้อ1เสื้อ2= c a s e ( x , L T r e e , λ y. ก.1( ฉ2Y) )= c a s e ( l , l ฉันs tL T r e e ,λhร. ก.2( ฉ1h ) ( f2r ) )
ฉJเสื้อผมฉผม
- i = 1j = 2
l
t
size
- i = 2j = 1
h
l
size_l
- i = 2j = 2
r
l
size_l
เหตุผลที่ทำไมh
โครงสร้างไม่เล็กกว่าl
ตามล่าม Coq ไม่ชัดเจนสำหรับฉัน เท่าที่ฉันเข้าใจจากการอภิปรายในรายการ Coq-club [1] [2] นี่เป็นข้อ จำกัด ในล่ามซึ่งในหลักการสามารถยกขึ้นได้ แต่อย่างระมัดระวังเพื่อหลีกเลี่ยงการแนะนำที่ไม่สอดคล้องกัน
อ้างอิง
Cocorico, การทำลายล้าง Coq wiki: การเหนี่ยวนำร่วมกัน
รายชื่อผู้รับจดหมาย Coq-Club:
ทีมพัฒนา Coq Coq ช่วยพิสูจน์: คู่มืออ้างอิง รุ่น 8.3 (2010) [ เว็บ ] ch. 4 .
Eduardo Giménez หมวดหมู่คำจำกัดความกับแผนการรักษา recursive ในTypes'94: ประเภทของการพิสูจน์และโปรแกรม LNCS 996 Springer-Verlag, 1994. ดอย: 10.1007 / 3-540-60579-7_3 [ Springer ]
Eduardo Giménez โครงสร้างการซ้ำคำนิยามในประเภททฤษฎี ในICALP'98: การดำเนินการของการประชุมนานาชาติครั้งที่ 25 เรื่อง Automata, ภาษาและการเขียนโปรแกรม Springer-Verlag, 1998. [ PDF ]