Semantics of Hoare Logic Aquinas Hobor and Martin Henz.

Slides:



Advertisements
Similar presentations
Automated Theorem Proving Lecture 1. Program verification is undecidable! Given program P and specification S, does P satisfy S?
Advertisements

With examples from Number Theory
In this episode of The Verification Corner, Rustan Leino talks about Loop Invariants. He gives a brief summary of the theoretical foundations and shows.
Semantics Static semantics Dynamic semantics attribute grammars
Chapter Three: Closure Properties for Regular Languages
Q1 Review. Other News US News top CS Universities global-universities/computer- science?int=994b08.
CML CML CS 230: Computer Organization and Assembly Language Aviral Shrivastava Department of Computer Science and Engineering School of Computing and Informatics.
Reasoning About Code; Hoare Logic, continued
Hoare’s Correctness Triplets Dijkstra’s Predicate Transformers
Rigorous Software Development CSCI-GA Instructor: Thomas Wies Spring 2012 Lecture 11.
This Week Finish relational semantics Hoare logic Interlude on one-point rule Building formulas from programs.
Proofs, Recursion and Analysis of Algorithms Mathematical Structures for Computer Science Chapter 2 Copyright © 2006 W.H. Freeman & Co.MSCS SlidesProofs,
Chapter 8 Representing Information Digitally.
Lecture # 20 Type Systems. 2 A type system defines a set of types and rules to assign types to programming language constructs Informal type system rules,
Copyright © 2006 Addison-Wesley. All rights reserved.1-1 ICS 410: Programming Languages Chapter 3 : Describing Syntax and Semantics Axiomatic Semantics.
ISBN Chapter 3 Describing Syntax and Semantics.
1 Semantic Description of Programming languages. 2 Static versus Dynamic Semantics n Static Semantics represents legal forms of programs that cannot be.
1/22 Programs : Semantics and Verification Charngki PSWLAB Programs: Semantics and Verification Mordechai Ben-Ari Mathematical Logic for Computer.
1 Conditional XPath, the first order complete XPath dialect Maarten Marx Presented by: Einav Bar-Ner.
Comp 205: Comparative Programming Languages Semantics of Imperative Programming Languages denotational semantics operational semantics logical semantics.
Proof Points Key ideas when proving mathematical ideas.
CSE115/ENGR160 Discrete Mathematics 04/12/11 Ming-Hsuan Yang UC Merced 1.
Software Engineering: Where are we? And where do we go from here? V Software Engineering Lecture 23 Clark Barrett New York University 4/17/2006.
Induction Sections 41. and 4.2 of Rosen Fall 2008 CSCE 235 Introduction to Discrete Structures Course web-page: cse.unl.edu/~cse235 Questions:
Denotational Semantics Syntax-directed approach, generalization of attribute grammars: –Define context-free abstract syntax –Specify syntactic categories.
Discrete Mathematics Lecture 4 Harper Langston New York University.
ARIANE 5 FAILURE ► BACKGROUND:- ► European space agency’s re-useable launch vehicle. ► Ariane-4 was a major success ► Ariane -5 was developed for the larger.
What makes a good language Does the task you want Keeps you from making mistakes Supports debugging when you need it Has a strong tool kit.
MinML: an idealized programming language CS 510 David Walker.
4/17/2017 Section 3.6 Program Correctness ch3.6.
Operational Semantics Semantics with Applications Chapter 2 H. Nielson and F. Nielson
Describing Syntax and Semantics
Administrivia First pieces of assignment 5 Comments about assignment 5 Assignment 6 Labs 5 and 6.
Algorithm Design and Analysis (ADA)
Scientific Computing Algorithm Convergence and Root Finding Methods.
Created by, Author Name, School Name—State FLUENCY WITH INFORMATION TECNOLOGY Skills, Concepts, and Capabilities.
Reading and Writing Mathematical Proofs
Chapter 3 (Part 3): Mathematical Reasoning, Induction & Recursion  Recursive Algorithms (3.5)  Program Correctness (3.6)
1 Inference Rules and Proofs (Z); Program Specification and Verification Inference Rules and Proofs (Z); Program Specification and Verification.
CSC201 Analysis and Design of Algorithms Asst.Proof.Dr.Surasak Mungsing Oct-151 Lecture 2: Definition of algorithm and Mathematical.
Pushdown Automata (PDAs)
Chapter 25 Formal Methods Formal methods Specify program using math Develop program using math Prove program matches specification using.
Semester Review. As we have discussed, Friday we will have in class time for you to work on a program, this program will come with instructions and you.
Discrete Maths: Induction/1 1 Discrete Maths Objective – –to introduce mathematical induction through examples , Semester
CPS120: Introduction to Computer Science Decision Making in Programs.
CSE-490 Logic in Computer Science The Coq Proof Assistant POSTECH Dec 15, 2006 박성우.
Reading and Writing Mathematical Proofs Spring 2015 Lecture 4: Beyond Basic Induction.
Conditional Statement Chapter 8. Conditional Statements Are statements that check an expression then may or may not execute a statement or group of statement.
Operators Precedence - Operators with the highest precedence will be executed first. Page 54 of the book and Appendix B list C's operator precedence. Parenthesis.
CS Introduction to AI Tutorial 8 Resolution Tutorial 8 Resolution.
Recursive Algorithms &
Chapter 3 Part II Describing Syntax and Semantics.
I Power Higher Computing Software Development High Level Language Constructs.
CSE Winter 2008 Introduction to Program Verification January 31 proofs through simplification.
Using Loops. Goals Understand how to create while loops in JavaScript. Understand how to create do/while loops in JavaScript. Understand how to create.
13 Aug 2013 Program Verification. Proofs about Programs Why make you study logic? Why make you do proofs? Because we want to prove properties of programs.
Copyright © Curt Hill Proofs An Introduction.
1 INFO 2950 Prof. Carla Gomes Module Induction Rosen, Chapter 4.
Static Techniques for V&V. Hierarchy of V&V techniques Static Analysis V&V Dynamic Techniques Model Checking Simulation Symbolic Execution Testing Informal.
CSC3315 (Spring 2009)1 CSC 3315 Languages & Compilers Hamid Harroud School of Science and Engineering, Akhawayn University
C HAPTER 3 Describing Syntax and Semantics. D YNAMIC S EMANTICS Describing syntax is relatively simple There is no single widely acceptable notation or.
1 Interactive Computer Theorem Proving CS294-9 October 19, 2006 Adam Chlipala UC Berkeley Lecture 9: Beyond Primitive Recursion.
Lecture 11: Proof by Reflection
Fault Tolerant Computing
Control Structures – Selection
Copyright © Cengage Learning. All rights reserved.
Programming Languages and Compilers (CS 421)
Computer Organization COMP 210
Program correctness Axiomatic semantics
Programming Languages and Compilers (CS 421)
Presentation transcript:

