如何匹配Coq中的特定值?

时间:2017-09-23 19:37:14

标签: coq

我试图实现一个只计算一个包中某些nat出现次数的函数(只是列表的同义词)。

这就是我想要做的,但它不起作用:

Require Import Coq.Lists.List.
Import ListNotations.

Definition bag := list nat.

Fixpoint count (v:nat) (s:bag) : nat :=
  match s with
  | nil    => O
  | v :: t => S (count v t) 
  | _ :: t => count v t
  end. 

Coq说最后一个条款是多余的,即它只是将v视为头部的名称,而不是传递给计数调用的特定v。有没有办法模式匹配作为函数参数传递的值?如果没有,我应该如何编写函数?

我让这个工作:

Fixpoint count (v:nat) (s:bag) : nat :=
match s with
| nil    => O
| h :: t => if (beq_nat v h) then S (count v t) else count v t
end. 

但我不喜欢它。如果可能,我宁愿模式匹配。

3 个答案:

答案 0 :(得分:3)

模式匹配是一种与平等不同的结构,旨在区分以“归纳”形式编码的数据,作为函数式编程的标准。

特别是,在许多情况下,模式匹配不足,例如当您需要潜在的无限模式时。

话虽这么说,一个更合理的计数类型是math-comp库中可用的类型:

count : forall T : Type, pred T -> seq T -> nat
Fixpoint count s := if s is x :: s' then a x + count s' else 0.

然后,您可以将您的函数构建为count (pred1 x),其中pred1 : forall T : eqType, T -> pred T,也就是说,具有可判定(可计算)相等的类型的固定元素的一元等式谓词; pred1 x y <-> x = y

答案 1 :(得分:0)

我在另一个练习中发现,可以在函数的输出上打开match子句。在这种情况下,它是“基础”中的“ evenb”。在这种情况下,请尝试“ eqb”。

答案 2 :(得分:0)

好吧,由于v在比赛中不起作用,我想也许我可以问一下列表的开头是否等于v。是的,它奏效了。这是代码:

Fixpoint count (v : nat) (s : bag) : nat :=
  match s with
  |  nil => 0
  |  x :: t => 
    match x =? v with 
    | true => S ( count v t )
    | false => count v t
    end
  end.