Wednesday, 27 February 2013

Proofs: Simple Structures, Complicated Content

I just wanted to slog about how to generally start a proof and set it up/structure it. There is nothing more really to say about writing up proofs beyond that because each proof is unique and the meatiest part of the proof, finding the connections, is vastly different with each different proof.

The example I will be using (even though this example is covered in lecture, I want to go more in-depth, step-by-step):

"For every natural number n, n² odd implies that n is odd"

1. Decide whether you want to prove the statement or disprove the statement. Do this by using intuition or scribbling some cases you think will make the statement wrong. Basically look for some counter-examples.

Since I can't think of any odd numbers` that has an even root, I'm going to attempt to prove this.



2. Now you're ready to begin. Always start with the symbolic representation of the original statement of what you're trying to prove or disprove. After figuring out the symbolic representation of the statement, if you decided you want to disprove it, NEGATE the statement before proceeding with the next steps.

  • What does an odd natural number mean symbolically??? We'll have to refer to the symbolic definition of what it means to be an odd number by either looking it up on the internet, or finding it in the Course Notes.
  • We see that for a natural number to be odd, it means there exists a natural number where 2 multiplied by that natural number, plus one, equals to our odd number. Thus the symbolic statement would be:
∀n∋N, (∃ k∋N, n² = 2k + 1) ⇒ (∃ k₀∋N, n² = 2(k₀) + 1)
  • Since we want to prove this, then we don't need to negate it.

3. Now it's time to set up the structure for the proof, while leaving out the meat of it. While setting up the structure for a proof, you want to follow these guide lines:
  • Start from left to right of the symbolic statement
  • Whenever you have have a Universal Quantifier (∀), you want to assume there is a generic number of this set, and then proceed with the proof with everything below with one indent. After completing the structure and/or proof for all the proceeding elements after the universal quantifier, the whole statement after the universal quantifier, including the universal quantifier should be restated in conclusion form, aligned vertically with the original assumption line of this universal quantifier. 
    • Assume x∋Y     # x is a generic to introduce ∀ 
      • proceeding lines start here vertically (without a bullet obviously)
      •  
      • # ***Lines connecting the antecedent to the consequent ***
      •  

    • Then x∋Y................  # conclude for all x in Y
    • For our example:
      • Assume ∀n∋N     # n is a generic natural number to introduce ∀
        •  
        •  
        •  
      • Then  conclude ∀n∋N, (∃ k∋N, n² = 2k + 1) ⇒ (∃ k₀∋N, n² = 2(k₀) + 1)  # for all n in N
  • Whenever you have an Existential Quantifier (∃), you want to "pick" or "let" that number equal to something that you haven't decided yet, unless the existential is a part of your antecedent for a direct proof. So you want to have either:
    • pick x = _____ then x∋Y
    • or let x = _____ then x∋Y
    • For our example, since our existential is part of our antecedent for a direct proof, we don't pick until we get the the consequent part of our proof
  •  Whenever you get to an antecedent of an implication, you want to assume the antecedent is true and the lines proceeding the proof should be indented by one. The proceeding lines should be the meat of your proof where you show a connection from the antecedent to the consequent. Then, after these lines, the consequent should be stated. Then on the next line afterwards, the whole implication should be stated without the indent, thus lined back up with the antecedent vertically.
    • Assume x = y   # x = y is an example antecedent
      • proceeding lines start here vertically (without the bullet obviously)
      •  
      •  
      • then consequent 
    • Then x=y ⇒consequent
    • For our example:
      • Then ∃ k∋N, n² = 2k + 1
        •  
        •  
        •  
        • Then ∃ k₀∋N, n² = 2(k₀) + 1
      • Then (∃ k∋N, n² = 2k + 1) ⇒ (∃ k₀∋N, n² = 2(k₀) + 1)
  • Keep in mind that the meatiest part of the proof, the fruit of the proof, the most meaningful part of the proof, the hardest part of the proof, are the ***Lines connecting the antecedent to the consequent ***, from the antecedent assumption. Thus you can have this structure set up while leaving space for these lines.
4. If you suspect that your antecedent implies a conjunction, you may want to have different cases set up in your proof that follow the same structure guidelines.