Semantics of Hoare Logic Aquinas Hobor and Martin Henz

What does a Hoare tuple mean? { Á } P { Ã } Informal meaning (already given): “If the program P is run in a state that satisfies Á and P terminates, then the state resulting from P’s execution will satisfy Ã.” 2

We would like to formalize { Á } P { Ã } Informal meaning (already given): “If the program P is run in a state that satisfies Á and P terminates, then the state resulting from P’s execution will satisfy Ã.” 3

We would like to formalize { Á } P { Ã } Need to define: 1.Running a program P 2.P terminates 3.State satisfies Á 4.Resulting state satisfies Ã. 4

We would like to formalize { Á } P { Ã } For better clarity and “fun”, we will do it in Coq. 5

We would like to formalize { Á } P { Ã } For better clarity and “fun”, we will do it in Coq. (And by “we”, I mean I will do part of it in class and you will do the rest at home…) 6

We would like to formalize { Á } P { Ã } Need to define: 1.Running a program P 2.P terminates 3.State satisfies Á 4.Resulting state satisfies Ã. 7

Operational Semantics Numeric Expressions E: – n | x | (−E) | (E + E) | (E − E) | (E ∗ E) Boolean Expressions B: – true | false | (!B) | (B&B) | (B||B) | (E < E) Commands C: – x = E | C;C | if B {C} else {C} | while B {C} 8

We have to specify exactly how each evaluates Numeric Expressions E: – n | x | (−E) | (E + E) | (E − E) | (E ∗ E) First problem: what are our variables “x”? We will use our usual trick of letting variables be natural numbers: Definition var : Type := nat. 9

We have to specify exactly how each evaluates Numeric Expressions E: – n | x | (−E) | (E + E) | (E − E) | (E ∗ E) Next: how do we define our expressions? Definition num : Type := Z. Inductive nExpr : Type := | Num: forall n : num, nExpr | Var: forall v : var, nExpr | Neg: forall ne : nExpr, nExpr | Plus: forall ne1 ne2 : nExpr, nExpr | Minus: forall ne1 ne2 : nExpr, nExpr | Times: forall ne1 ne2 : nExpr, nExpr. 10

We have to specify exactly how each evaluates Numeric Expressions E: – n | x | (−E) | (E + E) | (E − E) | (E ∗ E) Now, what does evaluation of an E mean? We want to write E  n to mean “the expression E evaluates to the numeric n” But what about E = x? By itself, we don’t know what to do... 11

