Coq 将无穷级数的存在性证明转换为给出该无穷级数的函数
我试图在TRS上进行推理,我遇到了以下证明义务:Coq 将无穷级数的存在性证明转换为给出该无穷级数的函数,coq,Coq,我试图在TRS上进行推理,我遇到了以下证明义务: infinite_sequence : forall t' : Term, transitive_closure R t t' -> exists t'' : Term, R t' t'' ============================ exists f : nat -> Term, forall n : nat, R (f
infinite_sequence : forall t' : Term,
transitive_closure R t t' ->
exists t'' : Term, R t' t''
============================
exists f : nat -> Term, forall n : nat, R (f n) (f (n + 1))
带有传递闭包的定义如下:
Definition transitive_closure (trs : TRS) (x y : Term) :=
exists f: nat -> Term,
f 0 = x
/\
exists l: nat,
f l = y
/\
forall n: nat,
n < l
->
trs (f n) (f (n + 1))
.
这一证明义务能否履行?我没有考虑过传递闭包的确切定义,因此,如果选择不同的定义变得更容易,我愿意接受。因为你的目标是从exists f:nat->Term
开始的,你必须明确地构建这样一个函数。最简单的方法是首先构建一个返回类型稍丰富的函数({u:Term | transitive_closure R t u}
而不是Term
),然后逐点投影其第一个组件以完成证明。这将产生以下脚本:
simple refine (let f : nat -> { u: Term | transitive_closure R t u } := _ in _).
- fix f 1.
intros [|n].
{ exists t. exists (fun _ => t). admit. }
destruct (f n) as [t' H].
destruct (infinite_sequence t' H) as [t'' H']. (* ISSUE *)
exists t''.
destruct H as [f' [H1 [l [H2 H3]]]].
exists (fun m => if Nat.ltb m l then f' m else t'').
admit.
- exists (fun n => proj1_sig (f n)).
intros n.
rewrite Nat.add_1_r.
simpl.
destruct (f n) as [fn Hn].
now destruct infinite_sequence as [t'' H'].
两个
admit只是为了保持代码的简单性;他们没有什么困难。真正的问题来自行析构函数(无限序列t'H)
,因为Coq会抱怨“归纳定义不允许对排序集进行案例分析”。事实上,无限序列
声明存在t'
,因此R t't'
,但它是以非信息性的方式这样做的(即,在Prop
)中),而您需要它来构建生活在具体世界中的函数(即,在Set
)
只有两种无公理的解决方案,但这两种解决方案都可能与开发的其余部分不兼容。最简单的解决方案是将infinite_sequence
放入Set
,这意味着它的类型更改为forall t',transitive_closure R t'->{t'.\R t't'
第二种解决方案要求
R
是一个可判定关系,Term
是一个可枚举集。这样,您仍然可以通过枚举所有的项来构建一个具体的t'
,直到找到一个满足R t't'
的项。在这种情况下,无限序列
仅用于证明此过程终止,因此它可以是非信息性的。我的猜测是,应该可以实现这一点,但您需要假设选择公理。直观地说,要构建函数f
,您需要使用假设为每个有限的转换序列提取一个项。因为t''
项在假设,你需要选择。这可能是正确的方法,但我最终改写了一些定义,所以我不需要给出这个证明。尽管如此,谢谢!
simple refine (let f : nat -> { u: Term | transitive_closure R t u } := _ in _).
- fix f 1.
intros [|n].
{ exists t. exists (fun _ => t). admit. }
destruct (f n) as [t' H].
destruct (infinite_sequence t' H) as [t'' H']. (* ISSUE *)
exists t''.
destruct H as [f' [H1 [l [H2 H3]]]].
exists (fun m => if Nat.ltb m l then f' m else t'').
admit.
- exists (fun n => proj1_sig (f n)).
intros n.
rewrite Nat.add_1_r.
simpl.
destruct (f n) as [fn Hn].
now destruct infinite_sequence as [t'' H'].