5. Now that you have enough information to start, setup, and structure a proof, all you need is to figure out the hard part of connecting any antecedent to the consequent. In the case of just showing if a conjunction or disjunction is true, the same structure can be followed.
  • For our example:
    • Then ∃ k∋N, n² = 2k + 1
    • Then n² - 1 = 2k
    • Then (n + 1)(n - 1) = 2k
    • Then n = 2(k/(n+1)) + 1
    • Then let k₀ = (k/(n+1))
    • Then∃ k₀∋N, n² = 2(k₀) + 1

6. When concluding a disprove, state that the original statement is incorrect because you showed the negation to be true.

7. This is just a simple guide, there are many other things you may need to think of while proving such as should you take the contrapositive of the statement? Should you perform a direct proof? Should you perform an indirect proof? Should you prove by contradiction? Etc.

So he final product for our proof of ∀n∋N, (∃ k∋N, n² = 2k + 1) ⇒ (∃ k₀∋N, n² = 2(k₀) + 1)
is:

  • Assume ∀n∋N     # n is a generic natural number to introduce ∀
    • Then ∃ k∋N, n² = 2k + 1
      • Then n² - 1 = 2k
      • Then (n + 1)(n - 1) = 2k
      • Then n = 2(k/(n+1)) + 1
      • Then let k₀ = (k/(n+1))
      • Then∃ k₀∋N, n² = 2(k₀) + 1
      • Then ∃ k₀∋N, n² = 2(k₀) + 1
    • Then (∃ k∋N, n² = 2k + 1) ⇒ (∃ k₀∋N, n² = 2(k₀) + 1)
  • Then  conclude ∀n∋N, (∃ k∋N, n² = 2k + 1) ⇒ (∃ k₀∋N, n² = 2(k₀) + 1)  # for all n in N

So this would be a proper proof with proper structure (minus the bullet points on each line).

Hope someone finds this helpful!



Wednesday, 20 February 2013

Applying skills learned in CSC165

I found it very interesting that something we've learned from CSC165 was very useful and relevant to courses outside of CSC165. For example, in our CSC148 project, one of our tasks was to compare two sets of elements to see whether they had any elements in common.

After reading the instructions for this particular task my partners and I instantly thought of Venn Diagrams, sets, subsets, etc. We were conditioned on how to approach this question logically through CSC165. So basically, what it boiled down to, was that we had to create a class method that would check whether two sets had no elements in common. In regards to Venn Diagrams, this meant that there must be no overlapping elements in the two sets (no elements in the intersection of the two sets).

Thinking about this logically, like we were taught in CSC165, was not so difficult anymore. What was even more surprising was that we've made very similar functions in CSC165 lectures. We've made functions that addressed these exact questions and the functions involved List Comprehension!

We were taught how to understand and make use of list comprehension in CSC165, but not in CSC148, and now my partners and I had the opportunity to apply what we've learned from one course to the other. It was an exciting moment!

The best part of this experience was that the class method worked flawlessly with the list comprehension and the method's body was only a one-liner; return one list comprehension.

Now, here's what I was talking about:

The required method's docstring:
"Return True iff there are no elements in common between this multiset and the other multiset."

Our body for the function:
return True not in [item in other.multiset for item in self.multiset]


This way, our function looked a lot cleaner and a lot more lines of space were saved because we didn't have to create actual looks to make this function (which we would have done if we didn't know about list comprehensions).

Monday, 11 February 2013

Use LOGIC!


While going through the first test, in preparation for term-test #1, I found that Part B of the first question was pretty time consuming and a tad difficult. Since it is part of the first question and each sub-question(i, ii, iii, iv, v, vi) was only worth 1 mark, this indicated that these questions weren't supposed to be that difficult.

################################################################################
The question:

Recall these python functions from lecture:

def quant1(L1, L2): return False in [x in L2 for x in L1]
def quant2(L1, L2): return True in [x in L2 for x in L1]
def quant3(L1, L2): return False not in [x in L2 for x in L1]
def quant4(L1, L2): return True not in [x in L2 for x in L1]


Part(B)

For each output (i)-(vi), either devise lists L1 and L2 so that the python expression:
[quant1(L1, L2), quant2(L1, L2), quant3(L1, L2), quant4(L1, L2)]
evaluates to that output, or else explain why it is impossible to devise such lists.