We have to specify exactly how each evaluates Numeric Expressions E: – n | x | (−E) | (E + E) | (E − E) | (E ∗ E) Define a context ° to be a function from variables to numbers. Definition ctx := var -> num. 12

We have to specify exactly how each evaluates Numeric Expressions E: – n | x | (−E) | (E + E) | (E − E) | (E ∗ E) Now define ° ` E  n to mean “in context °, the expression E evaluates to the numeric n.” 13

Numeric Evaluation in Coq Fixpoint neEval (g : ctx) (ne : nExpr) : num := match ne with | Num n => n | Var x => g x | Neg ne => 0 - (neEval g ne) | Plus ne1 ne2 => neEval g ne1) + (neEval g ne2) | Minus ne1 ne2 => (neEval g ne1) - (neEval g ne2) | Times ne1 ne2 => (neEval g ne1) * (neEval g ne2) end. 14

Boolean Expressions Boolean Expressions B: – true | false | (!B) | (B&B) | (B||B) | (E < E) Inductive bExpr : Type := | T : bExpr | F : bExpr | bNeg : forall be : bExpr, bExpr | And : forall be1 be2 : bExpr, bExpr | Or : forall be1 be2 : bExpr, bExpr | LT : forall ne1 ne2 : nExpr, bExpr. 15

Boolean Evaluation Boolean Expressions B: – true | false | (!B) | (B&B) | (B||B) | (E < E) Since B includes E, we will need contexts to evaluate Bs. What do we evaluate to? How about Prop. So define ° ` B  P to mean “in context °, the expression B evaluates to the proposition P.” 16

Boolean Evaluation Fixpoint beEval (g : ctx) (be : bExpr) : Prop := match be with | T => True | F => False | bNeg be => ~(beEval g be) | And be1 be2 => (beEval g be1) /\ (beEval g be2) | Or be1 be2 => (beEval g be1) \/ (beEval g be2) | LT ne1 ne2 => (neEval g ne1) < (neEval g ne2) end. 17

Commands Commands C: – x = E | C;C | if B {C} else {C} | while B {C} Inductive Coms : Type := | Assign : forall (x : var) (e: nExpr), Coms | Seq : forall c1 c2 : Coms, Coms | If : forall (b : bExpr) (c1 c2 : Coms), Coms | While : forall (b : bExpr) (c : Coms), Coms. 18

Command Evaluation Idea: executing command C for one step moves the machine from one state to the next What is a state ¾ ? Pair of context ° (data) and control k (code) Control k is either kStop (we are done) or kSeq C k – We can write C ² k for kSeq if that is easier – We can also write ¥ for kHalt 19

Controls and states in Coq Inductive ctl : Type := | kStop : ctl | kSeq : forall (c : Coms) (k : ctl), ctl. Definition state : Type := ctx * ctl. 20

Step relation, assign(a) We now define the step relation, written ¾ 1  ¾ 2 that is, “state ¾ 1 steps to state ¾ 2 ”, in parts: ° ` E  n ° ’ = [x ! n] ° ( °, (x = E) ² k)  ( ° ’, k) 21

Step relation, assign(b) ° ` E  n ° ’ = [x ! n] ° ( °, (x = E) ² k)  ( ° ’, k) | stepA: forall g x e n k g', n = neEval g e -> g' = upd_ctx g x n -> step (g, kSeq (Assign x e) k) (g', k) 22

Step relation, seq ( °, (C 1 ; C 2 ) ² k)  ( °, C 1 ² (C 2 ² k)) | stepS: forall g c1 c2 k, step (g, kSeq (Seq c1 c2) k) (g, kSeq c1 (kSeq c2 k)) 23

Step relation, if (a) ° ` B  True ( °, (if B then {C 1 } else {C 2 }) ² k)  ( °, C 1 ² k) | stepI1: forall g b c1 c2 k, beEval g b -> step (g, kSeq (If b c1 c2) k) (g, kSeq c1 k) 24

Step relation, if (b) ° ` B  False ( °, (if B then {C 1 } else {C 2 }) ² k)  ( °, C 2 ² k) | stepI2: forall g b c1 c2 k, ~beEval g b -> step (g, kSeq (If b c1 c2) k) (g, kSeq c2 k) 25

Step relation, while (a) ° ` B  True ( °, (while B {C}) ² k)  ( °, C ² (while B {C} ² k)) | stepW1: forall g b c k, beEval g b -> step (g, kSeq (While b c) k) (g, kSeq c (kSeq (While b c) k)) 26

Step relation, while (b) ° ` B  False ( °, (while B {C}) ² k)  ( °, k)) | stepW2: forall g b c k, ~beEval g b -> step (g, kSeq (While b c) k) (g, k) 27

