Karachi   ->   Sweden   ->   Karachi, again   ->   Dubai   ->   Bahrain   ->   Karachi, once more   ->   London and Leeds
Showing posts with label logic. Show all posts
Showing posts with label logic. Show all posts

Saturday, May 07, 2011

Proof of -x * -y = x * y

An inquisitive person posted a question on pakgrid: Why a negative number multiplied by a negative number gave a positive result? An example given by the poster was

While (-6) + (-6) + (-6) + (-6) = -24
why (-6) * (-4) = 24?

To help him, many people came forward with their examples and proofs. Here is one interesting proof by an assistant professor at NUST. Produced verbatim.

The proof of
-x * -y = x * y

is as follows:
-x * - y = -(x * -y) = --(x * y) = x * y

I have my sympathies with the professor's students. For one, what's this -- symbol? What on earth does that mean? Secondly, what property of arithmetic operators are you using when you convert -x * -y to -(x * -y), and finally isn't the whole argument cyclic? Isn't mathematical rigidity of your proofs the first thing they teach to a PhD candidate? Or have things changed these days?

On a side note, other interesting "logical" posts can be found here:

Jokes aside, the example given of -6 and -4 is plain wrong but the question "why a negative multiplied by a negative number gives a positive number" is a very genuine one. It's very sad that as school children we are not encouraged to ask such questions when a new concept is introduced. But sooner or later one realizes that all of the rules in Mathematics must have a rationale.

Sunday, October 19, 2008

TRG Tech Mind Games

TRG Tech sometimes posts a "crack this code" challenge along with their job ads in local newspapers. This month the challenge is to tell what the following code does:

z = lambda n:{ x for x in range (2, n+1) if len ([ i for i in range (2, x) if x%i == 0 ]) == 0 }

I am not sure what functional language this is written in but it seems to be definition of a function which returns a set of prime numbers below the given number. However, I think there is a bug as well (not sure about the language, so I can't be 100% confident). The check in the list should be as following, in my opinion:

[i for i in range (2, x-1) if x%i == 0]

Saturday, June 02, 2007

The 99 Feet Man

I have come to know that I can only grasp a little when flooded with information. So happened with my recent purchase of Labyrinths of Reason: Paradoxes, Puzzles, and the Frailty of Knowledge. The book is about "scientific method" and its shortcomings. By scientific method, the author, William Poundstone, means beginning with a hypothesis and coming to some conclusion by experimentation and empirical evidence.

I have read quite a few chapters. So far, this is the best thing that I learned from the book (reproduced in my own words):
Suppose, I claim that no human being is longer than 100 feet. Since we don't know the exact details of how height of human beings is controlled, there is no direct proof of the statement. Naturally, we'll have to resolve to inductive reasoning. That is, each example that you see will strengthen your "belief" in the claim. You see Mr. A; ok, he is shorter than 100 feet. You see Mr. B; he is just 6 feet. He also confirms the hypothesis, and so on.

Now suppose that you see a 99 feet man (perhaps, in a circus). Theoretically, that should strengthen your belief in the hypothesis even further (as 99 < 100). But in practice, this example shakes your belief!

I have become a fan of William Poundstone. The first book of his that I came to read was How Would You Move Mount Fuji? Microsoft's Cult of the Puzzle. I bought it because I had heard that they ask weird puzzles in MS interviews. But I was pleasantly surprised to see that half of the book was on the history of the term IQ, the formation of the silicon valley (trust me, it's very interesting), and a general discussion on what puzzles show and what they can't.

Thursday, September 15, 2005

Being a Numbers Guy

"What is the length of a Boeing 747 airplane?" asked Saleem Mirza, Software Development Manager at Techlogix during my interview there. I was surprised at this question because we were having serious technical discussion till that point. I thought for a moment and replied, "100 meters." He enquired further, "Not more than that?" I was confused and stepped back, "I am not much into airplanes and flying."

Fast forward...A few days ago, I was reading Jon Bentley's Programming Pearls, a highly recommended book for programming interviews at various software companies, including Microsoft. The 7th chapter starts as,

