Coq:如何引用由特定构造函数生成的类型?

时间:2018-10-03 07:07:25

标签: coq

例如,如果我定义一个从nat到nat的函数,它将是

Definition plusfive(a:nat): nat := a + 5.

但是,我想定义一个函数,其参数是使用“ S”构造函数(即非零)构造的nat,是否可以直接指定为类型?像

Definition plusfive(a: nat.S): nat := a + 5.

(我知道在这种情况下,我还可以添加一个证明a非零的参数,但我想知道是否有可能直接基于'S'构造函数来命名类型)。

1 个答案:

答案 0 :(得分:5)

功能必须完整,因此您必须使用某些子类型而不是nat,或者添加一个减少输入空间的参数,例如(H: a<>0)

Definition plusfive(a:nat) (H:a<>0) :=
  match a as e return a=e -> _ with
  | S _ => fun _  => a + 5
  | _   => fun H0 => match (H H0) with end
  end eq_refl.

但是,已经发现在大型开发中使用这些技巧非常麻烦,并且通常在基本类型上使用完整的函数,这些函数为错误的输入值返回伪值,并证明该函数已被调用具有正确的参数和功能定义。例如,请参见标准库中如何定义除法。

Require Import Nat.
Print div.

div = 
fun x y : nat => match y with
                 | 0 => y
                 | S y' => fst (divmod x y' 0 y')
                 end
     : nat -> nat -> nat

因此Compute (div 1 0).给您0

令人高兴的是,您可以直接在表达式中使用div,而不必插入分母为非零的证明。然后在定义了表达式之后, 证明表达式正确,而不是同时进行。