ProgTutorial/FirstSteps.thy
changeset 301 2728e8daebc0
parent 299 d0b81d6e1b28
child 304 14173c0e8688
equal deleted inserted replaced
300:f286dfa9f173 301:2728e8daebc0
     1 theory FirstSteps
     1 theory FirstSteps
     2 imports Base
     2 imports Base
     3 begin
     3 begin
     4 
     4 
     5 chapter {* First Steps *}
     5 chapter {* First Steps *}
     6 
       
     7 
     6 
     8 text {*
     7 text {*
     9   Isabelle programming is done in ML. Just like lemmas and proofs, ML-code
     8   Isabelle programming is done in ML. Just like lemmas and proofs, ML-code
    10   in Isabelle is part of a theory. If you want to follow the code given in
     9   in Isabelle is part of a theory. If you want to follow the code given in
    11   this chapter, we assume you are working inside the theory starting with
    10   this chapter, we assume you are working inside the theory starting with
   228 text {*
   227 text {*
   229   Theorems also include schematic variables, such as @{text "?P"}, 
   228   Theorems also include schematic variables, such as @{text "?P"}, 
   230   @{text "?Q"} and so on. 
   229   @{text "?Q"} and so on. 
   231 
   230 
   232   @{ML_response_fake [display, gray]
   231   @{ML_response_fake [display, gray]
   233   "writeln (string_of_thm @{context} @{thm conjI})"
   232   "tracing (string_of_thm @{context} @{thm conjI})"
   234   "\<lbrakk>?P; ?Q\<rbrakk> \<Longrightarrow> ?P \<and> ?Q"}
   233   "\<lbrakk>?P; ?Q\<rbrakk> \<Longrightarrow> ?P \<and> ?Q"}
   235 
   234 
   236   In order to improve the readability of theorems we convert
   235   In order to improve the readability of theorems we convert
   237   these schematic variables into free variables using the 
   236   these schematic variables into free variables using the 
   238   function @{ML [index] import in Variable}.
   237   function @{ML [index] import in Variable}.
   250 
   249 
   251 text {* 
   250 text {* 
   252   Theorem @{thm [source] conjI} is now printed as follows:
   251   Theorem @{thm [source] conjI} is now printed as follows:
   253 
   252 
   254   @{ML_response_fake [display, gray]
   253   @{ML_response_fake [display, gray]
   255   "writeln (string_of_thm_no_vars @{context} @{thm conjI})"
   254   "tracing (string_of_thm_no_vars @{context} @{thm conjI})"
   256   "\<lbrakk>P; Q\<rbrakk> \<Longrightarrow> P \<and> Q"}
   255   "\<lbrakk>P; Q\<rbrakk> \<Longrightarrow> P \<and> Q"}
   257   
   256   
   258   Again the function @{ML commas} helps with printing more than one theorem. 
   257   Again the function @{ML commas} helps with printing more than one theorem. 
   259 *}
   258 *}
   260 
   259 
   357   val t = @{term \"P::nat \<Rightarrow> int \<Rightarrow> unit \<Rightarrow> bool\"}
   356   val t = @{term \"P::nat \<Rightarrow> int \<Rightarrow> unit \<Rightarrow> bool\"}
   358   val ctxt = @{context}
   357   val ctxt = @{context}
   359 in 
   358 in 
   360   apply_fresh_args t ctxt
   359   apply_fresh_args t ctxt
   361    |> Syntax.string_of_term ctxt
   360    |> Syntax.string_of_term ctxt
   362    |> writeln
   361    |> tracing
   363 end" 
   362 end" 
   364   "P z za zb"}
   363   "P z za zb"}
   365 
   364 
   366   You can read off this behaviour from how @{ML apply_fresh_args} is
   365   You can read off this behaviour from how @{ML apply_fresh_args} is
   367   coded: in Line 2, the function @{ML [index] fastype_of} calculates the type of the
   366   coded: in Line 2, the function @{ML [index] fastype_of} calculates the type of the
   382   val t = @{term \"za::'a \<Rightarrow> 'b \<Rightarrow> 'c\"}
   381   val t = @{term \"za::'a \<Rightarrow> 'b \<Rightarrow> 'c\"}
   383   val ctxt = @{context}
   382   val ctxt = @{context}
   384 in
   383 in
   385   apply_fresh_args t ctxt 
   384   apply_fresh_args t ctxt 
   386    |> Syntax.string_of_term ctxt
   385    |> Syntax.string_of_term ctxt
   387    |> writeln
   386    |> tracing
   388 end"
   387 end"
   389   "za z zb"}
   388   "za z zb"}
   390   
   389   
   391   where the @{text "za"} is correctly avoided.
   390   where the @{text "za"} is correctly avoided.
   392 
   391 
   741 "let
   740 "let
   742   val v1 = Var ((\"x\", 3), @{typ bool})
   741   val v1 = Var ((\"x\", 3), @{typ bool})
   743   val v2 = Var ((\"x1\", 3), @{typ bool})
   742   val v2 = Var ((\"x1\", 3), @{typ bool})
   744   val v3 = Free (\"x\", @{typ bool})
   743   val v3 = Free (\"x\", @{typ bool})
   745 in
   744 in
   746   writeln (Syntax.string_of_term @{context} v1);
   745   tracing (Syntax.string_of_term @{context} v1);
   747   writeln (Syntax.string_of_term @{context} v2);
   746   tracing (Syntax.string_of_term @{context} v2);
   748   writeln (Syntax.string_of_term @{context} v3)
   747   tracing (Syntax.string_of_term @{context} v3)
   749 end"
   748 end"
   750 "?x3
   749 "?x3
   751 ?x1.3
   750 ?x1.3
   752 x"}
   751 x"}
   753 
   752 
   774 
   773 
   775   @{ML_response_fake [display,gray] 
   774   @{ML_response_fake [display,gray] 
   776 "let
   775 "let
   777   val omega = Free (\"x\", @{typ nat}) $ Free (\"x\", @{typ nat})
   776   val omega = Free (\"x\", @{typ nat}) $ Free (\"x\", @{typ nat})
   778 in 
   777 in 
   779   writeln (Syntax.string_of_term @{context} omega)
   778   tracing (Syntax.string_of_term @{context} omega)
   780 end"
   779 end"
   781   "x x"}
   780   "x x"}
   782 
   781 
   783   with the raw ML-constructors.
   782   with the raw ML-constructors.
   784   
   783   
   978 
   977 
   979 @{ML_response_fake [gray,display]
   978 @{ML_response_fake [gray,display]
   980 "let
   979 "let
   981   val eq = HOLogic.mk_eq (@{term \"True\"}, @{term \"False\"})
   980   val eq = HOLogic.mk_eq (@{term \"True\"}, @{term \"False\"})
   982 in
   981 in
   983   writeln (Syntax.string_of_term @{context} eq)
   982   tracing (Syntax.string_of_term @{context} eq)
   984 end"
   983 end"
   985   "True = False"}
   984   "True = False"}
   986 *}
   985 *}
   987 
   986 
   988 text {*
   987 text {*
  1906           | SOME i => Int.toString i
  1905           | SOME i => Int.toString i
  1907       val s3 =
  1906       val s3 =
  1908          case realOut (!r) of
  1907          case realOut (!r) of
  1909             NONE => "NONE"
  1908             NONE => "NONE"
  1910           | SOME x => Real.toString x
  1909           | SOME x => Real.toString x
  1911       val () = writeln (concat [s1, " ", s2, " ", s3, "\n"])
  1910       val () = tracing (concat [s1, " ", s2, " ", s3, "\n"])
  1912    end*}
  1911    end*}
  1913 
  1912 
  1914 ML_val{*structure t = Test(U) *} 
  1913 ML_val{*structure t = Test(U) *} 
  1915 
  1914 
  1916 ML_val{*structure Datatab = TableFun(type key = int val ord = int_ord);*}
  1915 ML_val{*structure Datatab = TableFun(type key = int val ord = int_ord);*}
  1983   string}. This can be done with the function @{ML [index] string_of in Pretty}. In what
  1982   string}. This can be done with the function @{ML [index] string_of in Pretty}. In what
  1984   follows we will use the following wrapper function for printing a pretty
  1983   follows we will use the following wrapper function for printing a pretty
  1985   type:
  1984   type:
  1986 *}
  1985 *}
  1987 
  1986 
  1988 ML{*fun pprint prt = writeln (Pretty.string_of prt)*}
  1987 ML{*fun pprint prt = tracing (Pretty.string_of prt)*}
  1989 
  1988 
  1990 text {*
  1989 text {*
  1991   The point of the pretty-printing infrastructure is to give hints about how to
  1990   The point of the pretty-printing infrastructure is to give hints about how to
  1992   layout text and let Isabelle do the actual layout. Let us first explain
  1991   layout text and let Isabelle do the actual layout. Let us first explain
  1993   how you can insert places where a line break can occur. For this assume the
  1992   how you can insert places where a line break can occur. For this assume the
  2006   We deliberately chose a large string so that it spans over more than one line. 
  2005   We deliberately chose a large string so that it spans over more than one line. 
  2007   If we print out the string using the usual ``quick-and-dirty'' method, then
  2006   If we print out the string using the usual ``quick-and-dirty'' method, then
  2008   we obtain the ugly output:
  2007   we obtain the ugly output:
  2009 
  2008 
  2010 @{ML_response_fake [display,gray]
  2009 @{ML_response_fake [display,gray]
  2011 "writeln test_str"
  2010 "tracing test_str"
  2012 "fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar foooooooooo
  2011 "fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar foooooooooo
  2013 ooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaa
  2012 ooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaa
  2014 aaaaaaar fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar fo
  2013 aaaaaaar fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar fo
  2015 oooooooooooooobaaaaaaaaaaaar"}
  2014 oooooooooooooobaaaaaaaaaaaar"}
  2016 
  2015 
  2210 *}
  2209 *}
  2211 
  2210 
  2212 text {* the infrastructure of Syntax-pretty-term makes sure it is printed nicely  *}
  2211 text {* the infrastructure of Syntax-pretty-term makes sure it is printed nicely  *}
  2213 
  2212 
  2214 
  2213 
  2215 ML {* Pretty.mark Markup.hilite (Pretty.str "foo") |> Pretty.string_of  |> writeln *}
  2214 ML {* Pretty.mark Markup.hilite (Pretty.str "foo") |> Pretty.string_of  |> tracing *}
  2216 ML {* (Pretty.str "bar") |> Pretty.string_of |> writeln *}
  2215 ML {* (Pretty.str "bar") |> Pretty.string_of |> tracing *}
  2217 
  2216 
  2218 
  2217 
  2219 ML {* Pretty.mark Markup.subgoal (Pretty.str "foo") |> Pretty.string_of  |> writeln *}
  2218 ML {* Pretty.mark Markup.subgoal (Pretty.str "foo") |> Pretty.string_of  |> tracing *}
  2220 ML {* (Pretty.str "bar") |> Pretty.string_of |> writeln *}
  2219 ML {* (Pretty.str "bar") |> Pretty.string_of |> tracing *}
  2221 
  2220 
  2222 text {*
  2221 text {*
  2223   Still to be done:
  2222   Still to be done:
  2224 
  2223 
  2225   What happens with big formulae?
  2224   What happens with big formulae?
  2236 text {*
  2235 text {*
  2237   printing into the goal buffer as part of the proof state
  2236   printing into the goal buffer as part of the proof state
  2238 *}
  2237 *}
  2239 
  2238 
  2240 
  2239 
  2241 ML {* Pretty.mark Markup.hilite (Pretty.str "foo") |> Pretty.string_of  |> writeln *}
  2240 ML {* Pretty.mark Markup.hilite (Pretty.str "foo") |> Pretty.string_of  |> tracing *}
  2242 ML {* (Pretty.str "bar") |> Pretty.string_of |> writeln *}
  2241 ML {* (Pretty.str "bar") |> Pretty.string_of |> tracing *}
  2243 
  2242 
  2244 text {* writing into the goal buffer *}
  2243 text {* writing into the goal buffer *}
  2245 
  2244 
  2246 ML {* fun my_hook interactive state =
  2245 ML {* fun my_hook interactive state =
  2247          (interactive ? Proof.goal_message (fn () => Pretty.str  
  2246          (interactive ? Proof.goal_message (fn () => Pretty.str  
  2258 
  2257 
  2259 ML {*Datatype.get_info @{theory} "List.list"*}
  2258 ML {*Datatype.get_info @{theory} "List.list"*}
  2260 
  2259 
  2261 section {* Name Space(TBD) *}
  2260 section {* Name Space(TBD) *}
  2262 
  2261 
       
  2262 
  2263 end
  2263 end