500 likes | 721 Views
15-820A Modeling Hardware and Software with PVS. Edmund Clarke Daniel Kroening Carnegie Mellon University. Outline. PVS Language Parameterized Theories Modeling Hardware with PVS Combinatorial Clocked Circuits Modeling Software with PVS Sequential Software. Outline. Proofs
E N D
15-820AModeling Hardware and Software with PVS Edmund Clarke Daniel Kroening Carnegie Mellon University
Outline • PVS Language • Parameterized Theories • Modeling Hardware with PVS • Combinatorial • Clocked Circuits • Modeling Software with PVS • Sequential Software
Outline • Proofs • The Gentzen Sequent • Propositional Part • Quantifiers • Equality • Induction • Using Lemmas/Theorems • Rewriting • Model Checking • Strategies
Example stacks4: THEORY BEGIN stack: TYPE = [# size: nat, elements: ARRAY[{i:nat|i<size}->int] #] empty: stack = (# size:=0, elements:=(LAMBDA (j:nat| FALSE): 0) #) push(x: int, s:stack): { s: stack | s`size>=1 } = (# size:=s`size+1, elements:=LAMBDA (j: below(s`size+1)): IF j<s`size THEN s`elements(j) ELSE x ENDIF #) pop(s:stack | s`size>=1): stack = (# size:=s`size-1, elements:=LAMBDA (j:nat|j<s`size-1): s`elements(j) #) END stacks4 What about the stacks of other types? A
Example stacks4: THEORY BEGIN stack: TYPE = [# size: nat, elements: ARRAY[{i:nat|i<size}->int] #] empty: stack = (# size:=0, elements:=(LAMBDA (j:nat| FALSE): 0) #) push(x: int, s:stack): { s: stack | s`size>=1 } = (# size:=s`size+1, elements:=LAMBDA (j: below(s`size+1)): IF j<s`size THEN s`elements(j) ELSE x ENDIF #) pop(s:stack | s`size>=1): stack = (# size:=s`size-1, elements:=LAMBDA (j:nat|j<s`size-1): s`elements(j) #) END stacks4
Theory Parameters • Idea: do something like a C++ template template <class T1, class T2, ...> class stack { ... }; theory[T1: TYPE, T2: TYPE, ...]:THEORY BEGIN ... END theory A
Theory Parameters • Idea: do something like a C++ template template <class T1, class T2, ...> class stack { ... f(e: T1):bool; ... }; theory[T1: TYPE, T2: TYPE, ...]:THEORY BEGIN ... f(e: T1):bool; ... END theory
Example stacks4[T: NONEMPTY_TYPE]: THEORY BEGIN stack: TYPE = [# size: nat, elements: ARRAY[{i:nat|i<size}->T] #] e: T empty: stack = (# size:=0, elements:=(LAMBDA (j:nat| FALSE): e) #) push(x: T, s:stack): { s: stack | s`size>=1 } = (# size:=s`size+1, elements:=LAMBDA (j: below(s`size+1)): IF j<s`size THEN s`elements(j) ELSE x ENDIF #) pop(s:stack | s`size>=1): stack = (# size:=s`size-1, elements:=LAMBDA (j:nat|j<s`size-1): s`elements(j) #) END stacks4
Example use_stack: THEORY BEGIN my_type: TYPE = [ posint, posint ] IMPORTING stacks5; s: stack[my_type]; x: my_type = (1, 2); d: stack[my_type] = push(x , s); END use_stack
Theory Parameters • PVS uses theory parameters for many definitions PVS has many heuristics to automatically detect the right theory parameters a, b: posint; a=b same as =[posint](a,b) equalities [T: TYPE]: THEORY BEGIN =: [T, T -> boolean] END equalities
Useful Parameterized Theories • PVS comes with several useful parameterized theories • Sets over elements of type Tsubsets, union, complement, power set,finite sets, … • Infinite Sequences • Finite Sequences • Lists • Bit vectors A
Bit Vectors • Bit Vectors are defined using an ARRAY type bv[N: nat]: THEORY BEGIN bvec : TYPE = [below(N) -> bit] same asboolean 0, …, N-1 A
Bit Vectors • Extract a bit: bv^(i) i 2 { 0, … , N-1 } • Vector extraction: bv^(m,n)n≤m<N • bN: fill(b) • Concatenation: bv1 o bv2 • Bitwise: bv1 OR bv2 • Conversion to integer: bv2nat(bv) • Conversion from integer: nat2bv(bv)
Bit Vector Arithmetic • Requires IMPORTING bitvectors@bv_arith_nat • *, +, -, <=, >=, <, > • Many other useful theoriesLook in pvs/lib/bitvectors
Bit Vectors • Example: bv_ex: THEORY BEGIN x: VAR bvec[32] zero_lemma: LEMMA bv2nat(x)=0 IFF x=fill(false) END bv_ex How many bits? A
Bit Vectors • Example: bv_ex: THEORY BEGIN x: VAR bvec[32] zero_lemma: LEMMA bv2nat[32](x)=0 IFF x=fill[32](false) END bv_ex
PVS Workflow System PROOFS PVS File Properties Conversion of system (Program, circuit, protocol…)and property. Can be automated or donemanually Proof construction Interaction with the theorem prover A
Modeling Hardware with PVS • Combinational Hardware • No latches • Circuit is loop-free • Examples: arithmetic circuits, ALUs, … • Clocked Circuits • Combinational part + registers (latches) • Examples: Processors, Controllers,… A
Modeling Hardware with PVS • Idea: Model combinational circuits using functions on bit vectors f(A, B, reset: bit):bit= IF reset THEN (NOT A) OR B ELSE false ENDIF Translation from/to Verilog, VHDL, etc. easy A
Modeling Hardware with PVS • What is the Theorem Prover good for? • Equivalence checking? No. • Parameterized circuits • Prove circuit with “N” bits • Arithmetic • What is a correct adder? Integer? Floating Point? • A purely propositional specification is not really useful A
Parameterized Circuits Binary tree for 8 inputs Parameterized for 2k inputs A
Modeling Hardware with PVS btree[T: TYPE, K: posnat, o: [T,T->T]]: THEORY BEGIN btree(k: nat, l:[below(exp2(k))->T]): RECURSIVE T = IF k=0 THEN l(0)ELSE btree(k-1, LAMBDA (i: below(exp2(k-1))): l(i)) o btree(k-1, LAMBDA (i: below(exp2(k-1))): l(i+exp2(k-1))) ENDIF MEASURE k btree(l:[below(exp2(K))->T]):T=btree(K, l) END btree Property? A
Modeling Hardware with PVS btree[T: TYPE, K: posnat, o: [T,T->T]]: THEORY BEGIN ... btree_correct: THEOREMbtree(l) = l(0) o l(1) o ... o l(exp(K)-1) END btree Dot dot dot? A
Modeling Hardware with PVS btree[T: TYPE, K: posnat, o: [T,T->T]]: THEORY BEGIN ... btree_correct: THEOREM btree(l) = l(0) o l(1) o ... o l(exp(K)-1) seq(i: nat, l:[upto(i)->T]): RECURSIVE T = IF i=0 THEN l(0) ELSE seq (i-1, LAMBDA (j: below(i)): l(j)) o l(i) ENDIF MEASURE i Btree_correct: THEOREM btree(l) = seq(exp(K)-1, l) END btree What is missing? Can you prove this? A
Modeling Hardware with PVS btree[T: TYPE, K: posnat, o: [T,T->T]]: THEORY BEGIN ASSUMING fassoc: ASSUMPTION associative?(o) ENDASSUMING ... END btree This is NOT like an axiom! zerotester_imp(op): bit = NOT btree[bit, K, OR](op) PVS will make you prove here that OR is associative A
Arithmetic Circuits a,b,cin : VAR bit oba_sum(a,b,cin): bit = (a XOR b XOR cin) oba_cout(a,b,cin): bit = ((a AND b) OR (a AND cin) OR (b AND cin)) Wait a second!You are adding bits here! Property? One Bit Adder (oba) oba_correct: LEMMA a + b + cin = 2 * oba_cout(a,b,cin) + oba_sum(a,b,cin) A
Conversions oba_correct: LEMMA a + b + cin = 2 * oba_cout(a,b,cin) + oba_sum(a,b,cin) There is no addition on bits (or boolean)! bit : TYPE = bool nbit : TYPE = below(2) b2n(b:bool): nbit = IF b THEN 1 ELSE 0 ENDIF CONVERSION b2n below(2) is a subtype of the integer type,and we have addition for that. A
Arithmetic Circuits Carry Chain Adder
Arithmetic Circuits cout(n,a,b,a_cin): RECURSIVE bit = IF n=0 THEN oba_cout(a(0),b(0),a_cin) ELSE oba_cout(a(n),b(n), cout(n-1,a,b,a_cin)) ENDIFMEASURE n bv_adder(a,b,a_cin): bvec[N] = LAMBDA (i:below(N)): IF i=0 THEN oba_sum(a(0),b(0),a_cin) ELSE oba_sum(x(i),y(i), cout(i-1,x,y,a_cin)) ENDIF A
Arithmetic Circuits bv_adder(a,b,a_cin): bvec[N] = LAMBDA (i:below(N)): IF i=0 THEN oba_sum(a(0),b(0),a_cin) ELSE oba_sum(x(i),y(i), cout(i-1,x,y,a_cin)) ENDIF adder_correct: THEOREM exp2(N)*cout(N-1,a,b,a_cin)+bv2nat(bv_adder(a,b,a_cin))= bv2nat(a) + bv2nat(b) + a_cin adder_is_add: THEOREM bv_adder(a,b,FALSE) = a + b A
Modeling Hardware with PVS • Combinational Hardware • No latches • Circuit is loop-free • Examples: arithmetic circuits, ALUs, … • Clocked Circuits • Combinational part + registers (latches) • Examples: Processors, Controllers,… A
Clocked Circuits Configuration in cycle 4 A
Clocked Circuits 1. Define Type for STATE and INPUTS C: TYPE = [# A, B: bit #] I: TYPE = [# reset: bit #] 2. Define the Transition Function t(c: C, i: I):C= (# A:= IF i`reset THEN false ELSE(NOT c`A) OR c`B ENDIF, B:= IF i`reset THEN false ELSE c`A OR c`B ENDIF #) A
Clocked Circuits 3. Define Initial State and Inputs initial: C i: [nat -> I]; 4. Define the Configuration Sequence c(T: nat):RECURSIVE C= IF T=0 THEN initial ELSE t(c(T-1), i(T-1)) ENDIF MEASURE T A
Clocked Circuits 5. Prove things about this sequence c(T: nat):RECURSIVE C= IF T=0 THEN initial ELSE t(c(T-1), i(T-1)) ENDIF MEASURE T c_lem: LEMMA (i(0)`reset AND NOT i(1)`reset AND NOT i(2)`reset) => (c(2)`A AND NOT c(2)`B) You can also verify invariants, even temporal properties that way. A
Modeling Software with PVS • (Software written in functional language) • (Take a subset of PVS, and compile that) • Software written in language like ANSI-C int f(int i) { int a[10]={ 0, … }; ... a[i]=5; ... return a[0]; } f(i: int):int= LET a1=LAMBDA (x: below(10)): 0 IN ... LET a2=a1 WITH [(i):=5] IN ... ai(0) What about loops? A
Modeling Software with PVS int a[10]; unsigned i; int main() { . . . } 1. Define Type for STATE C: TYPE = [# a: [below(10)->integer], i: nat #] nat?Of course, bvec[32] is better A
Modeling Software with PVS 2. Translate your program into goto program int a[10]; unsigned i,j,k; int main() { L1: i=k=0; L2: if(!(i<10)) goto L4; L3: i++; k+=2; goto L2; L4: j=100; k++; } int a[10]; unsigned i,j,k; int main() { i=k=0; while(i<10) { i++; k+=2; } j=100; k++; } A
Modeling Software with PVS 3. Partition your program into basic blocks 4. Write transition function for each basic block L1(c: C):C= c WITH [i:=0, k:=0] L2(c: C):C= c L3(c: C):C= c WITH [i:=c`i+1, k:=c`k+2] L4(c: C):C= c WITH [j:=100, k:=c`k+1] int a[10]; unsigned i,j,k; int main() { L1: i=k=0; L2: if(!(i<10)) goto L4; L3: i++; k+=2; goto L2; L4: j=100; k++; } A
Modeling Software with PVS addPC: PCtto C 5. Combine transition functions using a program counter make sure the PC of the initial state is L1 PCt: TYPE = { L1, L2, L3, L4, END } int a[10]; unsigned i,j,k; int main() { L1: i=k=0; L2: if(!(i<10)) goto L4; L3: i++; k+=2; goto L2; L4: j=100; k++; } t(c: C): C= CASES c`PC OF L1: L1(c) WITH [PC:=L2], L2: L2(c) WITH [PC:= IF NOT (c`i<10) THEN L4 ELSE L3 ENDIF, L3: L3(c) WITH [PC:=L2], L4: L4(c) WITH [PC:=END], END: c ENDCASES A
Modeling Software with PVS • Next week: • I/O in case of programs • Proving termination • Concurrent programs A
PVS Workflow System PROOFS PVS File Properties Conversion of system (Program, circuit, protocol…)and property. Can be automated or donemanually Proof construction Interaction with the theorem prover A
The Gentzen Sequent {-1} i(0)`reset {-2} i(4)`reset |------- {1} i(1)`reset {2} i(2)`reset {3} (c(2)`A AND NOT c(2)`B) Conjunction (Antecedents) Disjunction (Consequents) Or: Reset in cycles 0, 4 is on, and off in 1, 2.Show that A and not B holds in cycle 2.
The Gentzen Sequent • COPY duplicates a formulaWhy? When you instantiate a quantified formula, the original one is lost • DELETE removes unnecessary formulae – keep your proof easy to follow
Propositional Rules • BDDSIMP simplify propositional structure using BDDs • CASE: case splittingusage: (CASE “i!1=5”) • FLATTEN: Flattens conjunctions, disjunctions, and implications • IFF: Convert a=b to a<=>b for a, b boolean • LIFT-IF move up case splits inside a formula
Quantifiers • INST: Instantiate Quantifiers • Do this if you have EXISTS in the consequent, or FORALL in the antecedent • Usage: (INST -10 “100+x”) • SKOLEM!: Introduce Skolem Constants • Do this if you have FORALL in the consequent (and do not want induction), or EXISTS in the antecedent • If the type of the variable matters, use SKOLEM-TYPEPRED
Equality • REPLACE: If you have an equality in the antecedent, you can use REPLACE • Example: (REPLACE -1){-1} l=r replace l by r • Example: (REPLACE -1 RL){-1} l=r replace r by l
Using Lemmas / Theorems • EXPAND: Expand the definition • Example: (EXPAND “min”) • LEMMA: add a lemma as antecedent • Example: (LEMMA “my_lemma”) • After that, instantiate the quantifiers with (INST -1 “x”) • Try (USE “my_lemma”).It will try to guess how you want to instantiate
Induction • INDUCT: Performs induction • Usage: (INDUCT “i”) • There should be a FORALL i: … equation in the consequent • You get two subgoals, one for the induction base and one for the step • PVS comes with many induction schemes. Look in the prelude for the full list
What next… • Webpage! • Installation instructions for PVS • Further reading • Homework assignment