CookBook/FirstSteps.thy
changeset 11 733614e236a3
parent 10 df09e49b19bf
child 12 2f1736cb8f26
equal deleted inserted replaced
10:df09e49b19bf 11:733614e236a3
    62 
    62 
    63 text {*
    63 text {*
    64   then Isabelle's undo operation has no effect on the definition of 
    64   then Isabelle's undo operation has no effect on the definition of 
    65   @{ML "foo"}. 
    65   @{ML "foo"}. 
    66 
    66 
    67   During coding you might find it necessary to quickly inspect some data
    67   During developments you might find it necessary to quickly 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   @{ML "warning"}. For example
    69   the function @{ML "warning"}. For example
    70 *}
    70 *}
    71 
    71 
    72 ML {*
    72 ML {*
    73   val _ = warning "any string"
    73   val _ = warning "any string"
    74 *}
    74 *}
   128 *}
   128 *}
   129 
   129 
   130 section {* Terms *}
   130 section {* Terms *}
   131 
   131 
   132 text {*
   132 text {*
   133   Terms of Isabelle can be constructed on the ML-level using the @{text "@{term \<dots>}"} 
   133   One way to construct terms of Isabelle on the ML-level is by using the antiquotation 
   134   antiquotation:
   134   @{text "@{term \<dots>}"}:
   135 *}
   135 *}
   136 
   136 
   137 ML {* @{term "(a::nat) + b = c"} *}
   137 ML {* @{term "(a::nat) + b = c"} *}
   138 
   138 
   139 text {*
   139 text {*
   140   This will show the term @{term "(a::nat) + b = c"}, but printed out using the internal
   140   This will show the term @{term "(a::nat) + b = c"}, but printed out using the internal
   141   representation of this term. This internal represenation is just a 
   141   representation of this term. This internal represenation corresponds to the 
   142   datatype defined in @{ML_file "Pure/term.ML"}.
   142   datatype defined in @{ML_file "Pure/term.ML"}.
   143   
   143   
   144   The internal representation of terms uses the usual deBruin indices mechanism: bound 
   144   The internal representation of terms uses the usual de-Bruijn indices mechanism where bound 
   145   variables are represented by the constructor @{ML Bound} whose argument refers to
   145   variables are represented by the constructor @{ML Bound}. The index in @{ML Bound} refers to
   146   the number of Abstractions (@{ML Abs}) we have to skip until we hit the @{ML Abs} that
   146   the number of Abstractions (@{ML Abs}) we have to skip until we hit the @{ML Abs} that
   147   binds the corresponding variable. However, the names of bound variables are 
   147   binds the corresponding variable. However, the names of bound variables are 
   148   kept at abstractions for printing purposes, and so should be treated just as comments. 
   148   kept at abstractions for printing purposes, and so should be treated only as comments. 
   149   See \ichcite{ch:logic} for more details.
       
   150 
       
   151   (FIXME: Alex why is the reference bolow given. It somehow does not read
       
   152   with what is written above.)
       
   153 
   149 
   154   \begin{readmore}
   150   \begin{readmore}
   155   Terms are described in detail in \ichcite{ch:logic}. Their
   151   Terms are described in detail in \ichcite{ch:logic}. Their
   156   definition and many useful operations can be found in @{ML_file "Pure/term.ML"}.
   152   definition and many useful operations can be found in @{ML_file "Pure/term.ML"}.
   157   \end{readmore}
   153   \end{readmore}
   172 
   168 
   173   Hint: The third term is already quite big, and the pretty printer
   169   Hint: The third term is already quite big, and the pretty printer
   174   may omit parts of it by default. If you want to see all of it, you
   170   may omit parts of it by default. If you want to see all of it, you
   175   can use @{ML "print_depth 50"} to set the limit to a value high enough.
   171   can use @{ML "print_depth 50"} to set the limit to a value high enough.
   176   \end{exercise}
   172   \end{exercise}
   177 
       
   178   \begin{exercise}
       
   179   Write a function @{ML_text "rev_sum : term -> term"} that takes a
       
   180   term of the form @{text "t\<^isub>1 + t\<^isub>2 + \<dots> + t\<^isub>n"}
       
   181   and returns the reversed sum @{text "t\<^isub>n + \<dots> + t\<^isub>2 + t\<^isub>1"}.
       
   182   Note that @{text "+"} associates to the left.
       
   183   Try your function on some examples, and see if the result typechecks.
       
   184   \end{exercise}
       
   185 *}
       
   186 
       
   187 text {* FIXME: check possible solution *}
       
   188 
       
   189 ML {* 
       
   190   exception FORM_ERROR 
       
   191 
       
   192   fun rev_sum term =
       
   193     case term of
       
   194        @{term "op +"} $ (Free (x,t1)) $ (Free (y,t2)) => 
       
   195                    @{term "op +"} $ (Free (y,t2)) $ (Free (x,t1))
       
   196     |  @{term "op +"} $ left $ (Free (x,t)) => 
       
   197                    @{term "op +"} $ (Free (x,t)) $ (rev_sum left)
       
   198     |  _ => raise FORM_ERROR
       
   199 *}
       
   200 
       
   201 
       
   202 text {*
       
   203   \begin{exercise}
       
   204   Write a function which takes two terms representing natural numbers
       
   205   in unary (like @{term "Suc (Suc (Suc 0))"}), and produce the unary
       
   206   number representing their sum.
       
   207   \end{exercise}
       
   208 
       
   209   \begin{exercise}
       
   210   Look at the functions defined in @{ML_file "Pure/logic.ML"} and
       
   211   @{ML_file "HOL/hologic.ML"} and see if they can make your life
       
   212   easier.
       
   213   \end{exercise}
       
   214 
       
   215   (FIXME what is coming next should fit with the main flow)
       
   216 *}
   173 *}
   217 
   174 
   218 ML {*
   175 ML {*
   219   @{const_name plus}
   176   @{const_name plus}
   220 *}
   177 *}
   237 
   194 
   238 ML {* @{prop "True"} *}
   195 ML {* @{prop "True"} *}
   239 
   196 
   240 
   197 
   241 
   198 
       
   199 section {* Possible Section on Construting Explicitly Terms *} 
       
   200 
       
   201 text {*
       
   202 
       
   203   There is a disadvantage of using the @{text "@{term \<dots>}"} antiquotation
       
   204   directly in order to construct terms. 
       
   205 *}
       
   206 
       
   207 ML {*
       
   208 
       
   209   val nat = HOLogic.natT
       
   210   val x = Free ("x", nat)
       
   211   val t = Free ("t", nat)
       
   212   val P = Free ("P", nat --> HOLogic.boolT)
       
   213   val Q = Free ("Q", nat --> HOLogic.boolT)
       
   214 
       
   215   val A1 = Logic.all x 
       
   216            (Logic.mk_implies (HOLogic.mk_Trueprop (P $ x),
       
   217                               HOLogic.mk_Trueprop (Q $ x)))
       
   218            
       
   219 
       
   220   val A2 = HOLogic.mk_Trueprop (P $ t)
       
   221 
       
   222 *}
       
   223 
       
   224 text {*
       
   225 
       
   226   \begin{exercise}
       
   227   Write a function @{ML_text "rev_sum : term -> term"} that takes a
       
   228   term of the form @{text "t\<^isub>1 + t\<^isub>2 + \<dots> + t\<^isub>n"} (whereby @{text "i"} might be zero)
       
   229   and returns the reversed sum @{text "t\<^isub>n + \<dots> + t\<^isub>2 + t\<^isub>1"}. Assume
       
   230   the @{text "t\<^isub>i"} can be arbitrary expressions and also note that @{text "+"} 
       
   231   associates to the left. Try your function on some examples, and see if 
       
   232   the result typechecks. (FIXME: clash with the type-checking section later)
       
   233   \end{exercise}
       
   234 *}
       
   235 
       
   236 ML {* 
       
   237   fun rev_sum t =
       
   238   let
       
   239    fun dest_sum (Const (@{const_name plus}, _) $ u $ u') = 
       
   240                                                       u' :: dest_sum u
       
   241      | dest_sum u = [u]
       
   242    in
       
   243      foldl1 (HOLogic.mk_binop @{const_name plus}) (dest_sum t)
       
   244    end;
       
   245 *}
       
   246 
       
   247 text {*
       
   248   \begin{exercise}
       
   249   Write a function which takes two terms representing natural numbers
       
   250   in unary (like @{term "Suc (Suc (Suc 0))"}), and produce the unary
       
   251   number representing their sum.
       
   252   \end{exercise}
       
   253 
       
   254 *}
       
   255 
       
   256 ML {*
       
   257   fun make_sum t1 t2 =
       
   258       HOLogic.mk_nat (HOLogic.dest_nat t1 + HOLogic.dest_nat t2)
       
   259 *}
       
   260 
       
   261 
       
   262 text {*
       
   263   \begin{exercise}
       
   264   Look at the functions defined in @{ML_file "Pure/logic.ML"} and
       
   265   @{ML_file "HOL/hologic.ML"} and see if they can make your life
       
   266   easier.
       
   267   \end{exercise}
       
   268 *}
       
   269 
   242 
   270 
   243 section {* Type checking *}
   271 section {* Type checking *}
   244 
   272 
   245 text {* 
   273 text {* 
   246   We can freely construct and manipulate terms, since they are just
   274   We can freely construct and manipulate terms, since they are just
   286   can be proved in ML like 
   314   can be proved in ML like 
   287   this\footnote{Note that @{text "|>"} is just reverse
   315   this\footnote{Note that @{text "|>"} is just reverse
   288   application. This combinator, and several variants are defined in
   316   application. This combinator, and several variants are defined in
   289   @{ML_file "Pure/General/basics.ML"}}:
   317   @{ML_file "Pure/General/basics.ML"}}:
   290 
   318 
   291 
   319 *}
   292   (FIXME: Alex why did you not use antiquotations for this?)
   320 
   293 *}
   321 
   294 
       
   295 ML {*
       
   296 let
       
   297   val thy = @{theory}
       
   298   val nat = HOLogic.natT
       
   299   val x = Free ("x", nat)
       
   300   val t = Free ("t", nat)
       
   301   val P = Free ("P", nat --> HOLogic.boolT)
       
   302   val Q = Free ("Q", nat --> HOLogic.boolT)
       
   303 
       
   304   val A1 = Logic.all x 
       
   305            (Logic.mk_implies (HOLogic.mk_Trueprop (P $ x),
       
   306                               HOLogic.mk_Trueprop (Q $ x)))
       
   307            |> cterm_of thy
       
   308 
       
   309   val A2 = HOLogic.mk_Trueprop (P $ t)
       
   310            |> cterm_of thy
       
   311 
       
   312   val Pt_implies_Qt = 
       
   313         assume A1
       
   314         |> forall_elim (cterm_of thy t)
       
   315 
       
   316   val Qt = implies_elim Pt_implies_Qt (assume A2)
       
   317 in
       
   318   Qt 
       
   319   |> implies_intr A2
       
   320   |> implies_intr A1
       
   321 end
       
   322 *}
       
   323 
   322 
   324 ML {*
   323 ML {*
   325 
   324 
   326 let
   325 let
   327   val thy = @{theory}
   326   val thy = @{theory}
   342 end
   341 end
   343 
   342 
   344 *}
   343 *}
   345 
   344 
   346 text {*
   345 text {*
   347   FIXME Explain this program more carefully
   346   FIXME Explain this program more carefully (@{ML_text assume},  @{ML_text "forall_elim"} \ldots)
   348 *}
   347 *}
   349 
   348 
   350 
   349 
   351 section {* Tactical reasoning *}
   350 section {* Tactical reasoning *}
   352 
   351 
   407 
   406 
   408 text {*
   407 text {*
   409   Tactics that affect only a certain subgoal, take a subgoal number as
   408   Tactics that affect only a certain subgoal, take a subgoal number as
   410   an integer parameter. Here we always work on the first subgoal,
   409   an integer parameter. Here we always work on the first subgoal,
   411   following exactly the @{text "apply"} script.
   410   following exactly the @{text "apply"} script.
       
   411 
       
   412   (Fixme: would it make sense to explain THEN' here)
       
   413 
   412 *}
   414 *}
   413 
   415 
   414 
   416 
   415 section {* Case Study: Relation Composition *}
   417 section {* Case Study: Relation Composition *}
   416 
   418