Những gì hoạt động
Nếu bạn lồng định nghĩa của điểm cố định vào danh sách bên trong định nghĩa của điểm cố định trên cây, kết quả sẽ được gõ tốt. Đây là một nguyên tắc chung khi bạn đã đệ quy lồng nhau theo kiểu quy nạp, tức là khi đệ quy đi qua một hàm tạo như thế nào 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.
Hoặc nếu bạn thích viết điều này chặt chẽ hơn:
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.
(Tôi không biết tôi đã nghe ai từ đầu; điều này chắc chắn được phát hiện độc lập nhiều lần.)
Một vị ngữ đệ quy chung
Tổng quát hơn, bạn có thể định nghĩa nguyên tắc cảm ứng phù hợp của Wap trên LTree
thủ công. Nguyên tắc cảm ứng được tạo tự động LTree_rect
bỏ qua giả thuyết trong danh sách, bởi vì trình tạo nguyên lý cảm ứng chỉ hiểu các trường hợp tích cực nghiêm trọng không lồng nhau của loại quy nạp.
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
Hãy thêm giả thuyết cảm ứng vào danh sách. Để thực hiện nó trong cuộc gọi đệ quy, chúng ta gọi nguyên tắc cảm ứng danh sách và truyền cho nó nguyên tắc cảm ứng cây trên cây nhỏ hơn trong danh sách.
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.
Tại sao
Câu trả lời tại sao nằm trong các quy tắc chính xác để chấp nhận các hàm đệ quy. Các quy tắc này là lực lượng tinh vi, bởi vì có một sự cân bằng tinh tế giữa việc cho phép các trường hợp phức tạp (chẳng hạn như trường hợp này, với đệ quy lồng nhau trong kiểu dữ liệu) và sự không rõ ràng. Tài liệu tham khảo Coq giới thiệu ngôn ngữ (tính toán của các cấu trúc quy nạp, là ngôn ngữ chứng minh của Coq), chủ yếu là với các định nghĩa chính xác, nhưng nếu bạn muốn các quy tắc chính xác về quy nạp và cưỡng chế, bạn sẽ cần đến các tài liệu nghiên cứu, về chủ đề này của Eduardo Giménez [1].
Fix
Fixfi{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
Lý do tại sao h
cấu trúc không nhỏ hơn l
theo thông dịch viên Coq là không rõ ràng đối với tôi. Theo như tôi hiểu từ các cuộc thảo luận trong danh sách câu lạc bộ Coq [1] [2], đây là một hạn chế trong trình thông dịch, về nguyên tắc có thể được gỡ bỏ, nhưng rất cẩn thận để tránh đưa ra sự không nhất quán.
Tài liệu tham khảo
Cocorico, wiki Coq đang thịnh hành: Cảm ứng lẫn nhau
Danh sách gửi thư của Coq-Club:
Nhóm phát triển Coq. Trợ lý bằng chứng Coq: Tài liệu tham khảo . Phiên bản 8.3 (2010). [ web ] ch. 4 .
Eduardo Giménez. Mã hóa các định nghĩa được bảo vệ với các sơ đồ đệ quy . Trong các loại'94: Các loại bằng chứng và chương trình , LNCS 996. Springer-Verlag, 1994. doi: 10.1007 / 3-540-60579-7_3 [ Springer ]
Eduardo Giménez. Định nghĩa đệ quy cấu trúc trong lý thuyết loại . Trong ICALP'98: Kỷ yếu của Hội thảo quốc tế lần thứ 25 về Automata, Ngôn ngữ và Lập trình. Springer-Verlag, 1998. [ PDF ]