500 likes | 509 Views
This text provides an outline of PVS language, parameterized theories, modeling hardware and software, proofs, and model checking, with examples on stacks and circuit modeling.
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