(i) [T,F,T,F]
(ii) [T,F,F,T]
(iii) [T,T,F,F]
(iv) [F,T,F,T]
(v) [F,F,T,T]
(vi) [F,T,T,F]


################################################################################

I was wondering why I was taking so long with these questions that are assumed to be easy, so I spent some time trying to figure out what the problem was.

My first attempts at these questions, for each of the questions (i) - (vi), I didn't have an attack plan. I just jumped straight into the question, creating a small random list in my head, and then going through each of the 4 quants individually. Now that I think about it, that was kind of crazy. No wonder why I took so long. I was going through each function in my head, sometimes more than once for a question using a newly created list in my head, and I did this for each question the first time. Thus I ran over 4*6 functions using random made up lists in my head. That was such a waste of time! That definitely wasn't the method the prof had intended.

So then I kept trying to see whether there was a better method, an attack plan, something we've learned in lectures. Then I thought to myself that this is a logic course, and we've went over negations many times. So I went back to the quant functions and wrote comments to indicate what they predicate in English:


def quant1(L1, L2): return False in [x in L2 for x in L1]
## Means there exists an element in L1 that is not in L2

def quant2(L1, L2): return True in [x in L2 for x in L1]
## Means there exists an element in L1 that is also in L2

def quant3(L1, L2): return False not in [x in L2 for x in L1]
## Means all elements in L1 are in L2

def quant4(L1, L2): return True not in [x in L2 for x in L1]
## Means no elements in L1 are in L2

Now I can clearly see that quant1 and quant3 are negations of each other and quant2 and quant4 are negations of each other as well.

"What can I do with this information?" I thought to myself. Well, if some quants are negations of each other, then they both can't be True at the same time in each list. Now that was an easy way to find the impossible lists in (i) - (vi).

Now, thinking logically, it only makes sense that each list would have 2 Trues and 2 Falses in them. Also if any quant predicate is True, the negation quant predicate must be False, and vice versa. So now that eliminates having to go through each of the 4 quants in the list because you can trust that the negation of a quant is false if that quant is true.

So now, thanks to logic, I've developed an attack plan! All I had to do, after filtering out the impossible lists, was to find the quants corresponding to the Trues in the list and then generate a list that would satisfy the quants for them.

Now, with all this knowledge in mind derived from logic, all I had to do was eliminate the lists that have Trues for the quant and it's negation quant in the same list, then generate a list that would satisfy 2 quants.

Why didn't I think of this sooner?!?!

Since it took me a while to figure all this out, I'm guessing I didn't have a good grasp on logic and utilizing logic yet. This course is meant to teach you about logic and how to apply it and a lot of logic definitely applied in this question. Using logic, you can develop techniques for analyzing these types of questions swiftly. It was a good thing that I ran into these problems and figured out better ways to attack the problems because it really helped me with the actual term-test which had similar questions!



Also, for any TA or Professor reading my posts, I know they're pretty long and I apologize for that. I just like to ramble on and I feel that shorter posts aren't sufficient.

Sorry for making you guys read all this!

Wednesday, 30 January 2013

A Very Powerful Manipulation Rule

There is one manipulation rule that I feel is not emphasized enough (for me at least) and that is:


P ⇒ Q       ⇔     ¬P ∨ Q

To me, this is one of most powerful manipulation rules that is extremely important to know so I didn't just want to memorize it. I wanted to understand it.

At first, It was kind of hard to wrap my head around the idea that "If P is true, then Q must be true" is the exact same as "P is not true or Q is true." When trying to connect these two statements using English only, it felt kind of hard to visualize, for me at least.

So I ended up working out several different ways to try to grasp this idea logically.

First, I did the truth tables:

P
Q
P ⇒ Q 
¬P ∨ Q
T
T
T
T
T
F
F
F
F
T
T
T
F
F
T
T
After I did the truth tables, it was clearly evident that the implication and the logical disjunction statements were identical (according to the truth table). However, in terms of wording and a way of making English sense of it in my head, I was still not fully understanding this. So I continued:

Second, I did the Venn Diagram for both:

For P ⇒ Q : If P is true, then Q must be true, meaning there cannot be anything in the set of P where Q is not true, hence:

