【Coq】01 Basics I 枚举类型 布尔值

数据和功能 Data and Functions I

枚举类型 Enumerated Types

Inductive day

以下声明告诉 Coq,我们正在定义一组数据值 - a type。

Inductive day : Type :=
  | monday
  | tuesday
  | wednesday
  | thursday
  | friday
  | saturday
  | sunday.

新 type 称为 day ,其成员为 monday、tuesday 等。 定义了 day 后,我们可以编写在 day 上操作的 function 。

Definition next_weekday

Definition next_weekday (d:day) : day :=
  match d with
  | monday ⇒ tuesday
  | tuesday ⇒ wednesday
  | wednesday ⇒ thursday
  | thursday ⇒ friday
  | friday ⇒ monday
  | saturday ⇒ monday
  | sunday ⇒ monday
  end.

需要注意的一点是,明确声明此函数的参数和返回类型。与大多数功能性编程语言一样,Coq 经常可以在未明确给出这些类型时自行找出这些类型(即它可以进行类型推理)但通常我们会将其包括在内,以便于阅读。
定义了一个 function 后,我们接下来应该检查它是否适用于某些示例。
实际上,在 Coq 中,有三种不同的方法可以做这些例子。

计算 Compute

首先,我们可以使用命令 Compute 来评估涉及 next_weekday 的复合表达。

Compute (next_weekday friday).
(* ==> monday : day *)
Compute (next_weekday (next_weekday saturday)).
(* ==> tuesday : day *)

示例 Example

其次,我们可以以 Coq Example 的形式记录我们期望的结果:

Example test_next_weekday:
  (next_weekday (next_weekday saturday)) = tuesday.

此声明有两件事:它做出断言( Saturday 之后的第二个工作日是 Tuesday),并且它给断言起一个名字,以后可以用来参考它。在做出断言后,我们还可以要求 Coq 这样验证它:

Proof. simpl. reflexivity. Qed.

提取 Extract

第三,我们可以要求 Coq 从我们的定义中提取另一种更传统的编程语言(OCaml、计划或哈斯克尔)中的程序,并配备高性能编译器。

家庭作业提交指南

不要改变划分练习的"标记":练习头、练习名称、末尾的"空方括号"标记等。请留下这个标记。
不要删除练习。如果您跳过练习(例如,因为它被标记为"可选",或者因为无法解决它),请确定在您的.v文件中留下部分证据。这种情况下,请确保它以 Admitted 结束(而不是,例如 Abort)。
在解决方案中使用其他定义(帮助功能、有用的 Lemmas 等)是可以的。你可以把这些放在练习头和你被要求证明的定理之间。
如果你介绍一个帮手 Lemma ,你最终无法证明,因此用 Admitted 结束它,然后确保也用 Admitted 结束你使用它的主要定理,而不是Qed。

布尔值 Booleans

Inductive bool

以类似的方式,我们可以定义布尔值的标准类型 bool ,成员 true 和 false 。

Inductive bool : Type :=
  | true
  | false.

Definition negb

对 Booleans 的 Function 可以以与上述相同的方式定义:

Definition negb (b:bool) : bool :=
  match b with
  | true ⇒ false
  | false ⇒ true
  end.

Definition andb

Definition andb (b1:bool) (b2:bool) : bool :=
  match b1 with
  | true ⇒ b2
  | false ⇒ false
  end.

Definition orb

Definition orb (b1:bool) (b2:bool) : bool :=
  match b1 with
  | true ⇒ true
  | false ⇒ b2
  end.

