我有一种列表,其头部和尾部必须具有某种意义并且#34;兼容":
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.
但是,由于以下原因,我不太喜欢这段代码:
我有一个不同的方法,包括三个步骤:
定义单一类型的标记元素(与标记类型的元素系列相对):
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中执行第三步?
答案 0 :(得分:2)
看看你的estack
,它有什么作用?概括! element
只是一种关系(A -> A -> Set
),tag
只是Set
。你得到了什么?
Inductive RTList {I : Set} (X : Rel I) : Rel I :=
| RTNil : forall {i : I}, RTList X i i
| RTCons : forall {i j k : I}, X i j -> RTList X j k -> RTList X i k.
(Rel
只是Rel I = I -> I -> Set
的定义。)
反身传递闭合! 是常见的,可重用的和模块化的。或者你认为。
我在Coq的库中找到的唯一实现是在Coq.Relations.Relation_Operators
,名为clos_refl_trans
,结构不同并锁定在Prop
(根据文档,所有都没有尝试)。
你可能不得不重新实现它或在某个地方找到一个库。至少,您只需执行一次此操作(或Set
,Prop
和Type
最多三次。
你的另一个想法可能会更难管理。查看NoDup
与您的描述类似的内容,您可以重用该模式。如果你真的想要那个。 NoDup
使用In
,这是一个检查元素是否在列表中的函数。我最后一次尝试使用它时,我发现解决涉及In
的证据要困难得多。你不能只是destruct
但是必须使用辅助引理,你必须小心地展开$ n级别,折回很难等等。我建议除非真的有必要,否则你最好坚持下去包含Prop
s。