24 |
24 |
25 (** functorial mappers and their properties **) |
25 (** functorial mappers and their properties **) |
26 |
26 |
27 (* bookkeeping *) |
27 (* bookkeeping *) |
28 |
28 |
29 fun term_with_typ ctxt T t = Envir.subst_term_types |
|
30 (Type.typ_match (ProofContext.tsig_of ctxt) (fastype_of t, T) Vartab.empty) t; |
|
31 |
|
32 type entry = { mapper: term, variances: (sort * (bool * bool)) list, |
29 type entry = { mapper: term, variances: (sort * (bool * bool)) list, |
33 comp: thm, id: thm }; |
30 comp: thm, id: thm }; |
34 |
31 |
35 structure Data = Generic_Data( |
32 structure Data = Generic_Data( |
36 type T = entry Symtab.table |
33 type T = entry Symtab.table |
41 |
38 |
42 val entries = Data.get o Context.Proof; |
39 val entries = Data.get o Context.Proof; |
43 |
40 |
44 |
41 |
45 (* type analysis *) |
42 (* type analysis *) |
|
43 |
|
44 fun term_with_typ ctxt T t = Envir.subst_term_types |
|
45 (Type.typ_match (ProofContext.tsig_of ctxt) (fastype_of t, T) Vartab.empty) t; |
46 |
46 |
47 fun find_atomic ctxt T = |
47 fun find_atomic ctxt T = |
48 let |
48 let |
49 val variances_of = Option.map #variances o Symtab.lookup (entries ctxt); |
49 val variances_of = Option.map #variances o Symtab.lookup (entries ctxt); |
50 fun add_variance is_contra T = |
50 fun add_variance is_contra T = |
191 end; |
191 end; |
192 val (variances, left_variances) = fold_map check_variance_pair (vs1 ~~ vs2) Ts; |
192 val (variances, left_variances) = fold_map check_variance_pair (vs1 ~~ vs2) Ts; |
193 val _ = if null left_variances then () else bad_typ (); |
193 val _ = if null left_variances then () else bad_typ (); |
194 in variances end; |
194 in variances end; |
195 |
195 |
196 fun gen_type_lifting prep_term some_prfx raw_t thy = |
196 fun gen_type_lifting prep_term some_prfx raw_mapper thy = |
197 let |
197 let |
198 val mapper_fixT = prep_term thy raw_t; |
198 val input_mapper = prep_term thy raw_mapper; |
199 val T = fastype_of mapper_fixT; |
199 val T = fastype_of input_mapper; |
200 val _ = Type.no_tvars T; |
200 val _ = Type.no_tvars T; |
201 val mapper = singleton (Variable.polymorphic (ProofContext.init_global thy)) mapper_fixT; |
201 val mapper = singleton (Variable.polymorphic (ProofContext.init_global thy)) input_mapper; |
202 fun add_tycos (Type (tyco, Ts)) = insert (op =) tyco #> fold add_tycos Ts |
202 fun add_tycos (Type (tyco, Ts)) = insert (op =) tyco #> fold add_tycos Ts |
203 | add_tycos _ = I; |
203 | add_tycos _ = I; |
204 val tycos = add_tycos T []; |
204 val tycos = add_tycos T []; |
205 val tyco = if tycos = ["fun"] then "fun" |
205 val tyco = if tycos = ["fun"] then "fun" |
206 else case remove (op =) "fun" tycos |
206 else case remove (op =) "fun" tycos |
209 val prfx = the_default (Long_Name.base_name tyco) some_prfx; |
209 val prfx = the_default (Long_Name.base_name tyco) some_prfx; |
210 val variances = analyze_variances thy tyco T; |
210 val variances = analyze_variances thy tyco T; |
211 val ctxt = ProofContext.init_global thy; |
211 val ctxt = ProofContext.init_global thy; |
212 val (comp_prop, prove_compositionality) = make_comp_prop ctxt variances (tyco, mapper); |
212 val (comp_prop, prove_compositionality) = make_comp_prop ctxt variances (tyco, mapper); |
213 val (id_prop, prove_identity) = make_id_prop ctxt variances (tyco, mapper); |
213 val (id_prop, prove_identity) = make_id_prop ctxt variances (tyco, mapper); |
214 val _ = Thm.cterm_of thy id_prop; |
|
215 val qualify = Binding.qualify true prfx o Binding.name; |
214 val qualify = Binding.qualify true prfx o Binding.name; |
|
215 fun mapper_declaration comp_thm id_thm phi context = |
|
216 let |
|
217 val typ_instance = Type.typ_instance (ProofContext.tsig_of (Context.proof_of context)); |
|
218 val mapper' = Morphism.term phi mapper; |
|
219 val T_T' = pairself fastype_of (mapper, mapper'); |
|
220 in if typ_instance T_T' andalso typ_instance (swap T_T') |
|
221 then Data.map (Symtab.update (tyco, |
|
222 { mapper = mapper', variances = variances, |
|
223 comp = Morphism.thm phi comp_thm, id = Morphism.thm phi id_thm })) context |
|
224 else context |
|
225 end; |
216 fun after_qed [single_comp_thm, single_id_thm] lthy = |
226 fun after_qed [single_comp_thm, single_id_thm] lthy = |
217 lthy |
227 lthy |
218 |> Local_Theory.note ((qualify compN, []), single_comp_thm) |
228 |> Local_Theory.note ((qualify compN, []), single_comp_thm) |
219 ||>> Local_Theory.note ((qualify idN, []), single_id_thm) |
229 ||>> Local_Theory.note ((qualify idN, []), single_id_thm) |
220 |-> (fn ((_, [comp_thm]), (_, [id_thm])) => fn lthy => |
230 |-> (fn ((_, [comp_thm]), (_, [id_thm])) => fn lthy => |
223 [prove_compositionality lthy comp_thm]) |
233 [prove_compositionality lthy comp_thm]) |
224 |> snd |
234 |> snd |
225 |> Local_Theory.note ((qualify identityN, []), |
235 |> Local_Theory.note ((qualify identityN, []), |
226 [prove_identity lthy id_thm]) |
236 [prove_identity lthy id_thm]) |
227 |> snd |
237 |> snd |
228 |> Local_Theory.declaration false (fn phi => Data.map |
238 |> Local_Theory.declaration false (mapper_declaration comp_thm id_thm)) |
229 (Symtab.update (tyco, { mapper = Morphism.term phi mapper, variances = variances, |
|
230 comp = Morphism.thm phi comp_thm, id = Morphism.thm phi id_thm })))) |
|
231 in |
239 in |
232 thy |
240 thy |
233 |> Named_Target.theory_init |
241 |> Named_Target.theory_init |
234 |> Proof.theorem NONE after_qed (map (fn t => [(t, [])]) [comp_prop, id_prop]) |
242 |> Proof.theorem NONE after_qed (map (fn t => [(t, [])]) [comp_prop, id_prop]) |
235 end |
243 end |