CookBook/FirstSteps.thy
changeset 72 7b8c4fe235aa
parent 71 14c3dd5ee2ad
child 73 bcbcf5c839ae
equal deleted inserted replaced
71:14c3dd5ee2ad 72:7b8c4fe235aa
    66 
    66 
    67   During development you might find it necessary to inspect some data
    67   During development you might find it necessary to inspect some data
    68   in your code. This can be done in a ``quick-and-dirty'' fashion using 
    68   in your code. This can be done in a ``quick-and-dirty'' fashion using 
    69   the function @{ML "warning"}. For example 
    69   the function @{ML "warning"}. For example 
    70 
    70 
    71   @{ML_response_fake [display] "warning \"any string\"" "\"any string\""}
    71   @{ML_response_fake [display,gray] "warning \"any string\"" "\"any string\""}
    72 
    72 
    73   will print out @{text [quotes] "any string"} inside the response buffer
    73   will print out @{text [quotes] "any string"} inside the response buffer
    74   of Isabelle.  This function expects a string as argument. If you develop under PolyML,
    74   of Isabelle.  This function expects a string as argument. If you develop under PolyML,
    75   then there is a convenient, though again ``quick-and-dirty'', method for
    75   then there is a convenient, though again ``quick-and-dirty'', method for
    76   converting values into strings, namely @{ML makestring}:
    76   converting values into strings, namely @{ML makestring}:
    77 
    77 
    78   @{ML_response_fake [display] "warning (makestring 1)" "\"1\""} 
    78   @{ML_response_fake [display,gray] "warning (makestring 1)" "\"1\""} 
    79 
    79 
    80   However @{ML makestring} only works if the type of what is converted is monomorphic 
    80   However @{ML makestring} only works if the type of what is converted is monomorphic 
    81   and is not a function.
    81   and is not a function.
    82 
    82 
    83   The function @{ML "warning"} should only be used for testing purposes, because any
    83   The function @{ML "warning"} should only be used for testing purposes, because any
    84   output this function generates will be overwritten as soon as an error is
    84   output this function generates will be overwritten as soon as an error is
    85   raised. For printing anything more serious and elaborate, the
    85   raised. For printing anything more serious and elaborate, the
    86   function @{ML tracing} is more appropriate. This function writes all output into
    86   function @{ML tracing} is more appropriate. This function writes all output into
    87   a separate tracing buffer. For example
    87   a separate tracing buffer. For example
    88 
    88 
    89   @{ML_response_fake [display] "tracing \"foo\"" "\"foo\""}
    89   @{ML_response_fake [display,gray] "tracing \"foo\"" "\"foo\""}
    90 
    90 
    91   It is also possible to redirect the ``channel'' where the string @{text "foo"} is 
    91   It is also possible to redirect the ``channel'' where the string @{text "foo"} is 
    92   printed to a separate file, e.g. to prevent ProofGeneral from choking on massive 
    92   printed to a separate file, e.g. to prevent ProofGeneral from choking on massive 
    93   amounts of trace output. This redirection can be achieved using the code
    93   amounts of trace output. This redirection can be achieved using the code
    94 *}
    94 *}
   105     (TextIO.output (stream, (strip_specials s));
   105     (TextIO.output (stream, (strip_specials s));
   106      TextIO.output (stream, "\n");
   106      TextIO.output (stream, "\n");
   107      TextIO.flushOut stream)) *}
   107      TextIO.flushOut stream)) *}
   108 
   108 
   109 text {*
   109 text {*
   110 
       
   111   Calling @{ML "redirect_tracing"} with @{ML "(TextIO.openOut \"foo.bar\")"} 
   110   Calling @{ML "redirect_tracing"} with @{ML "(TextIO.openOut \"foo.bar\")"} 
   112   will cause that all tracing information is printed into the file @{text "foo.bar"}.
   111   will cause that all tracing information is printed into the file @{text "foo.bar"}.
   113 
       
   114 *}
   112 *}
   115 
   113 
   116 
   114 
   117 section {* Antiquotations *}
   115 section {* Antiquotations *}
   118 
   116 
   122   this we mean definitions, theorems, terms and so on. This kind of reference is
   120   this we mean definitions, theorems, terms and so on. This kind of reference is
   123   realised with antiquotations.  For example, one can print out the name of the current
   121   realised with antiquotations.  For example, one can print out the name of the current
   124   theory by typing
   122   theory by typing
   125 
   123 
   126   
   124   
   127   @{ML_response [display] "Context.theory_name @{theory}" "\"FirstSteps\""}
   125   @{ML_response [display,gray] "Context.theory_name @{theory}" "\"FirstSteps\""}
   128  
   126  
   129   where @{text "@{theory}"} is an antiquotation that is substituted with the
   127   where @{text "@{theory}"} is an antiquotation that is substituted with the
   130   current theory (remember that we assumed we are inside the theory 
   128   current theory (remember that we assumed we are inside the theory 
   131   @{text FirstSteps}). The name of this theory can be extracted with
   129   @{text FirstSteps}). The name of this theory can be extracted with
   132   the function @{ML "Context.theory_name"}. 
   130   the function @{ML "Context.theory_name"}. 
   147   some data structure and return it. Instead, it is literally
   145   some data structure and return it. Instead, it is literally
   148   replaced with the value representing the theory name.
   146   replaced with the value representing the theory name.
   149 
   147 
   150   In a similar way you can use antiquotations to refer to theorems or simpsets:
   148   In a similar way you can use antiquotations to refer to theorems or simpsets:
   151 
   149 
   152   @{ML_response_fake [display] "@{thm allI}" "(\<And>x. ?P x) \<Longrightarrow> \<forall>x. ?P x"}
   150   @{ML_response_fake [display,gray] "@{thm allI}" "(\<And>x. ?P x) \<Longrightarrow> \<forall>x. ?P x"}
   153   @{ML_response_fake [display] 
   151   @{ML_response_fake [display,gray] 
   154 "let
   152 "let
   155   val ({rules,...},_) = MetaSimplifier.rep_ss @{simpset}
   153   val ({rules,...},_) = MetaSimplifier.rep_ss @{simpset}
   156 in
   154 in
   157   map #name (Net.entries rules)
   155   map #name (Net.entries rules)
   158 end" "[\"Nat.of_nat_eq_id\", \"Int.of_int_eq_id\", \"Nat.One_nat_def\", \<dots>]"}
   156 end" "[\"Nat.of_nat_eq_id\", \"Int.of_int_eq_id\", \"Nat.One_nat_def\", \<dots>]"}
   184 
   182 
   185 text {*
   183 text {*
   186   One way to construct terms of Isabelle on the ML-level is by using the antiquotation 
   184   One way to construct terms of Isabelle on the ML-level is by using the antiquotation 
   187   \mbox{@{text "@{term \<dots>}"}}. For example
   185   \mbox{@{text "@{term \<dots>}"}}. For example
   188 
   186 
   189   @{ML_response [display] 
   187   @{ML_response [display,gray] 
   190     "@{term \"(a::nat) + b = c\"}" 
   188     "@{term \"(a::nat) + b = c\"}" 
   191     "Const (\"op =\", \<dots>) $ (Const (\"HOL.plus_class.plus\", \<dots>) $ \<dots> $ \<dots>) $ \<dots>"}
   189     "Const (\"op =\", \<dots>) $ (Const (\"HOL.plus_class.plus\", \<dots>) $ \<dots> $ \<dots>) $ \<dots>"}
   192 
   190 
   193   This will show the term @{term "(a::nat) + b = c"}, but printed using the internal
   191   This will show the term @{term "(a::nat) + b = c"}, but printed using the internal
   194   representation of this term. This internal representation corresponds to the 
   192   representation of this term. This internal representation corresponds to the 
   221 
   219 
   222   Hint: The third term is already quite big, and the pretty printer
   220   Hint: The third term is already quite big, and the pretty printer
   223   may omit parts of it by default. If you want to see all of it, you
   221   may omit parts of it by default. If you want to see all of it, you
   224   can use the following ML function to set the limit to a value high 
   222   can use the following ML function to set the limit to a value high 
   225   enough:
   223   enough:
       
   224 
       
   225   @{ML [display] "print_depth 50"}
   226   \end{exercise}
   226   \end{exercise}
   227 
       
   228   @{ML [display] "print_depth 50"}
       
   229 
   227 
   230   The antiquotation @{text "@{prop \<dots>}"} constructs terms of propositional type, 
   228   The antiquotation @{text "@{prop \<dots>}"} constructs terms of propositional type, 
   231   inserting the invisible @{text "Trueprop"}-coercions whenever necessary. 
   229   inserting the invisible @{text "Trueprop"}-coercions whenever necessary. 
   232   Consider for example the pairs
   230   Consider for example the pairs
   233 
   231 
   234   @{ML_response [display] "(@{term \"P x\"}, @{prop \"P x\"})" "(Free (\"P\", \<dots>) $ Free (\"x\", \<dots>),
   232   @{ML_response [display,gray] "(@{term \"P x\"}, @{prop \"P x\"})" "(Free (\"P\", \<dots>) $ Free (\"x\", \<dots>),
   235  Const (\"Trueprop\", \<dots>) $ (Free (\"P\", \<dots>) $ Free (\"x\", \<dots>)))"}
   233  Const (\"Trueprop\", \<dots>) $ (Free (\"P\", \<dots>) $ Free (\"x\", \<dots>)))"}
   236  
   234  
   237   where an coercion is inserted in the second component and 
   235   where an coercion is inserted in the second component and 
   238 
   236 
   239   @{ML_response [display] "(@{term \"P x \<Longrightarrow> Q x\"}, @{prop \"P x \<Longrightarrow> Q x\"})" 
   237   @{ML_response [display,gray] "(@{term \"P x \<Longrightarrow> Q x\"}, @{prop \"P x \<Longrightarrow> Q x\"})" 
   240   "(Const (\"==>\", \<dots>) $ \<dots> $ \<dots>, Const (\"==>\", \<dots>) $ \<dots> $ \<dots>)"}
   238   "(Const (\"==>\", \<dots>) $ \<dots> $ \<dots>, Const (\"==>\", \<dots>) $ \<dots> $ \<dots>)"}
   241 
   239 
   242   where it is not (since it is already constructed using the meta-implication). 
   240   where it is not (since it is already constructed by a meta-implication). 
   243 
   241 
   244   Types can be constructed using the antiquotation @{text "@{typ \<dots>}"}. For example
   242   Types can be constructed using the antiquotation @{text "@{typ \<dots>}"}. For example
   245 
   243 
   246   @{ML_response_fake [display] "@{typ \"bool \<Rightarrow> nat\"}" "bool \<Rightarrow> nat"}
   244   @{ML_response_fake [display,gray] "@{typ \"bool \<Rightarrow> nat\"}" "bool \<Rightarrow> nat"}
   247 
   245 
   248   \begin{readmore}
   246   \begin{readmore}
   249   Types are described in detail in \isccite{sec:types}. Their
   247   Types are described in detail in \isccite{sec:types}. Their
   250   definition and many useful operations can also be found in @{ML_file "Pure/type.ML"}.
   248   definition and many useful operations can also be found in @{ML_file "Pure/type.ML"}.
   251   \end{readmore}
   249   \end{readmore}
   281 text {*
   279 text {*
   282   To see this apply @{text "@{term S}"}, @{text "@{term T}"} and @{text "@{typ nat}"} 
   280   To see this apply @{text "@{term S}"}, @{text "@{term T}"} and @{text "@{typ nat}"} 
   283   to both functions. With @{ML make_imp} we obtain the correct term involving 
   281   to both functions. With @{ML make_imp} we obtain the correct term involving 
   284   @{term "S"}, @{text "T"} and  @{text "@{typ nat}"} 
   282   @{term "S"}, @{text "T"} and  @{text "@{typ nat}"} 
   285 
   283 
   286   @{ML_response [display] "make_imp @{term S} @{term T} @{typ nat}" 
   284   @{ML_response [display,gray] "make_imp @{term S} @{term T} @{typ nat}" 
   287     "Const \<dots> $ 
   285     "Const \<dots> $ 
   288     Abs (\"x\", Type (\"nat\",[]),
   286     Abs (\"x\", Type (\"nat\",[]),
   289       Const \<dots> $ (Free (\"S\",\<dots>) $ \<dots>) $ 
   287       Const \<dots> $ (Free (\"S\",\<dots>) $ \<dots>) $ 
   290                   (Free (\"T\",\<dots>) $ \<dots>))"}
   288                   (Free (\"T\",\<dots>) $ \<dots>))"}
   291 
   289 
   292   With @{ML make_wrong_imp} we obtain an incorrect term involving the @{term "P"} 
   290   With @{ML make_wrong_imp} we obtain an incorrect term involving the @{term "P"} 
   293   and @{text "Q"} from the antiquotation.
   291   and @{text "Q"} from the antiquotation.
   294 
   292 
   295   @{ML_response [display] "make_wrong_imp @{term S} @{term T} @{typ nat}" 
   293   @{ML_response [display,gray] "make_wrong_imp @{term S} @{term T} @{typ nat}" 
   296     "Const \<dots> $ 
   294     "Const \<dots> $ 
   297     Abs (\"x\", \<dots>,
   295     Abs (\"x\", \<dots>,
   298       Const \<dots> $ (Const \<dots> $ (Free (\"P\",\<dots>) $ \<dots>)) $ 
   296       Const \<dots> $ (Const \<dots> $ (Free (\"P\",\<dots>) $ \<dots>)) $ 
   299                   (Const \<dots> $ (Free (\"Q\",\<dots>) $ \<dots>)))"}
   297                   (Const \<dots> $ (Free (\"Q\",\<dots>) $ \<dots>)))"}
   300 
   298 
   312   "HOL"} indicates in which theory they are defined. Guessing such internal
   310   "HOL"} indicates in which theory they are defined. Guessing such internal
   313   names can sometimes be quite hard. Therefore Isabelle provides the
   311   names can sometimes be quite hard. Therefore Isabelle provides the
   314   antiquotation @{text "@{const_name \<dots>}"} which does the expansion
   312   antiquotation @{text "@{const_name \<dots>}"} which does the expansion
   315   automatically, for example:
   313   automatically, for example:
   316 
   314 
   317   @{ML_response_fake [display] "@{const_name \"Nil\"}" "List.list.Nil"}
   315   @{ML_response_fake [display,gray] "@{const_name \"Nil\"}" "List.list.Nil"}
   318 
   316 
   319   (FIXME: Is it useful to explain @{text "@{const_syntax}"}?)
   317   (FIXME: Is it useful to explain @{text "@{const_syntax}"}?)
   320 
   318 
   321   Similarly, types can be constructed manually, for example as follows:
   319   Similarly, types can be constructed manually, for example as follows:
   322 
   320 
   375 
   373 
   376   Type-checking is always relative to a theory context. For now we use
   374   Type-checking is always relative to a theory context. For now we use
   377   the @{ML "@{theory}"} antiquotation to get hold of the current theory.
   375   the @{ML "@{theory}"} antiquotation to get hold of the current theory.
   378   For example we can write
   376   For example we can write
   379 
   377 
   380   @{ML_response_fake [display] "cterm_of @{theory} @{term \"a + b = c\"}" "a + b = c"}
   378   @{ML_response_fake [display,gray] "cterm_of @{theory} @{term \"a + b = c\"}" "a + b = c"}
   381 
   379 
   382   or use the antiquotation
   380   or use the antiquotation
   383 
   381 
   384   @{ML_response_fake [display] "@{cterm \"(a::nat) + b = c\"}" "a + b = c"}
   382   @{ML_response_fake [display,gray] "@{cterm \"(a::nat) + b = c\"}" "a + b = c"}
   385 
   383 
   386   Attempting
   384   Attempting
   387 
   385 
   388   @{ML_response_fake_both [display] "@{cterm \"1 + True\"}" "Type unification failed \<dots>"}
   386   @{ML_response_fake_both [display,gray] "@{cterm \"1 + True\"}" "Type unification failed \<dots>"}
   389 
   387 
   390   yields an error. A slightly more elaborate example is
   388   yields an error. A slightly more elaborate example is
   391 
   389 
   392 @{ML_response_fake [display] 
   390 @{ML_response_fake [display,gray] 
   393 "let
   391 "let
   394   val natT = @{typ \"nat\"}
   392   val natT = @{typ \"nat\"}
   395   val zero = @{term \"0::nat\"}
   393   val zero = @{term \"0::nat\"}
   396 in
   394 in
   397   cterm_of @{theory} 
   395   cterm_of @{theory} 
   424 text {*
   422 text {*
   425   on the ML-level:\footnote{Note that @{text "|>"} is reverse
   423   on the ML-level:\footnote{Note that @{text "|>"} is reverse
   426   application. This combinator, and several variants are defined in
   424   application. This combinator, and several variants are defined in
   427   @{ML_file "Pure/General/basics.ML"}.}
   425   @{ML_file "Pure/General/basics.ML"}.}
   428 
   426 
   429 @{ML_response_fake [display]
   427 @{ML_response_fake [display,gray]
   430 "let
   428 "let
   431   val thy = @{theory}
   429   val thy = @{theory}
   432 
   430 
   433   val assm1 = cterm_of thy @{prop \"\<And>(x::nat). P x \<Longrightarrow> Q x\"}
   431   val assm1 = cterm_of thy @{prop \"\<And>(x::nat). P x \<Longrightarrow> Q x\"}
   434   val assm2 = cterm_of thy @{prop \"(P::nat\<Rightarrow>bool) t\"}
   432   val assm2 = cterm_of thy @{prop \"(P::nat\<Rightarrow>bool) t\"}
   495   file is most code for dealing with goals?)
   493   file is most code for dealing with goals?)
   496   \end{readmore}
   494   \end{readmore}
   497 
   495 
   498   Tactics are functions that map a goal state to a (lazy)
   496   Tactics are functions that map a goal state to a (lazy)
   499   sequence of successor states, hence the type of a tactic is
   497   sequence of successor states, hence the type of a tactic is
       
   498   
   500   @{ML_type[display] "thm -> thm Seq.seq"}
   499   @{ML_type[display] "thm -> thm Seq.seq"}
   501   
   500   
   502   \begin{readmore}
   501   \begin{readmore}
   503   See @{ML_file "Pure/General/seq.ML"} for the implementation of lazy
   502   See @{ML_file "Pure/General/seq.ML"} for the implementation of lazy
   504   sequences. However in day-to-day Isabelle programming, one rarely 
   503   sequences. However in day-to-day Isabelle programming, one rarely 
   529   (empty in the proof at hand) 
   528   (empty in the proof at hand) 
   530   with the variables @{text xs} that will be generalised once the
   529   with the variables @{text xs} that will be generalised once the
   531   goal is proved. The @{text "tac"} is the tactic which proves the goal and which 
   530   goal is proved. The @{text "tac"} is the tactic which proves the goal and which 
   532   can make use of the local assumptions (there are none in this example).
   531   can make use of the local assumptions (there are none in this example).
   533 
   532 
   534 @{ML_response_fake [display]
   533 @{ML_response_fake [display,gray]
   535 "let
   534 "let
   536   val ctxt = @{context}
   535   val ctxt = @{context}
   537   val goal = @{prop \"P \<or> Q \<Longrightarrow> Q \<or> P\"}
   536   val goal = @{prop \"P \<or> Q \<Longrightarrow> Q \<or> P\"}
   538 in
   537 in
   539   Goal.prove ctxt [\"P\", \"Q\"] [] goal (fn _ => 
   538   Goal.prove ctxt [\"P\", \"Q\"] [] goal (fn _ => 
   550   \end{readmore}
   549   \end{readmore}
   551 
   550 
   552 
   551 
   553   An alternative way to transcribe this proof is as follows 
   552   An alternative way to transcribe this proof is as follows 
   554 
   553 
   555 @{ML_response_fake [display]
   554 @{ML_response_fake [display,gray]
   556 "let
   555 "let
   557   val ctxt = @{context}
   556   val ctxt = @{context}
   558   val goal = @{prop \"P \<or> Q \<Longrightarrow> Q \<or> P\"}
   557   val goal = @{prop \"P \<or> Q \<Longrightarrow> Q \<or> P\"}
   559 in
   558 in
   560   Goal.prove ctxt [\"P\", \"Q\"] [] goal (fn _ => 
   559   Goal.prove ctxt [\"P\", \"Q\"] [] goal (fn _ =>