ProgTutorial/Essential.thy
changeset 396 a2e49e0771b3
parent 395 2c392f61f400
child 398 7f7080ce7c2b
equal deleted inserted replaced
395:2c392f61f400 396:a2e49e0771b3
  1339 
  1339 
  1340 local_setup %gray {*
  1340 local_setup %gray {*
  1341   Local_Theory.note ((@{binding "my_thm"}, []), [my_thm]) #> snd *}
  1341   Local_Theory.note ((@{binding "my_thm"}, []), [my_thm]) #> snd *}
  1342 
  1342 
  1343 text {*
  1343 text {*
  1344   The fourth argument of @{ML note in Local_Theory} is the list of theorems we
  1344   The third argument of @{ML note in Local_Theory} is the list of theorems we
  1345   want to store under a name. We can store more than one under a single name. 
  1345   want to store under a name. We can store more than one under a single name. 
  1346   The first argument @{ML_ind theoremK in Thm} is
  1346   The first argument of @{ML note in Local_Theory} is the name under
  1347   a kind indicator, which classifies the theorem. There are several such kind
  1347   which we store the theorem or theorems. The second argument can contain a
  1348   indicators: for a theorem arising from a definition you should use @{ML_ind
       
  1349   definitionK in Thm}, and for
       
  1350   ``normal'' theorems the kinds @{ML_ind theoremK in Thm} or @{ML_ind lemmaK
       
  1351   in Thm}.  The second argument of @{ML note in Local_Theory} is the name under
       
  1352   which we store the theorem or theorems. The third argument can contain a
       
  1353   list of theorem attributes, which we will explain in detail in
  1348   list of theorem attributes, which we will explain in detail in
  1354   Section~\ref{sec:attributes}. Below we just use one such attribute for
  1349   Section~\ref{sec:attributes}. Below we just use one such attribute for
  1355   adding the theorem to the simpset:
  1350   adding the theorem to the simpset:
  1356 *}
  1351 *}
  1357 
  1352 
  1898   as argument and resolve the theorem with this list (one theorem 
  1893   as argument and resolve the theorem with this list (one theorem 
  1899   after another). The code for this attribute is
  1894   after another). The code for this attribute is
  1900 *}
  1895 *}
  1901 
  1896 
  1902 ML{*fun MY_THEN thms = 
  1897 ML{*fun MY_THEN thms = 
  1903   Thm.rule_attribute 
  1898 let
  1904     (fn _ => fn thm => fold (curry ((op RS) o swap)) thms thm)*}
  1899   fun RS_rev thm1 thm2 = thm2 RS thm1
       
  1900 in
       
  1901   Thm.rule_attribute (fn _ => fn thm => fold RS_rev thms thm)
       
  1902 end*}
  1905 
  1903 
  1906 text {* 
  1904 text {* 
  1907   where @{ML swap} swaps the components of a pair. The setup of this theorem
  1905   where for convenience we define the reverse and curried version of @{ML RS}. 
  1908   attribute uses the parser @{ML thms in Attrib}, which parses a list of
  1906   The setup of this theorem attribute uses the parser @{ML thms in Attrib}, 
  1909   theorems. 
  1907   which parses a list of theorems. 
  1910 *}
  1908 *}
  1911 
  1909 
  1912 attribute_setup %gray MY_THEN = {* Attrib.thms >> MY_THEN *} 
  1910 attribute_setup %gray MY_THEN = {* Attrib.thms >> MY_THEN *} 
  1913   "resolving the list of theorems with the theorem"
  1911   "resolving the list of theorems with the theorem"
  1914 
  1912 
  2021   We used in this example two functions declared as @{ML_ind
  2019   We used in this example two functions declared as @{ML_ind
  2022   declaration_attribute in Thm}, but there can be any number of them. We just
  2020   declaration_attribute in Thm}, but there can be any number of them. We just
  2023   have to change the parser for reading the arguments accordingly.
  2021   have to change the parser for reading the arguments accordingly.
  2024 
  2022 
  2025   \footnote{\bf FIXME What are: @{text "theory_attributes"}, @{text "proof_attributes"}?}
  2023   \footnote{\bf FIXME What are: @{text "theory_attributes"}, @{text "proof_attributes"}?}
       
  2024   \footnote{\bf FIXME readmore}
  2026 
  2025 
  2027   \begin{readmore}
  2026   \begin{readmore}
  2028   FIXME: @{ML_file "Pure/more_thm.ML"}; parsers for attributes is in 
  2027   FIXME: @{ML_file "Pure/more_thm.ML"}; parsers for attributes is in 
  2029   @{ML_file "Pure/Isar/attrib.ML"}...also explained in the chapter about
  2028   @{ML_file "Pure/Isar/attrib.ML"}...also explained in the chapter about
  2030   parsing.
  2029   parsing.
  2218 "1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 
  2217 "1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 
  2219 and 22
  2218 and 22
  2220 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 and
  2219 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 and
  2221 28"}
  2220 28"}
  2222 
  2221 
  2223   Next we like to pretty-print a term and its type. For this we use the
  2222   Like @{ML blk in Pretty}, the function @{ML_ind chunks in Pretty} prints out 
  2224   function @{text "tell_type"}.
  2223   a list of items, but automatically inserts forced breaks between each item.
  2225 *}
  2224   Compare
  2226 
  2225 
  2227 ML %linenosgray{*fun tell_type ctxt t = 
  2226   @{ML_response_fake [display,gray]
  2228 let
  2227   "let
  2229   fun pstr s = Pretty.breaks (map Pretty.str (space_explode " " s))
  2228   val a_and_b = [Pretty.str \"a\", Pretty.str \"b\"]
  2230   val ptrm = Pretty.quote (Syntax.pretty_term ctxt t)
  2229 in
  2231   val pty  = Pretty.quote (Syntax.pretty_typ ctxt (fastype_of t))
  2230   pprint (Pretty.blk (0, a_and_b));
  2232 in
  2231   pprint (Pretty.chunks a_and_b)
  2233   pprint (Pretty.blk (0, 
  2232 end"
  2234     (pstr "The term " @ [ptrm] @ pstr " has type " 
  2233 "ab
  2235       @ [pty, Pretty.str "."])))
  2234 a
  2236 end*}
  2235 b"}
  2237 
       
  2238 text {*
       
  2239   In Line 3 we define a function that inserts possible linebreaks in places
       
  2240   where a space is. In Lines 4 and 5 we pretty-print the term and its type
       
  2241   using the functions @{ML_ind  pretty_term in Syntax} and @{ML_ind 
       
  2242   pretty_typ in Syntax}. We also use the function @{ML_ind quote in
       
  2243   Pretty} in order to enclose the term and type inside quotation marks. In
       
  2244   Line 9 we add a period right after the type without the possibility of a
       
  2245   line break, because we do not want that a line break occurs there.
       
  2246   Now you can write
       
  2247 
       
  2248   @{ML_response_fake [display,gray]
       
  2249   "tell_type @{context} @{term \"min (Suc 0)\"}"
       
  2250   "The term \"min (Suc 0)\" has type \"nat \<Rightarrow> nat\"."}
       
  2251   
       
  2252   To see the proper line breaking, you can try out the function on a bigger term 
       
  2253   and type. For example:
       
  2254 
       
  2255   @{ML_response_fake [display,gray]
       
  2256   "tell_type @{context} @{term \"op = (op = (op = (op = (op = op =))))\"}"
       
  2257   "The term \"op = (op = (op = (op = (op = op =))))\" has type 
       
  2258 \"((((('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool\"."}
       
  2259 
  2236 
  2260   The function @{ML_ind big_list in Pretty} helps with printing long lists.
  2237   The function @{ML_ind big_list in Pretty} helps with printing long lists.
  2261   It is used for example in the command \isacommand{print\_theorems}. An
  2238   It is used for example in the command \isacommand{print\_theorems}. An
  2262   example is as follows.
  2239   example is as follows.
  2263 
  2240 
  2274   7
  2251   7
  2275   8
  2252   8
  2276   9
  2253   9
  2277   10"}
  2254   10"}
  2278 
  2255 
  2279   Like @{ML blk in Pretty}, the function @{ML_ind chunks in Pretty} prints out 
  2256   The point of the pretty-printing functions is to conveninetly obtain 
  2280   a list of items, but automatically inserts forced breaks between each item.
  2257   a lay-out of terms and types that is pleasing to the eye. If we print
  2281   Compare
  2258   out the the terms produced by the the function @{ML de_bruijn} from 
  2282 
  2259   exercise~\ref{ex:debruijn} we obtain the following: 
  2283   @{ML_response_fake [display,gray]
  2260 
  2284   "let
  2261   @{ML_response_fake [display,gray]
  2285   val a_and_b = [Pretty.str \"a\", Pretty.str \"b\"]
  2262   "pprint (Syntax.pretty_term  @{context} (de_bruijn 4))"
  2286 in
  2263   "(P 3 = P 4 \<longrightarrow> P 4 \<and> P 3 \<and> P 2 \<and> P 1) \<and>
  2287   pprint (Pretty.blk (0, a_and_b));
  2264 (P 2 = P 3 \<longrightarrow> P 4 \<and> P 3 \<and> P 2 \<and> P 1) \<and>
  2288   pprint (Pretty.chunks a_and_b)
  2265 (P 1 = P 2 \<longrightarrow> P 4 \<and> P 3 \<and> P 2 \<and> P 1) \<and> 
  2289 end"
  2266 (P 1 = P 4 \<longrightarrow> P 4 \<and> P 3 \<and> P 2 \<and> P 1) \<longrightarrow>
  2290 "ab
  2267 P 4 \<and> P 3 \<and> P 2 \<and> P 1"}
  2291 a
  2268 
  2292 b"}
  2269   We use the function @{ML_ind pretty_term in Syntax} for pretty-printing
       
  2270   terms. Next we like to pretty-print a term and its type. For this we use the
       
  2271   function @{text "tell_type"}.
       
  2272 *}
       
  2273 
       
  2274 ML %linenosgray{*fun tell_type ctxt trm = 
       
  2275 let
       
  2276   fun pstr s = Pretty.breaks (map Pretty.str (space_explode " " s))
       
  2277   val ptrm = Pretty.quote (Syntax.pretty_term ctxt trm)
       
  2278   val pty  = Pretty.quote (Syntax.pretty_typ ctxt (fastype_of trm))
       
  2279 in
       
  2280   pprint (Pretty.blk (0, 
       
  2281     (pstr "The term " @ [ptrm] @ pstr " has type " 
       
  2282       @ [pty, Pretty.str "."])))
       
  2283 end*}
       
  2284 
       
  2285 text {*
       
  2286   In Line 3 we define a function that inserts possible linebreaks in places
       
  2287   where a space is. In Lines 4 and 5 we pretty-print the term and its type
       
  2288   using the functions @{ML pretty_term in Syntax} and @{ML_ind 
       
  2289   pretty_typ in Syntax}. We also use the function @{ML_ind quote in
       
  2290   Pretty} in order to enclose the term and type inside quotation marks. In
       
  2291   Line 9 we add a period right after the type without the possibility of a
       
  2292   line break, because we do not want that a line break occurs there.
       
  2293   Now you can write
       
  2294 
       
  2295   @{ML_response_fake [display,gray]
       
  2296   "tell_type @{context} @{term \"min (Suc 0)\"}"
       
  2297   "The term \"min (Suc 0)\" has type \"nat \<Rightarrow> nat\"."}
  2293   
  2298   
  2294   \footnote{\bf FIXME: What happens with printing big formulae?}
  2299   To see the proper line breaking, you can try out the function on a bigger term 
  2295 
  2300   and type. For example:
  2296   
  2301 
       
  2302   @{ML_response_fake [display,gray]
       
  2303   "tell_type @{context} @{term \"op = (op = (op = (op = (op = op =))))\"}"
       
  2304   "The term \"op = (op = (op = (op = (op = op =))))\" has type 
       
  2305 \"((((('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool\"."}
  2297 
  2306 
  2298   \begin{readmore}
  2307   \begin{readmore}
  2299   The general infrastructure for pretty-printing is implemented in the file
  2308   The general infrastructure for pretty-printing is implemented in the file
  2300   @{ML_file "Pure/General/pretty.ML"}. The file @{ML_file "Pure/Syntax/syntax.ML"}
  2309   @{ML_file "Pure/General/pretty.ML"}. The file @{ML_file "Pure/Syntax/syntax.ML"}
  2301   contains pretty-printing functions for terms, types, theorems and so on.
  2310   contains pretty-printing functions for terms, types, theorems and so on.
  2302   
  2311   
  2303   @{ML_file "Pure/General/markup.ML"}
  2312   @{ML_file "Pure/General/markup.ML"}
  2304   \end{readmore}
  2313   \end{readmore}
  2305 *}
  2314 *}
  2306 
  2315 
  2307 (*
       
  2308 text {*
       
  2309   printing into the goal buffer as part of the proof state
       
  2310 *}
       
  2311 
       
  2312 text {* writing into the goal buffer *}
       
  2313 
       
  2314 ML {* fun my_hook interactive state =
       
  2315          (interactive ? Proof.goal_message (fn () => Pretty.str  
       
  2316 "foo")) state
       
  2317 *}
       
  2318 
       
  2319 setup %gray {* Context.theory_map (Specification.add_theorem_hook my_hook) *}
       
  2320 
       
  2321 lemma "False"
       
  2322 oops
       
  2323 *)
       
  2324 
       
  2325 (*
       
  2326 ML {*
       
  2327 fun setmp_show_all_types f =
       
  2328    setmp show_all_types
       
  2329          (! show_types orelse ! show_sorts orelse ! show_all_types) f;
       
  2330 
       
  2331 val ctxt = @{context};
       
  2332 val t1 = @{term "undefined::nat"};
       
  2333 val t2 = @{term "Suc y"};
       
  2334 val pty =        Pretty.block (Pretty.breaks
       
  2335              [(setmp show_question_marks false o setmp_show_all_types)
       
  2336                   (Syntax.pretty_term ctxt) t1,
       
  2337               Pretty.str "=", Syntax.pretty_term ctxt t2]);
       
  2338 pty |> Pretty.string_of  
       
  2339 *}
       
  2340 
       
  2341 text {* the infrastructure of Syntax-pretty-term makes sure it is printed nicely  *}
       
  2342 
       
  2343 
       
  2344 ML {* Pretty.mark Markup.hilite (Pretty.str "foo") |> Pretty.string_of  |> tracing *}
       
  2345 ML {* (Pretty.str "bar") |> Pretty.string_of |> tracing *}
       
  2346 *)
       
  2347 
       
  2348 section {* Summary *}
  2316 section {* Summary *}
  2349 
  2317 
  2350 text {*
  2318 text {*
  2351   \begin{conventions}
  2319   \begin{conventions}
  2352   \begin{itemize}
  2320   \begin{itemize}