Illogical Engineers
“Those who cannot remember the past are
condemned to repeat it.”
Software engineers
“Software Engineering”
7th-11th Oct 1968
50
years ago
50years ago
“A software system can best be designed if
the testing is interlaced with the designing
instead of being used after the design.”
“The good systems that are presently working
were written by small groups. More than
twenty programmers working on a project is
usually disastrous.”
"I bought my boss two
copies of The
Mythical Man Month
so that he could read
it twice as fast."
“The reason that small groups have succeeded (...) is
that there is a need for a certain structure of
communication, and a structure of decision making in
the development of software. This succeeds with small
groups, because it can all be done intuitively by one
person serving as most of the network. For large groups
to succeed, we (...) have to face organizational
structure for communications and decisions.”
How to design successful software?
1. Flowchart until you think you understand the problem.
1. Flowchart until you think you understand the problem.
2. Write code until you realize that you don’t.
1. Flowchart until you think you understand the problem.
2. Write code until you realize that you don’t.
3. Go back and re-do the flowchart.
1. Flowchart until you think you understand the problem.
2. Write code until you realize that you don’t.
3. Go back and re-do the flowchart.
4. Write some more code and iterate to what you feel is the
correct solution.
How to design successful software?
“Design and implementation proceeded in a
number of stages. Each stage was typified by
a period of intellectual activity followed by a
period of program reconstruction”
“Each stage produced a usable product and
the period between the end of one stage and
the start of the next provided the operational
experience upon which the next design was
based.”
“In general the products of successive stages
approached the final design requirement;
each stage included more facilities than the
last.”
“Selig’s picture requires a feedback loop, for
monitoring of the system. One must collect
data on system performance, for use in future
improvements.”
Speaking about waterfall...
“I believe in this concept, but the implementation described above is
risky and invites failure. The testing phase which occurs at the end of
the development cycle is the first event for which timing, storage,
input/output transfers, etc., are experienced as distinguished from
analyzed. (...) then invariably a major redesign is required. A simple (...)
redo of some isolated code will not fix these kinds of difficulties. The
required design changes are likely to be so disruptive that the software
requirements upon which the design is based and which provides the
rationale for everything are violated. Either the requirements must be
modified, or a substantial change in the design is required. In effect the
development process has returned to the origin and one can expect up
to a lO0% overrun in schedule and/or costs.”
“Royce's 1970 paper is generally considered
to be the paper which defined the stagewise
"waterfall" model of the software process. But
it is surprising to see that (...) he already
incorporates prototyping as an essential step
compatible with the waterfall model.”
“The earlier Benington and Hosier papers had
good approximations to the waterfall model,
and that Royce's paper”
"Pitfalls and Safeguards in Real-Time Digital
Systems with Emphasis on Programming"
W.A. Hosier, 1961
"Production of Large Computer Programs”
H.D. Benington, June 1956.
http://gildingandcompany.co.uk/pegasus-computer-from-1956-the-passage-of-time/
“As soon as specifications a system program
are definitive, contractors should begin to
consider how they will verify the program's
meeting of the specifications.“
“"A requirements spec was generated. It has a
number of untestable requirements, with
phrases like 'appropriate response' all too
common. The design review took weeks, yet
still retained the untestable requirements."
“Software Process Management: Lessons
Learned From History”
Barry W. Boehm, 1987
“There are 2 hard problems in computer
science:
“There are 2 hard problems in computer
science: cache invalidation
“There are 2 hard problems in computer
science: cache invalidation and naming things
“There are 2 hard problems in computer
science: cache invalidation, naming things,
and off-by-1 errors.
“There are 2 hard problems in computer
science: cache invalidation, naming things,
and off-by-1 errors.
Microservices
Microservices
What is a microservice?
Microservices
What is a difference between Microservices and SOA?
“When we've talked about microservices a common
question is whether this is just Service Oriented
Architecture (SOA) that we saw a decade ago. (...) The
problem, however, is that SOA means too many different
things, (...) the fact that SOA means such different things
means it's valuable to have a term that more crisply defines
this architectural style.” -- Martin Fowler
“Alexander Pasik, a former analyst at Gartner, coined
the term SOA. (...) Pasik was driven to create term SOA
because “client/server” had lost its classical meaning.”
from “SOA in Practice: The Art of Distributed System Design” by Nicolai M. Josuttis
“The common notion that Gartner Group
invented SOA is simply absurd. (...) the
underlying approach to distributed computing
was invented at least 15 years earlier.”
Are the problems being
addressed and solved?
Software Engineer?
Software Craftsman
What does it mean to be a software engineer?
“The phrase ‘software engineering’ was
deliberately chosen as being provocative, in
implying the need for software manufacture
to be based on the types of theoretical
foundations and practical disciplines, that are
traditional in the established branches of
engineering.”
“The phrase ‘software engineering’ was
deliberately chosen as being provocative, in
implying the need for software manufacture
to be based on the types of theoretical
foundations and practical disciplines, that are
traditional in the established branches of
engineering.”
Towards engineering!
Towards engineering!
● Type System matters
Towards engineering!
● Type System matters
● Functional Programming is our lord and saviour
Towards engineering!
● Type System matters
● Functional Programming is our lord and saviour
○ statically typed
○ dependently typed
○ total
Towards engineering!
● Type System matters
● Functional Programming is our lord and saviour
○ statically typed
○ dependently typed
○ total
● Recognising Computer Science roots in math is essential to
write correct software
if (a = 10) {
...
} else {
// will never be executed, variable a is changed!
}
The “beauty” of C++
Compiles!
And that’s a
bad thing
val a: Int = 10
if(a == “10”) “ten” else “sth else”
val a: Int = 10
“sth else”
val a: Int = 10
if(a == “10”) “ten” else “sth else”
trait Eq[A] {
def ===(a1: A)(a2: A): Boolean
}
val a: Int = 10
if(a == “10”) “ten” else “sth else”
trait Eq[A] {
def ===(a1: A)(a2: A): Boolean
}
val a: Int = 10
if(a === “10”) “ten” else “sth else”
trait Eq[A] {
def ===(a1: A)(a2: A): Boolean
}
val a: Int = 10
if(a === “10”) “ten” else “sth else”
Doesn’t
compile
trait Eq[A] {
def ===(a1: A)(a2: A): Boolean
}
val a: Int = 10
if(a === “10”) “ten” else “sth else”
Doesn’t
compile
and that’s a goodthing!
Let's play a
game
/** Concatenate two maps. Keys from both maps must be
* included. If keys collide, add values together. */
def concat(
map1: Map[String, Int],
map2: Map[String, Int]
): Map[String, Int] = ???
00:59
00:58
00:57
00:56
/** Concatenate two maps. Keys from both maps must be
* included. If keys collide, add values together. */
def concat(
map1: Map[String, Int],
map2: Map[String, Int]
): Map[String, Int] = ???
/** Concatenate two maps. Keys from both maps must be
* included. If keys collide, add values together. */
def concat(
map1: Map[String, Option[(Int, Option[FinancialReport])],
map2: Map[String, Option[(Int, Option[FinancialReport])]
): Map[String, Option[(Int, Option[FinancialReport])] = ???
00:27
00:26
00:25
00:25
trait Semigroup[A] {
def |+|(a1: A, a2: A): A
}
trait Semigroup[A] {
def |+|(a1: A, a2: A): A
}
trait Semigroup {
def pairS[A, B]: Semigroup[(A, B)] = ???
}
trait Semigroup[A] {
def |+|(a1: A, a2: A): A
}
trait Semigroup {
def pairS[A:Semigroup, B:Semigroup]: Semigroup[(A, B)] = ...
}
trait Semigroup[A] {
def |+|(a1: A, a2: A): A
}
trait Semigroup {
def pairS[A:Semigroup, B:Semigroup]: Semigroup[(A, B)] = ...
def optionS[A:Semigroup]: Semigroup[Option[A]] = ...
}
trait Semigroup[A] {
def |+|(a1: A, a2: A): A
}
trait Semigroup {
def pairS[A:Semigroup, B:Semigroup]: Semigroup[(A, B)] = ...
def optionS[A:Semigroup]: Semigroup[Option[A]] = ...
def mapS[A, B:Semigroup]: Semigroup[Map[A,B]] = ...
}
/** Concatenate two maps. Keys from both maps must be
* included. If keys collide, add values together. */
def concat(
m1: Map[String, Option[(Int, Option[FinancialReport])],
m2: Map[String, Option[(Int, Option[FinancialReport])]
): Map[String, Option[(Int, Option[FinancialReport])] = ???
/** Concatenate two maps. Keys from both maps must be
* included. If keys collide, add values together. */
def concat(
m1: Map[String, Option[(Int, Option[FinancialReport])],
m2: Map[String, Option[(Int, Option[FinancialReport])]
): Map[String, Option[(Int, Option[FinancialReport])] = m1 |+| m2
If it compiles, it works!
Can I prove correctness of
my program?
Can code be generated
from types?
Can I prove that my
program will terminate?
Curry–Howard
correspondence
Propositions as types, proofs as programs.
The Curry–Howard correspondence is the
observation that two families of seemingly
unrelated formalisms—namely, the proof
systems on one hand, and the models of
computation on the other—are in fact the
same kind of mathematical objects.
Curry–Howard correspondence
Proposition ≡ Type
Proof ≡ Program
Propositional Logic
∧ AND
∨ OR
→ IMPLIES
¬ NOT
Predicate Logic
∧ AND
∨ OR
→ IMPLIES
¬ NOT
∀ FOR ALL
∃ EXISTS
Constructive Logic (Intuitionistic Logic)
In mathematics, a constructive
proof is a method of proof that
demonstrates the existence of
a mathematical object by
creating or providing a method
for creating the object.
Constructive Logic (Intuitionistic Logic)
Constructive Logic (Intuitionistic Logic)
Constructive Logic (Intuitionistic Logic)
Constructive Logic (Intuitionistic Logic)
Constructive Logic (Intuitionistic Logic)
Constructive Logic (Intuitionistic Logic)
Constructive Logic (Intuitionistic Logic)
P ∨ ¬P
P → ¬¬P
Constructive Logic (Intuitionistic Logic)
P ∨ ¬P
P → ¬¬P
Curry–Howard correspondence
Proposition ≡ Type
Proof ≡ Program
Prove that:
P ∧ (Q ∨ R) → (P ∧ Q) ∨ (P ∧ R)
Prove that:
P ∧ (Q ∨ R) → (P ∧ Q) ∨ (P ∧ R)
X ∧ Y (X, Y)
Prove that:
P ∧ (Q ∨ R) → (P ∧ Q) ∨ (P ∧ R)
X ∧ Y (X, Y)
X ∨ Y X + Y
Prove that:
P ∧ (Q ∨ R) → (P ∧ Q) ∨ (P ∧ R)
X ∧ Y (X, Y)
X ∨ Y Either[X, Y]
Prove that:
P ∧ (Q ∨ R) → (P ∧ Q) ∨ (P ∧ R)
X ∧ Y (X, Y)
X ∨ Y Either[X, Y]
X → Y X => Y
Prove that:
P ∧ (Q ∨ R) → (P ∧ Q) ∨ (P ∧ R)
def proof[P, Q, R]: (P, Either[Q, R]) => Either[(P, Q), (P, R)] = ???
Prove that:
P ∧ (Q ∨ R) → (P ∧ Q) ∨ (P ∧ R)
def proof[P, Q, R]: (P, Either[Q, R]) => Either[(P, Q), (P, R)] = ???
Prove that:
P ∧ (Q ∨ R) → (P ∧ Q) ∨ (P ∧ R)
def proof[P, Q, R]: (P, Either[Q, R]) => Either[(P, Q), (P, R)] = ???
Prove that:
P ∧ (Q ∨ R) → (P ∧ Q) ∨ (P ∧ R)
def proof[P, Q, R]: (P, Either[Q, R]) => Either[(P, Q), (P, R)] =
(input: (P, Either[Q, R])) => input match {
case (p, Left(q)) => Left((p, q))
case (p, Right(r)) => Right((p, r))
}
Prove that:
P ∧ (Q ∨ R) → (P ∧ Q) ∨ (P ∧ R)
def proof[P, Q, R]: (P, Either[Q, R]) => Either[(P, Q), (P, R)] =
(input: (P, Either[Q, R])) => input match {
case (p, Left(q)) => Left((p, q))
case (p, Right(r)) => Right((p, r))
}
So why can’t we prove?
P ∨ ¬P
So why can’t we prove?
P ∨ ¬P
¬P P => “False”
So why can’t we prove?
P ∨ ¬P
¬P P => Nothing
So why can’t we prove?
P ∨ ¬P
¬P P => Nothing
def proof[P]: Either[P, P => Nothing] = ???
What’s the point of all this?
Computer Science is my
rooted in Math
“We must know! We will know!”
While the roots of formalised logic go back to
Aristotle, the end of the 19th and early 20th
centuries saw the development of modern logic and
formalised mathematics.
“We must know! We will know!”
Question: could you derive all
mathematical truth using axioms and
inference rules of formal logic, in principle
opening up the process to automatisation?
“We must know! We will know!”
In 1929, Mojżesz Presburger showed that the theory
of natural numbers with addition is decidable and
gave an algorithm that could determine if a given
sentence in the language was true or false.
“We must know! We will know!”
“Bertrand Russell and Alfred Whitehead set out to
do something amazing.”
“Starting with just basic axioms of set theory, tried
to build complete edifice of mathematics as one
system, published as Principia Mathematica.”
Kurt Gödel
“On Formally Undecidable Propositions of
Principia Mathematica and Related
Systems” (1931)
Incompleteness theorem
Kurt Gödel proved that for any system which
is at least as powerful to represent simple
arithmetic: either your system is incomplete
(i.e. cannot prove its own axioms) or it is
inconsistent (i.e. can derive a contradiction)
Kurt Gödel proved that for any system which
is at least as powerful to represent simple
arithmetic: either your system is incomplete
(i.e. cannot prove its own axioms) or it is
inconsistent (i.e. can derive a contradiction)
def identity[A](a: A): A = a
def willProveAnything[A]: A = ???
def willProveAnything[A]: A = null
def willProveAnything[A]: A = throw RuntimeException(“ha!”)
def willProveAnything[A]: A = willProveAnything
Kurt Gödel proved that for any system which
is at least as powerful to represent simple
arithmetic: either your system is incomplete
(i.e. cannot prove its own axioms) or it is
inconsistent (i.e. can derive a contradiction)
Kurt Gödel proved that for any system which
is at least as powerful to represent simple
arithmetic: either your system is incomplete
(i.e. cannot prove its own axioms) or it is
inconsistent (i.e. can derive a contradiction)
Automated Theorem Prover
It follows that an automated theorem prover will fail to
terminate while searching for a proof precisely when the
statement being investigated is undecidable in the theory being
used. Despite this theoretical limit, in practice, theorem provers
can solve many hard problems, even in models that are not fully
described by any first order theory.
Chymyst/curryhoward
https://github.com/Chymyst/curryhoward
Before we finish...
The End
Pawel Szulc
Pyrofex
@rabbitonweb
http://rabbitonweb.com
paul.szulc@gmail.com

Illogical engineers

  • 1.
    Illogical Engineers “Those whocannot remember the past are condemned to repeat it.”
  • 2.
  • 3.
  • 8.
  • 9.
  • 10.
    “A software systemcan best be designed if the testing is interlaced with the designing instead of being used after the design.”
  • 11.
    “The good systemsthat are presently working were written by small groups. More than twenty programmers working on a project is usually disastrous.”
  • 12.
    "I bought myboss two copies of The Mythical Man Month so that he could read it twice as fast."
  • 13.
    “The reason thatsmall groups have succeeded (...) is that there is a need for a certain structure of communication, and a structure of decision making in the development of software. This succeeds with small groups, because it can all be done intuitively by one person serving as most of the network. For large groups to succeed, we (...) have to face organizational structure for communications and decisions.”
  • 14.
    How to designsuccessful software?
  • 15.
    1. Flowchart untilyou think you understand the problem.
  • 16.
    1. Flowchart untilyou think you understand the problem. 2. Write code until you realize that you don’t.
  • 17.
    1. Flowchart untilyou think you understand the problem. 2. Write code until you realize that you don’t. 3. Go back and re-do the flowchart.
  • 18.
    1. Flowchart untilyou think you understand the problem. 2. Write code until you realize that you don’t. 3. Go back and re-do the flowchart. 4. Write some more code and iterate to what you feel is the correct solution.
  • 19.
    How to designsuccessful software?
  • 20.
    “Design and implementationproceeded in a number of stages. Each stage was typified by a period of intellectual activity followed by a period of program reconstruction”
  • 21.
    “Each stage produceda usable product and the period between the end of one stage and the start of the next provided the operational experience upon which the next design was based.”
  • 22.
    “In general theproducts of successive stages approached the final design requirement; each stage included more facilities than the last.”
  • 24.
    “Selig’s picture requiresa feedback loop, for monitoring of the system. One must collect data on system performance, for use in future improvements.”
  • 25.
  • 28.
    “I believe inthis concept, but the implementation described above is risky and invites failure. The testing phase which occurs at the end of the development cycle is the first event for which timing, storage, input/output transfers, etc., are experienced as distinguished from analyzed. (...) then invariably a major redesign is required. A simple (...) redo of some isolated code will not fix these kinds of difficulties. The required design changes are likely to be so disruptive that the software requirements upon which the design is based and which provides the rationale for everything are violated. Either the requirements must be modified, or a substantial change in the design is required. In effect the development process has returned to the origin and one can expect up to a lO0% overrun in schedule and/or costs.”
  • 29.
    “Royce's 1970 paperis generally considered to be the paper which defined the stagewise "waterfall" model of the software process. But it is surprising to see that (...) he already incorporates prototyping as an essential step compatible with the waterfall model.”
  • 30.
    “The earlier Beningtonand Hosier papers had good approximations to the waterfall model, and that Royce's paper”
  • 31.
    "Pitfalls and Safeguardsin Real-Time Digital Systems with Emphasis on Programming" W.A. Hosier, 1961
  • 32.
    "Production of LargeComputer Programs” H.D. Benington, June 1956.
  • 33.
  • 34.
    “As soon asspecifications a system program are definitive, contractors should begin to consider how they will verify the program's meeting of the specifications.“
  • 35.
    “"A requirements specwas generated. It has a number of untestable requirements, with phrases like 'appropriate response' all too common. The design review took weeks, yet still retained the untestable requirements."
  • 36.
    “Software Process Management:Lessons Learned From History” Barry W. Boehm, 1987
  • 37.
    “There are 2hard problems in computer science:
  • 38.
    “There are 2hard problems in computer science: cache invalidation
  • 39.
    “There are 2hard problems in computer science: cache invalidation and naming things
  • 40.
    “There are 2hard problems in computer science: cache invalidation, naming things, and off-by-1 errors.
  • 41.
    “There are 2hard problems in computer science: cache invalidation, naming things, and off-by-1 errors.
  • 42.
  • 43.
  • 44.
    Microservices What is adifference between Microservices and SOA?
  • 45.
    “When we've talkedabout microservices a common question is whether this is just Service Oriented Architecture (SOA) that we saw a decade ago. (...) The problem, however, is that SOA means too many different things, (...) the fact that SOA means such different things means it's valuable to have a term that more crisply defines this architectural style.” -- Martin Fowler
  • 46.
    “Alexander Pasik, aformer analyst at Gartner, coined the term SOA. (...) Pasik was driven to create term SOA because “client/server” had lost its classical meaning.” from “SOA in Practice: The Art of Distributed System Design” by Nicolai M. Josuttis
  • 48.
    “The common notionthat Gartner Group invented SOA is simply absurd. (...) the underlying approach to distributed computing was invented at least 15 years earlier.”
  • 49.
    Are the problemsbeing addressed and solved?
  • 50.
  • 51.
  • 53.
    What does itmean to be a software engineer?
  • 54.
    “The phrase ‘softwareengineering’ was deliberately chosen as being provocative, in implying the need for software manufacture to be based on the types of theoretical foundations and practical disciplines, that are traditional in the established branches of engineering.”
  • 55.
    “The phrase ‘softwareengineering’ was deliberately chosen as being provocative, in implying the need for software manufacture to be based on the types of theoretical foundations and practical disciplines, that are traditional in the established branches of engineering.”
  • 56.
  • 57.
  • 58.
    Towards engineering! ● TypeSystem matters ● Functional Programming is our lord and saviour
  • 59.
    Towards engineering! ● TypeSystem matters ● Functional Programming is our lord and saviour ○ statically typed ○ dependently typed ○ total
  • 60.
    Towards engineering! ● TypeSystem matters ● Functional Programming is our lord and saviour ○ statically typed ○ dependently typed ○ total ● Recognising Computer Science roots in math is essential to write correct software
  • 62.
    if (a =10) { ... } else { // will never be executed, variable a is changed! } The “beauty” of C++ Compiles! And that’s a bad thing
  • 63.
    val a: Int= 10 if(a == “10”) “ten” else “sth else”
  • 64.
    val a: Int= 10 “sth else”
  • 65.
    val a: Int= 10 if(a == “10”) “ten” else “sth else”
  • 66.
    trait Eq[A] { def===(a1: A)(a2: A): Boolean } val a: Int = 10 if(a == “10”) “ten” else “sth else”
  • 67.
    trait Eq[A] { def===(a1: A)(a2: A): Boolean } val a: Int = 10 if(a === “10”) “ten” else “sth else”
  • 68.
    trait Eq[A] { def===(a1: A)(a2: A): Boolean } val a: Int = 10 if(a === “10”) “ten” else “sth else” Doesn’t compile
  • 69.
    trait Eq[A] { def===(a1: A)(a2: A): Boolean } val a: Int = 10 if(a === “10”) “ten” else “sth else” Doesn’t compile and that’s a goodthing!
  • 70.
  • 72.
    /** Concatenate twomaps. Keys from both maps must be * included. If keys collide, add values together. */ def concat( map1: Map[String, Int], map2: Map[String, Int] ): Map[String, Int] = ???
  • 73.
  • 74.
  • 75.
  • 76.
  • 78.
    /** Concatenate twomaps. Keys from both maps must be * included. If keys collide, add values together. */ def concat( map1: Map[String, Int], map2: Map[String, Int] ): Map[String, Int] = ???
  • 79.
    /** Concatenate twomaps. Keys from both maps must be * included. If keys collide, add values together. */ def concat( map1: Map[String, Option[(Int, Option[FinancialReport])], map2: Map[String, Option[(Int, Option[FinancialReport])] ): Map[String, Option[(Int, Option[FinancialReport])] = ???
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
    trait Semigroup[A] { def|+|(a1: A, a2: A): A }
  • 85.
    trait Semigroup[A] { def|+|(a1: A, a2: A): A } trait Semigroup { def pairS[A, B]: Semigroup[(A, B)] = ??? }
  • 86.
    trait Semigroup[A] { def|+|(a1: A, a2: A): A } trait Semigroup { def pairS[A:Semigroup, B:Semigroup]: Semigroup[(A, B)] = ... }
  • 87.
    trait Semigroup[A] { def|+|(a1: A, a2: A): A } trait Semigroup { def pairS[A:Semigroup, B:Semigroup]: Semigroup[(A, B)] = ... def optionS[A:Semigroup]: Semigroup[Option[A]] = ... }
  • 88.
    trait Semigroup[A] { def|+|(a1: A, a2: A): A } trait Semigroup { def pairS[A:Semigroup, B:Semigroup]: Semigroup[(A, B)] = ... def optionS[A:Semigroup]: Semigroup[Option[A]] = ... def mapS[A, B:Semigroup]: Semigroup[Map[A,B]] = ... }
  • 89.
    /** Concatenate twomaps. Keys from both maps must be * included. If keys collide, add values together. */ def concat( m1: Map[String, Option[(Int, Option[FinancialReport])], m2: Map[String, Option[(Int, Option[FinancialReport])] ): Map[String, Option[(Int, Option[FinancialReport])] = ???
  • 90.
    /** Concatenate twomaps. Keys from both maps must be * included. If keys collide, add values together. */ def concat( m1: Map[String, Option[(Int, Option[FinancialReport])], m2: Map[String, Option[(Int, Option[FinancialReport])] ): Map[String, Option[(Int, Option[FinancialReport])] = m1 |+| m2
  • 91.
    If it compiles,it works!
  • 92.
    Can I provecorrectness of my program?
  • 93.
    Can code begenerated from types?
  • 94.
    Can I provethat my program will terminate?
  • 95.
  • 96.
    The Curry–Howard correspondenceis the observation that two families of seemingly unrelated formalisms—namely, the proof systems on one hand, and the models of computation on the other—are in fact the same kind of mathematical objects.
  • 97.
  • 98.
    Propositional Logic ∧ AND ∨OR → IMPLIES ¬ NOT
  • 99.
    Predicate Logic ∧ AND ∨OR → IMPLIES ¬ NOT ∀ FOR ALL ∃ EXISTS
  • 100.
    Constructive Logic (IntuitionisticLogic) In mathematics, a constructive proof is a method of proof that demonstrates the existence of a mathematical object by creating or providing a method for creating the object.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
    Constructive Logic (IntuitionisticLogic) P ∨ ¬P P → ¬¬P
  • 108.
    Constructive Logic (IntuitionisticLogic) P ∨ ¬P P → ¬¬P
  • 109.
  • 110.
    Prove that: P ∧(Q ∨ R) → (P ∧ Q) ∨ (P ∧ R)
  • 111.
    Prove that: P ∧(Q ∨ R) → (P ∧ Q) ∨ (P ∧ R) X ∧ Y (X, Y)
  • 112.
    Prove that: P ∧(Q ∨ R) → (P ∧ Q) ∨ (P ∧ R) X ∧ Y (X, Y) X ∨ Y X + Y
  • 113.
    Prove that: P ∧(Q ∨ R) → (P ∧ Q) ∨ (P ∧ R) X ∧ Y (X, Y) X ∨ Y Either[X, Y]
  • 114.
    Prove that: P ∧(Q ∨ R) → (P ∧ Q) ∨ (P ∧ R) X ∧ Y (X, Y) X ∨ Y Either[X, Y] X → Y X => Y
  • 115.
    Prove that: P ∧(Q ∨ R) → (P ∧ Q) ∨ (P ∧ R) def proof[P, Q, R]: (P, Either[Q, R]) => Either[(P, Q), (P, R)] = ???
  • 116.
    Prove that: P ∧(Q ∨ R) → (P ∧ Q) ∨ (P ∧ R) def proof[P, Q, R]: (P, Either[Q, R]) => Either[(P, Q), (P, R)] = ???
  • 117.
    Prove that: P ∧(Q ∨ R) → (P ∧ Q) ∨ (P ∧ R) def proof[P, Q, R]: (P, Either[Q, R]) => Either[(P, Q), (P, R)] = ???
  • 118.
    Prove that: P ∧(Q ∨ R) → (P ∧ Q) ∨ (P ∧ R) def proof[P, Q, R]: (P, Either[Q, R]) => Either[(P, Q), (P, R)] = (input: (P, Either[Q, R])) => input match { case (p, Left(q)) => Left((p, q)) case (p, Right(r)) => Right((p, r)) }
  • 119.
    Prove that: P ∧(Q ∨ R) → (P ∧ Q) ∨ (P ∧ R) def proof[P, Q, R]: (P, Either[Q, R]) => Either[(P, Q), (P, R)] = (input: (P, Either[Q, R])) => input match { case (p, Left(q)) => Left((p, q)) case (p, Right(r)) => Right((p, r)) }
  • 120.
    So why can’twe prove? P ∨ ¬P
  • 121.
    So why can’twe prove? P ∨ ¬P ¬P P => “False”
  • 122.
    So why can’twe prove? P ∨ ¬P ¬P P => Nothing
  • 123.
    So why can’twe prove? P ∨ ¬P ¬P P => Nothing def proof[P]: Either[P, P => Nothing] = ???
  • 124.
    What’s the pointof all this?
  • 125.
    Computer Science ismy rooted in Math
  • 126.
    “We must know!We will know!” While the roots of formalised logic go back to Aristotle, the end of the 19th and early 20th centuries saw the development of modern logic and formalised mathematics.
  • 127.
    “We must know!We will know!” Question: could you derive all mathematical truth using axioms and inference rules of formal logic, in principle opening up the process to automatisation?
  • 128.
    “We must know!We will know!” In 1929, Mojżesz Presburger showed that the theory of natural numbers with addition is decidable and gave an algorithm that could determine if a given sentence in the language was true or false.
  • 129.
    “We must know!We will know!” “Bertrand Russell and Alfred Whitehead set out to do something amazing.” “Starting with just basic axioms of set theory, tried to build complete edifice of mathematics as one system, published as Principia Mathematica.”
  • 132.
    Kurt Gödel “On FormallyUndecidable Propositions of Principia Mathematica and Related Systems” (1931) Incompleteness theorem
  • 134.
    Kurt Gödel provedthat for any system which is at least as powerful to represent simple arithmetic: either your system is incomplete (i.e. cannot prove its own axioms) or it is inconsistent (i.e. can derive a contradiction)
  • 135.
    Kurt Gödel provedthat for any system which is at least as powerful to represent simple arithmetic: either your system is incomplete (i.e. cannot prove its own axioms) or it is inconsistent (i.e. can derive a contradiction)
  • 136.
  • 137.
  • 138.
  • 139.
    def willProveAnything[A]: A= throw RuntimeException(“ha!”)
  • 140.
    def willProveAnything[A]: A= willProveAnything
  • 141.
    Kurt Gödel provedthat for any system which is at least as powerful to represent simple arithmetic: either your system is incomplete (i.e. cannot prove its own axioms) or it is inconsistent (i.e. can derive a contradiction)
  • 142.
    Kurt Gödel provedthat for any system which is at least as powerful to represent simple arithmetic: either your system is incomplete (i.e. cannot prove its own axioms) or it is inconsistent (i.e. can derive a contradiction)
  • 143.
    Automated Theorem Prover Itfollows that an automated theorem prover will fail to terminate while searching for a proof precisely when the statement being investigated is undecidable in the theory being used. Despite this theoretical limit, in practice, theorem provers can solve many hard problems, even in models that are not fully described by any first order theory.
  • 144.
  • 157.
  • 161.