5 datatype flag = absF | repF |
5 datatype flag = absF | repF |
6 |
6 |
7 val absrep_fun: flag -> Proof.context -> (typ * typ) -> term |
7 val absrep_fun: flag -> Proof.context -> (typ * typ) -> term |
8 val absrep_fun_chk: flag -> Proof.context -> (typ * typ) -> term |
8 val absrep_fun_chk: flag -> Proof.context -> (typ * typ) -> term |
9 |
9 |
|
10 val equiv_relation: Proof.context -> (typ * typ) -> term |
|
11 val equiv_relation_chk: Proof.context -> (typ * typ) -> term |
|
12 |
10 val regularize_trm: Proof.context -> (term * term) -> term |
13 val regularize_trm: Proof.context -> (term * term) -> term |
11 val regularize_trm_chk: Proof.context -> (term * term) -> term |
14 val regularize_trm_chk: Proof.context -> (term * term) -> term |
12 |
15 |
13 val inj_repabs_trm: Proof.context -> (term * term) -> term |
16 val inj_repabs_trm: Proof.context -> (term * term) -> term |
14 val inj_repabs_trm_chk: Proof.context -> (term * term) -> term |
17 val inj_repabs_trm_chk: Proof.context -> (term * term) -> term |
55 end |
58 end |
56 |
59 |
57 (* produces an aggregate map function for the *) |
60 (* produces an aggregate map function for the *) |
58 (* rty-part of a quotient definition; abstracts *) |
61 (* rty-part of a quotient definition; abstracts *) |
59 (* over all variables listed in vs (these variables *) |
62 (* over all variables listed in vs (these variables *) |
60 (* correspond to the type variables in rty *) |
63 (* correspond to the type variables in rty) *) |
61 fun mk_mapfun ctxt vs ty = |
64 fun mk_mapfun ctxt vs ty = |
62 let |
65 let |
63 val vs' = map (mk_Free) vs |
66 val vs' = map (mk_Free) vs |
64 |
67 |
65 fun mk_mapfun_aux ty = |
68 fun mk_mapfun_aux ty = |
81 val qdata = (quotdata_lookup thy s) handle NotFound => raise exc |
84 val qdata = (quotdata_lookup thy s) handle NotFound => raise exc |
82 in |
85 in |
83 (#rtyp qdata, #qtyp qdata) |
86 (#rtyp qdata, #qtyp qdata) |
84 end |
87 end |
85 |
88 |
86 (* receives two type-environments and looks *) |
89 (* takes two type-environments and looks *) |
87 (* up in both of them the variable v *) |
90 (* up in both of them the variable v, which *) |
|
91 (* must be listed in the environment *) |
88 fun double_lookup rtyenv qtyenv v = |
92 fun double_lookup rtyenv qtyenv v = |
89 let |
93 let |
90 val v' = fst (dest_TVar v) |
94 val v' = fst (dest_TVar v) |
91 in |
95 in |
92 (snd (the (Vartab.lookup rtyenv v')), snd (the (Vartab.lookup qtyenv v'))) |
96 (snd (the (Vartab.lookup rtyenv v')), snd (the (Vartab.lookup qtyenv v'))) |
101 case flag of |
105 case flag of |
102 absF => Const (Sign.full_bname thy ("abs_" ^ qty_name), dummyT) |
106 absF => Const (Sign.full_bname thy ("abs_" ^ qty_name), dummyT) |
103 | repF => Const (Sign.full_bname thy ("rep_" ^ qty_name), dummyT) |
107 | repF => Const (Sign.full_bname thy ("rep_" ^ qty_name), dummyT) |
104 end |
108 end |
105 |
109 |
106 (* produces the aggregate absrep function *) |
110 fun absrep_match_err ctxt ty_pat ty = |
|
111 let |
|
112 val ty_pat_str = Syntax.string_of_typ ctxt ty_pat |
|
113 val ty_str = Syntax.string_of_typ ctxt ty |
|
114 in |
|
115 raise LIFT_MATCH (space_implode " " |
|
116 ["absrep_fun (Types ", quote ty_pat_str, "and", quote ty_str, " do not match.)"]) |
|
117 end |
|
118 |
|
119 (* produces an aggregate absrep function *) |
107 (* *) |
120 (* *) |
108 (* - In case of function types and TFrees, we recurse, taking in *) |
121 (* - In case of function types and TFrees, we recurse, taking in *) |
109 (* the first case the polarity change into account. *) |
122 (* the first case the polarity change into account. *) |
110 (* *) |
123 (* *) |
111 (* - If the type constructors are equal, we recurse for the *) |
124 (* - If the type constructors are equal, we recurse for the *) |
155 list_comb (get_mapfun ctxt s, args) |
168 list_comb (get_mapfun ctxt s, args) |
156 end |
169 end |
157 else |
170 else |
158 let |
171 let |
159 val thy = ProofContext.theory_of ctxt |
172 val thy = ProofContext.theory_of ctxt |
160 val exc = (LIFT_MATCH "absrep_fun (Types do not match.)") |
|
161 val (rty_pat, qty_pat as Type (_, vs)) = get_rty_qty ctxt s' |
173 val (rty_pat, qty_pat as Type (_, vs)) = get_rty_qty ctxt s' |
162 val (rtyenv, qtyenv) = |
174 val rtyenv = Sign.typ_match thy (rty_pat, rty) Vartab.empty |
163 (Sign.typ_match thy (rty_pat, rty) Vartab.empty, |
175 handle MATCH_TYPE => absrep_match_err ctxt rty_pat rty |
164 Sign.typ_match thy (qty_pat, qty) Vartab.empty) |
176 val qtyenv = Sign.typ_match thy (qty_pat, qty) Vartab.empty |
165 handle MATCH_TYPE => raise exc |
177 handle MATCH_TYPE => absrep_match_err ctxt qty_pat qty |
166 val args_aux = map (double_lookup rtyenv qtyenv) vs |
178 val args_aux = map (double_lookup rtyenv qtyenv) vs |
167 val args = map (absrep_fun flag ctxt) args_aux |
179 val args = map (absrep_fun flag ctxt) args_aux |
168 val map_fun = mk_mapfun ctxt vs rty_pat |
180 val map_fun = mk_mapfun ctxt vs rty_pat |
169 val result = list_comb (map_fun, args) |
181 val result = list_comb (map_fun, args) |
170 in |
182 in |
180 fun absrep_fun_chk flag ctxt (rty, qty) = |
192 fun absrep_fun_chk flag ctxt (rty, qty) = |
181 absrep_fun flag ctxt (rty, qty) |
193 absrep_fun flag ctxt (rty, qty) |
182 |> Syntax.check_term ctxt |
194 |> Syntax.check_term ctxt |
183 |
195 |
184 |
196 |
185 (* Regularizing an rtrm means: |
197 (**********************************) |
186 |
198 (* Aggregate Equivalence Relation *) |
187 - Quantifiers over types that need lifting are replaced |
199 (**********************************) |
188 by bounded quantifiers, for example: |
|
189 |
|
190 All P ----> All (Respects R) P |
|
191 |
|
192 where the aggregate relation R is given by the rty and qty; |
|
193 |
|
194 - Abstractions over types that need lifting are replaced |
|
195 by bounded abstractions, for example: |
|
196 |
|
197 %x. P ----> Ball (Respects R) %x. P |
|
198 |
|
199 - Equalities over types that need lifting are replaced by |
|
200 corresponding equivalence relations, for example: |
|
201 |
|
202 A = B ----> R A B |
|
203 |
|
204 or |
|
205 |
|
206 A = B ----> (R ===> R) A B |
|
207 |
|
208 for more complicated types of A and B |
|
209 *) |
|
210 |
200 |
211 (* instantiates TVars so that the term is of type ty *) |
201 (* instantiates TVars so that the term is of type ty *) |
212 fun force_typ ctxt trm ty = |
202 fun force_typ ctxt trm ty = |
213 let |
203 let |
214 val thy = ProofContext.theory_of ctxt |
204 val thy = ProofContext.theory_of ctxt |
237 |
227 |
238 (* builds the aggregate equivalence relation *) |
228 (* builds the aggregate equivalence relation *) |
239 (* that will be the argument of Respects *) |
229 (* that will be the argument of Respects *) |
240 |
230 |
241 (* FIXME: check that the types correspond to each other? *) |
231 (* FIXME: check that the types correspond to each other? *) |
242 fun mk_resp_arg ctxt (rty, qty) = |
232 fun equiv_relation ctxt (rty, qty) = |
243 if rty = qty |
233 if rty = qty |
244 then HOLogic.eq_const rty |
234 then HOLogic.eq_const rty |
245 else |
235 else |
246 case (rty, qty) of |
236 case (rty, qty) of |
247 (Type (s, tys), Type (s', tys')) => |
237 (Type (s, tys), Type (s', tys')) => |
248 if s = s' |
238 if s = s' |
249 then |
239 then |
250 let |
240 let |
251 val args = map (mk_resp_arg ctxt) (tys ~~ tys') |
241 val args = map (equiv_relation ctxt) (tys ~~ tys') |
252 in |
242 in |
253 list_comb (get_relmap ctxt s, args) |
243 list_comb (get_relmap ctxt s, args) |
254 end |
244 end |
255 else |
245 else |
256 let |
246 let |
257 val eqv_rel = get_equiv_rel ctxt s' |
247 val eqv_rel = get_equiv_rel ctxt s' |
258 in |
248 in |
259 force_typ ctxt eqv_rel ([rty, rty] ---> @{typ bool}) |
249 force_typ ctxt eqv_rel ([rty, rty] ---> @{typ bool}) |
260 end |
250 end |
261 | _ => HOLogic.eq_const rty |
251 | _ => HOLogic.eq_const rty |
|
252 |
|
253 fun equiv_relation_chk ctxt (rty, qty) = |
|
254 equiv_relation ctxt (rty, qty) |
|
255 |> Syntax.check_term ctxt |
|
256 |
|
257 |
|
258 (******************) |
|
259 (* Regularization *) |
|
260 (******************) |
|
261 |
|
262 (* Regularizing an rtrm means: |
|
263 |
|
264 - Quantifiers over types that need lifting are replaced |
|
265 by bounded quantifiers, for example: |
|
266 |
|
267 All P ----> All (Respects R) P |
|
268 |
|
269 where the aggregate relation R is given by the rty and qty; |
|
270 |
|
271 - Abstractions over types that need lifting are replaced |
|
272 by bounded abstractions, for example: |
|
273 |
|
274 %x. P ----> Ball (Respects R) %x. P |
|
275 |
|
276 - Equalities over types that need lifting are replaced by |
|
277 corresponding equivalence relations, for example: |
|
278 |
|
279 A = B ----> R A B |
|
280 |
|
281 or |
|
282 |
|
283 A = B ----> (R ===> R) A B |
|
284 |
|
285 for more complicated types of A and B |
|
286 *) |
|
287 |
262 |
288 |
263 val mk_babs = Const (@{const_name Babs}, dummyT) |
289 val mk_babs = Const (@{const_name Babs}, dummyT) |
264 val mk_ball = Const (@{const_name Ball}, dummyT) |
290 val mk_ball = Const (@{const_name Ball}, dummyT) |
265 val mk_bex = Const (@{const_name Bex}, dummyT) |
291 val mk_bex = Const (@{const_name Bex}, dummyT) |
266 val mk_resp = Const (@{const_name Respects}, dummyT) |
292 val mk_resp = Const (@{const_name Respects}, dummyT) |
290 (Abs (x, ty, t), Abs (_, ty', t')) => |
316 (Abs (x, ty, t), Abs (_, ty', t')) => |
291 let |
317 let |
292 val subtrm = Abs(x, ty, regularize_trm ctxt (t, t')) |
318 val subtrm = Abs(x, ty, regularize_trm ctxt (t, t')) |
293 in |
319 in |
294 if ty = ty' then subtrm |
320 if ty = ty' then subtrm |
295 else mk_babs $ (mk_resp $ mk_resp_arg ctxt (ty, ty')) $ subtrm |
321 else mk_babs $ (mk_resp $ equiv_relation ctxt (ty, ty')) $ subtrm |
296 end |
322 end |
297 |
323 |
298 | (Const (@{const_name "All"}, ty) $ t, Const (@{const_name "All"}, ty') $ t') => |
324 | (Const (@{const_name "All"}, ty) $ t, Const (@{const_name "All"}, ty') $ t') => |
299 let |
325 let |
300 val subtrm = apply_subt (regularize_trm ctxt) (t, t') |
326 val subtrm = apply_subt (regularize_trm ctxt) (t, t') |
301 in |
327 in |
302 if ty = ty' then Const (@{const_name "All"}, ty) $ subtrm |
328 if ty = ty' then Const (@{const_name "All"}, ty) $ subtrm |
303 else mk_ball $ (mk_resp $ mk_resp_arg ctxt (qnt_typ ty, qnt_typ ty')) $ subtrm |
329 else mk_ball $ (mk_resp $ equiv_relation ctxt (qnt_typ ty, qnt_typ ty')) $ subtrm |
304 end |
330 end |
305 |
331 |
306 | (Const (@{const_name "Ex"}, ty) $ t, Const (@{const_name "Ex"}, ty') $ t') => |
332 | (Const (@{const_name "Ex"}, ty) $ t, Const (@{const_name "Ex"}, ty') $ t') => |
307 let |
333 let |
308 val subtrm = apply_subt (regularize_trm ctxt) (t, t') |
334 val subtrm = apply_subt (regularize_trm ctxt) (t, t') |
309 in |
335 in |
310 if ty = ty' then Const (@{const_name "Ex"}, ty) $ subtrm |
336 if ty = ty' then Const (@{const_name "Ex"}, ty) $ subtrm |
311 else mk_bex $ (mk_resp $ mk_resp_arg ctxt (qnt_typ ty, qnt_typ ty')) $ subtrm |
337 else mk_bex $ (mk_resp $ equiv_relation ctxt (qnt_typ ty, qnt_typ ty')) $ subtrm |
312 end |
338 end |
313 |
339 |
314 | (* equalities need to be replaced by appropriate equivalence relations *) |
340 | (* equalities need to be replaced by appropriate equivalence relations *) |
315 (Const (@{const_name "op ="}, ty), Const (@{const_name "op ="}, ty')) => |
341 (Const (@{const_name "op ="}, ty), Const (@{const_name "op ="}, ty')) => |
316 if ty = ty' then rtrm |
342 if ty = ty' then rtrm |
317 else mk_resp_arg ctxt (domain_type ty, domain_type ty') |
343 else equiv_relation ctxt (domain_type ty, domain_type ty') |
318 |
344 |
319 | (* in this case we just check whether the given equivalence relation is correct *) |
345 | (* in this case we just check whether the given equivalence relation is correct *) |
320 (rel, Const (@{const_name "op ="}, ty')) => |
346 (rel, Const (@{const_name "op ="}, ty')) => |
321 let |
347 let |
322 val exc = LIFT_MATCH "regularise (relation mismatch)" |
348 val exc = LIFT_MATCH "regularise (relation mismatch)" |
323 val rel_ty = fastype_of rel |
349 val rel_ty = fastype_of rel |
324 val rel' = mk_resp_arg ctxt (domain_type rel_ty, domain_type ty') |
350 val rel' = equiv_relation ctxt (domain_type rel_ty, domain_type ty') |
325 in |
351 in |
326 if rel' aconv rel then rtrm else raise exc |
352 if rel' aconv rel then rtrm else raise exc |
327 end |
353 end |
328 |
354 |
329 | (_, Const _) => |
355 | (_, Const _) => |