Program Analysis via 3-Valued Logic

1 / 111

# Program Analysis via 3-Valued Logic - PowerPoint PPT Presentation

Program Analysis via 3-Valued Logic. Mooly Sagiv, Tal Lev-Ami, Roman Manevich Tel Aviv University Thomas Reps, University of Wisconsi n, Madison Reinhard Wilhelm, Universität des Saarlandes. Interprocedural Analysis, so far. Abstract domains

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

## PowerPoint Slideshow about 'Program Analysis via 3-Valued Logic' - mingan

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

### Program Analysisvia 3-Valued Logic

Mooly Sagiv, Tal Lev-Ami, Roman Manevich

Tel Aviv University

Thomas Reps, University of Wisconsin, Madison

Reinhard Wilhelm, Universität des Saarlandes

Interprocedural Analysis, so far

Abstract domains

• (Powerset of) fixed set of program entities andentities from underlying domain
• Domains:
• P(Aexp*) Available expressions
• P(Var* Lab* ) Reaching Definitions
• Var*  Val Constant Propagation
• Var*  Int Interval Analysis
Interprocedural Analysis
• Dynamically created procedure incarnations
• Domain P(Lab* (Var*  …))
• Call strings – strings of labels ofcall sites
• Sufficient to represent recursion because of nested lifetimes, a call string corresponds to an actual stack
• in general of unbounded length  non-computable fixed point
• approximated by fixed length, k
Dynamically Created “Objects”
• How to represent dynamically created
• heap cells, created by calls to mallocx=malloc();… x=malloc();… x=malloc();
• objects, created by constructors of classesx=new C;… x=new C;… x=new C;
• In general,
• unbounded sets
• anonymous
Anonymous Objects (contd.)
• Concrete domains: relations reflecting accessibility,
• Stack for program variables
• Heap for anonymous, dynamically created objects
• pointer variables point from Stack into Heap
• Heap consists of a set of functions modelling references/pointer components
• Abstract domains: How to deal with unboundedness?
• How to analyze programs without bounds on number of objects?

Invariant:

x points to head of

non-reversed suffix,

reversed prefix

or NULL (start)

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

Reverses lists of

arbitrary length

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

Questions Posed to the Analysis
• Can x be dereferenced while having value NULL in some execution state?
• Can an object leak out of the program’s execution?
• Can an object be freed while being shared?
Freeing a Shared Object

a = malloc(…) ;

b = a;

free (a);

c = malloc (…);

if (b == c) printf(“unexpected equality”);

Dereferencing a NULL pointer

