在Coq的函数定义中使用证明和见证结构

在Coq的函数定义中使用证明和见证结构,coq,Coq,我试图将一些直觉的概念形式化。其中之一是连续性原则。在Coq中,我将其定义为: (* Infinite sequences *) Definition N := nat -> nat. (* The first n elements of a and b coincide. *) Definition con (a b : N) n := forall i, i < n -> a i = b i. (* Brouwers Continuity Principle *) Ax

我试图将一些直觉的概念形式化。其中之一是连续性原则。在Coq中,我将其定义为:

(* Infinite sequences *)
Definition N := nat -> nat.

(* The first n elements of a and b coincide. *)
Definition con (a b : N) n := forall i, i < n -> a i = b i.

(* Brouwers Continuity Principle *)
Axiom BCP :
  forall (R : N -> nat -> Prop),
  (forall a, exists n, R a n) ->
  (forall a, exists m n, forall b, con a b m -> R b n).
现在我遇到了真正的问题。在
{?????}
部分,我需要插入一个证明
ot=0
。这是因为rho只返回决策器o接受的序列。也许我可以让rho返回一个包含新序列的元组,并证明该序列被接受(这样我可以在递归后将其馈送到
w
),但我不知道如何返回。请注意,这对于else分支来说尤其棘手,因为该值被接受的证据成立,因为见证是有效的


当然,定义价差的其他想法也很受欢迎。但我确实觉得这是可以实现的(就我所见,没有逻辑上的不一致)。

我似乎已经找到了一些办法:

(* Only sequences that are accepted by o *)
Inductive spr (o : decider) :=
  | spr_s s : o s = 0 -> spr o.

(* Return smallest n such that o accepts n :: s. *)
Definition find_extension o s (witness : exists n, o (n :: s) = 0) : spr o :=
  let P := (fun n => o (n :: s) = 0) in
  let D := (decider_dec o s) in
  spr_s o
    ((constructive_ground_epsilon_nat P D witness) :: s)
    (constructive_ground_epsilon_spec_nat P D witness).

(*
To generalize BCP to spreads we first define a function that retracts the Baire
space onto an arbitrary spread given its spread law. This happens in two steps.
*)

(* Compute retraction for finite start sequences. *)
Fixpoint rho o
  (Hnil : o [] = 0)
  (Hcons : forall s, o s = 0 -> exists n, o (n :: s) = 0)
  (s : list nat) : spr o :=
  match s with
  | [] => spr_s o [] Hnil
  | n :: s =>
    match rho o Hnil Hcons s with
    | spr_s _ t Ht =>
      match eq_dec (o (n :: t)) 0 with
      | left Heq  => spr_s o (n :: t) Heq
      | right  _  => find_extension o t (Hcons t Ht)
      end
    end
  end.

(* Retraction of N onto F_o *)
Definition retract o
  (Hnil : o [] = 0)
  (Hcons : forall s, o s = 0 -> exists n, o (n :: s) = 0)
  : N -> N :=
  fun a => fun n =>
    match rho o Hnil Hcons (get (n + 1) a) with
    | spr_s _ [] _ => 0 (* not reachable *)
    | spr_s _ (rho_n :: _) _ => rho_n
    end.

如果您可以将编辑内容与问题分开,并将其作为答案发布,这将非常有用。
Definition find_extension o s (w : exists n, o (n :: s) = 0) : nat :=
  constructive_ground_epsilon_nat (fun n => o (n :: s) = 0) (decider_dec o s) w.

(* Compute retraction for finite start sequences. *)
Fixpoint rho o (w : forall s, o s = 0 -> exists n, o (n :: s) = 0)
  (s : list nat) : list nat :=
  match s with
  | [] => []
  | n :: s => let t := rho o w s in
    if o (n :: t) =? 0
    then n :: t
    else (find_extension o t (w t {?????})) :: t
  end.
(* Only sequences that are accepted by o *)
Inductive spr (o : decider) :=
  | spr_s s : o s = 0 -> spr o.

(* Return smallest n such that o accepts n :: s. *)
Definition find_extension o s (witness : exists n, o (n :: s) = 0) : spr o :=
  let P := (fun n => o (n :: s) = 0) in
  let D := (decider_dec o s) in
  spr_s o
    ((constructive_ground_epsilon_nat P D witness) :: s)
    (constructive_ground_epsilon_spec_nat P D witness).

(*
To generalize BCP to spreads we first define a function that retracts the Baire
space onto an arbitrary spread given its spread law. This happens in two steps.
*)

(* Compute retraction for finite start sequences. *)
Fixpoint rho o
  (Hnil : o [] = 0)
  (Hcons : forall s, o s = 0 -> exists n, o (n :: s) = 0)
  (s : list nat) : spr o :=
  match s with
  | [] => spr_s o [] Hnil
  | n :: s =>
    match rho o Hnil Hcons s with
    | spr_s _ t Ht =>
      match eq_dec (o (n :: t)) 0 with
      | left Heq  => spr_s o (n :: t) Heq
      | right  _  => find_extension o t (Hcons t Ht)
      end
    end
  end.

(* Retraction of N onto F_o *)
Definition retract o
  (Hnil : o [] = 0)
  (Hcons : forall s, o s = 0 -> exists n, o (n :: s) = 0)
  : N -> N :=
  fun a => fun n =>
    match rho o Hnil Hcons (get (n + 1) a) with
    | spr_s _ [] _ => 0 (* not reachable *)
    | spr_s _ (rho_n :: _) _ => rho_n
    end.