From mathcomp Require Import all_ssreflect. Set Implicit Arguments. Unset Strict Implicit. Unset Printing Implicit Defensive. (** ---------------------------------------------------------- #
# ** Lesson 3: summary - proofs by backchaining/backward reasoning - proofs by induction - stack model, tacticials [=>] and [:] - operations on the stack #


# #

# ---------------------------------------------------------- #
# ** Proofs by backward chaining - [move=> names] introduces hypotheses in the context. - [apply: term] does backward reasoning. #
# *) Lemma example m p : prime p -> p %| m `! + 1 -> m < p. Proof. move=> prime_p. (* Search "contra". *) apply: contraLR. rewrite -leqNgt. move=> leq_p_m. rewrite dvdn_addr. by rewrite gtnNdvd // prime_gt1. (* Search _ dvdn factorial.*) apply: dvdn_fact. by rewrite leq_p_m prime_gt0. Qed. (** #
# Remark [dvdn_addr] has a side condition. Remark [rewrite] accepts - many rewrite rules, - the minus switch [-] to rewrite right to left, - [//] to solve simple goals, - [/=] to call the simplification heuristic, - [/name] to unfold definition [name], - [{x}] to clear [x] from the context. cf #ssreflect documentation on rewrite# Remark [n <= m <= p] is [n <= m && m <= p]. #
(notes)
# This slide corresponds to section 2.3.3 of #the Mathematical Components book# #
# #


# #

# ---------------------------------------------------------- #
# ** Proofs by induction The [elim:] tactic is like [case:] but gives you an induction hypothesis. #
# *) Lemma addn0 m : m + 0 = m. Proof. elim: m => [|m IHm]. by []. by rewrite addSn IHm. Qed. Lemma muln0 m : m * 0 = 0. Proof. elim: m => [|m IHm]. by []. by rewrite mulSn IHm. Qed. (** #
# The first pitfall when proving programs by induction is not generalizing enough the property being proved before starting the induction. #
# *) Lemma foldl_cat T R f (z0 : R) (s1 s2 : seq T) : foldl f z0 (s1 ++ s2) = foldl f (foldl f z0 s1) s2. Proof. move: z0. elim: s1. by []. move=> x xs IH. move=> acc. rewrite /=. by rewrite IH. Qed. (** #
# #
(notes)
# This slide corresponds to section 2.3.4 of #the Mathematical Components book# #
# #


# #

# ---------------------------------------------------------- #
# ** Goal management - naming everything can become bothersome - but, we should not let the system give random names - we adopt some sort of "stack & heap" model *** The stack model of a goal #
# #
#
ci : Ti
…
dj := ej : Tj
…
Fk : Pk ci
…
=================
forall (xl : Tl) …,
let ym := bm in … in
Pn xl -> … ->
Conclusion
#
# #
# #
# *) Axiom (Ti Tj Tl : Type) (ej bm : Tj). Axiom (Pk : Ti -> Type) (Pn : Tl -> Type). Axiom (Conclusion : Ti -> Tj -> Tj -> Tl -> Type). Lemma goal_model_example (ci : Ti) (dj : Tj := ej) (Fk : Pk ci) : forall (xl : Tl), let ym := bm in Pn xl -> Conclusion ci dj ym xl. Abort. (** #
# #
(notes)
# This slide corresponds to section #Bookkeeping# of the online docmentation of the ssreflect proof language. #
# #


# #

# ---------------------------------------------------------- #
# *** Managing the stack - [tactic=> names] executes tactics, pops and names - [tactic: names] pushes the named objects, then execute tactic - [move] is the tactic that does nothing (no-op, [idtac]) #
# *) Lemma goal_model_example (ci : Ti) (dj : Tj := ej) (Fk : Pk ci) : forall (xl : Tl), let ym := bm in Pn xl -> Conclusion ci dj ym xl. Proof. move=> xl ym pnxl. move: ci Fk. Abort. (** #
# #
(notes)
# #
# #


# #

# ---------------------------------------------------------- #
# ** intro-pattern and discharge partterns You can write - [tactic=> i_items] where i_item could be a name, or - [?] name chosen by the system, no user access, - [_] remove the top of the stack (if possible), - [//] close trivial subgoals, - [/=] perform simplifications, - [//=] do both the previous, - [->] rewrite using the top of the stack, left to right, - [<-] same but right to left, - [{x}] clear name [x] from the context. - [ [i_items|..|i_items] ] introductions on various sub-goals when immediately [tactic] is [case] or [elim] cf #ssreflect documentation on introduction to the context# - [tactic: d_items] where d_item could be a name or a pattern, and - [tactic] must be [move], [case], [elim], [apply], [exact] or [congr], - [move: name] clears the name from the context, - [move: pattern] generalize a subterm of the goal that match the pattern, - [move: (name)] forces [name] to be a pattern, hence not clearing it. cf #ssreflect documentation on discharge# #


# #

# ---------------------------------------------------------- #
# ** Example #
# *) Lemma goal_model_example (ci : Ti) (dj : Tj := ej) (Fk : Pk ci) : forall (xl : Tl), let ym := bm in Pn xl -> Conclusion ci dj ym xl. Proof. move=> xl /= pnxl. Fail move=> {xl}. Fail move=> {dj}. rewrite /dj {dj}. move: ci Fk. move=> {pnxl}. move=> ci _. Abort. (** #
# #


# #

# ---------------------------------------------------------- #
# ** elim and case work on the top of the stack [elim: x y z => [t u v | w] ] is the same as - [move: x y z.] - [elim.] - [move=> t u v.] in one sub-goal, [move=> w.] in the other. #
# *) Lemma addnA m n p : m + (n + p) = (m + n) + p. Proof. by elim: m => // m IHm; rewrite !addSn IHm. Restart. Proof. by elim: m => // m; rewrite !addSn => ->. Qed. Lemma subnDA m n p : n - (m + p) = (n - m) - p. Proof. by move: m n; elim=> [//|m IHm]; case. Restart. Proof. by elim: m n => [|m IHm] []. Qed. Lemma andbC : commutative andb. Proof. move=> b1 b2; case: b1; case: b2. Restart. Proof. by case; case. Restart. Proof. by move=> [] []. Qed. (** #
# #


# #

# ---------------------------------------------------------- #
# ** Example of [foldl_cat] #
# *) Lemma foldl_cat' T R f (z0 : R) (s1 s2 : seq T) : foldl f z0 (s1 ++ s2) = foldl f (foldl f z0 s1) s2. Proof. move: s1 z0. elim. done. move=> x xs IH. move=> acc. rewrite /=. by rewrite IH. Restart. Proof. by elim: s1 z0 => [//|x xs IH] acc /=; rewrite IH. Qed. (** #
# #


# #

# ---------------------------------------------------------- #
# ** Lesson 3: sum up - [rewrite] takes many arguments - [apply: t] backward reasonning on the whole goal - [=>] is pop to context and [:] is push - [case] case analysis on the top of the stack - [elim] induction on the top of the stack #
# *)