(虽然我们在这里滚动我们自己的布尔值,以建立一切从零开始,Coq当然提供一个默认的布尔值的实施,以及许多有用的 Functions 和 Lemmas 。只要有可能,我们将命名我们自己的定义和定理,以便它们与标准库中的定义和定理完全一致。 最后两个说明了 Coq 的多参数函数定义语法。相应的多参数应用语法由以下"单位测试"说明,该测试构成了 orb 函数的完整规范 (真值表):

Example test_orb1: (orb true false) = true.
Proof. simpl. reflexivity. Qed.
Example test_orb2: (orb false false) = false.
Proof. simpl. reflexivity. Qed.
Example test_orb3: (orb false true) = true.
Proof. simpl. reflexivity. Qed.
Example test_orb4: (orb true true) = true.
Proof. simpl. reflexivity. Qed.

符号 Notation

我们还可以介绍一些熟悉的固定语法,我们刚刚定义的布尔值操作。 Notation 命令为现有定义定义了新的符号符号。

Notation "x && y" := (andb x y).
Notation "x || y" := (orb x y).
Example test_orb5: false || false || true = true.
Proof. simpl. reflexivity. Qed.

Notation 说明:在.v文件,我们使用方括号在注释中划定 Coq 代码的片段;此公约也由coqdoc文档工具使用,使其在视觉上与周围的文本保持独立。在 HTML 版本的文件中,这些文本以不同的字体显示。
这些示例也是引入 Coq 编程语言的又一个小功能的机会:有条件表达式。

有条件表达式 Conditional Expressions

Definition negb' (b:bool) : bool :=
  if b then false
  else true.
Definition andb' (b1:bool) (b2:bool) : bool :=
  if b1 then b2
  else false.
Definition orb' (b1:bool) (b2:bool) : bool :=
  if b1 then true
  else b2.

Coq 的条件与任何其他语言中的条件完全一样,具有一个小概括。由于bool类型不是内置的,Coq 实际上支持有条件的表达方式,而不是任何具有电感定义的类型,其定义中正好有两个子句。如果保护者对 Inductive 定义第一条款的"构造者"进行评估(在这种情况下恰好被称为 true ),则该护卫被视为 true ,如果对第二个条款进行评估则被视为 false 。

练习 Exercise

1: 1 star, standard (nandb)

命令 Admitted 可用作不完整证据的占位符。我们在练习中使用它来指示我们要留给你的部分 - 即, 你的工作是用真实的 Proofs 来取代 Admitted 。 删除" Admitted ",并完成以下功能的定义:然后确保以下 Examples 断言可以由 Coq 验证。(即,按照上面的 orb 测试模型填写每个证明,并确保 Coq 接受它。如果其中一项或两项输入都是 false 的,则该函数应返回 true 。

Definition nandb (b1:bool) (b2:bool) : bool
  (* REPLACE THIS LINE WITH ":= _your_definition_ ." *). Admitted.
Example test_nandb1: (nandb true false) = true.
(* FILL IN HERE *) Admitted.
Example test_nandb2: (nandb false false) = true.
(* FILL IN HERE *) Admitted.
Example test_nandb3: (nandb false true) = true.
(* FILL IN HERE *) Admitted.
Example test_nandb4: (nandb true true) = false.
(* FILL IN HERE *) Admitted.

Coq代码

Definition nandb (b1:bool) (b2:bool) : bool 
:= 
if andb b1 b2 then false
else true.

Coq运行截图

2: 1 star, standard (andb3)

对下面的 andb3 功能也做同样的操作。当所有输入都是 true 的时候返回 true,否则这个功能应该会返回 false 。

Definition andb3 (b1:bool) (b2:bool) (b3:bool) : bool
  (* REPLACE THIS LINE WITH ":= _your_definition_ ." *). Admitted.
Example test_andb31: (andb3 true true true) = true.
(* FILL IN HERE *) Admitted.
Example test_andb32: (andb3 false true true) = false.
(* FILL IN HERE *) Admitted.
Example test_andb33: (andb3 true false true) = false.
(* FILL IN HERE *) Admitted.
Example test_andb34: (andb3 true true false) = false.
(* FILL IN HERE *) Admitted.

Coq代码

Definition andb3 (b1:bool) (b2:bool) (b3:bool) : bool
:=
if andb(andb b1 b2) b3 then true
else false.

Coq运行截图
图片说明

【学习】函数语言程序设计 文章被收录于专栏

函数语言程序设计 Coq章节 Ch1 Basics【COQ中的函数编程】 Ch2 Induction【归纳法证明】 Ch3 Lists【使用结构化数据】 Ch4 Poly【多态性与高阶函数】 Ch5 Tactics【更基本的战术】 Ch6 Logic【COQ中的逻辑】 Ch7 IndProp【归纳定义命题】 Ch8 Maps【全图和局部图】 Ch9 Rel【关系的性质】

全部评论

相关推荐

评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务