Entire step relation ° ` E  n ° ’ = [x ! n] ° ( °, (x = E) ² k)  ( ° ’, k) ( °, (C 1 ; C 2 ) ² k)  ( °, C 1 ² (C 2 ² k)) ° ` B  True ( °, (if B then {C 1 } else {C 2 }) ² k)  ( °, C 1 ² k) ° ` B  False ( °, (if B then {C 1 } else {C 2 }) ² k)  ( °, C 2 ² k) ° ` B  True ( °, (while B {C}) ² k)  ( °, C ² (while B {C} ² k)) ° ` B  False ( °, (while B {C}) ² k)  ( °, k)) 28

Inductive step : state -> state -> Prop := | stepA: forall g x e k g', g' = upd_ctx g x (neEval g e) -> step (g, kSeq (Assign x e) k) (g', k) | stepS: forall g c1 c2 k, step (g, kSeq (Seq c1 c2) k) (g, kSeq c1 (kSeq c2 k)) | stepI1: forall g b c1 c2 k, beEval g b -> step (g, kSeq (If b c1 c2) k) (g, kSeq c1 k) | stepI2: forall g b c1 c2 k, ~beEval g b -> step (g, kSeq (If b c1 c2) k) (g, kSeq c2 k) | stepW1: forall g b c k, beEval g b -> step (g, kSeq (While b c) k) (g, kSeq c (kSeq (While b c) k)) | stepW2: forall g b c k, ~beEval g b -> step (g, kSeq (While b c) k) (g, k). 29

From step to step* Usually we want to run our program for more than one step. We write ¾  * ¾ ’ to mean that the state ¾ steps to the state ¾ ’ in some number of steps. 30

From step to step* ¾  * ¾ ¾  ¾ ’ ¾ ’  * ¾ ’’ ¾  * ¾ ’’ Inductive stepstar : state -> state -> Prop := | stepsZ: forall s, stepstar s s | stepsS: forall s s' s'', step s s' -> stepstar s' s'' -> stepstar s s''. 31

We would like to formalize { Á } P { Ã } Need to define: 1.Running a program P 2.P terminates 3.State satisfies Á 4.Resulting state satisfies Ã. 32

Halted; Terminates means eventually halted We say a state ( °, k) is halted when k = ¥ (* 20 points *) Lemma only_stuck_when_at_kStop: forall g k, (~ exists st', step (g, k) st') -> k = kStop. Proof. admit. Qed. ¾ terminates if 9 s’ such that ¾  * ¾ ’ and ¾ ’ is halted. 33

We would like to formalize { Á } P { Ã } Need to define: 1.Running a program P 2.P terminates 3.State satisfies Á 4.Resulting state satisfies Ã. 34

What is an assertion? We can do what we did for modal logic: Definition assertion : Type := ctx -> Prop. We can even write ° ² à as shorthand for à ( ° ) Thus, we can use the rules of our Coq metalogic to easily reason about our Hoare assertions. 35

Lifting Assertions to Metalogic 1 ° ² Á Æ Ã ´ ( ° ² Ã ) Æ ( ° ² Á ) Definition assertAnd (P Q : assertion) : assertion := fun g => P g /\ Q g. Notation "P && Q" := (assertAnd P Q). ° ² B ´ ° ` B  True Definition assertbEval (b : bExpr) : assertion := fun g => beEval g b. Notation "[ b ]" := (assertbEval b). 36

Lifting Assertions to Metalogic 2 ° ² [x ! e] Ã ´ [x ! n] ° ² Ã (where ° ` e  n) Definition assertReplace (x : var) (e : nExpr) (psi : assertion) : assertion := fun g => psi (upd_ctx g x (neEval g e)). Notation "[ x => psi ]" := (assertReplace x e psi). ` AR Á ! Ã ´ 8 °, ( ° ² Á ) ) ( ° ² Ã ) Definition Implies (P Q: assertion) : Prop := forall g, P g -> Q g. Notation "P |-- Q" := (Implies P Q) (at level 30). 37

We would like to formalize { Á } P { Ã } Need to define: 1.Running a program P 2.P terminates 3.State satisfies Á 4.Resulting state satisfies Ã. 38

Putting it all together { Ã } C { Á } ´ 8 °. ° ² Ã ) 8 ° ’. ( °, C ² ¥ )  * ( ° ’, ¥ ) ) ° ’ ² Á Definition HTuple (pre : assertion) (c : Coms) (post : assertion) : Prop := forall g, pre g -> forall g', stepstar (g, kSeq c kStop) (g', kStop) -> post g'. 39

