1 theorem proving and model checking in pvs 15-820a proving software with pvs edmund clarke daniel...
TRANSCRIPT
1
Theorem Proving and Model Checking in PVS
15-820AProving Software with PVS
Edmund Clarke
Daniel Kroening
Carnegie Mellon University
2
Theorem Proving and Model Checking in PVS
Outline
• Modeling Software with PVS– Complete Example for
Sequential Software,including proof
– The Magic GRIND– Modularization
3
Theorem Proving and Model Checking in PVS
Modeling Software with PVS
C: TYPE = [# a: [below(10)->integer], i: nat #]
C: TYPE = [# a: [below(10)->integer], i: nat #]
1. Define Type for STATEint a[10];unsigned i;
int main() { . . . }
int a[10];unsigned i;
int main() { . . . }
A
4
Theorem Proving and Model Checking in PVS
Modeling Software with PVS
A
2. Translate your program into goto program
int a[10];unsigned i,j,k;
int main() { i=k=0;
while(i<10) { i++; k+=2; }
j=100; k++;}
int a[10];unsigned i,j,k;
int main() { i=k=0;
while(i<10) { i++; k+=2; }
j=100; k++;}
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() { L1: i=k=0;
L2: if(!(i<10)) goto L4; L3: i++; k+=2; goto L2;
L4: j=100; k++;}
5
Theorem Proving and Model Checking in PVS
Modeling Software with PVS
A
3. Partition your program into basic blocks
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() { L1: i=k=0;
L2: if(!(i<10)) goto L4; L3: i++; k+=2; goto L2;
L4: j=100; k++;}
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]
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]
4. Write transition function for each basic block
6
Theorem Proving and Model Checking in PVS
Modeling Software with PVS
5. Combine transition functions using a program counter
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() { L1: i=k=0;
L2: if(!(i<10)) goto L4; L3: i++; k+=2; goto L2;
L4: j=100; k++;}
PCt: TYPE = { L1, L2, L3, L4, END }PCt: TYPE = { L1, L2, L3, L4, END }
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
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
7
Theorem Proving and Model Checking in PVS
Modeling Software with PVS
A
6. Define Configuration Sequence
c(T: nat, initial: C):RECURSIVE C= IF T=0 THEN initial WITH [PC:=L1] ELSE t(c(T-1, initial)) ENDIF MEASURE T
c(T: nat, initial: C):RECURSIVE C= IF T=0 THEN initial WITH [PC:=L1] ELSE t(c(T-1, initial)) ENDIF MEASURE T
7. Now prove properties about PC=LEND states
program_correct: THEOREM FORALL (initial: C): FORALL (T: nat | c(T)`PC=LEND): c(T)`result=correct_result(initial)
program_correct: THEOREM FORALL (initial: C): FORALL (T: nat | c(T)`PC=LEND): c(T)`result=correct_result(initial)
8
Theorem Proving and Model Checking in PVS
C: TYPE = [# size: nat, a: [nat -> integer], x: integer, i: nat, result: bool, PC: PCt #]
C: TYPE = [# size: nat, a: [nat -> integer], x: integer, i: nat, result: bool, PC: PCt #]
Example I
bool find_linear(unsigned size, const int a[], int x) { unsigned i;
for(i=0; i<size; i++) if(a[i]==x) return TRUE;
return FALSE;}
bool find_linear(unsigned size, const int a[], int x) { unsigned i;
for(i=0; i<size; i++) if(a[i]==x) return TRUE;
return FALSE;}
A
1. Define Type for STATE
9
Theorem Proving and Model Checking in PVS
bool find_linear(unsigned size, const int a[], int x) { L1: i=0; L2: if(!(i<size)) goto L8; L3: if(!(a[i]==x)) goto L6; L4: result=TRUE; L5: goto LEND; L6: i++; L7: goto L2; L8: result=FALSE; LEND:; return result;}
bool find_linear(unsigned size, const int a[], int x) { L1: i=0; L2: if(!(i<size)) goto L8; L3: if(!(a[i]==x)) goto L6; L4: result=TRUE; L5: goto LEND; L6: i++; L7: goto L2; L8: result=FALSE; LEND:; return result;}
Example II
bool find_linear(unsigned size, const int a[], int x) { unsigned i;
for(i=0; i<size; i++) if(a[i]==x) return TRUE;
return FALSE;}
bool find_linear(unsigned size, const int a[], int x) { unsigned i;
for(i=0; i<size; i++) if(a[i]==x) return TRUE;
return FALSE;}
A
2. Translate your program into goto program
10
Theorem Proving and Model Checking in PVS
Example III/IV
A
3. Partition your program into basic blocks
L1(c: C):C=c WITH [i:=0] L2(c: C):C=c L3(c: C):C=c L4(c: C):C=c WITH [result:=TRUE] L5(c: C):C=c L6(c: C):C=c WITH [i:=c`i+1] L7(c: C):C=c L8(c: C):C=c WITH [result:=FALSE]
L1(c: C):C=c WITH [i:=0] L2(c: C):C=c L3(c: C):C=c L4(c: C):C=c WITH [result:=TRUE] L5(c: C):C=c L6(c: C):C=c WITH [i:=c`i+1] L7(c: C):C=c L8(c: C):C=c WITH [result:=FALSE]
4. Write transition function for each basic block
bool find_linear (unsigned size, const int a[], int x) {L1: i=0;L2: if(!(i<size)) goto L8;L3: if(!(a[i]==x)) goto L6;L4: result=TRUE;L5: goto LEND;L6: i++;L7: goto L2;L8: result=FALSE;LEND:;return result;}
bool find_linear (unsigned size, const int a[], int x) {L1: i=0;L2: if(!(i<size)) goto L8;L3: if(!(a[i]==x)) goto L6;L4: result=TRUE;L5: goto LEND;L6: i++;L7: goto L2;L8: result=FALSE;LEND:;return result;}
11
Theorem Proving and Model Checking in PVS
Example V
5. Combine transition functions using a program counter
t(c: C):C=CASES c`PC OF L1: L1(c) WITH [PC:=L2], L2: L2(c) WITH [PC:= IF NOT c`i < c`size THEN L8 ELSE L3 ENDIF], L3: L3(c) WITH [PC:= IF NOT c`a(c`i)=c`x THEN L6 ELSE L4 ENDIF], L4: L4(c) WITH [PC:=L5], L5: L5(c) WITH [PC:=LEND], L6: L6(c) WITH [PC:=L7], L7: L7(c) WITH [PC:=L2], L8: L8(c) WITH [PC:=LEND], LEND: cENDCASES
t(c: C):C=CASES c`PC OF L1: L1(c) WITH [PC:=L2], L2: L2(c) WITH [PC:= IF NOT c`i < c`size THEN L8 ELSE L3 ENDIF], L3: L3(c) WITH [PC:= IF NOT c`a(c`i)=c`x THEN L6 ELSE L4 ENDIF], L4: L4(c) WITH [PC:=L5], L5: L5(c) WITH [PC:=LEND], L6: L6(c) WITH [PC:=L7], L7: L7(c) WITH [PC:=L2], L8: L8(c) WITH [PC:=LEND], LEND: cENDCASES
A
bool find_linear (unsigned size, const int a[], int x) {L1: i=0;L2: if(!(i<size)) goto L8;L3: if(!(a[i]==x)) goto L6;L4: result=TRUE;L5: goto LEND;L6: i++;L7: goto L2;L8: result=FALSE;LEND:;return result;}
bool find_linear (unsigned size, const int a[], int x) {L1: i=0;L2: if(!(i<size)) goto L8;L3: if(!(a[i]==x)) goto L6;L4: result=TRUE;L5: goto LEND;L6: i++;L7: goto L2;L8: result=FALSE;LEND:;return result;}
12
Theorem Proving and Model Checking in PVS
Example VI
A
6. Define Configuration Sequence
c(T: nat, initial: C):RECURSIVE C= IF T=0 THEN initial WITH [PC:=L1] ELSE t(c(T-1, initial)) ENDIF MEASURE T
c(T: nat, initial: C):RECURSIVE C= IF T=0 THEN initial WITH [PC:=L1] ELSE t(c(T-1, initial)) ENDIF MEASURE T
7. Now prove properties about PC=LEND states
program_correct: THEOREM FORALL (initial: C): FORALL (T: nat | c(T)`PC=LEND): c(T)`result=correct_result(initial)
program_correct: THEOREM FORALL (initial: C): FORALL (T: nat | c(T)`PC=LEND): c(T)`result=correct_result(initial)
What is the correct result?
What is the correct result?
13
Theorem Proving and Model Checking in PVS
C: TYPE = [# size: nat, a: [nat -> integer], x: integer, i: nat, result: bool, PC: PCt #]
C: TYPE = [# size: nat, a: [nat -> integer], x: integer, i: nat, result: bool, PC: PCt #]
Example IV
correct_result(c: C): bool= EXISTS (j: below(c`size)): c`a(j)=c`xcorrect_result(c: C): bool= EXISTS (j: below(c`size)): c`a(j)=c`x
A
OK!LET’S PROVE
THIS!
OK!LET’S PROVE
THIS!
14
Theorem Proving and Model Checking in PVS
C: TYPE = [# size: nat, a: [nat -> integer], x: integer, i: nat, result: bool, PC: PCt #]
C: TYPE = [# size: nat, a: [nat -> integer], x: integer, i: nat, result: bool, PC: PCt #]
Something useful first…
A
program_correct: THEOREM FORALL (initial: C): FORALL (T: nat | c(T)`PC=LEND): c(T)`result=correct_result(initial)
program_correct: THEOREM FORALL (initial: C): FORALL (T: nat | c(T)`PC=LEND): c(T)`result=correct_result(initial)
This relates initial state and
final state
We need to say:c(T)`a = initial`a Æc(T)`x = initial`x Æ
c(T)`size = initial`size
OR: The program only changes i, result, PC
We need to say:c(T)`a = initial`a Æc(T)`x = initial`x Æ
c(T)`size = initial`size
OR: The program only changes i, result, PC
15
Theorem Proving and Model Checking in PVS
invar_constants(T: nat, initial: C): bool= c(T, initial)`size=initial`size AND c(T, initial)`a =initial`a AND c(T, initial)`x =initial`x;
constants: LEMMA FORALL (initial:C, T: nat): invar_constants(T, initial)
invar_constants(T: nat, initial: C): bool= c(T, initial)`size=initial`size AND c(T, initial)`a =initial`a AND c(T, initial)`x =initial`x;
constants: LEMMA FORALL (initial:C, T: nat): invar_constants(T, initial)
Something useful first…
A
We need to say:c(T)`a = initial`a Æc(T)`x = initial`x Æ
c(T)`size = initial`size
OR: The program only changes i, result, PC
We need to say:c(T)`a = initial`a Æc(T)`x = initial`x Æ
c(T)`size = initial`size
OR: The program only changes i, result, PC
Proof:Induction on T
+ GRIND
Proof:Induction on T
+ GRIND next: the real invariant…
16
Theorem Proving and Model Checking in PVS
FORALL (j: below(c`i)): c`a(j)/=c`x FORALL (j: below(c`i)): c`a(j)/=c`x
Loop Invariant
bool find_linear(unsigned size, const int a[], int x) { unsigned i;
for(i=0; i<size; i++) if(a[i]==x) return TRUE;
return FALSE;}
bool find_linear(unsigned size, const int a[], int x) { unsigned i;
for(i=0; i<size; i++) if(a[i]==x) return TRUE;
return FALSE;}
A
17
Theorem Proving and Model Checking in PVS
The Invariant
A
invar(c: C):bool=CASES c`PC OF L1: % i=0; L2: % if(!(i<size)) goto L8; L3: % if(!(a[i]==x)) goto L6; L4: % result=TRUE; L5: % goto LEND; L6: % i++; L7: % goto L2; L8: % result=FALSE; LEND: c`result <=> EXISTS (j: below(c`size)): c`a(j)=c`xENDCASES
invar(c: C):bool=CASES c`PC OF L1: % i=0; L2: % if(!(i<size)) goto L8; L3: % if(!(a[i]==x)) goto L6; L4: % result=TRUE; L5: % goto LEND; L6: % i++; L7: % goto L2; L8: % result=FALSE; LEND: c`result <=> EXISTS (j: below(c`size)): c`a(j)=c`xENDCASES
Beginningof the Loop
Endof the Loop
18
Theorem Proving and Model Checking in PVS
The Invariant
A
invar(c: C):bool=CASES c`PC OF L1: % i=0; L2: FORALL (j: below(c`i)): c`a(j)/=c`x, % if(!(i<size)) goto L8; L3: % if(!(a[i]==x)) goto L6; L4: % result=TRUE; L5: % goto LEND; L6: % i++; L7: FORALL (j: below(c`i)): c`a(j)/=c`x, % goto L2; L8: % result=FALSE; LEND: c`result <=> EXISTS (j: below(c`size)): c`a(j)=c`xENDCASES
invar(c: C):bool=CASES c`PC OF L1: % i=0; L2: FORALL (j: below(c`i)): c`a(j)/=c`x, % if(!(i<size)) goto L8; L3: % if(!(a[i]==x)) goto L6; L4: % result=TRUE; L5: % goto LEND; L6: % i++; L7: FORALL (j: below(c`i)): c`a(j)/=c`x, % goto L2; L8: % result=FALSE; LEND: c`result <=> EXISTS (j: below(c`size)): c`a(j)=c`xENDCASES
What here?What here?
19
Theorem Proving and Model Checking in PVS
The Invariant
A
invar(c: C):bool=CASES c`PC OF L1: TRUE, % i=0; L2: FORALL (j: below(c`i)): c`a(j)/=c`x, % if(!(i<size)) goto L8; L3: % if(!(a[i]==x)) goto L6; L4: % result=TRUE; L5: % goto LEND; L6: % i++; L7: FORALL (j: below(c`i)): c`a(j)/=c`x, % goto L2; L8: % result=FALSE; LEND: c`result <=> EXISTS (j: below(c`size)): c`a(j)=c`xENDCASES
invar(c: C):bool=CASES c`PC OF L1: TRUE, % i=0; L2: FORALL (j: below(c`i)): c`a(j)/=c`x, % if(!(i<size)) goto L8; L3: % if(!(a[i]==x)) goto L6; L4: % result=TRUE; L5: % goto LEND; L6: % i++; L7: FORALL (j: below(c`i)): c`a(j)/=c`x, % goto L2; L8: % result=FALSE; LEND: c`result <=> EXISTS (j: below(c`size)): c`a(j)=c`xENDCASES
Exitingthe Loop
Exitingthe Loop
Exitingthe Loop
Exitingthe Loop
20
Theorem Proving and Model Checking in PVS
The Invariant
A
invar(c: C):bool=CASES c`PC OF L1: TRUE, % i=0; L2: FORALL (j: below(c`i)): c`a(j)/=c`x, % if(!(i<size)) goto L8; L3: % if(!(a[i]==x)) goto L6; L4: % result=TRUE; L5: % goto LEND; L6: % i++; L7: FORALL (j: below(c`i)): c`a(j)/=c`x, % goto L2; L8: c`i>=c`size AND FORALL (j: below(c`i)): c`a(j)/=c`x, % result=FALSE; LEND: c`result <=> EXISTS (j: below(c`size)): c`a(j)=c`xENDCASES
invar(c: C):bool=CASES c`PC OF L1: TRUE, % i=0; L2: FORALL (j: below(c`i)): c`a(j)/=c`x, % if(!(i<size)) goto L8; L3: % if(!(a[i]==x)) goto L6; L4: % result=TRUE; L5: % goto LEND; L6: % i++; L7: FORALL (j: below(c`i)): c`a(j)/=c`x, % goto L2; L8: c`i>=c`size AND FORALL (j: below(c`i)): c`a(j)/=c`x, % result=FALSE; LEND: c`result <=> EXISTS (j: below(c`size)): c`a(j)=c`xENDCASES
What here?What here?
21
Theorem Proving and Model Checking in PVS
The Invariant
A
invar(c: C):bool=CASES c`PC OF L1: TRUE, % i=0; L2: FORALL (j: below(c`i)): c`a(j)/=c`x, % if(!(i<size)) goto L8; L3: c`i<c`size AND FORALL (j: below(c`i)): c`a(j)/=c`x, % if(!(a[i]==x)) goto L6; L4: % result=TRUE; L5: % goto LEND; L6: % i++; L7: FORALL (j: below(c`i)): c`a(j)/=c`x, % goto L2; L8: c`i>=c`size AND FORALL (j: below(c`i)): c`a(j)/=c`x, % result=FALSE; LEND: c`result <=> EXISTS (j: below(c`size)): c`a(j)=c`xENDCASES
invar(c: C):bool=CASES c`PC OF L1: TRUE, % i=0; L2: FORALL (j: below(c`i)): c`a(j)/=c`x, % if(!(i<size)) goto L8; L3: c`i<c`size AND FORALL (j: below(c`i)): c`a(j)/=c`x, % if(!(a[i]==x)) goto L6; L4: % result=TRUE; L5: % goto LEND; L6: % i++; L7: FORALL (j: below(c`i)): c`a(j)/=c`x, % goto L2; L8: c`i>=c`size AND FORALL (j: below(c`i)): c`a(j)/=c`x, % result=FALSE; LEND: c`result <=> EXISTS (j: below(c`size)): c`a(j)=c`xENDCASES
What here?What here?
22
Theorem Proving and Model Checking in PVS
The Invariant
A
invar(c: C):bool=CASES c`PC OF L1: TRUE, % i=0; L2: FORALL (j: below(c`i)): c`a(j)/=c`x, % if(!(i<size)) goto L8; L3: c`i<c`size AND FORALL (j: below(c`i)): c`a(j)/=c`x, % if(!(a[i]==x)) goto L6; L4: % result=TRUE; L5: % goto LEND; L6: FORALL (j: below(c`i+1)): c`a(j)/=c`x, % i++; L7: FORALL (j: below(c`i)): c`a(j)/=c`x, % goto L2; L8: c`i>=c`size AND FORALL (j: below(c`i)): c`a(j)/=c`x, % result=FALSE; LEND: c`result <=> EXISTS (j: below(c`size)): c`a(j)=c`xENDCASES
invar(c: C):bool=CASES c`PC OF L1: TRUE, % i=0; L2: FORALL (j: below(c`i)): c`a(j)/=c`x, % if(!(i<size)) goto L8; L3: c`i<c`size AND FORALL (j: below(c`i)): c`a(j)/=c`x, % if(!(a[i]==x)) goto L6; L4: % result=TRUE; L5: % goto LEND; L6: FORALL (j: below(c`i+1)): c`a(j)/=c`x, % i++; L7: FORALL (j: below(c`i)): c`a(j)/=c`x, % goto L2; L8: c`i>=c`size AND FORALL (j: below(c`i)): c`a(j)/=c`x, % result=FALSE; LEND: c`result <=> EXISTS (j: below(c`size)): c`a(j)=c`xENDCASES
What here?What here?
23
Theorem Proving and Model Checking in PVS
The Invariantinvar(c: C):bool=CASES c`PC OF L1: TRUE, % i=0; L2: FORALL (j: below(c`i)): c`a(j)/=c`x, % if(!(i<size)) goto L8; L3: c`i<c`size AND FORALL (j: below(c`i)): c`a(j)/=c`x, % if(!(a[i]==x)) goto L6; L4: c`i<c`size AND c`a(c`i)=c`x, % result=TRUE; L5: c`i<c`size AND c`a(c`i)=c`x AND c`result=true, % goto LEND; L6: FORALL (j: below(c`i+1)): c`a(j)/=c`x, % i++; L7: FORALL (j: below(c`i)): c`a(j)/=c`x, % goto L2; L8: c`i>=c`size AND FORALL (j: below(c`i)): c`a(j)/=c`x, % result=FALSE; LEND: c`result <=> EXISTS (j: below(c`size)): c`a(j)=c`xENDCASES
invar(c: C):bool=CASES c`PC OF L1: TRUE, % i=0; L2: FORALL (j: below(c`i)): c`a(j)/=c`x, % if(!(i<size)) goto L8; L3: c`i<c`size AND FORALL (j: below(c`i)): c`a(j)/=c`x, % if(!(a[i]==x)) goto L6; L4: c`i<c`size AND c`a(c`i)=c`x, % result=TRUE; L5: c`i<c`size AND c`a(c`i)=c`x AND c`result=true, % goto LEND; L6: FORALL (j: below(c`i+1)): c`a(j)/=c`x, % i++; L7: FORALL (j: below(c`i)): c`a(j)/=c`x, % goto L2; L8: c`i>=c`size AND FORALL (j: below(c`i)): c`a(j)/=c`x, % result=FALSE; LEND: c`result <=> EXISTS (j: below(c`size)): c`a(j)=c`xENDCASES
24
Theorem Proving and Model Checking in PVS
The Invariant
DARING CLAIM
““Once you have found the invariant,Once you have found the invariant,the proof is done.”the proof is done.”
We now have the invariant.Lets do the actual proof.
Who believes we are done?
A
25
Theorem Proving and Model Checking in PVS
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)
Disjunction (Consequents)
Conjunction (Antecedents)
Or: Reset in cycles 0, 4 is on, and off in 1, 2.Show that A and not B holds in cycle 2.
26
Theorem Proving and Model Checking in PVS
The Magic of (GRIND)
• Myth: Grind does it all…• Reality:
• Use it when:– Case splitting, skolemization, expansion, and
trivial instantiations are left• Does not do induction• Does not apply lemmas
“... frequently used to automatically complete a proof
branch…”
27
Theorem Proving and Model Checking in PVS
The Magic of (GRIND)
• If it goes wrong…– you can get unprovable subgoals– it might expand recursions forever
• How to abort?– Hit Ctrl-C twice, then (restore)
• How to make it succeed?– Before running (GRIND), remove unnecessary
parts of the sequent using (DELETE fnum).It will prevent that GRIND makes wrong instantiations and expands the wrong definitions.
29
Theorem Proving and Model Checking in PVS
A word on automation…
A
• The generation of C, t, and c can be trivially automated
• Most of the invariant can be generated automatically – all but the actual loop invariant (case L7/L2)
• The proof is automatic unless quantifier instantiation is required
30
Theorem Proving and Model Checking in PVS
Modularizationt(c: C):C=CASES c`PC OF L1: L1(c) WITH [PC:=L2], L2: L2(c) WITH [PC:= IF NOT c`i < c`size THEN L8 ELSE L3 ENDIF], L3: L3(c) WITH [PC:= IF NOT c`a(c`i)=c`x THEN L6 ELSE L4 ENDIF], L4: L4(c) WITH [PC:=L5], L5: L5(c) WITH [PC:=LEND], L6: L6(c) WITH [PC:=L7], L7: L7(c) WITH [PC:=L2], L8: L8(c) WITH [PC:=LEND], LEND: cENDCASES
t(c: C):C=CASES c`PC OF L1: L1(c) WITH [PC:=L2], L2: L2(c) WITH [PC:= IF NOT c`i < c`size THEN L8 ELSE L3 ENDIF], L3: L3(c) WITH [PC:= IF NOT c`a(c`i)=c`x THEN L6 ELSE L4 ENDIF], L4: L4(c) WITH [PC:=L5], L5: L5(c) WITH [PC:=LEND], L6: L6(c) WITH [PC:=L7], L7: L7(c) WITH [PC:=L2], L8: L8(c) WITH [PC:=LEND], LEND: cENDCASES
bool find_linear (unsigned size, const int a[], int x) {L1: i=0;L2: if(!(i<size)) goto L8;L3: if(!(a[i]==x)) goto L6;L4: result=TRUE;L5: goto LEND;L6: i++;L7: goto L2;L8: result=FALSE;LEND:;return result;}
bool find_linear (unsigned size, const int a[], int x) {L1: i=0;L2: if(!(i<size)) goto L8;L3: if(!(a[i]==x)) goto L6;L4: result=TRUE;L5: goto LEND;L6: i++;L7: goto L2;L8: result=FALSE;LEND:;return result;}
How about a program with a 1000 basic
blocks?= 1000 cases?
How about a program with a 1000 basic
blocks?= 1000 cases?
A
• Better not• Remedy: Modularize the program and the proof• Idea: find_linear is a function in the C
program, make it a function in PVS as wellC C
• Functions in PVS must be total, thus, this requires proof of termination
31
Theorem Proving and Model Checking in PVS
Modularization
A
epsilon_ax: AXIOM (EXISTS x: p(x)) => p(epsilon(p)) epsilon_ax: AXIOM (EXISTS x: p(x)) => p(epsilon(p))
find_linear(start: C): C= c( epsilon! (T: nat): c(T, start)`PC=LEND , start)find_linear(start: C): C= c( epsilon! (T: nat): c(T, start)`PC=LEND , start)
a T such that c(T, start)`PC=LEND
"epsilon! (x:t): p(x)”is translated to
"epsilon(LAMBDA (x:t): p(x))”
"epsilon! (x:t): p(x)”is translated to
"epsilon(LAMBDA (x:t): p(x))”
THIS IS WHATREQUIRES
TERMINATION
32
Theorem Proving and Model Checking in PVS
Modularization
A
termination: THEOREM FORALL (initial: C): EXISTS (T: nat): c(T, initial)`PC=LEND
termination: THEOREM FORALL (initial: C): EXISTS (T: nat): c(T, initial)`PC=LEND
epsilon_ax: AXIOM (EXISTS x: p(x)) => p(epsilon(p)) epsilon_ax: AXIOM (EXISTS x: p(x)) => p(epsilon(p))
allows to show the left hand side of
the right hand side then says
c(epsilon! (T: nat): c(T, start)`PC=LEND, start)`PC=LENDc(epsilon! (T: nat): c(T, start)`PC=LEND, start)`PC=LEND
33
Theorem Proving and Model Checking in PVS
Modularization
A
find_linear(start: C): C= c( epsilon! (T: nat): c(T, start)`PC=LEND , start)find_linear(start: C): C= c( epsilon! (T: nat): c(T, start)`PC=LEND , start)
What to prove about it?
find_linear_correct: THEOREM FORALL (c: C): LET new=find_linear(c) IN new=c WITH [result:=correct_result(c)]
find_linear_correct: THEOREM FORALL (c: C): LET new=find_linear(c) IN new=c WITH [result:=correct_result(c)]??What is missing?
34
Theorem Proving and Model Checking in PVS
Modularization
A
find_linear(start: C): C= c( epsilon! (T: nat): c(T, start)`PC=LEND , start)find_linear(start: C): C= c( epsilon! (T: nat): c(T, start)`PC=LEND , start)
What to prove about it?
find_linear_correct: THEOREM FORALL (c: C): LET new=find_linear(c) IN new=c WITH [result:=correct_result(c), PC:=new`PC, i:=new`i]
find_linear_correct: THEOREM FORALL (c: C): LET new=find_linear(c) IN new=c WITH [result:=correct_result(c), PC:=new`PC, i:=new`i]
“All variables but result, PC, and i are unchanged,and result is the correct result.”