在Coq中,如何构建一个“sig”的元素。类型

时间:2017-07-07 09:31:53

标签: types casting coq subtype

使用类型A的简单归纳定义:

Inductive A: Set := mkA : nat-> A.

(*get ID of A*)
Function getId (a: A) : nat := match a with mkA n => n end. 

和子类型定义:

(* filter that test ID of *A* is 0 *)
Function filter (a: A) : bool := if (beq_nat (getId a) 0) then true else false.

(* cast bool to Prop *)
Definition IstrueB (b : bool) : Prop := if b then True else False.

(* subtype of *A* that only interests those who pass the filter *)
Definition subsetA : Set := {a : A | IstrueB (filter a) }.

我尝试使用此代码在A通过时将subsetA的元素转换为filter,但未能方便Coq它是一个有效的构造,用于' sig& #39;类型:

Definition cast (a: A) : option subsetA :=
match (filter a) with
 | true => Some (exist _ a (IstrueB (filter a)))
 | false => None
end.

错误:

In environment
a : A
The term "IstrueB (filter a)" has type "Prop"
while it is expected to have type "?P a"
(unable to find a well-typed instantiation for "?P": cannot ensure that
"A -> Type" is a subtype of "?X114@{__:=a} -> Prop").

因此,Coq希望得到(IstrueB (filter a))类型的实际证明,但我提供的是类型Prop

你能谈谈如何提供这种类型吗?谢谢。

1 个答案:

答案 0 :(得分:3)

首先,有标准is_true包装器。您可以像这样明确地使用它:

Definition subsetA : Set := {a : A | is_true (filter a) }.

或隐含地使用强制机制:

Coercion is_true : bool >-> Sortclass.
Definition subsetA : Set := { a : A | filter a }.

接下来,filter a上的非依赖模式数学运算不会将filter a = true传播到true分支。您至少有三个选择:

  1. 使用策略构建cast函数:

    Definition cast (a: A) : option subsetA.
      destruct (filter a) eqn:prf.
      - exact (Some (exist _ a prf)).
      - exact None.
    Defined.
    
  2. 明确使用依赖模式匹配(在Stackoverflow或CDPT中搜索“convoy模式”):

    Definition cast' (a: A) : option subsetA :=
      match (filter a) as fa return (filter a = fa -> option subsetA) with
      | true => fun prf => Some (exist _ a prf)
      | false => fun _ => None
      end eq_refl.
    
  3. 使用Program设施:

    Require Import Coq.Program.Program.
    
    Program Definition cast'' (a: A) : option subsetA :=
      match filter a with
      | true => Some (exist _ a _)
      | false => None
      end.