src/HOL/Tools/type_lifting.ML
changeset 41389 d06a6d15a958
parent 41388 945b42e3b3c2
child 41390 207ee8f8a19c
equal deleted inserted replaced
41388:945b42e3b3c2 41389:d06a6d15a958
    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