deleted old files and added code to give a special tag to the command ML
authorChristian Urban <urbanc@in.tum.de>
Thu, 08 Jan 2009 22:47:15 +0000
changeset 64 9a6e5e0c4906
parent 63 83cea5dc6bac
child 65 c8e9a4f97916
deleted old files and added code to give a special tag to the command ML
CookBook/Base.thy
CookBook/CookBook.thy
CookBook/Intro.thy
CookBook/Readme.thy
CookBook/comp_simproc.ML
CookBook/document/root.tex
cookbook.pdf
--- a/CookBook/Base.thy	Thu Jan 08 22:46:06 2009 +0000
+++ b/CookBook/Base.thy	Thu Jan 08 22:47:15 2009 +0000
@@ -5,4 +5,14 @@
   "antiquote_setup.ML"
 begin
 
+(* to have a special tag for text enclosed in ML *)
+ML {*
+
+val _ =
+  OuterSyntax.command "ML" "eval ML text within theory"
+    (OuterKeyword.tag "CookBookML" OuterKeyword.thy_decl)
+    (OuterParse.ML_source >> (fn (txt, pos) =>
+      Toplevel.generic_theory (ML_Context.exec (fn () => ML_Context.eval true pos txt))));
+*}
+
 end
--- a/CookBook/CookBook.thy	Thu Jan 08 22:46:06 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,743 +0,0 @@
-theory CookBook
-imports Main
-uses "~/Theorem-Provers/Isabelle/Isabelle-CVS/Doc/antiquote_setup.ML"
-("comp_simproc")
-begin
-(*<*)
-
-ML {*
-local structure O = ThyOutput
-in
-  fun check_exists f = 
-    if File.exists (Path.explode ("~~/src/" ^ f)) then ()
-    else error ("Source file " ^ quote f ^ " does not exist.")
-  
-  val _ = O.add_commands
-   [("ML_file", O.args (Scan.lift Args.name) (O.output (fn _ => fn name =>
-         (check_exists name; Pretty.str name))))];
-
-end
-*}
-(*>*)
-
-section {* Introduction *}
-
-text {*
-  The purpose of this document is to guide the reader through the
-  first steps in Isabelle programming, and to provide recipes for
-  solving common problems. 
-*}
-
-subsection {* Intended Audience and Prior Knowledge *}
-
-text {* 
-  This cookbook targets an audience who already knows how to use the Isabelle
-  system to write theories and proofs, but without using ML.
-  You should also be familiar with the \emph{Standard ML} programming
-  language, which is  used for Isabelle programming. If you are unfamiliar with any of
-  these two subjects, you should first work through the Isabelle/HOL
-  tutorial \cite{isa-tutorial} and Paulson's book on Standard ML
-  \cite{paulson-ml2}.
-
-*}
-
-subsection {* Primary Documentation *}
-
-text {*
-  
-
-  \begin{description}
-  \item[The Implementation Manual \cite{isa-imp}] describes Isabelle
-  from a programmer's perspective, documenting both the underlying
-  concepts and the concrete interfaces. 
-
-  \item[The Isabelle Reference Manual \cite{isabelle-ref}] is an older document that used
-  to be the main reference, when all reasoning happened on the ML
-  level. Many parts of it are outdated now, but some parts, mainly the
-  chapters on tactics, are still useful.
-
-  \item[The code] is of course the ultimate reference for how
-  things really work. Therefore you should not hesitate to look at the
-  way things are actually implemented. More importantly, it is often
-  good to look at code that does similar things as you want to do, to
-  learn from other people's code.
-  \end{description}
-
-  Since Isabelle is not a finished product, these manuals, just like
-  the implementation itself, are always under construction. This can
-  be dificult and frustrating at times, when interfaces are changing
-  frequently. But it is a reality that progress means changing
-  things (FIXME: need some short and convincing comment that this
-  is a strategy, not a problem that should be solved).
-*}
-
-
-
-section {* First Steps *}
-
-text {* 
-  Isabelle programming happens in an enhanced dialect of Standard ML,
-  which adds antiquotations containing references to the logical
-  context.
-
-  Just like all lemmas or proofs, all ML code that you write lives in
-  a theory, where it is embedded using the \isacommand{ML} command:
-*}
-
-ML {*
-  3 + 4
-*}
-
-text {*
-  The \isacommand{ML} command takes an arbitrary ML expression, which
-  is evaluated. It can also contain value or function bindings.
-*}
-subsection {* Antiquotations *}
-text {*
-  The main advantage of embedding all code in a theory is that the
-  code can contain references to entities that are defined in the
-  theory. Let us for example, print out the name of the current
-  theory:
-*}
-
-ML {* Context.theory_name @{theory} *}
-
-text {* The @{text "@{theory}"} antiquotation is substituted with the
-  current theory, whose name can then be extracted using a the
-  function @{ML "Context.theory_name"}. Note that antiquotations are
-  statically scoped. The function
-*}
-
-ML {* 
-  fun current_thyname () = Context.theory_name @{theory}
-*}
-
-text {*
-  does \emph{not} return the name of the current theory. Instead, we have
-  defined the constant function that always returns the string @{ML "\"CookBook\""}, which is
-  the name of @{text "@{theory}"} at the point where the code
-  is embedded. Operationally speaking,  @{text "@{theory}"} is \emph{not}
-  replaced with code that will look up the current theory in some
-  (destructive) data structure and return it. Instead, it is really
-  replaced with the theory value.
-
-  In the course of this introduction, we will learn about more of
-  these antoquotations, which greatly simplify programming, since you
-  can directly access all kinds of logical elements from ML.
-*}
-
-subsection {* Terms *}
-
-text {*
-  We can simply quote Isabelle terms from ML using the @{text "@{term \<dots>}"} 
-  antiquotation:
-*}
-
-ML {* @{term "(a::nat) + b = c"} *}
-
-text {*
-  This shows the term @{term "(a::nat) + b = c"} in the internal
-  representation, with all gory details. Terms are just an ML
-  datatype, and they are defined in @{ML_file "Pure/term.ML"}.
-  
-  The representation of terms uses deBruin indices: Bound variables
-  are represented by the constructor @{ML Bound}, and the index refers to
-  the number of lambdas we have to skip until we hit the lambda that
-  binds the variable. The names of bound variables are kept at the
-  abstractions, but they are just comments. 
-  See \ichcite{ch:logic} for more details.
-
-  \begin{readmore}
-  Terms are described in detail in \ichcite{ch:logic}. Their
-  definition and many useful operations can be found in @{ML_file "Pure/term.ML"}.
-  \end{readmore}
-
-  In a similar way we can quote types and theorems:
-*}
-
-ML {* @{typ "(int * nat) list"} *}
-ML {* @{thm allI} *}
-
-text {* 
-  In the default setup, types and theorems are printed as strings. 
-*}
-
-
-text {*
-  Sometimes the internal representation can be surprisingly different
-  from what you see at the user level, because the layer of
-  parsing/type checking/pretty printing can be quite thick. 
-
-\begin{exercise}
-  Look at the internal term representation of the following terms, and
-  find out why they are represented like this.
-
-  \begin{itemize}
-  \item @{term "case x of 0 \<Rightarrow> 0 | Suc y \<Rightarrow> y"}  
-  \item @{term "\<lambda>(x,y). P y x"}  
-  \item @{term "{ [x::int] | x. x \<le> -2 }"}  
-  \end{itemize}
-
-  Hint: The third term is already quite big, and the pretty printer
-  may omit parts of it by default. If you want to see all of it, you
-  can use @{ML "print_depth 50"} to set the limit to a value high enough.
-\end{exercise}
-*}
-
-subsection {* Type checking *}
-
-text {* 
-  We can freely construct and manipulate terms, since they are just
-  arbitrary unchecked trees. However, we eventually want to see if a
-  term is wellformed in a certain context.
-
-  Type checking is done via @{ML cterm_of}, which turns a @{ML_type
-  term} into a  @{ML_type cterm}, a \emph{certified} term. Unlike
-  @{ML_type term}s, which are just trees, @{ML_type
-  "cterm"}s are abstract objects that are guaranteed to be
-  type-correct, and can only be constructed via the official
-  interfaces.
-
-  Type
-  checking is always relative to a theory context. For now we can use
-  the @{ML "@{theory}"} antiquotation to get hold of the theory at the current
-  point:
-*}
-
-ML {*
-  let
-    val natT = @{typ "nat"}
-    val zero = @{term "0::nat"}(*Const ("HOL.zero_class.zero", natT)*)
-  in
-    cterm_of @{theory} 
-        (Const ("HOL.plus_class.plus", natT --> natT --> natT) 
-         $ zero $ zero)
-  end
-*}
-
-ML {*
-  @{const_name plus}
-*}
-
-ML {*
-  @{term "{ [x::int] | x. x \<le> -2 }"}
-*}
-
-text {*
-  The internal names of constants like @{term "zero"} or @{text "+"} are
-  often more complex than one first expects. Here, the extra prefixes
-  @{text zero_class} and @{text plus_class} are present because the
-  constants are defined within a type class. Guessing such internal
-  names can be extremely hard, which is why the system provides
-  another antiquotation: @{ML "@{const_name plus}"} gives just this
-  name.
-
-  \begin{exercise}
-  Write a function @{ML_text "rev_sum : term -> term"} that takes a
-  term of the form @{text "t\<^isub>1 + t\<^isub>2 + \<dots> + t\<^isub>n"}
-  and returns the reversed sum @{text "t\<^isub>n + \<dots> + t\<^isub>2 + t\<^isub>1"}.
-  Note that @{text "+"} associates to the left.
-  Try your function on some examples, and see if the result typechecks.
-  \end{exercise}
-
-  \begin{exercise}
-  Write a function which takes two terms representing natural numbers
-  in unary (like @{term "Suc (Suc (Suc 0))"}), and produce the unary
-  number representing their sum.
-  \end{exercise}
-
-  \begin{exercise}
-  Look at the functions defined in @{ML_file "Pure/logic.ML"} and
-  @{ML_file "HOL/hologic.ML"} and see if they can make your life
-  easier.
-  \end{exercise}
-*}
-
-subsection {* Theorems *}
-
-text {*
-  Just like @{ML_type cterm}s, theorems (of type @{ML_type thm}) are
-  abstract objects that can only be built by going through the kernel
-  interfaces, which means that all your proofs will be checked. The
-  basic rules of the Isabelle/Pure logical framework are defined in
-  @{ML_file "Pure/thm.ML"}. 
-
-  Using these rules, which are just ML functions, you can do simple
-  natural deduction proofs on the ML level. For example, the statement
-  @{prop "(\<And>(x::nat). P x \<Longrightarrow> Q x) \<Longrightarrow> P t \<Longrightarrow> Q t"} can be proved like
-  this\footnote{Note that @{text "|>"} is just reverse
-  application. This combinator, and several variants are defined in
-  @{ML_file "Pure/General/basics.ML"}}:
-*}
-
-ML {*
-let
-  val thy = @{theory}
-  val nat = HOLogic.natT
-  val x = Free ("x", nat)
-  val t = Free ("t", nat)
-  val P = Free ("P", nat --> HOLogic.boolT)
-  val Q = Free ("Q", nat --> HOLogic.boolT)
-
-  val A1 = Logic.all x 
-           (Logic.mk_implies (HOLogic.mk_Trueprop (P $ x),
-                              HOLogic.mk_Trueprop (Q $ x)))
-           |> cterm_of thy
-
-  val A2 = HOLogic.mk_Trueprop (P $ t)
-           |> cterm_of thy
-
-  val Pt_implies_Qt = 
-        assume A1
-        |> forall_elim (cterm_of thy t)
-
-  val Qt = implies_elim Pt_implies_Qt (assume A2)
-in
-  Qt 
-  |> implies_intr A2
-  |> implies_intr A1
-end
-*}
-
-subsection {* Tactical reasoning *}
-
-text {*
-  The goal-oriented tactical style is similar to the @{text apply}
-  style at the user level. Reasoning is centered around a \emph{goal},
-  which is modified in a sequence of proof steps until it is solved.
-
-  A goal (or goal state) is a special @{ML_type thm}, which by
-  convention is an implication:
-  @{text[display] "A\<^isub>1 \<Longrightarrow> \<dots> \<Longrightarrow> A\<^isub>n \<Longrightarrow> #(C)"}
-  Since the final result @{term C} could again be an implication, there is the
-  @{text "#"} around the final result, which protects its premises from being
-  misinterpreted as open subgoals. The protection @{text "# :: prop \<Rightarrow>
-  prop"} is just the identity and used as a syntactic marker.
-
-  Now tactics are just functions that map a goal state to a (lazy)
-  sequence of successor states, hence the type of a tactic is
-  @{ML_type[display] "thm -> thm Seq.seq"}
-  See @{ML_file "Pure/General/seq.ML"} for the implementation of lazy
-  sequences.
-
-  Of course, tactics are expected to behave nicely and leave the final
-  conclusion @{term C} intact. In order to start a tactical proof for
-  @{term A}, we
-  just set up the trivial goal @{text "A \<Longrightarrow> #(A)"} and run the tactic
-  on it. When the subgoal is solved, we have just @{text "#(A)"} and
-  can remove the protection.
-
-  The operations in @{ML_file "Pure/goal.ML"} do just that and we can use
-  them.
-
-  Let us transcribe a simple apply style proof from the
-  tutorial\cite{isa-tutorial} into ML:
-*}
-
-lemma disj_swap: "P \<or> Q \<Longrightarrow> Q \<or> P"
-apply (erule disjE)
- apply (rule disjI2)
- apply assumption
-apply (rule disjI1)
-apply assumption
-done
-
-ML {*
-let
-  val ctxt = @{context}
-  val goal = @{prop "P \<or> Q \<Longrightarrow> Q \<or> P"}
-in
-  Goal.prove ctxt ["P", "Q"] [] goal (fn _ => 
-    eresolve_tac [disjE] 1
-    THEN resolve_tac [disjI2] 1
-    THEN assume_tac 1
-    THEN resolve_tac [disjI1] 1
-    THEN assume_tac 1)
-end
-*}
-
-text {*
-  Tactics that affect only a certain subgoal, take a subgoal number as
-  an integer parameter. Here we always work on the first subgoal,
-  following exactly the @{text "apply"} script.
-*}
-
-
-section {* Case Study: Relation Composition *}
-
-text {*
-  \emph{Note: This is completely unfinished. I hoped to have a section
-  with a nontrivial example, but I ran into several problems.}
-
-
-  Recall that HOL has special syntax for set comprehensions:
-  @{term "{ f x y |x y. P x y}"} abbreviates 
-  @{term[source] "{u. \<exists>x y. u = f x y \<and> P x y}"}. 
-
-  We will automatically prove statements of the following form:
-  
-  @{lemma[display] "{(l\<^isub>1 x, r\<^isub>1 x) |x. P\<^isub>1 x} O {(l\<^isub>2 x, r\<^isub>2 x) |x. P\<^isub>2 x}
-  = {(l\<^isub>2 x, r\<^isub>1 y) |x y. r\<^isub>2 x = l\<^isub>1 y \<and>
-  P\<^isub>2 x \<and> P\<^isub>1 y}" by auto}
-
-  In Isabelle, relation composition is defined to be consistent with
-  function composition, that is, the relation applied ``first'' is
-  written on the right hand side. This different from what many
-  textbooks do.
-
-  The above statement about composition is not proved automatically by
-  @{method simp}, and it cannot be solved by a fixed set of rewrite
-  rules, since the number of (implicit) quantifiers may vary. Here, we
-  only have one bound variable in each comprehension, but in general
-  there can be more. On the other hand, @{method auto} proves the
-  above statement quickly, by breaking the equality into two parts and
-  proving them separately. However, if e.g.\ @{term "P\<^isub>1"} is a
-  complicated expression, the automated tools may get confused.
-
-  Our goal is now to develop a small procedure that can compute (with proof) the
-  composition of two relation comprehensions, which can be used to
-  extend the simplifier.
-*}
-
-subsection {*A tactic *}
-
-text {* Let's start with a step-by-step proof of the above statement *}
-
-lemma "{(l\<^isub>1 x, r\<^isub>1 x) |x. P\<^isub>1 x} O {(l\<^isub>2
-  x, r\<^isub>2 x) |x. P\<^isub>2 x}
-  = {(l\<^isub>2 x, r\<^isub>1 y) |x y. r\<^isub>2 x = l\<^isub>1 y \<and> P\<^isub>2 x \<and> P\<^isub>1 y}"
-apply (rule set_ext)
-apply (rule iffI)
- apply (erule rel_compE)  -- {* @{text "\<subseteq>"} *}
- apply (erule CollectE)     -- {* eliminate @{text "Collect"}, @{text "\<exists>"}, @{text "\<and>"}, and pairs *}
- apply (erule CollectE)
- apply (erule exE)
- apply (erule exE)
- apply (erule conjE)
- apply (erule conjE)
- apply (erule Pair_inject)
- apply (erule Pair_inject)
- apply (simp only:)
-
- apply (rule CollectI)    -- {* introduce them again *}
- apply (rule exI)
- apply (rule exI)
- apply (rule conjI)
-  apply (rule refl)
- apply (rule conjI)
-  apply (rule sym)
-  apply (assumption)
- apply (rule conjI)
-  apply assumption
- apply assumption
-
-apply (erule CollectE)   -- {* @{text "\<subseteq>"} *}
-apply (erule exE)+
-apply (erule conjE)+
-apply (simp only:)
-apply (rule rel_compI)
- apply (rule CollectI)
- apply (rule exI)
- apply (rule conjI)
-  apply (rule refl)
- apply assumption
-
-apply (rule CollectI)
-apply (rule exI)
-apply (rule conjI)
-apply (subst Pair_eq)
-apply (rule conjI)
- apply assumption
-apply (rule refl)
-apply assumption
-done
-
-text {*
-  The reader will probably need to step through the proof and verify
-  that there is nothing spectacular going on here.
-  The @{text apply} script just applies the usual elimination and introduction rules in the right order.
-
-  This script is of course totally unreadable. But we are not trying
-  to produce pretty Isar proofs here. We just want to find out which
-  rules are needed and how they must be applied to complete the
-  proof. And a detailed apply-style proof can often be turned into a
-  tactic quite easily. Of course we must resist the temptation to use
-  @{method auto}, @{method blast} and friends, since their behaviour
-  is not predictable enough. But the simple @{method rule} and
-  @{method erule} methods are fine.
-
-  Notice that this proof depends only in one detail on the
-  concrete equation that we want to prove: The number of bound
-  variables in the comprehension corresponds to the number of
-  existential quantifiers that we have to eliminate and introduce
-  again. In fact this is the only reason why the equations that we
-  want to prove are not just instances of a single rule.
-
-  Here is the ML equivalent of the tactic script above:
-*}
-
-ML {*
-val compr_compose_tac =
-  rtac @{thm set_ext}
-  THEN' rtac @{thm iffI}
-  THEN' etac @{thm rel_compE}
-  THEN' etac @{thm CollectE}
-  THEN' etac @{thm CollectE}
-  THEN' (fn i => REPEAT (etac @{thm exE} i))
-  THEN' etac @{thm conjE}
-  THEN' etac @{thm conjE}
-  THEN' etac @{thm Pair_inject}
-  THEN' etac @{thm Pair_inject}
-  THEN' asm_full_simp_tac HOL_basic_ss
-  THEN' rtac @{thm CollectI}
-  THEN' (fn i => REPEAT (rtac @{thm exI} i))
-  THEN' rtac @{thm conjI}
-  THEN' rtac @{thm refl}
-  THEN' rtac @{thm conjI}
-  THEN' rtac @{thm sym}
-  THEN' assume_tac
-  THEN' rtac @{thm conjI}
-  THEN' assume_tac
-  THEN' assume_tac
-
-  THEN' etac @{thm CollectE}
-  THEN' (fn i => REPEAT (etac @{thm exE} i))
-  THEN' etac @{thm conjE}
-  THEN' etac @{thm conjE}
-  THEN' etac @{thm conjE}
-  THEN' asm_full_simp_tac HOL_basic_ss
-  THEN' rtac @{thm rel_compI}
-  THEN' rtac @{thm CollectI}
-  THEN' (fn i => REPEAT (rtac @{thm exI} i))
-  THEN' rtac @{thm conjI}
-  THEN' rtac @{thm refl}
-  THEN' assume_tac
-  THEN' rtac @{thm CollectI}
-  THEN' (fn i => REPEAT (rtac @{thm exI} i))
-  THEN' rtac @{thm conjI}
-  THEN' simp_tac (HOL_basic_ss addsimps [@{thm Pair_eq}])
-  THEN' rtac @{thm conjI}
-  THEN' assume_tac
-  THEN' rtac @{thm refl}
-  THEN' assume_tac
-*}
-
-lemma test1: "{(l\<^isub>1 x, r\<^isub>1 x) |x. P\<^isub>1 x} O {(l\<^isub>2
-  x, r\<^isub>2 x) |x. P\<^isub>2 x}
-  = {(l\<^isub>2 x, r\<^isub>1 y) |x y. r\<^isub>2 x = l\<^isub>1 y \<and> P\<^isub>2 x \<and> P\<^isub>1 y}"
-by (tactic "compr_compose_tac 1")
-
-lemma test3: "{(l\<^isub>1 x, r\<^isub>1 x) |x. P\<^isub>1 x} O {(l\<^isub>2 x z, r\<^isub>2 x z) |x z. P\<^isub>2 x z}
-  = {(l\<^isub>2 x z, r\<^isub>1 y) |x y z. r\<^isub>2 x z = l\<^isub>1 y \<and> P\<^isub>2 x z \<and> P\<^isub>1 y}"
-by (tactic "compr_compose_tac 1")
-
-text {*
-  So we have a tactic that works on at least two examples.
-  Getting it really right requires some more effort. Consider the goal
-*}
-lemma "{(n, Suc n) |n. n > 0} O {(n, Suc n) |n. P n}
-  = {(n, Suc m)|n m. Suc n = m \<and> P n \<and> m > 0}"
-
-(*lemma "{(l\<^isub>1 x, r\<^isub>1 x) |x. P\<^isub>1 x} O {(l\<^isub>2
-  x, r\<^isub>2 x) |x. P\<^isub>2 x}
-  = {(l\<^isub>2 x, r\<^isub>1 y) |x y. r\<^isub>2 x = l\<^isub>1 y \<and> P\<^isub>2 x \<and> P\<^isub>1 y}"*)
-txt {*
-  This is exactly an instance of @{fact test1}, but our tactic fails
-  on it with the usual uninformative
-  \emph{empty result requence}.
-
-  We are now in the frequent situation that we need to debug. One simple instrument for this is @{ML "print_tac"},
-  which is the same as @{ML all_tac} (the identity for @{ML_text "THEN"}),
-  i.e.\ it does nothing, but it prints the current goal state as a
-  side effect.
-  Another debugging option is of course to step through the interactive apply script.
-
-  Finding the problem could be taken as an exercise for the patient
-  reader, and we will go ahead with the solution.
-
-  The problem is that in this instance the simplifier does more than it did in the general version
-  of lemma @{fact test1}. Since @{text "l\<^isub>1"} and @{text "l\<^isub>2"} are just the identity function,
-  the equation corresponding to @{text "l\<^isub>1 y = r\<^isub>2 x "}
-  becomes @{text "m = Suc n"}. Then the simplifier eagerly replaces
-  all occurences of @{term "m"} by @{term "Suc n"} which destroys the
-  structure of the proof.
-
-  This is perhaps the most important lesson to learn, when writing tactics:
-  \textbf{Avoid automation at all cost!!!}.
-
-  Let us look at the proof state at the point where the simplifier is
-  invoked:
-  
-*}
-(*<*)
-apply (rule set_ext)
-apply (rule iffI)
- apply (erule rel_compE)
- apply (erule CollectE)
- apply (erule CollectE)
- apply (erule exE)
- apply (erule exE)
- apply (erule conjE)
- apply (erule conjE)
- apply (erule Pair_inject)
- apply (erule Pair_inject)(*>*)
-txt {*
-  
-  @{subgoals[display]}
-  
-  Like in the apply proof, we now want to eliminate the equations that
-  ``define'' @{term x}, @{term xa} and @{term z}. The other equations
-  are just there by coincidence, and we must not touch them.
-  
-  For such purposes, there is the internal tactic @{text "hyp_subst_single"}.
-  Its job is to take exactly one premise of the form @{term "v = t"},
-  where @{term v} is a variable, and replace @{term "v"} in the whole
-  subgoal. The hypothesis to eliminate is given by its position.
-
-  We can use this tactic to eliminate @{term x}:
-*}
-apply (tactic "single_hyp_subst_tac 0 1")
-txt {*
-  @{subgoals[display]}
-*}
-apply (tactic "single_hyp_subst_tac 2 1")
-apply (tactic "single_hyp_subst_tac 2 1")
-apply (tactic "single_hyp_subst_tac 3 1")
- apply (rule CollectI)    -- {* introduce them again *}
- apply (rule exI)
- apply (rule exI)
- apply (rule conjI)
-  apply (rule refl)
- apply (rule conjI)
-  apply (assumption)
- apply (rule conjI)
-  apply assumption
- apply assumption
-
-apply (erule CollectE)   -- {* @{text "\<subseteq>"} *}
-apply (erule exE)+
-apply (erule conjE)+
-apply (tactic "single_hyp_subst_tac 0 1")
-apply (rule rel_compI)
- apply (rule CollectI)
- apply (rule exI)
- apply (rule conjI)
-  apply (rule refl)
- apply assumption
-
-apply (rule CollectI)
-apply (rule exI)
-apply (rule conjI)
-apply (subst Pair_eq)
-apply (rule conjI)
- apply assumption
-apply (rule refl)
-apply assumption
-done
-
-ML {*
-val compr_compose_tac =
-  rtac @{thm set_ext}
-  THEN' rtac @{thm iffI}
-  THEN' etac @{thm rel_compE}
-  THEN' etac @{thm CollectE}
-  THEN' etac @{thm CollectE}
-  THEN' (fn i => REPEAT (etac @{thm exE} i))
-  THEN' etac @{thm conjE}
-  THEN' etac @{thm conjE}
-  THEN' etac @{thm Pair_inject}
-  THEN' etac @{thm Pair_inject}
-  THEN' single_hyp_subst_tac 0
-  THEN' single_hyp_subst_tac 2
-  THEN' single_hyp_subst_tac 2
-  THEN' single_hyp_subst_tac 3
-  THEN' rtac @{thm CollectI}
-  THEN' (fn i => REPEAT (rtac @{thm exI} i))
-  THEN' rtac @{thm conjI}
-  THEN' rtac @{thm refl}
-  THEN' rtac @{thm conjI}
-  THEN' assume_tac
-  THEN' rtac @{thm conjI}
-  THEN' assume_tac
-  THEN' assume_tac
-
-  THEN' etac @{thm CollectE}
-  THEN' (fn i => REPEAT (etac @{thm exE} i))
-  THEN' etac @{thm conjE}
-  THEN' etac @{thm conjE}
-  THEN' etac @{thm conjE}
-  THEN' single_hyp_subst_tac 0
-  THEN' rtac @{thm rel_compI}
-  THEN' rtac @{thm CollectI}
-  THEN' (fn i => REPEAT (rtac @{thm exI} i))
-  THEN' rtac @{thm conjI}
-  THEN' rtac @{thm refl}
-  THEN' assume_tac
-  THEN' rtac @{thm CollectI}
-  THEN' (fn i => REPEAT (rtac @{thm exI} i))
-  THEN' rtac @{thm conjI}
-  THEN' stac @{thm Pair_eq}
-  THEN' rtac @{thm conjI}
-  THEN' assume_tac
-  THEN' rtac @{thm refl}
-  THEN' assume_tac
-*}
-
-lemma "{(n, Suc n) |n. n > 0 \<and> A} O {(n, Suc n) |n m. P m n}
-  = {(n, Suc m)|n m' m. Suc n = m \<and> P m' n \<and> (m > 0 \<and> A)}"
-apply (tactic "compr_compose_tac 1")
-done
-
-text {*
-  The next step is now to turn this tactic into a simplification
-  procedure. This just means that we need some code that builds the
-  term of the composed relation.
-*}
-
-use "comp_simproc"
-
-(*<*)
-(*simproc_setup mysp ("x O y") = {* compose_simproc *}*)
-
-lemma "{(n, Suc n) |n. n > 0 \<and> A} O {(n, Suc n) |n m. P m n} = x"
-(*apply (simp del:ex_simps)*)
-oops
-
-
-lemma "({(g m, k) | m k. Q m k} 
-O {(h j, f j) | j. R j}) = x"
-(*apply (simp del:ex_simps) *)
-oops
-
-lemma "{uu. \<exists>j m k. uu = (h j, k) \<and> f j = g m \<and> R j \<and> Q m k}
-O {(h j, f j) | j. R j} = x"
-(*apply (simp del:ex_simps)*)
-oops
-
-lemma "
-  { (l x, r x) | x. P x \<and> Q x \<and> Q' x }
-O { (l1 x, r1 x) | x. P1 x \<and> Q1 x \<and> Q1' x }
-= A"
-(*apply (simp del:ex_simps)*)
-oops
-
-lemma "
-  { (l x, r x) | x. P x }
-O { (l1 x, r1 x) | x. P1 x }
-O { (l2 x, r2 x) | x. P2 x }
-= A"
-(*
-apply (simp del:ex_simps)*)
-oops
-
-lemma "{(f n, m) |n m. P n m} O ({(g m, k) | m k. Q m k} 
-O {(h j, f j) | j. R j}) = x"
-(*apply (simp del:ex_simps)*)
-oops
-
-lemma "{u. \<exists>n. u=(f n, g n)} O {u. \<exists>n. u=(h n, j n)} = A"
-oops
-
-
-(*>*)
-end
\ No newline at end of file
--- a/CookBook/Intro.thy	Thu Jan 08 22:46:06 2009 +0000
+++ b/CookBook/Intro.thy	Thu Jan 08 22:47:15 2009 +0000
@@ -3,6 +3,7 @@
 
 begin
 
+
 chapter {* Introduction *}
 
 text {*
--- a/CookBook/Readme.thy	Thu Jan 08 22:46:06 2009 +0000
+++ b/CookBook/Readme.thy	Thu Jan 08 22:47:15 2009 +0000
@@ -14,7 +14,8 @@
   \end{center}
 
   You very likely need a recent snapshot of Isabelle in order to compile
-  the Cookbook.
+  the Cookbook. Some parts of the Cookbook also rely on compilation with
+  PolyML.
 
   \item You can include references to other Isabelle manuals using the 
   reference names from those manuals. To do this the following
--- a/CookBook/comp_simproc.ML	Thu Jan 08 22:46:06 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-
-fun dest_relcomp (t as (Const (@{const_name "Collect"}, _) $ Abs (_, pT, ex_exp))) =
-    let
-      val (T1, T2) = HOLogic.dest_prodT pT
-      val qs  = Term.strip_qnt_vars "Ex" ex_exp
-      val bod = Term.strip_qnt_body "Ex" ex_exp
-
-      val (l, r, cond) = case bod of
-        Const ("op &", _) 
-         $ (Const ("op =", _) $ Bound idx
-              $ (Const ("Pair", _) $ l $ r)) 
-         $ cond
-          => if idx = length qs then (l, r, cond)
-            else raise TERM ("dest_relcomp", [t])
-      | _ => raise TERM ("dest_relcomp", [t])
-    in
-      (T1, T2, qs, l, r, cond)
-    end
-  | dest_relcomp t = raise TERM ("dest_relcomp", [t])
-
-fun mk_pair_compr (T1, T2, qs, l, r, cond) =
-    let
-      val pT = HOLogic.mk_prodT (T1, T2)
-      val peq = HOLogic.eq_const pT $ Bound (length qs) $ (HOLogic.pair_const T1 T2 $ l $ r)
-      val bod = HOLogic.mk_conj (peq, cond)
-    in
-      HOLogic.Collect_const pT $
-      Abs ("uu_", pT, fold_rev (fn (a,T) => fn b => HOLogic.exists_const T $ Abs(a, T, b)) qs bod)
-    end
-
-fun join_compr c1 c2 : term = 
-    let
-      val (T1, T2, qs1, l1, r1, cond1) = dest_relcomp c1
-      val (T2, T3, qs2, l2, r2, cond2) = dest_relcomp c2
-
-      val lift = incr_boundvars (length qs2)
-      val cond = HOLogic.mk_conj (HOLogic.eq_const T2 $ lift r1 $ l2,
-                   HOLogic.mk_conj (lift cond1, cond2))
-    in
-      mk_pair_compr
-        (T1, T3, qs1 @ qs2, lift l1, r2, cond)
-    end
-
-val compr_compose_tac'=
-    EVERY1 (map (curry op o DETERM)
-  [rtac @{thm set_ext},
-   rtac @{thm iffI},
-   etac @{thm rel_compE},
-   etac @{thm CollectE},
-   etac @{thm CollectE},
-   single_hyp_subst_tac 0,
-   (fn i => REPEAT_DETERM (etac @{thm exE} i)),
-   K (print_tac "A"),
-   etac @{thm conjE},
-   K (print_tac "B"),
-   etac @{thm conjE},
-   K (print_tac "B'"),
-   etac @{thm Pair_inject},
-   K (print_tac "C"),
-   rotate_tac 1,
-   K (print_tac "D"),
-   etac @{thm Pair_inject},
-   K (print_tac "E"),
-   single_hyp_subst_tac 2,
-   single_hyp_subst_tac 3,
-   single_hyp_subst_tac 3,
-   rtac @{thm CollectI},
-   (fn i => REPEAT_DETERM (rtac @{thm exI} i)),
-   rtac @{thm conjI},
-   rtac @{thm refl},
-   rtac @{thm conjI},
-   assume_tac,
-   rtac @{thm conjI},
-   assume_tac,
-   assume_tac,
-   etac @{thm CollectE},
-   (fn i => REPEAT (etac @{thm exE} i)),
-   etac @{thm conjE},
-   single_hyp_subst_tac 0,
-   etac @{thm conjE},
-   etac @{thm conjE},
-   rtac @{thm rel_compI},
-   rtac @{thm CollectI},
-   (fn i => REPEAT (rtac @{thm exI} i)),
-   rtac @{thm conjI},
-   rtac @{thm refl},
-   assume_tac,
-   rtac @{thm CollectI},
-   (fn i => REPEAT (rtac @{thm exI} i)),
-   rtac @{thm conjI},
-   stac @{thm Pair_eq},
-   rtac @{thm conjI},
-   assume_tac,
-   rtac @{thm refl},
-   assume_tac])
-
-
-fun compose_simproc _ ss ct : thm option =
-    let
-      val thy = theory_of_cterm ct
-      val sCt as (_ $ s $ t) = term_of ct
-      val T = fastype_of sCt
-      val g : term = Logic.mk_equals (sCt, join_compr t s)
-(*      val _ = Output.tracing (Syntax.string_of_term (Simplifier.the_context ss) g)*)
-    in
-      SOME (Goal.prove_internal [] (cterm_of thy g)
-             (K (rtac @{thm eq_reflection} 1
-                 THEN compr_compose_tac')))
-    end
-    handle TERM _ => NONE
-
--- a/CookBook/document/root.tex	Thu Jan 08 22:46:06 2009 +0000
+++ b/CookBook/document/root.tex	Thu Jan 08 22:47:15 2009 +0000
@@ -75,8 +75,9 @@
 \renewcommand{\isacharverbatimclose}{}%
 \hspace{-1.5mm}\mbox{}}{}
 
-\renewcommand{\isatagML}{\begin{vanishML}}
-\renewcommand{\endisatagML}{\end{vanishML}}
+\isakeeptag{CookBookML}
+\renewcommand{\isatagCookBookML}{\begin{vanishML}}
+\renewcommand{\endisatagCookBookML}{\end{vanishML}}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Binary file cookbook.pdf has changed