(Where P is the antecedent, Q is the consequent, and U is the universe. White is unoccupied)

For ¬P ∨ Q : Everything that is not P can be occupied and all of Q can be occupied, hence:

(Where P and Q are both predicates and U is the universe. White is unoccupied)

After creating the Venn Diagrams for both. It was starting to make a lot more sense. The Venn Diagrams are exactly the same. Since P implies Q means that "If P is true, then Q must be true" which means that there can't be any P's that aren't Q, then that would mean anything that's not P is fine. Also, if it's not P, then it doesn't matter what Q is for the implication as a whole to be true; vacuously. This is making a lot of sense. However, I still wanted to justify this some more!


Finally, I found negating the implication helped finalize my understanding of this manipulation rule:

First, "If P is true, then Q must be true" may be reworded with sets: "Every D that is also a P is also a Q" which would symbolically be:

∀x ∈ D, P(x) ⇒ Q(x)

So, if this was negated, the English would be "There exists a D that is also a P but is not Q." Symbolically:

∃x ∈ D, P(x) ∧ ¬Q(x)

So, I tried to negate the negation, to get back the original implication using De Morgan's Law:


¬(∃x ∈ D, P(x) ∧ ¬Q(x))

∀x ∈ D, ¬(P(x) ∧ ¬Q(x))

∀x ∈ D, (¬P ∨ Q)

Here I stopped and I didn't bother to change the disjunction back to an implication because I now saw that they are truly equivalent. This may have seemed like a roundabout way to get this the implication and disjunction stuck in your head, but this really helped me out! I thought to myself "I think I fully understand this concept now!"

Wednesday, 16 January 2013

Venn Diagram Madness............

I came across something confusing for CSC165 Tutorial Exercise #1:

Drawing a Venn Diagram that Falsifies statement
d) "There is one of the three python programs that fails all three test suites."

So to falsify the above statement, you'd have to create a Venn Diagram portraying a situation where all python programs pass at least one test suite. If a python program passes at least 1 test suite, then it is not in the set of python programs that "fails all three test suites". Thus all we have to show on the Venn Diagram is that all of the 3 python programs in set Q passes at least one test suite. So technically, the programs can exist anywhere in Q, either in the overlapping Q and T area or just the Q area itself since the Q area itself just represents python programs, not stating how many test suites they pass or fail. So I figured the diagram for this would be:

(**Where Q is the set of 3 python programs, T is the set of universal python programs that pass all 3 test suites, and P is the universe of python programs. Also, O represents area must be occupied, X represents area that must not be occupied, and ? represents area could be empty or occupied.)

However, this diagram does not really say anything definite about making the statement false. For example, since ? represents may be empty or may be occupied, let's say for example that the overlapping T and Q area was empty. Now all the python programs in Q are in the Q only region. In this case, we may have a situation that falsifies the above statement (if all the programs in Q passed at least one test) or we may also have a situation that does not falsify it (any one of the python programs may fail all 3 tests and still be in this region). So this diagram wouldn't be enough to falsify the above claim.

During the tutorial, the Venn Diagram that was presented in answer to d) false situation was:


This Venn Diagram makes sense in that it presents a situation where the statement would be false for sure (if all of the 3 python programs passes all 3 test suites, then there can't be any that failed all 3), but there was just something still bothering me about this diagram. The area in Q may be occupied, not necessarily must not be. This diagram presents one situation where the statement would be false, but not a general diagram showing how to make the statement false. I don't know if I'm conveying myself properly, sorry for the confusion. For example, let's consider the Venn Diagram portraying a False situation for a) "All three python programs that passes all test suites." The correct diagram is:



However, another situation that would make the a) statement False would be this Venn Diagram:


This diagram would show a situation where a) would be False but it wouldn't be the correct most general Venn Diagram.

This is the feeling I'm getting for the tutorial provided Venn Diagram. I feel as if there is another region needed to indicate either programs that passed at least 1 test suite or a region indicating programs that failed all test suite.

The good thing about this experience is that after writing this blog, my head is a lot more clear about this whole situation!


Friday, 11 January 2013

First time SLOGger

Hhhhhmmmmmmmmmmmm. This will be an internet milestone for me. This is not only my first time slogging, it's my first time doing anything related to blogging as well!

This will be interesting!