<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5780206530047749771</id><updated>2011-07-30T10:56:00.535-07:00</updated><category term='visual studio'/><category term='irksome software'/><category term='linux'/><category term='math'/><category term='algebra'/><category term='tech help'/><category term='research'/><category term='real analysis'/><category term='theorem proving'/><category term='ACL2'/><category term='smt solving'/><category term='macros'/><category term='prose'/><category term='microsoft'/><category term='graduate school'/><category term='strange consequences'/><category term='code'/><category term='complexity'/><category term='meta-reasoning'/><category term='computers'/><category term='scripts'/><title type='text'>Life, the Universe and Math</title><subtitle type='html'>Computer science Ph.D. student discusses interesting finds in math, algorithms and formal methods. Also down-to-earth hacking experiences for the problem-solvers.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://lifeandmath.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5780206530047749771/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://lifeandmath.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>J. Ian Johnson</name><uri>http://www.blogger.com/profile/02510605633293210260</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>12</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5780206530047749771.post-5606260719968474794</id><published>2010-07-15T14:20:00.000-07:00</published><updated>2010-07-15T14:20:19.609-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='meta-reasoning'/><category scheme='http://www.blogger.com/atom/ns#' term='theorem proving'/><category scheme='http://www.blogger.com/atom/ns#' term='macros'/><title type='text'>Going Meta on the Macro</title><content type='html'>Today I want to talk a little bit about what I've been researching over the summer. For a little context, I've finished the first year of the CS Ph.D. program at my university, and I have mainly focused on formal methods/automated reasoning. My passion is for proving properties about software - specifically, I want to make that process easier, more natural and commonplace. Since I did not learn how to prove theorems with transfinite induction (the most common tool for proofs about software) until grad school, even after getting B.S. degrees in pure mathematics and computer science at a very good university, I don't think the "commonplace" goal is coming soon. Perhaps I will discuss this area and the difficulties it faces in a future post.&lt;br /&gt;At this university, the largest research group - and the most famous - is for programming languages (PL). Academia's approach to PL over the past few decades has focused mainly on functional programming languages, as far as I can tell. That was shocking to me, since just about everything I've seen in industry has been imperative stuff. After dealing with proofs, I now understand a reason why PL fancies functional languages - they use recursion and immutable values much more often than while loops and repeated variable assignments. This approach allows you to disregard the global state of your program and focus specifically on one function at a time. Why? If your function depends on a variable that x other functions can change, then you must keep track of how that variable is changed. Most likely your proof of correctness hinges on that variable holding a specific property, such as prime number or normalized vector. Every place that variable changes, you must make sure that property holds; if it doesn't, you have to make sure it does before your function is called. That's a lot to keep track of. It's not all that easy to maintain, especially if you work in a team setting.&lt;br /&gt;So what's cool about functional programming languages other than that fact? Well, I haven't begun to talk about macros. There are ways of abstracting behavior of your program beyond what a function can do. Say you need the same large initialization sequence executed before some block of code in many different places. You can make a new command that will wrap your code with all that boilerplate at compile time with a macro. That's a simple example. There are other examples in which a macro will do long and complicated analyses on input code, and then output optimized or annotated code that should be equivalent in functionality.&lt;br /&gt;Ooh, "equivalent" sounds like a theorem proving word. Can we prove that these analyses find the invariants we need for correctness of the transform? How about after that - actually proving that the macro form expands to an equivalent expression &lt;i&gt;in all contexts&lt;/i&gt;? The answer is (you're going to love this) it depends. It depends on what you consider proof. Certainly you can write functions that describe the semantics of the language you're working in (say, with an embedded operational semantics - oh but for a termination argument you have to specifically limit how many evaluation steps are allowed. Yikes.) So wait, you have to embed the language you're working in... in the language you're working in? Why would you want to do that? Gross.&lt;br /&gt;So what if we want our logic to allow talking about macros inside the logic? Say we don't need that embedding, and then we can actually write rewrite rules to simplify macro forms without having to expand them. This is some heavy stuff. Now we are talking about quantification over syntax rather than simply values.&lt;br /&gt;&lt;br /&gt;Some vocabulary - when a macro expands, it is a function from representation of syntax to representation of syntax, but when it's complete, that representation is &lt;i&gt;reified&lt;/i&gt; to become actual syntax that will be evaluable. &lt;br /&gt;&lt;br /&gt;A problem enjoyed (rather, suffered) by many macro systems is the loss of scoping laws. It is not possible that in all contexts your macro will have the same meaning. This is due to free and bound variable capture. A simple textual replacement macro system such as in LISP and C is bound to change the meaning of your program when you decide to use a variable name that the macro redefines. In LISP at least you can check that variables you introduce are not in the &lt;i&gt;support&lt;/i&gt; (set of free or bound variables) of the input expressions, and fail to expand if they are. This is ugly. Not only does it reveal internals of a macro (something that module abstraction should give), but it pits the programmer against the macro - "why can't I use the variable names &lt;i&gt;I&lt;/i&gt; want?" There is a solution, however it is not the most palatable either (just the best we've got), called hygienic macro expansion. A hygienic macro expander will rename variables as it goes to make sure variables are available &lt;i&gt;only in the scope of where they are intended to be used&lt;/i&gt;. I can think of more ambiguous statements, but that one surely is a nuisance to anyone doing formal reasoning.&lt;br /&gt;&lt;br /&gt;Hygienic macros have only recently gotten a formal treatment (see Dave Herman's thesis - &lt;a href="http://www.ccs.neu.edu/home/dherman/research/papers/dissertation.pdf"&gt;A Theory of Typed Hygienic Macros&lt;/a&gt;), and since it is in the setting of a decidable type theory, the whole story is not delivered. However it does give us hope for a complete meaning. If one is able to completely describe how a macro's input will be used for introducing and consuming bindings in its expansion, then we can show that if two inputs have the same binding structure implies that the macro's expansion on both inputs has the same binding structure (more precisely, both expansions are alpha-equivalent), then the macro expander is hygienic. Nice. That takes care of the all contexts problem. Now how do we express this without long-winded arguments? My idea is to have simple base that requires long-windedness to begin with, but (haha!) we use macros to conceal this detail.&lt;br /&gt;&lt;br /&gt;Notice that the hygiene property cannot be defined inside the logic, since any function describing binding structure would be manipulating only a representation of syntax, and not actual syntax for which the logic has reasoning capabilities. Wait wait wait... we are now introducing to the logic a means to have meta-reasoning at the non-meta level. That shouldn't work, right? Gödel did some work on this I think. Well, there are theorem provers out there that allow for meta-reasoning, so let's look at how they do it.&lt;br /&gt;&lt;br /&gt;The key idea is that you don't collapse the meta-theory into your theory, but you separate the two and start at the meta level to begin with. This is what is meant by working in a &lt;i&gt;logical framework&lt;/i&gt; rather than a specific logic. Thus we do have an "embedding" of the language we're working in, but it's already given as it is defined in the logical framework. A bit of a hack, but logically necessary. Then what encoding does one choose for syntax? If you have any familiarity with the lambda calculus, you should know how beta-reduction is rather involved (in call-by-value semantics) since it must do bound variable renaming. In hygienic macro systems, lexical information about a term must be stored somewhere, and for a practical language, so too must source code correlation information.&lt;br /&gt;&lt;br /&gt;Yikes again. Source code correlation information is purely for debugging purposes and thus logically uninteresting. We can abstract over this by instead defining an abstract datatype that satisfies the properties we want of syntax, and then let an arbitrarily complicated implementation prove that it satisfies this specification. One way researchers have been able to describe binding in syntax is by actually using a higher order representation. That is, instead of symbolically representing bindings everywhere like LISP does, actually use a real lambda abstraction. This is called Higher-Order Abstract Syntax (HOAS) and it has been getting lots of attention for that past, oh, 15 years. Why then aren't we sipping on piña coladas while our informal meta-reasoning style proofs whiz through formal systems?&lt;br /&gt;&lt;br /&gt;Remember my description of theorem proving in the beginning, and how induction is vital? Well it turns out that in general, inductive proofs over HOAS is... impossible. The reason for this is because its general representation is not inductively definable - variable references can be arbitrarily far down a syntax tree from the binding point; a crippling technicality called "negative occurrence" in type theory. Though IANAH (I am not a historian), the first attempt I know of to restrict syntax for meta-reasoning was in Edinburgh LF (logical framework), actually implemented at CMU as "Twelf", based on (competes with?) a logic called &lt;img border="0" src="http://www.codecogs.com/gif.latex?FO%5Clambda%5E%7B%5CDelta%5Cmathbb%7BN%7D%7D" /&gt; (fold-n) developed by some guys at École Polytechnique. There is additional work in Isabelle/HOL that builds off Twelf's idea, but this building is a big stack of confused mess if you ask me. At the bottom of the stack is Isabelle's logical framework, then classical higher order logic axioms, then some concrete representation of syntax, then the "specification logic," and then the "object logic." These layers are &lt;i&gt;abstractly&lt;/i&gt; what needs to exist, but everything is logically defined, so execution isn't given (can't just build on top of Common LISP like ACL2 does). There is quite a bit of research into extracting programs from specifications, but what if I want programs AS specifications? As far as I know, there is no real programming language basis for these systems that would mean executable specifications and reasoning about actual runnable programs, and &lt;b&gt;not&lt;/b&gt; their (trusted) translation into some other logic.&lt;br /&gt;&lt;br /&gt;Perhaps it's my history with ACL2 - it is a programming language, a logic and a theorem prover - but is it too much to ask for? This is not a solved problem. I'd like to chip out a big piece of this mystery though. Meta-reasoning about (hygienic) macros must be a possibility. Since meta-reasoning itself has not yet been well-executed, there &lt;a href="http://alliance.seas.upenn.edu/%7Eplclub/cgi-bin/poplmark/index.php?title=The_POPLmark_Challenge"&gt;certainly is a lot to do&lt;/a&gt; [collection of meta-reasoning problems for mechanized systems to tackle]. There is a chance though, that by attacking the problem from a macro setting might just simplify (and generalize) the problem space.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5780206530047749771-5606260719968474794?l=lifeandmath.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeandmath.blogspot.com/feeds/5606260719968474794/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5780206530047749771&amp;postID=5606260719968474794' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5780206530047749771/posts/default/5606260719968474794'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5780206530047749771/posts/default/5606260719968474794'/><link rel='alternate' type='text/html' href='http://lifeandmath.blogspot.com/2010/07/going-meta-on-macro.html' title='Going Meta on the Macro'/><author><name>J. Ian Johnson</name><uri>http://www.blogger.com/profile/02510605633293210260</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5780206530047749771.post-1216607814117724053</id><published>2010-04-12T11:17:00.000-07:00</published><updated>2010-04-12T11:17:26.975-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='irksome software'/><category scheme='http://www.blogger.com/atom/ns#' term='smt solving'/><title type='text'>SMT solvers hate you</title><content type='html'>And me, of course. No one is safe from their wrath of awful error messages. Boolector-1.2 was giving me "illformed 'let' or 'flet'" at the very end of my 1200 line file. Very useful. After poking around for 30 minutes or so, I found that it did not like my identifiers with hyphens (they should be underscores). Yices did just fine on the file, by the way. Boolector also does not like (let (?varname (let (... ...) ...)) ...). Nested lets are stupid. Scope is for humans.&lt;br /&gt;&lt;br /&gt;On that note, I found that Boolector confuses nested lets with shadowed variables, so if ?x is bound twice, it incorrectly concludes that a nested let was found. Yices' behavior for shadowed variables is in my opinion far worse; it persists the first binding as if the second never happened. You will get models when you do not expect them.&lt;br /&gt;&lt;br /&gt;Granted, this format really isn't for humans, but for the SMT solvers themselves. Let researchers munch on some NP-completeness rather than inform users. That said, there is an OCaml implementation of a well-formedness check, but it is admitted to be incomplete. The (faulty) implementations of the language specification are the real specs, so some error handling on the solvers' side is very well justified.&lt;br /&gt;&lt;br /&gt;Just a note for some other researchers/engineers out there that run into Boolector giving some really nasty errors. I may edit this post after future interaction with more solvers like CVC3, MathSAT and Z3.&lt;br /&gt;&lt;br /&gt;P.S. Yices doesn't care about the hundreds of close parens that are bound to conclude your file while Boolector expects all parens to match (no extra ')'s allowed). The error is the unhelpful "Unexpected EOF" message when they do not match.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5780206530047749771-1216607814117724053?l=lifeandmath.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeandmath.blogspot.com/feeds/1216607814117724053/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5780206530047749771&amp;postID=1216607814117724053' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5780206530047749771/posts/default/1216607814117724053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5780206530047749771/posts/default/1216607814117724053'/><link rel='alternate' type='text/html' href='http://lifeandmath.blogspot.com/2010/04/smt-solvers-hate-you.html' title='SMT solvers hate you'/><author><name>J. Ian Johnson</name><uri>http://www.blogger.com/profile/02510605633293210260</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5780206530047749771.post-8491577362710215192</id><published>2010-02-18T09:54:00.000-08:00</published><updated>2010-02-18T09:54:43.571-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='research'/><category scheme='http://www.blogger.com/atom/ns#' term='graduate school'/><category scheme='http://www.blogger.com/atom/ns#' term='ACL2'/><category scheme='http://www.blogger.com/atom/ns#' term='theorem proving'/><title type='text'>After Almost a Year of Graduate School</title><content type='html'>A lot has happened in the past year. I graduated UT with degrees in computer science and pure mathematics, I moved to Boston to pursue my Ph.D. in computer science at Northeastern, and I embarked on a research journey. Allow me to give convey some lessons I have learned.&lt;br /&gt;&lt;br /&gt;As you may know, Ph.D. students seldom have to pay for tuition or worry about supporting themselves, as do (some) undergraduates and masters students. No, in exchange for your education, you are required to (at first) be a teaching assistant (you are supported by your college), and later a research assistant (you are supported by your advisor). If you are clever, you might manage to get a fellowship and just give your own work attention. Perhaps next year when I have a better idea of what is an interesting research direction I will apply for a fellowship, but for now I am a TA for a freshman logic class.&lt;br /&gt;&lt;br /&gt;This class is very different from my own experience with logic in undergrad, where I spent most of my time smearing glaze over my eyes and amassing a large drool stain on my book while a coke-bottle glasses-wearing emeritus professor drones on about the most menial pedantry of set theory, functions and recursion. This class actually uses my beloved interactive theorem prover, ACL2, to teach students how to reason about their programs, and in the mean time surreptitiously teach them rigorous fundamentals of propositional logic, induction and first-order logic.&lt;br /&gt;&lt;br /&gt;ACL2 is a tool that has been taking up a majority of my time recently, and is essentially the reason I came to Northeastern. The name stands for A Computational Logic in Applicative Common LISP, so the 2 is not a version number, but more of an ordinal coefficient/concatenation multiplier. My interest in ACL2 arose when a friend of mine told me about research he was doing with its inventor, J Moore. The idea for systems like ACL2 and the reason theorem proving intrigues me so much comes from a comment John McCarthy (inventor of LISP) made in the 60s along the lines of, "rather than debugging, programs should be proven correct, and that proof should be checked by a computer program." I had only seen reasoning about programs for a couple of lectures in my analysis of programs class (really a discrete structures class), presented in Floyd-Hoare logic, with the caveat that proving properties about programs this way does not scale, is a pain in the ass, and no one does it. Thus I had forgotten about proving properties about programs and went back to hacking and debugging as usual.&lt;br /&gt;&lt;br /&gt;A computational logic is a logic for reasoning about algorithms - you stay in the realm of computation, instead of careening off into pure mathematics. ACL2 deals only with finite structures; there is no concept of infinity, functions cannot be values, and lists have a natural number length. All functions must be proven to terminate on any possible input (i.e. ACL2 is a total logic). These restrictions keep the logic very simple, but still very expressive. There are definitely theorem proving systems out there that allow for reasoning about infinity, higher-order functions and partially-defined functions, but proofs in these systems are much less easily automated. Because of the restrictions on the logic, some fantastic engineering and brilliant proof search heuristics, ACL2 is the most automated theorem prover in existence.&lt;br /&gt;&lt;br /&gt;Have I sold you yet? If yes, you are just like most other people faced with ACL2 for the first time and shown what it can do. Bright eyes. Naive expectations. The reality of the matter is that proofs of interesting theorems still need mathematicians to come up with a proof strategy. Not only that though - in theorem provers, statements of truth that normally can be used the way you wish when proving theorems by hand now have extra semantics attached to them. You see, when you prove something to be true, you are programming the theorem prover to apply rules in a directed way. Typically if you prove A = B, then really what you are telling the prover is, "when you see A, replace it with B." This is called "substituting equals for equals," a special case of term rewriting. If you do not know the gory details of the prover's rewriting strategy, then you can end up proving extra very specific, horribly inelegant lemmas in order to ram your proof through the system.&lt;br /&gt;&lt;br /&gt;The reasons for the prover's rewriting strategies being so directed come from years of experience and a lot of empirical data from heavy users of the system. Here is the learning curve: new to ACL2, you write some simple statement that is obvious to anyone and the prover fails - "stupid piece of crap," you say. Next you start reading and toying around with carefully crafted examples that the prover gets automatically, "oh cool, I was just doing it wrong. ACL2 is awesome!" Later you try to actually use ACL2 for arbitrary code, say you are trying to prove a flood fill algorithm makes a flooded region bigger or the same size as before (intuitively obvious), "AHHH MY EYES! MY FACE! I'M ON FIRE!" and after your Ph.D. in computer science with a focus on formal methods, "oh I get it." At least that is what I am promised. Currently I have bandages on my third degree burns, staring at a burning building, considering going back to save my dog.&lt;br /&gt;&lt;br /&gt;My current research attempts to distribute large spanners to users of ACL2, so they have access to their fire hydrants - okay enough of this metaphor. ACL2 tries its very hardest to prove a conjecture true by applying different types of rules to rewrite the whole thing to T (true). The order in which rules are applied matters very much in the success of the proof, and ACL2's approach is to try everything, one by one, in the reverse order theorems were proved. In very directed proofs of one particular theorem, this generally works - consider in mathematics when you prove minor theorems, use those to prove stronger theorems, and then use those to prove your punchline theorem. Typically you do not have to appeal to the low level, minor theorems in your main proof.&lt;br /&gt;&lt;br /&gt;In software? Not so much. You tend to work in layers of abstraction, and these layers have borders that allow for communication with other layers. It is this communication that destroys the reverse-chronological ordering strategy. Without communication, the prover would skip over entire layers as irrelevant to get to rules that apply - no big deal. With communication, things get hairy, and you would like to reason at the highest level you can before you have to dive deeper to resolve some technical issue. By tricking ACL2 into reasoning in different layers of abstraction, the order in which you prove theorems becomes less relevant, so you can worry about reasoning rather than rewrite strategies, and it structures proofs to progress in a more natural order.&lt;br /&gt;&lt;br /&gt;How I trick ACL2 is the topic of a paper I am writing, and the main idea came from my mentor, Pete Manolios (actually got his Ph.D. under J Moore's supervision, so a very relevant source of ideas). His insight into this "reasoning in layers" came from reasoning about hardware - a very layered process goes into their design. In fact, my methods for tricking ACL2 made the proof of a refinement theorem about a pipelined machine go through in 100 seconds, when previously it made my computer crash, and Pete's computer 15 minutes to prove. This result was a marvellous fluke, since I managed to get such drastic results from a flawed implementation of my trickery. When I corrected the flaw, the proof shot up to 48 minutes on my computer. It took months of fiddling, engineering, and adding heuristics to get the corrected version to emulate the behavior of the flawed version in the case of the refinement proof. I now have a rather robust framework for reasoning in layers of abstraction. Now all I need to do is find some more problems to apply it to that give similar results.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5780206530047749771-8491577362710215192?l=lifeandmath.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeandmath.blogspot.com/feeds/8491577362710215192/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5780206530047749771&amp;postID=8491577362710215192' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5780206530047749771/posts/default/8491577362710215192'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5780206530047749771/posts/default/8491577362710215192'/><link rel='alternate' type='text/html' href='http://lifeandmath.blogspot.com/2010/02/after-almost-year-of-graduate-school.html' title='After Almost a Year of Graduate School'/><author><name>J. Ian Johnson</name><uri>http://www.blogger.com/profile/02510605633293210260</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5780206530047749771.post-7819236360861838134</id><published>2009-04-08T13:27:00.000-07:00</published><updated>2009-04-25T22:48:04.366-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='strange consequences'/><category scheme='http://www.blogger.com/atom/ns#' term='real analysis'/><category scheme='http://www.blogger.com/atom/ns#' term='math'/><title type='text'>Strange Consequences of Simple Definitions (I)</title><content type='html'>&lt;a href="http://sites.google.com/site/lifeandmath/Home/consequences1.pdf?attredirects=0"&gt;PDF of this post&lt;/a&gt;&lt;br /&gt;I decided that upon finding Thomae's function, of which today's topic is about, that a good subsection of this journal of mathematical musings should be about what strange things can be mathematically correct, but not at all intended from a given definition. We look into the realm of real analysis today, a topic I am rather fond of, seeing as the real numbers are really more bizarre than one might originally think. Good old rational numbers, the collection of integer over natural (coprime), can approximate any real number to any arbitrary precision, yet the two fields are vastly different in mathematical properties.&lt;br /&gt;&lt;br /&gt;That aside, which I might talk about in a later entry, I turn to the core discussion about continuous functions. How are they defined, and what's something really weird I can construct that is still considered continuous?&lt;br /&gt;&lt;br /&gt;A function &lt;img src="http://www.codecogs.com/gif.latex?f" align="middle" border="0" /&gt; from a subset &lt;img src="http://www.codecogs.com/gif.latex?E%20%5Csubseteq%20%5Cmathbb%7BR%7D" align="middle" border="0" /&gt; to &lt;img src="http://www.codecogs.com/gif.latex?%5Cmathbb%7BR%7D" align="middle" border="0" /&gt; is said to be continuous at a point &lt;img src="http://www.codecogs.com/gif.latex?p%20%5Cin%20E" align="middle" border="0" /&gt; if for every &lt;img src="http://www.codecogs.com/gif.latex?%5Cepsilon%20%3E%200" align="middle" border="0" /&gt;, there exists a &lt;img src="http://www.codecogs.com/gif.latex?%5Cdelta%20%3E%200" align="middle" border="0" /&gt; such that if &lt;img src="http://www.codecogs.com/gif.latex?x%20%5Cin%20E" align="middle" border="0" /&gt; and &lt;img src="http://www.codecogs.com/gif.latex?%7Cx%20-%20p%7C%20%3C%20%5Cdelta" align="middle" border="0" /&gt;, then &lt;img src="http://www.codecogs.com/gif.latex?%7Cf%28x%29%20-%20f%28p%29%7C%20%3C%20%5Cepsilon" align="middle" border="0" /&gt;. Let us step back and get an intuitive understanding of this definition. If we look at &lt;img src="http://www.codecogs.com/gif.latex?f%28p%29" align="middle" border="0" /&gt; and all its neighbouring points, then we can get a neighbourhood in &lt;img src="http://www.codecogs.com/gif.latex?E" align="middle" border="0" /&gt; around &lt;img src="http://www.codecogs.com/gif.latex?p" align="middle" border="0" /&gt; that all map into the neighbourhood about &lt;img src="http://www.codecogs.com/gif.latex?f%28p%29" align="middle" border="0" /&gt;. Visualising the &lt;img src="http://www.codecogs.com/gif.latex?%5Cepsilon" align="middle" border="0" /&gt; shrinking and the function still staying nicely mapped into the smaller and smaller neighbourhoods, this gives us a nice image about what it means to be continuous.  Notice that this definition is for single points. If &lt;img src="http://www.codecogs.com/gif.latex?f" align="middle" border="0" /&gt; is continuous at all points &lt;img src="http://www.codecogs.com/gif.latex?p%20%5Cin%20E" align="middle" border="0" /&gt;, then we say that the function is simply continuous. However, what if we construct a function that is continuous just about everywhere, and discontinuous everywhere else (which is also... everywhere?). Yes, I go back to my point about the rationals being able to approximate the reals to any arbitrary precision - in other words, dense in &lt;img src="http://www.codecogs.com/gif.latex?%5Cmathbb%7BR%7D" align="middle" border="0" /&gt;. Thomae's function is continuous at every irrational point, and discontinuous at every rational point.  Thomae's function is defined as &lt;img src="http://www.codecogs.com/gif.latex?f%28x%29%20=%200" align="middle" border="0" /&gt; if &lt;img src="http://www.codecogs.com/gif.latex?x" align="middle" border="0" /&gt; is irrational, &lt;img src="http://www.codecogs.com/gif.latex?f%28x%29%20=%20%5Cfrac%7B1%7D%7Bn%7D" align="middle" border="0" /&gt; if &lt;img src="http://www.codecogs.com/gif.latex?x=%5Cfrac%7Bm%7D%7Bn%7D" align="middle" border="0" /&gt;, and if &lt;img src="http://www.codecogs.com/gif.latex?x%20=%200" align="middle" border="0" /&gt; we say &lt;img src="http://www.codecogs.com/gif.latex?n%20=%201" align="middle" border="0" /&gt;. Let us first prove that &lt;img src="http://www.codecogs.com/gif.latex?f" align="middle" border="0" /&gt; is discontinuous at each rational point. Let &lt;img src="http://www.codecogs.com/gif.latex?%5Cfrac%7Bm%7D%7Bn%7D%20%5Cin%20%5Cmathbb%7BQ%7D" align="middle" border="0" /&gt; be arbitrary, let &lt;img src="http://www.codecogs.com/gif.latex?%5Cepsilon%20=%20%5Cfrac%7B1%7D%7B2n%7D" align="middle" border="0" /&gt;, and let &lt;img src="http://www.codecogs.com/gif.latex?%5Cdelta%20%3E%200" align="middle" border="0" /&gt; be arbitrary. Since the irrationals are dense in &lt;img src="http://www.codecogs.com/gif.latex?%5Cmathbb%7BR%7D" align="middle" border="0" /&gt;, there exists an &lt;img src="http://www.codecogs.com/gif.latex?x%5Cin%5Cmathbb%7BR%7D%5Csetminus%5Cmathbb%7BQ%7D" align="middle" border="0" /&gt; such that &lt;img src="http://www.codecogs.com/gif.latex?%7C%5Cfrac%7Bm%7D%7Bn%7D%20-%20x%7C%20%3C%20%5Cdelta" align="middle" border="0" /&gt;. Since &lt;img src="http://www.codecogs.com/gif.latex?f%28%5Cfrac%7Bm%7D%7Bn%7D%29%20=%20%5Cfrac%7B1%7D%7Bn%7D" align="middle" border="0" /&gt; and &lt;img src="http://www.codecogs.com/gif.latex?f%28x%29%20=%200" align="middle" border="0" /&gt;, &lt;img src="http://www.codecogs.com/gif.latex?%7Cf%28x%29%20-%20f%28%5Cfrac%7Bm%7D%7Bn%7D%29%7C%20=%20%5Cfrac%7B1%7D%7Bn%7D%20=%202%5Cepsilon%20%5Cge%20%5Cepsilon" align="middle" border="0" /&gt;. Thus since &lt;img src="http://www.codecogs.com/gif.latex?%5Cdelta%20%3E%200" align="middle" border="0" /&gt; was arbitrary, for all &lt;img src="http://www.codecogs.com/gif.latex?%5Cdelta%20%3E%200" align="middle" border="0" /&gt; there exists an &lt;img src="http://www.codecogs.com/gif.latex?x%5Cin%5Cmathbb%7BR%7D" align="middle" border="0" /&gt; such that &lt;img src="http://www.codecogs.com/gif.latex?%7C%5Cfrac%7Bm%7D%7Bn%7D%20-%20x%7C%20%3C%20%5Cdelta" align="middle" border="0" /&gt; implies &lt;img src="http://www.codecogs.com/gif.latex?%7Cf%28x%29%20-%20f%28%5Cfrac%7Bm%7D%7Bn%7D%29%7C%20%5Cge%20%5Cepsilon" align="middle" border="0" /&gt;. By the definition of discontinuous, &lt;img src="http://www.codecogs.com/gif.latex?f" align="middle" border="0" /&gt; is discontinuous at &lt;img src="http://www.codecogs.com/gif.latex?%5Cfrac%7Bm%7D%7Bn%7D" align="middle" border="0" /&gt;. Since &lt;img src="http://www.codecogs.com/gif.latex?%5Cfrac%7Bm%7D%7Bn%7D%5Cin%5Cmathbb%7BQ%7D" align="middle" border="0" /&gt; was arbitrary, &lt;img src="http://www.codecogs.com/gif.latex?f" align="middle" border="0" /&gt; is discontinuous at every rational point.&lt;br /&gt;&lt;br /&gt;Next we show the more shocking result that &lt;img src="http://www.codecogs.com/gif.latex?f" align="middle" border="0" /&gt; is continuous on an arbitrary irrational &lt;img src="http://www.codecogs.com/gif.latex?p" align="middle" border="0" /&gt;. Let &lt;img src="http://www.codecogs.com/gif.latex?%5Cepsilon%20%3E%200" align="middle" border="0" /&gt; be arbitrary. By the Archimedean property, there exists an &lt;img src="http://www.codecogs.com/gif.latex?N%20%5Cin%5Cmathbb%7BN%7D" align="middle" border="0" /&gt; such that &lt;img src="http://www.codecogs.com/gif.latex?N%20%3E%20%5Cfrac%7B1%7D%7B%5Cepsilon%7D" align="middle" border="0" /&gt;, so &lt;img src="http://www.codecogs.com/gif.latex?%5Cfrac%7B1%7D%7BN%7D%20%3C%20%5Cepsilon" align="middle" border="0" /&gt;. Call the set of rationals with denominator at most &lt;img src="http://www.codecogs.com/gif.latex?N" align="middle" border="0" /&gt; within &lt;img src="http://www.codecogs.com/gif.latex?%28p%20-%20%5Cfrac%7B1%7D%7BN%7D,%20p%20+%20%5Cfrac%7B1%7D%7BN%7D%29" align="middle" border="0" /&gt; set &lt;img src="http://www.codecogs.com/gif.latex?R" align="middle" border="0" /&gt;. We know that &lt;img src="http://www.codecogs.com/gif.latex?%7CR%7C" align="middle" border="0" /&gt; is finite from the following combinatorial argument. Since &lt;img src="http://www.codecogs.com/gif.latex?%5Cfrac%7B%5Clceil%20%7CpN%20+%201%7C%5Crceil%7D%7BN%7D%20%5Cge%20p%20+%20%5Cfrac%7B1%7D%7BN%7D" align="middle" border="0" /&gt; and &lt;img src="http://www.codecogs.com/gif.latex?%5Cfrac%7B%5Clceil%20%7CpN%20-%201%7C%5Crceil%7D%7BN%7D%5Cge%20p%20-%20%5Cfrac%7B1%7D%7BN%7D" align="middle" border="0" /&gt; , the number of rationals with denominator &lt;img src="http://www.codecogs.com/gif.latex?N" align="middle" border="0" /&gt; in the desired range is less than or equal &lt;img src="http://www.codecogs.com/gif.latex?N%28%5Clceil%20%7CpN+1%7C%5Crceil%20+%20%5Clceil%20%7CpN%20-%201%7C%5Crceil%29" align="middle" border="0" /&gt;, and so forth for natural numbers &lt;img src="http://www.codecogs.com/gif.latex?1%5Cle%20n%20%3C%20N" align="middle" border="0" /&gt;, so &lt;img src="http://www.codecogs.com/gif.latex?%7CR%7C" align="middle" border="0" /&gt; is finite. Let &lt;img src="http://www.codecogs.com/gif.latex?%5Cdelta%20=%20%5Cmbox%7Bmin%7D%5C%7B%20%7Cp%20-%20x%7C%20%5Cmid%20x%20%5Cin%20R%20%5C%7D" align="middle" border="0" /&gt;. There are two cases for &lt;img src="http://www.codecogs.com/gif.latex?x%5Cin%5Cmathbb%7BR%7D" align="middle" border="0" /&gt; such that &lt;img src="http://www.codecogs.com/gif.latex?%7Cx%20-%20p%7C%20%3C%20%5Cdelta" align="middle" border="0" /&gt;, where &lt;img src="http://www.codecogs.com/gif.latex?x" align="middle" border="0" /&gt; is irrational and thus &lt;img src="http://www.codecogs.com/gif.latex?f%28x%29%20=%200%20%3C%20%5Cepsilon" align="middle" border="0" /&gt;, or &lt;img src="http://www.codecogs.com/gif.latex?x%20=%20%5Cfrac%7Bm%7D%7Bn%7D" align="middle" border="0" /&gt; where &lt;img src="http://www.codecogs.com/gif.latex?m,n%5Cin%5Cmathbb%7BZ%7D" align="middle" border="0" /&gt; and &lt;img src="http://www.codecogs.com/gif.latex?gcd%28m,n%29%20=%201" align="middle" border="0" /&gt;. In this case, &lt;img src="http://www.codecogs.com/gif.latex?n" align="middle" border="0" /&gt; cannot be less than &lt;img src="http://www.codecogs.com/gif.latex?N" align="middle" border="0" /&gt; since &lt;img src="http://www.codecogs.com/gif.latex?%5Cdelta" align="middle" border="0" /&gt; is defined to be small enough to skip each point in &lt;img src="http://www.codecogs.com/gif.latex?%28p%20-%20%5Cfrac%7B1%7D%7BN%7D,%20p%20+%20%5Cfrac%7B1%7D%7BN%7D%29" align="middle" border="0" /&gt; with a smaller denominator than &lt;img src="http://www.codecogs.com/gif.latex?N" align="middle" border="0" /&gt;. Thus &lt;img src="http://www.codecogs.com/gif.latex?n%20%5Cge%20N" align="middle" border="0" /&gt;, so &lt;img src="http://www.codecogs.com/gif.latex?f%28x%29%20=%20%5Cfrac%7B1%7D%7Bn%7D%20%5Cle%20%5Cfrac%7B1%7D%7BN%7D%20%3C%20%5Cepsilon" align="middle" border="0" /&gt;. Therefore &lt;img src="http://www.codecogs.com/gif.latex?f" align="middle" border="0" /&gt; is continuous at &lt;img src="http://www.codecogs.com/gif.latex?p" align="middle" border="0" /&gt;.  For more information and an image of what &lt;img src="http://www.codecogs.com/gif.latex?f" align="middle" border="0" /&gt; looks like, take a look at &lt;a href="http://en.wikipedia.org/wiki/Thomae%27s_function"&gt;the Wikipedia page&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5780206530047749771-7819236360861838134?l=lifeandmath.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeandmath.blogspot.com/feeds/7819236360861838134/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5780206530047749771&amp;postID=7819236360861838134' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5780206530047749771/posts/default/7819236360861838134'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5780206530047749771/posts/default/7819236360861838134'/><link rel='alternate' type='text/html' href='http://lifeandmath.blogspot.com/2009/04/strange-consequences-of-simple.html' title='Strange Consequences of Simple Definitions (I)'/><author><name>J. Ian Johnson</name><uri>http://www.blogger.com/profile/02510605633293210260</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5780206530047749771.post-5817418161202255664</id><published>2009-01-30T21:28:00.000-08:00</published><updated>2009-01-30T21:35:47.907-08:00</updated><title type='text'>Fellow blogger.com mathematicians...</title><content type='html'>If you stumble upon this page in the hopes of finding a way to add LaTeX capabilities to your blogger/blogspot posts, today is your lucky day. Well, your lucky day could have been back in March 2007 when wolverineX02 wrote his "LaTeX for blogger" script, but I have added the ability to UNDO the translated LaTeX code. Now if you wish to revise a formula, you don't have to wade through a lot of URL translation codes/rewrite your whole formula.&lt;br /&gt;&lt;br /&gt;This script requires Firefox and the greasemonkey extension, both of which I highly recommend. &lt;a href="http://userscripts.org/scripts/show/41481"&gt;http://userscripts.org/scripts/show/41481&lt;/a&gt;&lt;br /&gt;The only thing different from normal is that math must be enclosed in two dollars signs on each side instead of the one you're used to in your TeX compilers. $$\LaTeX$$ becomes &lt;img src="http://www.codecogs.com/gif.latex?%5CLaTeX" align="middle" border="0" /&gt; :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5780206530047749771-5817418161202255664?l=lifeandmath.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeandmath.blogspot.com/feeds/5817418161202255664/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5780206530047749771&amp;postID=5817418161202255664' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5780206530047749771/posts/default/5817418161202255664'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5780206530047749771/posts/default/5817418161202255664'/><link rel='alternate' type='text/html' href='http://lifeandmath.blogspot.com/2009/01/fellow-bloggercom-mathematicians.html' title='Fellow blogger.com mathematicians...'/><author><name>J. Ian Johnson</name><uri>http://www.blogger.com/profile/02510605633293210260</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5780206530047749771.post-1339406299504834804</id><published>2009-01-30T08:08:00.000-08:00</published><updated>2009-04-20T08:44:47.044-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='algebra'/><category scheme='http://www.blogger.com/atom/ns#' term='math'/><title type='text'>Interesting occurrence with 7th root of unity</title><content type='html'>&lt;a href="http://sites.google.com/site/lifeandmath/Home/root7unity.pdf?attredirects=0"&gt;PDF of this post&lt;/a&gt;&lt;br /&gt;I've come across a property of &lt;img src="http://www.codecogs.com/gif.latex?i%5Csqrt%7B7%7D" align="middle" border="0" /&gt; that is rather interesting. Letting &lt;img src="http://www.codecogs.com/gif.latex?%5Comega%20=%20e%5E%7B%5Cfrac%7B2%5Cpi%20i%7D%7B7%7D%7D" align="middle" border="0" /&gt;, we let &lt;img src="http://www.codecogs.com/gif.latex?%5Ceta%20=%20%5Comega%20+%20%5Comega%5E2%20+%20%5Comega%5E4" align="middle" border="0" /&gt;, we will see that &lt;img src="http://www.codecogs.com/gif.latex?%5Ceta%20-%20%5Coverline%7B%5Ceta%7D%20=%20i%5Csqrt%7B7%7D" align="middle" border="0" /&gt;.&lt;br /&gt;&lt;br /&gt;Instead of working directly with this difference, we square the expression for something more easily manipulated. &lt;img src="http://www.codecogs.com/gif.latex?%28%5Ceta%20-%20%5Coverline%7B%5Ceta%7D%29%5E2%20=%20%5Ceta%5E2%20-%20%5Ceta%5Coverline%7B%5Ceta%7D%20+%20%5Coverline%7B%5Ceta%7D%5E2%20=%20%28%5Comega%5E2%20+%202%20%5Comega%5E3%20+%20%5Comega%5E4%20+%202%20%5Comega%5E5%20+%202%20%5Comega%5E6%20+%20%5Comega%5E8%29%20+%20%28%5Comega%5E%7B-2%7D%20+%202%20%5Comega%5E%7B-3%7D%20+%20%5Comega%5E%7B-4%7D%20+%202%20%5Comega%5E%7B-5%7D%20+%202%20%5Comega%5E%7B-6%7D%20+%20%5Comega%5E%7B-8%7D%29%20-%202%28%5Comega%20%5Comega%5E%7B-1%7D%20+%20%5Comega%5E2%20%5Comega%5E%7B-1%7D%20+%20%5Comega%5E4%20%5Comega%5E%7B-1%7D%20+%20%5Comega%20%5Comega%5E%7B-2%7D%20+%20%5Comega%5E2%20%5Comega%5E%7B-2%7D%20+%20%5Comega%5E4%20%5Comega%5E%7B-2%7D%20+%20%5Comega%20%5Comega%5E%7B-4%7D%20+%20%5Comega%5E2%20%5Comega%5E%7B-4%7D%20+%20%5Comega%5E4%20%5Comega%5E%7B-4%7D%29" align="middle" border="0" /&gt;. Using the equalities &lt;img src="http://www.codecogs.com/gif.latex?%5Comega%5E%7B-1%7D%20=%20%5Comega%5E6" align="middle" border="0" /&gt;, &lt;img src="http://www.codecogs.com/gif.latex?%5Comega%5E%7B-2%7D%20=%20%5Comega%5E5" align="middle" border="0" /&gt; etc., we can simplify this down to &lt;img src="http://www.codecogs.com/gif.latex?%5Comega%20+%20%5Comega%5E2%20+%20%5Comega%5E3%20+%20%5Comega%5E4%20+%20%5Comega%5E5%20+%20%5Comega%5E6%20-%206" align="middle" border="0" /&gt;. Since the sum of the 7th roots of unity equals 0 and the sum only neglects the root &lt;img src="http://www.codecogs.com/gif.latex?%5Comega%5E7%20=%201" align="middle" border="0" /&gt;, we see that &lt;img src="http://www.codecogs.com/gif.latex?%28%5Ceta%20-%20%5Coverline%7B%5Ceta%7D%29%5E2%20=%20-7" align="middle" border="0" /&gt;. Thus &lt;img src="http://www.codecogs.com/gif.latex?%5Ceta%20-%20%5Coverline%7B%5Ceta%7D%20=%20i%5Csqrt%7B7%7D" align="middle" border="0" /&gt;. Amazing stuff, right?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5780206530047749771-1339406299504834804?l=lifeandmath.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeandmath.blogspot.com/feeds/1339406299504834804/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5780206530047749771&amp;postID=1339406299504834804' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5780206530047749771/posts/default/1339406299504834804'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5780206530047749771/posts/default/1339406299504834804'/><link rel='alternate' type='text/html' href='http://lifeandmath.blogspot.com/2009/01/interesting-occurrence-with-7th-root-of.html' title='Interesting occurrence with 7th root of unity'/><author><name>J. Ian Johnson</name><uri>http://www.blogger.com/profile/02510605633293210260</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5780206530047749771.post-763093849573304748</id><published>2009-01-08T14:07:00.000-08:00</published><updated>2009-01-08T14:31:54.822-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>A bash script I wrote and love</title><content type='html'>I, like many Linux geeks before me, love to use the terminal for just about everything. However when I need to use programs with GUIs (Firefox, amarok, okular, etc), I wanted to execute them silently and to get them to return focus to the terminal. Normally if you type&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;$ firefox&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;You get a bunch of X and Gtk warnings during execution of Firefox, and you can't use that shell anymore. You have to open another tab in konsole. So, this script I wrote is called "sex" for "silent execute." Mainly for the brevity and the humor of having&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;$ sex dolphin&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;be a valid command. This script also allows parameters to be sent correctly to an executable, so&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;$ sex okular A\ document\ with\ spaces.pdf&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;opens "A document with spaces.pdf" in okular correctly.&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;#!/bin/sh&lt;br /&gt;CONCAT=&amp;quot;${1}&amp;quot;; shift&lt;br /&gt;for ARG in &amp;quot;$@&amp;quot;; do&lt;br /&gt;  CONCAT=&amp;quot;${CONCAT} \&amp;quot;${ARG}\&amp;quot;&amp;quot;&lt;br /&gt;done&lt;br /&gt;eval &amp;quot;$CONCAT &amp;gt;&amp;gt; /dev/null 2&amp;gt;&amp;amp;1 &amp;amp;&amp;quot;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Simply put this in /usr/bin/sex (need root) and do a chmod +x /usr/bin/sex. I recommend adding&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;alias ff='sex firefox'&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;to your ~/.bashrc or your /etc/bash.bashrc too. It's a nice shortcut.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5780206530047749771-763093849573304748?l=lifeandmath.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeandmath.blogspot.com/feeds/763093849573304748/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5780206530047749771&amp;postID=763093849573304748' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5780206530047749771/posts/default/763093849573304748'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5780206530047749771/posts/default/763093849573304748'/><link rel='alternate' type='text/html' href='http://lifeandmath.blogspot.com/2009/01/bash-script-i-wrote-and-love.html' title='A bash script I wrote and love'/><author><name>J. Ian Johnson</name><uri>http://www.blogger.com/profile/02510605633293210260</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5780206530047749771.post-4563048066799642611</id><published>2008-12-05T10:57:00.000-08:00</published><updated>2008-12-05T16:12:24.402-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='algebra'/><category scheme='http://www.blogger.com/atom/ns#' term='math'/><title type='text'>Divide by 0 != universe explode</title><content type='html'>Post inspired by: &lt;a href="http://www.youtube.com/watch?v=CLxMN5YMS3A" target=_blank&gt;The Last Denominator&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I just want to let people know that there is no way that any (true) theorem about the field of real numbers (or any field) has a division by zero. In order to get to the concluding statement would require an element that is 1/0 (which I will call the inverse of zero) to be summoned. Since this element does not exist in a field other than the zero ring (in which case 0 = 1), it cannot be used. The step taken is invalid.&lt;br /&gt;&lt;br /&gt;Now that I have shown that the usage of zero's inverse is invalid, I will show that no true statement can imply a theorem that involves zero's inverse. By the axioms of inference that logicians, philosophers and mathematicians have developed, A implies B is equivalent to (NOT A) OR B. Therefore since B = conclusion with zero's inverse, if A is true, then the implication is false. And so we conclude that only false statements can imply the existence of zero's inverse (with the exception of the extremely uninteresting case of the zero ring).&lt;br /&gt;&lt;br /&gt;To those of you who do not know to what I refer to as a ring and field, here is the break down (first we need the concept of a group):&lt;br /&gt;A group G is a set of elements with a very limited amount of structure imposed on them under one operation (call it *):&lt;br /&gt;1) There exists an identity element, 1, such that 1*x = x for each element x in G.&lt;br /&gt;2) There exists an inverse element 1/x such that 1/x * x = 1 for each x in G.&lt;br /&gt;3) For two elements in G, x and y, x*y is also in G.&lt;br /&gt;4) For three elements in G, x,y and z, (x*y)*z = x*(y*z). In other words, * is an associative operation.&lt;br /&gt;&lt;br /&gt;A ring R is simply a set of elements that have a certain structure under two operations defined among the elements (call them + and *):&lt;br /&gt;1) R is an abelian group under + (abelian just means that for x,y in R, x + y = y + x. In other words, + is commutative).&lt;br /&gt;2) For two elements x, y in R, x*y is in R.&lt;br /&gt;3) The distributive laws hold: x,y,z in R imply x(y + z) = xy + xz, and (x + y)z = xz + yz.&lt;br /&gt;&lt;br /&gt;A field F is a special kind of ring that really has a lot of great qualities that allow us to prove a lot of cool things:&lt;br /&gt;1) F is a ring.&lt;br /&gt;2) All elements of F except the identity of + form an abelian group under *.&lt;br /&gt;&lt;br /&gt;The "except the identity of +" is the key term. Since we commonly call the identity of +, 0, this means that 0 is not required to have an inverse (with regards to *) in F. We know that the real numbers form a field because every element other than 0 has a multiplicative inverse (namely 1/x), and every element has an additive inverse (-x), and you can't add or multiply two numbers and get an answer that isn't a real number. Since 0*x = 0 for any x in the reals, 0 does not have an inverse z such that 0*z = 1. Thus 0 does not have an inverse in the real numbers.&lt;br /&gt;&lt;br /&gt;Okay? Now you can be sure that if you get a division by 0 that either the number is too small for your calculator to keep the correct precision and it just rounded to 0, you started off with a false statement, or you had an incorrect deductive step.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5780206530047749771-4563048066799642611?l=lifeandmath.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeandmath.blogspot.com/feeds/4563048066799642611/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5780206530047749771&amp;postID=4563048066799642611' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5780206530047749771/posts/default/4563048066799642611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5780206530047749771/posts/default/4563048066799642611'/><link rel='alternate' type='text/html' href='http://lifeandmath.blogspot.com/2008/12/divide-by-0-universe-explode.html' title='Divide by 0 != universe explode'/><author><name>J. Ian Johnson</name><uri>http://www.blogger.com/profile/02510605633293210260</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5780206530047749771.post-3416733093164503421</id><published>2008-11-25T16:25:00.000-08:00</published><updated>2009-04-22T17:47:11.751-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='complexity'/><title type='text'>The intersection inference problem is NP-complete</title><content type='html'>&lt;style type="text/css"&gt;img {position:relative;top:-1px; border:0px !important;}&lt;/style&gt;&lt;a href="http://sites.google.com/site/lifeandmath/Home/intersection_inference.pdf?attredirects=0"&gt;PDF for this post&lt;/a&gt;&lt;br /&gt;First let me start off by defining the intersection inference problem.&lt;br /&gt;&lt;br /&gt;Given a set &lt;img src="http://www.codecogs.com/gif.latex?U" align="middle" /&gt;, some finite number (&lt;img src="http://www.codecogs.com/gif.latex?n%5Cin%5Cmathbb%7BN%7D" align="middle" /&gt;) subsets &lt;img src="http://www.codecogs.com/gif.latex?A_i" align="middle" /&gt;, and &lt;img src="http://www.codecogs.com/gif.latex?n" align="middle" /&gt; constants &lt;img src="http://www.codecogs.com/gif.latex?c_i" align="middle" /&gt;, is there a subset &lt;img src="http://www.codecogs.com/gif.latex?X%5Csubseteq%20U" align="middle" /&gt; such that &lt;img src="http://www.codecogs.com/gif.latex?%7CX%5Ccap%20A_i%7C=c_i" align="middle" /&gt; for &lt;img src="http://www.codecogs.com/gif.latex?i" align="middle" /&gt; ranging all &lt;img src="http://www.codecogs.com/gif.latex?n" align="middle" /&gt; values?&lt;br /&gt;&lt;br /&gt;First we prove that intersection inference is in NP. Suppose we have a solution &lt;img src="http://www.codecogs.com/gif.latex?X%20%5Csubseteq%20U" align="middle" /&gt;. In order to verify that &lt;img src="http://www.codecogs.com/gif.latex?X" align="middle" /&gt; is indeed a solution, we perform the &lt;img src="http://www.codecogs.com/gif.latex?m" align="middle" /&gt; intersections of &lt;img src="http://www.codecogs.com/gif.latex?X" align="middle" /&gt; with &lt;img src="http://www.codecogs.com/gif.latex?A" align="middle" /&gt; and confirm that &lt;img src="http://www.codecogs.com/gif.latex?%7CX%20%5Ccap%20A_i%7C%20=%20c_i" align="middle" /&gt;. Set intersection can be performed (naively) in &lt;img src="http://www.codecogs.com/gif.latex?O%28%7CX%7C%5Ccdot%7CA_i%7C%29" align="middle" /&gt; time, so this process is indeed polynomial and clearly yields the correct answer. Thus intersection inference is in NP.&lt;br /&gt;&lt;br /&gt;To prove intersection inference is NP-complete, we will show a reduction from 3-dimensional mapping to the intersection inference problem. With an arbitrary instance of the 3-dimensional mapping problem defined as sets &lt;img src="http://www.codecogs.com/gif.latex?X,%20Y,%20Z,%20T" align="middle" /&gt; such that &lt;img src="http://www.codecogs.com/gif.latex?X%5Ccap%20Y%20=%20X%5Ccap%20Z%20=%20Y%5Ccap%20Z%20=%20%5Cvarnothing" align="middle" /&gt;, &lt;img src="http://www.codecogs.com/gif.latex?%7CX%7C=%7CY%7C=%7CZ%7C=n%5Cin%5Cmathbb%7BN%7D" align="middle" /&gt; and &lt;img src="http://www.codecogs.com/gif.latex?T%5Csubseteq%20X%5Ctimes%20Y%5Ctimes%20Z" align="middle" /&gt;. To reduce this to the intersection inference problem, let &lt;img src="http://www.codecogs.com/gif.latex?U%20=%20T" align="middle" /&gt;, and define &lt;img src="http://www.codecogs.com/gif.latex?%5Clbrace%20A_1,%20A_2,%20...,%20A_n%5Crbrace" align="middle" /&gt; to be the subsets of triples that contain &lt;img src="http://www.codecogs.com/gif.latex?x_1,%20x_2,%20...,%20x_n%20%5Cin%20X" align="middle" /&gt; respectively. Define in a similar manner from &lt;img src="http://www.codecogs.com/gif.latex?n+1" align="middle" /&gt; to &lt;img src="http://www.codecogs.com/gif.latex?2n" align="middle" /&gt; for &lt;img src="http://www.codecogs.com/gif.latex?y_i%5Cin%20Y" align="middle" /&gt; and from &lt;img src="http://www.codecogs.com/gif.latex?2n+1" align="middle" /&gt; to &lt;img src="http://www.codecogs.com/gif.latex?3n" align="middle" /&gt; for &lt;img src="http://www.codecogs.com/gif.latex?z_i%5Cin%20Z" align="middle" /&gt;. Finally define &lt;img src="http://www.codecogs.com/gif.latex?A_0%20=%20T" align="middle" /&gt;. The constraints are &lt;img src="http://www.codecogs.com/gif.latex?c_0%20=%20n" align="middle" /&gt; and &lt;img src="http://www.codecogs.com/gif.latex?c_i%20=%201" align="middle" /&gt; for &lt;img src="http://www.codecogs.com/gif.latex?i%20%5Cin%20%5Clbrace%201,2,...,n%5Crbrace" align="middle" /&gt;. We can see that to create these subsets takes &lt;img src="http://www.codecogs.com/gif.latex?O%28n%5E3%29" align="middle" /&gt; time in the rather straightforward manner of iterating over &lt;img src="http://www.codecogs.com/gif.latex?T" align="middle" /&gt;'s elements to divvy up the elements into arrays representing &lt;img src="http://www.codecogs.com/gif.latex?A_i" align="middle" /&gt;.&lt;br /&gt;&lt;br /&gt;Through this construction we can see that exactly &lt;img src="http://www.codecogs.com/gif.latex?n" align="middle" /&gt; triples must match, and only one triple can contain each specific element in &lt;img src="http://www.codecogs.com/gif.latex?X%5Ccup%20Y%5Ccup%20Z" align="middle" /&gt;. Thus if there exists a solution to this intersection inference problem, the solution is exactly the &lt;img src="http://www.codecogs.com/gif.latex?n" align="middle" /&gt; triples that satisfy the 3-dimensional matching problem. If there does not exist a solution, then at least one constraint was not satisfied, meaning at least one element in &lt;img src="http://www.codecogs.com/gif.latex?X%5Ccup%20Y%5Ccup%20Z" align="middle" /&gt; was not covered, or all elements were covered with some redundancies. Thus the reduction is correct and intersection inference is NP-complete because a known NP-complete problem was poly-time reducible to the intersection inference problem which is in NP.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5780206530047749771-3416733093164503421?l=lifeandmath.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeandmath.blogspot.com/feeds/3416733093164503421/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5780206530047749771&amp;postID=3416733093164503421' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5780206530047749771/posts/default/3416733093164503421'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5780206530047749771/posts/default/3416733093164503421'/><link rel='alternate' type='text/html' href='http://lifeandmath.blogspot.com/2008/11/intersection-inference-problem-is-np.html' title='The intersection inference problem is NP-complete'/><author><name>J. Ian Johnson</name><uri>http://www.blogger.com/profile/02510605633293210260</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5780206530047749771.post-8672941930990254122</id><published>2008-08-07T23:29:00.001-07:00</published><updated>2008-08-07T23:40:55.982-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='visual studio'/><category scheme='http://www.blogger.com/atom/ns#' term='tech help'/><category scheme='http://www.blogger.com/atom/ns#' term='microsoft'/><title type='text'>Windows installer and bad design</title><content type='html'>So I have a hard drive that I use to share data between my Linux and Windows OSes. That drive is in EXT2 and thus does not support the "hidden" file attribute. I decided I wanted to install Visual Studio Express 2008, but behold... the installer decides to use my EXT2 drive to extract to and then copy from into my temp directory on the other hard drive. Ridiculous? I haven't even started yet.&lt;br /&gt;&lt;br /&gt;Setup decided to create a file called $shtdwn$.req with the hidden bit on. During the copy process, instead of saying, "these are the files I need. Copy them," it just gets the directory contents and tries to copy them all. This would work on any file system that supports the hidden attribute. The kicker? Well, first of all I have no idea why it decided to use P: instead of C:, but more importantly I could not discover any way to reconfigure this setting. No command-line argument help prompt in order to discover said functionality... I even tried using the cmd prompt to copy at elevated privileges to no avail.&lt;br /&gt;&lt;br /&gt;But to my relief, the gurus of Linux prevail (yes, not a windows dev... hah) and give me a workaround.&lt;br /&gt;set _SFX_CAB_SHUTDOWN_REQUEST=$shtdwn$.req&lt;br /&gt;before running vcssetup.exe and it will skip that file. I'm pretty sure it just has to contain a value and not $shtdwn$.req specifically, but I didn't bother to test.&lt;br /&gt;&lt;br /&gt;This post is for people like me in the future. For those of you that stumble upon this page, I hope this is what you were looking for.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5780206530047749771-8672941930990254122?l=lifeandmath.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeandmath.blogspot.com/feeds/8672941930990254122/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5780206530047749771&amp;postID=8672941930990254122' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5780206530047749771/posts/default/8672941930990254122'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5780206530047749771/posts/default/8672941930990254122'/><link rel='alternate' type='text/html' href='http://lifeandmath.blogspot.com/2008/08/windows-installer-and-bad-design.html' title='Windows installer and bad design'/><author><name>J. Ian Johnson</name><uri>http://www.blogger.com/profile/02510605633293210260</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5780206530047749771.post-457873807109555324</id><published>2008-07-23T19:38:00.000-07:00</published><updated>2009-01-08T14:32:56.114-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><title type='text'>BrowserOS</title><content type='html'>This somewhat unorganized post is about my vision of desktops merging with the internet. A day's brainstorm session, let's say.&lt;br /&gt; &lt;br /&gt; Abstract&lt;br /&gt; An amazing amount of our time is spent online. So much so that browsing the web has become more natural to us than browsing our computer. My vision of computers in the future (apart from Minority Report-style holographic and surface computing) involves intertwining the browser and the rest of the computer. What I see involves probably the biggest risk toward this approach, and that is getting rid of hierarchical directories to store files, but rather allowing a user to search for documents via a common search engine query.&lt;br /&gt; &lt;br /&gt; The File System (BrowserFS)&lt;br /&gt; Files can be tagged by users and also by a background data mining process for relevancy determining algorithms. The way to best implement this is to have one's hard drive be totally a one- to two-level database system.&lt;br /&gt;What is a two-level database system? Well, in my mind there are three types of files. User-created/owned, executable, and application data. Application data would be stored in the second level of the database. The second level is a database as a blob entry in the first level of the database in order to minimize clutter and narrow query results to relevant areas. The motivation for this, or rather my inspiration for this comes from my observation of two classes of applications. One class uses many flat files in complex directory hierarchies, and the other uses very few "packed" files which are basically virtual file systems that have all those many flat files organized as described of the previous class. Obviously one approach is cleaner than the other, and there only exists one level of indirection between the two. If the OS API has a boolean in fopen, say, that specifies if the data is first or second level, the resulting query could be limited to the application database.&lt;br /&gt;"But wait!" you say, "Applications don't need to search for their data files, since they know exactly what they need. Don't introduce this overhead." I agree 100%, which brings me to my next idea.&lt;br /&gt;The development tools for this operating system would allow order to be introduced to files residing on the build system. A tool that could create directory hierarchies that references files residing on the system would output a necessary build file for dependent data files. We impose directory hierarchies because hey, we know that's how we organize without ad hoc search queries. The most important reason however is because creating a URI to the file would allow direct access without queries. Since before shipping an application, one generally works in debug mode, debug applications would use this hierarchy file to open the referenced files on the first level database. Ship applications however would compile the second level database BLOB and work as described.&lt;br /&gt;Applications can still access all other files; first or second level. The second level database is just another file in the first level database, only access to it is optimized more in the OS kernel. Thus if a user specifies he wants to use that application database file that a search has given him, he can, and then browse though that database as well. This is all if he has the permissions to do so, of course.&lt;br /&gt;So where are the first level files, and how do applications access them once search spits them out? Well they all have URIs too, and querying the database in standard fashion can output all files on your computer if one so desires. The main difference is that first-level file URIs are assigned by the OS, and the second-level file URIs are assigned by the developer.&lt;br /&gt; &lt;br /&gt; File Name and Extension Makeover&lt;br /&gt;File names and file extensions are no longer what you might think either. A file extension is an attribute of a file record in the database that will either reference an application (applications register extensions with the OS by simply being applications on the system) that will open it, or are generic (ex. type EXT) and do not reference an application. So developers can still change a file's type, and it's still by changing what filename.end ends with, but by changing the extension, a disambiguation text extension would ask if it's for common applications A, B, C, Generic, or search. With machine learning, the OS can determine the behavior it should take by default for changing certain file names to others.&lt;br /&gt;Keep in mind file names are no longer file names. They're optional titles that are also part of the user tags (weighted differently though) that are displayed on search results, along with snippets, if enabled.&lt;br /&gt; &lt;br /&gt; Relevant Material Preview&lt;br /&gt;This brings me to another thought. File snippets can mean loads of different things for different files. For this reason, applications can define ways to render snippets. Rendering can be in the form of text, rich text, images or even other applications' output. Why other applications' output? It's lame if the OS is in charge of things such as all the video playback with codecs galore ever changing. No, that makes the OS monolithic and breaks precious programming patterns. Of course one would aim on shipping the OS with a default video player, but I digress. By letting other applications render things for you, this enables third parties to customize snippet behavior without modifying the application itself. Say you have a text document that normally renders the text around what's found as relevant in its own way. Say the default behavior is the output the rich text, but you want it to output normal text. Assuming the application doesn't allow you to specify this yourself, there is a third party app that does this, and only this. Assign it to render that file's type and presto! Customization is at your fingertips.&lt;br /&gt; Now I'm getting into just features the search application would provide. Granted there are craploads of ways to present information, but I won't go into those details now.&lt;br /&gt; &lt;br /&gt; Replacing Explorer&lt;br /&gt; What I want to talk about now is the user interface of the desktop manager. I've never really liked the taskbar and the start menu. The start menu has basically a directory hierarchy with links to files or applications that installed apps have deemed themselves worthy of adding to. This is clutter that becomes unnecessary with search. Screw the start menu. It's gone.&lt;br /&gt; What do I LIKE about the start menu? Recent programs and access to control panel, along with links to the mostly used folders. But... what makes those folders so important? What criteria is used for determining which recently used apps are shown? This seems like customizable queries should be allowed. I actually don't like how recent programs messes up a lot and adds things I really don't want shown. This is another application where machine learning or AI could really show its shine. As for folders, ya... folders no longer exist. Only tags and relevancy by content. So what do we do? We show some default set of "popular tags'" query results along with some other logic we deem adds visibility weight. Obviously we can't/don't want to show all files tagged documents on the computer. No, we want to add importance like date made, times opened, etc. Really one could use tags to make a pseudo folder/file hierarchy, as I'm sure you can imagine, but that defeats the purpose of search, and isn't how people will think to organize. Say... you're loading pictures off your digital camera and normally would make a new folder in "Pictures\Jojo's family\Life in Madagascar" this time for "Summer 2008". This time, instead of navigating to Life in Madagascar and then making the file to import to, you're prompted to simply add tags. So "jojo's family Madagascar summer 2008" and pow, searches for jojo and more restricted searches will yield these pictures. For those who hate to type, search can be extended to finding relevant tags as well, so you can click through results and add tags to the list.&lt;br /&gt; This need for metadata is the current major risk of the imaginary BrowserOS. I can see in the near future though, using facial recognition and other image processing, more indexing techniques can be added to the system to build tags to improve relevancy without the need for user input.&lt;br /&gt; &lt;br /&gt; Feeds, Feeds, Feeds&lt;br /&gt; Back to the desktop. Query results can be rendered in any control that is deemed capable of rendering data, even if not in the most verbose way (say of the search application). Controls can make up your desktop. Multiple desktops are also possible (think Spaces if you're a Mac fanboy, or Gnome/KDE if you're awesome and use linux) that are all customized different ways. When I visualize this, I think of iGoogle, and all the different feeds and widgets I can have everywhere. I also think of computers of tomorrow all on static IPs and server oriented, so you could set up queries to render RSS feeds and server iGoogle if you so wish. My aim is really to merge the internet and the desktop experience into one seemless vision.&lt;br /&gt; Search could even show results from searching the local computer and with a search engine of choice. All these different modes would be easily discoverable in the search application.&lt;br /&gt; &lt;br /&gt; Window Management&lt;br /&gt; So yes, search result rendering, no more start menu, quick launch can be simple controls set up on the desktop that just fetch from a URI, but what of running applications? Surely those must be like windows and KDE and Gnome and Mac OSX somehow...? Nope. Running apps are just entries in the database as well. Granted, apps that start and stop all the time without showing themselves wouldn't be performing all these transactions in realtime. Applications will have execution tags that the desktop manager will be able to hook into. User apps, namely separate windows that normally show in the taskbar will have certain tags, background processes have other tags, but aren't added to the database until queried, or not at all. This information will likely just reside in memory. I imagine most likely that I would have alt-tab functionality only as a UI add-on that uses these queries. To actually show the gamut of applications running... I say default query in a feed somewhere. If an application needs to get your attention, the side of the screen could glow and once hovered over would show a feed of applications that are tagged to get your attention (think orange flashing tabs for a new AIM message for this attention-grabbing idea). Of course all this would be customizable as behavioral UI addons. Hell, an addon could actually show you the windows taskbar, if you really wanted it. In my opinion though, this is cluttered UI and won't be long missed once users get addicted to search.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5780206530047749771-457873807109555324?l=lifeandmath.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeandmath.blogspot.com/feeds/457873807109555324/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5780206530047749771&amp;postID=457873807109555324' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5780206530047749771/posts/default/457873807109555324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5780206530047749771/posts/default/457873807109555324'/><link rel='alternate' type='text/html' href='http://lifeandmath.blogspot.com/2008/07/browseros.html' title='BrowserOS'/><author><name>J. Ian Johnson</name><uri>http://www.blogger.com/profile/02510605633293210260</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5780206530047749771.post-6477363165002796422</id><published>2008-07-20T00:02:00.001-07:00</published><updated>2008-07-20T00:22:20.296-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='prose'/><category scheme='http://www.blogger.com/atom/ns#' term='algebra'/><category scheme='http://www.blogger.com/atom/ns#' term='math'/><title type='text'>Unstructured Thoughts on Structures</title><content type='html'>As an undergraduate in mathematics, I know more math than you, but still less math than epsilon. It is for this reason that most all my opinions and thoughts on mathematics are much more romantic than they are useful. I have written papers on different areas that interested me, and I have gone to many different talks and read several papers. Could I come up with an hypothesis and prove it? Probably not, but given my current position in university, I am sure I could find guidance toward starting such an endeavor.&lt;br /&gt;My goal with this blog is to increase readers' interest in mathematics and programming. I plan on talking about many random topics (but not truly random... a very fun investigation to do right there) that come to catch my interest, and I also aim to post solutions to different programming problems I come across. As long as my solutions to obscure problems are archived on the net, search engines will be able to index them and help a programmer in distress in the future.&lt;br /&gt;I plan not to touch such topics as politics, philosophy or my personal life, but as an opinionated person without the motivation to maintain more than one blog, I make no promises about the future.&lt;br /&gt;&lt;br /&gt;Back to the topic of this post, "Unstructured Thoughts on Structures." I am sure by now you have observed the unstructured thoughts, but what of these structures? Mathematics is all about creating abstractions to quantitatively and generally describe a problem. Structures, namely algebraic structures, are currently my focus of interest. Group theory, ring theory, field theory and Galois theory may ring bells for some of you. This is what I am talking about. This area of mathematics is so vastly different from anything else one studies before it that even mathematicians like to joke about it not being, "real math." A quote comes to mind from a source I cannot currently recall that is along the lines of, "Now we can solve this problem without any math at all; just group theory!" With this tidbit about structures to pique your interest, I will save more depth descriptions and discussions for later posts.&lt;br /&gt;&lt;br /&gt;Welcome to my blog, friends of mathematics and computers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5780206530047749771-6477363165002796422?l=lifeandmath.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lifeandmath.blogspot.com/feeds/6477363165002796422/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5780206530047749771&amp;postID=6477363165002796422' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5780206530047749771/posts/default/6477363165002796422'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5780206530047749771/posts/default/6477363165002796422'/><link rel='alternate' type='text/html' href='http://lifeandmath.blogspot.com/2008/07/unstructured-thoughts-on-structures.html' title='Unstructured Thoughts on Structures'/><author><name>J. Ian Johnson</name><uri>http://www.blogger.com/profile/02510605633293210260</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