It was in the middle of a fascinating conversation on software engineering that Bob Martin asked me, "How much water flows out of the Mississippi River in a day?"

What is the use of knowing such stuff? Nothing. Then why is it important to be able to answer such questions?

It's all about your ability to estimate within reasonable bounds: Suppose, I tell you that one of my friends is 9 feet tall. Instead of being amazed, most probably, you will exhibit disbelief. What if I tell you that Pakistan's software export is $6 billion? Your reaction should be the same because it's way beyond a reasonable value.

Good estimates result in better planning and they are the basis of fruitful discussion. If you could regard the above two statements as "unreasonable" it was probably due to some comparison that you immediately performed in your head. Perhaps, you know that the world's tallest man is less than 9 feet. Similarly, you probably know that India's total software export is $8.8 billion and Pakistan's figure should be a fraction of it. In fact, Pakistan's total export (not just software) is stated to be at $12 billion.

Ebay recently decided to buy Skype for $2.6 billion. This figure is actually too high. I double checked it before telling it to my friends. I was pleasantly surprised when some friends showed disbelief.

Knowing some standard figures is very important because that's what actually becomes a reference for comparison and helps you come up with an estimate. How high is the ceiling of your room? What time is it? How far is Karachi from Islamabad? Even if the exact answer is not known, one should try to give a good estimate.

It's dumb to state a figure in millions when it should be in billions, or vice versa. I'd have exhibited that much dumbness quite a few times. It's better to remain silent if you have so much confusion about what you are going to say. I believe estimation is amongst the things that one can improve with a little practice. Just try to remember when you come to know of a "standard statistic" and always do comparison before coming up with an estimate. The idea is even more important for software developers who are the worst when it comes to estimating time and effort.

Tuesday, August 23, 2005

Decision Procedures for Presburger Arithmetic

Note: This post will be edited as I learn more.

One of the results of Gödel's Incompleteness Theorem is that deciding the validity of arbitrary mathematical formulas is impossible. Here, deciding the validity means telling if "1 < 2" is true or false. Of course, the impossibility result is for arbitrary mathematical formulas and not for simple equalities and inequalities. If we could somehow restrict ourselves to simple formulas (which arise in practice), we might get a complete decision procedure.

