
diff -r 1ca2f41770cc -r 79202e2eab6a ProgTutorial/Solutions.thy
--- a/ProgTutorial/Solutions.thy	Wed Aug 19 09:25:49 2009 +0200
+++ b/ProgTutorial/Solutions.thy	Thu Aug 20 10:38:26 2009 +0200
@@ -74,6 +74,102 @@
 "(\"foo bar\", \"foo (**test**) bar (**test**)\")"}
 *}
 
+text {* \solution{ex:dyckhoff} *}
+
+text {*
+  The axiom rule can be implemented with the function @{ML atac}. The other
+  rules correspond to the theorems:
+
+  \begin{center}
+  \begin{tabular}{cc}
+  \begin{tabular}{rl}
+  $\wedge_R$ & @{thm [source] conjI}\\
+  $\vee_{R_1}$ & @{thm [source] disjI1}\\
+  $\vee_{R_2}$ & @{thm [source] disjI2}\\
+  $\longrightarrow_R$ & @{thm [source] impI}\\
+  $=_R$ & @{thm [source] iffI}\\
+  \end{tabular}
+  &
+  \begin{tabular}{rl}
+  $False$ & @{thm [source] FalseE}\\
+  $\wedge_L$ & @{thm [source] conjE}\\
+  $\vee_L$ & @{thm [source] disjE}\\
+  $=_L$ & @{thm [source] iffE}
+  \end{tabular}
+  \end{tabular}
+  \end{center}
+
+  For the other rules we need to prove the following lemmas.
+*}
+
+lemma impE1:
+  shows "\<lbrakk>A \<longrightarrow> B; A; B \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R"
+  by iprover
+
+lemma impE2:
+  shows "\<lbrakk>(C \<and> D) \<longrightarrow> B; C \<longrightarrow> (D \<longrightarrow>B) \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R"
+  by iprover
+
+lemma impE3:
+  shows "\<lbrakk>(C \<or> D) \<longrightarrow> B; \<lbrakk>C \<longrightarrow> B; D \<longrightarrow> B\<rbrakk> \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R"
+  by iprover
+
+lemma impE4:
+  shows "\<lbrakk>(C \<longrightarrow> D) \<longrightarrow> B; D \<longrightarrow> B \<Longrightarrow> C \<longrightarrow> D; B \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R"
+  by iprover
+
+lemma impE5:
+  shows "\<lbrakk>(C = D) \<longrightarrow> B; (C \<longrightarrow> D) \<longrightarrow> ((D \<longrightarrow> C) \<longrightarrow> B) \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R"
+  by iprover
+
+text {*
+  Now the tactic which applies a single rule can be implemented
+  as follows.
+*}
+
+ML %linenosgray{*val apply_tac =
+let
+  val intros = [@{thm conjI}, @{thm disjI1}, @{thm disjI2}, 
+                @{thm impI}, @{thm iffI}]
+  val elims  = [@{thm FalseE}, @{thm conjE}, @{thm disjE}, @{thm iffE},
+                @{thm impE2}, @{thm impE3}, @{thm impE4}, @{thm impE5}]
+in
+  atac
+  ORELSE' resolve_tac intros
+  ORELSE' eresolve_tac elims
+  ORELSE' (etac @{thm impE1} THEN' atac)
+end*}
+
+text {*
+  In Line 11 we apply the rule @{thm [source] impE1} in concjunction 
+  with @{ML atac} in order to reduce the number of possibilities that
+  need to be explored. You can use the tactic as follows.
+*}
+
+lemma
+  shows "((((P \<longrightarrow> Q) \<longrightarrow> P) \<longrightarrow> P) \<longrightarrow> Q) \<longrightarrow> Q"
+apply(tactic {* (DEPTH_SOLVE o apply_tac) 1 *})
+done
+
+text {*
+  We can use the tactic to prove or disprove automatically the
+  de Bruijn formulae from Exercise \ref{ex:debruijn}.
+*}
+
+ML{*fun de_bruijn_prove ctxt n =
+let 
+  val goal = HOLogic.mk_Trueprop (HOLogic.mk_imp (lhs n n, rhs n))
+in
+  Goal.prove ctxt ["P"] [] goal
+   (fn _ => (DEPTH_SOLVE o apply_tac) 1)
+end*}
+
+text {* 
+  You can use this function to prove de Bruijn formulae.
+*}
+
+ML{*de_bruijn_prove @{context} 3 *}
+
 text {* \solution{ex:addsimproc} *}
 
 ML{*fun dest_sum term =