Now what? Prove the Hoare rules as lemmas from definitions! { Ã } c 1 { Â } { Â } c 2 { Á } { Ã } c 1 ; c 2 { Á } Lemma HT_Seq: forall a1 c1 a2 c2 a3, HTuple a1 c1 a2 -> HTuple a2 c2 a3 -> HTuple a1 (Seq c1 c2) a3. 40

Assignment Rule {[x ! E] Ã } x = E { Ã } Lemma HT_Asgn: forall x e psi, HTuple [x => psi] (Assign x e) psi. 41

If Rule { Á Æ B} C 1 { Ã } { Á Æ : B} C 2 { Ã } { Á } if B {C 1 } else {C 2 } { Ã } Lemma HT_If: forall phi b c1 psi c2, HTuple (phi && [b]) c1 psi -> HTuple (phi && [bNeg b]) c2 psi -> HTuple phi (If b c1 c2) psi. 42

While Rule { Ã Æ B} C { Ã } { Ã } while B {C} { Ã Æ : B} Lemma HT_While: forall psi b c, HTuple (psi && [b]) c psi -> HTuple psi (While b c) (psi && [bNeg b]). 43

Implied Rule ` AR Á ’ ! Á { Á } C { Ã } ` AR Ã ! Ã ’ { Á ’} C { Ã ’} Lemma HT_Implied: forall phi phi' psi psi' c, phi' |-- phi -> HTuple phi c psi -> psi |-- psi' -> HTuple phi' c psi'. 44

Your task: Prove these lemmas HT_Seq : 10 points (with 20 extra credit if you solve the supporting lemma) HT_Asgn : 10 points HT_If : 10 points HT_Implied : 5 points HT_While : 40 points extra credit (good luck!) 45

Finally Definition x : var := 0. Definition y : var := 1. Definition z : var := 2. Open Local Scope Z_scope. Definition neq (ne1 ne2 : nExpr) : bExpr := Or (LT ne1 ne2) (LT ne2 ne1). Definition factorial_prog : Coms := Seq (Assign y (Num 1)) (* y := 1 *) (Seq (Assign z (Num 0)) (* z := 0 *) (While (neq (Var z) (Var x)) (* while z <> x { *) (Seq (Assign z (Plus (Var z) (Num 1))) (* z := z + 1 *) (Assign y (Times (Var y) (Var z)))(* y := y * z *) ) (* } *) ) ). 46

Statement of Theorem Definition Top : assertion := fun _ => True. Open Local Scope nat_scope. Fixpoint factorial (n : nat) := match n with | O => 1 | S n' => n * (factorial n') end. Open Local Scope Z_scope. Lemma factorial_good: HTuple Top factorial_prog (fun g => g y = Z_of_nat (factorial (Zabs_nat (g x)))). 47

Casts Definition Top : assertion := fun _ => True. Open Local Scope nat_scope. Fixpoint factorial (n : nat) := match n with | O => 1 | S n' => n * (factorial n') end. Open Local Scope Z_scope. Lemma factorial_good: HTuple Top factorial_prog (fun g => g y = Z_of_nat (factorial (Zabs_nat (g x)))). 48

