a sat characterization of boolean program correctness n.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
A SAT characterization of boolean-program correctness PowerPoint Presentation
Download Presentation
A SAT characterization of boolean-program correctness

Loading in 2 Seconds...

play fullscreen
1 / 34

A SAT characterization of boolean-program correctness - PowerPoint PPT Presentation


  • 107 Views
  • Uploaded on

A SAT characterization of boolean-program correctness. K. Rustan M. Leino Microsoft Research, Redmond, WA. 14 Nov 2002 IFIP WG 2.4 meeting, Schlo β Dagstuhl, Germany. Motivation. This program has performed an illegal operation. If the problem persists, please contact the vendor.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'A SAT characterization of boolean-program correctness' - maurilio


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
a sat characterization of boolean program correctness

A SAT characterization of boolean-program correctness

K. Rustan M. LeinoMicrosoft Research, Redmond, WA

14 Nov 2002IFIP WG 2.4 meeting, Schloβ Dagstuhl, Germany

motivation
Motivation

This program has performed an illegal operation.

If the problem persists, please contact the vendor.

the slam toolkit
The SLAM toolkit

Tom Ball, Sriram Rajamani, et al., Microsoft Research

Properties of interest:

x  “resource is locked”

y  t > 0

Device driver (C program)

Abstraction (boolean program)

APIERR DevGetStatus(LPSTATUS status){ unsigned int t; struct _Info info; for (i = 0; i < SPIGOT_COUNT; i++) { APIERR err; info.cbSize = sizeof(struct _Info); info.iSpigot = i; err = W_GetStatus(&info); if (err != APIERR_Success) { return err; } t |= info.fStatus & SPIGOT_ALIVE; } status->result = t | 0x2055; return APIERR_Success;}

APIERR W_GetStatus(struct _Info * pinfo){ APIERR err; bool fChanged = TRUE; do { err = DevRegisterColumn(pinfo, TRUE); if (err != APIERR_Success) { return err; } if (pinfo->huwMagi < 10) { fChanged = FALSE; } else { err = DevReleaseColumn(pinfo); } } while (fChanged); return DevReleaseColumn(pinfo);}

APIERR DevGetStatus(LPSTATUS status){ unsigned int t; struct _Info info; for (i = 0; i < SPIGOT_COUNT; i++) { APIERR err; info.cbSize = sizeof(struct _Info); info.iSpigot = i; err = W_GetStatus(&info); if (err != APIERR_Success) { return err; } t |= info.fStatus & SPIGOT_ALIVE; } status->result = t | 0x2055; return APIERR_Success;}

APIERR W_GetStatus(struct _Info * pinfo){ APIERR err; bool fChanged = TRUE; do { err = DevRegisterColumn(pinfo, TRUE); if (err != APIERR_Success) { return err; } if (pinfo->huwMagi < 10) { fChanged = FALSE; } else { err = DevReleaseColumn(pinfo); } } while (fChanged); return DevReleaseColumn(pinfo);}

y := false;

assert x;

x := true;

x := x  y;

Predicate abstraction

the slam toolkit1
The SLAM toolkit

Tom Ball, Sriram Rajamani, et al., Microsoft Research

Device driver (C program)

Abstraction (boolean program)

APIERR DevGetStatus(LPSTATUS status){ unsigned int t; struct _Info info; for (i = 0; i < SPIGOT_COUNT; i++) { APIERR err; info.cbSize = sizeof(struct _Info); info.iSpigot = i; err = W_GetStatus(&info); if (err != APIERR_Success) { return err; } t |= info.fStatus & SPIGOT_ALIVE; } status->result = t | 0x2055; return APIERR_Success;}

APIERR W_GetStatus(struct _Info * pinfo){ APIERR err; bool fChanged = TRUE; do { err = DevRegisterColumn(pinfo, TRUE); if (err != APIERR_Success) { return err; } if (pinfo->huwMagi < 10) { fChanged = FALSE; } else { err = DevReleaseColumn(pinfo); } } while (fChanged); return DevReleaseColumn(pinfo);}

