Theory Basic

theory Basic imports Main begin

lemma conj_rule: " P; Q   P  (Q  P)"
apply (rule conjI)
 apply assumption
apply (rule conjI)
 apply assumption
apply assumption
done
    

lemma disj_swap: "P | Q  Q | P"
apply (erule disjE)
 apply (rule disjI2)
 apply assumption
apply (rule disjI1)
apply assumption
done

lemma conj_swap: "P  Q  Q  P"
apply (rule conjI)
 apply (drule conjunct2)
 apply assumption
apply (drule conjunct1)
apply assumption
done

lemma imp_uncurry: "P  Q  R  P  Q  R"
apply (rule impI)
apply (erule conjE)
apply (drule mp)
 apply assumption
apply (drule mp)
  apply assumption
 apply assumption
done

text 
by eliminates uses of assumption and done


lemma imp_uncurry': "P  Q  R  P  Q  R"
apply (rule impI)
apply (erule conjE)
apply (drule mp)
 apply assumption
by (drule mp)


text 
substitution

@{thm[display] ssubst}
\rulename{ssubst}


lemma " x = f x; P(f x)   P x"
by (erule ssubst)

text 
also provable by simp (re-orients)


text 
the subst method

@{thm[display] mult.commute}
\rulename{mult.commute}

this would fail:
apply (simp add: mult.commute) 



lemma "P x y z; Suc x < y  f z = x*y"
txt
@{subgoals[display,indent=0,margin=65]}

apply (subst mult.commute) 
txt
@{subgoals[display,indent=0,margin=65]}

oops

(*exercise involving THEN*)
lemma "P x y z; Suc x < y  f z = x*y"
apply (rule mult.commute [THEN ssubst]) 
oops


lemma "x = f x; triple (f x) (f x) x  triple x x x"
apply (erule ssubst) 
  ― ‹@{subgoals[display,indent=0,margin=65]}
back ― ‹@{subgoals[display,indent=0,margin=65]}
back ― ‹@{subgoals[display,indent=0,margin=65]}
back ― ‹@{subgoals[display,indent=0,margin=65]}
back ― ‹@{subgoals[display,indent=0,margin=65]}
apply assumption
done

lemma " x = f x; triple (f x) (f x) x   triple x x x"
apply (erule ssubst, assumption)
done

text
or better still 


lemma " x = f x; triple (f x) (f x) x   triple x x x"
by (erule ssubst)


lemma " x = f x; triple (f x) (f x) x   triple x x x"
apply (erule_tac P="λu. triple u u x" in ssubst)
apply (assumption)
done


lemma " x = f x; triple (f x) (f x) x   triple x x x"
by (erule_tac P="λu. triple u u x" in ssubst)


text 
negation

@{thm[display] notI}
\rulename{notI}

@{thm[display] notE}
\rulename{notE}

@{thm[display] classical}
\rulename{classical}

@{thm[display] contrapos_pp}
\rulename{contrapos_pp}

@{thm[display] contrapos_pn}
\rulename{contrapos_pn}

@{thm[display] contrapos_np}
\rulename{contrapos_np}

@{thm[display] contrapos_nn}
\rulename{contrapos_nn}



lemma "¬(PQ); ¬(RQ)  R"
apply (erule_tac Q="RQ" in contrapos_np)
        ― ‹@{subgoals[display,indent=0,margin=65]}
apply (intro impI)
        ― ‹@{subgoals[display,indent=0,margin=65]}
by (erule notE)

text 
@{thm[display] disjCI}
\rulename{disjCI}


lemma "(P  Q)  R  P  Q  R"
apply (intro disjCI conjI)
        ― ‹@{subgoals[display,indent=0,margin=65]}

apply (elim conjE disjE)
 apply assumption
        ― ‹@{subgoals[display,indent=0,margin=65]}

by (erule contrapos_np, rule conjI)
text
proof\ {\isacharparenleft}prove{\isacharparenright}{\isacharcolon}\ step\ {\isadigit{6}}\isanewline
\isanewline
goal\ {\isacharparenleft}lemma{\isacharparenright}{\isacharcolon}\isanewline
{\isacharparenleft}P\ {\isasymor}\ Q{\isacharparenright}\ {\isasymand}\ R\ {\isasymLongrightarrow}\ P\ {\isasymor}\ Q\ {\isasymand}\ R\isanewline
\ {\isadigit{1}}{\isachardot}\ {\isasymlbrakk}R{\isacharsemicolon}\ Q{\isacharsemicolon}\ {\isasymnot}\ P{\isasymrbrakk}\ {\isasymLongrightarrow}\ Q\isanewline
\ {\isadigit{2}}{\isachardot}\ {\isasymlbrakk}R{\isacharsemicolon}\ Q{\isacharsemicolon}\ {\isasymnot}\ P{\isasymrbrakk}\ {\isasymLongrightarrow}\ R



textrule_tac, etc.


lemma "P&Q"
apply (rule_tac P=P and Q=Q in conjI)
oops


textunification failure trace

declare [[unify_trace_failure = true]]

lemma "P(a, f(b, g(e,a), b), a)  P(a, f(b, g(c,a), b), a)"
txt
@{subgoals[display,indent=0,margin=65]}
apply assumption
Clash: e =/= c

Clash: == =/= Trueprop

oops

lemma "x y. P(x,y) --> P(y,x)"
apply auto
txt
@{subgoals[display,indent=0,margin=65]}
apply assumption

Clash: bound variable x (depth 1) =/= bound variable y (depth 0)

Clash: == =/= Trueprop
Clash: == =/= Trueprop

oops

declare [[unify_trace_failure = false]]


textQuantifiers

text 
@{thm[display] allI}
\rulename{allI}

