# Abstract interpretation

Post on 07-Jan-2016

35 views

Category:

## Documents

1 download

Embed Size (px)

DESCRIPTION

Abstract interpretation. Giorgio Levi Dipartimento di Informatica, Universit di Pisa levi@di.unipi.it http://www.di.unipi.it/~levi/levi.html. The general idea. a semantics any definition style, from a denotational definition to a detailed interpreter - PowerPoint PPT Presentation

TRANSCRIPT

<ul><li><p>Abstract interpretationGiorgio LeviDipartimento di Informatica, Universit di Pisalevi@di.unipi.ithttp://www.di.unipi.it/~levi/levi.html</p></li><li><p>The general ideaa semanticsany definition style, from a denotational definition to a detailed interpreterassigning meanings to programs on a suitable concrete domain (concrete computations domain)an abstract domain modeling some properties of concrete computations and forgetting about the remaining information (abstract computations domain)we derive an abstract semantics, which allows us to execute the program on the abstract domain to compute its abstract meaning, i.e., the modeled property</p></li><li><p>Concrete and Abstract Domainstwo complete partial ordersthe partial orders reflect precisionsmaller is betterconcrete domain ((C), , {}, C, , )has the structure of a powersetwe will see later why abstract domain (A, , bottom, top, lub, glb)each abstract value is a description of a set of concrete values</p></li><li><p>Concretizationconcrete domain ((C), , {}, C, , )abstract domain (A, , bottom, top, lub, glb)the meaning of abstract values is defined by a concretization function: A (C)a A, (a) is the set of concrete computations described by athats why the concrete domain needs to be a powersetthe concretization function must be monotonica1,a2 A, a1 a2 implies (a1) (a2)concretization preserves relative precision</p></li><li><p>Abstractionconcrete domain ((C), , {}, C, , )abstract domain (A, , bottom, top, lub, glb)every element of (C) should have a unique best (most precise) description in A this is possible if and only if A is a Moore familyclosed under glbin such a case, we can define an abstraction functiona: (C) A c (C), a(c) is the best abstract description of cthe abstraction function must be monotonicc1,c2 (C), c1 c2 implies a(c1) a(c2)abstraction preserves relative precision</p></li><li><p>Galois connectionGalois connection (insertion)x (C). x ((x)) y A. ((y)) y (y A. ((y)) = y) , mutually determine each other((C), , {}, C, , )(A, , bottom, top, lub, glb): A (C) (concretization)a: (C) A (abstraction) , monotonicthere may be loss of information (approximation) in describing an element of (C) by an element of A</p><p>(</p><p>(</p><p> C</p><p> A</p></li><li><p>Concrete semanticsthe concrete semantics is defined as the least or (greatest) fixpont of a concrete semantic evaluation function F defined on the domain C this does not necessarily mean that the semantic definition style is denotational! F is defined in terms of primitive semantic operations fi on C the abstract semantic evaluation function is obtained by replacing in F each concrete operation fi by a suitable abstract operationhowever, since the actual concrete domain is (C), we need first to lift the concrete semantics lfp F to a collecting semantics defined on (C)</p></li><li><p>Collecting semanticslifting lfp F to the powerset (to get the collecting semantics) is simply a conceptual operationcollecting semantics = {lfp F}we dont need to define a brand new collecting semantic evaluation function Fc on (C)we just need to reason in terms of liftings of all the primitive operations (and of F), while designing the abstract operations and establishing their propertiesin the following, by abuse of notation, we will use the same notation for the standard and the collecting (conceptually lifted) operations</p></li><li><p>Abstract operations: local correctnessan abstract operator fi defined on A is locally correct wrt a concrete operator fi if x1,..,xn (C). fi (x1,..,xn) (fi ((x1),..,(xn)))the concrete computation step is more precise than the concretization of the corresponding abstract computation stepa very weak requirement, which is satisfied, for example, by an abstract operator which always computes the worst abstract value topthe real issue in the design of abstract operations is therefore precision</p></li><li><p>Abstract operations: optimality and completenesscorrectness x1,..,xn (C). fi (x1,..,xn) (fi ((x1),..,(xn)))optimality y1,..,yn A. fi (y1,..,yn) = a(fi (g(y1),..,g(yn)))the most precise abstract operator fi correct wrt fia theoretical bound and basis for the design, rather then an implementable definitioncompleteness (exactness or absolute precision) x1,..,xn (C). a(fi (x1,..,xn)) = fi ((x1),..,(xn))no loss of information, the abstraction of the concrete computation step is exactly the same as the result of the corresponding abstract computation step</p></li><li><p>From local to global correctnessthe composition of locally correct abstract operations is locally correct wrt the composition of concrete operationscomposition does not preserve optimality, i.e., the composition of optimal operators may be less precise than the optimal abstract version of the compositionif we obtain F (abstract semantic evaluation function) by replacing in F every concrete semantic operation by a corresponding (locally correct) abstract operation, the local correctness property still holdsx (C). F (x) (F ((x)))local correctness implies global correctness, i.e., correctness of the abstract semantics wrt the concrete onelfp F (lfp F ) gfp F (gfp F )a(lfp F ) lfp F a(gfp F ) gfp F the abstraction of the concrete semantics is more precise than the abstract semantics</p></li><li><p>a (lfp F ) lfp F :why computing lfp F ?</p><p>lfp F cannot be computed in finitely many steps steps are in general requiredlfp F can be computed in finitely many steps, if the abstract domain is finite or at least noetheriandoes not contain infinite increasing chainsinteresting for static program analysis, where the fixpoint computation must terminatemost program properties considered in static analysis are undecidablewe accept a loss of precision (safe approximation) in order to make the analysis feasible</p></li><li><p>Applications</p><p>comparative semanticsa technique to reason about semantics at different level of abstractionnon-noetherian abstract domainabstraction without approximation (completeness) (lfp F) = lfp Fstatic analysis = effective computation of the abstract semanticsif the abstract domain is noetherian and the abstract operations are computationally feasibleif the abstract domain is non-noetherian or if the fixpoint computation is too complexuse widening operatorswhich effectively compute an (upper) approximation of lfp F one example later </p></li><li><p>The abstract interpretation framework((C), , {}, C, , ) (concrete domain)(A, , bottom, top, lub, glb)(abstract domain): A (C) monotonic (concretization function)a: (C) A monotonic (abstraction function)x (C). x ((x)) y A. ((y)) y(Galois connection) fi \$ fi | x1,..,xn (C). fi (x1,..,xn) (fi ((x1),..,(xn)))(local correctness)</p><p>critical choicesthe abstract domain to model the propertythe (possibly optimal) correct abstract operations</p></li><li><p>Other approaches and extensionsthere exist weaker versions of abstract interpretationwithout Galois connections (e.g., concretization function only)based on approximation operators (widening, narrowing)without explicit abstract domain (closure operators)the theory provides also several results on abstract domain designhow to combine domainshow to improve the precision of a domainhow to transform an abstract domain into a complete one...we will look at some of these results in the last lecture</p></li><li><p>A simple abstract interpreter computing Signsconcrete semanticsexecutable specification (in ML) of the denotational semantics of untyped l-calculus without recursionabstract semanticsabstract interpreter computing on the domain Sign</p></li><li><p>The language: syntaxtype ide = Id of stringtype exp = | Eint of int | Var of ide| Times of exp * exp| Ifthenelse of exp * exp * exp | Fun of ide * exp| Appl of exp * exp</p></li><li><p>A programFun(Id "x", Ifthenelse(Var (Id "x"), Times (Var (Id "x"), Var (Id "x")), Times (Var (Id "x"), Eint (-1))))</p><p>the ML expressionfunction x -&gt; if x=0 then x * x else x * (-1)</p></li><li><p>Concrete semanticsdenotational interpretereager semanticsseparation from the main semantic evaluation function of the primitive operationswhich will then be replaced by their abstract versionsabstraction of concrete valuesidentity function in the concrete semanticssymbolic non-deterministic semantics of the conditional </p></li><li><p>Semantic domains type eval = | Funval of (eval -&gt; eval) | Int of int | Wrong let alfa x = x type env = ide -&gt; eval let emptyenv (x: ide) = alfa(Wrong) let applyenv ((x: env), (y: ide)) = x y let bind ((r:env), (l:ide), (e:eval)) (lu:ide) = if lu = l then e else r(lu)</p></li><li><p>Semantic evaluation function let rec sem (e:exp) (r:env) = match e with| Eint(n) -&gt; alfa(Int(n))| Var(i) -&gt; applyenv(r,i)| Times(a,b) -&gt; times ( (sem a r), (sem b r)) | Ifthenelse(a,b,c) -&gt; let a1 = sem a r in (if valid(a1) then sem b r else (if unsatisfiable(a1) then sem c r else merge(a1,sem b r,sem c r))) | Fun(ii,aa) -&gt; makefun(ii,aa,r) | Appl(a,b) -&gt; applyfun(sem a r, sem b r) </p></li><li><p>Primitive operations </p><p>let times (x,y) = match (x,y) with |(Int nx, Int ny) -&gt; Int (nx * ny) | _ -&gt; alfa(Wrong) let valid x = match x with |Int n -&gt; n=0let unsatisfiable x = match x with |Int n -&gt; if n=0 then false else truelet merge (a,b,c) = match a with |Int n -&gt; if b=c then b else alfa(Wrong)| _ -&gt; alfa(Wrong) </p><p>let applyfun ((x:eval),(y:eval)) = match x with|Funval f -&gt; f y| _ -&gt; alfa(Wrong)</p><p>let rec makefun(ii,aa,r) = Funval(function d -&gt; if d = alfa(Wrong) then alfa(Wrong) else sem aa (bind(r,ii,d)))</p></li><li><p>From the concrete to the collecting semanticsthe concrete semantic evaluation functionsem: exp -&gt; env -&gt; evalthe collecting semantic evaluation functionsemc: exp -&gt; env -&gt; (eval)semc e r = {sem e r}all the concrete primitive operations have to be lifted to (eval) in the design of the abstract operations</p></li><li><p>Example of concrete evaluation </p><p># let esempio = sem( Fun (Id "x", Ifthenelse (Var (Id "x"), Times (Var (Id "x"), Var (Id "x")), Times (Var (Id "x"), Eint (-1)))) ) emptyenv;;val esempio : eval = Funval </p><p># applyfun(esempio,Int 0);;- : eval = Int 0# applyfun(esempio,Int 1);;- : eval = Int -1# applyfun(esempio,Int(-1));;- : eval = Int 1</p><p>in the virtual collecting versionapplyfunc(esempio,{Int 0,Int 1}) = {Int 0, Int -1}applyfunc(esempio,{Int 0,Int -1}) = {Int 0, Int 1}applyfunc(esempio,{Int -1,Int 1}) = {Int 1, Int -1}</p></li><li><p>From the collecting to the abstract semanticsconcrete domain: ((ceval), )concrete (non-collecting) environment: cenv = ide -&gt; cevalabstract domain: (eval, )abstract environment: env = ide -&gt; evalthe collecting semantic evaluation functionsemc: exp -&gt; env -&gt; (ceval)the abstract semantic evaluation functionsem: exp -&gt; env -&gt; eval</p></li><li><p>The Sign Abstract Domainconcrete domain ((Z), ) sets of integersabstract domain (Sign, )</p><p> 0-</p><p> top</p><p> 0</p><p> -</p><p> +</p><p> bot</p><p> 0+</p></li><li><p>Redefining eval for Signtype ceval = Funval of (ceval -&gt; ceval) | Int of int | Wrongtype eval = Afunval of (eval -&gt; eval) | Top | Bottom | Zero | Zerop | Zerom | P | Mlet alfa x = match x with Wrong -&gt; Top | Int n -&gt; if n = 0 then Zero else if n &gt; 0 then P else M</p><p>the partial order relation the relation shown in the Sign lattice, extended with its lifting to functions there exist no infinite increasing chainswe might add a recursive function construct and find a way to compute the abstract least fixpoint in a finite number of stepslub and glb of eval are the obvious onesconcrete domain: ((ceval), , {}, ceval, , )abstract domain: (eval, , Bottom, Top, lub, glb) </p></li><li>Concretization functionconcrete domain: ((ceval), , {}, ceval, , )abstract domain: (eval, , Bottom, Top, lub, glb)gs(x) ={}, if x = Bottom{Int(y) |y&gt;0}, if x = P{Int(y) |y0}, if x = Zerop{Int(0)}, if x = Zero{Int(y)|y0}, if x = Zerom{Int(y)|y</li><li><p>Abstraction functionconcrete domain: ((ceval), , {}, ceval, , )abstract domain: (eval, , Bottom, Top, lub, glb)as(y) = glb{Bottom, if y = {}M, if y {Int(z)| z0}Top, if y cevallub{Afunval(f)| Funval(g) gs(Afunval(f))}, if y {Funval(g)} &amp; Funval(g) y}} </p></li><li><p>Galois connectionas and gs are monotonicdefine a Galois connection </p></li><li><p>Times Signoptimal (hence correct) and complete (no approximation) </p><p>bot</p><p> -</p><p> 0-</p><p> 0 </p><p> 0+</p><p> +</p><p>top</p><p>bot</p><p>bot</p><p>bot</p><p>bot</p><p>bot</p><p>bot</p><p>bot</p><p>bot</p><p> -</p><p>bot</p><p> +</p><p> 0+</p><p> 0</p><p> 0-</p><p> -</p><p>top</p><p> 0-</p><p>bot</p><p> 0+</p><p> 0+</p><p> 0</p><p> 0-</p><p> 0-</p><p>top</p><p> 0</p><p>bot</p><p> 0</p><p> 0</p><p> 0</p><p> 0</p><p> 0</p><p> 0</p><p> 0+</p><p>bot</p><p> 0-</p><p> 0-</p><p> 0</p><p> 0+</p><p> 0+</p><p>top</p><p> +</p><p>bot</p><p> -</p><p> 0-</p><p> 0</p><p> 0+</p><p> +</p><p>top</p><p>top</p><p>bot</p><p>top</p><p>top</p><p> 0</p><p>top</p><p>top</p><p>top</p></li><li><p>Abstract operationsin addition to times and lublet valid x = match x with | Zero -&gt; true | _ -&gt; falselet unsatisfiable x = match x with | M -&gt; true| P -&gt; true| _ -&gt; falselet merge (a,b,c) = match a with | Afunval(_) -&gt; Top| _ -&gt; lub(b,c)let applyfun ((x:eval),(y:eval)) = match x with |Afunval f -&gt; f y| _ -&gt; alfa(Wrong)let rec makefun(ii,aa,r) = Afunval(function d -&gt; if d = alfa(Wrong) then d else sem aa (bind(r,ii,d))) sem is left unchanged </p></li><li><p>An example of abstract evaluation# let esempio = sem( Fun (Id "x", Ifthenelse (Var (Id "x"), Times (Var (Id "x"), Var (Id "x")), Times (Var (Id "x"), Eint (-1)))) ) emptyenv;;val esempio : eval = Afunval # applyfun(esempio,P);;- : eval = M# applyfun(esempio,Zero);;- : eval = Zero# applyfun(esempio,M);;- : eval = P# applyfun(esempio,Zerop);;- : eval = Top# applyfun(esempio,Zerom);;- : eval = Zerop# applyfun(esempio,Top);;- : eval = Topapplyfunc(esempio,{Int 0,Int 1}) = {Int 0, Int -1}applyfunc(esempio,{Int 0,Int -1}) = {Int 0, Int 1}applyfunc(esempio,{Int -1,Int 1}) = {Int 1, Int -1}wrt the abstraction of the concrete (collecting) semantics, approximation for Zeropno abstract operations which invent the values Zerop and Zerom which are the only ones on which the conditional takes both ways and can introduce approximation</p></li><li><p>Recursionthe language has no recursionfixpoint computations are not needed if (sets of) functions on the concrete domain are abstracted to functions on the abstract domain, we must be careful in the case of recursive definitionsa nave solution might cause the application of a recursive abstract function to diverge, even if the domain is finitewe might never get rid of recursion because the guard in the conditional is not valid or satisfiablewe cannot explicitely compute the fixpoint, because equivalence on functions cannot be expressed termination can only be obtained by a loop checking mechanism (finitely many different recursive calls)we will see a different solution in a case where (sets of) functions are abstracted to non functional valuesthe explicit fixpoint computation will then be possible</p></li></ul>