ProgTutorial/FirstSteps.thy
changeset 299 d0b81d6e1b28
parent 298 8057d65607eb
child 301 2728e8daebc0
--- a/ProgTutorial/FirstSteps.thy	Sat Aug 01 08:59:41 2009 +0200
+++ b/ProgTutorial/FirstSteps.thy	Sun Aug 02 08:44:41 2009 +0200
@@ -852,7 +852,7 @@
   \end{readmore}
 *}
 
-section {* Constructing Terms Manually\label{sec:terms_types_manually} *} 
+section {* Constructing Terms and Types Manually\label{sec:terms_types_manually} *} 
 
 text {*
   While antiquotations are very convenient for constructing terms, they can
@@ -904,18 +904,23 @@
 
 @{ML_response_fake [display,gray]
 "let
-  val t = @{term \"P::nat\"}
+  val trm = @{term \"P::nat\"}
   val args = [@{term \"True\"}, @{term \"False\"}]
 in
-  list_comb (t, args)
+  list_comb (trm, args)
 end"
 "Free (\"P\", \"nat\") $ Const (\"True\", \"bool\") $ Const (\"False\", \"bool\")"}
 
   Another handy function is @{ML [index] lambda}, which abstracts a variable 
   in a term. For example
-  
+
   @{ML_response_fake [display,gray]
-  "lambda @{term \"x::nat\"} @{term \"(P::nat \<Rightarrow> bool) x\"}"
+"let
+  val x_nat = @{term \"x::nat\"}
+  val trm = @{term \"(P::nat \<Rightarrow> bool) x\"}
+in
+  lambda x_nat trm
+end"
   "Abs (\"x\", \"nat\", Free (\"P\", \"bool \<Rightarrow> bool\") $ Bound 0)"}
 
   In this example, @{ML lambda} produces a de Bruijn index (i.e.~@{ML "Bound 0"}), 
@@ -926,10 +931,15 @@
   as in
 
   @{ML_response_fake [display,gray]
-  "lambda @{term \"x::nat\"} @{term \"(P::bool \<Rightarrow> bool) x\"}"
-  "Abs (\"x\", \"nat\", Free (\"P\", \"bool \<Rightarrow> bool\") $ Free (\"x\", \"bool\"))"}
-
-  then the variable @{text "Free (\"x\", \"bool\")"} is \emph{not} abstracted. 
+"let
+  val x_int = @{term \"x::int\"}
+  val trm = @{term \"(P::nat \<Rightarrow> bool) x\"}
+in
+  lambda x_int trm
+end"
+  "Abs (\"x\", \"int\", Free (\"P\", \"nat \<Rightarrow> bool\") $ Free (\"x\", \"nat\"))"}
+
+  then the variable @{text "Free (\"x\", \"int\")"} is \emph{not} abstracted. 
   This is a fundamental principle
   of Church-style typing, where variables with the same name still differ, if they 
   have different type.
@@ -943,7 +953,7 @@
 "let
   val s1 = (@{term \"(f::nat \<Rightarrow> nat \<Rightarrow> nat) 0\"}, @{term \"y::nat \<Rightarrow> nat\"})
   val s2 = (@{term \"x::nat\"}, @{term \"True\"})
-  val trm =  @{term \"((f::nat \<Rightarrow> nat \<Rightarrow> nat) 0) x\"}
+  val trm = @{term \"((f::nat \<Rightarrow> nat \<Rightarrow> nat) 0) x\"}
 in
   subst_free [s1, s2] trm
 end"
@@ -967,8 +977,11 @@
   arguments. For example
 
 @{ML_response_fake [gray,display]
-  "writeln (Syntax.string_of_term @{context}
-   (HOLogic.mk_eq (@{term \"True\"}, @{term \"False\"})))"
+"let
+  val eq = HOLogic.mk_eq (@{term \"True\"}, @{term \"False\"})
+in
+  writeln (Syntax.string_of_term @{context} eq)
+end"
   "True = False"}
 *}
 
@@ -977,14 +990,11 @@
   Most of the HOL-specific operations on terms and types are defined 
   in @{ML_file "HOL/Tools/hologic.ML"}.
   \end{readmore}
-*}
-
-section {* Constants *}
-
-text {*
-  There are a few subtle issues with constants. They usually crop up when
-  pattern matching terms or types, or when constructing them. While it is perfectly ok
-  to write the function @{text is_true} as follows
+
+  When constructing terms manually, there are a few subtle issues with
+  constants. They usually crop up when pattern matching terms or types, or
+  when constructing them. While it is perfectly ok to write the function
+  @{text is_true} as follows
 *}
 
 ML{*fun is_true @{term True} = true
@@ -1108,11 +1118,7 @@
   Functions about naming are implemented in @{ML_file "Pure/General/name_space.ML"};
   functions about signatures in @{ML_file "Pure/sign.ML"}.
   \end{readmore}
-*}
-
-section {* Constructing Types Manually *}
-
-text {*
+
   Although types of terms can often be inferred, there are many
   situations where you need to construct types manually, especially  
   when defining constants. For example the function returning a function 
@@ -1166,12 +1172,12 @@
   call them as follows
 
   @{ML_response [gray,display]
-  "Term.add_tfrees @{term \"(a,b)\"} []"
+  "Term.add_tfrees @{term \"(a, b)\"} []"
   "[(\"'b\", [\"HOL.type\"]), (\"'a\", [\"HOL.type\"])]"}
 
   The reason for this definition is that @{ML add_tfrees in Term} can
   be easily folded over a list of terms. Similarly for all functions
-  named @{text "add_"}some\_name in @{ML_file "Pure/term.ML"}.
+  named @{text "add_*"} in @{ML_file "Pure/term.ML"}.
 
 *}
 
@@ -2252,4 +2258,6 @@
 
 ML {*Datatype.get_info @{theory} "List.list"*}
 
+section {* Name Space(TBD) *}
+
 end