Coq 将无穷级数的存在性证明转换为给出该无穷级数的函数

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

我试图在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 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'].