我正在尝试在证明检查器 coq 中定义一个域。我该怎么做呢?
我正在尝试做相当于V in [0,10]
.
我已经尝试过这样做Definition V := forall v in R, 0 <= v /\ v <= 10.
,但这会导致常量出现问题,例如根据 Coq0
不在其中。V
我正在尝试在证明检查器 coq 中定义一个域。我该怎么做呢?
我正在尝试做相当于V in [0,10]
.
我已经尝试过这样做Definition V := forall v in R, 0 <= v /\ v <= 10.
,但这会导致常量出现问题,例如根据 Coq0
不在其中。V
一个简单的方法可能是这样的,
Require Import Omega.
Inductive V : Set :=
mkV : forall (v:nat), 0 <= v /\ v <= 10 -> V.
Lemma member0 : V.
Proof. apply (mkV 0). omega. Qed.
Definition inc (v:V) : nat := match v with mkV n _ => n + 1 end.
Lemma inc_bounds : forall v, 0 <= inc v <= 11.
Proof. intros v; destruct v; simpl. omega. Qed.
当然,类型member0
可能不像您希望的那样提供信息。在这种情况下,您可能希望按集合中每个元素V
的nat
对应项进行索引。
Require Import Omega.
Inductive V : nat -> Set :=
mkV : forall (v:nat), 0 <= v /\ v <= 10 -> V v.
Lemma member0 : V 0.
Proof. apply (mkV 0). omega. Qed.
Definition inc {n} (v:V n) : nat := n + 1.
Lemma inc_bounds : forall {n:nat} (v:V n), 0 <= inc v <= 11.
Proof. intros n v. unfold inc. destruct v. omega. Qed.
我以前没有使用Reals
过,但是上面也可以实现R
。
Require Import Reals.
Require Import Fourier.
Open Scope R_scope.
Inductive V : R -> Set :=
mkV : forall (v:R), 0 <= v /\ v <= 10 -> V v.
Lemma member0 : V 0.
Proof. apply (mkV 0). split. right; auto. left; fourier. Qed.
Definition inc {r} (v:V r) : R := r + 1.
Lemma inc_bounds : forall {r:R} (v:V r), 0 <= inc v <= 11.
Proof. intros r v; unfold inc.
destruct v as (r,pf). destruct pf. split; fourier.
Qed.
我相信这样做的自然方法是使用 sig 类型,Yves 在评论中也提到了这一点。
V 的元素将是来自 R 的数字 x,以及证明它们确实应该在集合 V 中的证明。
Require Import Reals Fourier.
Open Scope R_scope.
Definition V_prop (x : R) : Prop := 0 <= x /\ x <= 10.
Definition V : Set := { x : R | V_prop x }.
Lemma V_prop0: V_prop 0.
Proof.
unfold V_prop; split;
[right; auto | left; fourier].
Qed.
Definition V0 : V := exist _ 0 V_prop0.