APIERR DevGetStatus(LPSTATUS status){ unsigned int t; struct _Info info; for (i = 0; i < SPIGOT_COUNT; i++) { APIERR err; info.cbSize = sizeof(struct _Info); info.iSpigot = i; err = W_GetStatus(&info); if (err != APIERR_Success) { return err; } t |= info.fStatus & SPIGOT_ALIVE; } status->result = t | 0x2055; return APIERR_Success;}

APIERR W_GetStatus(struct _Info * pinfo){ APIERR err; bool fChanged = TRUE; do { err = DevRegisterColumn(pinfo, TRUE); if (err != APIERR_Success) { return err; } if (pinfo->huwMagi < 10) { fChanged = FALSE; } else { err = DevReleaseColumn(pinfo); } } while (fChanged); return DevReleaseColumn(pinfo);}

y := false;

assert x

assert x;

x := true;

x := x  y;

the slam toolkit2
The SLAM toolkit

Tom Ball, Sriram Rajamani, et al., Microsoft Research

Device driver (C program)

Abstraction (boolean program)

APIERR DevGetStatus(LPSTATUS status){ unsigned int t; struct _Info info; for (i = 0; i < SPIGOT_COUNT; i++) { APIERR err; info.cbSize = sizeof(struct _Info); info.iSpigot = i; err = W_GetStatus(&info); if (err != APIERR_Success) { return err; } t |= info.fStatus & SPIGOT_ALIVE; } status->result = t | 0x2055; return APIERR_Success;}

APIERR W_GetStatus(struct _Info * pinfo){ APIERR err; bool fChanged = TRUE; do { err = DevRegisterColumn(pinfo, TRUE); if (err != APIERR_Success) { return err; } if (pinfo->huwMagi < 10) { fChanged = FALSE; } else { err = DevReleaseColumn(pinfo); } } while (fChanged); return DevReleaseColumn(pinfo);}

APIERR DevGetStatus(LPSTATUS status){ unsigned int t; struct _Info info; for (i = 0; i < SPIGOT_COUNT; i++) { APIERR err; info.cbSize = sizeof(struct _Info); info.iSpigot = i; err = W_GetStatus(&info); if (err != APIERR_Success) { return err; } t |= info.fStatus & SPIGOT_ALIVE; } status->result = t | 0x2055; return APIERR_Success;}

APIERR W_GetStatus(struct _Info * pinfo){ APIERR err; bool fChanged = TRUE; do { err = DevRegisterColumn(pinfo, TRUE); if (err != APIERR_Success) { return err; } if (pinfo->huwMagi < 10) { fChanged = FALSE; } else { err = DevReleaseColumn(pinfo); } } while (fChanged); return DevReleaseColumn(pinfo);}

y := false;

assert x

assert x;

x := true;

x := x  y;

real error

the slam toolkit3
The SLAM toolkit

Tom Ball, Sriram Rajamani, et al., Microsoft Research

Device driver (C program)

Abstraction (boolean program)

APIERR DevGetStatus(LPSTATUS status){ unsigned int t; struct _Info info; for (i = 0; i < SPIGOT_COUNT; i++) { APIERR err; info.cbSize = sizeof(struct _Info); info.iSpigot = i; err = W_GetStatus(&info); if (err != APIERR_Success) { return err; } t |= info.fStatus & SPIGOT_ALIVE; } status->result = t | 0x2055; return APIERR_Success;}

APIERR W_GetStatus(struct _Info * pinfo){ APIERR err; bool fChanged = TRUE; do { err = DevRegisterColumn(pinfo, TRUE); if (err != APIERR_Success) { return err; } if (pinfo->huwMagi < 10) { fChanged = FALSE; } else { err = DevReleaseColumn(pinfo); } } while (fChanged); return DevReleaseColumn(pinfo);}

