您的类型具有嵌套归纳,它们是归纳类型的递归出现,作为其他归纳类型(在您的情况下是对和列表)的参数。
与其他情况一样,您需要通过归纳来展示您想要的内容。不幸的是,与更简单的类型不同,Coq 没有为此类类型自动生成归纳原则的内置机制,因此您必须推出自己的机制。有一些关于一般问题here 的有趣链接。以下是如何解决您的问题,结合嵌套和相互递归。请注意Forall' 用于陈述归纳假设的辅助归纳
Require Import String.
Require Import List.
Require Import ListSet.
Import ListNotations.
Set Implicit Arguments.
Inductive a : Type :=
| basic : string -> (string * string) -> a
| complex : string -> list a -> nat -> list t -> (string * string) -> a
| complex2 : string -> list a -> a
with t : Type :=
| t_intro : string * a * (set string) * (set string) -> t.
Inductive Forall' A (T : A -> Type) : list A -> Type :=
| Forall_nil' : Forall' T []
| Forall_cons' : forall x l, T x -> Forall' T l -> Forall' T (x :: l).
Definition build_forall A (T : A -> Type) (f : forall x, T x) :=
fix F l : Forall' T l :=
match l with
| [] => Forall_nil' _
| x :: l' => Forall_cons' x (f x) (F l')
end.
Lemma forall_eq_dec A (l : list A) (H : Forall' (fun x => forall y, {x = y} + {x <> y}) l) :
forall l', {l = l'} + {l <> l'}.
Proof.
induction H as [| x l Hx Hl IH]; intros [|y l']; try (right; congruence); eauto.
specialize (IH l').
destruct IH; subst; try (right; congruence).
destruct (Hx y); subst; try (right; congruence).
eauto.
Qed.
Fixpoint a_ind' (Ta : a -> Type) (Tt : t -> Type)
(H1 : forall s p, Ta (basic s p))
(H2 : forall s la, Forall' Ta la ->
forall n lt, Forall' Tt lt ->
forall p, Ta (complex s la n lt p))
(H3 : forall s la, Forall' Ta la -> Ta (complex2 s la))
(H4 : forall s x, Ta x ->
forall ss1 ss2, Tt (t_intro (s, x, ss1, ss2))) x {struct x} : Ta x :=
match x with
| basic s p => H1 s p
| complex s la n lt p => H2 s la (build_forall _ (a_ind' H1 H2 H3 H4) la)
n lt (build_forall _ (t_ind' H1 H2 H3 H4) lt)
p
| complex2 s la => H3 s la (build_forall _ (a_ind' H1 H2 H3 H4) la)
end
with t_ind' (Ta : a -> Type) (Tt : t -> Type)
(H1 : forall s p, Ta (basic s p))
(H2 : forall s la, Forall' Ta la ->
forall n lt, Forall' Tt lt ->
forall p, Ta (complex s la n lt p))
(H3 : forall s la, Forall' Ta la -> Ta (complex2 s la))
(H4 : forall s x, Ta x ->
forall ss1 ss2, Tt (t_intro (s, x, ss1, ss2))) x {struct x} : Tt x :=
match x with
| t_intro (s, x, ss1, ss2) => H4 s x (a_ind' H1 H2 H3 H4 x) ss1 ss2
end.
Definition a_and_t_ind (Ta : a -> Type) (Tt : t -> Type)
(H1 : forall s p, Ta (basic s p))
(H2 : forall s la, Forall' Ta la ->
forall n lt, Forall' Tt lt ->
forall p, Ta (complex s la n lt p))
(H3 : forall s la, Forall' Ta la -> Ta (complex2 s la))
(H4 : forall s x, Ta x ->
forall ss1 ss2, Tt (t_intro (s, x, ss1, ss2))) :
(forall x, Ta x) * (forall x, Tt x) :=
(a_ind' H1 H2 H3 H4, t_ind' H1 H2 H3 H4).
Lemma pair_dec A B (HA : forall x y : A, {x = y} + {x <> y})
(HB : forall x y : B, {x = y} + {x <> y}) :
forall x y : A * B, {x = y} + {x <> y}.
Proof. decide equality. Qed.
Definition a_and_t_dec : (forall x y : a, {x = y} + {x <> y}) *
(forall x y : t, {x = y} + {x <> y}).
Proof.
apply a_and_t_ind.
- intros s p [s' p'| |]; try (right; congruence).
destruct (string_dec s s'); try (right; congruence).
subst.
destruct (pair_dec string_dec string_dec p p'); try (right; congruence).
subst. eauto.
- intros s la Hla n lt Hlt p y.
destruct y as [|s' la' n' lt' p'|]; try (right; congruence).
destruct (string_dec s s'); subst; try (right; congruence).
destruct (forall_eq_dec Hla la'); subst; try (right; congruence).
destruct (NPeano.Nat.eq_dec n n'); subst; try (right; congruence).
destruct (forall_eq_dec Hlt lt'); subst; try (right; congruence).
destruct (pair_dec string_dec string_dec p p'); subst; try (right; congruence).
eauto.
- intros s la Hla [| |s' la']; try (right; congruence).
destruct (string_dec s s'); subst; try (right; congruence).
destruct (forall_eq_dec Hla la'); subst; try (right; congruence).
eauto.
- intros s x Hx ss1 ss2 [[[[s' x'] ss1'] ss2']].
destruct (string_dec s s'); subst; try (right; congruence).
destruct (Hx x'); subst; try (right; congruence).
destruct (list_eq_dec string_dec ss1 ss1'); subst; try (right; congruence).
destruct (list_eq_dec string_dec ss2 ss2'); subst; try (right; congruence).
eauto.
Qed.
Definition a_dec := fst a_and_t_dec.
Definition t_dec := snd a_and_t_dec.