Proof of Theorem Lemma factorial_good: HTuple Top factorial_prog (fun g => g y = Z_of_nat (factorial (Zabs_nat (g x)))). Proof. apply HT_Seq with (fun g => g y = 1). replace Top with ([y => (Num (fun g : ctx => g y = 1)]). apply HT_Asgn. extensionality g. unfold assertReplace, Top, upd_ctx. simpl. apply prop_ext. firstorder. apply HT_Seq with (fun g :ctx => g z = 0 /\ g y = 1). replace (fun g : var -> Z => g y = 1) with ([z => (Num (fun g :ctx => g z = 0 /\ g y = 1)]). apply HT_Asgn. extensionality g. unfold assertReplace, Top, upd_ctx. simpl. apply prop_ext. firstorder. apply HT_Implied with (fun g => g z >= 0 /\ g y = Z_of_nat (factorial (Zabs_nat (g z)))) ((fun g => g z >= 0 /\ g y = Z_of_nat (factorial (Zabs_nat (g z)))) && [bNeg (neq (Var z) (Var x))]). repeat intro. destruct H. rewrite H, H0. simpl. firstorder. apply HT_While. apply HT_Implied with (fun g => g z >=0 /\ (g y) * ((g z) + 1) = Z_of_nat (factorial (Zabs_nat ((g z) + 1)))) (fun g : ctx => g z - 1 >= 0 /\ g y = Z_of_nat (factorial (Zabs_nat (g z)))). repeat intro. destruct H. clear H0. rewrite H1. split; auto. remember (g z) as n. clear -H. destruct n; auto. simpl. rewrite <- Pplus_one_succ_r. rewrite nat_of_P_succ_morphism. simpl. remember (factorial (nat_of_P p)). clear. rewrite Zpos_succ_morphism. rewrite inj_plus. rewrite inj_mult. rewrite <- Zpos_eq_Z_of_nat_o_nat_of_P. ring. elimtype False. auto with zarith. apply HT_Seq with (fun g => g z - 1 >= 0 /\ g y * g z = Z_of_nat (factorial (Zabs_nat (g z)))). replace (fun g : var -> Z => g z >= 0 /\ g y * (g z + 1) = Z_of_nat (factorial (Zabs_nat (g z + 1)))) with [z => (Plus (Var z) (Num (fun g : var -> Z => g z - 1 >= 0 /\ g y * g z = Z_of_nat (factorial (Zabs_nat (g z))))]. apply HT_Asgn. extensionality g. apply prop_ext. firstorder. unfold upd_ctx in H. simpl in H. auto with zarith. simpl. unfold upd_ctx. simpl. auto with zarith. replace (fun g : var -> Z => g z - 1 >= 0 /\ g y * g z = Z_of_nat (factorial (Zabs_nat (g z)))) with [y => (Times (Var y) (Var (fun g : var -> Z => g z - 1>= 0 /\ g y = Z_of_nat (factorial (Zabs_nat (g z))))]. apply HT_Asgn. extensionality g. apply prop_ext. firstorder. repeat intro; firstorder. repeat intro. destruct H. rewrite H1. simpl in H0. destruct (Ztrichotomy (g z) (g x)). contradiction H0; auto. destruct H2. rewrite <- H2. trivial. contradiction H0. right. apply Zgt_lt. trivial. Qed. 49

The good news… Your HW does not require you to do one of these yourself (we are not without mercy…) Still… why did I show it to you? 50

Seems like a lot of work… why bother? Lemma factorial_good: HTuple Top factorial_prog (fun g => g y = Z_of_nat (factorial (Zabs_nat (g x)))). Proof. apply HT_Seq with (fun g => g y = 1). replace Top with ([y => (Num (fun g : ctx => g y = 1)]). apply HT_Asgn. extensionality g. unfold assertReplace, Top, upd_ctx. simpl. apply prop_ext. firstorder. apply HT_Seq with (fun g :ctx => g z = 0 /\ g y = 1). replace (fun g : var -> Z => g y = 1) with ([z => (Num (fun g :ctx => g z = 0 /\ g y = 1)]). apply HT_Asgn. extensionality g. unfold assertReplace, Top, upd_ctx. simpl. apply prop_ext. firstorder. apply HT_Implied with (fun g => g z >= 0 /\ g y = Z_of_nat (factorial (Zabs_nat (g z)))) ((fun g => g z >= 0 /\ g y = Z_of_nat (factorial (Zabs_nat (g z)))) && [bNeg (neq (Var z) (Var x))]). repeat intro. destruct H. rewrite H, H0. simpl. firstorder. apply HT_While. apply HT_Implied with (fun g => g z >=0 /\ (g y) * ((g z) + 1) = Z_of_nat (factorial (Zabs_nat ((g z) + 1)))) (fun g : ctx => g z - 1 >= 0 /\ g y = Z_of_nat (factorial (Zabs_nat (g z)))). repeat intro. destruct H. clear H0. rewrite H1. split; auto. remember (g z) as n. clear -H. destruct n; auto. simpl. rewrite <- Pplus_one_succ_r. rewrite nat_of_P_succ_morphism. simpl. remember (factorial (nat_of_P p)). clear. rewrite Zpos_succ_morphism. rewrite inj_plus. rewrite inj_mult. rewrite <- Zpos_eq_Z_of_nat_o_nat_of_P. ring. elimtype False. auto with zarith. apply HT_Seq with (fun g => g z - 1 >= 0 /\ g y * g z = Z_of_nat (factorial (Zabs_nat (g z)))). replace (fun g : var -> Z => g z >= 0 /\ g y * (g z + 1) = Z_of_nat (factorial (Zabs_nat (g z + 1)))) with [z => (Plus (Var z) (Num (fun g : var -> Z => g z - 1 >= 0 /\ g y * g z = Z_of_nat (factorial (Zabs_nat (g z))))]. apply HT_Asgn. extensionality g. apply prop_ext. firstorder. unfold upd_ctx in H. simpl in H. auto with zarith. simpl. unfold upd_ctx. simpl. auto with zarith. replace (fun g : var -> Z => g z - 1 >= 0 /\ g y * g z = Z_of_nat (factorial (Zabs_nat (g z)))) with [y => (Times (Var y) (Var (fun g : var -> Z => g z - 1>= 0 /\ g y = Z_of_nat (factorial (Zabs_nat (g z))))]. apply HT_Asgn. extensionality g. apply prop_ext. firstorder. repeat intro; firstorder. repeat intro. destruct H. rewrite H1. simpl in H0. destruct (Ztrichotomy (g z) (g x)). contradiction H0; auto. destruct H2. rewrite <- H2. trivial. contradiction H0. right. apply Zgt_lt. trivial. Qed. 51

Bug in Paper Proof Lemma factorial_good: HTuple Top factorial_prog (fun g => g y = Z_of_nat (factorial (Zabs_nat (g x)))). Proof. apply HT_Seq with (fun g => g y = 1). replace Top with ([y => (Num (fun g : ctx => g y = 1)]). apply HT_Asgn. extensionality g. unfold assertReplace, Top, upd_ctx. simpl. apply prop_ext. firstorder. apply HT_Seq with (fun g :ctx => g z = 0 /\ g y = 1). replace (fun g : var -> Z => g y = 1) with ([z => (Num (fun g :ctx => g z = 0 /\ g y = 1)]). apply HT_Asgn. extensionality g. unfold assertReplace, Top, upd_ctx. simpl. apply prop_ext. firstorder. apply HT_Implied with (fun g => g z >= 0 /\ g y = Z_of_nat (factorial (Zabs_nat (g z)))) ((fun g => g z >= 0 /\ g y = Z_of_nat (factorial (Zabs_nat (g z)))) && [bNeg (neq (Var z) (Var x))]). repeat intro. destruct H. rewrite H, H0. simpl. firstorder. apply HT_While. apply HT_Implied with (fun g => g z >=0 /\ (g y) * ((g z) + 1) = Z_of_nat (factorial (Zabs_nat ((g z) + 1)))) (fun g : ctx => g z - 1 >= 0 /\ g y = Z_of_nat (factorial (Zabs_nat (g z)))). repeat intro. destruct H. clear H0. rewrite H1. split; auto. remember (g z) as n. clear -H. destruct n; auto. simpl. rewrite <- Pplus_one_succ_r. rewrite nat_of_P_succ_morphism. simpl. remember (factorial (nat_of_P p)). clear. rewrite Zpos_succ_morphism. rewrite inj_plus. rewrite inj_mult. rewrite <- Zpos_eq_Z_of_nat_o_nat_of_P. ring. elimtype False. auto with zarith. apply HT_Seq with (fun g => g z - 1 >= 0 /\ g y * g z = Z_of_nat (factorial (Zabs_nat (g z)))). replace (fun g : var -> Z => g z >= 0 /\ g y * (g z + 1) = Z_of_nat (factorial (Zabs_nat (g z + 1)))) with [z => (Plus (Var z) (Num (fun g : var -> Z => g z - 1 >= 0 /\ g y * g z = Z_of_nat (factorial (Zabs_nat (g z))))]. apply HT_Asgn. extensionality g. apply prop_ext. firstorder. unfold upd_ctx in H. simpl in H. auto with zarith. simpl. unfold upd_ctx. simpl. auto with zarith. replace (fun g : var -> Z => g z - 1 >= 0 /\ g y * g z = Z_of_nat (factorial (Zabs_nat (g z)))) with [y => (Times (Var y) (Var (fun g : var -> Z => g z - 1>= 0 /\ g y = Z_of_nat (factorial (Zabs_nat (g z))))]. apply HT_Asgn. extensionality g. apply prop_ext. firstorder. repeat intro; firstorder. repeat intro. destruct H. rewrite H1. simpl in H0. destruct (Ztrichotomy (g z) (g x)). contradiction H0; auto. destruct H2. rewrite <- H2. trivial. contradiction H0. right. apply Zgt_lt. trivial. Qed. 52

Forgot to track boundary condition (z >= 0 at all times in the loop) Lemma factorial_good: HTuple Top factorial_prog (fun g => g y = Z_of_nat (factorial (Zabs_nat (g x)))). Proof. apply HT_Seq with (fun g => g y = 1). replace Top with ([y => (Num (fun g : ctx => g y = 1)]). apply HT_Asgn. extensionality g. unfold assertReplace, Top, upd_ctx. simpl. apply prop_ext. firstorder. apply HT_Seq with (fun g :ctx => g z = 0 /\ g y = 1). replace (fun g : var -> Z => g y = 1) with ([z => (Num (fun g :ctx => g z = 0 /\ g y = 1)]). apply HT_Asgn. extensionality g. unfold assertReplace, Top, upd_ctx. simpl. apply prop_ext. firstorder. apply HT_Implied with (fun g => g z >= 0 /\ g y = Z_of_nat (factorial (Zabs_nat (g z)))) ((fun g => g z >= 0 /\ g y = Z_of_nat (factorial (Zabs_nat (g z)))) && [bNeg (neq (Var z) (Var x))]). repeat intro. destruct H. rewrite H, H0. simpl. firstorder. apply HT_While. apply HT_Implied with (fun g => g z >=0 /\ (g y) * ((g z) + 1) = Z_of_nat (factorial (Zabs_nat ((g z) + 1)))) (fun g : ctx => g z - 1 >= 0 /\ g y = Z_of_nat (factorial (Zabs_nat (g z)))). repeat intro. destruct H. clear H0. rewrite H1. split; auto. remember (g z) as n. clear -H. destruct n; auto. simpl. rewrite <- Pplus_one_succ_r. rewrite nat_of_P_succ_morphism. simpl. remember (factorial (nat_of_P p)). clear. rewrite Zpos_succ_morphism. rewrite inj_plus. rewrite inj_mult. rewrite <- Zpos_eq_Z_of_nat_o_nat_of_P. ring. elimtype False. auto with zarith. apply HT_Seq with (fun g => g z - 1 >= 0 /\ g y * g z = Z_of_nat (factorial (Zabs_nat (g z)))). replace (fun g : var -> Z => g z >= 0 /\ g y * (g z + 1) = Z_of_nat (factorial (Zabs_nat (g z + 1)))) with [z => (Plus (Var z) (Num (fun g : var -> Z => g z - 1 >= 0 /\ g y * g z = Z_of_nat (factorial (Zabs_nat (g z))))]. apply HT_Asgn. extensionality g. apply prop_ext. firstorder. unfold upd_ctx in H. simpl in H. auto with zarith. simpl. unfold upd_ctx. simpl. auto with zarith. replace (fun g : var -> Z => g z - 1 >= 0 /\ g y * g z = Z_of_nat (factorial (Zabs_nat (g z)))) with [y => (Times (Var y) (Var (fun g : var -> Z => g z - 1>= 0 /\ g y = Z_of_nat (factorial (Zabs_nat (g z))))]. apply HT_Asgn. extensionality g. apply prop_ext. firstorder. repeat intro; firstorder. repeat intro. destruct H. rewrite H1. simpl in H0. destruct (Ztrichotomy (g z) (g x)). contradiction H0; auto. destruct H2. rewrite <- H2. trivial. contradiction H0. right. apply Zgt_lt. trivial. Qed. 53

Coercions (easily forgotten about…) Fixpoint factorial (n : nat) := match n with | O => 1 | S n' => n * (factorial n') end. fun g => g y = Z_of_nat (factorial (Zabs_nat (g x)))). We define factorial on nats because that way we have the best chance of not making a mistake in our specification. But there is a cost: we must coerce from Z to N and back to Z… 54

Where you need this fact in the proof Our “x!” has an implicit coercion in it: first we take the integer x, get the absolute value of it, and then calculate factorial on nats (and then coerce back to Z)… while (z <> x) { {y = z! Æ z <> x} Now use Implied {y * (z + 1) = (z + 1)!} 55

Where you need this fact in the proof Our “x!” has an implicit coercion in it: first we take the integer x, get the absolute value of it, and then calculate factorial on nats (and then coerce back to Z)… while (z <> x) { {y = z! Æ z <> x} Now use Implied {y * (z + 1) = (z + 1)!}  But wait! What if z < 0? Try y = 3, z = -4: 3 * (-4 + 1) = -9 (-4 + 1)! = (-3)! = 3! = 6 56

The Explosion of the Ariane 5 On June 4, 1996 an unmanned Ariane 5 rocket launched by the European Space Agency exploded just forty seconds after its lift- off from Kourou, French Guiana. The rocket was on its first voyage, after a decade of development costing $7 billion. The destroyed rocket and its cargo were valued at $500 million. A board of inquiry investigated the causes of the explosion and in two weeks issued a report. It turned out that the cause of the failure was a software error in the inertial reference system. Specifically a 64 bit floating point number relating to the horizontal velocity of the rocket with respect to the platform was converted to a 16 bit signed integer. The number was larger than 32,767, the largest integer storable in a 16 bit signed integer, and thus the conversion failed. 57

58