APIERR DevGetStatus(LPSTATUS status){ unsigned int t; struct _Info info; for (i = 0; i < SPIGOT_COUNT; i++) { APIERR err; info.cbSize = sizeof(struct _Info); info.iSpigot = i; err = W_GetStatus(&info); if (err != APIERR_Success) { return err; } t |= info.fStatus & SPIGOT_ALIVE; } status->result = t | 0x2055; return APIERR_Success;}

APIERR W_GetStatus(struct _Info * pinfo){ APIERR err; bool fChanged = TRUE; do { err = DevRegisterColumn(pinfo, TRUE); if (err != APIERR_Success) { return err; } if (pinfo->huwMagi < 10) { fChanged = FALSE; } else { err = DevReleaseColumn(pinfo); } } while (fChanged); return DevReleaseColumn(pinfo);}

y := false;

assert x;

x := true;

x := x  y;

infeasible path

the slam toolkit4
The SLAM toolkit

Tom Ball, Sriram Rajamani, et al., Microsoft Research

Properties of interest:

x  “resource is locked”

y  t > 0

z  p≠ NULL

Device driver (C program)

Abstraction (boolean program)

APIERR DevGetStatus(LPSTATUS status){ unsigned int t; struct _Info info; for (i = 0; i < SPIGOT_COUNT; i++) { APIERR err; info.cbSize = sizeof(struct _Info); info.iSpigot = i; err = W_GetStatus(&info); if (err != APIERR_Success) { return err; } t |= info.fStatus & SPIGOT_ALIVE; } status->result = t | 0x2055; return APIERR_Success;}

APIERR W_GetStatus(struct _Info * pinfo){ APIERR err; bool fChanged = TRUE; do { err = DevRegisterColumn(pinfo, TRUE); if (err != APIERR_Success) { return err; } if (pinfo->huwMagi < 10) { fChanged = FALSE; } else { err = DevReleaseColumn(pinfo); } } while (fChanged); return DevReleaseColumn(pinfo);}

APIERR DevGetStatus(LPSTATUS status){ unsigned int t; struct _Info info; for (i = 0; i < SPIGOT_COUNT; i++) { APIERR err; info.cbSize = sizeof(struct _Info); info.iSpigot = i; err = W_GetStatus(&info); if (err != APIERR_Success) { return err; } t |= info.fStatus & SPIGOT_ALIVE; } status->result = t | 0x2055; return APIERR_Success;}

APIERR W_GetStatus(struct _Info * pinfo){ APIERR err; bool fChanged = TRUE; do { err = DevRegisterColumn(pinfo, TRUE); if (err != APIERR_Success) { return err; } if (pinfo->huwMagi < 10) { fChanged = FALSE; } else { err = DevReleaseColumn(pinfo); } } while (fChanged); return DevReleaseColumn(pinfo);}

y := false;

assert x;

x := true;

z := true;

Predicate abstraction

x := x  y;

Predicate abstraction

if (z) …

boolean programs
Boolean programs
  • Prog ::= var Id* ; Block*
  • Block ::= LabelId : Stmt* goto LabelId*
  • Stmt ::= Id := Expr | assert Expr | assume Expr
  • Expr ::= false | true | Id | Expr | Expr  Expr | Expr  Expr
example
Example
  • var x, y;A: x := true; goto BB: assert x; x := x  y; goto B or CC:

A: x := true

B: assert x; x := x  y

C:

semantics weakest preconditions
Semantics: Weakest preconditions
  • For any statement S and postcondition Q, wp(S,Q) characterizes those pre-states from which execution is guaranteed:
    • not to go wrong, and
    • either the execution doesn’t terminate or it terminates in a state satisfying Q

Q

S

wp(S,Q)

semantics weakest preconditions1
Semantics: Weakest preconditions
  • wp(x := E, Q) = Q[x:=E]wp(assert E, Q) = E  Qwp(assume E, Q) = E  Q
  • wp(skip, Q) = Qwp(S;T, Q) = wp(S, wp(T,Q))
  • wp(gotolabels, Q) = ( L  labels :: wp(L,Q))
