如何在Coq中以sigma类型为例?

时间:2019-05-29 17:08:49

标签: coq

对于该类型:

Record Version := mkVersion { 
  major  : nat; 
  minor  : nat; 
  branch : {b:nat| b > 0 /\ b <= 9};
  hotfix : {h:nat| h > 0 /\ h < 8} 
}.

我想举一个例子:

Example ex1 := mkVersion 3 2 (exist _ 5) (exist _ 5).

它失败并显示:

  

“ exist?P 5”一词的类型为“?P 5-> {x:nat |?P x}”   预期其类型为“ {b:nat | b> 0 / \ b <= 9}”。

我想念什么?

1 个答案:

答案 0 :(得分:5)

失败的原因是,您不仅需要提供证人(在这种情况下为bh),还需要证明所提供的证人符合相应条件。

我将改用布尔值使生活更轻松,因为这允许通过计算进行证明,这基本上是eq_refl在下面的代码段中所做的事情:

From Coq Require Import Bool Arith.

Coercion is_true : bool >-> Sortclass.

Record Version := mkVersion {
  major  : nat;
  minor  : nat;
  branch : {b:nat| (0 <? b) && (b <=? 9)};
  hotfix : {h:nat| (0 <? h) && (h <? 8)}
}.

Example ex1 := mkVersion 3 2 (exist _ 5 eq_refl) (exist _ 5 eq_refl).

我们可以引入一种表示法,以更好地表示文字:

Notation "<| M ',' m ',' b '~' h |>" :=
  (mkVersion M m (exist _ b eq_refl) (exist _ h eq_refl)).

Example ex2 := <| 3,2,5~5 |>.

如果需要添加手动证明,那么我建议使用Program机制:

From Coq Require Import Program.

Program Definition ex3 b h (condb : b =? 5) (condh : h =? 1) :=
  mkVersion 3 2 (exist _ b _) (exist _ h _).
Next Obligation.
  now unfold is_true in * |-; rewrite Nat.eqb_eq in * |-; subst. Qed.
Next Obligation.
  now unfold is_true in * |-; rewrite Nat.eqb_eq in * |-; subst. Qed.

refine策略:

Definition ex3' b h (condb : b =? 5) (condh : h =? 1) : Version.
Proof.
  now refine (mkVersion 3 2 (exist _ b _) (exist _ h _));
  unfold is_true in * |-; rewrite Nat.eqb_eq in * |-; subst.
Qed.