bool search(int value, Elements *c) {Elements *elem;for (elem = c;

c != NULL;

elem = elem->next;) if (elem->val == value)

return TRUE;

return FALSE

typedef struct element {

int value;

struct element *next;

} Elements

Dereferencing a NULL pointer

bool search(int value, Elements *c) {Elements *elem;for (elem = c;

c != NULL;

elem = elem->next;) if (elem->val == value)

return TRUE;

return FALSE

typedef struct element {

int value;

struct element *next;

} Elements

potential null de-reference

Memory Leakage

typedef struct element {

int value;

struct element *next;

} Elements

Elements* strange(Elements *x){

Elements *y,*g;y = NULL;while (x!= NULL) { g = x->next; y = x; x->next = y; x = g; }return y;

Memory Leakage

typedef struct element {

int value;

struct element *next;

} Elements

Elements* strange (Elements *x){

Elements *y,*g;y = NULL;while (x!= NULL) { g = x->next;y = x; x->next = y; x = g; }return y;

leakage of list

elements

class Make {

private Worklist worklist;

public static void main (String[] args) {

Make m = new Make();

m.initializeWorklist(args);

m.processWorklist(); }

void initializeWorklist(String[] args) {

...; worklist = new Worklist(); ...

// add some items to worklist}

void processWorklist() {

Set s = worklist.unprocessedItems();

for (Iterator i = s.iterator(); i.hasNext()){

Object item = i.next();

if (...) processItem(item);

} }

void processItem(Object i){ ...; doSubproblem(...);}

void doSubproblem(...) {

... worklist.addItem(newitem); ... }

}

public class Worklist {

Set s;

public Worklist() {.

..; s = new HashSet(); ... }

public void addItem(Object item) { s.add(item); }

public Set unprocessedItems() {

return s; }

}

return rev; }

### Example: In-Situ List Reversal

Concrete execution on a list of length 3

t

y

NULL

1

2

3

NULL

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

t

y

NULL

1

2

3

NULL

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

t

y

1

2

3

NULL

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

NULL

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

NULL

1

2

3

NULL

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

NULL

1

2

3

NULL

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

NULL

1

2

3

NULL

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

NULL

1

2

3

NULL

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

NULL

1

2

3

NULL

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

NULL

1

2

3

NULL

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

NULL

1

2

3

NULL

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

NULL

1

2

3

NULL

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

NULL

1

2

3

NULL

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

NULL

1

2

3

NULL

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

NULL

1

2

3

NULL

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Original Problem: Shape Analysis
• Characterize dynamically allocated data structures
• x points to an acyclic list, cyclic list, tree, dag, etc.
• data-structure invariants
• Identify may-alias relationships
• Establish “disjointedness” properties
• x and y point to data structures that do not share cells
Properties of reverse(x)
• On entry: x points to an acyclic list
• On exit: y points to an acyclic list
• On exit: x = = NULL
• Invariant: At the start of while loop, x points to head of non-reversed suffix, y to head of already reversed prefix or NULL (start)(they are disjoint acyclic lists)
• All the pointer dereferences are safe
• No memory leaks

### Example: In-Situ List Reversal

Abstract execution

t

y

x

• could be
• the empty list
• a non-empty list
Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

t

y

NULL

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

NULL

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

NULL

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Materialization

assuming that

is not the empty list

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

NULL

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

NULL

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

NULL

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

NULL

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Materialization

assuming that

is not the empty list

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

NULL

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

NULL

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

NULL

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

could be

• the empty list
• a non-empty list
Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

assuming that

stood for the empty list

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

NULL

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

NULL

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

NULL

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

NULL

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Why is Shape Analysis Difficult?
• Destructive updating through pointers
• pnext = q
• Produces complicated aliasing relationships
• Dynamic storage allocation
• No bound on the size of run-time data structures
• No syntactic names for locations
• Data-structure invariants typically only hold at the beginning and end of operations
• Need to verify that data-structure invariants are re-established
Main Ingredients: Abstract Domain
• A new abstract domain for static analysis
• Represents dynamically allocated memory
• Based on predicate logic
• Execution states in concrete semantics coded as interpretations of sets of predicates over a 2-valued domain (1  true, 0  false)
• unary predicatex for pointer variable x –x(l)if x points to l
• binary predicatenext for selector next –next (l1, l2) if next selector of l1 points to l2

l1

l3

l2

Coding:

t(l2)=1, y(l3)=1,

n(l2,l1)=1,

predicates with value 0

not listed

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

NULL

1

2

3

NULL

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

Main Ingredients: Semantics of Statements
• Predicate-Update Formulae for a statement
• Describe how the interpretation of predicates changes by executing the statement
• x = ychanges the interpretation ofxto that ofy
• x -> next = ychanges the interpretation of next such thatn(l1,l2)=1 for some l, l1, l2 with x(l) = 1, n(l, l1)=1, and y(l2)=1
Main Ingredients: Analysis
• Abstract interpretation by evaluation over 3-valued domain (1, 0, ½  don’t know)
• Kleene’s interpretation of predicate logic
• A system TVLA
• Input:
• Operational semantics
• Input Program
• Output: the result of the analysis

l2

l1

l3

x(l3)=1, t(l2)=1, y(l3)=1,

n(l2, l1)=1,

Example: In-Situ List Reversal

typedef struct list_cell {

int val;

struct list_cell *next;

} *List;

t

y

List reverse (List x) {

List y, t;

y = NULL;

while (x != NULL) {

t = y;

y = x;

x = x  next;

y  next = t;

}

return y;

}

x

n(l1,…) = ?

n(l3,…) = ?

n(l1,…) = 1/2

n(l3,…) = 1/2

Formal:

Summary

node

x

Formalizing “. . .”

Informal:

x

Plan
• Motivation
• SWhile
• An SOS for SWhile
• An SOS for SWhile using predicate calculus
• Simple Abstract interpretation using 3-valued logics
• More precise abstract interpretation+ TVLA (next meeting)
Repetition

3-valued logic based analysis

• computes invariants about data structuresxpoints to acyclic singly linked list
• Semantics is formulated in 1st order predicate logicx(v) = 1 if x points to v
• 3rd value ½ to express don’t know
The SWhile Programming Language Abstract Syntax

sel:= car | cdr

a := x | x.sel | null | n | a1 opa a2

b := true | false | not b | b1 opb b2 | a1 opr a2

S := x := a | x.sel := a | x := malloc() | skip | S1 ; S2| if b then S1else S2 | while b do S

Predicate Logic
• Vocabulary
• A finite set of predicate symbolsPeach with a fixed arity
• A finite set of function symbols
• Logical Structures S provide meaning for the predicate symbols
• A set of individuals (nodes) U
• PS: US {0, 1}
• First-Order Formulas using , , , ,  express properties

l1

l2

l3

{l1, l2, l3},

[xl1 ,y null],

[l1  1, l2  2, l3  3],

[l1 l2, l2 l3, l3 null]

1

2

3

x

null

y

null

P = {x1, y1, car2, cdr2}

US={l1, l2, l3}

xS=[l1 1, l2  0, l3  0]

yS=[l1 0, l2  0, l3  0},

carS=[<l1, 1>  1, <l2, 2>  1, <l3, 3>  1, <l1, 0>  0, <l1,2 >  0, …, <l2, 1>  0, <l2,3 >  0, … ]

cdrS=[<l1, l1>  0, <l1 , l2>  1, <l1,l3 >  0, <l2, l1>  0, <l2, l2>  0, <l2,l3 >  1, <l3, l1>  0, <l3, l2>  0, <l3,l3 >  0 ]

1 if z(v1) = z(v2)

• v1=v2S(z) =

0 if z(v1)  z(v2)

Formal Semantics of First Order Formulae
• For a structure S=<US, PS>
• Formula  with free variables from a set LVar
• Assignment z: LVarUS
• S(z): {0, 1}
• 1S(z)=1
• 0S(z)=1

p(v1, v2, …, vk)S(z)=pS (z(v1), z(v2), …, z(vk))

Formal Semantics of 1st Order Formulae
• For a structure S = <US, PS>
• Formulae  with LVar free variables
• Assignment z: LVarUS
• S(z): {0, 1}
• 1 2S(z)=max (1 S(z), 2S(z))
• 1 2S(z)=min (1 S(z), 2S(z))
•  1S(z)=1- 1 S(z)
• v: 1S(z)=max {1 S(z[vu]) : u  US}
Using Predicate Logic to Describe States
• U=O
• For a pointer variable x define a unary predicate
• x(u)=1 when env(x)=u and u is an object
• Two binary predicates:
• car(u1, u2) = 1 when car(u1)=u2 and u2 is object
• cdr(u1, u2) = 1 when cdr(u1)=u2 and u2 is object
Semantics Described in Predicate Logic
• First-order structures
• hold recorded information about states
• Formulae
• means for querying structures describing states
• Predicate-update formulae
• operational semantics of statements
• update recorded information about states
Formulae for Querying Structures
• Are x and y pointer aliases?

v: x(v)  y(v)

• Does x point to a cell with a self cycle?

v : x(v)  n(v,v)

Yes

= 1

x

y

x

y

u1

Are x and y Pointer Aliases?

v: x(v)  y(v)

u2

u3

u4

u1

Predicate-Update Formulae for ‘y = x’
• x’(v) = x(v)
• y’(v) = x(v)
• t’(v) = t(v)
• n’(v1,v2) = n(v1,v2)
Predicate-Update Formulae for ‘x = x  n’
• x’(v) = v1: x(v1)  n(v1,v)
• y’(v) = y(v)
• t’(v) = t(v)
• n’(v1, v2) = n(v1, v2)

x

0

1

Predicate-Update Formulae for ‘x = x  n’

x’(v) = v1: x(v1)  n(v1,v)

x

y

u2

u3

u4

u1

Predicate-Update Formulae for ‘y  n = t’
• x’(v) = x(v)
• y’(v) = y(v)
• t’(v) = t(v)
• n’(v1,v2) = y(v1) n(v1,v2)  y(v1)  t(v2)

Two-valued logic

Three-valued logic

{0,1}

0

1

{0}

{1}

Two- vs. Three-Valued Logic

{0} {0,1}

{1} {0,1}

Three-valued logic

Two- vs. Three-Valued Logic

Two-valued logic

1

0

1

1

0

0

0

0

1

0

1

1

1

0

1

0

Two-valued logic

1

{1}

1

0

{0,1}

½

{0}

0

Two- vs. Three-Valued Logic

Three-valued logic

1/2

Information order

Three-Valued Logic
• 1: True
• 0: False
• 1/2: Unknown
• A join semi-lattice: 0  1 = 1/2
The Abstraction Principle
• Partition the individuals into equivalence classes based on the values of their unary predicates
• Collapse other predicates via 

x

x

u234

u1

u2

u3

u4

u1

0  1

0  0 0

The Abstraction Principle

x

u1

x

x

x

3

8

37

What StoresDoes a 3-Valued Structure Represent?
• Example 3-valued structure
• individuals: {u1}
• predicates:
• graphical presentation
• concrete stores represented

x

x

u

u

u1

u1

x

31

71

91

What StoresDoes a 3-Valued Structure Represent?
• Example 3-valued structure
• graphical presentation
• concrete stores

x

x

u

u

u1

u1

x

31

71

91

What StoresDoes a 3-Valued Structure Represent?
• Example 3-valued structure
• graphical presentation
• concrete stores
Property-Extraction Principle
• Questions about store properties can be answered conservatively by evaluating formulae in three-valued logic
• Formula evaluates to 1

 formula always holds in every store 

• Formula evaluates to 0

 formula never holds in any store 

• Formula evaluates to 1/2

 don’t know  

The Embedding Theorem (Intuition)

Property of Canonical Abstraction

• definitive information, i.e. with value 0 or 1 is preserved (conservatism)
• allows trading precision for efficiency (up to surprises)
The Embedding Theorem
• If a structure B can be embedded into a structure S via a surjective (onto) function f such that the interpretation of predicates is preserved, i.e., pB(u1, ..., uk)  pS(f(u1), ..., f(uk))
• Then, the interpretation of every formula  is preserved
• =1 in S  =1 in B
• =0 in S  =0 in B
• =1/2 in S  don’t know

Yes

x

y

u

u1

1

1

1

Are x and y Pointer Aliases?

v: x(v)  y(v)

Yes

1

1

1

1

Is Cell u Heap-Shared?

u

v1,v2: n(v1,u)  n(v2,u)  v1  v2

Maybe

x

y

u

u1

1

1/2

1/2

1/2

Is Cell u Heap-Shared?

v1,v2: n(v1,u)  n(v2,u)  v1  v2

The Instrumentation Principle
• So far, structures could be queried by evaluating a formula
• However, often low precision
• Increase precision by storing the truth-value of some designated formulae
• Introduce predicate-update formulae to update the extra predicates

x

31

71

91

is = 1

is = 0

is = 0

is = 0

is = 0

x

x

u

u

u1

u1

is = 1/2

is = 0

is = 0

Example: Heap Sharing

is(v) = v1,v2: n(v1,v)  n(v2,v)  v1  v2

x

31

71

91

is = 0

is = 0

is = 0

is = 0

x

x

u

u

u1

u1

is = 0

is = 0

Example: Heap Sharing

is(v) = v1,v2: n(v1,v)  n(v2,v)  v1  v2

x

31

71

91

is = 0

is = 0

is = 0

is = 0

Example: Heap Sharing

is(v) = v1,v2: n(v1,v)  n(v2,v)  v1  v2

is = 1

x

x

u

u

u1

u1

is = 0

is = 1

is = 0

No!

x

y

u

u1

1

1/2

1/2



1/2

Is Cell u Heap-Shared?

is = 0

is = 0

v1,v2: n(v1,u)  n(v2,u)  v1  v2

x

51

71

91

x

x

u

u

u1

u1

Example2: Sortedness

inOrder(v) = v1: n(v,v1)  dle(v, v1)

n

n

n

inOrder = 1

inOrder = 1

inOrder = 1

inOrder = 1

n

n

inOrder = 1

inOrder = 1

x

51

45

91

Example2: Sortedness

inOrder(v) = v1: n(v,v1)  dle(v, v1)

n

n

n

inOrder = 1

inOrder = 0

inOrder = 1

inOrder = 1

n

n

n

x

x

u

inOrder = 1

inOrder = 0

inOrder = 1

Shape Analysis viaAbstract Interpretation
• Iteratively compute a set of 3-valued structures for every program point
• Every statement transforms structures according to the predicate-update formulae
• use 3-valued logic instead of 2-valued logic
• use exactly the predicate-update formulae of the concrete semantics!!

Old:

New:

x

x

y

u

u1

y

u

u1

0

1/2

Predicate-Update Formulae for “x = x  n”

x’(v) =  v1: x(v1)  n(v1,v)

Summary
• Predicate logics allows to naturally express the operational semantics for languages with pointers and dynamically allocated objects
• 3-valued logic provides a sound solution