software foundations LF Basics

更多内容见 https://github.com/january147/software_foundations_notes

原始章节参考 Software Foundations (upenn.edu)

Coq

Coq’s native functional programming language, called Gallina.

注释

(* 注释内容 * )

分隔符

Coq使用.(英文句号)来分隔表达式。

显示类型

使用Check关键字来检查一个表达式的类型

Check true.

定义类型

enumerated types

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

使用已有类型定义新类型

Inductive rgb : Type :=
	| red
	| green
	| blue.

Inductive color : Type :=
	| black
	| white
	| primary (p:rgb)

red, green, blue, black等等被称为constructor,给constructor设置所需的参数(可以没有参数)就得到一个constructor expression, 参数也是constructor expression。

red 					(* constructor *)
red 					(* 无参数的constructor expression *)
primary red				(* 有参数的constructor expression *)

An Inductive definition carves out(分离) a subset of the whole space of constructor expressions and gives it a name, like bool, rgb, or color.

Definition monochrome (c : color) : bool :=
  match c with
  | black ⇒ true
  | white ⇒ true
  | primary p ⇒ false
  end.

Definition isred (c : color) : bool :=
  match c with
  | black ⇒ false
  | white ⇒ false
  | primary red ⇒ true
  | primary _ ⇒ false
  end.

Since the primary constructor takes an argument, a pattern matching primary should include either a variable (as above – note that we can choose its name freely) or a constant of appropriate type.

The pattern “primary _” here is shorthand for “the constructor primary applied to any rgb constructor except red.” (The wildcard pattern _ has the same effect as the dummy pattern variable p in the definition of monochrome.)

定义函数

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

计算函数结果

使用Compute关键字可以计算并输出一个函数执行结果

Compute (next_weekay tuesday).

定义模块

Module TestModule.
	Definition b : rgb := blue.
End TestModule.

元组(Tuples)

使用接收多个参数的constructor可以定义一个元组

Inductive bit : Type :=
  | B0
  | B1.
Inductive nybble : Type :=
  | bits (b0 b1 b2 b3 : bit).
Check (bits B1 B0 B1 B0)
    : nybble.
Definition all_zero (nb : nybble) : bool :=
  match nb with
    | (bits B0 B0 B0 B0) ⇒ true
    | (bits _ _ _ _) ⇒ false
  end.

We use underscore (_) as a wildcard pattern

使用递归定义的函数

Fixpoint evenb (n:nat) : bool :=
  match n with
  | O ⇒ true
  | S O ⇒ false
  | S (S n') ⇒ evenb n'
  end.

For most interesting computations involving numbers, simple pattern matching is not enough: we also need recursion. For example, to check that a number n is even, we may need to recursively check whether n-2 is even. Such functions are introduced with the keyword Fixpoint instead of Definition.

使用 Notion进行简化

使用Notion可以定义函数的简化表示

Notation "x + y" := (plus x y)
                       (at level 50, left associativity)
                       : nat_scope.

证明

Proof by Simplification

使用Example来定义一个证明目标,使用Proof开始一段证明,使用Qed表示证明结束。

(* 定义子目标 *)
Example test_next_weekday:
  (next_weekday (next_weekday saturday)) = tuesday.

Proof. simpl. reflexivity. Qed.

simpl, reflexivity被称为tactic,tactic是用于描述证明流程的命令,通过组合使用tactic来实现对目标的证明。simpl

还可以使用Theorem来定义一个证明目标

Theorem plus_O_n : forall n : nat, 0 + n = n.
Proof.
  intros m. reflexivity. Qed.

First, we’ve used the keyword Theorem instead of Example. This difference is mostly a matter of style; the keywords Example and Theorem (and a few others, including Lemma, Fact, and Remark) mean pretty much the same thing to Coq.

Proof by Rewrite

通常使用simpl化简时,coq会根据各个运算的定义进行展开,而使用rewrite可以让coq根据已有的假设或者定理对目标进行中匹配的部分进行改写。

Theorem mult_n_1 : forall p : nat,
  p * 1 = p.
Proof.
  intros p.
  (** 此处目标为 p * (S O) = p, 注意1 = S O
  	  定理 mult_n_Sm为 n * m + n = n * (S m), 目标中有同该定理匹配的
  	  部分(即p * (S O) 匹配 n * (S m)),因此可以用rewrite改写为左边得
  	  到 p * O + p = p *)
  rewrite <- mult_n_Sm.
  (** 此处目标为 p * O + p = p,
      定理 mult_n_O为 O = n * O, 目标中有同该定理匹配的
      部分(即p * O 匹配 n * O),因此可以用rewrite改写为左边得
      到 O + p = p *)
  rewrite <- mult_n_O.
  (** 根据 + 的定义化简即可)
  simpl.
  reflexivity.
  Qed.

Proof by Case analysis

使用destruct对变量进行分类讨论。destruct会生成子目标以及对应每个目标的新假设, 使用eqn:E,可以将子目标中的新假设命名为E

Theorem andb_true_elim2 : forall b c : bool,
  andb b c = true -> c = true.
Proof.
  intros b c. destruct c eqn:Ec.
  (* 子目标1,将假设c = true命名为Ec*)
  -intros H.
  reflexivity.
  (* 子目标2,将假设c = false命名为Ec*)
  -destruct b eqn:Eb.
  --intros G.
    rewrite <- G.
    reflexivity.
  --intros G2.
    rewrite <- G2.
    reflexivity.
Qed.

destruct按照变量的定义方式来分解变量的,例如对于bool类型,

Inductive bool : Type :=
  | true
  | false.

destruct会将变量分解为truefalse两种情况;对于nat类型

Inductive nat : Type :=
  | O
  | S (n : nat).

则会将变量分解为O以及S n两种情况。

tactics

intros

可以使用intros引入一个变量或者假设,intros会按照目标中定义的各个变量和假设的顺序进行引入

Theorem t1 : forall n m : nat, n = m -> n + n = m + m.
Proof.
(* 按照顺序,首先引入变量n,其次为m *)
intros n m.
(* 按照顺序,接着引入n = m的假设条件 *)
intros H.
...

If there are universally quantified variables in the goal (i.e. forall), you can introduce those variables into the context using the intros tactic. You can also use intros to introduce all propositions on the left side of an implication as assumptions.

reflexivity

If the goal contains an equality that looks obviously true, the reflexivity tactic can finish off the proof, doing some basic simplification if needed.

rewrite

使用假设中的关系重写目标等式。

Theorem t1 : forall n m : nat, n = m -> n + n = m + m.
Proof.
intros n m.
intros H.
(* 使用假设H来重写目标n+n = m+m,其中->表示匹配假设H中等式的左端并重写为其右端, <-则相反*)
rewrite -> H.
...

destruct

使用destruct对变量进行分类讨论

Theorem plus_1_neq_0 : ∀ n : nat,
  (n + 1) =? 0 = false.
Proof.
  intros n. destruct n as [| n'] eqn:E.
  - reflexivity.
  - reflexivity. 
Qed.

Admitted

不进行证明,告诉coq此目标是正确的。多用于先定义小目标,利用小目标在顶层证明最终目标,然后再分别证明小目标。

函数式编程语言OCaml, Scheme, Haskell

Software Foundations (upenn.edu)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值