在Coq';s函数式编程语言?
我试图计算Coq中在Coq';s函数式编程语言?,coq,Coq,我试图计算Coq中natlist/bag中元素v的出现次数。我试过: Fixpoint count (v:nat) (s:bag) : nat := match s with | nil => 0 | h :: tl => match h with | v => 1 + (count v tl) end end. 但是,我的证明不起作用: Example test_count1:
natlist/bag
中元素v
的出现次数。我试过:
Fixpoint count (v:nat) (s:bag) : nat :=
match s with
| nil => 0
| h :: tl => match h with
| v => 1 + (count v tl)
end
end.
但是,我的证明不起作用:
Example test_count1: count 1 [1;2;3;1;4;1] = 3.
Proof. simpl. reflexivity. Qed.
为什么第一段代码不起作用?当v
不匹配时,它在做什么
我还尝试:
Fixpoint count (v:nat) (s:bag) : nat :=
match s with
| nil => 0
| h :: tl => match h with
| v => 1 + (count v tl)
| _ => count v tl
end
end.
但这也给了Coq一个错误,我甚至不能运行它
函数式编程对我来说有点陌生,所以我不知道如何用Coq来表达它。我真的只想说如果h
匹配v
,那么执行a+1递归,否则只递归(即,我猜加零)
有没有一种简单的方法可以用Coq的函数式编程语言来表达这一点
我之所以问这个问题,是因为我觉得match与“普通”Python编程中的if-else语句非常相似。因此,要么我错过了函数式编程的要点,要么是什么。这是我所关心的主要问题,我想是隐式的。您试图编写的
match
语句实际上只是在v
变量后面添加了一个新变量,也称为v
,它只包含h
的一个副本
为了测试两个自然数是否相等,您可以使用Nat.eqb
,它返回一个bool
值,然后您可以对该值进行匹配:
Require Import Arith.
Fixpoint count (v:nat) (s:bag) : nat :=
match s with
| nil => 0
| h :: tl => match Nat.eqb v h with
| true => 1 + (count v tl)
| false => count v tl
end
end.
<> P> > <代码> BoOL 值与<代码>真< /代码>或<代码>伪< /代码>,Coq也提供了函数-<代码>的语法糖> < < /Calp>/Cuth> Ethue/Cuth>构造(这非常像三元<代码>:< /Cord> C或C++的运算符,如果你熟悉其中任一个):
(实际上,if
与任何归纳类型一起工作时正好有两个构造函数:然后第一个构造函数转到if
分支,第二个构造函数转到else
分支。然而,list
类型的第一个构造函数是nil
,第二个构造函数是cons
构造函数:因此,即使从技术上讲,您可以编写一个包含列表的if
语句来测试空性或非空性,它最终也会与您可能期望的工作方式相反。)
但是,一般来说,对于泛型类型,不一定有一种方法来决定该类型的两个成员是否相等,因为在Nat
的情况下有Nat.eqb
。因此,如果您想编写一个可以适用于更一般类型的count
的泛化,您必须接受一个argument指定相等决策过程。您试图编写的match
语句实际上只是用一个新变量(也称为v
)来隐藏v
变量,该变量只包含h
的副本
为了测试两个自然数是否相等,您可以使用Nat.eqb
,它返回一个bool
值,然后您可以对该值进行匹配:
Require Import Arith.
Fixpoint count (v:nat) (s:bag) : nat :=
match s with
| nil => 0
| h :: tl => match Nat.eqb v h with
| true => 1 + (count v tl)
| false => count v tl
end
end.
<> P> > <代码> BoOL 值与<代码>真< /代码>或<代码>伪< /代码>,Coq也提供了函数-<代码>的语法糖> < < /Calp>/Cuth> Ethue/Cuth>构造(这非常像三元<代码>:< /Cord> C或C++的运算符,如果你熟悉其中任一个):
(实际上,if
与任何归纳类型一起工作时正好有两个构造函数:然后第一个构造函数转到if
分支,第二个构造函数转到else
分支。然而,list
类型的第一个构造函数是nil
,第二个构造函数是cons
构造函数:因此,即使从技术上讲,您可以编写一个包含列表的if
语句来测试空性或非空性,它最终也会与您可能期望的工作方式相反。)
但是,一般来说,对于泛型类型,不一定有一种方法来决定该类型的两个成员是否相等,因为在Nat
的情况下有Nat.eqb
。因此,如果您想编写一个可以适用于更一般类型的count
的泛化,您必须接受一个argument指定平等决策程序。(这与Daniel的答案类似,但我已经写了大部分)
您的问题是,在此代码中:
match h with
| v => 1 + (count v tl)
end
与v
匹配将绑定一个新变量v
。要测试h
是否等于v
,必须使用一些决策过程来测试自然数的相等性
例如,您可以使用Nat.eqb
,它接受两个自然数并返回一个bool
,指示它们是否相等
Require Import Nat.
Fixpoint count (v:nat) (s:bag) : nat :=
match s with
| nil => 0
| h :: tl => if (eqb h v) then (1 + count v t1) else (count v t1)
end.
为什么我们不能简单地匹配我们想要的术语呢?模式匹配总是匹配类型的构造函数。在这段代码中,外部匹配语句匹配nil
和h::t1
(这是cons h t1
或类似的符号,取决于bag
的精确定义).在匹配语句中,如
match n with
| 0 => (* something *)
| S n => (* something else *)
end.
我们在nat
的构造函数上进行匹配:0
和S
在原始代码中,您尝试匹配v
,它不是构造函数,因此Coq只需绑定一个新变量并调用它v
(这与Daniel的答案类似,但我已经编写了大部分)
您的问题是,在此代码中:
match h with
| v => 1 + (count v tl)
end
与v
匹配将绑定一个新变量v
。要测试h
是否等于v
,必须使用一些决策过程来测试自然数的相等性
例如,您可以使用Nat.eqb
,它接受两个自然数并返回一个表示w的bool