semantics of blocks
Semantics of blocks

What I write:

  • For any block: var w; … L: S; goto labels …introduce a boolean function L, such that:

What I really mean:

L(w) = wp(S, (Glabels :: G(w)))

(w :: L(w) = wp(S, (Glabels :: G(w))) )

or equivalently:

L = (λw :: wp(S, (Glabels :: G(w))) )

example1
Example
  • A(x,y) = wp(x := true, B(x,y))B(x,y) = wp(assert x; x := x  y, B(x,y)  C(x,y))C(x,y) = wp(skip, true)
  • A(x,y) = B(true,y)B(x,y) = x B(x  y, y)  C(x  y, y)C(x,y) = true

A: x := true

B: assert x; x := x  y

C:

equations with multiple solutions
Equations with multiple solutions

A, B, C : A(x,y) = B(true, y) B(x,y) = x  B(xy, y)  C(xy, y) C(x,y) = true

The unknowns

Solution 0:

A(x,y) = false B(x,y) = false C(x,y) = true

Solution 1:

A(x,y) = y B(x,y) = x  y C(x,y) = true

We want the weakest solution

weakest solution
Weakest solution

A,B,C : A(x,y) = B(true, y) B(x,y) = x  B(xy, y)  C(xy, y) C(x,y) = true

weakest solution1
Weakest solution

A,B,C : A = (λx,y :: B(true, y)) B = (λx,y :: x  B(xy, y)  C(xy, y)) C = (λx,y :: true)

F(A,B,C)

G(A,B,C)

H(A,B,C)

weakest solution fixpoint
Weakest solution/fixpoint

A,B,C : A = F(A,B,C) B = G(A,B,C) C = H(A,B,C)

where F = (λx,y :: B(true, y)) G = (λx,y :: x  B(xy, y)  C(xy, y)) H = (λx,y :: true)

(λx,y :: B(true, y))

(λx,y :: x  B(xy, y)  C(xy, y))

Weakest solution of A,B,C

(λx,y :: true)

F(A,B,C)

F

G(A,B,C)

G

H(A,B,C)

H

Weakest fixpoint of F,G,H

program correctness
Program correctness
  • A program with variables w and start block A is correct iff: (w :: A(w))
  • That is, the program has an error iff: A(w)is satisfiable.

boolean equations, satisfiability

SAT

SAT

functions, weakest solutions

equations over a closed set of terms
Equations over a closed set of “terms”
  • Using the definitions: A(x,y) = B(true, y) B(x,y) = x  B(xy, y)  C(xy, y) C(x,y) = true
  • We produce:
    • A(x,y) = B(true, y)
    • B(true, y) = true  B(truey, y)  C(truey, y)
    • B(truey, y) = truey  B(trueyy, y)  C(trueyy, y)
    • C(truey, y) = true
point functions
Point functions
  • A function: f(w) = f(false)  f(w)can be expressed as two point functions : ffalse = ffalse  ffalse ftrue = ffalse  ftrue
point function equations
Point-function equations
  • A set of equations: f : f(w) = f(false)  f(w)can be expressed as: ffalse, ftrue : ffalse = ffalse  ffalse ftrue = ffalse  ftrue
a fixpoint theorem
A fixpoint theorem
  • Given a function F on a complete lattice,if F is continuous, then its weakest fixpoint exists and is given by: Fk( T )for some natural number k.
  • k is the fixpoint depth of F
  • fixpoint depth  lattice height

T

lattice height

F k ( T )

computing fixpoints outward
Computing fixpoints: outward
  • T

{ apply F }

  • F(T)

{ apply F }

  • F(F(T))

{ apply F }

  • F(F(F(T)))

{ apply F }

  • F(F(F(F(T))))

Suppose fixpoint depth of F is 3

produced in previous step

equal to each other—weakest fixpoint of F

computing fixpoints inward
Computing fixpoints: inward

{ replace  with F() }

  • F()

{ replace  with F() }

  • F(F())

