CookBook/Solutions.thy
changeset 174 a29b81d4fa88
parent 172 ec47352e99c2
child 175 7c09bd3227c5
equal deleted inserted replaced
173:d820cb5873ea 174:a29b81d4fa88
   142 *}(*<*)oops(*>*)
   142 *}(*<*)oops(*>*)
   143 
   143 
   144 text {* \solution{ex:addconversion} *}
   144 text {* \solution{ex:addconversion} *}
   145 
   145 
   146 text {* 
   146 text {* 
   147   To measure the difference, we will create mechanically some terms involving 
   147   We use the timing function @{ML timing_wrapper} from Recipe~\ref{rec:timing}.
   148   additions and then set up a goal to be simplified. To prove the remaining 
   148   To measure any difference between the simproc and conversion, we will create 
   149   goal we use the ``lemma'':
   149   mechanically terms involving additions and then set up a goal to be 
       
   150   simplified. We have to be careful to set up the goal so that
       
   151   other parts of the simplifier do not interfere. For this we set up an
       
   152   unprovable goal which, after simplification, we are going to ``prove'' with
       
   153   the help of the lemma:
   150 *}
   154 *}
   151 
   155 
   152 lemma cheat: "A" sorry
   156 lemma cheat: "A" sorry
   153 
   157 
   154 text {*
   158 text {*
   155   The reason is that it allows us to set up an unprovable goal where we can
   159   For constructing test cases, we first define a function that returns a 
   156   eliminate all interferences from other parts of the simplifier and
   160   complete binary tree whose leaves are numbers and the nodes are 
   157   then prove the goal using @{thm [source] cheat}. We also assume
   161   additions.
   158   the timing function @{ML timing_wrapper} from Recipe~\ref{rec:timing}.
       
   159 
       
   160   First we define a function that returns a complete binary tree whose 
       
   161   leaves are numbers and the nodes are additions.
       
   162 *}
   162 *}
   163 
   163 
   164 ML{*fun term_tree n =
   164 ML{*fun term_tree n =
   165 let
   165 let
   166   val count = ref 0; 
   166   val count = ref 0; 
   173 in
   173 in
   174   term_tree_aux n
   174   term_tree_aux n
   175 end*}
   175 end*}
   176 
   176 
   177 text {*
   177 text {*
   178   For example
   178   This function generates for example
   179 
   179 
   180   @{ML_response_fake [display,gray] 
   180   @{ML_response_fake [display,gray] 
   181   "warning (Syntax.string_of_term @{context} (term_tree 2))" 
   181   "warning (Syntax.string_of_term @{context} (term_tree 2))" 
   182   "(1 + 2) + (3 + 4)"} 
   182   "(1 + 2) + (3 + 4)"} 
   183 
   183 
   184   The next function generates a goal of the form @{text "P \<dots>"} with a term 
   184   The next function constructs a goal of the form @{text "P \<dots>"} with a term 
   185   filled in.
   185   produced by @{ML term_tree} filled in.
   186 *}
   186 *}
   187 
   187 
   188 ML{*fun goal n = HOLogic.mk_Trueprop (@{term "P::nat\<Rightarrow> bool"} $ (term_tree n))*}
   188 ML{*fun goal n = HOLogic.mk_Trueprop (@{term "P::nat\<Rightarrow> bool"} $ (term_tree n))*}
   189 
   189 
   190 text {*
   190 text {*
   191   Note that the goal needs to be wrapped in a @{term "Trueprop"}. Next we define
   191   Note that the goal needs to be wrapped in a @{term "Trueprop"}. Next we define
   192   two tactics, @{text "c_tac"} and @{text "s_tac"}, for the conversion and simproc,
   192   two tactics, @{text "c_tac"} and @{text "s_tac"}, for the conversion and simproc,
   193   respectively. The tactics first apply the conversion (respectively simproc) and 
   193   respectively. The idea is to first apply the conversion (respectively simproc) and 
   194   then prove the remaining goal using the lemma @{thm [source] cheat}.
   194   then prove the remaining goal using the lemma @{thm [source] cheat}.
   195 *}
   195 *}
   196 
   196 
   197 ML{*local
   197 ML{*local
   198   fun mk_tac tac = timing_wrapper (EVERY1 [tac, rtac @{thm cheat}])
   198   fun mk_tac tac = timing_wrapper (EVERY1 [tac, rtac @{thm cheat}])
   199 in
   199 in
   200 val c_tac = mk_tac add_tac
   200 val c_tac = mk_tac add_tac
   201 val s_tac = mk_tac 
   201 val s_tac = mk_tac (simp_tac (HOL_basic_ss addsimprocs [@{simproc add_sp}]))
   202              (simp_tac (HOL_basic_ss addsimprocs [@{simproc add_sp}]))
       
   203 end*}
   202 end*}
   204 
   203 
   205 text {*
   204 text {*
   206   This is all we need to let them run against each other.
   205   This is all we need to let the conversion run against the simproc.
   207 *}
   206 *}
   208 
   207 
   209 ML{*val _ = Goal.prove @{context} [] [] (goal 8) (K c_tac);
   208 ML{*val _ = Goal.prove @{context} [] [] (goal 8) (K c_tac)
   210 val _ = Goal.prove @{context} [] [] (goal 8) (K s_tac)*}
   209 val _ = Goal.prove @{context} [] [] (goal 8) (K s_tac)*}
   211 
   210 
   212 text {*
   211 text {*
   213   As you can see, both versions perform relatively the same with perhaps some
   212   If you do the exercise, you can see that both ways of simplifying additions
   214   advantages for the simproc. That means the simplifier, while much more
   213   perform relatively the same with perhaps some advantages for the
   215   complicated than conversions, is quite good for tasks it is designed for. It
   214   simproc. That means the simplifier, even if much more complicated than
   216   usually does not make sense to implement general-purpose rewriting using
   215   conversions, is quite efficient for tasks it is designed for. It usually does not
       
   216   make sense to implement general-purpose rewriting using
   217   conversions. Conversions only have clear advantages in special situations:
   217   conversions. Conversions only have clear advantages in special situations:
   218   for example if you need to have control over innermost or outermost
   218   for example if you need to have control over innermost or outermost
   219   rewriting; another situation is when rewriting rules are prone to
   219   rewriting, or when rewriting rules are lead to non-termination.
   220   non-termination.
   220 *}
   221 *}
   221 
   222 
   222 end
   223 end