<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CEYDQX0_eip7ImA9WhRWGEU.&quot;"><id>tag:blogger.com,1999:blog-22566012</id><updated>2012-01-06T15:36:10.342-05:00</updated><category term="sympy" /><category term="alienware" /><category term="edgy" /><category term="graphtheory" /><category term="visualization" /><category term="ubuntu" /><category term="compgeom" /><category term="complexity" /><category term="krr" /><title>Tech Talk</title><subtitle type="html">Projects and thoughts for the more technically driven.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://haz-tech.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://haz-tech.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Christian Muise</name><uri>https://profiles.google.com/112066465008349537127</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-adkyhxmhzn8/AAAAAAAAAAI/AAAAAAAADd4/YitpKs1XsPc/s512-c/photo.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>59</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/blogspot/QmpX" /><feedburner:info uri="blogspot/qmpx" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;CkAGSHc-eSp7ImA9Wx5SEk8.&quot;"><id>tag:blogger.com,1999:blog-22566012.post-4683860477825075771</id><published>2010-08-07T18:38:00.000-04:00</published><updated>2010-08-07T18:38:49.951-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-08-07T18:38:49.951-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sympy" /><title>SoC Wrap-up</title><content type="html">&lt;a href="http://socghop.appspot.com/gsoc/student_project/show/google/gsoc2010/python/t127230762878"&gt;Supercharging SymPy's Assumptions&lt;/a&gt; -- that was the task for my SoC project this year. So how far has it come? Well there were three substantial pushes I'll outline here:&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;i&gt;Removal of Old Assumptions&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;By a decent margin, this was the most time consuming task, and likely the one that will see the least contribution to SymPy's code-base. The conversation as to how best strip out SymPy's old assumptions continues, and my foray into the mess can be found in [&lt;a href="http://github.com/haz/sympy/tree/disconnect-assumptions"&gt;these&lt;/a&gt;] [&lt;a href="http://github.com/haz/sympy/tree/disconnect-assumptions-2"&gt;two&lt;/a&gt;] branches (the latter being the most recent and promising).&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Despite the possibility of this code not making it into the trunk, this task served as a vital in-depth introduction to the SymPy system as a whole, and gave me a far greater understanding of SymPy in general than I could have hoped by simply browsing the code-base. It also brought some of the issues with the assumption system to the forefront for discussion, which will hopefully continue beyond the bounds of the SoC timeline.&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;i&gt;SAT Solver&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Probably the most effective use of my skills, I implemented a new SAT Solver from the ground up for SymPy. It's got an &lt;a href="http://haz-tech.blogspot.com/2010/07/clause-learning-and-heuristics.html"&gt;effective heuristic&lt;/a&gt;, the &lt;a href="http://haz-tech.blogspot.com/2010/07/clause-learning-flunk.html"&gt;ground work&lt;/a&gt; for clause learning, and advanced SAT solver &lt;a href="http://haz-tech.blogspot.com/2010/08/whos-watching-watch-literals.html"&gt;data structures&lt;/a&gt;. I've spent a fair bit talking about this on the blog already, so I won't go into further detail here. But [&lt;a href="http://github.com/haz/sympy/tree/sat-solver"&gt;this&lt;/a&gt;] is the branch, and here's how it stacks up against the old DPLL solver (note that the y-axis is log scale):&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_DvrW_QLstcQ/TF3S_KdyDJI/AAAAAAAACLU/9qhiJV4q0CM/s1600/dpll.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="318" src="http://4.bp.blogspot.com/_DvrW_QLstcQ/TF3S_KdyDJI/AAAAAAAACLU/9qhiJV4q0CM/s400/dpll.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;i&gt;Knowledge Compilation&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;This here is a fuzzy term used to describe pre-computation that helps in online queries. There's a large body of research when considering queries in boolean logic, and I've had some experience dealing with such things. In fact, [&lt;a href="http://github.com/sympy/sympy/blob/master/sympy/assumptions/ask.py#L214"&gt;this line&lt;/a&gt;] in SymPy could be considered something along the lines of knowledge compilation for the assumption system -- it pre-computes the CNF of the known rules so that queries to the &lt;b&gt;ask&lt;/b&gt; function don't need to compile them every time for the logical inference.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Well we can take this a step further. And that's precisely what [&lt;a href="http://github.com/haz/sympy/tree/atms"&gt;this&lt;/a&gt;] branch does. One thing it does is [&lt;a href="http://github.com/haz/sympy/blob/atms/sympy/assumptions/ask.py#L253"&gt;explicitly store&lt;/a&gt;] the CNF so it's not computed at import time. This is accomplished by copying the output of [&lt;a href="http://github.com/haz/sympy/blob/atms/sympy/assumptions/ask.py#L180"&gt;this function&lt;/a&gt;] to the ask.py file. So now we have a simple CNF ready to go whenever the SAT solver is invoked to answer an &lt;b&gt;ask&lt;/b&gt; query.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Beyond this simple compilation, there is more we can do to completely avoid calling the SAT solver -- if we can answer the query quickly, there's no sense in calling the full DPLL algorithm. This is accomplished by pre-computing all of the implications from single assumptions -- see [&lt;a href="http://github.com/haz/sympy/blob/atms/sympy/assumptions/ask.py#L280"&gt;this dictionary&lt;/a&gt;]. An entry such as '&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Courier, monospace; font-size: 12px; line-height: 17px; white-space: pre;"&gt;&lt;span class="n" style="line-height: 1.4em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;Q&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Courier, monospace; font-size: 12px; line-height: 17px; white-space: pre;"&gt;&lt;span class="o" style="font-weight: bold; line-height: 1.4em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Courier, monospace; font-size: 12px; line-height: 17px; white-space: pre;"&gt;&lt;span class="n" style="line-height: 1.4em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;imaginary&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Courier, monospace; font-size: 12px; line-height: 17px; white-space: pre;"&gt;&lt;span class="p" style="line-height: 1.4em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Courier, monospace; font-size: 12px; line-height: 17px; white-space: pre;"&gt; &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Courier, monospace; font-size: 12px; line-height: 17px; white-space: pre;"&gt;&lt;span class="nb" style="color: #0086b3; line-height: 1.4em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;set&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Courier, monospace; font-size: 12px; line-height: 17px; white-space: pre;"&gt;&lt;span class="p" style="line-height: 1.4em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;([&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Courier, monospace; font-size: 12px; line-height: 17px; white-space: pre;"&gt;&lt;span class="n" style="line-height: 1.4em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;Q&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Courier, monospace; font-size: 12px; line-height: 17px; white-space: pre;"&gt;&lt;span class="o" style="font-weight: bold; line-height: 1.4em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Courier, monospace; font-size: 12px; line-height: 17px; white-space: pre;"&gt;&lt;span class="n" style="line-height: 1.4em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;complex&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Courier, monospace; font-size: 12px; line-height: 17px; white-space: pre;"&gt;&lt;span class="p" style="line-height: 1.4em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Courier, monospace; font-size: 12px; line-height: 17px; white-space: pre;"&gt; &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Courier, monospace; font-size: 12px; line-height: 17px; white-space: pre;"&gt;&lt;span class="n" style="line-height: 1.4em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;Q&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Courier, monospace; font-size: 12px; line-height: 17px; white-space: pre;"&gt;&lt;span class="o" style="font-weight: bold; line-height: 1.4em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Courier, monospace; font-size: 12px; line-height: 17px; white-space: pre;"&gt;&lt;span class="n" style="line-height: 1.4em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;imaginary&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Courier, monospace; font-size: 12px; line-height: 17px; white-space: pre;"&gt;&lt;span class="p" style="line-height: 1.4em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;])&lt;/span&gt;&lt;/span&gt;' should be read as, "If we know it's imaginary, then we know it must be complex and it must be imaginary".&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Simple, I know, but it saves us from calling a sat solver simply to find out that a variable is imaginary if we assume it's imaginary ;). Well maybe that would be captured by [&lt;a href="http://github.com/haz/sympy/blob/atms/sympy/assumptions/ask.py#L101"&gt;this line&lt;/a&gt;], but successive implications are all compiled down, so this does save you a fair bit. How much? Well running 'bin/test sympy/assumptions' on the trunk calls the SAT Solver 811 times while this branch cuts it down to a mere 258. Granted we now have a faster SAT solver, but why use such a big hammer when the query is simple?&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;The method also captures things like ask(x, Q.imaginary, Assume(x, Q.complex, False)) -- if Q.imaginary was true, then Q.complex must be true (because of the lookup we pre-compiled), and since we know this isn't the case, we can conclude that x is not imaginary as well. How are these facts compiled? Well we do the exhaustive checks with the SAT solver ([&lt;a href="http://github.com/haz/sympy/blob/atms/sympy/assumptions/ask.py#L195"&gt;this line&lt;/a&gt;]), and dump the results just like the pre-computed CNF.&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;So these were the dives into SymPy this summer. As I mentioned earlier, the first may not see the light of day (in the SymPy trunk), but the second two have been merged to a unified branch, [&lt;a href="http://github.com/haz/sympy/tree/soc-final"&gt;here&lt;/a&gt;]. It's been rebased on top of the current SymPy trunk, and is ready to go for testing / tampering. I'll be sending it around to the sympy-patches list, and putting notes of it up on the relevant issues. Hopefully by the firm pencil down date (August 16th), it'll be in shape for inclusion to the SymPy core. So please play with it, and let me know what you think.&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;i&gt;???&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;The concern of caching everything (in the presence of assumptions) came up for the removal of old assumptions. One thought was to disable caching altogether, but it seems vital for the efficiency in some of the more advanced features of SymPy (integral calculation, etc). But would happen if we enable the cache as soon as a SymPy call is made, and disable / flush it when the computation is done? This would allow things to be cached within a single computation, but since assumptions don't change mid-way, we would avoid any bad-cache hits. &lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Do [&lt;a href="http://github.com/haz/sympy/blob/atms/sympy/assumptions/ask.py#L280"&gt;these rules&lt;/a&gt;] all make sense? They look good to me, but like anything pre-compiled they should have some more eyes on them ;). &lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Assume(x &amp;gt; 1) is a missing puzzle piece thus far. Since &lt;b&gt;ask&lt;/b&gt;&amp;nbsp;can be called with any arbitrary expression (which is subsequently decomposed), this becomes increasingly more difficult to figure out. At a high level we want to be able to compute all of the primitive assumptions (ie. Predicates) for an expression, given a more complex expression. So for ask(x, Q.whatever, Assume(x &amp;gt; 0)), we would ask the Gt class to answer things such as, "is x Q.positive?" which would return True iff "0 is nonnegative". But this is just a specific case, and like I mentioned things get complicated with complex assumptions on more than one variable. How do we get from here to there?  &lt;br /&gt;
&lt;br /&gt;
(&lt;b&gt;Note&lt;/b&gt;: &lt;i&gt;This wasn't really part of the SoC plan, but I don't intend on stopping work on the assumptions after next week.&lt;/i&gt;) &lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22566012-4683860477825075771?l=haz-tech.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/QmpX/~4/_GncOTM0si0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://haz-tech.blogspot.com/feeds/4683860477825075771/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=22566012&amp;postID=4683860477825075771" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/4683860477825075771?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/4683860477825075771?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/QmpX/~3/_GncOTM0si0/soc-wrap-up.html" title="SoC Wrap-up" /><author><name>Christian Muise</name><uri>https://profiles.google.com/112066465008349537127</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-adkyhxmhzn8/AAAAAAAAAAI/AAAAAAAADd4/YitpKs1XsPc/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_DvrW_QLstcQ/TF3S_KdyDJI/AAAAAAAACLU/9qhiJV4q0CM/s72-c/dpll.png" height="72" width="72" /><thr:total>4</thr:total><feedburner:origLink>http://haz-tech.blogspot.com/2010/08/soc-wrap-up.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0YFRn44fyp7ImA9Wx5SEUg.&quot;"><id>tag:blogger.com,1999:blog-22566012.post-6375375338891344793</id><published>2010-08-07T00:25:00.000-04:00</published><updated>2010-08-07T00:25:17.037-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-08-07T00:25:17.037-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sympy" /><title>Who's Watching the Watch Literals?</title><content type="html">**Yes, I just made a bad &lt;a href="http://www.imdb.com/title/tt0409459/"&gt;Watchmen&lt;/a&gt;&amp;nbsp;joke, and no I haven't seen the movie yet ;).**&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;So far we have seen how the general &lt;a href="http://haz-tech.blogspot.com/2010/07/davis-putnam-logemann-loveland.html"&gt;DPLL procedure&lt;/a&gt; works, along with &lt;a href="http://haz-tech.blogspot.com/2010/07/clause-learning-and-heuristics.html"&gt;clause learning and a fancy heuristic&lt;/a&gt;. If we were to profile the solver, we'd find that most of the time at this point is spent doing unit propagation -- especially when we start adding clauses, unit prop triggers constantly. So that is precisely what &lt;i&gt;watch literals&lt;/i&gt; are used to speed up.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;The concept of watch literals was born out of a realization as to when exactly a clause is unit-prop'd -- this happens when every literal but one in a clause is set the wrong way. For a while solvers tried just counting the number of literals left to be set in a clause that isn't satisfied, and whenever this went from 2 to 1, you know it's time for unit propagation. Well since we only really care about that specific point (going from two unset literals to one), we will explicitly keep track of those two -- they are our watch literals.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Every clause that remains to be satisfied will have two watch literals associated with it. But the clause doesn't store this information, those literals do. So instead of keeping track of which clauses are yet to be satisfied, we keep a list of clauses for each literal such that the literal is one of the two watch literals assigned to that clause. And what happens when we set a variable? Well we only need to look at the clauses that the literal's negation is watching, and pick a new watch literal for that clause. An example:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Say we have the clause (x | y | z) and x / y are being watched.&lt;/li&gt;
&lt;li&gt;If z was set (regardless of direction), we don't need to do anything for this clause -- not even consider whether or not we should do anything (since updating clauses is done by enumerating z's watch literals).&lt;/li&gt;
&lt;li&gt;Say on the other hand that we set y = False instead of z. Well this clause has y as a watch literal so we would find a new watch literal to replace y -- namely z. After storing a pointer to this clause in the watch literal list for z, we continue with the search.&lt;/li&gt;
&lt;li&gt;Now assume z was set to False. Again, we would check out this clause since z was a watch literal, but this time find that we can no longer find an alternative -- this triggers unit propagation.&lt;/li&gt;
&lt;/ul&gt;&amp;nbsp;&amp;nbsp;So now the clause is satisfied, but what happens to our watch literals? This is the beautiful part -- nothing. Sure, if x is set False later on, we'll check the clause again, but we only update watch literals when the clause isn't satisfied (quick linear time check to see if a clause is satisfied).&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;But what happens when we backtrack past the decisions for y and z? This is the /really/ beautiful part -- nothing again. The clause will go from being satisfied to unsatisfied (but we aren't keeping a flag for this anymore -- remember that satisfiability of a clause is a linear time check), but we still have two watch literals set (x and z). Sure, these are different watch literals than what we started with (namely x and y), but that's perfectly ok, and it's unbelievably fast -- all because backtracking doesn't need to update any of the watch literals.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;So that's basically it. Implementing things to work properly isn't the easiest (I've failed a few times before taking up the SoC project this year), but boy oh boy does it ever pay off (see the latter part of &lt;a href="http://haz-tech.blogspot.com/2010/07/clause-learning-flunk.html"&gt;this post&lt;/a&gt;). So have watch literals gone in to SymPy yet? &lt;a href="http://github.com/haz/sympy/commit/a4facd8d6d94f54c0fbea48806b7858bc82d99bb"&gt;You bet&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;That wraps up the series of SAT solving tutorials. I haven't covered everything that went into &lt;a href="http://github.com/haz/sympy/tree/sat-solver"&gt;this branch&lt;/a&gt;, but I did touch on all the important points. I haven't come close to covering everything that goes into modern SAT solvers, but if you're interested, the &lt;a href="http://www.satisfiability.org/"&gt;Conference on Satisfiability&lt;/a&gt; would be a great place to start ;). Thanks for following along, and stay tuned for some further Assumption tweaks.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22566012-6375375338891344793?l=haz-tech.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/QmpX/~4/DKFX1Q__V-k" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://haz-tech.blogspot.com/feeds/6375375338891344793/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=22566012&amp;postID=6375375338891344793" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/6375375338891344793?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/6375375338891344793?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/QmpX/~3/DKFX1Q__V-k/whos-watching-watch-literals.html" title="Who's Watching the Watch Literals?" /><author><name>Christian Muise</name><uri>https://profiles.google.com/112066465008349537127</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-adkyhxmhzn8/AAAAAAAAAAI/AAAAAAAADd4/YitpKs1XsPc/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://haz-tech.blogspot.com/2010/08/whos-watching-watch-literals.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEcFRXk_fCp7ImA9Wx5TEks.&quot;"><id>tag:blogger.com,1999:blog-22566012.post-6741089899169036082</id><published>2010-07-27T17:26:00.000-04:00</published><updated>2010-07-27T17:26:54.744-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-27T17:26:54.744-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sympy" /><title>Clause Learning Flunk</title><content type="html">A few days back, I was on my way to write up a blog post detailing how impressive the new system is (and it /does/ have some great speedups in there). To be thorough, I wanted to show results for different parameters being disabled, but to my surprise I discovered clause learning was hurting. This flies in the face of everything we know about SAT solving, so the hunt for reasoning commenced.&lt;br /&gt;
&lt;br /&gt;
Well long story short, the hunt continues but a likely reason is the lack of impact that the simple clause learning scheme actually has. Monitoring the clauses that cause unit propagation (a measure of how useful a clause is) reveals that the learned clauses aren't actually ever being used -- big-time bummer. It's because of this, I've disabled the conflict analysis in the &lt;a href="http://github.com/haz/sympy/commit/35c0bdab85b754de91a1fb1a606155e9b4628210"&gt;latest version&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
But results are still be be had. First off, how much better are we than the original DPLL solver, and how bad does the clause learning actually hurt? Well the answers are (roughly) pretty good, and not much ;). Here's a graph plotting the run-time for the three approaches (-CA means clause learning was disabled):&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_DvrW_QLstcQ/TE9MirdDSSI/AAAAAAAACLI/VT2jesJMXYc/s1600/dpll.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="315" src="http://3.bp.blogspot.com/_DvrW_QLstcQ/TE9MirdDSSI/AAAAAAAACLI/VT2jesJMXYc/s400/dpll.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Note that the y-axis is on a log scale, so the differences are actually more drastic than they appear. Take-away: the new sat-solver is doing great, and the clause learning doesn't hurt that much...just doesn't help like we'd expect.&lt;br /&gt;
&lt;br /&gt;
Next up is the impact of watch literals. I'll have a blog post in a day or two for the final installment of "what goes into a SAT solver", and the focus will be on watch literals. The introduction of this data structure hack heralded in a wave of killer SAT solvers, and they helped out here too. The following is a comparison (with clause learning disabled) between using watch literals and not using them:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_DvrW_QLstcQ/TE9Mivz864I/AAAAAAAACLM/Gkn_qTnwkg0/s1600/watch+literal.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="318" src="http://3.bp.blogspot.com/_DvrW_QLstcQ/TE9Mivz864I/AAAAAAAACLM/Gkn_qTnwkg0/s400/watch+literal.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Oh, and it should be noted that when points don't exist, it's because the solver just couldn't handle it in a reasonable amount of time.&lt;br /&gt;
&lt;br /&gt;
So in the interest of actually letting SymPy users see these enhancements, I'm going to wrap up this week with that final post, and post-pone the clause learning investigation until more time is available. Next up is investigating how a &lt;a href="http://en.wikipedia.org/wiki/Truth_maintenance_system"&gt;truth maintenance system&lt;/a&gt; can be used to smartly cache queries to the assumption framework. If we can avoid repeated SAT queries (no matter how beefy the solver is), that's a win.&lt;br /&gt;
&lt;br /&gt;
One final note, there will likely be an incorporation of an industrial SAT-solver interface for those who really want the power. This will be through the &lt;a href="http://4c110.ucc.ie/numberjack/"&gt;Numberjack Library&lt;/a&gt;, and be optional if you happen to have it installed. The start of it is in &lt;a href="http://github.com/haz/sympy/tree/numberjack"&gt;this branch&lt;/a&gt;, but we'll need to wait until the next version of Numberjack is released due to limitations it currently has.&lt;br /&gt;
&lt;br /&gt;
That's all for now. Cheers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22566012-6741089899169036082?l=haz-tech.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/QmpX/~4/n0XP2De0jFg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://haz-tech.blogspot.com/feeds/6741089899169036082/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=22566012&amp;postID=6741089899169036082" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/6741089899169036082?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/6741089899169036082?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/QmpX/~3/n0XP2De0jFg/clause-learning-flunk.html" title="Clause Learning Flunk" /><author><name>Christian Muise</name><uri>https://profiles.google.com/112066465008349537127</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-adkyhxmhzn8/AAAAAAAAAAI/AAAAAAAADd4/YitpKs1XsPc/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_DvrW_QLstcQ/TE9MirdDSSI/AAAAAAAACLI/VT2jesJMXYc/s72-c/dpll.png" height="72" width="72" /><thr:total>4</thr:total><feedburner:origLink>http://haz-tech.blogspot.com/2010/07/clause-learning-flunk.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkcDRH89fip7ImA9WxFaGUw.&quot;"><id>tag:blogger.com,1999:blog-22566012.post-7163828547914825642</id><published>2010-07-23T14:34:00.000-04:00</published><updated>2010-07-23T14:34:35.166-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-23T14:34:35.166-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sympy" /><title>Clause Learning and Heuristics</title><content type="html">&lt;hr /&gt;&lt;div style="text-align: center;"&gt;&lt;i&gt;Clause Learning&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Everyone should learn from their mistakes, right? Of course ;). Well SAT solvers are no different. If the solver discovers that the problem has no solution when a subset of the variables are set a certain way, then that is useful knowledge -- this knowledge is captured in the form of new clauses that are added to the theory.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Now you may think that since we're doing a systematic search, we won't ever need that information again: for example if x=True / y=True / z=False led to an inconsistency and we backtracked to try other values of z, y and x, will we ever use the fact that&amp;nbsp;(!x | !y | z)&amp;nbsp;must hold? When using a static variable ordering, the answer is no. This is because if we backtrack, we will never see the same setting of variables again that led to the inconsistency. However static variable orderings are brutal :p.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Let's expand on our example to see clause learning in a little more detail. Imagine the SAT solver went as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Set x = True&lt;/li&gt;
&lt;li&gt;From unit propagation set v1 = True and v2 = False&lt;/li&gt;
&lt;li&gt;Set y = True&lt;/li&gt;
&lt;li&gt;From unit propagation set v3 = False, v4 = True, v5 = False&lt;/li&gt;
&lt;li&gt;Set z = False&lt;/li&gt;
&lt;li&gt;From unit propagation we get the empty clause !!conflict!!&lt;/li&gt;
&lt;/ul&gt;&amp;nbsp;&amp;nbsp;So what do we know? Well right off the bat x = v1 = y = v4 = True and v2 = v3 = v5 = z = False is enough to make the theory unsatisfiable (so solution exists with those settings). But remember that unit propagation is a sound procedure -- the variables v1 - v5 are all implied by setting x and y to True [0]. So really just the settings to x, y, and z are enough to cause the problem. How could we have avoided it? Well what if we had the clause (!x | !y | z)? Note that this is just say at least one of the variables was set different. If we had that clause to begin with, our search would have looked like this:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Set x = True&lt;/li&gt;
&lt;li&gt;From unit propagation set v1 = True and v2 = False&lt;/li&gt;
&lt;li&gt;Set y = True&lt;/li&gt;
&lt;li&gt;From unit propagation set v3 = False, v4 = True, v5 = False, &lt;b&gt;z = True&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;So what we do is add the clause,&amp;nbsp;(!x | !y | z), to our database of clauses and continue the search. Since we're backtracking, we'll set z=True anyways (the clause wasn't really needed), but in the future (say if we backtrack higher and go down another branch, we may face the same decisions. This is when the clause really becomes useful.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Now the method I just described uses a very simple technique to figure out the clause it should create / add -- it picks the negation of all the decisions you've made so far. However there are far more complex schemes that are ongoing research. I may incorporate these into SymPy some day, but for now the default &lt;a href="http://github.com/haz/sympy/commit/e85c6a8d7ac736bcbe1d60c3cb96d4f932421db4"&gt;works great&lt;/a&gt; ;).&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Another common concern (which I'll avoid dealing with for now) is how to detect useless clauses -- eventually learned clauses are no longer triggering and just taking up precious cycles in the solving process (and memory too). Elaborate cache flushing schemes have been proposed (and still are being actively researched), but SymPy likely won't be getting to the point where that would be&amp;nbsp;necessary.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;So that's all for clause learning. It's extremely helpful in the context of SAT solving, and is finally in our SymPy solver.&lt;br /&gt;
&lt;br /&gt;
[0]: I won't go into detail here, but you get the same result if you set a number of variables and then do unit prop as if you interleaved unit prop with each variable setting.&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;&lt;div style="text-align: center;"&gt;&lt;i&gt;VSIDS Heuristic&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;So behind any reasonable SAT solver is a great heuristic. Variable State Independent Decaying Sum (VSIDS) is one such heuristic. What does a heuristic do? Well at each node in the search tree, it should tell you what variable to set, and what to set it to.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;VSIDS works by three main steps:&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;First it assigns a score to every literal (or variable setting if you will) matching the number of clauses that the literal appears in. So if a literal is in a large number of clauses, it will be picked before one that isn't.&lt;/li&gt;
&lt;li&gt;Every time a clause is added, the literals in that clause get their score bumped up (by 1). Every time a clause is deleted, the scores get reduced (by 1).&lt;/li&gt;
&lt;li&gt;At regular intervals, /every/ literal has their score reduced by a constant factor (divide by two is typical).&lt;/li&gt;
&lt;/ol&gt;&amp;nbsp;&amp;nbsp;So what does this accomplish? Well at a high level it prefers variable settings that will satisfy the majority of clauses, and over time (through steps 2 and 3) it will prefer literals that will satisfy a large number of learned clauses. This has the effect of avoiding bad parts of the search space where a solution is unlikely to exist.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;The SymPy solver &lt;a href="http://github.com/haz/sympy/commit/4690882e075e0ef1bbfdd3f8155e365fcdac17eb"&gt;now has VSIDS&lt;/a&gt; driving the search, with the one step of #3 missing (coming soon ;)). The beauty of VSIDS is how nicely it plays with the clause-learning of the SAT solver to make things exceptionally fast.&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;That's all for now. I'll have another post soon showing some recent results, and one more within the following week to describe the data structures that make all this possible.&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22566012-7163828547914825642?l=haz-tech.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/QmpX/~4/ud94Vn2Rvlc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://haz-tech.blogspot.com/feeds/7163828547914825642/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=22566012&amp;postID=7163828547914825642" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/7163828547914825642?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/7163828547914825642?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/QmpX/~3/ud94Vn2Rvlc/clause-learning-and-heuristics.html" title="Clause Learning and Heuristics" /><author><name>Christian Muise</name><uri>https://profiles.google.com/112066465008349537127</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-adkyhxmhzn8/AAAAAAAAAAI/AAAAAAAADd4/YitpKs1XsPc/s512-c/photo.jpg" /></author><thr:total>4</thr:total><feedburner:origLink>http://haz-tech.blogspot.com/2010/07/clause-learning-and-heuristics.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0IASX88cSp7ImA9WxFaFU0.&quot;"><id>tag:blogger.com,1999:blog-22566012.post-8630940078326612150</id><published>2010-07-18T22:12:00.000-04:00</published><updated>2010-07-18T22:12:28.179-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-18T22:12:28.179-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sympy" /><title>Davis Putnam Logemann Loveland</title><content type="html">&amp;nbsp;&amp;nbsp;Last post we saw what the problem of Satisfiability was, and specifically the form of input that we're concerned with handling -- CNF. In this post I'll describe the primary method of solving this problem that almost every modern SAT solver uses (and there are quite a few out there) -- &lt;a href="http://en.wikipedia.org/wiki/DPLL_algorithm"&gt;DPLL&lt;/a&gt; (named after the authors).&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Before I get into the DPLL details, however, I should mention local search. There has indeed been some success over the years with local search algorithms when applied to the Satisfiability problem. The idea with these algorithms is to fix all of the variables (your candidate solution) and explore the neighborhood of candidate solutions found by flipping the value of a single variable. This is not what SymPy uses, nor will it, but it's worth mentioning for the sake of completeness.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;So...on to DPLL. This can be broken down into three main parts: the &lt;b&gt;DP&lt;/b&gt; algorithm (which was out there before Logemann and Loveland came along), &lt;b&gt;unit propagation&lt;/b&gt;, and the &lt;b&gt;pure literal&lt;/b&gt; rule.&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;i&gt;DP&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;The DP part of the DPLL algorithm is a systematic search through the variable assignments that follow from a few (somewhat obvious) facts about the boolean theory in CNF. At each stage in the search, the algorithm must 1. Pick a variable it is going to set next and 2. Decide what that variable should be set to. Why can we do this? Well any variable must be set either True or False in any full assignment.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;So say we've selected the variable x and decided to set it to True. Any clause that has the literal x is now guaranteed to be satisfied, so we throw it away for the next part of the search. Any clause that had the literal !x, on the other hand, must rely on one of the other literals in the clause -- hence we throw out the literal !x before going forward. After this, we now have a new theory that says nothing about x, and is simpler than the original one. We recursively call the DP algorithm for this theory, and if that fails (I'll describe how in a sec), we throw all those clauses and literals back in, and try again with x=False. If both fail, we return fail, and if we're at the root of our search tree, there doesn't exist any solution to the set of clauses.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;So what's our base case? Well if we have an empty clause in the theory, none of the literals in that clause can be satisfied (obviously). It seems silly to have a CNF with an empty clause in it, and you wouldn't expect one to be given to a solver, but through the solving process I've just described, they certainly come up all the time -- otherwise the problem would be far too easy to solve ;).&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;So that's the DP algorithm. Simply a systematic search through the variable assignments where each search node in the tree is a variable selection and the branches are on what value at variable should take.&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;i&gt;Unit Propagation&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;If you have a boolean theory in CNF, and there's a clause that contains only a single literal (recall that every clause in CNF needs to hold), the we know for certain that the literal must be set to True (if it's x, then set x to True / if it's !x, then set x to False). This is the premise behind unit propagation. It can be extremely powerful when doing SAT solving since it sets so many other variables after making a single decision (most of the time).&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Essentially unit prop works by setting variables according to the unit clauses they appear in when any unit clause exists. Some unit propagation can cause other clauses to become unit, so the process continues to a fix-point. If the empty clause is ever generated, then you've found an inconsistency and you backtrack. When used with the DPLL algorithm, these variable settings found with unit propagation are considered implications of the last decision the search made. So when it comes time to backtrack, you don't go and try every opposite setting of a unit prop'd variable -- it would just be wasting time.&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;i&gt;Pure literals&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;If you have a theory in CNF and a variable appears only a certain way, say positively, then if any solution exists we can be sure one exists with the variable set to True. This is the intuition behind the purer literal rule. A literal is pure, with respect to a boolean theory, if it's negation doesn't appear in the theory at all. When this happens, we can safely set the variable, and continue. If no solution is found, then we know that no solution would be found with the variable set in the opposite manner (since that would only make solving the problem harder by removing literals from clauses that still need to be satisfied).&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;The pure literal rule changes the theory, but it is sound in the sense that if any solution existed before, we're guaranteed at least one still exists. Despite this nice property, the pure literal rule is left out of most modern SAT solvers. It will be implemented in SymPy, but likely disabled by default. The reason for this is that the largest advancements (since the invention of DPLL in the 60's) to SAT solving are attributed to data structure improvements. Keeping around the info for efficient pure literal detection has proven to hurt more than help.&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;So that's the DPLL algorithm in a nut shell. Next time I'll describe clause learning and non-chronological backtracking -- another two significant advances for SAT solving that came in the 90's. After that, a little data structures talk, and the discussion (as far as what's going into SymPy) will be complete. Hopefully so will the solver for SymPy.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Cheers&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22566012-8630940078326612150?l=haz-tech.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/QmpX/~4/mLKR5TUahvY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://haz-tech.blogspot.com/feeds/8630940078326612150/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=22566012&amp;postID=8630940078326612150" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/8630940078326612150?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/8630940078326612150?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/QmpX/~3/mLKR5TUahvY/davis-putnam-logemann-loveland.html" title="Davis Putnam Logemann Loveland" /><author><name>Christian Muise</name><uri>https://profiles.google.com/112066465008349537127</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-adkyhxmhzn8/AAAAAAAAAAI/AAAAAAAADd4/YitpKs1XsPc/s512-c/photo.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://haz-tech.blogspot.com/2010/07/davis-putnam-logemann-loveland.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0ABQXY9eSp7ImA9WxFaE04.&quot;"><id>tag:blogger.com,1999:blog-22566012.post-4786568322299478819</id><published>2010-07-17T00:09:00.000-04:00</published><updated>2010-07-17T00:09:10.861-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-17T00:09:10.861-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sympy" /><title>SAT Solving -- The Basics</title><content type="html">So I've come to the realization that in order for anyone reading this to understand the concepts forthcoming, some level of SAT solving theory is going to be required. As such, I'll put up a few posts describing the basics from both the theoretical and empirical sides of things. So first up, the theory...&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;I won't go into too much detail about the benefit of the problem of Satisfiability. It's the grand daddy of all generic problems that you can map some problem into (one of the original NP-Complete discoveries). It suffices to say that there's an absurd amount of "really difficult" problems in computer science that can be cast as a Satisfiability problem, and if you had an oracle that could solve these Satisfiability problems, you have an efficient means of solving all those difficult problems.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;So what is the problem of Satisfiability? Well you have a number of boolean variables to start with -- lets use x, y, and z to example -- and a well formed formula involving just those variables, negation (denoted by '!'), disjunctions (denoted by '|'), conjunctions (denoted by '&amp;amp;'), and brackets. Recall that a boolean variable can take on the value True or False. The disjunctions simply mean 'or', so (x | y) says that either x or y is True. The conjunctions simply mean 'and', so (x &amp;amp; y) says that both x and y is True. Further, we say that a literal is either a variable (eg. x), or it's negation (eg. !x).&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Once you have a big formula of these variables, and the symbols ! | &amp;amp;, the problem of Satisfiability is to find an assignment of those variables that satisfy the boolean formula. Some formulas can be quite simple, for example a solution to (x | y) would just require you to have either x = True or y = True. But some syntactic restriction on the formulas gives us something that most problems map easily to, but isn't so simple to solve -- the form most common for this is &lt;i&gt;Conjunctive Normal Form&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;So we define a clause as a disjunction of literals -- for example (x | y | !z). A theory is in conjunctive normal form (or CNF) if it is a conjunction of clauses. This would be an example of a theory with one solution --&amp;nbsp;(x | y) &amp;amp; (!x | y) &amp;amp; (x | !y) -- both x and y have to be True, but that's not immediately evident from the formula. Note that if we add the clause (!x | !y) to the theory, then there exists no solution (ie. is is unsatisfiable or UNSAT).&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;How might one go about figuring out the assignment of variables? Well one (foolish) way would be to try all 2**n combinations (where n is the number of variables) of truth assignments and see if any of them work out. This, however, is not practical for any reasonable size n. In fact, state of the art solvers today can solve problems with hundreds of thousands of variables and millions of clauses. In the next post I'll describe the classical algorithm that forms the foundation of almost all modern SAT solvers -- DPLL.&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;A quick update -- I've re-implemented the data structure used for the heuristic in the SAT solver. This results in about another 30%-50% speed up depending on the size of the problem (more pronounced on larger problems). By the end of next week I hope to have watch literals and clause learning both explained here in the blog, and implemented for the sympy solver.&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
&lt;div style="text-align: center;"&gt;???&lt;/div&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;My only question would be, does anyone have any questions? ;)&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/22566012-4786568322299478819?l=haz-tech.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/QmpX/~4/zya3G0jGbVM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://haz-tech.blogspot.com/feeds/4786568322299478819/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=22566012&amp;postID=4786568322299478819" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/4786568322299478819?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/4786568322299478819?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/QmpX/~3/zya3G0jGbVM/sat-solving-basics.html" title="SAT Solving -- The Basics" /><author><name>Christian Muise</name><uri>https://profiles.google.com/112066465008349537127</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-adkyhxmhzn8/AAAAAAAAAAI/AAAAAAAADd4/YitpKs1XsPc/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://haz-tech.blogspot.com/2010/07/sat-solving-basics.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A04MQXo4fyp7ImA9WxFbF00.&quot;"><id>tag:blogger.com,1999:blog-22566012.post-2912436776325383830</id><published>2010-07-09T17:13:00.000-04:00</published><updated>2010-07-09T17:13:00.437-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-09T17:13:00.437-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sympy" /><title>Day Delay</title><content type="html">This week has been quite crazy, and unproductive from a SoC standpoint. Well at least if that's measured in commits ;). I did manage to have a number of fruitful discussions with some SAT solving experts as to how the current approach can be approved, and I'll be writing a blog post about some of that tomorrow. And what's been keeping me busy? I'll be presenting my master's work (which is somewhat related to this summer's project) at a &lt;a href="http://www.cs.cornell.edu/~sabhar/workshops/wara-2010/schedule.htm"&gt;workshop on Monday&lt;/a&gt;. Stay tuned, the next few weeks should be lively.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Cheers&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22566012-2912436776325383830?l=haz-tech.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/QmpX/~4/bCpBA2hmBWs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://haz-tech.blogspot.com/feeds/2912436776325383830/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=22566012&amp;postID=2912436776325383830" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/2912436776325383830?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/2912436776325383830?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/QmpX/~3/bCpBA2hmBWs/day-delay.html" title="Day Delay" /><author><name>Christian Muise</name><uri>https://profiles.google.com/112066465008349537127</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-adkyhxmhzn8/AAAAAAAAAAI/AAAAAAAADd4/YitpKs1XsPc/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://haz-tech.blogspot.com/2010/07/day-delay.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEYDQnY_eSp7ImA9WxFbEU4.&quot;"><id>tag:blogger.com,1999:blog-22566012.post-521273536291163599</id><published>2010-07-03T00:42:00.000-04:00</published><updated>2010-07-03T00:42:53.841-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-03T00:42:53.841-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sympy" /><title>A Satisfying Week</title><content type="html">&amp;nbsp;&amp;nbsp;Work switched up this week from the &lt;a href="http://github.com/haz/sympy/tree/disconnect-assumptions-2"&gt;removal of the assumption system&lt;/a&gt;, to &lt;a href="http://github.com/haz/sympy/tree/sat-solver"&gt;re-implementing a fast SAT solver&lt;/a&gt;. Granted, a good 11 commits went in to the removal of the assumption system to bring it to it's current state -- 7 failed / 9 exceptions over the entire project -- but these came early in the week, and the discussion on that branch continues on the SymPy list.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;The SAT-Solver re-implementation just barely made it to a workable state earlier this evening -- valid models are found for SAT theories and UNSAT ones are proven as such. The internal use of the SAT solver was switched to the new one, and all still runs fine (unit tests and whatnot). Beyond that, we need a way to measure progress, so I wrote a quick little script to benchmark SAT solving systems (and potentially heuristics within them if we'd like to compare those as well). The benchmark script can be found &lt;a href="http://github.com/haz/sympy/blob/sat-solver/sympy/logic/benchmarks/run-solvers.py"&gt;here&lt;/a&gt;. Basically it runs the systems against a number of random 3SAT theories created at the &lt;a href="http://www.springerlink.com/content/12nj961tv674k177/"&gt;hardness threshold&lt;/a&gt; (about 4.25 clauses to every variable).&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;So how does the new system compare? The following graph plots the original (dpll) against the new version (dpll2):&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://spreadsheets.google.com/oimg?key=0Ap3zPxQBULIedG0xRWtKR0ltZThKNGQxSUtMdHZrT3c&amp;amp;oid=2&amp;amp;zx=ta69bq-2inhk2" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="300" src="https://spreadsheets.google.com/oimg?key=0Ap3zPxQBULIedG0xRWtKR0ltZThKNGQxSUtMdHZrT3c&amp;amp;oid=2&amp;amp;zx=ta69bq-2inhk2" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;And where might the speedup be coming from? Well there are a few data structure improvements that save time at various parts of the algorithm, but the largest improvement is likely due to the inclusion of a heuristic. At the moment it is quite crude -- basically picking the literal that appears in the most number of clauses -- but it's enough to have a surprising impact. So far unit propagation is implemented, but the next step will be to incorporate &lt;a href="http://en.wikipedia.org/wiki/Constraint_learning"&gt;clauses learning&lt;/a&gt; and &lt;a href="http://books.google.ca/books?id=Kjap9ZWcKOoC&amp;amp;pg=PA101&amp;amp;lpg=PA101&amp;amp;dq=watch+literals&amp;amp;source=bl&amp;amp;ots=QACnxQ_RTh&amp;amp;sig=jzXND6ZSdbD2y7YFTxHlUyVt3pI&amp;amp;hl=en&amp;amp;ei=Hb0uTM7rM4W8lQfXio2xCQ&amp;amp;sa=X&amp;amp;oi=book_result&amp;amp;ct=result&amp;amp;resnum=3&amp;amp;ved=0CBwQ6AEwAg#v=onepage&amp;amp;q=watch%20literals&amp;amp;f=false"&gt;watch literals&lt;/a&gt;. Both have been known to offer substantial savings for SAT solvers, and will likely do the same for SymPy.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;One last thing to note -- the typical clause learning scheme in SAT solvers is &lt;a href="http://portal.acm.org/citation.cfm?id=1768142.1768169"&gt;1UIP&lt;/a&gt;. However, &lt;a href="http://www.aaai.org/Conferences/AAAI/aaai10.php"&gt;AAAI&lt;/a&gt; is just around the corner and I'll be presenting some of my research there. Coincidentally there is some nifty new clause learning schemes being presented by some of the recent contenders in the yearly SAT solving contest, and I may take a stab at implementing their ideas if they are accessible enough.&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
&lt;div style="text-align: center;"&gt;???&lt;/div&gt;&lt;ol&gt;&lt;li&gt;Eventually things may be ported to cython. I've been trying to avoid anything /too/ pythonic (stick to using lists like arrays, simple sets, etc). Does there happen to be a set of "best practices" for programming in python with the intent of porting to cython at some point in the future?&lt;/li&gt;
&lt;li&gt;What's some of the "hard core" assumption problems that the SAT solver in SymPy is actually the bottleneck for? I'd like to have some ultimate goal in mind rather than just trying to squeeze the speed out of the thing in random SAT theory comparisons.&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22566012-521273536291163599?l=haz-tech.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/QmpX/~4/l3Ol6KBdZNs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://haz-tech.blogspot.com/feeds/521273536291163599/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=22566012&amp;postID=521273536291163599" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/521273536291163599?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/521273536291163599?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/QmpX/~3/l3Ol6KBdZNs/satisfying-week.html" title="A Satisfying Week" /><author><name>Christian Muise</name><uri>https://profiles.google.com/112066465008349537127</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-adkyhxmhzn8/AAAAAAAAAAI/AAAAAAAADd4/YitpKs1XsPc/s512-c/photo.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://haz-tech.blogspot.com/2010/07/satisfying-week.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkEESXk_cCp7ImA9WxFUFU4.&quot;"><id>tag:blogger.com,1999:blog-22566012.post-7881231194766096203</id><published>2010-06-26T01:36:00.001-04:00</published><updated>2010-06-26T01:36:48.748-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-26T01:36:48.748-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sympy" /><title>Testing, testing, 1 - 2 - 3</title><content type="html">&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&amp;nbsp;&amp;nbsp;The SoC work this week consisted of a strong push to remove the assumptions, found in &lt;a href="http://github.com/haz/sympy/tree/disconnect-assumptions-2"&gt;this branch&lt;/a&gt;. First step was to get the sympy core working, and that was achieved around &lt;a href="http://github.com/haz/sympy/commit/5fe539cf48d9f130c41eb7a032c8ef01942ec8b9"&gt;this commit&lt;/a&gt;. From there I started picking off the surrounding systems one by one until today. I didn't get all the way, but I've fixed a number of substantial things along the way that the core tests just didn't cover.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&amp;nbsp;&amp;nbsp;Most of the intricate issues were raised not by disabling the assumptions used in testing, but modifying them to use the global_assumptions rather than local variable ones. Granted this did mean a large amount of re-write, and disabling of assumptions every time they were included, but a number of problems created by removing AssumeMeths have been brought to the forefront, and dealt with. Some were simple (for example saying that something finite is bounded), but others had me picking through winpdb hours on end to try and find infinite loops. As a result I've become much more intimate with the system, which I guess is a good thing ;).&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&amp;nbsp;&amp;nbsp;As it stands, 1902 tests pass, 16 fail, and 41 throw an exception. Since I currently only have access to the netbook for testing (G20 is in town and the Uni is shut down), which takes 20-30min for a full run through testing, I won't be generating a commit-by-commit set of statistics this week. But needless to say, 57 issues is very low, and likely only a day or two worth of work at the pace I've been able to get to. Depending on what the mentors think, I may or may not continue pushing on this branch, but either way next week's post will focus on the SAT solver improvements ;).&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&amp;nbsp;&amp;nbsp;So some major take-aways from what was done:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;Assumption handling is now done and delegated mostly in the Expr class. Most things inherit from this, and so it is a logical place. In general when is_* is asked, we look for an assumption in the global_assumptions, then try an _eval_is_* function, and then possibly check sufficient conditions. Care was taken to avoid infinite loops, and many of the old assumption implications are present here.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;At one point the cache was disabled, since certain expressions would be cached with assumptions, and then retrieved later during testing with a different set of assumptions (which is wrong -- it should be recomputed). This slowed things down horribly, but was still&amp;nbsp;manageable&amp;nbsp;until I hit the 'series' code earlier today. Countless objects are created and re-created in the gantz approach to calculating limits, and for the longest time I was looking for an infinite loop when in fact it was just deathly slow. &lt;a href="http://github.com/haz/sympy/commit/10943393dbc019ddb627885ff46cd4c84274071b"&gt;This commit&lt;/a&gt; re-enables the cache, and flushes it out every time the global_assumptions are updated. A crude work-around, but quite effective since the number of assumption modifications is quite limited. The solution is still not ideal, but does the trick. In the future, it should only clear out the relevant parts of the cache when an assumption changes, and it will be a design decision as to whether or not calling Symbol('x') more than once should clear the cache of all expressions involving x or not.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;When the caching is flushed or disabled, f(x) != f(x) where f and x are just symbols. The comparison is done on object hash's, and when a separate one is created because of cache issues they don't equal one another. This was a very ugly beast when trying to figure out why tests were failing.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;AssumptionContext isn't all that smart. It now flushes the cache whenever an assumption is added or deleted, but at the very least it should avoid adding assumptions that are already there. Since AssumptionContext subclasses set, this should already be handled, so there's likely something funny going on with the Assume __eq__ operator.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;The assumptions argument is still in the constructor of many objects. Gradually all parts of the code that use this are being changed to use global_assumptions, but the kwargs should still be brought in -- for example some objects look for an evaluate=True/False. In these cases, the **assumptions should be renamed to **options, and any code depending on specific assumptions should be stripped out.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;hr /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;???&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;Is there any way to use bin/test to get at a specific test case in a file? Some of the testing files take quite a while (on the netbook) to run through all the working tests to hit a failing one.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;Whats the best practice (for sympy) on rebasing? I've neglected to do it thus far, and that may make things difficult come merge time. What's a typical recommended frequency?&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22566012-7881231194766096203?l=haz-tech.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/QmpX/~4/zexhwf_IwMA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://haz-tech.blogspot.com/feeds/7881231194766096203/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=22566012&amp;postID=7881231194766096203" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/7881231194766096203?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/7881231194766096203?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/QmpX/~3/zexhwf_IwMA/testing-testing-1-2-3.html" title="Testing, testing, 1 - 2 - 3" /><author><name>Christian Muise</name><uri>https://profiles.google.com/112066465008349537127</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-adkyhxmhzn8/AAAAAAAAAAI/AAAAAAAADd4/YitpKs1XsPc/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://haz-tech.blogspot.com/2010/06/testing-testing-1-2-3.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0QDSXg9fSp7ImA9WxFVGU8.&quot;"><id>tag:blogger.com,1999:blog-22566012.post-4699957336727067003</id><published>2010-06-19T01:29:00.000-04:00</published><updated>2010-06-19T01:29:38.665-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-19T01:29:38.665-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sympy" /><title>Take Two</title><content type="html">&amp;nbsp;&amp;nbsp;So after struggling with the&amp;nbsp;amalgamated&amp;nbsp;attempt to merge assumption-rewrite attempts, it was decided that I should just restart from the single branch that's most recent -- Ondrej's &lt;a href="http://github.com/certik/sympy/tree/assum"&gt;removal attempt&lt;/a&gt;. To this end, and through subsequent discussion, the following is the game plan going forward:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Push forward as best I can to try and get &lt;a href="http://github.com/haz/sympy/commits/disconnect-assumptions-2"&gt;my version&lt;/a&gt; of the branch down to a workable state with assumptions removed, with a deadline of next Friday.&lt;/li&gt;
&lt;li&gt;Provide constant feedback on the state of the system throughout the week.&lt;/li&gt;
&lt;li&gt;Move on to working on the new SAT solver next Friday -- regardless of the state of the branch.&lt;/li&gt;
&lt;/ol&gt;&amp;nbsp;&amp;nbsp;So which me luck I guess ;). I'm unclear as to how far I'll get, but one thing for sure is that the next phase of SoC won't depend on the previous, and development on this assumption removal can happen concurrently since there is such a large disconnect.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Since I'll be trying to document the progress made, here's a list of the progress so far (since forking Ondrej's branch):&lt;br /&gt;
&lt;br /&gt;
&lt;iframe frameborder="0" height="300" src="https://spreadsheets.google.com/pub?key=0Ap3zPxQBULIedGs1c2FCSzJnVzJaZTZGSXBoU1dCZWc&amp;amp;single=true&amp;amp;gid=0&amp;amp;output=html&amp;amp;widget=true" width="500"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
&lt;div style="text-align: center;"&gt;???&lt;/div&gt;&lt;ol&gt;&lt;li&gt;'git co HEAD~1' brings me back one revision. How do I go forward one?&lt;/li&gt;
&lt;li&gt;In the &lt;a href="http://github.com/haz/sympy/commit/e9d346e31a1e1573d123da1151df6df81ddd1a38"&gt;current state&lt;/a&gt;, abs(Symbol('x')) returns&amp;nbsp;x**(1/2)*conjugate(x)**(1/2). In a proper branch (eg. trunk), it returns abs(x). I can't seem to figure out what's going on here...assumptions shouldn't be involved, should they?&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22566012-4699957336727067003?l=haz-tech.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/QmpX/~4/y2wX9fZbyXM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://haz-tech.blogspot.com/feeds/4699957336727067003/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=22566012&amp;postID=4699957336727067003" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/4699957336727067003?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/4699957336727067003?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/QmpX/~3/y2wX9fZbyXM/take-two.html" title="Take Two" /><author><name>Christian Muise</name><uri>https://profiles.google.com/112066465008349537127</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-adkyhxmhzn8/AAAAAAAAAAI/AAAAAAAADd4/YitpKs1XsPc/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://haz-tech.blogspot.com/2010/06/take-two.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE8CQnc4cCp7ImA9WxFVEkQ.&quot;"><id>tag:blogger.com,1999:blog-22566012.post-6454913605742455404</id><published>2010-06-11T17:47:00.000-04:00</published><updated>2010-06-11T17:47:43.938-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-11T17:47:43.938-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sympy" /><title>Plowing Forward</title><content type="html">This week I continued in my quest to remove the old assumptions. One key aspect of this process is removing it from the constructor of typical sympy objects -- under the new way of doing assumptions you should be creating an assumption context when anything out of the ordinary is being assumed.&lt;br /&gt;
&lt;br /&gt;
As mentioned in last week's post, this week was spent pushing forward from the changes found [&lt;a href="http://github.com/rlamy/sympy/commits/use-new-assump2"&gt;here&lt;/a&gt;]. As per a suggestion from Ondrej's last &lt;a href="http://ondrejcertik.blogspot.com/2010/06/week-may-30-june-4.html"&gt;blog post&lt;/a&gt;, this is what the weeks commit history looks like:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Christian Muise (7):&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;Merge branch 'master' into disconnect-assumptions&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;Lots of fixes from this branch ( http://github.com/rlamy/sympy/commits/use-new-assump2 ) on the May 17th commits. Only those that mesh well with Ondrej's branch are used.&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;Changes from May 18th on this branch ( http://github.com/rlamy/sympy/commits/use-new-assump2 ).&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;Fixing some bugs with constructors that didn't allow the project to be installed / tested.&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;Minor import fix.&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;Removing the assumptions from the Pow object.&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;Trying to remove assumptions from the constructor of sympy objects, encountered an infinite loop some place.&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;Quite a decent summary ;). What isn't reflected there, is the loads of cherry-picking I managed to achieve. After getting a grasp of how to set up the local repos, and what sha1 I was actually looking for, I went through Ronan's commits one by one, and brought in those that made sense with the stuff from Ondrej's branch. Quite happy with how the whole thing works out, and in general it went off without a hitch.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;To monitor the status of the branch, I've been keeping a tally of a few metrics from running a simple test (bin/test sympy/core): the number of tests passing, failing, errors thrown, and time. Together they give a rough indication of how things are progressing. I may write up a quick script that samples the history of the branch and plots those metrics -- might be a good way of monitoring progress.&lt;br /&gt;
&lt;br /&gt;
Unfortunately the branch is currently in a hairy state with an infinite loop being caused (recursion depth on constructors). I think this may have been an issue that already existed with the changes put in for the 'Application' class (see &lt;a href="http://github.com/rlamy/sympy/commit/454bbe395d40dde96902ba6e82f05cce26117604"&gt;this commit&lt;/a&gt;), and only revealed by fixing other problems in the code, but I can't be sure (see question 1 below).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;So the removal of old assumptions seems to be taking longer than expected. This may require a rethinking of milestones, and hopefully I'll have a better handle on the projected time-to-completion by next week with the help of my mentor, and lurkers in the sympy channel.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;hr /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: center;"&gt;???&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;The infinite loop actually occurs in a number of different ways during the testing (all related to the Application class I believe). An example of one such loop can be found [&lt;a href="http://www.haz.ca/docs/temp/loop.txt"&gt;here&lt;/a&gt;]. A minimal script causing the problem would be to import re (from sympy), and try to execute that on an arbitrary symbol. I'm at a loss as to what's going wrong here...but hopefully someone with better sympy eyes can see the error with the narrowing down I've done.&lt;/li&gt;
&lt;li&gt;Only one question this week -- it's a road-blocker for me...&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22566012-6454913605742455404?l=haz-tech.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/QmpX/~4/XeQlYMC9udM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://haz-tech.blogspot.com/feeds/6454913605742455404/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=22566012&amp;postID=6454913605742455404" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/6454913605742455404?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/6454913605742455404?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/QmpX/~3/XeQlYMC9udM/plowing-forward.html" title="Plowing Forward" /><author><name>Christian Muise</name><uri>https://profiles.google.com/112066465008349537127</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-adkyhxmhzn8/AAAAAAAAAAI/AAAAAAAADd4/YitpKs1XsPc/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://haz-tech.blogspot.com/2010/06/plowing-forward.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk4HQXk7cSp7ImA9WxFWF0w.&quot;"><id>tag:blogger.com,1999:blog-22566012.post-8235398742651062199</id><published>2010-06-05T01:15:00.000-04:00</published><updated>2010-06-05T01:15:30.709-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-05T01:15:30.709-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sympy" /><title>Two steps forward, one step back...</title><content type="html">&amp;nbsp;&amp;nbsp;So I finally got up and going this week with the code base according to last week's plan. It's been more of a learning experience than a productive one, but better now than later in the summer, eh?&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;First off, the newly created branch you can track my changes on can be found [&lt;a href="http://github.com/haz/sympy/tree/disconnect-assumptions"&gt;here&lt;/a&gt;]. The life of this branch will not extend to the knowledge compilation or SAT speedups, but simply for the disconnection of the old assumption system -- a task that's proving to be far more difficult than expected :p.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Two steps forward:&lt;/b&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;The main thrust of the work done this week was to first branch the right spot from &lt;a href="http://github.com/rlamy/sympy/commits/new-assump"&gt;Ronan's work&lt;/a&gt; building off the predicate branch. Along with this, I merged in all of &lt;a href="http://github.com/certik/sympy/tree/assum"&gt;Ondrej's work&lt;/a&gt;, commit by commit [1].&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Second thing I did was to try and fix up some of the errors. Unfortunately my approach was &lt;i&gt;way&lt;/i&gt; off base. After going through all the commits from Ondrej's work, I was under the impression that simple assumptions were things inherited from the Basic class (eg. is_Integer, etc), and these are overridden when appropriate (eg. in the Integer class). Commits such as &lt;a href="http://github.com/certik/sympy/commit/1769e221f4c84ca44d754311460e95774a6d2dee"&gt;this one&lt;/a&gt; gave me the impression that things like is_rational should have been is_Rational instead. Ditto with is_real --&amp;gt; is_Real. Because of this, I proceeded to include all of the basic assumptions (is_even, is_nonpositive, etc) in the Basic class, and fix all is_real to be is_Real.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;One step back:&lt;/b&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Apparently the lowercase refers to assumptions that can be inferred through the assumption system / reasoning, while the uppercase refers to just a check for whether or not it matches the class. One step back.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Onwards?&lt;/b&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Well now that I've cleared up my misconception (props to Aaron for fielding the questions), I think the best next step will be to try and follow the history &lt;a href="http://github.com/rlamy/sympy/commits/use-new-assump2"&gt;this branch&lt;/a&gt; takes. It naturally follows from the branch I forked in the first place, and doesn't stray so far from the changes introduced by Ondrej's work. Again, this will mainly serve to help me learn how the assumption framework is intertwined with the sympy core, and hopefully give a glimpse into how I can make the speedup this summer as seamless as possible.&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
&lt;div style="text-align: center;"&gt;???&lt;/div&gt;&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;With the removal of AssumeMeths (and Basic inheriting from it), the natural question is whether or not assumptions should even be passed in when creating symbols as is currently the case? If not, then should the &lt;symbol var=""&gt;.is_* be removed when * is even, real, nonpositive, etc?&lt;/symbol&gt;&lt;/li&gt;
&lt;li&gt;It looks like the old assumptions did have some higher form of reasoning. Should that be mirrored in the new simple backend for the ask, refine, etc?&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
[1]: I know, I know -- why not use cherry-pick instead of manually applying changes? Well I wanted to make sure I knew what was going in, and I haven't fully figured out the cherry-pick command yet :p.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22566012-8235398742651062199?l=haz-tech.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/QmpX/~4/Do-YCiawl_0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://haz-tech.blogspot.com/feeds/8235398742651062199/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=22566012&amp;postID=8235398742651062199" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/8235398742651062199?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/8235398742651062199?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/QmpX/~3/Do-YCiawl_0/two-steps-forward-one-step-back.html" title="Two steps forward, one step back..." /><author><name>Christian Muise</name><uri>https://profiles.google.com/112066465008349537127</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-adkyhxmhzn8/AAAAAAAAAAI/AAAAAAAADd4/YitpKs1XsPc/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://haz-tech.blogspot.com/2010/06/two-steps-forward-one-step-back.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0cGRXw9eyp7ImA9WxFXGEk.&quot;"><id>tag:blogger.com,1999:blog-22566012.post-2806354351852366778</id><published>2010-05-25T22:30:00.000-04:00</published><updated>2010-05-25T22:30:24.263-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-25T22:30:24.263-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sympy" /><title>Assumptions: Out with the old, in with the new...</title><content type="html">Today marks the first day of coding for SoC '10, and to mark the date I thought it proper to post a summary of the &lt;a href="http://googlesummerofcode.blogspot.com/2007/04/so-what-is-this-community-bonding-all.html"&gt;community bonding period&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
In general I've continued to hop my way through (multiple versions of) the SymPy code base. To document the progress, aim, and general process, I've started to piece things together on the wiki [&amp;nbsp;&lt;a href="http://wiki.sympy.org/wiki/Supercharging_sympy"&gt;here&lt;/a&gt;&amp;nbsp;]. Sparse? Mostly...but by the end there should be a decent documentation on the inner workings of the assumption system on &lt;a href="http://wiki.sympy.org/wiki/SCSP_AS_Summary"&gt;this page&lt;/a&gt; -- something that doesn't exist and could help substantially in the future.&lt;br /&gt;
&lt;br /&gt;
That brings me back to understanding the assumptions. Historically the assumptions were done by initializing a number of primitive facts when a symbol was created (and possibly modified?). The new assumption system (a killer SoC project from 2009) changed the scene so that dynamic assumptions could be queried. This was done via 'ask' and 'refine' methods, but alas this process has proven to be a bit cumbersome (a problem my project aims to tackle).&lt;br /&gt;
&lt;br /&gt;
However, before I can proceed to injecting some juice into the new assumption system, the old one needs to be phased out...gracefully. Now there has been &lt;a href="http://github.com/rlamy/sympy/commits/use-new-assump2"&gt;no&lt;/a&gt; &lt;a href="http://github.com/rlamy/sympy/commits/new-assump"&gt;shortage&lt;/a&gt; &lt;a href="http://github.com/certik/sympy/commits/assum"&gt;of&lt;/a&gt; &lt;a href="http://github.com/vks/sympy/tree/new_assump"&gt;reasonable&lt;/a&gt; &lt;a href="http://github.com/vks/sympy/tree/local_assump"&gt;attempts&lt;/a&gt;&amp;nbsp;to remove the old assumptions, and wading through them has been the main focus for me this month. It's still not crystal clear, but I'm getting close:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;The old assumption system should be stripped out -- essentially the Basic class in SymPy should no longer inherit from AssumeMeths and the AssumeMeths should probably be removed altogether.&lt;/li&gt;
&lt;li&gt;The same queries and usage should still work. This means explicitly handling things like is_integer and such on an on-demand basis and make sure that it isn't called by just creating an object.&lt;/li&gt;
&lt;li&gt;Queries to 'ask' and 'refine' methods should use a static version of the old system that will (understandably) only work for a subset of the queries.&lt;/li&gt;
&lt;li&gt;The 'ask' and 'refine' methods should have an argument 'use_new_system' (set as False by default) that can be enabled when we start to speed up the new assumption system.&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;Concurrently, there is a &lt;a href="http://github.com/rlamy/sympy/commits/implement-Predicate"&gt;branch&lt;/a&gt; under &lt;a href="http://code.google.com/p/sympy/issues/detail?id=1903"&gt;review&lt;/a&gt; that introduces the notion of a Predicate -- a notion I'm very excited to see enter the SymPy mix since it brings things into language I'm more familiar with. My current direction is to wait for the Predicate system to enter the mix, and then start the old assumption strip by merging two of the techniques previously attempted. This direction, however, may change on a daily basis as I gain a better understanding of what's what.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;hr /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;i&gt;As part of these weekly updates I hope to not only sum things up, but also raise some questions I'm currently facing. Maybe it will allow commenters to help clear things up, but at the very least it will help me figure out what questions I need to answer next.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;???&lt;/div&gt;&lt;ol&gt;&lt;li&gt;With all of the branch hopping I'm doing, it's unclear to me how best I should bring commits together. I've dabbled in some mercurial project stuff (and lots of svn), but git repos with a large number of contributers is new to me. I have already figured out how to pull in and switch from branch to branch, but what I'm lacking is how to pinpoint certain specific commits (or range of commits) on one branch, and pull them into my own.&lt;/li&gt;
&lt;li&gt;I'm trying to figure out a reasonable test suite to quickly get a gauge on the efficiency of the assumption system. This would help me measure the effectiveness (or the harm) that different changes have on the assumption system, but the question I'm faced with is where this test suite best fits. It doesn't really test functionality, but will simply serve to measure speed -- as such the default unit tests don't seem appropriate. If it belongs anywhere other than my local computer, where?&lt;br /&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;&lt;hr /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
That's all for now. See you next week.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22566012-2806354351852366778?l=haz-tech.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/QmpX/~4/tbVJ83KuG3k" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://haz-tech.blogspot.com/feeds/2806354351852366778/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=22566012&amp;postID=2806354351852366778" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/2806354351852366778?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/2806354351852366778?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/QmpX/~3/tbVJ83KuG3k/assumptions-out-with-old-in-with-new.html" title="Assumptions: Out with the old, in with the new..." /><author><name>Christian Muise</name><uri>https://profiles.google.com/112066465008349537127</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-adkyhxmhzn8/AAAAAAAAAAI/AAAAAAAADd4/YitpKs1XsPc/s512-c/photo.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://haz-tech.blogspot.com/2010/05/assumptions-out-with-old-in-with-new.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE4MQH88fCp7ImA9WxFRE0Q.&quot;"><id>tag:blogger.com,1999:blog-22566012.post-506591396145781474</id><published>2010-04-27T14:29:00.000-04:00</published><updated>2010-04-27T14:29:41.174-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-27T14:29:41.174-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sympy" /><title>SoC 2010: Let the games begin</title><content type="html">&amp;nbsp; I was &lt;a href="http://socghop.appspot.com/gsoc/program/list_projects/google/gsoc2010"&gt;accepted&lt;/a&gt; for a G. SoC position this year working with the &lt;a href="http://code.google.com/p/sympy/"&gt;SymPy&lt;/a&gt; project on something near and dear to my academic heart -- &lt;a href="http://en.wikipedia.org/wiki/Boolean_satisfiability_problem"&gt;SAT solving&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Knowledge_compilation"&gt;knowledge compilation&lt;/a&gt;. Needless to say, I'm pretty stoked and can't wait to bring my knowledge to speeding up the great library.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; Feed for this summer's work (specifically) is [ &lt;a href="http://haz-tech.blogspot.com/search/label/sympy"&gt;here&lt;/a&gt; ] -- I'll be posting my progress on a weekly basis.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; Cheers&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22566012-506591396145781474?l=haz-tech.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/QmpX/~4/Js6S5jniq0w" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://haz-tech.blogspot.com/feeds/506591396145781474/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=22566012&amp;postID=506591396145781474" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/506591396145781474?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/506591396145781474?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/QmpX/~3/Js6S5jniq0w/soc-2010-let-games-begin.html" title="SoC 2010: Let the games begin" /><author><name>Christian Muise</name><uri>https://profiles.google.com/112066465008349537127</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-adkyhxmhzn8/AAAAAAAAAAI/AAAAAAAADd4/YitpKs1XsPc/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://haz-tech.blogspot.com/2010/04/soc-2010-let-games-begin.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEAMSH0-eCp7ImA9WxNbF04.&quot;"><id>tag:blogger.com,1999:blog-22566012.post-6838597206348664586</id><published>2009-11-20T10:59:00.000-05:00</published><updated>2009-11-20T10:59:49.350-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-20T10:59:49.350-05:00</app:edited><title>Academic Genealogy</title><content type="html">Just ran my advisors through &lt;a href="http://genealogy.math.ndsu.nodak.edu/"&gt;these&lt;/a&gt; &lt;a href="http://www.davidalber.net/geneagrapher/"&gt;two&lt;/a&gt; services and came up with this:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_DvrW_QLstcQ/Swa82g1R1KI/AAAAAAAACBk/nKK6vS4ddSc/s1600/graph.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="207" src="http://1.bp.blogspot.com/_DvrW_QLstcQ/Swa82g1R1KI/AAAAAAAACBk/nKK6vS4ddSc/s400/graph.png" width="400" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22566012-6838597206348664586?l=haz-tech.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/QmpX/~4/mp5qwj5HfEs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://haz-tech.blogspot.com/feeds/6838597206348664586/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=22566012&amp;postID=6838597206348664586" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/6838597206348664586?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/6838597206348664586?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/QmpX/~3/mp5qwj5HfEs/academic-genealogy.html" title="Academic Genealogy" /><author><name>Christian Muise</name><uri>https://profiles.google.com/112066465008349537127</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-adkyhxmhzn8/AAAAAAAAAAI/AAAAAAAADd4/YitpKs1XsPc/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_DvrW_QLstcQ/Swa82g1R1KI/AAAAAAAACBk/nKK6vS4ddSc/s72-c/graph.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://haz-tech.blogspot.com/2009/11/academic-genealogy.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUUHRXg5eCp7ImA9WxNXGU8.&quot;"><id>tag:blogger.com,1999:blog-22566012.post-6240722755092818817</id><published>2009-10-07T09:47:00.002-04:00</published><updated>2009-10-07T09:47:14.620-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-07T09:47:14.620-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="visualization" /><title>Twitter Trends</title><content type="html">Wow: http://trendsmap.com/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22566012-6240722755092818817?l=haz-tech.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/QmpX/~4/UMg317lR6yY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://haz-tech.blogspot.com/feeds/6240722755092818817/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=22566012&amp;postID=6240722755092818817" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/6240722755092818817?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/6240722755092818817?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/QmpX/~3/UMg317lR6yY/twitter-trends.html" title="Twitter Trends" /><author><name>Christian Muise</name><uri>https://profiles.google.com/112066465008349537127</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-adkyhxmhzn8/AAAAAAAAAAI/AAAAAAAADd4/YitpKs1XsPc/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://haz-tech.blogspot.com/2009/10/twitter-trends.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0INR3w4cCp7ImA9WxJbEUU.&quot;"><id>tag:blogger.com,1999:blog-22566012.post-7176637684064202038</id><published>2009-07-21T10:13:00.000-04:00</published><updated>2009-07-21T10:13:16.238-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-21T10:13:16.238-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="visualization" /><title>U of T Admissions</title><content type="html">On the topic of visualization, [&lt;a href="http://www3.thestar.com/static/googlemaps/starmaps_090610.html?xml=090717_uoft_stgeorge.xml"&gt;this&lt;/a&gt;] just came across my feed reader this morning. The &lt;a href="http://www.thestar.com/"&gt;Toronto Star&lt;/a&gt; has someone doing a number of &lt;a href="http://thestar.blogs.com/maps/"&gt;residential visualizations&lt;/a&gt;, and every once in a while something interesting like this pops up.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22566012-7176637684064202038?l=haz-tech.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/QmpX/~4/LcCoGTrGbzI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://haz-tech.blogspot.com/feeds/7176637684064202038/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=22566012&amp;postID=7176637684064202038" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/7176637684064202038?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/7176637684064202038?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/QmpX/~3/LcCoGTrGbzI/u-of-t-admissions.html" title="U of T Admissions" /><author><name>Christian Muise</name><uri>https://profiles.google.com/112066465008349537127</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-adkyhxmhzn8/AAAAAAAAAAI/AAAAAAAADd4/YitpKs1XsPc/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://haz-tech.blogspot.com/2009/07/u-of-t-admissions.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak8BSH4zfSp7ImA9WxVbEE4.&quot;"><id>tag:blogger.com,1999:blog-22566012.post-237491331691553547</id><published>2009-03-25T23:38:00.003-04:00</published><updated>2009-03-25T23:40:59.085-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-25T23:40:59.085-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="visualization" /><title>Reddit Visualization</title><content type="html">Just thought that anyone interested in visualization should give this [&lt;a href="http://erqqvg.com/"&gt;site&lt;/a&gt;] a gander. There are a number of different ideas implemented on the site, and all of them are really well done. Enjoy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22566012-237491331691553547?l=haz-tech.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/QmpX/~4/7LC08EYx7Ng" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://haz-tech.blogspot.com/feeds/237491331691553547/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=22566012&amp;postID=237491331691553547" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/237491331691553547?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/237491331691553547?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/QmpX/~3/7LC08EYx7Ng/reddit-visualization.html" title="Reddit Visualization" /><author><name>Christian Muise</name><uri>https://profiles.google.com/112066465008349537127</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-adkyhxmhzn8/AAAAAAAAAAI/AAAAAAAADd4/YitpKs1XsPc/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://haz-tech.blogspot.com/2009/03/reddit-visualization.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEAGQHw8fSp7ImA9WxVVEk8.&quot;"><id>tag:blogger.com,1999:blog-22566012.post-4775289873152590833</id><published>2009-03-04T23:18:00.000-05:00</published><updated>2009-03-04T23:18:41.275-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-04T23:18:41.275-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="complexity" /><title>Scooping the Loop Snooper</title><content type="html">Found this nice little poetic proof on the internets a few days ago. This last semester I had the privilege of taking &lt;a href="http://www.cs.toronto.edu/%7Esacook/csc438h/"&gt;Computability and Logic&lt;/a&gt; with &lt;a href="http://en.wikipedia.org/wiki/Stephen_Cook"&gt;Stephen Cook&lt;/a&gt; and this just about sums up the punchline of the course:&lt;br /&gt;
&lt;br /&gt;
(via &lt;a href="http://www.lel.ed.ac.uk/%7Egpullum/loopsnoop.html"&gt;this site&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;h1&gt;SCOOPING THE LOOP SNOOPER&lt;/h1&gt;&lt;h2&gt;A proof that the Halting Problem is undecidable&lt;/h2&gt;&lt;b&gt;Geoffrey K. Pullum&lt;/b&gt;&lt;br /&gt;
(&lt;i&gt;School of Philosophy, Psychology and Language Sciences,    University of Edinburgh&lt;/i&gt;)  &amp;nbsp; &lt;/blockquote&gt;&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;i&gt;No general procedure for bug checks succeeds.&lt;/i&gt;&lt;br /&gt;
Now, I won't just assert that, I'll show where it leads: &lt;br /&gt;
I will prove that although you might work till you drop, &lt;br /&gt;
you cannot tell if computation will stop.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;blockquote&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;For imagine we have a procedure called &lt;i&gt;P&lt;/i&gt; &lt;br /&gt;
that for specified input permits you to see&lt;br /&gt;
whether specified source code, with all of its faults,&lt;br /&gt;
defines a routine that eventually halts.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;blockquote&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;You feed in your program, with suitable data, &lt;br /&gt;
and &lt;i&gt;P&lt;/i&gt; gets to work, and a little while later &lt;br /&gt;
(in finite compute time) correctly infers&lt;br /&gt;
whether infinite looping behavior occurs. &lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;blockquote&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;If there will be no looping, then &lt;i&gt;P&lt;/i&gt; prints out `Good.'&lt;br /&gt;
That means work on this input will halt, as it should.&lt;br /&gt;
But if it detects an unstoppable loop,&lt;br /&gt;
then &lt;i&gt;P&lt;/i&gt; reports `Bad!' --- which means you're in the soup.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;blockquote&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Well, the truth is that &lt;i&gt;P&lt;/i&gt; cannot possibly be, &lt;br /&gt;
because if you wrote it and gave it to me, &lt;br /&gt;
I could use it to set up a logical bind &lt;br /&gt;
that would shatter your reason and scramble your mind. &lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;blockquote&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Here's the trick that I'll use -- and it's simple to do. &lt;br /&gt;
I'll define a procedure, which I will call &lt;i&gt;Q&lt;/i&gt;,&lt;br /&gt;
that will use &lt;i&gt;P&lt;/i&gt;'s predictions of halting success  &lt;br /&gt;
to stir up a terrible logical mess. &lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;blockquote&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;For a specified program, say &lt;i&gt;A&lt;/i&gt;, one supplies,&lt;br /&gt;
the first step of this program called &lt;i&gt;Q&lt;/i&gt; I devise&lt;br /&gt;
is to find out from &lt;i&gt;P&lt;/i&gt; what's the right thing to say&lt;br /&gt;
of the looping behavior of &lt;i&gt;A&lt;/i&gt; run on &lt;i&gt;A&lt;/i&gt;. &lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;blockquote&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;If &lt;i&gt;P&lt;/i&gt;'s answer is `Bad!', &lt;i&gt;Q&lt;/i&gt; will suddenly stop. &lt;br /&gt;
But otherwise, &lt;i&gt;Q&lt;/i&gt; will go back to the top, &lt;br /&gt;
and start off again, looping endlessly back, &lt;br /&gt;
till the universe dies and turns frozen and black. &lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;blockquote&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;And this program called &lt;i&gt;Q&lt;/i&gt; wouldn't stay on the shelf; &lt;br /&gt;
I would ask it to forecast its run on &lt;i&gt;itself&lt;/i&gt;.&lt;br /&gt;
When it reads its own source code, just what will it do? &lt;br /&gt;
What's the looping behavior of &lt;i&gt;Q&lt;/i&gt; run on &lt;i&gt;Q&lt;/i&gt;? &lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;blockquote&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;If &lt;i&gt;P&lt;/i&gt; warns of infinite loops, &lt;i&gt;Q&lt;/i&gt; will quit; &lt;br /&gt;
yet &lt;i&gt;P&lt;/i&gt; is supposed to speak truly of it! &lt;br /&gt;
And if &lt;i&gt;Q&lt;/i&gt;'s going to quit, then &lt;i&gt;P&lt;/i&gt; should say `Good'&lt;br /&gt;
--- which makes &lt;i&gt;Q&lt;/i&gt; start to loop!  (&lt;i&gt;P&lt;/i&gt; denied that it would.) &lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;blockquote&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;No matter how &lt;i&gt;P&lt;/i&gt; might perform, &lt;i&gt;Q&lt;/i&gt; will scoop it: &lt;br /&gt;
&lt;i&gt;Q&lt;/i&gt; uses &lt;i&gt;P&lt;/i&gt;'s output to make &lt;i&gt;P&lt;/i&gt; look stupid.&lt;br /&gt;
Whatever &lt;i&gt;P&lt;/i&gt; says, it cannot predict &lt;i&gt;Q&lt;/i&gt;: &lt;br /&gt;
&lt;i&gt;P&lt;/i&gt; is right when it's wrong, and is false when it's true! &lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;blockquote&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;I've created a paradox, neat as can be ---&lt;br /&gt;
and simply by using your putative &lt;i&gt;P&lt;/i&gt;. &lt;br /&gt;
When you posited &lt;i&gt;P&lt;/i&gt; you stepped into a snare; &lt;br /&gt;
Your assumption has led you right into my lair. &lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;blockquote&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;So where can this argument possibly go? &lt;br /&gt;
I don't have to tell you; I'm sure you must know. &lt;br /&gt;
By &lt;i&gt;reductio&lt;/i&gt;, there cannot possibly be &lt;br /&gt;
a procedure that acts like the mythical &lt;i&gt;P&lt;/i&gt;. &lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;blockquote&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;You can never find general mechanical means&lt;br /&gt;
for predicting the acts of computing machines. &lt;br /&gt;
It's something that cannot be done.  So we users &lt;br /&gt;
must find our own bugs.  Our computers are losers! &lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22566012-4775289873152590833?l=haz-tech.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/QmpX/~4/XllxDhEk2wg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://haz-tech.blogspot.com/feeds/4775289873152590833/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=22566012&amp;postID=4775289873152590833" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/4775289873152590833?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/4775289873152590833?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/QmpX/~3/XllxDhEk2wg/scooping-loop-snooper.html" title="Scooping the Loop Snooper" /><author><name>Christian Muise</name><uri>https://profiles.google.com/112066465008349537127</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-adkyhxmhzn8/AAAAAAAAAAI/AAAAAAAADd4/YitpKs1XsPc/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://haz-tech.blogspot.com/2009/03/scooping-loop-snooper.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEEHRH44fSp7ImA9WxVWE04.&quot;"><id>tag:blogger.com,1999:blog-22566012.post-4923858061163390732</id><published>2009-02-22T15:59:00.002-05:00</published><updated>2009-02-22T16:03:55.035-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-22T16:03:55.035-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="visualization" /><category scheme="http://www.blogger.com/atom/ns#" term="graphtheory" /><title>Graph of NP-Complete Problems</title><content type="html">&lt;div&gt;Earlier today I found a neat visualization of the most common NP-Complete problems [&lt;a href="http://page.mi.fu-berlin.de/aneumann/npc.html"&gt;here&lt;/a&gt;]. I don't quite enjoy the layout used for the graph, but the fact that the nodes / edges link to publications is a nice touch.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22566012-4923858061163390732?l=haz-tech.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/QmpX/~4/KnAQ-FCd1yE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://haz-tech.blogspot.com/feeds/4923858061163390732/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=22566012&amp;postID=4923858061163390732" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/4923858061163390732?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/4923858061163390732?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/QmpX/~3/KnAQ-FCd1yE/graph-of-np-complete-problems.html" title="Graph of NP-Complete Problems" /><author><name>Christian Muise</name><uri>https://profiles.google.com/112066465008349537127</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-adkyhxmhzn8/AAAAAAAAAAI/AAAAAAAADd4/YitpKs1XsPc/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://haz-tech.blogspot.com/2009/02/graph-of-np-complete-problems.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkYGQH88eyp7ImA9WxVWEko.&quot;"><id>tag:blogger.com,1999:blog-22566012.post-8113694044217538827</id><published>2009-02-10T13:36:00.025-05:00</published><updated>2009-02-21T23:48:41.173-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-21T23:48:41.173-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="visualization" /><title>Master's Thesis</title><content type="html">&amp;nbsp; The master's thesis is officially done. Final drafts have been reviewed, and all edits are made. I'm not going to make the whole thing public, but a fair bit of it may find its way into papers for future &lt;a href="http://www.cs.swan.ac.uk/%7Ecsoliver/SAT2009/"&gt;SAT&lt;/a&gt; conferences (with any luck).&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; I will, however, write a series of posts (to be cross-posted on a few blogs) that describes what I did: from the logic background needed to understand it, all the way to my final results. Before I get going on that, here's my &lt;a href="http://www.wordle.net/gallery/wrdl/527573/Master%27s_Thesis"&gt;master's paper&lt;/a&gt; as a wordle:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_DvrW_QLstcQ/SZHLaTdHPpI/AAAAAAAABs4/etYuDOPYLh8/s1600-h/Thesis.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="202" src="http://4.bp.blogspot.com/_DvrW_QLstcQ/SZHLaTdHPpI/AAAAAAAABs4/etYuDOPYLh8/s400/Thesis.png" width="375" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&amp;nbsp; Yes, this is the new meme. I want to see &lt;a href="http://lilaprime.blogspot.com/"&gt;all&lt;/a&gt; &lt;a href="http://www-thphys.physics.ox.ac.uk/people/JuliaYeomans/irwin.html"&gt;of&lt;/a&gt; &lt;a href="http://compscigail.blogspot.com/"&gt;your&lt;/a&gt; thesis' as a &lt;a href="http://www.wordle.net/"&gt;wordle&lt;/a&gt;. Same goes for anyone else who reads this with a thesis to share.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&amp;nbsp; Cheers&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22566012-8113694044217538827?l=haz-tech.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/QmpX/~4/0FlJ6w_0QMc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://haz-tech.blogspot.com/feeds/8113694044217538827/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=22566012&amp;postID=8113694044217538827" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/8113694044217538827?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/8113694044217538827?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/QmpX/~3/0FlJ6w_0QMc/masters-thesis.html" title="Master's Thesis" /><author><name>Christian Muise</name><uri>https://profiles.google.com/112066465008349537127</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-adkyhxmhzn8/AAAAAAAAAAI/AAAAAAAADd4/YitpKs1XsPc/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_DvrW_QLstcQ/SZHLaTdHPpI/AAAAAAAABs4/etYuDOPYLh8/s72-c/Thesis.png" height="72" width="72" /><thr:total>4</thr:total><feedburner:origLink>http://haz-tech.blogspot.com/2009/02/masters-thesis.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0MMSHw8eCp7ImA9WxVQGUk.&quot;"><id>tag:blogger.com,1999:blog-22566012.post-8693415635329181941</id><published>2009-02-06T14:40:00.003-05:00</published><updated>2009-02-06T14:44:49.270-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-06T14:44:49.270-05:00</app:edited><title>The Springer GTM Test</title><content type="html">An update on my (oh-so-close-to-being-finished) master's thesis will be coming within a week or so. In the mean time, what Springer book are you?&lt;br /&gt;
&lt;br /&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;img alt="" height="182" src="http://www.math.arizona.edu/%7Esavitt/GTM/eisenbud.jpg" width="120" /&gt;&lt;/td&gt;&lt;td&gt;If I were a Springer-Verlag Graduate Text in Mathematics, I would be David Eisenbud's &lt;b&gt;&lt;i&gt;Commutative Algebra with a view towards Algebraic Geometry&lt;/i&gt;&lt;/b&gt;.&lt;br /&gt;
I am an attempt to write on commutative algebra in a way that includes the geometric ideas that played a great role in its formation; with a view, in short, towards Algebraic Geometry. I cover the material that graduate students studying Algebraic Geometry - and in particular those  studying the book Algebraic Geometry by Robin Hartshorne - should know.  The reader should have had one year of basic graduate algebra. &lt;br /&gt;
Which Springer GTM would &lt;i&gt;you&lt;/i&gt; be? &lt;a href="http://www.math.arizona.edu/%7Esavitt/GTM.html"&gt;The Springer GTM Test&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22566012-8693415635329181941?l=haz-tech.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/QmpX/~4/Wq2vin4AKXA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://haz-tech.blogspot.com/feeds/8693415635329181941/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=22566012&amp;postID=8693415635329181941" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/8693415635329181941?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/8693415635329181941?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/QmpX/~3/Wq2vin4AKXA/springer-gtm-test.html" title="The Springer GTM Test" /><author><name>Christian Muise</name><uri>https://profiles.google.com/112066465008349537127</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-adkyhxmhzn8/AAAAAAAAAAI/AAAAAAAADd4/YitpKs1XsPc/s512-c/photo.jpg" /></author><thr:total>4</thr:total><feedburner:origLink>http://haz-tech.blogspot.com/2009/02/springer-gtm-test.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkYGQH88fCp7ImA9WxVWEko.&quot;"><id>tag:blogger.com,1999:blog-22566012.post-4922813364944844559</id><published>2008-11-22T18:59:00.000-05:00</published><updated>2009-02-21T23:48:41.174-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-21T23:48:41.174-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="visualization" /><title>Periodic Table of Visualization</title><content type="html">Quite a few of posts I write here have to do with my arbitrary quests to visualize things in my research. I still maintain that I don't want to focus on the task of visualization, but using it properly (and in innovative ways) is something I definitely will continue to strive for. Hopefully a publication or two will come out of it as well during my studies, but that'd just be a pretty perk.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;With that train of though in mind, I've been casually browsing through visualization projects for inspiration and a few weeks ago this came across my feed reader: &lt;a href="http://www.visual-literacy.org/periodic_table/periodic_table.html"&gt;A Periodic Table of Visualization Methods&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;The site is actually a nice example of Metaphor Visualization, and its interactive nature makes browsing the different types quite accessible.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Where's my visualization? Ya, ya its coming. Unfortunately there are some serious bugs with &lt;a href="http://ubietylab.net/ubigraph/"&gt;Ubigraph&lt;/a&gt; on 64-bit linux and whenever I try visualizing my search space with more than a few hundred nodes the thing freezes. I have an official bug ticket opened for the issue but I haven't heard anything from the devs in months. In the meantime I've been trying to think of how &lt;a href="http://vis.cs.ucdavis.edu/~ogawa/codeswarm/"&gt;CodeSwarm&lt;/a&gt;&amp;nbsp;can be used for visualizing 3-SAT solving properties. That'd be a fun one to see ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22566012-4922813364944844559?l=haz-tech.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/QmpX/~4/tYW1-3T2pe8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://haz-tech.blogspot.com/feeds/4922813364944844559/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=22566012&amp;postID=4922813364944844559" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/4922813364944844559?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/4922813364944844559?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/QmpX/~3/tYW1-3T2pe8/periodic-table-of-visualization.html" title="Periodic Table of Visualization" /><author><name>Christian Muise</name><uri>https://profiles.google.com/112066465008349537127</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-adkyhxmhzn8/AAAAAAAAAAI/AAAAAAAADd4/YitpKs1XsPc/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://haz-tech.blogspot.com/2008/11/periodic-table-of-visualization.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkQAQ3Y4eip7ImA9WxRWF0s.&quot;"><id>tag:blogger.com,1999:blog-22566012.post-1411833795651938038</id><published>2008-11-03T14:11:00.002-05:00</published><updated>2008-11-03T19:59:02.832-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-11-03T19:59:02.832-05:00</app:edited><title>Palinode Thesis</title><content type="html">A friend of mine brought up a &lt;a href="http://lilaprime.blogspot.com/2008/10/mathematics-is-fixed-again.html"&gt;very interesting point&lt;/a&gt; on her blog: What if we had to write our thesis as a palinode?&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;palinode&lt;/i&gt;: &lt;span style="font-size: small;"&gt;A palinode or palinody is an ode in which the writer retracts a view or sentiment expressed in an earlier poem.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: small;"&gt;  Now retracting any views within the same thesis is bound for failure, but it is an intriguing thought to try and figure out what your thesis would look like in poem form. The current state of mine as a haiku:&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;a href="http://en.wikipedia.org/wiki/3SAT#3-satisfiability"&gt;SAT&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/NP-complete#NP-complete_problems"&gt;problems&lt;/a&gt; are &lt;a href="http://en.wikipedia.org/wiki/NP-complete"&gt;hard&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;a href="http://scholar.google.ca/scholar?hl=en&amp;amp;lr=&amp;amp;cluster=3719538122340842533"&gt;Dualization&lt;/a&gt;'s an &lt;a href="http://scholar.google.ca/scholar?q=dualization&amp;amp;hl=en&amp;amp;lr=&amp;amp;btnG=Search"&gt;option&lt;/a&gt; -&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;I just can't prove it.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;  ...and back to the thesis...&lt;br /&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22566012-1411833795651938038?l=haz-tech.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/QmpX/~4/WYSXKcv1Xok" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://haz-tech.blogspot.com/feeds/1411833795651938038/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=22566012&amp;postID=1411833795651938038" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/1411833795651938038?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/1411833795651938038?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/QmpX/~3/WYSXKcv1Xok/palinode-thesis.html" title="Palinode Thesis" /><author><name>Christian Muise</name><uri>https://profiles.google.com/112066465008349537127</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-adkyhxmhzn8/AAAAAAAAAAI/AAAAAAAADd4/YitpKs1XsPc/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://haz-tech.blogspot.com/2008/11/palinode-thesis.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0QFSX88cCp7ImA9WxRTGEQ.&quot;"><id>tag:blogger.com,1999:blog-22566012.post-6723024459228401758</id><published>2008-09-08T14:41:00.001-04:00</published><updated>2008-09-08T14:41:58.178-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-09-08T14:41:58.178-04:00</app:edited><title>Learning From a Legend</title><content type="html">&amp;nbsp;&amp;nbsp;    For my 5th and final course for my masters degree, I'm taking &lt;a href="http://www.cs.toronto.edu/%7Esacook/csc438h/"&gt;Computability and Logic&lt;/a&gt; with &lt;a href="http://www.cs.toronto.edu/%7Esacook/"&gt;Stephen Cook&lt;/a&gt;. You might remember him from such theorem's as &lt;a href="http://en.wikipedia.org/wiki/Cook%27s_theorem"&gt;Cook's Theorem&lt;/a&gt;. :p&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Essentially every person with a Computer Science degree has come across this nugget in one form or another (pioneering the great question of P = NP), and if you haven't then you don't have a real Computer Science degree.&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Best part of the opening lecture - seeing the expression on Cook's face when asking the class what complexity class the problem of satisfiability is in. ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22566012-6723024459228401758?l=haz-tech.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/QmpX/~4/aVWbZOQgohY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://haz-tech.blogspot.com/feeds/6723024459228401758/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=22566012&amp;postID=6723024459228401758" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/6723024459228401758?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/22566012/posts/default/6723024459228401758?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/QmpX/~3/aVWbZOQgohY/learning-from-legend.html" title="Learning From a Legend" /><author><name>Christian Muise</name><uri>https://profiles.google.com/112066465008349537127</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-adkyhxmhzn8/AAAAAAAAAAI/AAAAAAAADd4/YitpKs1XsPc/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://haz-tech.blogspot.com/2008/09/learning-from-legend.html</feedburner:origLink></entry></feed>

