Lecture notes 20190226
Introduction
What is this course about?
Sample program 1.
struct list {unsigned int head; struct list *tail;}; unsigned int sumlist (struct list * t) { unsigned int s = 0; struct list * t2; if (t == NULL) return 0; t2 = t -> tail; while (t) { s = s + (t->head); t = t2; t2 = t->tail; } return s; }
Sample program 2.
int binary_search (int L, int R) { int m; while (L < R) { m = (L + R) / 2; if (test(m)) { L = m; } else { R = m; } } return L; }
Sample program 2'.
\\ test(m) is true when m is too small \\ test(m) is false when m is OK or too large int binary_search (int L, int R) { int m; while (L < R) { m = (L + R) / 2; if (test(m)) { L = m + 1; } else { R = m; } } return L; }
Sample program 3.
void swap_int (int * L, int * R) { * L = ( * L ) + ( * R ); * R = ( * L ) - ( * R ); * L = ( * L ) - ( * R ); }
If an exceptional condition occurs during the evaluation of an expression (that is, if the result is not mathematically defined or not in the range of representable values for its type), the behavior is undefined.
Terminology
How will this course be taught?
Course material
Course grade
Office hour
One more thing: a Coq demo
Require Import Setoid.
Coq is a proof management tool—-it is designed to help researchers write
math definitions and strict math proofs. For example, the following theorem
might be the first proof that students will learn in an abstract algebra course.
First, a group contains an underlying set A with a unit element, a binary
operator (addition) and a unary operator (negation). They are usually rewriten
as (A, 0, +, -).
Section Group.
Variable A: Type.
Variable z: A.
Variable add: A → A → A.
Variable neg: A → A.
Notation "x + y" := (add x y).
Notation "- x" := (neg x).
Notation "0" := z.
Variable A: Type.
Variable z: A.
Variable add: A → A → A.
Variable neg: A → A.
Notation "x + y" := (add x y).
Notation "- x" := (neg x).
Notation "0" := z.
Such quadruple is called a group if it satisfies associativity, the left
unit property and the left inversion property.
Hypothesis assoc: ∀(x y z: A), (x + y) + z = x + (y + z).
Hypothesis left_unit: ∀(x: A), 0 + x = x.
Hypothesis left_inv: ∀(x: A), (- x) + x = 0.
Hypothesis left_unit: ∀(x: A), 0 + x = x.
Hypothesis left_inv: ∀(x: A), (- x) + x = 0.
Then we prove that such a group must have the right inversion property and
the right unit property.
Keywords "Theorem", "Lemma" and "Corollary" indicates the beginning of a
theorem statement. Users should write proof scripts inside a "Proof-Qed" block.
Theorem right_inv: ∀(x: A), x + (- x) = 0.
Proof.
Proof.
In the proof mode, you can always see a proof goal (or proof goals) on the
right side windows of your IDE. For example, you can see a proof goal now.
Every tactic will reduce a proof goal into zero, one, or more proof goals.
For example, a Coq proof script usually starts with "intros".
intros.
Then "rewrite" can be used to turn an expression into an equivalent one.
rewrite <- left_unit with (x := (x + - x)).
rewrite <- left_inv with (x := - x) at 1.
rewrite → assoc.
rewrite <- assoc with (x := -x).
rewrite left_inv.
rewrite left_unit.
rewrite left_inv.
rewrite <- left_inv with (x := - x) at 1.
rewrite → assoc.
rewrite <- assoc with (x := -x).
rewrite left_inv.
rewrite left_unit.
rewrite left_inv.
In the end, we use "reflexivity" to complete the proof since equlity is
reflexive.
reflexivity.
Qed.
Qed.
Here is another proof.
Theorem right_unit: ∀(x: A), x + 0 = x.
Proof.
intros.
rewrite <- left_inv with (x := x).
rewrite <- assoc.
Proof.
intros.
rewrite <- left_inv with (x := x).
rewrite <- assoc.
We can not only use hypothesis but also proved theorems when proving new
theorems. We just proved right_inv; now we use it.
rewrite right_inv.
rewrite left_unit.
reflexivity.
Qed.
End Group.
(* Thu Feb 28 18:49:10 CST 2019 *)
rewrite left_unit.
reflexivity.
Qed.
End Group.
(* Thu Feb 28 18:49:10 CST 2019 *)