我有一种列表,其头部和尾部必须在某种意义上“兼容”:
Inductive tag := A | B. (* Just an example *)
Inductive element : tag -> tag -> Set :=
| AA : element A A
| AB : element A B
| BB : element B B. (* Also just an example *)
Inductive estack : tag -> tag -> Set :=
| ENil : forall t, estack t t
| ECons : forall r s t, element r s -> estack s t -> estack r t.
但是,我不太喜欢这段代码,原因如下:
- 它不是模块化的:ad-hoc 列表数据构造器本质上与头部和尾部兼容的证明 - 标记相结合。
- 它不利于代码重用:我被迫重新定义通常的列表函数(例如列表连接)并重新证明通常的列表定理(例如列表连接的关联性)。
我想到了一种不同的方法,它包括三个步骤:
定义单一类型的标记元素(而不是一系列标记类型的元素):
Inductive taggedElement := Tagged : forall t1 t2, element t1 t2 -> taggedElement.
定义标记元素的任意(即有效或无效)列表的类型:
Definition taggedElementStack := list taggedElement.
将标记元素的有效列表定义为元组,其元素是标记元素的任意列表,并证明元素与相邻元素兼容。
(* I have no idea how to do this in Coq, hence the question! * * I am going to use pseudomathematical notation. I am not well versed in either * mathematics or theoretical computer science, so please do not beat me with a * stick if I say something that is completely bogus! * * I want to construct the type * * (tes : taggedElementStack, b : proof that P(tes) holds) * * where P(tes) is a predicate that is only true when, for every sublist of tes, * including tes itself, the heads and tails are compatible. *)
我将如何在 Coq 中执行第三步?