2204 |
2204 |
2205 definition id2::"'a \<Rightarrow> 'a" |
2205 definition id2::"'a \<Rightarrow> 'a" |
2206 where "id2 \<equiv> \<lambda>x. x" |
2206 where "id2 \<equiv> \<lambda>x. x" |
2207 |
2207 |
2208 text {* |
2208 text {* |
2209 Both definitions define the same function. Indeed, the |
2209 Both definitions define the same function, although the theorems @{thm |
2210 function @{ML_ind abs_def in Drule} can automatically |
2210 [source] id1_def} and @{thm [source] id2_def} are different. However it is |
2211 transform the theorem @{thm [source] id1_def} into |
2211 easy to transform one theorem into the other. The function @{ML_ind abs_def |
2212 the theorem @{thm [source] id2_def}. |
2212 in Drule} can automatically transform theorem @{thm [source] id1_def} |
|
2213 into @{thm [source] id2_def} by abstracting all variables on the |
|
2214 left-hand side in the right-hand side. |
2213 |
2215 |
2214 @{ML_response_fake [display,gray] |
2216 @{ML_response_fake [display,gray] |
2215 "Drule.abs_def @{thm id1_def}" |
2217 "Drule.abs_def @{thm id1_def}" |
2216 "id1 \<equiv> \<lambda>x. x"} |
2218 "id1 \<equiv> \<lambda>x. x"} |
2217 |
2219 |
2218 There is however no function inIsabelle that transforms |
2220 Unfortunately, Isabelle has no build-in function that transforms the |
2219 the theorems in the other direction. We can implement one |
2221 theorems in the other direction. We can conveniently implement one using |
2220 using conversions. The feature of conversions we are |
2222 conversions. The feature of conversions we are using is that if we apply a |
2221 using is that if we apply a @{ML_type cterm} to a |
2223 @{ML_type cterm} to a conversion we obtain a meta-equality theorem (recall |
2222 conversion we obtain a meta-equality theorem. The |
2224 that the type of conversions is an abbreviation for |
2223 code of the transformation is below. |
2225 @{ML_type "cterm -> thm"}). The code of the transformation is below. |
2224 *} |
2226 *} |
2225 |
2227 |
2226 ML %linenosgray{*fun unabs_def ctxt def = |
2228 ML %linenosgray{*fun unabs_def ctxt def = |
2227 let |
2229 let |
2228 val (lhs, rhs) = Thm.dest_equals (cprop_of def) |
2230 val (lhs, rhs) = Thm.dest_equals (cprop_of def) |
2232 val thy = ProofContext.theory_of ctxt' |
2234 val thy = ProofContext.theory_of ctxt' |
2233 val cxs = map (cterm_of thy o Free) xs |
2235 val cxs = map (cterm_of thy o Free) xs |
2234 val new_lhs = Drule.list_comb (lhs, cxs) |
2236 val new_lhs = Drule.list_comb (lhs, cxs) |
2235 |
2237 |
2236 fun get_conv [] = Conv.rewr_conv def |
2238 fun get_conv [] = Conv.rewr_conv def |
2237 | get_conv (x::xs) = Conv.fun_conv (get_conv xs) |
2239 | get_conv (_::xs) = Conv.fun_conv (get_conv xs) |
2238 in |
2240 in |
2239 get_conv xs new_lhs |> |
2241 get_conv xs new_lhs |> |
2240 singleton (ProofContext.export ctxt' ctxt) |
2242 singleton (ProofContext.export ctxt' ctxt) |
2241 end*} |
2243 end*} |
2242 |
2244 |
2243 text {* |
2245 text {* |
2244 In Line 3 we destruct the meta-equality into the @{ML_type cterm}s |
2246 In Line 3 we destruct the meta-equality into the @{ML_type cterm}s |
2245 corresponding to the left-hand and right-hand side of the meta-equality. The |
2247 corresponding to the left-hand and right-hand side of the meta-equality. The |
2246 assumption in @{ML unabs_def} is that the right-hand side is an |
2248 assumption in @{ML unabs_def} is that the right-hand side is an |
2247 abstraction. We compute the list of abstracted variables in Line 4 using the |
2249 abstraction. We compute the possibly empty list of abstracted variables in |
2248 function @{ML_ind strip_abs_vars}. For this we have to transform the |
2250 Line 4 using the function @{ML_ind strip_abs_vars}. For this we have to |
2249 @{ML_type cterm} into @{ML_type term}. In Line 5 we importing these |
2251 transform the @{ML_type cterm} into a @{ML_type term}. In Line 5 we |
2250 variables into the context @{ML_text ctxt'}, in order to export them again |
2252 importing these variables into the context @{ML_text ctxt'}, in order to |
2251 in Line 15. In Line 8 we certify the list of variables, which in turn we |
2253 export them again in Line 15. In Line 8 we certify the list of variables, |
2252 apply to the @{ML_text lhs} of the definition using the function @{ML_ind |
2254 which in turn we apply to the @{ML_text lhs} of the definition using the |
2253 list_comb in Drule}. In Line 11 and 12 generate the conversion according to |
2255 function @{ML_ind list_comb in Drule}. In Line 11 and 12 we generate the |
2254 the length of the list of variables. If there are none, we just return the |
2256 conversion according to the length of the list of (abstracted) variables. If |
2255 conversion corresponding to the original definition. If there are variables, |
2257 there are none, then we just return the conversion corresponding to the |
2256 we have to prefix this conversion with @{ML_ind fun_conv in Conv}. Now in |
2258 original definition. If there are variables, then we have to prefix this |
2257 Line 14 we only have to apply the new left-hand side to the generated |
2259 conversion with @{ML_ind fun_conv in Conv}. Now in Line 14 we only have to |
2258 conversion and obtain the the theorem we are after. In Line 15 we only have |
2260 apply the new left-hand side to the generated conversion and obtain the the |
2259 to export the context @{ML_text ctxt'} in order to produce meta-variables |
2261 theorem we want to construct. As mentioned above, in Line 15 we only have to |
2260 for the theorem. For example |
2262 export the context @{ML_text ctxt'} in order to produce meta-variables for |
2261 |
2263 the theorem. An example is as follows. |
2262 |
2264 |
2263 @{ML_response_fake [display, gray] |
2265 @{ML_response_fake [display, gray] |
2264 "unabs_def @{context} @{thm id2_def}" |
2266 "unabs_def @{context} @{thm id2_def}" |
2265 "id2 ?x1 \<equiv> ?x1"} |
2267 "id2 ?x1 \<equiv> ?x1"} |
2266 *} |
2268 *} |