(*
  Load this file with "Isabelle FirstOrder.thy &"
*)

theory FirstOrder
imports Main
begin

section {* Prelude *}

text {* Provide syntax for <->. *}

syntax
  iff :: "[bool, bool] => bool" (infixr "<->" 25)
syntax (xsymbol)
  iff :: "[bool, bool] => bool" (infixr "\<longleftrightarrow>" 25)

translations
  "P <-> Q" => "P = Q"

typed_print_translation {*
  let
    fun iff_tr' _ (Type ("fun", (Type ("bool", _) :: _))) ts =
      Term.list_comb (Syntax.const "iff", ts)
      | iff_tr' _ _ _ = raise Match;
  in [("op =", iff_tr')] end
*}

text {* Provide rule names similar to those in Huth and Ryan's textbook. *}

theorems conjE1 = conjunct1
theorems conjE2 = conjunct2
theorem mp: "[| P; P --> Q |] ==> Q" by blast
theorems impE = mp
theorem notE: "[| P; ~P |] ==> False" by blast
theorem notnotE: "~ ~ P ==> P" by blast
theorem PBC: "(~ P ==> False) ==> P" by blast
theorems allE = spec


section {* Introduction *}

text {* This section assumes that you have read and understood
  Propositional.thy. *}

text {*
  First-order connectives:

                    ASCII     symbol    token, put between \ < and >

    for all:         ALL        \<forall>       forall
    there exists:    EX         \<exists>       exists
    equality         =


  Quantifier notation in Isabelle is different from the lecture.  One writes

    ALL x. P    instead of    ALL x P

  and the quantifier binds very weakly.  That is, you must write

    (ALL x. P(x) & Q(x))    instead of    ALL x (P(x) & Q(x)).

  Also notation for application of function and predicate symbols is different,
  in order to reduce the number of parentheses.  Write:

    P x y  instead of  P(x, y)  and  f x y  instead of  f(x, y)

  If arguments are not just variables but more complicated terms, use
  parantheses:

    P (f x y) y          stands for    P(f(x, y), y)
    P (f (g x)) (g x)    stands for    P(f(g(x)), g(x))
  *}


section {* First-Order Logic *}

subsection {* Natural Deduction Rules *}

text {* universal quantification *}
thm allI allE

text {* existential quantification *}
thm exI exE

text {* equality *}
thm refl subst


subsection {* Proofs *}

theorem "[| ALL x. P x --> Q x; ALL x. P x |] ==> ALL x. Q x"
  by blast

theorem "[| ALL x. P x --> Q x; EX x. P x |] ==> EX x. Q x"
  by blast


subsection {* Modelling *}

text {*
  Transsilvania is inhabited not only by truthful humans but also by
  vampires who always lie.  Not everybody knows that every second
  Transsilvanian, be it human or vampire, is insane.  These insanes
  believe true things to be wrong and false things correct.

  For example, all sane humans know that the earth is round.  The
  insane humans in contrast believe it is flat.  Sane vampires know
  about the globe but deny it is a sphere.  And the insane vampires,
  finally, believe that the earth is a disc but claim the opposite.

  On a journey through the Balkans in a suspicious area, Inspector
  Craig meet the girls Minna and Lucy.  He has been warned that one of
  the two belonged to the family of Dracula; which of the two he was
  unable to tell.

  Since after dusk Craig didn't want to get in trouble with vampires,
  he asked them: "Please tell me something about you!"

  Lucy: "We are both insane."

  Craig: "Is that true?"

  Minna: "Of course not!"

  With whom of the two did the inspector spend the evening?
*}

text {* Solution:

  We use the following constant symbols:
    m : Minna, l : Lucy
  and predicate symbols:
    h(x) : x is human,  i(x) : x is insane,  s(x) : x speaks the truth
  *}

theorem "[| h m <-> ~ h l;
  ALL x. s x <-> (h x & ~ i x) | (~ h x & i x);
  s m <-> i m & i l; s l <-> ~ (i m & i l)  |] ==> EX x. h x"
  by blast

theorem "[| h m <-> ~ h l;
  ALL x. s x <-> (h x & ~ i x) | (~ h x & i x);
  s m <-> i m & i l; s l <-> ~ (i m & i l)  |] ==> h l"
  by blast

end