Presburger Arithmetic is a first-order theory of natural numbers with addition. Though it doesn't support division amongst other things, it's of interest because it is decidable. Again, decidability means that we can build machines (or algorithms - doesn't make any difference) which, given a Presburger formula, correctly return "true" or "false" but never say "don't know".

Michael Norrish of ANU gives an overview of two such algorithms: Fourier-Motzkin Variable Elimination and Omega Test. John Harrison of Intel has provided a library of OCaml functions for automated theorem proving, which includes Cooper's algorithm.

I'll briefly cover how to use John Harrison's library and Omega Test as part of your system. My interest is in checking if a list of linear constraints has a solution or not. As an example, we'll see how to use these libraries to check

exists y. y > 2 && y < 50;


John Harrison's OCaml Library


You need OCaml to interactively run or build an executable of this library. Unzip and un-tar the archive and build using "make." Once you have done that, you can run a set of examples by running "./example" built by the make process.

The .ml files in the package are dependent on each other. It's not easy to take a fragment out of it and compile that separately (unless you are a good Caml programmer). But you don't need to take out the needed fragments, either. You can make your own example file (example.ml) and re-build using "make." In my case, I changed example.ml to:

open Atp;;
open Format;;

let print_formula fm = formula_printer print_atom fm; print_newline();;
let result = integer_qelim << exists x. x > 2 /\ x < 50 >> in
print_formula result


If I run "./example" I get <<true>> at the console. Unfortunately, no documentation is available but there are several examples in the .ml files that can give you insight into how to use it.

There are several ways to integrate it with your software. The ugliest one is to write an example.ml that reads formulas from a text file (generated by your software) and invokes integer_qelim on it. The result can be written back to an output file. If you are using Java, you might be interested in CamlJava which provides an interface between Java and Caml using JNI and extern. I might try that out and post my experience.


Omega Test


I could compile Omega only with gcc 2.95 on a Solaris box. The later versions of gcc give errors. The project also seems to be abandoned but it's widely quoted at different places. You can get release 1.2 from here. Follow the following steps to compile:

make depend
make libomega.a
make libuniform.a
make libcode_gen.a
make oc


Omega works on sets and relations. The compiled executable (called Omega Calculator) can be found in omega/omega_calc/obj. It's built on top of Omega Library. Instead of using the calculator, you can invoke the library from your code as well, as this interface document explains.

I created a test.txt file with the following contents:

S := {[i] : i <= 50};
T := {[j] : j >= 20};

S intersection T;


And I could run the calculator on this file ("./oc test.txt") and get the following output:

Omega Calculator v1.2 (based on Omega Library 1.2, August, 2000):
# S := {[i] : i <= 50};
#
# T := {[j] : j >= 20};
#
# S intersection T;

{[In_1]: 20 <= In_1 <= 50}


As you can see the constraints have been combined. If they were unsatisfiable (such as contradictory constraints) you would have gotten:

Omega Calculator v1.2 (based on Omega Library 1.2, August, 2000):
# S := {[i] : i >= 50};
#
# T := {[j] : j <= 20};
#
# S intersection T;

{[In_1]: FALSE}


I hope there is a way of getting a "witness" back from these decision procedures.

Wednesday, July 20, 2005

Proving Loops with Loop Invariants

In continuation to the proof obligation posted last week, I decided to explore loop invariants. This means converting the for loop in the code to a while one. The new proof obligation is as follows:

\problem {
\<{ int[] a; int max; }\>
(
 (!a = null & a.length > 0) ->
 (
  \<{ 
   max = a[0];
   int k = 1;
   while (k < a.length) {
    if (a[k] > max) max = a[k];
    k++;
   }
  }\>
  \forall int i; (i < a.length & i >= 0 -> max >= a[i] )
 )
)
}


Now, this is much easier to prove if we can select a proper loop invariant. What is it that holds before the loop starts execution, remains true after each iteration and holds even after the loop termination? A good first attempt can be

\forall int i; (i >= 0 & i < k -> max >= a[i])


Again, the syntax is specific to KeY but the semantics are valid for any theorem prover for imperative languages. A stronger invariant can be more useful and in fact, in this particular example, the loop invariant can be strengthened to

k > 0 & k <= a.length & 
\forall int i; (i >= 0 & i < k -> max >= a[i])


There are two subcases (amongst others) generated by KeY when a loop invariant is used: Invariant Initially Valid and Body Preserves Invariant. Since we are dealing with necessity (signified by <code in angle brackets>), and not with just a possibility, we have to show termination of the loop as well. In other words, we have to show that the loop terminates and, after termination, the formula holds. Thus, the third case to prove is Termination.

Invariant Initially Valid:
 a.length >  0
==>
 \forall int i;  (i >= 0 & i <  1 -> a[0] >= a[i])


Body Preserves Invariant:
   _k >  0
 & _k <= a.length
 & \forall int i; 
     (i >= 0 & i <  _k -> _max >= a[i]),
 a.length >  0
==>
 {
   k:=_k,
   max:=_max}
   \[{method-frame(()): {
             if (k < a.length) {
                if (a[k] > max)
                   max=a[k];
                k++;
             }
       }
     }\] (\forall int i; (i >= 0 & i <  a.length -> max >= a[i])
  }


But termination is not easy to show unless we can somehow tell that something is gradually approaching towards a limit which will make the while statement false. This is where the concept of Variant is Decreasing comes in. In KeY, we can define that a.length - k is decreasing with each iteration of the loop. With the help of this statement (which of course, we have to prove separately), Termination subgoal takes the following form:

(a.length - _k) <= 0
==>
 {k:=_k,
  max:=_max}
  \<{
      while ( k < a.length ) {
         if (a[k]>max)
           max=a[k];
         k++;
      }
  }\> true


This is, of course, very easy to prove because of the premises of the implication; the loop will not execute at all and there is no statement after the loop, Hence, the termination. But while doing this, we have introduced a new sub goal: Variant is Decreasing. We have to prove that with each iteration of the loop a.length - k is actually decreasing. This subgoal has the following form:

 _k_1 >  0,
 _k_1 <= a.length,
 \forall int i;  (i >= 0 & i <  _k_1 -> _max_1 >= a[i]),
 {k:=_k_1}
   \<{method-frame(()): {
         var=k       }
     }\> var = TRUE,
 a.length >  0
==>
 {k:=_k_1,
   max:=_max_1,
   var_1:=a.length - _k_1}
   \<{
        if (a[k]>max)
          max=a[k];
        k++;
     }\> (a.length - k) <  var_1


It looks daunting but after symbolic execution of the code, it's pretty simple.

Once we have proved everything regarding the invariant, we can use the invariant to prove the real thing, which was the following first order logical formula:

\forall int i; (i < a.length & i >= 0 -> max >= a[i] )


Thus, the fourth case, called Use Case is something of the form

k > 0 & k <= a.length & 
\forall int i; (i >= 0 & i < k -> max >= a[i]) ==>
\forall int i; (i < a.length & i >= 0 -> max >= a[i] )


which is much easier to prove than the standalone formula that we initially had.




My affair with loop invariants was a very short one. Perhaps, I'll come back to these in future. At present, I'm moving on to manually injecting bugs in this code and trying to find them using KeY.

Saturday, May 14, 2005

Alice in Wonderland

There are good chances that you already know about Alice and her Wonderland. Perhaps, you saw the cartoon movie or read the book itself. Or perhaps you were made to read an excerpt from it as part of your textbook.

I read some part of the story during my school days (perhaps in 6th grade). I found it very stupid as it made no sense to me. There was no "moral of the story" that you learn at the end, like other stories for children. But years later I came to know about the author: Lewis Carroll (pen name). He was a mathematician!

I couldn't believe that somebody good at logic could write a story like this. More years passed and I happened to come across a few passages from the story. Here is one for your reading pleasure:

"Would you tell me, please, which way I ought to go from here?"

"That depends a good deal on where you want to get to," said the Cat.

"I don't much care where --" said Alice.

"Then it doesn't much matter which way you go," said the Cat.

"--- so long as I get somewhere," Alice added as an explanation.

"Oh, you're sure to do that," said the Cat, "if only you walk long enough."


I think this is a very well written anecdote. Some more years passed and I faced an interesting question in my Software Engineering Using Formal Methods course:

Given that
Some pillows are soft.
No sticks are soft.

Which one of these can you conclude?
(a) Some pillows are not sticks.
(b) Some sticks are not pillows.


It's a slightly modified form of a puzzle by Lewis Carroll. It's a very interesting exercise to solve this puzzle. I'll tell the answer in comments and some hints on how to solve such things.

Now, I was pretty sure that though Alice's Adventures in Wonderland (that's the original name) is for children but it's not that stupid. Fortunately, the complete work is available as part of Project Gotenburg.

Lastly, here is another excerpt from the story:

"I couldn't afford to learn it." said the Mock Turtle with a sigh. "I only took the regular course."

"What was that?" inquired Alice.

"Reeling and Writhing, of course, to begin with," the Mock Turtle replied; "and then the different branches of Arithmetic-- Ambition, Distraction, Uglification, and Derision."

"I never heard of Uglification," Alice ventured to say. "What is it?"

The Gryphon lifted up both its paws in surprise. "What! Never heard of uglifying!" it exclaimed. "You know what to beautify is, I suppose?"


What baffles me is, "how on earth do children enjoy this story?" It's really for grown up people who can understand the satire, the logic and the paradox referred to. Now, I really want to meet those kids who like this story and ask them what's interesting in it for them.

Or perhaps, it's the parents who don't understand anything out of it and then think that it might be very funny for their children.