1 theorem proving and model checking in pvs 15-820a pvs – an introduction edmund clarke daniel...
TRANSCRIPT
1
Theorem Proving and Model Checking in PVS
15-820APVS – An Introduction
Edmund Clarke
Daniel Kroening
Carnegie Mellon University
2
Theorem Proving and Model Checking in PVS
Outline
• Theorem provers• Why PVS?• Topics for this semester• Short introduction to the PVS
language• The PVS workflow• A short proof
3
Theorem Proving and Model Checking in PVS
Theorem Provers• Stores theorems and establishes their
correctness• What kind of theorems?
– First order– Second order / higher order
• How to establish the correctness?– Completely automated– Semi-automated– Interactive (manual)
4
Theorem Proving and Model Checking in PVS
Theorem Provers
There is a wide range of theoremprovers• Higher order: ALF, Alfa, Coq, HOL, PVS• Logical Frameworks: Isabelle, LF, Twelf• Inductive: ACL2, Inka• Automated: Gandalf, TPS, Otter, Setheo,
SPASS• EQP, Maude
5
Theorem Proving and Model Checking in PVS
Theorem Provers• The most commonly used Theorem Provers,
from systems verification point of view– HOL: Floating Point Verification (Intel)– ACL2: Floating Point Verification (AMD)– PVS: NASA/DoD, e.g., Space Shuttle flight control
requirements specificationIt also does Floating Point Units.
• PVS is…– Higher order– Interactive
6
Theorem Proving and Model Checking in PVS
PVS Workflow
PVS FilePVS File
System
Properties
PROOFSPROOFS
Conversion of system (Program, circuit, protocol…)and property.
Can be automated or donemanually
Proof construction
Interaction with the theorem prover
A
7
Theorem Proving and Model Checking in PVS
Why PVS?• Why PVS and not some other theorem prover?
From PVS website:
“PVS is a large and complex system and it takes a long while to learn to use it effectively. You
should be prepared to invest six months to become a moderately skilled user”
From PVS website:
“PVS is a large and complex system and it takes a long while to learn to use it effectively. You
should be prepared to invest six months to become a moderately skilled user”
A
8
Theorem Proving and Model Checking in PVS
Why PVS?• Why PVS and not some other theorem prover?
• Other (strong) theorem provers probably worse• The PVS language is close to “normal” notation
– Not LISP!• PVS is interactive – why not an automated
theorem prover?– Decidable logics often not rich enough, or inconvenient– Semi-automated theorem provers usually don’t tell what
is wrong, experience and knowledge about internals required
9
Theorem Proving and Model Checking in PVS
Topics for this Semester
• PVS– Installation– Proof Interaction
• Language Basics– Types– Type Checking– Recursion– Lambda Notation– Abstract Data Types
10
Theorem Proving and Model Checking in PVS
Topics for this Semester
• Specification using PVS–Prelude, Libraries–State Machines–Tabular Specifications–How to get “systems” into PVS
• Hardware• Software
11
Theorem Proving and Model Checking in PVS
Topics for this Semester• Proofs
– Induction– Real Numbers– Abstraction of Infinite State Transition Systems
• Proof Automation– Rewriting– Write your own decision procedure!– Model Checking as Rule of Inference
12
Theorem Proving and Model Checking in PVS
The PVS Language
• There are two languages1. The language to write definitions and
theorems (“definition language“)2. The language to prove theorems
(“proof language”)They have nothing to do with each other
• The definition language looks like“normal math” (translator to Latex built in)
• The proof language looks like LISP
13
Theorem Proving and Model Checking in PVS
The PVS Definition Language
• Main language elements– Declarations
• Types• Constants
– Expressions over these types– Expressions of Boolean types may be a
formula– Formulae are theorems or axioms– Declarations and formulae are grouped into
theories
14
Theorem Proving and Model Checking in PVS
The PVS Definition Language class_theory: THEORY BEGIN
my_type: NONEMPTY_TYPE
constant1, constant2: my_type
f1: THEOREM FORALL (a, b: integer): a+b=b+a
f2: AXIOM constant1=constant2
END class_theory
class_theory: THEORY BEGIN
my_type: NONEMPTY_TYPE
constant1, constant2: my_type
f1: THEOREM FORALL (a, b: integer): a+b=b+a
f2: AXIOM constant1=constant2
END class_theory
TypeDeclarations
TypeDeclarations
ExpressionsExpressions
A
15
Theorem Proving and Model Checking in PVS
The PVS Definition Language class_theory: THEORY BEGIN
my_type: NONEMPTY_TYPE
constant1, constant2: my_type
f1: THEOREM FORALL (a, b: integer): a+b=b+a
f2: AXIOM constant1=constant2
END class_theory
class_theory: THEORY BEGIN
my_type: NONEMPTY_TYPE
constant1, constant2: my_type
f1: THEOREM FORALL (a, b: integer): a+b=b+a
f2: AXIOM constant1=constant2
END class_theory
FormulaeFormulae
A
16
Theorem Proving and Model Checking in PVS
The PVS Definition Language class_theory: THEORY BEGIN
my_type: NONEMPTY_TYPE
constant1, constant2: my_type
f1: THEOREM FORALL (a, b: integer): a+b=b+a
f2: AXIOM constant1=constant2
END class_theory
class_theory: THEORY BEGIN
my_type: NONEMPTY_TYPE
constant1, constant2: my_type
f1: THEOREM FORALL (a, b: integer): a+b=b+a
f2: AXIOM constant1=constant2
END class_theory
DeclarationsDeclarations
17
Theorem Proving and Model Checking in PVS
Axioms vs. Theorems
• Axioms are assumed to be true• Dangerous!• Avoid axioms, use constant declarations
instead: class_theory: THEORY BEGIN
c: integer
c: AXIOM c=3
END class_theory
class_theory: THEORY BEGIN
c: integer
c: AXIOM c=3
END class_theory
class_theory: THEORY BEGIN
c: integer = 3
END class_theory
class_theory: THEORY BEGIN
c: integer = 3
END class_theory
Left hand side is conservative
18
Theorem Proving and Model Checking in PVS
Types
• PVS has a very rich type concept– Uninterpreted type declaration:
numbers: TYPEnumbers: NONEMPTY_TYPE
– Interpreted type declarationIntroduce names for type expressions
posint: TYPE={ i: integer | i > 0}
19
Theorem Proving and Model Checking in PVS
Types PVS comes with
• boolean– FALSE, TRUE
• Number types– real, rational, integer, natural
• string• Ordinals
20
Theorem Proving and Model Checking in PVS
Type Expressions
• Function Types[ t1,…,tn -> t ]
Sugar for that:FUNCTION[ t1,…,tn -> t ]ARRAY[ t1,…,tn -> t ]
Note that ti and t may be function types as well!
21
Theorem Proving and Model Checking in PVS
Expressions
• Constants– Given by their name, as used in the
declaration– Numbers (1, 2, 3, …) are actually identifiers
and can even be overloaded– If name is ambiguous, use
identifier::type
22
Theorem Proving and Model Checking in PVS
Expressions
• Function Applicationsf(x)
– Tons of Syntactic sugar for that, don’t be confused
– Binary operator symbolsy * z is the same as *(y, z)
23
Theorem Proving and Model Checking in PVS
Expressions
• Functions PVS comes with– Boolean
AND &, OR, IMPLIES =>,WHEN, IFF <=>
– IF c THEN a ELSE bIF: [boolean, T, T -> T]
– (COND: sugar for IF THEN ELSE)– Numeric operators
+, -, *, /, ^, <, <=, >, >=
24
Theorem Proving and Model Checking in PVS
Expressions
• Binding Expressions– Quantifiers
EXISTS (x: T): p(x)FORALL (y: T): q(y)
25
Theorem Proving and Model Checking in PVS
Expressions
• Binding Expressions– Lambda: unnamed functions
LAMBDA (x: int): x+1Type of that: [ int -> int ]
class_theory: THEORYBEGIN
f: [int->int] = LAMBDA (x: int): x+1
END class_theory
class_theory: THEORYBEGIN
f: [int->int] = LAMBDA (x: int): x+1
END class_theory
class_theory: THEORYBEGIN
f(x: int): int = x+1
END class_theory
class_theory: THEORYBEGIN
f(x: int): int = x+1
END class_theory
A
26
Theorem Proving and Model Checking in PVS
Recursion
• Lambda cannot be used for recursion• Only named functions allow recursion• No mutual recursion
factorial(x: nat): RECURSIVE nat = IF x=0 THEN 1 ELSE factorial(x-1)*x ENDIF MEASURE (LAMBDA (x: nat): x)
factorial(x: nat): RECURSIVE nat = IF x=0 THEN 1 ELSE factorial(x-1)*x ENDIF MEASURE (LAMBDA (x: nat): x)
A
Used to prove that the function is total
Used to prove that the function is total
27
Theorem Proving and Model Checking in PVS
Expressions
• LET ExpressionsLET i:T=e1 IN e2
– Useful for avoiding redundancy if e1 is used many times in e2
– Sugar for LAMBDA (LAMBDA (i: T): e2)(e1)– Example
LET x=2 IN x*yis
(LAMBDA x: x*y)(2)
28
Theorem Proving and Model Checking in PVS
Expressions
• Override Expressions
e WITH [(i1):=v1, (i2):=v2, …]
– Sugar for LAMBDA LAMBDA x: IF x=i1 THEN v1
ELSIF x=i2 THEN v2 … ELSE e(x) ENDIF
– Also for records and tuples
29
Theorem Proving and Model Checking in PVS
Expressions
• LET and WITH useful for some sequential program constructs!
f(i: int):int= LET a1=LAMBDA (x: below(10)): 0 IN ... LET a2=a1 WITH [(i):=5] IN ... ai(0)
f(i: int):int= LET a1=LAMBDA (x: below(10)): 0 IN ... LET a2=a1 WITH [(i):=5] IN ... ai(0)
int f(int i) { int a[10]={ 0, … }; ... a[i]=5; ... return a[0];}
int f(int i) { int a[10]={ 0, … }; ... a[i]=5; ... return a[0];}
30
Theorem Proving and Model Checking in PVS
Expressions
• Set Expressions– In PVS, sets are represented using their
characteristic function[ T -> boolean ] same as setof[T]
– Set expressions:{ x:T | p(x) }
For sets a, b over T:Union: a OR b
Intersection: a AND b
31
Theorem Proving and Model Checking in PVS
Some Syntactic Sugar
• Tuple types[ t1,…,tn ]
• Tuple expressions( e1,…,en )
• Comes with projectionsPROJ_1, PROJ_2, ..., PROJ_n
32
Theorem Proving and Model Checking in PVS
Examplestacks1: THEORY BEGIN
stack: TYPE = [int, ARRAY[int->int]] empty: stack = (0, (LAMBDA (j: int): 0))
size(s: stack):int = PROJ_1(s) elements(s: stack):ARRAY[int->int] = PROJ_2(s)
push(x: int, s:stack): stack = (size(s)+1, elements(s) WITH [(size(s)):=x])
pop(s:stack): stack = (size(s)-1, elements(s))
END stacks1
stacks1: THEORY BEGIN
stack: TYPE = [int, ARRAY[int->int]] empty: stack = (0, (LAMBDA (j: int): 0))
size(s: stack):int = PROJ_1(s) elements(s: stack):ARRAY[int->int] = PROJ_2(s)
push(x: int, s:stack): stack = (size(s)+1, elements(s) WITH [(size(s)):=x])
pop(s:stack): stack = (size(s)-1, elements(s))
END stacks1
How abouta “struct”?
How abouta “struct”?
A
33
Theorem Proving and Model Checking in PVS
Some Syntactic Sugar
• Record types[# a1:t1,…,an:tn #]
• Record expressions(# a1:=e1,…,an:=en #)
• Comes with projectionsa1, a2, ..., an
• Or: e`ai
34
Theorem Proving and Model Checking in PVS
Examplestacks2: THEORY BEGIN
stack: TYPE = [# size: int, elements: ARRAY[int->int] #] empty: stack = (# size:=0, elements:=(LAMBDA (j: int): 0) #)
push(x: int, s:stack): stack = (# size:=s`size+1, elements:=s`elements WITH [(s`size):=x] #)
pop(s:stack): stack = (# size:=s`size-1, elements:=s`elements #)
END stacks2
stacks2: THEORY BEGIN
stack: TYPE = [# size: int, elements: ARRAY[int->int] #] empty: stack = (# size:=0, elements:=(LAMBDA (j: int): 0) #)
push(x: int, s:stack): stack = (# size:=s`size+1, elements:=s`elements WITH [(s`size):=x] #)
pop(s:stack): stack = (# size:=s`size-1, elements:=s`elements #)
END stacks2
What about the empty stack?
What about the empty stack?
A
35
Theorem Proving and Model Checking in PVS
Subtypes
{ x: T | p(x)}• p must be of type [ T -> boolean ]• Sugar for that:
(p)• This type contains all elements x of T
for which p(x) is true• E.g., define domain of integer division:
{ x: integer | x/=0 }• Makes type equivalence undecidable
36
Theorem Proving and Model Checking in PVS
Subtypes
• Subtypes in binding expressions– Forall, exists: forall (i: int | i>10): …– Lambda:
class_theory: THEORYBEGIN
f: [ {x: int | x/=0 }->real] = LAMBDA (x: int | x/=0): 1/x
END class_theory
class_theory: THEORYBEGIN
f: [ {x: int | x/=0 }->real] = LAMBDA (x: int | x/=0): 1/x
END class_theory
class_theory: THEORYBEGIN
f(x: int | x/=0): real = 1/x
END class_theory
class_theory: THEORYBEGIN
f(x: int | x/=0): real = 1/x
END class_theory
37
Theorem Proving and Model Checking in PVS
Examplestacks3: THEORY BEGIN
stack: TYPE = [# size: nat, elements: ARRAY[nat->int] #] empty: stack = (# size:=0, elements:=(LAMBDA (j: nat): 0) #)
push(x: int, s:stack): { s: stack | s`size>=1 } = (# size:=s`size+1, elements:=s`elements WITH [(s`size):=x] #)
pop(s:stack | s`size>=1): stack = (# size:=s`size-1, elements:=s`elements #)
END stacks3
stacks3: THEORY BEGIN
stack: TYPE = [# size: nat, elements: ARRAY[nat->int] #] empty: stack = (# size:=0, elements:=(LAMBDA (j: nat): 0) #)
push(x: int, s:stack): { s: stack | s`size>=1 } = (# size:=s`size+1, elements:=s`elements WITH [(s`size):=x] #)
pop(s:stack | s`size>=1): stack = (# size:=s`size-1, elements:=s`elements #)
END stacks3
Properties?Properties?
A
38
Theorem Proving and Model Checking in PVS
Examplestacks3: THEORY BEGIN
stack: TYPE = [# size: nat, elements: ARRAY[nat->int] #] empty: stack = (# size:=0, elements:=(LAMBDA (j: nat): 0) #)
push(x: int, s:stack): { s: stack | s`size>=1 } = (# size:=s`size+1, elements:=s`elements WITH [(s`size):=x] #)
pop(s:stack | s`size>=1): stack = (# size:=s`size-1, elements:=s`elements #)
push_pop: THEOREM FORALL (s: stack, x: int): pop(push(x, s))=s
END stacks3
stacks3: THEORY BEGIN
stack: TYPE = [# size: nat, elements: ARRAY[nat->int] #] empty: stack = (# size:=0, elements:=(LAMBDA (j: nat): 0) #)
push(x: int, s:stack): { s: stack | s`size>=1 } = (# size:=s`size+1, elements:=s`elements WITH [(s`size):=x] #)
pop(s:stack | s`size>=1): stack = (# size:=s`size-1, elements:=s`elements #)
push_pop: THEOREM FORALL (s: stack, x: int): pop(push(x, s))=s
END stacks3
Does this work?Does this work?
A
39
Theorem Proving and Model Checking in PVS
Examplestacks4: 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) #)
push_pop: THEOREM FORALL (s: stack, x: int): pop(push(x, s))=s
END stacks4
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) #)
push_pop: THEOREM FORALL (s: stack, x: int): pop(push(x, s))=s
END stacks4
40
Theorem Proving and Model Checking in PVS
Proof?
• How to argue?pop(push(x, s)) = s
• Let’s to the size component and the elements component separately
• Size:pop(push(x, s))`size = s`size
– Expand definition of pop:
push(x, s)`size - 1 = s`size– Expanding the definition of push results in
s`size+1-1=s`size
41
Theorem Proving and Model Checking in PVS
Proof? (2)
• Elements:pop(push(x, s))`elements = s`elements
– Expand definition of pop:((j:nat|j<push(x, s)`size-1):
push(x, s)`elements(j)) = s`elements– Expanding the definition of push results in
((j:nat|j<s`size):IF j<s`size THEN s`elements(j)
ELSE x ENDIF= s`elements
– Obviously, the condition of the IF is always true
42
Theorem Proving and Model Checking in PVS
What next…
• Webpage!– Installation instructions for PVS– Further reading– Homework assignment