{ replace  with F() }

  • F(F(F()))

{ replace  with T }

  • F(F(F(T)))

Suppose fixpoint depth of F is 3

produced in previous step

no need for further applications of F

weakest fixpoint of F

multiple unknowns
Multiple unknowns
  • a,b : a = F(a,b) b = G(a,b)
  • Suppose fixpoint depths of F,G are 2,1
  • Weakest solution for a is:
    • a00
    • F(a10 , b10 )
    • F(F(a20, b20 ), G(a11 , b11))
    • F(F(T , G(a21, b21)), G(F(a21, b21), T ))
    • F(F(T , G(T , T )), G(F(T , T ), T ))

Number of enclosing applications of G

Number of enclosing applications of F

special instance
Special instance
  • Lattice of booleans has height 1
  • If F returns a boolean, then F’s fixpoint depth is at most 1
  • and so F’s weakest fixpoint is F(T)
back to our problem
Back to our problem
  • Using the definitions: A(x,y) = B(true, y) B(x,y) = x  B(xy, y)  C(xy, y) C(x,y) = true
  • We produce:
    • Ax,y = Btrue,y
    • Btrue,y = true  Btruey,y  Ctruey,y
    • By,y = y  Byy,y  Cyy,y

true

back to our problem1
Back to our problem
  • Using the definitions: A(x,y) = B(true, y) B(x,y) = x  B(xy, y)  C(xy, y) C(x,y) = true
  • We produce:
    • Ax,y = Btrue,y
    • Btrue,y = true  Btruey,y  Ctruey,y
    • By,y = y  true  Cyy,y
    • Cy,y = true
leibniz constraints
Leibniz constraints
  • Being a function means, for any f: (w,w’ :: (w=w’)  (f(w)=f(w’)))“Leibniz’s rule”
  • So when we have: Btrue,y = … By,y = …we also generate the following Leibniz constraint : (true=y)  (y=y)  (Btrue,y = By,y)
sat formula
SAT formula
  • From the closed set of terms:Ax,y = Btrue,yBtrue,y = true  Btruey,y  Ctruey,yBy,y = y  true  Cyy,yCy,y = true

we produce the following SAT equations: a a = b b = true  b’  c b’ = y  true  c c = true y  (b=b’)

a

b

b’

c

negated start symbol:

A(x,y)

Leibniz constraint

summary
Summary
  • Boolean program, whose semantics is defined by weakest solution of weakest-precondition equations
  • Translate to SAT problem:
    • Instantiate equations to get a closed set of terms
    • Replace nested recursive instantiations by true
    • Conjoin negated start symbol and Leibniz constraints
    • Write point functions as propositional variables
    • Check for satisfiability
  • Performance? Heuristics?
  • Are Leibniz constraints really needed?
  • Better encoding of procedures?
complexity
Complexity
  • With N blocks and K variables:
    • each boolean function has K arguments, each a boolean expression
    • there are 22K different boolean expressions
    • So, there are N·2K·2K different terms
  • Suppose each of the 2K initial states were considered individually:
    • each boolean-function argument can then be folded into one of the 2 boolean constants
    • Then, there are only 2K·N·2K different terms

 Symbolic checking:

 Explicit-state checking:

symbolic vs explicit state checking
Symbolic vs. explicit-state checking
  • The following equality (and others?) can be exploited heuristically to try to get a good balance:

f(P, Q, R)=(P  f(true, Q, R))  (P  f(false, Q, R))

summary1
Summary
  • Boolean program, whose semantics is defined by weakest solution of weakest-precondition equations
  • Translate to SAT problem:
    • Instantiate equations to get a closed set of terms
    • Replace nested recursive instantiations by true
    • Conjoin negated start symbol and Leibniz constraints
    • Write point functions as propositional variables
    • Check for satisfiability
  • Performance heuristics: symbolic vs. explicit-state
  • Other heuristics?
  • Are Leibniz constraints really needed?
  • Better encoding of procedures?