36 fun mk_compose flag (trm1, trm2) = |
39 fun mk_compose flag (trm1, trm2) = |
37 case flag of |
40 case flag of |
38 absF => Const (@{const_name "comp"}, dummyT) $ trm1 $ trm2 |
41 absF => Const (@{const_name "comp"}, dummyT) $ trm1 $ trm2 |
39 | repF => Const (@{const_name "comp"}, dummyT) $ trm2 $ trm1 |
42 | repF => Const (@{const_name "comp"}, dummyT) $ trm2 $ trm1 |
40 |
43 |
41 fun absrep_fun_aux lthy s fs = |
44 fun get_map ctxt ty_str = |
42 let |
45 let |
43 val thy = ProofContext.theory_of lthy |
46 val thy = ProofContext.theory_of ctxt |
44 val exc = LIFT_MATCH (space_implode " " ["absrep_fun_aux: no map for type", quote s, "."]) |
47 val exc = LIFT_MATCH (space_implode " " ["absrep_fun: no map for type", quote ty_str, "."]) |
45 val info = maps_lookup thy s handle NotFound => raise exc |
48 val info = maps_lookup thy ty_str handle NotFound => raise exc |
46 in |
49 in |
47 list_comb (Const (#mapfun info, dummyT), fs) |
50 Const (#mapfun info, dummyT) |
48 end |
51 end |
49 |
52 |
50 fun get_const flag lthy _ qty = |
53 fun get_absrep_const flag ctxt _ qty = |
51 (* FIXME: check here that the type-constructors of _ and qty are related *) |
54 (* FIXME: check here that the type-constructors of _ and qty are related *) |
52 let |
55 let |
53 val thy = ProofContext.theory_of lthy |
56 val thy = ProofContext.theory_of ctxt |
54 val qty_name = Long_Name.base_name (fst (dest_Type qty)) |
57 val qty_name = Long_Name.base_name (fst (dest_Type qty)) |
55 in |
58 in |
56 case flag of |
59 case flag of |
57 absF => Const (Sign.full_bname thy ("abs_" ^ qty_name), dummyT) |
60 absF => Const (Sign.full_bname thy ("abs_" ^ qty_name), dummyT) |
58 | repF => Const (Sign.full_bname thy ("rep_" ^ qty_name), dummyT) |
61 | repF => Const (Sign.full_bname thy ("rep_" ^ qty_name), dummyT) |
59 end |
62 end |
60 |
63 |
61 fun absrep_fun flag lthy (rty, qty) = |
64 fun absrep_fun flag ctxt (rty, qty) = |
62 if rty = qty then mk_identity qty else |
65 if rty = qty then mk_identity qty else |
63 case (rty, qty) of |
66 case (rty, qty) of |
64 (Type ("fun", [ty1, ty2]), Type ("fun", [ty1', ty2'])) => |
67 (Type ("fun", [ty1, ty2]), Type ("fun", [ty1', ty2'])) => |
65 let |
68 let |
66 val fs_ty1 = absrep_fun (negF flag) lthy (ty1, ty1') |
69 val arg1 = absrep_fun (negF flag) ctxt (ty1, ty1') |
67 val fs_ty2 = absrep_fun flag lthy (ty2, ty2') |
70 val arg2 = absrep_fun flag ctxt (ty2, ty2') |
68 in |
71 in |
69 absrep_fun_aux lthy "fun" [fs_ty1, fs_ty2] |
72 list_comb (get_map ctxt "fun", [arg1, arg2]) |
70 end |
73 end |
71 | (Type (s, _), Type (s', [])) => |
74 | (Type (s, _), Type (s', [])) => |
72 if s = s' |
75 if s = s' |
73 then mk_identity qty |
76 then mk_identity qty |
74 else get_const flag lthy rty qty |
77 else get_absrep_const flag ctxt rty qty |
75 | (Type (s, tys), Type (s', tys')) => |
78 | (Type (s, tys), Type (s', tys')) => |
76 let |
79 let |
77 val args = map (absrep_fun flag lthy) (tys ~~ tys') |
80 val args = map (absrep_fun flag ctxt) (tys ~~ tys') |
78 in |
81 val result = list_comb (get_map ctxt s, args) |
|
82 in |
79 if s = s' |
83 if s = s' |
80 then absrep_fun_aux lthy s args |
84 then result |
81 else mk_compose flag (get_const flag lthy rty qty, absrep_fun_aux lthy s args) |
85 else mk_compose flag (get_absrep_const flag ctxt rty qty, result) |
82 end |
86 end |
83 | (TFree x, TFree x') => |
87 | (TFree x, TFree x') => |
84 if x = x' |
88 if x = x' |
85 then mk_identity qty |
89 then mk_identity qty |
86 else raise (LIFT_MATCH "absrep_fun (frees)") |
90 else raise (LIFT_MATCH "absrep_fun (frees)") |
87 | (TVar _, TVar _) => raise (LIFT_MATCH "absrep_fun (vars)") |
91 | (TVar _, TVar _) => raise (LIFT_MATCH "absrep_fun (vars)") |
88 | _ => raise (LIFT_MATCH "absrep_fun (default)") |
92 | _ => raise (LIFT_MATCH "absrep_fun (default)") |
89 |
93 |
90 fun absrep_fun_chk flag lthy (rty, qty) = |
94 fun absrep_fun_chk flag ctxt (rty, qty) = |
91 absrep_fun flag lthy (rty, qty) |
95 absrep_fun flag ctxt (rty, qty) |
92 |> Syntax.check_term lthy |
96 |> Syntax.check_term ctxt |
93 |
97 |
94 (* |
98 |
95 Regularizing an rtrm means: |
99 (* Regularizing an rtrm means: |
96 |
100 |
97 - Quantifiers over types that need lifting are replaced |
101 - Quantifiers over types that need lifting are replaced |
98 by bounded quantifiers, for example: |
102 by bounded quantifiers, for example: |
99 |
103 |
100 All P ----> All (Respects R) P |
104 All P ----> All (Respects R) P |
178 (* - the result still contains dummyTs *) |
182 (* - the result still contains dummyTs *) |
179 (* *) |
183 (* *) |
180 (* - for regularisation we do not need any *) |
184 (* - for regularisation we do not need any *) |
181 (* special treatment of bound variables *) |
185 (* special treatment of bound variables *) |
182 |
186 |
183 fun regularize_trm lthy (rtrm, qtrm) = |
187 fun regularize_trm ctxt (rtrm, qtrm) = |
184 case (rtrm, qtrm) of |
188 case (rtrm, qtrm) of |
185 (Abs (x, ty, t), Abs (_, ty', t')) => |
189 (Abs (x, ty, t), Abs (_, ty', t')) => |
186 let |
190 let |
187 val subtrm = Abs(x, ty, regularize_trm lthy (t, t')) |
191 val subtrm = Abs(x, ty, regularize_trm ctxt (t, t')) |
188 in |
192 in |
189 if ty = ty' then subtrm |
193 if ty = ty' then subtrm |
190 else mk_babs $ (mk_resp $ mk_resp_arg lthy (ty, ty')) $ subtrm |
194 else mk_babs $ (mk_resp $ mk_resp_arg ctxt (ty, ty')) $ subtrm |
191 end |
195 end |
192 |
196 |
193 | (Const (@{const_name "All"}, ty) $ t, Const (@{const_name "All"}, ty') $ t') => |
197 | (Const (@{const_name "All"}, ty) $ t, Const (@{const_name "All"}, ty') $ t') => |
194 let |
198 let |
195 val subtrm = apply_subt (regularize_trm lthy) (t, t') |
199 val subtrm = apply_subt (regularize_trm ctxt) (t, t') |
196 in |
200 in |
197 if ty = ty' then Const (@{const_name "All"}, ty) $ subtrm |
201 if ty = ty' then Const (@{const_name "All"}, ty) $ subtrm |
198 else mk_ball $ (mk_resp $ mk_resp_arg lthy (qnt_typ ty, qnt_typ ty')) $ subtrm |
202 else mk_ball $ (mk_resp $ mk_resp_arg ctxt (qnt_typ ty, qnt_typ ty')) $ subtrm |
199 end |
203 end |
200 |
204 |
201 | (Const (@{const_name "Ex"}, ty) $ t, Const (@{const_name "Ex"}, ty') $ t') => |
205 | (Const (@{const_name "Ex"}, ty) $ t, Const (@{const_name "Ex"}, ty') $ t') => |
202 let |
206 let |
203 val subtrm = apply_subt (regularize_trm lthy) (t, t') |
207 val subtrm = apply_subt (regularize_trm ctxt) (t, t') |
204 in |
208 in |
205 if ty = ty' then Const (@{const_name "Ex"}, ty) $ subtrm |
209 if ty = ty' then Const (@{const_name "Ex"}, ty) $ subtrm |
206 else mk_bex $ (mk_resp $ mk_resp_arg lthy (qnt_typ ty, qnt_typ ty')) $ subtrm |
210 else mk_bex $ (mk_resp $ mk_resp_arg ctxt (qnt_typ ty, qnt_typ ty')) $ subtrm |
207 end |
211 end |
208 |
212 |
209 | (* equalities need to be replaced by appropriate equivalence relations *) |
213 | (* equalities need to be replaced by appropriate equivalence relations *) |
210 (Const (@{const_name "op ="}, ty), Const (@{const_name "op ="}, ty')) => |
214 (Const (@{const_name "op ="}, ty), Const (@{const_name "op ="}, ty')) => |
211 if ty = ty' then rtrm |
215 if ty = ty' then rtrm |
212 else mk_resp_arg lthy (domain_type ty, domain_type ty') |
216 else mk_resp_arg ctxt (domain_type ty, domain_type ty') |
213 |
217 |
214 | (* in this case we just check whether the given equivalence relation is correct *) |
218 | (* in this case we just check whether the given equivalence relation is correct *) |
215 (rel, Const (@{const_name "op ="}, ty')) => |
219 (rel, Const (@{const_name "op ="}, ty')) => |
216 let |
220 let |
217 val exc = LIFT_MATCH "regularise (relation mismatch)" |
221 val exc = LIFT_MATCH "regularise (relation mismatch)" |
218 val rel_ty = (fastype_of rel) handle TERM _ => raise exc |
222 val rel_ty = (fastype_of rel) handle TERM _ => raise exc |
219 val rel' = mk_resp_arg lthy (domain_type rel_ty, domain_type ty') |
223 val rel' = mk_resp_arg ctxt (domain_type rel_ty, domain_type ty') |
220 in |
224 in |
221 if rel' aconv rel then rtrm else raise exc |
225 if rel' aconv rel then rtrm else raise exc |
222 end |
226 end |
223 |
227 |
224 | (_, Const _) => |
228 | (_, Const _) => |
239 (* cu: if I also test the type, then something else breaks *) |
243 (* cu: if I also test the type, then something else breaks *) |
240 in |
244 in |
241 if same_name rtrm qtrm then rtrm |
245 if same_name rtrm qtrm then rtrm |
242 else |
246 else |
243 let |
247 let |
244 val thy = ProofContext.theory_of lthy |
248 val thy = ProofContext.theory_of ctxt |
245 val qtrm_str = Syntax.string_of_term lthy qtrm |
249 val qtrm_str = Syntax.string_of_term ctxt qtrm |
246 val exc1 = LIFT_MATCH ("regularize (constant " ^ qtrm_str ^ " not found)") |
250 val exc1 = LIFT_MATCH ("regularize (constant " ^ qtrm_str ^ " not found)") |
247 val exc2 = LIFT_MATCH ("regularize (constant " ^ qtrm_str ^ " mismatch)") |
251 val exc2 = LIFT_MATCH ("regularize (constant " ^ qtrm_str ^ " mismatch)") |
248 val rtrm' = (#rconst (qconsts_lookup thy qtrm)) handle NotFound => raise exc1 |
252 val rtrm' = (#rconst (qconsts_lookup thy qtrm)) handle NotFound => raise exc1 |
249 in |
253 in |
250 if Pattern.matches thy (rtrm', rtrm) |
254 if Pattern.matches thy (rtrm', rtrm) |
251 then rtrm else raise exc2 |
255 then rtrm else raise exc2 |
252 end |
256 end |
253 end |
257 end |
254 |
258 |
255 | (t1 $ t2, t1' $ t2') => |
259 | (t1 $ t2, t1' $ t2') => |
256 (regularize_trm lthy (t1, t1')) $ (regularize_trm lthy (t2, t2')) |
260 (regularize_trm ctxt (t1, t1')) $ (regularize_trm ctxt (t2, t2')) |
257 |
261 |
258 | (Bound i, Bound i') => |
262 | (Bound i, Bound i') => |
259 if i = i' then rtrm |
263 if i = i' then rtrm |
260 else raise (LIFT_MATCH "regularize (bounds mismatch)") |
264 else raise (LIFT_MATCH "regularize (bounds mismatch)") |
261 |
265 |
262 | _ => |
266 | _ => |
263 let |
267 let |
264 val rtrm_str = Syntax.string_of_term lthy rtrm |
268 val rtrm_str = Syntax.string_of_term ctxt rtrm |
265 val qtrm_str = Syntax.string_of_term lthy qtrm |
269 val qtrm_str = Syntax.string_of_term ctxt qtrm |
266 in |
270 in |
267 raise (LIFT_MATCH ("regularize failed (default: " ^ rtrm_str ^ "," ^ qtrm_str ^ ")")) |
271 raise (LIFT_MATCH ("regularize failed (default: " ^ rtrm_str ^ "," ^ qtrm_str ^ ")")) |
268 end |
272 end |
269 |
273 |
270 fun regularize_trm_chk lthy (rtrm, qtrm) = |
274 fun regularize_trm_chk ctxt (rtrm, qtrm) = |
271 regularize_trm lthy (rtrm, qtrm) |
275 regularize_trm ctxt (rtrm, qtrm) |
272 |> Syntax.check_term lthy |
276 |> Syntax.check_term ctxt |
273 |
277 |
274 (* |
278 (* |
275 Injection of Rep/Abs means: |
279 Injection of Rep/Abs means: |
276 |
280 |
277 For abstractions |
281 For abstractions |
297 * We put aRep/Abs around it if the type needs lifting. |
301 * We put aRep/Abs around it if the type needs lifting. |
298 |
302 |
299 Vars case cannot occur. |
303 Vars case cannot occur. |
300 *) |
304 *) |
301 |
305 |
302 fun mk_repabs lthy (T, T') trm = |
306 fun mk_repabs ctxt (T, T') trm = |
303 absrep_fun repF lthy (T, T') $ (absrep_fun absF lthy (T, T') $ trm) |
307 absrep_fun repF ctxt (T, T') $ (absrep_fun absF ctxt (T, T') $ trm) |
304 |
308 |
305 |
309 |
306 (* bound variables need to be treated properly, *) |
310 (* bound variables need to be treated properly, *) |
307 (* as the type of subterms needs to be calculated *) |
311 (* as the type of subterms needs to be calculated *) |
308 |
312 |
309 fun inj_repabs_trm lthy (rtrm, qtrm) = |
313 fun inj_repabs_trm ctxt (rtrm, qtrm) = |
310 case (rtrm, qtrm) of |
314 case (rtrm, qtrm) of |
311 (Const (@{const_name "Ball"}, T) $ r $ t, Const (@{const_name "All"}, _) $ t') => |
315 (Const (@{const_name "Ball"}, T) $ r $ t, Const (@{const_name "All"}, _) $ t') => |
312 Const (@{const_name "Ball"}, T) $ r $ (inj_repabs_trm lthy (t, t')) |
316 Const (@{const_name "Ball"}, T) $ r $ (inj_repabs_trm ctxt (t, t')) |
313 |
317 |
314 | (Const (@{const_name "Bex"}, T) $ r $ t, Const (@{const_name "Ex"}, _) $ t') => |
318 | (Const (@{const_name "Bex"}, T) $ r $ t, Const (@{const_name "Ex"}, _) $ t') => |
315 Const (@{const_name "Bex"}, T) $ r $ (inj_repabs_trm lthy (t, t')) |
319 Const (@{const_name "Bex"}, T) $ r $ (inj_repabs_trm ctxt (t, t')) |
316 |
320 |
317 | (Const (@{const_name "Babs"}, T) $ r $ t, t' as (Abs _)) => |
321 | (Const (@{const_name "Babs"}, T) $ r $ t, t' as (Abs _)) => |
318 let |
322 let |
319 val rty = fastype_of rtrm |
323 val rty = fastype_of rtrm |
320 val qty = fastype_of qtrm |
324 val qty = fastype_of qtrm |
321 in |
325 in |
322 mk_repabs lthy (rty, qty) (Const (@{const_name "Babs"}, T) $ r $ (inj_repabs_trm lthy (t, t'))) |
326 mk_repabs ctxt (rty, qty) (Const (@{const_name "Babs"}, T) $ r $ (inj_repabs_trm ctxt (t, t'))) |
323 end |
327 end |
324 |
328 |
325 | (Abs (x, T, t), Abs (x', T', t')) => |
329 | (Abs (x, T, t), Abs (x', T', t')) => |
326 let |
330 let |
327 val rty = fastype_of rtrm |
331 val rty = fastype_of rtrm |
328 val qty = fastype_of qtrm |
332 val qty = fastype_of qtrm |
329 val (y, s) = Term.dest_abs (x, T, t) |
333 val (y, s) = Term.dest_abs (x, T, t) |
330 val (_, s') = Term.dest_abs (x', T', t') |
334 val (_, s') = Term.dest_abs (x', T', t') |
331 val yvar = Free (y, T) |
335 val yvar = Free (y, T) |
332 val result = Term.lambda_name (y, yvar) (inj_repabs_trm lthy (s, s')) |
336 val result = Term.lambda_name (y, yvar) (inj_repabs_trm ctxt (s, s')) |
333 in |
337 in |
334 if rty = qty then result |
338 if rty = qty then result |
335 else mk_repabs lthy (rty, qty) result |
339 else mk_repabs ctxt (rty, qty) result |
336 end |
340 end |
337 |
341 |
338 | (t $ s, t' $ s') => |
342 | (t $ s, t' $ s') => |
339 (inj_repabs_trm lthy (t, t')) $ (inj_repabs_trm lthy (s, s')) |
343 (inj_repabs_trm ctxt (t, t')) $ (inj_repabs_trm ctxt (s, s')) |
340 |
344 |
341 | (Free (_, T), Free (_, T')) => |
345 | (Free (_, T), Free (_, T')) => |
342 if T = T' then rtrm |
346 if T = T' then rtrm |
343 else mk_repabs lthy (T, T') rtrm |
347 else mk_repabs ctxt (T, T') rtrm |
344 |
348 |
345 | (_, Const (@{const_name "op ="}, _)) => rtrm |
349 | (_, Const (@{const_name "op ="}, _)) => rtrm |
346 |
350 |
347 | (_, Const (_, T')) => |
351 | (_, Const (_, T')) => |
348 let |
352 let |
349 val rty = fastype_of rtrm |
353 val rty = fastype_of rtrm |
350 in |
354 in |
351 if rty = T' then rtrm |
355 if rty = T' then rtrm |
352 else mk_repabs lthy (rty, T') rtrm |
356 else mk_repabs ctxt (rty, T') rtrm |
353 end |
357 end |
354 |
358 |
355 | _ => raise (LIFT_MATCH "injection (default)") |
359 | _ => raise (LIFT_MATCH "injection (default)") |
356 |
360 |
357 fun inj_repabs_trm_chk lthy (rtrm, qtrm) = |
361 fun inj_repabs_trm_chk ctxt (rtrm, qtrm) = |
358 inj_repabs_trm lthy (rtrm, qtrm) |
362 inj_repabs_trm ctxt (rtrm, qtrm) |
359 |> Syntax.check_term lthy |
363 |> Syntax.check_term ctxt |
360 |
364 |
361 end; (* structure *) |
365 end; (* structure *) |
362 |
366 |
363 |
367 |
364 |
368 |