|
3 | 3 | "nbformat_minor": 0, |
4 | 4 | "metadata": { |
5 | 5 | "colab": { |
6 | | - "name": "03_recursion_and_induction.ipynb", |
| 6 | + "name": "04_logic.ipynb", |
7 | 7 | "provenance": [], |
8 | 8 | "collapsed_sections": [] |
9 | 9 | }, |
|
40 | 40 | " if int(str(2 ** n)[:2]) == 65:\n", |
41 | 41 | " print(f'2**{n}={2 ** n}')" |
42 | 42 | ], |
43 | | - "execution_count": 1, |
| 43 | + "execution_count": null, |
44 | 44 | "outputs": [ |
45 | 45 | { |
46 | 46 | "output_type": "stream", |
|
57 | 57 | "id": "7gJYRIxbR_Hy" |
58 | 58 | }, |
59 | 59 | "source": [ |
60 | | - "Here, we use $\\texttt{int(str(2 ** n)[:2])}$ to compute the first two digits \n", |
61 | | - "of $2^n$. Indeed, the function $\\texttt{str}$ converts the value of $2^n$ into a string, then the slice $\\texttt{[:2]}$ takes the first two characters of this string, and finally the function $\\texttt{int}$ converts the result back into an integer." |
| 60 | + "Here, we use `int(str(2 ** n)[:2])` to compute the first two digits \n", |
| 61 | + "of $2^n$. Indeed, the function `str` converts the value of $2^n$ into a string, then the slice `[:2]` takes the first two characters of this string, and finally the function `int` converts the result back into an integer." |
62 | 62 | ] |
63 | 63 | }, |
64 | 64 | { |
|
98 | 98 | " if not is_prime(n ** 2 + n + 41):\n", |
99 | 99 | " print(n)" |
100 | 100 | ], |
101 | | - "execution_count": 7, |
| 101 | + "execution_count": null, |
102 | 102 | "outputs": [ |
103 | 103 | { |
104 | 104 | "output_type": "stream", |
|
118 | 118 | "id": "Dren-X37VKmU" |
119 | 119 | }, |
120 | 120 | "source": [ |
121 | | - "Here, the function $\\texttt{is_prime}$ checks whether the given positive integer $n$ is prime simply by checking all its potential divisors $2 \\le d < n$ (recall that $n=1$ is not prime by convention).\n", |
| 121 | + "Here, the function `is_prime` checks whether the given positive integer $n$ is prime simply by checking all its potential divisors $2 \\le d < n$ (recall that $n=1$ is not prime by convention).\n", |
122 | 122 | "We then go through all $1 \\le n < 50$ and check if $n^2+n+41$ \n", |
123 | 123 | "is prime. If it is not, we print $n$.\n", |
124 | 124 | "\n", |
|
142 | 142 | "print(next(n for n in range(2, 100) if\n", |
143 | 143 | " not is_prime(n * n + n + 41)))\n" |
144 | 144 | ], |
145 | | - "execution_count": 9, |
| 145 | + "execution_count": null, |
146 | 146 | "outputs": [ |
147 | 147 | { |
148 | 148 | "output_type": "stream", |
|
181 | 181 | " if a ** 2 + b ** 2 == c ** 2:\n", |
182 | 182 | " print(f'{a}**2 + {b}**2 = {c}**2')" |
183 | 183 | ], |
184 | | - "execution_count": 10, |
| 184 | + "execution_count": null, |
185 | 185 | "outputs": [ |
186 | 186 | { |
187 | 187 | "output_type": "stream", |
|
202 | 202 | "id": "JeYfJUppWIPx" |
203 | 203 | }, |
204 | 204 | "source": [ |
205 | | - "This code enumerates all triples $1\\leq a \\le b \\le c < 20$ (by using the $\\texttt{combinations}$ function from the $\\texttt{itertools}$ module). \n", |
206 | | - "For each such triple, it checks whether $a^2+b^2=c^2$ (recall the $\\texttt{python}$ notation $\\texttt{a ** n}$ for $a^n$)." |
| 205 | + "This code enumerates all triples $1\\leq a \\le b \\le c < 20$ (by using the `combinations` function from the `itertools` module). \n", |
| 206 | + "For each such triple, it checks whether $a^2+b^2=c^2$ (recall the Python notation `a ** n` for $a^n$)." |
207 | 207 | ] |
208 | 208 | }, |
209 | 209 | { |
|
249 | 249 | "print(95800 ** 4 + 217519 ** 4 + 414560 ** 4)\n", |
250 | 250 | "print(422481 ** 4)" |
251 | 251 | ], |
252 | | - "execution_count": 11, |
| 252 | + "execution_count": null, |
253 | 253 | "outputs": [ |
254 | 254 | { |
255 | 255 | "output_type": "stream", |
|
288 | 288 | "\n", |
289 | 289 | "print(x ** 3 + y ** 3 + z ** 3)" |
290 | 290 | ], |
291 | | - "execution_count": 12, |
| 291 | + "execution_count": null, |
292 | 292 | "outputs": [ |
293 | 293 | { |
294 | 294 | "output_type": "stream", |
|
307 | 307 | "source": [ |
308 | 308 | "## Logic\n", |
309 | 309 | "\n", |
310 | | - "A *proposition* is a statement that is true or false. For example, `I'm a human` and `25 is a multiple of 7` are propositions (the first one is true, and the second one if false), while `You should fly to the Moon` is not a proposition. Using the language of mathematical logic, we create compound propositions from simple ones (\"$i\\geq0$ and $i\\leq n$ and $a[i]$ divides $100$, or $i$ is a prime\"). We use such propositions as conditions in $\\texttt{if}$-statemenets and $\\texttt{while}$-loops, and, thus, \"give directions\" to computer programs. Here are a few examples of propositions." |
| 310 | + "A *proposition* is a statement that is true or false. For example, *I'm a human* and *25 is a multiple of 7* are propositions (the first one is true, and the second one if false), while *You should fly to the Moon* is not a proposition. Using the language of mathematical logic, we create compound propositions from simple ones (\"$i\\geq0$ and $i\\leq n$ and $a[i]$ divides $100$, or $i$ is a prime\"). We use such propositions as conditions in `if`-statemenets and `while`-loops, and, thus, \"give directions\" to computer programs. Here are a few examples of propositions." |
311 | 311 | ] |
312 | 312 | }, |
313 | 313 | { |
|
324 | 324 | "print(3 < 5 and not(7 < 5))\n", |
325 | 325 | "print(2+2 == 5 or 2+2 == 4)\n" |
326 | 326 | ], |
327 | | - "execution_count": 13, |
| 327 | + "execution_count": null, |
328 | 328 | "outputs": [ |
329 | 329 | { |
330 | 330 | "output_type": "stream", |
|
343 | 343 | "id": "x76h0PHuwP9G" |
344 | 344 | }, |
345 | 345 | "source": [ |
346 | | - "In the following code, the function $\\texttt{foo}$ prints out \"Foo!\". One of the conditions in the $\\texttt{if}$-statement calls the function $\\texttt{foo}$. Why don't we see \"Foo!\" in the output of the program?" |
| 346 | + "In the following code, the function `foo` prints out \"Foo!\". One of the conditions in the `if`-statement calls the function `foo`. Why don't we see \"Foo!\" in the output of the program?" |
347 | 347 | ] |
348 | 348 | }, |
349 | 349 | { |
|
366 | 366 | "else:\n", |
367 | 367 | " print('False')" |
368 | 368 | ], |
369 | | - "execution_count": 14, |
| 369 | + "execution_count": null, |
370 | 370 | "outputs": [ |
371 | 371 | { |
372 | 372 | "output_type": "stream", |
|
383 | 383 | "id": "_ojnHiO6wC4h" |
384 | 384 | }, |
385 | 385 | "source": [ |
386 | | - "This is known as *lazy evaluation*. The $\\texttt{python}$ interpreter knows that the whole $\\texttt{if}$-condition evaluates to $\\texttt{False}$ after evaluating its first part. That is why it does not even bother to call the $\\texttt{foo()}$ function (so \"Foo!\" is not printed). Try changing the order of two statements in the $\\texttt{if}$-statement and see what happens!" |
| 386 | + "This is known as *lazy evaluation*. The Python interpreter knows that the whole `if`-condition evaluates to `False` after evaluating its first part. That is why it does not even bother to call the `foo()` function (so \"Foo!\" is not printed). Try changing the order of two statements in the `if`$-statement and see what happens!" |
387 | 387 | ] |
388 | 388 | }, |
389 | 389 | { |
|
392 | 392 | "id": "jBvsZgdexAgD" |
393 | 393 | }, |
394 | 394 | "source": [ |
395 | | - "The universal quantifier is a mathematical analogue of the function $\\texttt{all}$ in $\\texttt{python}$ that outputs $\\texttt{True}$ if all elements\n", |
396 | | - "in the list are $\\texttt{True}$. Similarly, the existential quantifier is \n", |
397 | | - "a mathematical formalization of the function $\\texttt{any}$ that outputs $\\texttt{True}$ if at least one of the elements in the list \n", |
398 | | - "is $\\texttt{True}$.\n", |
| 395 | + "The universal quantifier is a mathematical analogue of the function `{all}` in Python that outputs `True` if all elements\n", |
| 396 | + "in the list are `True`. Similarly, the existential quantifier is \n", |
| 397 | + "a mathematical formalization of the function `any` that outputs `True` if at least one of the elements in the list \n", |
| 398 | + "is `True`.\n", |
399 | 399 | "\n", |
400 | 400 | "For example, the following program verifies the following two statements with universal quantifiers: \n", |
401 | 401 | "\n", |
402 | | - "`All integers in ${6, 2, 4}$ are even` \n", |
| 402 | + "*All integers in ${6, 2, 4}$ are even*\n", |
403 | 403 | "\n", |
404 | 404 | "and \n", |
405 | 405 | "\n", |
406 | | - "`All integers in ${2, 7, 6}$ are even`.\n" |
| 406 | + "*All integers in ${2, 7, 6}$ are even*.\n" |
407 | 407 | ] |
408 | 408 | }, |
409 | 409 | { |
|
421 | 421 | "a = (2, 7, 6)\n", |
422 | 422 | "print(all((i % 2 == 0) for i in a))" |
423 | 423 | ], |
424 | | - "execution_count": 15, |
| 424 | + "execution_count": null, |
425 | 425 | "outputs": [ |
426 | 426 | { |
427 | 427 | "output_type": "stream", |
|
441 | 441 | "source": [ |
442 | 442 | "Similarly, the following code evaluates the statements with the existential quantifier \n", |
443 | 443 | "\n", |
444 | | - "`There is an even integer in ${1, 7, 9}$` \n", |
| 444 | + "*There is an even integer in $\\{1, 7, 9\\}$*\n", |
445 | 445 | "\n", |
446 | 446 | "and \n", |
447 | 447 | "\n", |
448 | | - "`There is an even integer in ${9, 2, 3}$`" |
| 448 | + "*There is an even integer in $\\{9, 2, 3\\}$*" |
449 | 449 | ] |
450 | 450 | }, |
451 | 451 | { |
|
463 | 463 | "a = (9, 2, 3)\n", |
464 | 464 | "print(any((i % 2 == 0) for i in a))" |
465 | 465 | ], |
466 | | - "execution_count": 16, |
| 466 | + "execution_count": null, |
467 | 467 | "outputs": [ |
468 | 468 | { |
469 | 469 | "output_type": "stream", |
|
483 | 483 | "source": [ |
484 | 484 | "The negation of a universal quantifier is an existential quantifier; and the negation of an existential quantifier is a universal quantifier. For example, the negation of the statement\n", |
485 | 485 | "\n", |
486 | | - "`For all $n, A(n)$ is true`\n", |
| 486 | + "*For all $n, \\, A(n)$ is true*\n", |
487 | 487 | "\n", |
488 | 488 | "is the statement \n", |
489 | 489 | "\n", |
490 | | - "`There exists $n$, such that $A(n)$ is false`." |
| 490 | + "*There exists $n$, such that $A(n)$ is false.*" |
491 | 491 | ] |
492 | 492 | }, |
493 | 493 | { |
|
509 | 509 | "print(not any([is_divisible_by_3(x) for x in lst]))\n", |
510 | 510 | "print(all([not is_divisible_by_3(x) for x in lst]))" |
511 | 511 | ], |
512 | | - "execution_count": 17, |
| 512 | + "execution_count": null, |
513 | 513 | "outputs": [ |
514 | 514 | { |
515 | 515 | "output_type": "stream", |
|
527 | 527 | "id": "5kQScsCL1rO2" |
528 | 528 | }, |
529 | 529 | "source": [ |
530 | | - "In this example, the function $\\texttt{is_divisible_by_3(x)}$ returns $\\texttt{True}$ or $\\texttt{False}$ when $\\texttt{x}$ is (or is not) a multiple of $3$. Here, $\\texttt{True}$ and $\\texttt{False}$ are *Boolean values*. We may want to check whether \n", |
531 | | - "a list $\\texttt{lst}$ of integers contains a multiple of $3$. For that, we use a special $\\texttt{python}$ construction. First, $\\texttt{[is_divisible_by_3(x) for x in lst]}$ is the list of Boolean values $\\texttt{is_divisible_by_3(x)}$ for all elements $\\texttt{x}$ in the list $\\texttt{lst}$. \n", |
| 530 | + "In this example, the function `is_divisible_by_3(x)` returns `True` or `False` when `x` is (or is not) a multiple of $3$. Here, `True` and `False` are *Boolean values*. We may want to check whether \n", |
| 531 | + "a list `lst` of integers contains a multiple of $3$. For that, we use a special Python construction. First, `[is_divisible_by_3(x) for x in lst]` is the list of Boolean values `is_divisible_by_3(x)` for all elements `x` in the list `lst`. \n", |
532 | 532 | "\n", |
533 | | - "In our example, $\\texttt{l=[5,17,6,10]}$, so this list equals $\\texttt{[False, False, True, False]}$ (only $6$ is divisible by $3$). Then, $\\texttt{any(S)}$ checks whether there exists a $\\texttt{True}$ value in $\\texttt{S}$, and $\\texttt{not}$ reverses the answer. This way, we evaluate the statement \"there is no element $\\texttt{x}$ in the list $\\texttt{lst}$ that is divisible by $3$\". \n", |
| 533 | + "In our example, `l=[5,17,6,10]`, so this list equals `[False, False, True, False]` (only $6$ is divisible by $3$). Then, `any(S)` checks whether there exists a `True` value in `S`, and `not` reverses the answer. This way, we evaluate the statement *there is no element `x` in the list `lst` that is divisible by $3$*. \n", |
534 | 534 | "\n", |
535 | | - "In the next line, we evaluate the statement \"all elements of $\\texttt{l}$ are not divisible by $3$\" and get the same answer $\\texttt{False}$: there is no good element in the list if and only if all elements are bad." |
| 535 | + "In the next line, we evaluate the statement *all elements of `l` are not divisible by $3$* and get the same answer `False`: there is no good element in the list if and only if all elements are bad." |
536 | 536 | ] |
537 | 537 | } |
538 | 538 | ] |
|
0 commit comments