<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3742008638855759502</id><updated>2011-07-28T21:56:39.412-07:00</updated><category term='parallelism'/><category term='reading'/><category term='symbolic execution'/><category term='se'/><category term='logic'/><category term='model checking'/><title type='text'>Zak's research blog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://zkincaid.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://zkincaid.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>zkincaid</name><uri>http://www.blogger.com/profile/08127275535283166049</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>14</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3742008638855759502.post-2336027466693859064</id><published>2009-09-22T07:10:00.000-07:00</published><updated>2009-09-22T07:23:59.766-07:00</updated><title type='text'>This is not a particularly good way to spend time</title><content type='html'>I've written many hello world program in my lifetime.  This one took me the longest to write.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import sys&lt;br /&gt;w = 0&lt;br /&gt;&lt;br /&gt;fl=reduce&lt;br /&gt;&lt;br /&gt;o="he = lambda l:fl(lambda x, (o,z):x.replace(o,z), l)\np=lambda(f, x): \"w = \"  + str(w)+ \"\\n\\nfl=reduce\\n\\no=\\\"\"+f(x) + \"\\\"\"\ndef rg2(l):\n  d=0\n  while l&gt;0:\n    l=l&gt;&gt;1\n    d= 1+d\n  return d\nq = lambda d: he([d,(\"\\\\\", \"\\\\\\\\\"),(\"\\\"\", \"\\\\\\\"\"),(\"\\n\",\"\\\\n\")])\nsys.stdout.write(o[w])\nif w &lt; 173:\n  w = w+(3*rg2(w))+1\n  exec(p((q,o)) + \"\\n\" + o)"&lt;br /&gt;he = lambda l:fl(lambda x, (o,z):x.replace(o,z), l)&lt;br /&gt;p=lambda(f, x): "w = "  + str(w)+ "\n\nfl=reduce\n\no=\""+f(x) + "\""&lt;br /&gt;def rg2(l):&lt;br /&gt;  d=0&lt;br /&gt;  while l&gt;0:&lt;br /&gt;    l=l&gt;&gt;1&lt;br /&gt;    d= 1+d&lt;br /&gt;  return d&lt;br /&gt;q = lambda d: he([d,("\\", "\\\\"),("\"", "\\\""),("\n","\\n")])&lt;br /&gt;sys.stdout.write(o[w])&lt;br /&gt;if w &lt; 173:&lt;br /&gt;  w = w+(3*rg2(w))+1&lt;br /&gt;  exec(p((q,o)) + "\n" + o)&lt;br /&gt;  sys.stdout.write("\n")&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;... anybody know how it works?   The poor choice of variable names and non-standard spacing are, unfortunately, necessary.&lt;br /&gt;&lt;br /&gt;EDIT: interestingly, one of the lines seems to be truncated in blogger.  But copy+paste seems to get the full line.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3742008638855759502-2336027466693859064?l=zkincaid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zkincaid.blogspot.com/feeds/2336027466693859064/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3742008638855759502&amp;postID=2336027466693859064' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/2336027466693859064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/2336027466693859064'/><link rel='alternate' type='text/html' href='http://zkincaid.blogspot.com/2009/09/this-is-not-particularly-good-way-to.html' title='This is not a particularly good way to spend time'/><author><name>zkincaid</name><uri>http://www.blogger.com/profile/08127275535283166049</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3742008638855759502.post-6204359026106028625</id><published>2009-03-15T18:18:00.000-07:00</published><updated>2009-03-15T20:23:42.941-07:00</updated><title type='text'>Reading last week</title><content type='html'>Patrick Cousot: "Abstract Interpretation Based Formal Methods and Future Challenges" (&lt;a href="http://www.di.ens.fr/%7Ecousot/publications.www/Cousot-LNCS2000-sv-sb.pdf"&gt;pdf&lt;/a&gt;)&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The basic idea (I think): project values onto abstract domains.  Lift all operations to those abstract domains.  Replace conditional branches with nondeterministic ones.  Compute fixpoints in the abstract domain, then map back to the concrete domain and query the resulting structure.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Reaffirms my feeling that abstract interpretation is the "right way" to do program analysis.&lt;/li&gt;&lt;li&gt;Unfortunately, not much in the way of math.  I feel like I understand more about abstract interpretation, but only in a vague, handwavey-type of way&lt;/li&gt;&lt;/ul&gt;Patrick Lincoln: "Linear Logic" (&lt;a href="http://www.csl.sri.com/%7Elincoln/papers/sigact92.ps"&gt;ps&lt;/a&gt;)&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Nice introduction to linear logic; would have been more helpful if I knew less about linear logic.  Handy list of sequent calculus rules on the back!&lt;/li&gt;&lt;/ul&gt;Tanel Tammet: "Proof Strategies in Linear Logic" (&lt;a href="http://www.springerlink.com/content/h152101599870734/"&gt;springerlink&lt;/a&gt;)&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I skipped a (long) section of this paper because it deals with resolution theorem proving in LL, and I'm thinking the prover I'm working on is going to be bottom-up.  I also don't really know what the computational interpretation of resolution is, or if there is one.&lt;/li&gt;&lt;li&gt;Formalized a few intuitive ideas, said how they were proved (it's likely that the proofs are straightforward)&lt;/li&gt;&lt;li&gt;Gave me a better idea of what focusing is.  I should probably read the references for that subsection.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Silvia Richter, Malte Helmert, Matthias Westphal: "Landmarks Revisited" (&lt;a href="http://www.aaai.org/Papers/AAAI/2008/AAAI08-155.pdf"&gt;pdf&lt;/a&gt;)&lt;/p&gt;&lt;ul&gt;&lt;li&gt;A landmark for a planning task is a proposition that must hold at some point in any solution to the task.  Given the landmarks of a task and the ordering between them gives a planner an idea of the "shape" of solution plans.&lt;/li&gt;&lt;li&gt;Computing landmarks and their orderings is (PSPACE-) hard.  But a good way to extract some of them is to start at the goals of the task (which are trivially landmarks), and work backwards (a precondition of every task that achieves a landmark is a landmark, etc)&lt;/li&gt;&lt;li&gt;Landmarks/orderings can be  used to estimate goal distances and also in action selection&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style="margin: 0px; text-indent: 0px;"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style="margin: 0px; text-indent: 0px;"&gt;Hector Palacios, Hector Geffner: "From Conformant Into Classical Planning: Efficient Translations That May be Complete Too" (&lt;a href="www.tecn.upf.es/%7Ehgeffner/icaps07.pdf"&gt;pdf&lt;/a&gt;)&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Conformant planning is a generalization of classical planning in which the initial state is only partially known (specified by a CNF formula)&lt;/li&gt;&lt;li&gt;Epistemic logic is a modal logic that can be used to reason about knowledge rather than truth (a fact can be true without my knowledge).  Conformant planning tasks can be translated naturally to epistemic logic, where each literal is tagged by its "world" (the conditions that must have held in the initial state for the fact to hold - which actually specifies a set of initial states).  Merge actions are used to combine knowledge about different worlds.&lt;/li&gt;&lt;li&gt;This translation can then be encoded propositionally, and the planning task can be solved by a classical planner.&lt;/li&gt;&lt;li&gt;It's possible to place bounds on how "specific" the world tags need to be for the translation to remain complete.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style="margin: 0px; text-indent: 0px;"&gt;&lt;!--EndFragment--&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3742008638855759502-6204359026106028625?l=zkincaid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zkincaid.blogspot.com/feeds/6204359026106028625/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3742008638855759502&amp;postID=6204359026106028625' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/6204359026106028625'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/6204359026106028625'/><link rel='alternate' type='text/html' href='http://zkincaid.blogspot.com/2009/03/reading-last-week.html' title='Reading last week'/><author><name>zkincaid</name><uri>http://www.blogger.com/profile/08127275535283166049</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3742008638855759502.post-331686241524539650</id><published>2009-03-02T08:25:00.000-08:00</published><updated>2009-03-08T16:22:37.368-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='reading'/><title type='text'>Rory - you are the worst person.  The worst.</title><content type='html'>Malte Helmert: "A Planning Heuristic Based on Causal Graph Analysis" (&lt;a href="http://www-rcf.usc.edu/%7Eskoenig/icaps/icaps04/icapspapers/ICAPS04HelmertM.pdf"&gt;pdf&lt;/a&gt;)&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Advocates multi-valued planning domains, because the extra structure can be exploited to obtain effective heuristics&lt;/li&gt;&lt;li&gt;Defines a causal graph, which is basically represents the "may interact with" relation among variables in a planning task&lt;/li&gt;&lt;li&gt;Defines a domain transition graph, which basically represents the paths a variable can make through its domain using the supplied actions (eg, a traffic light needs to go through a "yellow" state to transition from "green" to "red").&lt;/li&gt;&lt;li&gt;Defines a heuristic based on these two structures that appears to be pretty effective on several of the IPC domains.  The heuristic is computed using costs to move each variable through its domain, where costs are computed by a modification of Dijkstra's algorithm on the domain transition graph.  The edge weights of a variable's DTG are computed on-the-fly using information from the DTGs of the causal predecessors of the variable.  This makes cyclic causal graphs awkward.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Malte Helmert, Hector Geffner: "Unifying the Causal Graph and Additive Heuristics" (&lt;a href="http://www.blogger.com/www.aaai.org/Papers/ICAPS/2008/ICAPS08-018.pdf"&gt;pdf&lt;/a&gt;)&lt;br /&gt;&lt;ul&gt;&lt;li&gt;More multi-valued planning&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Gives a declarative formulation of the causal graph and additive heuristics (that doesn't rely on any auxiliary strucutures like causual graphs, domain transition graphs, or planning graphs).&lt;/li&gt;&lt;li&gt;Shows how to obtain a heuristic that (sorta) generalizes both these heuristics.  Really, the equations that define it look like the additive heuristic, and the actual meaning behind those equations is more like the causal graph heuristic.  One notable success of this formalization is that it gets rid of some of the awkwardness that occurs in the CG heuristic when the causal graph contains cycles.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Patrik Haslum, Blai Bonet, Hector Geffner: "New Admissible Heuristics for Domain-Independent Planning" (&lt;a href="http://www.blogger.com/www.ldc.usb.ve/%7Ebonet/reports/AAAI05-pdbs.pdf"&gt;pdf&lt;/a&gt;)&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I wasn't crazy about this paper.  It seemed very... ad hoc in places.  This is possibly because I'm new to planning and I haven't built up my intuition yet.&lt;/li&gt;&lt;li&gt;One heuristic is based on another admissible heuristic which estimates the cost of achieving a set of goals by estimating (through recursive application of the heuristic) the cost of achieving a (fixed-size) subset of those goals.  The idea of the paper is to partition the set of actions and compute the heuristic for each cell in the parition, relaxing the cost of each action not in the current cell, and then adding the results.  It retains admissibility because the cells are disjoint so actions can't be counted twice.  It is intuitively &lt;span style="font-style: italic;"&gt;sometimes&lt;/span&gt; bigger, because actions that were "free" in the previous heuristic because of the fixed-size subset limitation may have to be paid for in the new heuristic.  But it seems like the heuristic can also be smaller if there are multiple actions that can achieve the same goals and we choose the parition poorly.&lt;/li&gt;&lt;li&gt;The other heuristic is based on pattern databases, and hopefully its description will require less typing then the previous.  The gist is that some mutex relations between variables are easy to find (particularly those that appear as a result of encoding multi-value variables into a propositional domain).  We can exploit these relationships to prune inconsistent branches of the abstract search space (which are created by abstracting away information required to maintain the mutex relation).&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Lucas Dixon, Alan Smaill, Tracy Tsang: "Plans, Actions and Dialogues using Linear Logic" (&lt;a href="http://dream.inf.ed.ac.uk/projects/dialoguell/dialoguell.pdf"&gt;pdf&lt;/a&gt;), and&lt;br /&gt;Lucas Dixon, Alan Smaill, Alan Bundy: "Planning as Deductive Synthesis in Intuitionist Linear Logic" (&lt;a href="http://homepages.inf.ed.ac.uk/ldixon/papers/infrep-06-planill.pdf"&gt;pdf&lt;/a&gt;)&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Linear logic is obtained from classical logic by rejecting the inference rules of weakening and contraction.  This allows for an interpretation of LL in which the proofs are essentially about &lt;span style="font-style: italic;"&gt;resources&lt;/span&gt; rather than logical facts.  A logical fact may be used arbitrarily many times (by contraction), or not used at all (by weakening).  This is not the case for resources - I cannot use the fact that I have a quarter to buy myself a red gum ball &lt;span style="font-style: italic;"&gt;and&lt;/span&gt; a green one; I cannot simply "forget" that I have an income so that I won't have to pay income taxes.  Similarly, planning tasks feature &lt;span style="font-style: italic;"&gt;fluents&lt;/span&gt;, whose truth value changes during plan execution. Interestingly, planning problems can be encoded into LL sequents such that each solution plan of a task will have a corresponding proof in LL.&lt;/li&gt;&lt;li&gt;Limiting LL to the intuitionistic fragment allows us to give a computational interpretation of the logic.  Proofs in intuitionistic logics are &lt;span style="font-style: italic;"&gt;constructive&lt;/span&gt;, which allows a proof of a sequent $\Gamma \vdash G$ to be seen as a program that, given objects corresponding to each type of $\Gamma$, constructs an object of type $G$.  This computational interpretation of ILL tightens the correspondence between linear logic and planning: proofs of an encoded planning task can be seen as &lt;span style="font-style: italic;"&gt;executable plans&lt;/span&gt;.  That is, not only do plans map into ILL proofs, but ILL proofs map to plans.  Thus, classical planning can be reduced to ILL theorem proving (the opposite reduction, however, is not possible).&lt;/li&gt;&lt;li&gt;The first paper is mostly about encoding multi-agent planning problems featuring dialogue into ILL, and then solving the planning problems using &lt;a href="http://www.lix.polytechnique.fr/Labo/Dale.Miller/lolli/"&gt;Lolli&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The second paper is about a writing a prover for ILL in Isabelle/HOL.  In particular, it features a neat way to handle $\otimes$R which they call lazy context splitting (which is pretty much what it sounds like).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Will become the basis of my &lt;a href="http://www.cs.toronto.edu/%7Esheila/2542/w09/"&gt;Topics in KR&amp;amp;R course&lt;/a&gt;.  Basically, I'm hoping to use planning techniques in an efficient(ish) theorem prover for intuitionist linear logic.  Most of what I wrote here was stolen from my proposal.&lt;/li&gt;&lt;li&gt;Interestingly, the idea for this project came from &lt;a href="http://homepages.inf.ed.ac.uk/ldixon/"&gt;Lucas Dixon&lt;/a&gt;, who I emailed looking for the IsaPlanner email and ended up exchanging a few emails.  He suggested the project and offered to advise me on it, which I'm pretty excited about.  Lucas is a nice guy.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Vijay D'Silva, Daniel Kroening, and Georg Weissenbacher: "A Survey of Automated Techniques for Formal Software Verification" (&lt;a href="http://www.blogger.com/www.csee.usf.edu/%7Ezheng/lib/verification/general/survey-sw-fv.pdf"&gt;pdf&lt;/a&gt;)&lt;br /&gt;(Survey paper, so here's a list of things that were mentioned that I'd like to know more about)&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Abstract interpretation&lt;/li&gt;&lt;li&gt;Shape analysis&lt;/li&gt;&lt;li&gt;Predicate abstraction&lt;/li&gt;&lt;li&gt;Counterexample-guided abstraction refinement&lt;/li&gt;&lt;/ul&gt;Bonus!  Random idea I've been thinking about lately: declarative concurrency.  Instead of inventing concurrency mechanisms every time we need something done and then verify that our programs do not violate those mechanisms, it would be neat to specify the constraints that can't be violated and leave it to the compiler to come up with the mechanisms to guarantee this.  For example, I can write a function &lt;tt&gt;atomic&lt;/tt&gt; that just evaluates a thunk, but also give the compiler a constraint that no other thread can access shared memory while a function is in an atomic evaluation context.  (Ok, that example's a bit awkward because then we'd also have to specify that atomic created an evaluation context or else we'd "forget" we're in an atomic context (call-by-name), or never realize that we're in one (call-by-value).  But you get the picture).  Thinking further along these lines, can we program in temporal logic?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3742008638855759502-331686241524539650?l=zkincaid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zkincaid.blogspot.com/feeds/331686241524539650/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3742008638855759502&amp;postID=331686241524539650' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/331686241524539650'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/331686241524539650'/><link rel='alternate' type='text/html' href='http://zkincaid.blogspot.com/2009/03/rory-you-are-worst-person-worst.html' title='Rory - you are the worst person.  The worst.'/><author><name>zkincaid</name><uri>http://www.blogger.com/profile/08127275535283166049</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3742008638855759502.post-6350723816320579813</id><published>2009-02-24T11:22:00.000-08:00</published><updated>2009-03-01T20:32:04.221-08:00</updated><title type='text'>Reading last week</title><content type='html'>Vineet Kahlon, Franjo Ivančić, Aarti Gupta: "Reasoning about Threads Communicating via Locks"&lt;br /&gt;&lt;blockquote&gt;We propose a new technique for the static analysis of concurrent programs comprised of multiple threads. In general, the problem is known to be undecidable even for programs with only two threads but where the threads communicate using CCS-style pairwise rendezvous [11]. However, in practice, a large fraction of concurrent programs can either be directly modeled as threads communicating solely using locks or can be reduced to such systems either by applying standard abstract interpretation techniques or by exploiting separation of control from data. For such a framework, we show that for the commonly occurring case of threads with nested access to locks, the problem is efficiently decidable. Our technique involves reducing the analysis of a concurrent program with multiple threads to individually analyzing augmented versions of the given threads. This not only yields decidability but also avoids construction of the state space of the concurrent program at hand and thus bypasses the state explosion problem making our technique scalable. We go on to show that for programs with threads that have non-nested access to locks, the static analysis problem for programs with even two threads becomes undecidable even for reachability, thus sharpening the result of [11]. As a case study, we consider the Daisy file system [1] which is a benchmark for analyzing the efficacy of different methodologies for debugging concurrent programs and provide results for the detection of several bugs.&lt;/blockquote&gt;&lt;br /&gt;Vineet Kahlon, Aarti Gupta: "An Automata-Theoretic Approach for Model Checking Threads for LTL Properties"&lt;br /&gt;&lt;blockquote&gt;In this paper, we propose a new technique for the verification of concurrent multi-threaded programs. In general, the problem is known to be undecidable even for programs with just two threads. However, we exploit the observation that, in practice, a large fraction of concurrent programs can either be modeled as pushdown systems communicating solely using locks or can be reduced to such systems by applying standard abstract interpretation techniques or by exploiting separation of data from control. Moreover, standard programming practice guidelines typically recommend that programs use locks in a nested fashion. In fact, in languages like Java and C#, locks are guaranteed to be nested. For such a framework, we show, by using the new concept of Lock Constrained Multi-Automata Pair (LMAP), that pre*-closures of regular sets of states can be computed efficiently. This is accomplished by reducing the pre*-closure computation for a regular set of states of a concurrent program with nested locks to those for its individual threads. Leveraging this new technique then allows us to formulate a fully automatic, efficient and exact (sound and complete) decision procedure for model checking threads communicating via nested locks for indexed linear-time temporal logic formulae&lt;/blockquote&gt;&lt;br /&gt;Erica Melis: "Proof Planning with Multiple Strategies"&lt;br /&gt;&lt;blockquote&gt;This paper addresses the integration of several planning strategies as a way to cope with otherwise intractable search spaces in proof planning. It discusses why it is reasonable to employ several refinement strategies and shows that it can be even necessary in order to find a proof plan at all. Motivated by our experiences in proof planning, the paper introduces new refinement strategies. Since choosing among strategies requires additional control some exemplary control knowledge that can be employed in proof planning is presented.&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3742008638855759502-6350723816320579813?l=zkincaid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zkincaid.blogspot.com/feeds/6350723816320579813/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3742008638855759502&amp;postID=6350723816320579813' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/6350723816320579813'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/6350723816320579813'/><link rel='alternate' type='text/html' href='http://zkincaid.blogspot.com/2009/02/reading-last-week_24.html' title='Reading last week'/><author><name>zkincaid</name><uri>http://www.blogger.com/profile/08127275535283166049</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3742008638855759502.post-2469307616029523770</id><published>2009-02-22T16:36:00.000-08:00</published><updated>2009-02-22T16:49:43.921-08:00</updated><title type='text'>Reading last week</title><content type='html'>&lt;span class="headNavBlueXLarge2"&gt;Vineet Kahlon: "Parameterization as Abstraction: A Tractable Approach to the Dataflow Analysis of Concurrent Programs"&lt;br /&gt;&lt;/span&gt;&lt;blockquote&gt;Dataflow analysis for concurrent programs is a problem of critical importance but, unfortunately, also an undecidable one. A key obstacle is to determine precisely how dataflow facts at a location in a given thread could be affected by operations of other threads.This problem, in turn, boils down to pairwise reachability, i.e., given program locations c&lt;sub&gt;1&lt;/sub&gt; and c&lt;sub&gt;2&lt;/sub&gt; in two threads T&lt;sub&gt;1&lt;/sub&gt; and T&lt;sub&gt;2&lt;/sub&gt;, respectively, determining whether c1 and c2 are simultaneously reachable in the presence of constraints imposed by synchronization primitives. Unfortunately, pairwise reachability is undecidable for most synchronization primitives. However, we leverage the surprising result that the closely related problem of parameterized pairwise reachability of c&lt;sub&gt;1&lt;/sub&gt; and c&lt;sub&gt;2&lt;/sub&gt;, i.e., whether for some n&lt;sub&gt;1&lt;/sub&gt; and n&lt;sub&gt;2&lt;/sub&gt;, c&lt;sub&gt;1&lt;/sub&gt; and c&lt;sub&gt;2&lt;/sub&gt; are simultaneously reachable in the program T&lt;sub&gt;1&lt;/sub&gt; n&lt;sub&gt;1||&lt;/sub&gt;T&lt;sub&gt;2&lt;/sub&gt; n&lt;sub&gt;2&lt;/sub&gt; comprised of n&lt;sub&gt;1&lt;/sub&gt; copies of T&lt;sub&gt;1&lt;/sub&gt; and n&lt;sub&gt;2&lt;/sub&gt; copies of T&lt;sub&gt;2&lt;/sub&gt;,is not only decidable for many primitives, but efficiently so. Although parameterization makes pairwise reachability tractable it may over-approximate the set of pairwise reachable locations and can, therefore, be looked upon as an abstraction technique.Where as abstract interpretation is used for control and data abstractions, we propose the use of parameterization as an abstraction for concurrency. Leveraging abstract interpretation in conjunction with parameterization allows us to lift two desirable properties of sequential dataflow analysis to the concurrent domain, i.e., precision and scalability.&lt;/blockquote&gt;Ravi Chugh, Jan W. Voung, Ranjit Jhala, Sorin Lerner: "Dataflow Analysis for Concurrent Programs using Datarace Detection"&lt;br /&gt;&lt;blockquote&gt;Dataflow analyses for concurrent programs differ from their single-threaded counterparts in that they must account for shared memory locations being overwritten by concurrent threads. Existing dataflow analysis techniques for concurrent programs typically fall at either end of a spectrum: at one end, the analysis conservatively kills facts about all data that might possibly be shared by multiple threads; at the other end, a precise thread-interleaving analysis determines which data may be shared, and thus which dataflow facts must be invalidated. The former approach can suffer from imprecision, whereas the latter does not scale.&lt;br /&gt;   We present RADAR, a framework that automatically converts a dataflow analysis for sequential programs into one that is correct for concurrent programs. RADAR uses a race detection engine to kill the dataflow facts, generated and propagated by the sequential analysis, that become invalid due to concurrent writes. Our approach of factoring all reasoning about concurrency into a race detection engine yields two benefits. First, to obtain analyses for code using new concurrency constructs, one need only design a suitable race detection engine for the constructs. Second, it gives analysis designers an easy way to tune the scalability and precision of the overall analysis by only modifying the race detection engine. We describe the RADAR framework and its implementation using a pre-existing race detection engine. We show how RADAR was used to&lt;br /&gt;generate a concurrent version of a null-pointer dereference analysis, and we analyze the result of running the generated concurrent analysis on several benchmarks.&lt;/blockquote&gt;Alan Bundy: "The Use of Explicit Plans to Guide Inductive Proofs"&lt;br /&gt;&lt;blockquote&gt;We propose the use of explicit proof plans to guide the search for a proof in automatic theorem proving. By representing proof plans as the specifications of LCF-like tactics, [Gordon et al 79], and by recording these specifications in a sorted meta-logic, we are able to reason about the conjectures to be proved and the methods available to prove them. In this way we can build proof plans of wide generality, formally account for and predict their successes and failures, apply them flexibly, recover from their failures, and learn them from example proofs. We illustrate this technique by building a proof plan based on a simple subset of the implicit proof plan embedded in the Boyer-Moore theorem prover, [Boyer &amp;amp; Moore 79].&lt;/blockquote&gt;&lt;span class="headNavBlueXLarge2"&gt;&lt;/span&gt;Manfred Kerber: "Proof Planning: A Practical Approach to Mechanized Reasoning in Mathemtics"&lt;br /&gt;&lt;blockquote&gt;The attempt to mechanize mathematical reasoning belongs to the first experiments in artificial intelligence in the 1950 (Newell et al., 1957). However, the idea to automate or to support deduction turned out to be harder than originally expected. This can not at least be seen in the multitude of approaches that were pursued to model different aspects of mathematical reasoning. There are different dimension according to which these systems can be classified: input language (e.g., order-sorted first-order logic), calculus (e.g., resolution), interaction level (e.g., batch mode), proof output (e.g., refutation graph), and the purpose (e.g., automated theorem proving) as well as many more subtle points concerning the fine tuning of the proof search.&lt;br /&gt;    In this contribution the proof planning approach will be presented. Since it is not the mainstream approach to mechanized reasoning, it seems to be worth to look at it in a more principled way and to contrast it to other approaches.  In order to do so I categorize the systems according to their purpose. The different attempts can be roughly categorized into three classes: machine-oriented automated theorem provers, interactive proof checkers, and human-oriented theorem provers. In the rest of the introduction we shall take a closerlook at these different categories.&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3742008638855759502-2469307616029523770?l=zkincaid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zkincaid.blogspot.com/feeds/2469307616029523770/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3742008638855759502&amp;postID=2469307616029523770' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/2469307616029523770'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/2469307616029523770'/><link rel='alternate' type='text/html' href='http://zkincaid.blogspot.com/2009/02/reading-last-week_22.html' title='Reading last week'/><author><name>zkincaid</name><uri>http://www.blogger.com/profile/08127275535283166049</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3742008638855759502.post-2894715547347714043</id><published>2009-02-10T10:49:00.001-08:00</published><updated>2009-02-15T19:24:24.363-08:00</updated><title type='text'>Reading last week</title><content type='html'>Thomas Reps, Susan Horwitz, and Mooly Sagiv: "Precise Interprocedural Dataflow Analysis via Graph Reachability"&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;The paper shows how a large class of interprocedural dataflow-analysis problems can be solved precisely in polynomial time by transforming them into a special kind of graph-reachability problem. The only restrictions are that the set of dataflow facts must be a finite set, and that the dataflow functions must distribute over the confluence operator (either union or intersection). This class of problems includes—but is not limited to—the classical separable problems (also known as “gen/kill” or “bit-vector” problems)—e.g., reaching definitions, available expressions, and live variables. In addition, the class of problems that our techniques handle includes many non-separable problems, including truly-live variables, copy constant pro pagation, and possibly-uninitialized variables.&lt;br /&gt; Results are reported from a preliminary experimental study of C programs (for the problem of finding possibly-uninitialized variables).&lt;br /&gt;&lt;/blockquote&gt;Jorg Hoffmann, Berhard Nebel: "The FF Planning System: Fast Plan Generation Through Heuristic Search"&lt;br /&gt;&lt;blockquote&gt;We describe and evaluate the algorithmic techniques that are used in the FF planning system. Like the HSP system, FF relies on forward state space search, using a heuristic that estimates goal distances by ignoring delete lists. Unlike HSP's heuristic, our method does not assume facts to be independent. We introduce a novel search strategy that combines hill-climbing with systematic search, and we show how other powerful heuristic information can be extracted and used to prune the search space. FF was the most successful automatic planner at the recent AIPS-2000 planning competition. We review the results of the competition, give data for other benchmark domains, and investigate the reasons for the runtime performance of FF compared to HSP&lt;/blockquote&gt;&lt;br /&gt;Checked out the first chapter of "Proofs and Types" by Jean-Yves Girard; "Programming in Martin-Lof's Type Theory: An Introduction" by Bengt Nordstrom, Kent Petersson, and Jan M. Smith; "Rippling: Meta-level Guidance for Mathematical Reasoning" by Alan Bundy, David Basin, Dieter Hutter, and Andrew Ireland; "Interactive Theorem Proving and Program Development" by Yves Bertot and Pierrre Castéran; and "Isabelle/HOL: A Proof Assistant for Higher Order Logic" by Tobias Nipkow, Lawrence C. Paulson, and Markus Wenzel.  I decided that I'm going to read "Proofs and Types", "Rippling", and "Isabelle/HOL" - the rest are going back to the library (for now).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3742008638855759502-2894715547347714043?l=zkincaid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zkincaid.blogspot.com/feeds/2894715547347714043/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3742008638855759502&amp;postID=2894715547347714043' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/2894715547347714043'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/2894715547347714043'/><link rel='alternate' type='text/html' href='http://zkincaid.blogspot.com/2009/02/reading-last-week_10.html' title='Reading last week'/><author><name>zkincaid</name><uri>http://www.blogger.com/profile/08127275535283166049</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3742008638855759502.post-5739698338195859020</id><published>2009-02-08T09:01:00.000-08:00</published><updated>2009-02-08T14:28:45.462-08:00</updated><title type='text'>Reading last week</title><content type='html'>Alan Bundy: "A Science of Reasoning"&lt;br /&gt;&lt;blockquote&gt;"This paper addresses the question of how we can understand reasoning in general and mathematical proofs in particular. It argues the need for a high-level understanding of proofs to complement the low-level understanding provided by Logic. It proposes a role for computation in providing this high-level understanding, namely by the association of proof plans with proofs. Proof plans are defined and examples are given for two families of proofs. Criteria are given for assessing the association of a proof plan with a proof."&lt;/blockquote&gt;&lt;br /&gt;Alessandro Armando, Alan Smaill, Ian Green: "Automatic Synthesis of Recursive Programs: The Proof-Planning Paradigm"&lt;br /&gt;&lt;blockquote&gt;"We describe a proof plan that characterises a family of proofs corresponding to the synthesis of recursive functional programs. This plan provides a significant degree of automation in the construction of recursive programs from specifications, together with correctness proofs. This plan makes use of meta-variables to allow successive refinement of the identity of unknowns, and so allows the program and the proof to be developed hand in hand. We illustrate the plan with parts of a substantial example-the synthesis of a unification algorithm."&lt;/blockquote&gt;&lt;br /&gt;Jens Knoop, Bernhard Steffen, Jurgen Vollmer: "Parallelism for Free: Efficient and Optimal Bitvector Analyses for Parallel Programs"&lt;br /&gt;&lt;blockquote&gt;"We consider parallel programs with shared memory and interleaving semantics, for which we show how to construct for unidirectional bitvector problems optimal analysis algorithms that are as efficient as their purely sequential counterparts and that can easily be implemented. Whereas the complexity result is rather obvious, our optimality result is a consequence of a new Kam/Ullman-style Coincidence Theorem. Thus using our method, the standard algorithms for sequential programs computing liveness, availability, very busyness, reaching definitions, definition-use chains, or the analyses for performing code motion, assignment motion, partial dead-code elimination or strength reduction, can straightforward be transferred to the parallel setting at almost no cost."&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Azadeh Farzan, P. Madhusudan: "Causal Dataflow Analysis for Concurrent Programs"&lt;br /&gt;&lt;blockquote&gt;"We define a novel formulation of dataflow analysis for con-current programs, where the flow of facts is along the causal dependencies of events. We capture the control flow of concurrent programs using a Petri net (called the control net), develop algorithms based on partially-ordered unfoldings, and report experimental results for solving causal dataflow analysis problems. For the subclass of distributive problems, we prove that complexity of checking data flow is linear in the number of facts and in the unfolding of the control net."&lt;/blockquote&gt;&lt;br /&gt;Robert Cartwright, Mike Fagan: "Soft Typing"&lt;br /&gt;&lt;blockquote&gt;"Type systems are designed to prevent the improper use of program operations. They can be classified as either static or dynamic. Static type systems detect "ill-typed" programs at compile-time and prevent their execution. Dynamic type systems detect "ill-typed" programs at run-time. Static type systems have two important advantages over dynamic type systems. First, they provide important feedback to the programmer by detecting a large class of program errors before execution. Second, they extract information that a compiler can exploit to produce more efficient code. The price paid for these advantages, however, is a loss of expressiveness, modularity, and semantic simplicity. This paper presents a soft type systems that retains the expressiveness of dynamic typing, but offers the early error detection and improved optimization capabilities of static typing. The key idea underlying soft typing is that a type checker need not reject programs containing "ill-typed" phrases. Instead, the type checker can insert explicit run-time checks, transforming "ill-typed" programs into type-correct ones."&lt;/blockquote&gt;&lt;br /&gt;Daniel Bryce, Subbarao Kambhampati: "A Tutorial on Planning Graph-Based Reachability Heuristics"&lt;blockquote&gt;"The primary revolution in automated planning in the last decade has been the very impressive scale-up in planner performance. A large part of the credit for this can be attributed squarely to the invention and deployment of powerful reachability heuristics. Most, if not all, modern reachability heuristics are based on a remarkably extensible data structure called the planning graph, which made its debut as a bit player in the success of GraphPlan, but quickly grew in prominence to occupy the center stage. Planning graphs are a cheap means to obtain informative look-ahead heuristics for search and have become ubiquitous in state-of-the-art heuristic search planners. We present the foundations of planning graph heuristics in classical planning and explain how their flexibility lets them adapt to more expressive scenarios that consider action costs, goal utility, numeric resources, time, and uncertainty."&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3742008638855759502-5739698338195859020?l=zkincaid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zkincaid.blogspot.com/feeds/5739698338195859020/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3742008638855759502&amp;postID=5739698338195859020' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/5739698338195859020'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/5739698338195859020'/><link rel='alternate' type='text/html' href='http://zkincaid.blogspot.com/2009/02/reading-last-week.html' title='Reading last week'/><author><name>zkincaid</name><uri>http://www.blogger.com/profile/08127275535283166049</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3742008638855759502.post-4112779841933810212</id><published>2008-12-07T09:26:00.000-08:00</published><updated>2008-12-07T18:26:08.338-08:00</updated><title type='text'>Difference lists</title><content type='html'>I posed a question in my tutorial hour a couple weeks ago: how do we append two lists in Prolog?  It's not too hard to come up with something that works:&lt;br /&gt;&lt;pre&gt;append([], Ys, Ys).&lt;br /&gt;append([X|Xs], Ys, [X|As]) :- append(Xs, Ys, As).&lt;br /&gt;&lt;/pre&gt;Ok.  Fine. Linear in the length of the first list.  I can probably live with that.  But what if I want to write a parser in Prolog, and I want to be able to append &lt;i&gt;a lot&lt;/i&gt; of lists quickly?  I need to represent my data differently.  Difference lists are a solution to this problem - they're a logical data structure that's capable of constant time appends.&lt;br /&gt;&lt;br /&gt;We can represent a list &lt;i&gt;L&lt;/i&gt; as a &lt;i&gt;pair&lt;/i&gt; of lists &lt;span style="font-style: italic;"&gt;(L1, L2)&lt;/span&gt; such that  &lt;span style="font-style: italic;"&gt;L1 = L++L2 &lt;/span&gt;(writing ++ for append).  Recall that - (minus symbol) is just an ordinary binary infix function symbol in Prolog, so we can write &lt;span style="font-style: italic;"&gt;(L1, L2)&lt;/span&gt; more intuitively as the Prolog term &lt;span style="font-style: italic;"&gt;L1-L2&lt;/span&gt; (the difference between &lt;span style="font-style: italic;"&gt;L1&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;L2&lt;/span&gt;).  The power of difference lists comes from the fact that we need not instantiate &lt;span style="font-style: italic;"&gt;L2&lt;/span&gt;.  That is, we represent &lt;span style="font-style: italic;"&gt;L&lt;/span&gt; as the difference list &lt;span style="font-style: italic;"&gt;[L|X]-X&lt;/span&gt;.  Ok, that's pretty fancy I guess.  Where do the constant-time appends come from?&lt;br /&gt;&lt;tt&gt;append_dl(Xs-X, Ys-Y, Xs-Y) :- X = Ys.&lt;br /&gt;&lt;/tt&gt;What is &lt;tt&gt;append_dl&lt;/tt&gt; doing?&lt;br /&gt;&lt;br /&gt;Suppose our goal is &lt;tt&gt;append_dl([1,2,3|A]-A, [4,5|B]-B, D)&lt;/tt&gt;.  Let's do some unifications.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;unify(Xs-X, [1,2,3|A]-A) =&gt; Xs = [1,2,3|A] and X = A&lt;br /&gt;unify(Ys-Y, [4,5|B]-B) =&gt; Ys = [4,5|B] and Y = B&lt;br /&gt;unify(X, Ys) =&gt; X = [4,5|B]&lt;br /&gt;unify(D, Xs-Y) =&gt; D = [1,2,3|A]-B = [1,2,3|X]-B = [1,2,3|[4,5|B]]-B = [1,2,3,4,5|B]-B&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So &lt;tt&gt;D = [1,2,3,4,5|B]-B&lt;/tt&gt;, which is a difference list representing &lt;tt&gt;[1,2,3,4,5]&lt;/tt&gt;.  Fancy.&lt;br /&gt;&lt;br /&gt;How do we represent an empty list?  Well, just &lt;tt&gt;L-L&lt;/tt&gt;.  Sure, that makes sense.  Then we can check emptiness with &lt;tt&gt; empty_dl(L-L). &lt;/tt&gt;, right?   Well... not quite.  Prolog's unification algorithm doesn't do an occurs check by default, so &lt;tt&gt;empty_dl&lt;/tt&gt; will succeed on a nonempty list (with a nonsensical unification&lt;span style="font-family:monospace;"&gt; &lt;/span&gt;&lt;tt&gt;L=[elements,of,the,list|L]&lt;/tt&gt;).  So we need to check emptiness with&lt;br /&gt;&lt;tt&gt;empty_dl(X, Y) :- unify_with_occurs_check(X, Y).&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;... which isn't as nice.  But on the upside, it actually works (always a plus).  The purpose of writing this was to talk about definite clause grammars, which I haven't even started doing.  So maybe next time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3742008638855759502-4112779841933810212?l=zkincaid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zkincaid.blogspot.com/feeds/4112779841933810212/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3742008638855759502&amp;postID=4112779841933810212' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/4112779841933810212'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/4112779841933810212'/><link rel='alternate' type='text/html' href='http://zkincaid.blogspot.com/2008/11/difference-lists.html' title='Difference lists'/><author><name>zkincaid</name><uri>http://www.blogger.com/profile/08127275535283166049</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3742008638855759502.post-5136402137067721551</id><published>2008-12-06T07:03:00.000-08:00</published><updated>2008-12-06T08:54:29.861-08:00</updated><title type='text'>Notes on "Sketching Concurrent Data Structures"</title><content type='html'>by Armando Solar-Lezama, Christopher Grand Jones, Rastislav Bodik&lt;br /&gt;&lt;br /&gt;The abstract got me very excited about this paper.  The basic idea is to turn high level descriptions (sketches) of concurrent data structures into full-blown, efficient, and correct implementations.  That's awesome.  I think that's more or less the future of programming.&lt;br /&gt;&lt;br /&gt;The rest of the paper left me much less excited.  It turns out that the sketches aren't &lt;span style="font-style: italic;"&gt;really&lt;/span&gt; high-level descriptions - they're more like grammars for generating lists of commands that the programmer thinks &lt;span style="font-style: italic;"&gt;might&lt;/span&gt; be involved in a correct implementation.  Then their algorithm just searches the space of programs generated by the grammar, trying to find one that's actually correct.  Still kinda neat, but I think this is far less interesting than what I understood from the abstract.  Now it seems less like a tool for helping programmers be more productive by not making them fill in all the gory details of their data structure, and more like a tool for helping students cheat on their homework.  I know that a sketch tool like this for Prolog would certainly help some of the people in the class I'm TAing with the latest assignment ("I know it has to be recursive, and I know it has to use this and this... but how do I &lt;span style="font-style: italic;"&gt;do&lt;/span&gt; it?").&lt;br /&gt;&lt;br /&gt;Theoretically, I think it's kinda interesting.  The search space is huge, but finite - so it isn't too impressive from a computability standpoint.  From a complexity standpoint, it's hard to say.  The author's don't give a complexity analysis of their algorithm (my guess: at best in NP, at worst, probably still in PSPACE).  I also don't have a sense for a lower bound on this kind of problem.  But their experimental results are reasonable.&lt;br /&gt;&lt;br /&gt;It's not clear to me exactly what assumptions they are making as far as verifying whether a candidate solution is correct.  But even if the algorithm requires a correct sequential implementation, I'm OK with that - that seems like a reasonable thing to have on hand in some situations.  But generally, I think that genetic programming people do more interesting things with fewer assumptions.&lt;br /&gt;&lt;br /&gt;That said, this could potentially be useful if it were much &lt;span style="font-style: italic;"&gt;faster&lt;/span&gt;.  I could see myself using the tool if it took a few seconds (rather than ~ 1 hour) to get a correct implementation.  Basically, if the tool isn't significantly faster than my brain (on realistic tasks, not homework assignments where you're told what kind of constructs you should use), then I'm not sure what practical use this has.&lt;br /&gt;&lt;br /&gt;So the verdict: kinda neat.  Wouldn't mind hearing a talk about it at a conference.  Wouldn't want to work on it myself.  If I was a professor, I would keep my eye on this project - "your implementation should use an atomic swap operation"-style hints for homework assignments may not be a good idea anymore.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3742008638855759502-5136402137067721551?l=zkincaid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zkincaid.blogspot.com/feeds/5136402137067721551/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3742008638855759502&amp;postID=5136402137067721551' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/5136402137067721551'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/5136402137067721551'/><link rel='alternate' type='text/html' href='http://zkincaid.blogspot.com/2008/12/notes-on-sketching-concurrent-data.html' title='Notes on &quot;Sketching Concurrent Data Structures&quot;'/><author><name>zkincaid</name><uri>http://www.blogger.com/profile/08127275535283166049</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3742008638855759502.post-3693013860437412741</id><published>2008-11-25T18:52:00.001-08:00</published><updated>2008-11-25T19:59:44.345-08:00</updated><title type='text'>Pragmatism</title><content type='html'>No one has ever accused me of being pragmatic.&lt;br /&gt;&lt;br /&gt;This afternoon, I decided to take another look at &lt;a href="http://projects.gnome.org/tomboy/"&gt;tomboy&lt;/a&gt; for my note-taking needs.  I tried it once before, when I first heard that it had a &lt;a href="http://www.reitwiessner.de/programs/tomboy-latex.html"&gt;latex plugin&lt;/a&gt;, which is pretty much essential for what I intend to do with tomboy.  This was maybe a year ago.  The latex plugin was pretty buggy back then and I didn't really like the idea of losing all of my notes, so I went back to my old system of just writing everything up in .tex files and then promptly forgetting where I put them.  For some reason, I looked up tomboy again this afternoon, and I discovered that the latex plugin "can now be considered stable".  Sweet.  I tried it out, and it seems stable enough.  Well... seemed stable enough.  Until I tried to copy and paste something.  It didn't crash - it just mutated my documents in exciting ways that I hadn't thought possible.  Oh well... I guess I can just disable the plugin on the rare occasion that I need to copy and paste latex formulas.  Except that's even worse.  That's... much worse.  Disabling and re-enabling the plugin makes every subsequent &lt;span style="font-style: italic;"&gt;keystroke&lt;/span&gt; in the note double &lt;span style="font-style: italic;"&gt;every single equation&lt;/span&gt;.  The equations are also strangely difficult to delete.  So I ruined a couple of hours of work.&lt;br /&gt;&lt;br /&gt;So clearly, the first step towards fixing this problem is design (and write a compiler for) an extensible programming language.  What?  Oh right -- pragmatism.  Not a quality I typically possess.  I'm a bottom-up kind of guy.  Of course, my first instinct was to just fix the problem.  But then I thought about what happened the last time I did that (a year ago).  I decided the code was too weird and I might as well rewrite the whole thing from scratch.  But I'm probably going to have to learn C# anyway if I'm going to write the plugin from scratch, so I might as well fix all the problems I had with tomboy.  But if I'm going to do all that, wouldn't it be simpler to just write my own note taking program that's better suited to my needs?  Yeah - that makes sense.  That's what I started doing last year.  I got surprisingly far (and learned a bit of python in the process), but eventually the semester started, classes+thesis got in the way and I put the project down.  Probably for the best.&lt;br /&gt;&lt;br /&gt;My opinions have changed since then - now they're even less practical.  Clearly, my mistake last time was trying to write the thing in python.  Python, and almost every other language in popular use for that matter, is complete unsuitable for GUI development.  So before I write my notes program, I will have to write a compiler for a DSL for GUI development (I think &lt;a href="http://www.sun.com/software/javafx/"&gt;JavaFX&lt;/a&gt; has the right idea, but it has Java right in the name, and frankly... I have principles).&lt;br /&gt;&lt;br /&gt;Not so fast!  I can't just go off writing a compiler every time I think that there aren't any languages suitable for my particular task!  That's just crazy.  Obviously, my first step must be to design an extensible language so that I can churn out DSLs effortlessly.&lt;br /&gt;&lt;br /&gt;This is something I was seriously considering until a couple of hours ago.  Sometimes I don't even stop there.  I can't believe that we're still using operating systems that haven't been formally verified.  I don't like the way processors are currently designed.  I don't think Turing machines are a particularly good formalism.  I will occasionally have a day or two where I decide that I am going to be a &lt;a href="http://en.wikipedia.org/wiki/Constructivism_%28mathematics%29"&gt;constructivist&lt;/a&gt;.  If left to my own devices, I would never accomplish anything.  Ever.&lt;br /&gt;&lt;br /&gt;But somehow, today, I bit the bullet.  &lt;a href="http://www.cs.toronto.edu/%7Ezkincaid/tomboy-latex-zk-patch.tar.gz"&gt;Tomboy-LaTeX, featuring copy+paste that won't ruin your afternoon&lt;/a&gt;, a fix that took (maybe) 10 lines.  At some point, I promise that I will alert the maintainer of Tomboy-LaTeX.  (I frequently break my promises).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3742008638855759502-3693013860437412741?l=zkincaid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zkincaid.blogspot.com/feeds/3693013860437412741/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3742008638855759502&amp;postID=3693013860437412741' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/3693013860437412741'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/3693013860437412741'/><link rel='alternate' type='text/html' href='http://zkincaid.blogspot.com/2008/11/pragmatism.html' title='Pragmatism'/><author><name>zkincaid</name><uri>http://www.blogger.com/profile/08127275535283166049</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3742008638855759502.post-4083024976558869947</id><published>2008-11-10T13:14:00.000-08:00</published><updated>2008-11-11T19:19:21.718-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='model checking'/><category scheme='http://www.blogger.com/atom/ns#' term='se'/><category scheme='http://www.blogger.com/atom/ns#' term='logic'/><title type='text'>Notes on "Applications of Craig Interpolants in Model Checking"</title><content type='html'>by K. L. McMillan &lt;br /&gt;&lt;br /&gt;Given a pair $(A,B)$ inconsistent formulas, an interpolant for $(A,B)$ is a formula $\hat{A}$ such that&lt;br /&gt;&lt;ol&gt;&lt;li&gt;$A \Rightarrow \hat{A}$&lt;/li&gt;&lt;li&gt;$\hat{A} \land B$ is unsatisfiable&lt;/li&gt;&lt;li&gt;$\hat{A}$ refers only to the common (extra-logical) symbols of   $A$ and $B$.&lt;/li&gt;&lt;/ol&gt;(I've also seen a Craig interpolant for $A, B$ with $A \Rightarrow B$ defined as a formula $\hat{A}$ over the common symbols of $A,B$ with $A \Rightarrow \hat{A}$ and $\hat{A} \Rightarrow B$, but it's the same concept - just negate $B$).  The idea of an interpolant is that $A$ may contain information that is not needed to contradict $B$, and we should be able to remove this extra information to obtain a simpler description of $A$.  In fact, we can remove the extra information (that is, compute the interpolant) efficiently from a refutation proof of $A \land B$ (in some proof systems, at least).  In the main algorithm proposed in this paper, these refutations are already being computed, so the interpolants essentially come "for free". &lt;br /&gt;&lt;br /&gt;There are three applications for Craig interpolants proposed in the paper in model checking: approximate image computation, predicate abstraction, and approximating the transition relation.  I'm only going to write about approximate image computation for now, but in all cases, we're working in the magical world of symbolic model checking. &lt;br /&gt;&lt;br /&gt;The basic idea of symbolic model checking is to avoid the cost of computing all the states of a system by representing and manipulating sets of states symbolically.  Typically, this means representing sets of states and transitions as formulas in first order logic (this paper is not an exception). &lt;br /&gt;&lt;br /&gt;Fix a vocabulary $S$ of variable, function, and proposition symbols. A &lt;span style="font-style: italic;"&gt;state formula&lt;/span&gt; $\phi$ is a first order forrmula over $S$ that represents a set of states (namely, the first-order models of $\phi$).  Now that we can encode sets of states, how can we encode the transition relation?  We define a vocabulary $S'$ that is the image of $S$ under a transformation that takes each symbol in $s \in S$ to a symbol $s'$ (we assume $\nexists s$ such that $s' \in S$, so $S$ and $S'$ are disjoint).  A transition formula is just a first-order formula over $S \cup S'$.  Intuitively, the $S$ symbols are used to represent what is true in the "current" state, and the $S'$ symbols are used to represent what is true in the "next" state.  Now we have the tools to define our entire system: a transition system is a pair $(I, T)$ consisting of an initial state formula $I$ and a transition formula $T$. &lt;br /&gt;&lt;br /&gt;In most of the following, we're actually interested in checking reachability (or safety) properties.  A formula $\psi$ is $T$-reachable from a formula $\phi$ if there is a sequence of models $\sigma_1, \ldots \sigma_k$ such that $\sigma_1 \vDash \phi$, $\sigma_k \vDash \psi$, and $\forall 1 \leq i &lt; k. [\sigma_i \cup   \sigma_{i+1}' \vDash T]$.  A formula $\phi$ is reachable in a transition $(I, T)$ if it is $T$-reachable from $\phi$, and is an invariant if $\lnot \phi$ is not $T$-reachable from $I$. &lt;br /&gt;&lt;br /&gt;Now that we have a bunch of fancy definitions, let's see if we can actually do anything useful with them.  Safety properties are usually phrased as "starting from the initial state, an error state is not reachable".  So we want an algorithm that, given a transition system $(I,T)$ and a formula $\psi$, either proves that $\psi$ is not $T$-reachable from $I$ or provides a counter-example. &lt;br /&gt;&lt;br /&gt;The image (strongest postcondition) $im_T(\phi)$ of a state formula $\phi$ with respect to transition formula $T$ is the strongest proposition $\psi$ such that $\phi \land T \Rightarrow \psi'$ (strongest in the sense that for all $\varphi$, if $\phi \land T \Rightarrow \varphi'$ then $\psi \Rightarrow \varphi$). The image of a formula captures the idea of "if the system is currently in state $\phi$, what can we prove about the next state?".  We can actually compute $im_T(\phi)$ with the formula $im_T(\phi)' = \exists S.\phi \land T$ (just existentially quantify the free variables of $\phi \land T$). &lt;br /&gt;&lt;br /&gt;OK - almost to the computationally useful stuff. &lt;br /&gt;&lt;br /&gt;A state formula $\phi$ is an invariant when $\lnot \phi$ is not reachable from $I$ by $T$.  $\phi$ is an inductive invariant when $I \Rightarrow \phi$ and $im_T(\phi) \Rightarrow \phi$. The strongest invariant of an $(I, T)$ is an invariant that implies all other invariants of $(I,T)$. It turns out that strongest inductive invariants are inductive invariants, and we can compute the strongest inductive invariant using the image operator (it's the fixed point $\mu Q. I \lor sp_T(Q)$).  The models of the strongest inductive invariant of $(I, T)$ are exactly the reachable states of the system. &lt;br /&gt;&lt;br /&gt;Finally, back to the problem at hand: we can verify that some formula $\psi$ is unreachable in $(I, T)$ by showing that it is inconsistent with the strongest inductive invariant. &lt;br /&gt;&lt;br /&gt;Whew.  Now let's start on the real contents of the paper. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Approximate image based on interpolation&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;An over-approximate image operator $\bar{sp}$ is an operator such that for all predicates $\phi$, $sp(\phi) \Rightarrow \bar{sp}(\phi)$. Unreachability analyses based on over-approximations are sound: the states reachable from $I$ by $\bar{sp}$ is a superset of those reached by $sp$.  We say that $\bar{sp}$ is adequate with respect to $\psi$ when, for any $\phi$, if $\phi$ can't reach $\psi$ with $sp$, then it can't reach $\psi$ with $\overline{sp}$.  Thus, unreachability analyses based on adequate over-approximate image operators are both sound and complete.  So the basic idea is to compute an adequate over-approximate image operator $\bar{sp}$, compute its strongest invariant $R$, and then prove that $\psi$ is unreachable by refuting $\psi \land R$.  But we haven't really saved anything because we've replaced our image operator (which we know how to compute) with an approximate image operator (which we don't).  So how do we compute an adequate $\bar{sp}$?  The solution is to bound our notion of adequacy. &lt;br /&gt;&lt;br /&gt;A $k$-adequate image operator is an $\bar{sp}$ such that, for any $\phi$ that cannot reach $\psi$, $\bar{sp}_T(\phi)$ cannot reach $\psi$ within $k$ steps.  This is looking to be more tractable - we can reuse the ideas of bounded model checking. &lt;br /&gt;&lt;br /&gt;Once again, we are trying to prove that $\psi$ is unreachable.  Define &lt;br /&gt;&lt;br /&gt;$A = \phi_0 \land T_0$ &lt;br /&gt;&lt;br /&gt;$B = T_1 \land \dotsi \land T_k \land (\psi_1 \lor \dotsi \lor \psi_{k+1})$ &lt;br /&gt;&lt;br /&gt;If $A \land B$ is satisfiable, then $\psi$ is reachable, and we're done.  Otherwise, we compute an interpolant $\hat{A}$ of $(A,B)$ (computationally inexpensive because we already have a refutation of $A \land B$).  $\hat{A}$ is taken to be the over-approximate image of $\phi$.  So by the definition of interpolants: $\hat{A}$ is over the symbols in $A_1$ (so $\hat{A}$ is a well-defined state formula), $A \Rightarrow \hat{A}$ (whence $\hat{A}$ is an over-approximation of $sp(\phi)$), $\hat{A}$ cannot reach $\psi$ in $k$-steps (by the structure of $B$ and the fact that $B \land \hat{A}$ is unsatisfiable, whence $\hat{A}$ is $k$-adequate). &lt;br /&gt;&lt;br /&gt;In summary, the algorithm goes something like this (I think): &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def unreachable(I, T, psi):&lt;br /&gt; for k &lt;- 1 to infinity&lt;br /&gt;   R &lt;- true&lt;br /&gt;   R' &lt;- I&lt;br /&gt;   while (R != R'):&lt;br /&gt;     R &lt;- R'&lt;br /&gt;     B &lt;-T_1 /\ ... /\ T_k /\ (psi_1 \/ ... \/ psi_k)&lt;br /&gt;     if (R' /\ T_0) /\ B is satisfiable:&lt;br /&gt;       if R = I: (* this is the first iteration of the invariant computation *)&lt;br /&gt;         return false (* psi is reachable from I in k steps *)&lt;br /&gt;       else:&lt;br /&gt;         goto next (* sorry, Dijkstra *)&lt;br /&gt;     R' &lt;- I \/ interp(R' /\ psi) (* interpolant from refutation of R' /\ psi *)&lt;br /&gt;   if R /\ psi is unsatisfiable:&lt;br /&gt;     return true&lt;br /&gt;   next: skip &lt;/pre&gt;When $k$ is the diameter of the state space, $k$-adequacy coincides with adequacy, so if psi is reachable).  So in finite systems, this method is complete.  This method works for infinite state systems, too, but it isn't guaranteed to terminate.&lt;br /&gt;&lt;br /&gt;Thoughts:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The author mentions that the properties of the benchmark suite are localizable, which likely improves the performance of the interpolation-based method.  What happens with other benchmark suites? How does the interpolating model checker compare with other (symbolic) model checkers?  (although the paper does mention that the SMV model checker (based on BDDs) is unable to verify any of the properties. Only compared to proof-based abstraction (another method co-developed by McMillan)&lt;/li&gt;&lt;li&gt;I wonder if we efficiently compute the diameter of a state space (so we can bound the run-time of the algorithm)?  And how can we efficiently test the equivalence of two formulas (needed in fixed point calculation)?  Double implication?  That doesn't seem to be efficient.  Am I even correct in thinking that this is how the strongest invariant is calculated?&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3742008638855759502-4083024976558869947?l=zkincaid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zkincaid.blogspot.com/feeds/4083024976558869947/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3742008638855759502&amp;postID=4083024976558869947' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/4083024976558869947'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/4083024976558869947'/><link rel='alternate' type='text/html' href='http://zkincaid.blogspot.com/2008/11/notes-on-applications-of-craig.html' title='Notes on &quot;Applications of Craig Interpolants in Model Checking&quot;'/><author><name>zkincaid</name><uri>http://www.blogger.com/profile/08127275535283166049</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3742008638855759502.post-7673043874598572131</id><published>2008-11-09T15:13:00.000-08:00</published><updated>2008-11-11T10:34:03.748-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='model checking'/><category scheme='http://www.blogger.com/atom/ns#' term='se'/><title type='text'>Notes on ``Symbolic Model Checking without BDDs''</title><content type='html'>By Armin Biere, Alessandro Cimatti, Edmund Clarke, and Yunshan Zhu&lt;br /&gt;&lt;br /&gt;Wow.  It has been over a month since I last wrote on this blog.  That is... not so good.  Also, I need to figure out how to use latex in blogger - my current solution, which is an incredibly ugly mixture of sed and awk scripts that I wrote earlier today, badly needs to be replaced.&lt;br /&gt;&lt;br /&gt;In the 1970's, a couple of people made a connection between temporal logics and automata, and started to use logic to analyze reactive systems.  People were pretty excited about it.  A few years after that, someone said that we're wasting a whole lot of time building these automata, and we could verify more stuff if we knocked it off and just represented it implicitly using BDDs.  People were, once again, pretty excited about it.  A few years after that, a few other people said that we're wasting a lot of time building these BDD's, and we could verify more stuff if we knocked it off and just represented everything as a propositional formula and left all the hard issues to SAT solvers.  These last people were Biere, Cimatti, Clarke, and Zhu.  I'm not sure how exciting other people found it, but I think it's pretty neat.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Bounded model checking&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;First, the authors restrict themselves to the existential model checking problem (an LTL formula &lt;span style="font-style: italic;"&gt;f&lt;/span&gt; is existentially valid in a Kripke structure &lt;span style="font-style: italic;"&gt;M&lt;/span&gt; iff there exists a path in &lt;span style="font-style: italic;"&gt;M&lt;/span&gt; (starting from an initial state) that satisfies &lt;span style="font-style: italic;"&gt;f&lt;/span&gt;).  This corresponds to model checking the formula &lt;span style="font-style: italic;"&gt;Ef&lt;/span&gt; (We get universal model checking for free by duality).  The idea behind bounded model checking is that we can "solve'' existential model checking problems by looking at finite prefixes of infinite paths.&lt;br /&gt;&lt;br /&gt;Soundness and completeness are the obvious desirable properties for bounded model checking.  That is, we want to show:&lt;br /&gt;1) If we can prove &lt;span style="font-style: italic;"&gt;Ef&lt;/span&gt; in bounded semantics, it should hold in the unbounded semantics&lt;br /&gt;2) If &lt;span style="font-style: italic;"&gt;Ef&lt;/span&gt; can be proved in the unbounded semantics, then we should be able to prove it in the bounded semantics.&lt;br /&gt;&lt;br /&gt;How can we say that a finite path satisfies an LTL formula?  Having &lt;span style="font-style: italic;"&gt;GP&lt;/span&gt; hold on a finite path doesn't mean that it holds on an infinite path (it could be the case that every infinite extension of any finite path that satisfies &lt;span style="font-style: italic;"&gt;GP&lt;/span&gt; does not satisfy &lt;span style="font-style: italic;"&gt;GP&lt;/span&gt;).  The trick is to consider finite paths that terminate at a node that has a transition back to a previous state in the path.  We can view these paths as describing the infinite path formed by traversing this loop forever (that is, we can identify a finite path &lt;span style="font-style: italic;"&gt;p&lt;/span&gt; with the infinite path $uv^\omega$ (where &lt;span style="font-style: italic;"&gt;p = uv&lt;/span&gt;)).  With this in mind, it isn't too hard to develop sound semantics for bounded model checking.&lt;br /&gt;&lt;br /&gt;The really interesting issue, I think, is completeness.   Not every infinite path over a finite automaton can be written as $uv^\omega$, and it isn't clear that every formula &lt;span style="font-style: italic;"&gt;f&lt;/span&gt; that is satisfied "complex" path is also satisfied by a "simple" path (we need &lt;span style="font-style: italic;"&gt;f&lt;/span&gt; to be satisfied by a path of the form $uv^\omega$ for completeness to hold).  We are saved by the fact that LTL isn't a very powerful language - it can't express properties that can't be satisfied by simple paths.&lt;br /&gt;&lt;br /&gt;So what have we gained from switching to bounded model checking? Well, now that we're only considering finite paths, we can express paths, transition functions, and LTL formulas in finite propositional logic.  Basically, we just reduce bounded model checking to SAT.  But wait!  Why would we reduce a problem to an NP-complete problem?  Well, it turns out that (unbounded) model checking is PSPACE-complete, so NP isn't that bad.  And there are some pretty good SAT solvers out there.&lt;br /&gt;&lt;br /&gt;So now we know the basic method for bounding model checking.  We know that for any formula that is provable in the unbounded semantics is provable in &lt;span style="font-style: italic;"&gt;k&lt;/span&gt; bounded semantics for some &lt;span style="font-style: italic;"&gt;k&lt;/span&gt;.  So if a formula &lt;span style="font-style: italic;"&gt;Ef&lt;/span&gt; is true in a Kripke structure&lt;span style="font-style: italic;"&gt;&lt;/span&gt;, we can prove it using bounded model checking by first using 1-bounded model checking, then 2 bounded, then 3, and so on until we prove &lt;span style="font-style: italic;"&gt;Ef&lt;/span&gt;.  But what if &lt;span style="font-style: italic;"&gt;Ef&lt;/span&gt; isn't provable?  Then our algorithm doesn't terminate.  So we need to find a bound for the largest k such that k-bounded model checking lets us prove more things than (&lt;span style="font-style: italic;"&gt;k&lt;/span&gt;-1)-bounded model checking.  The authors present bounds for various fragments of temporal logic, the worst of which is exponential (LTL), the best of which is linear (ECTL).&lt;br /&gt;&lt;br /&gt;Thoughts:&lt;br /&gt;- The efficiency of BDD-based approaches depends heavily on the choice of variable ordering. Finding an optimal variable ordering is NP-complete.  Are there good approximation algorithms? Maybe. I don't know. I'm sure that a lot of effort has gone into finding nice heuristics, but I am unaware of approximation hardness results.&lt;br /&gt;- The authors suggest that SAT solvers could be specialized to the domain of model checking.  I wonder if anyone has actually done anything in this direction - it seems interesting.&lt;br /&gt;- The authors derive different bounds (and thus, time complexities) for different fragments of temporal logic.  I wonder if there has been much work on automatically finding the minimal fragment of temporal logic to which a formula belongs and specializing the bound accordingly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3742008638855759502-7673043874598572131?l=zkincaid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zkincaid.blogspot.com/feeds/7673043874598572131/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3742008638855759502&amp;postID=7673043874598572131' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/7673043874598572131'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/7673043874598572131'/><link rel='alternate' type='text/html' href='http://zkincaid.blogspot.com/2008/11/notes-on-symbolic-model-checking.html' title='Notes on ``Symbolic Model Checking without BDDs&apos;&apos;'/><author><name>zkincaid</name><uri>http://www.blogger.com/profile/08127275535283166049</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3742008638855759502.post-8949294973623626919</id><published>2008-10-06T12:47:00.000-07:00</published><updated>2008-10-06T14:16:46.645-07:00</updated><title type='text'>Reversible Debugging Using Program Instrumentation</title><content type='html'>by Shyh-Kwei Chen, W. Kent Fuchs, and Jen-Yao Chung.&lt;br /&gt;&lt;br /&gt;Reversible execution allows a program to be executed backwards so that we can observe a previous state of execution. It is particularly useful as a debugging tool: imagine a "step backwards" button in your debugger (or a "step backwards" series of finger-mangling keystrokes, &lt;a href="http://www.gnu.org/software/emacs/"&gt;if that's your thing&lt;/a&gt;) that allows you to find the cause of an error by "undoing" previously executed commands.&lt;br /&gt;&lt;br /&gt;Loops are a pretty good justification for reversible debuggers. Suppose we are interested in the last execution of a loop, because, well, that's where the bug probably occurs.  With a forward-executing debugger, we have to step through &lt;span style="font-style: italic;"&gt;the entire loop&lt;/span&gt; to see what we're interested in.  Manually.  (Ok... in most cases we could also set a condition on the breakpoint - but not always).  Another interesting use case is when we just make a mistake while using our debugger (well, interesting in the sense that this happens to me all the time).&lt;br /&gt;&lt;br /&gt;One way to implement a reversible debugger is a checkpointing system, where the system state is periodically saved so that we can undo operations by reverting to the last checkpoint and then running the program forward until we get to the state just before the last instruction was executed.  The approach of the paper is a little more fine grained - more checkpoints, but less information stored at each checkpoint.  This speeds up forward execution at the price of not being able to undo across irreversible function calls.&lt;br /&gt;&lt;br /&gt;The "program instrumentation" part of this paper is that the reversible debugger is implemented by inserting instructions into the program to be debugged that record checkpoint information to a history buffer (but do not affect the semantics of the program).  In particular, the authors use assembly-level instrumentation (so no source code analysis needs to take place to determine which variables need to be saved).  Every procedure has an instrumented (reversible) and non-instrumented (irreversible) version, and the user of the debugger can choose which procedures they would like to be able to reverse ("recorded areas").&lt;br /&gt;&lt;br /&gt;I have a problem with the idea of recorded areas.  Basically, to speed up the debugger, the authors insist that only recorded areas be available for backwards execution.  This is pretty odd, because it means that the programmer needs to mark these areas &lt;span style="font-style: italic;"&gt;ahead&lt;/span&gt; of time, so that they can be computed backwards.  If we get to the end of a recorded region, we can't go back - we have to run everything forwards again.  I think this negates some of the effects of having a reversible debugger.&lt;br /&gt;&lt;br /&gt;Another issue is that we can't undo across irreversible function calls - this (in my opinion) severely limits the practicality of the approach.  On the other hand - there isn't really anything that can be done.  It is unsound to undo "past" an irreversible function call in a language with side effects.  Consider the following:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;int f() /* reversible */&lt;br /&gt;{&lt;br /&gt;  int x = 0;&lt;br /&gt;  if (x == 1)&lt;br /&gt;      return;&lt;br /&gt;  g(&amp;amp;x); /* do we save x here? */&lt;br /&gt;  while(1);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int g(int * x) /* irreversible */&lt;br /&gt;{&lt;br /&gt;  *x = 1;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;What if g modifies some element of a globally visible data structure -- do we make a copy of the entire data structure?  That's very expensive.  What if we just can't prove that a function doesn't modify a particular shared resource?  Do we need to make a copy?  I don't have a good solution (other than to use a language without mutable storage... but I don't really want to end &lt;span style="font-style: italic;"&gt;all&lt;/span&gt; of my blog posts with "this would be way easier if you were using Haskell").&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3742008638855759502-8949294973623626919?l=zkincaid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zkincaid.blogspot.com/feeds/8949294973623626919/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3742008638855759502&amp;postID=8949294973623626919' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/8949294973623626919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/8949294973623626919'/><link rel='alternate' type='text/html' href='http://zkincaid.blogspot.com/2008/10/reversible-debugging-using-program.html' title='Reversible Debugging Using Program Instrumentation'/><author><name>zkincaid</name><uri>http://www.blogger.com/profile/08127275535283166049</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3742008638855759502.post-2882680931325329188</id><published>2008-09-28T11:23:00.000-07:00</published><updated>2008-09-28T16:48:47.853-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='symbolic execution'/><category scheme='http://www.blogger.com/atom/ns#' term='model checking'/><category scheme='http://www.blogger.com/atom/ns#' term='parallelism'/><category scheme='http://www.blogger.com/atom/ns#' term='se'/><title type='text'>Notes on "Combining Symbolic Execution with Model Checking to Verify Parallel Numerical Programs"</title><content type='html'>by Stephen F. Siegel, Anastasia Mironova, George S. Avrunin, and Lori A. Clarke.&lt;br /&gt;&lt;br /&gt;I managed to avoid doing any work whatsoever while I was in Japan, so this is the first paper off the stack that Greg gave me that I've gotten around to reading.  Due to the long name of the paper, I'll refer to it as SE+MC.&lt;br /&gt;&lt;br /&gt;The idea of SE+MC is to combine symbolic execution and model checking to prove that a parallel program is (extensionally) equivalent to its sequential specification (two programs are equivalent if they produce the same output for a given input).  The method applies to numerical programs (taking a vector of ints/floats as input and producing a vector of ints/floats as output) without side-effects (no IO, no randomness).  So essentially, we build a sequential program that we assume is correct (after all, &lt;a href="http://en.wikipedia.org/wiki/Rice%27s_theorem"&gt;reasoning about sequential programs is easy&lt;/a&gt;), and we prove that our parallel program is correct by showing that it is equivalent to the sequential one.  The authors claim that in practice, a sequential version of a program will often be created as a prototype for the parallel version, so it isn't unreasonable to require both versions.&lt;br /&gt;&lt;br /&gt;Symbolic execution is a way to avoid losing information during the execution of a program.  Whenever we encounter an expression that we can't compute exactly (such as expressions involving unknown values, or floating point operations), we replace the numeric operation with a symbolic one.  While a numeric operation evaluates to a numeric value, its corresponding symbolic operation forms a symbolic expression tree, rooted at a node corresponding to the numeric operation, with children corresponding to its operands (thus, a symbolic expression tree is a tree where leaves are literals or symbolic constants and each internal node is associated with a numeric operation).&lt;br /&gt;&lt;br /&gt;It's pretty clear why we would want to model expressions like (&lt;span style="font-style: italic;"&gt;x&lt;/span&gt; + 1) symbolically - we just can't do better (assuming we don't have a value for &lt;span style="font-style: italic;"&gt;x&lt;/span&gt;).  The idea of using symbolic expressions to model floating point operations is more interesting.  Floating point arithmetic doesn't have all the nice properties of real arithmetic. If we use a computer to verify a program that uses floats, that verification will have a bias for the particular implementation of floating point arithmetic on the computer.  For instance, if the correctness of my program relies on the associativity of floating point addition (which need not hold in IEEE fp arithmetic), and my laptop happens to actually &lt;span style="font-style: italic;"&gt;have&lt;/span&gt; associative floating point addition, an analysis running on my laptop would miss the error.  If we use symbolic operations, the expression trees for, say, (1.0 + (2.0 + 3.0)) and ((1.0 + 2.0) + 3.0) are distinct, so we don't make this mistake.  And of course we can add special rules for the equivalence properties that we actually &lt;span style="font-style: italic;"&gt;can&lt;/span&gt; count on (like &lt;span style="font-style: italic;"&gt;x&lt;/span&gt; + 0.0 = &lt;span style="font-style: italic;"&gt;x&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;Given a sequential and a parallel program, the method of SE+MC is to construct models for each of these programs in which symbolic operations replace numeric ones wherever it is appropriate (unfortunately, these models are built by hand at the moment).  The models are then checked by &lt;a href="http://spinroot.com/spin/whatispin.html"&gt;Spin&lt;/a&gt;, a linear temporal logic model checker (which I'll probably write about later, because I'm &lt;a href="http://www.cs.toronto.edu/%7Eazadeh/page8/page8.html"&gt;taking a class in it&lt;/a&gt;).  These models are then combined into a single model that first executes the sequential program, then executes the parallel program.  Spin is responsible for exploring all the possible paths of this combined model and making sure that the outputs of the sub-models match.&lt;br /&gt;&lt;br /&gt;One interesting issue is programs that branch on conditions that depend on inputs (which is probably almost every program).  We need some way to say that we only need outputs to match if the programs had the "same" branch conditions - otherwise, a program as simple as&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def f(x):&lt;br /&gt;if x &amp;lt; 0:&lt;br /&gt;  return -1&lt;br /&gt;else:&lt;br /&gt;  return 1&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;wouldn't even be equivalent to itself.  For this reason, the authors introduce a &lt;span style="font-style: italic;"&gt;path condition&lt;/span&gt;, which is a conjunction of boolean-valued symbolic expressions that determine the path that was taken through the model.  This path condition is built during the execution of the sequential model: whenever a branch is encountered, if the path condition contains enough information to determine the value of the condition of the branch, the the appropriate branch is taken.  Otherwise, a branch should be chosen non-deterministically the branch condition (or its negation) should be added to the path condition.  During the execution of the part of the model corresponding to the parallel program, we hope to have enough information built up in the path condition that we don't explore paths that are inconsistent with the path taken in the sequential model.  So we have changed our equivalence condition slightly: two programs are equivalent if for every input and path condition, they produce the same output.&lt;br /&gt;&lt;br /&gt;Now there is an issue with how accurate we really need to be when determining whether a branch condition is a logical consequence of a path condition.  The most accurate thing to do would be to defer to a theorem prover, but that may slow down the analysis.  The authors use a much weaker reasoning facilities.  It would be interesting to see how much longer it would take to use a more powerful prover.  It's possible that using a powerful prover could actually &lt;span style="font-style: italic;"&gt;decrease&lt;/span&gt; running time because it would cause fewer paths to be explored by Spin.&lt;br /&gt;&lt;br /&gt;The authors also discuss methods to reduce the number of paths that Spin explores.  What we're really interested in for this analysis is the final state of the model.  Program equivalence is defined in terms of outputs - we don't need to know every detail about the executions that produced those outputs.  It is not necessary to explore all possible paths through a model in order to explore all possible terminal states.  There are often many equivalent paths that terminate in the same state, and it would be inefficient to explore all of them. So we would like some theorems that allow us to reduce the number of paths explored while maintaining the full set of possible final states.&lt;br /&gt;&lt;br /&gt;By default, Spin will explore every path through the model - this corresponds to a scheduling policy that allows any (non-blocked) instruction to executed in any order.  The authors prove a partial order reduction theorem that essentially states that we will explore the same set of terminal states if we restrict this scheduling policy (through the use of atomic blocks in Promela, Spin's modeling language).  They also prove a reduction theorem about symmetric input vectors, but it seems like it would not be very general.&lt;br /&gt;&lt;br /&gt;Another optimization that is briefly mentioned is that it is sometimes possible to refactor code to remove nondeterminism (and thus decrease the number of paths explored by Spin).  The example given by the authors is something that arose when analyzing a Monte Carlo algorithm to estimate the value of pi:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if x*x + y*y &amp;lt; 1.0:&lt;br /&gt; in++&lt;br /&gt;else:&lt;br /&gt; out++&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;can be refactored into something like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;in += delta(x*x + y*y, 1.0)&lt;br /&gt;out += 1.0 - delta(x*x + y*y, 1.0)&lt;br /&gt;&lt;/pre&gt;where delta is defined like&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def delta(a, b):&lt;br /&gt;if a &amp;lt; b:&lt;br /&gt; return 1&lt;br /&gt;else:&lt;br /&gt; return 0&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The authors add delta as an symbolic operation so it isn't analyzed (otherwise, we would have just moved the nondeterminism to another place). The natural limit of this kind of refactoring, I think, is to allow any pure function (referentially transparent, side-effect free, whatever), to be a symbolic operation.  I believe this would dramatically speed up analysis time.  For instance, one of the examples that was analyzed by the authors was parallel matrix multiplication.  The method of matrix multiplication is basically to have a master process that doles out column and row vectors to slave processes to compute the dot product.  Dot product can be represented as a pure function, so we can represent the slave processes with very few states (just receive, dot product, send).  We also end up with a much smaller expression table.  The additional cost would be in analyzing which functions are actually free of side-effects (which, of course, we could avoid if we were using a &lt;a href="http://haskell.org/"&gt;better language&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Another difficulty is that, all though pure functions guarantee that for any input they will always produce the same output, the converse is obviously not true.  Adding more operations to symbolic expressions makes for a coarser analysis.  Thus, if we apply the aforementioned optimization, we may report that two programs are not equivalent when they really are.  To compensate, we may have to introduce some more powerful reasoning to determine if outputs are actually equivalent.  Unfortunately, this won't solve our problems, either: our path condition reasoning facilities also need to account for the function calls.  In practice, however, I suspect that it would be easy to refactor code so that the bulk of the code lies in pure functions and we wouldn't have to worry too much about this.&lt;br /&gt;&lt;br /&gt;All in all, not a bad paper.  I don't know enough about the area to know which of the authors' ideas are really original, but at least it was a good read.  I'd say the only real problems are the lack of automated model construction and that the approach doesn't seem to be scalable.  It appears to work, however - the authors ran the analysis on 4 sample programs and found an error in one of them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3742008638855759502-2882680931325329188?l=zkincaid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zkincaid.blogspot.com/feeds/2882680931325329188/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3742008638855759502&amp;postID=2882680931325329188' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/2882680931325329188'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3742008638855759502/posts/default/2882680931325329188'/><link rel='alternate' type='text/html' href='http://zkincaid.blogspot.com/2008/09/notes-on-combining-symbolic-execution.html' title='Notes on &quot;Combining Symbolic Execution with Model Checking to Verify Parallel Numerical Programs&quot;'/><author><name>zkincaid</name><uri>http://www.blogger.com/profile/08127275535283166049</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