@{thm[display] allE}
\rulename{allE}

@{thm[display] spec}
\rulename{spec}


lemma "x. P x  P x"
apply (rule allI)
by (rule impI)

lemma "(x. P  Q x)  P  (x. Q x)"
apply (rule impI, rule allI)
apply (drule spec)
by (drule mp)

textrename_tac
lemma "x < y  x y. P x (f y)"
apply (intro allI)
        ― ‹@{subgoals[display,indent=0,margin=65]}
apply (rename_tac v w)
        ― ‹@{subgoals[display,indent=0,margin=65]}
oops


lemma "x. P x  P (h x); P a  P(h (h a))"
apply (frule spec)
        ― ‹@{subgoals[display,indent=0,margin=65]}
apply (drule mp, assumption)
apply (drule spec)
        ― ‹@{subgoals[display,indent=0,margin=65]}
by (drule mp)

lemma "x. P x  P (f x); P a  P(f (f a))"
by blast


text
the existential quantifier

text 
@{thm[display]"exI"}
\rulename{exI}

@{thm[display]"exE"}
\rulename{exE}



text
instantiating quantifiers explicitly by rule_tac and erule_tac

lemma "x. P x  P (h x); P a  P(h (h a))"
apply (frule spec)
        ― ‹@{subgoals[display,indent=0,margin=65]}
apply (drule mp, assumption)
        ― ‹@{subgoals[display,indent=0,margin=65]}
apply (drule_tac x = "h a" in spec)
        ― ‹@{subgoals[display,indent=0,margin=65]}
by (drule mp)

text 
@{thm[display]"dvd_def"}
\rulename{dvd_def}


lemma mult_dvd_mono: "i dvd m; j dvd n  i*j dvd (m*n :: nat)"
apply (simp add: dvd_def)
        ― ‹@{subgoals[display,indent=0,margin=65]}
apply (erule exE) 
        ― ‹@{subgoals[display,indent=0,margin=65]}
apply (erule exE) 
        ― ‹@{subgoals[display,indent=0,margin=65]}
apply (rename_tac l)
        ― ‹@{subgoals[display,indent=0,margin=65]}
apply (rule_tac x="k*l" in exI) 
        ― ‹@{subgoals[display,indent=0,margin=65]}
apply simp
done

text
Hilbert-epsilon theorems

text
@{thm[display] the_equality[no_vars]}
\rulename{the_equality}

@{thm[display] some_equality[no_vars]}
\rulename{some_equality}

@{thm[display] someI[no_vars]}
\rulename{someI}

@{thm[display] someI2[no_vars]}
\rulename{someI2}

@{thm[display] someI_ex[no_vars]}
\rulename{someI_ex}

needed for examples

@{thm[display] inv_def[no_vars]}
\rulename{inv_def}

@{thm[display] Least_def[no_vars]}
\rulename{Least_def}

@{thm[display] order_antisym[no_vars]}
\rulename{order_antisym}



lemma "inv Suc (Suc n) = n"
by (simp add: inv_def)

textbut we know nothing about inv Suc 0

theorem Least_equality:
     " P (k::nat);  x. P x  k  x   (LEAST x. P(x)) = k"
apply (simp add: Least_def)
 
txt
@{subgoals[display,indent=0,margin=65]}

   
apply (rule the_equality)

txt
@{subgoals[display,indent=0,margin=65]}

first subgoal is existence; second is uniqueness

by (auto intro: order_antisym)


theorem axiom_of_choice:
     "(x. y. P x y)  f. x. P x (f x)"
apply (rule exI, rule allI)

txt
@{subgoals[display,indent=0,margin=65]}

state after intro rules

apply (drule spec, erule exE)

txt
@{subgoals[display,indent=0,margin=65]}

applying @text{someI} automatically instantiates
termf to termλx. SOME y. P x y


by (rule someI)

(*both can be done by blast, which however hasn't been introduced yet*)
lemma "[| P (k::nat);  x. P x  k  x |] ==> (LEAST x. P(x)) = k"
apply (simp add: Least_def)
by (blast intro: order_antisym)

theorem axiom_of_choice': "(x. y. P x y)  f. x. P x (f x)"
apply (rule exI [of _  "λx. SOME y. P x y"])
by (blast intro: someI)

textend of Epsilon section


lemma "(x. P x)  (x. Q x)  x. P x  Q x"
apply (elim exE disjE)
 apply (intro exI disjI1)
 apply assumption
apply (intro exI disjI2)
apply assumption
done

lemma "(PQ)  (QP)"
apply (intro disjCI impI)
apply (elim notE)
apply (intro impI)
apply assumption
done

lemma "(PQ)(PR)  P  (QR)"
apply (intro disjCI conjI)
apply (elim conjE disjE)
apply blast
apply blast
apply blast
apply blast
(*apply elim*)
done

lemma "(x. P  Q x)  P  (x. Q x)"
apply (erule exE)
apply (erule conjE)
apply (rule conjI)
 apply assumption
apply (rule exI)
 apply assumption
done

lemma "(x. P x)  (x. Q x)  x. P x  Q x"
apply (erule conjE)
apply (erule exE)
apply (erule exE)
apply (rule exI)
apply (rule conjI)
 apply assumption
oops

lemma "y. R y y  x. y. R x y"
apply (rule exI) 
  ― ‹@{subgoals[display,indent=0,margin=65]}
apply (rule allI) 
  ― ‹@{subgoals[display,indent=0,margin=65]}
apply (drule spec) 
  ― ‹@{subgoals[display,indent=0,margin=65]}
oops

lemma "x. y. x=y"
apply (rule allI)
apply (rule exI)
apply (rule refl)
done

lemma "x. y. x=y"
apply (rule exI)
apply (rule allI)
oops

end