src/HOL/Tools/Transfer/transfer_bnf.ML
changeset 62324 ae44f16dcea5
parent 61768 99f1eaf70c3d
child 62329 9f7fa08d2307
equal deleted inserted replaced
62323:8c3eec5812d8 62324:ae44f16dcea5
    25 exception NO_PRED_DATA of unit
    25 exception NO_PRED_DATA of unit
    26 
    26 
    27 (* util functions *)
    27 (* util functions *)
    28 
    28 
    29 fun base_name_of_bnf bnf = Binding.name (Binding.name_of (name_of_bnf bnf))
    29 fun base_name_of_bnf bnf = Binding.name (Binding.name_of (name_of_bnf bnf))
    30 fun mk_Frees_free x Ts ctxt = Variable.variant_frees ctxt [] (mk_names (length Ts) x ~~ Ts) |> map Free
       
    31 
    30 
    32 fun mk_Domainp P =
    31 fun mk_Domainp P =
    33   let
    32   let
    34     val PT = fastype_of P
    33     val PT = fastype_of P
    35     val argT = hd (binder_types PT)
    34     val argT = hd (binder_types PT)
    36   in
    35   in
    37     Const (@{const_name Domainp}, PT --> argT --> HOLogic.boolT) $ P
    36     Const (@{const_name Domainp}, PT --> argT --> HOLogic.boolT) $ P
    38   end
    37   end
    39 
    38 
    40 fun mk_pred pred_def args T =
       
    41   let
       
    42     val pred_name = pred_def |> Thm.prop_of |> HOLogic.dest_Trueprop |> fst o HOLogic.dest_eq
       
    43       |> head_of |> fst o dest_Const
       
    44     val argsT = map fastype_of args
       
    45   in
       
    46     list_comb (Const (pred_name, argsT ---> (T --> HOLogic.boolT)), args)
       
    47   end
       
    48 
       
    49 fun mk_eq_onp arg =
    39 fun mk_eq_onp arg =
    50   let
    40   let
    51     val argT = domain_type (fastype_of arg)
    41     val argT = domain_type (fastype_of arg)
    52   in
    42   in
    53     Const (@{const_name eq_onp}, (argT --> HOLogic.boolT) --> argT --> argT --> HOLogic.boolT)
    43     Const (@{const_name eq_onp}, (argT --> HOLogic.boolT) --> argT --> argT --> HOLogic.boolT)
    54       $ arg
    44       $ arg
    55   end
    45   end
    56 
       
    57 fun subst_conv thm =
       
    58   Conv.top_sweep_conv (K (Conv.rewr_conv (safe_mk_meta_eq thm))) @{context}
       
    59 
    46 
    60 fun type_name_of_bnf bnf = T_of_bnf bnf |> dest_Type |> fst
    47 fun type_name_of_bnf bnf = T_of_bnf bnf |> dest_Type |> fst
    61 
    48 
    62 fun is_Type (Type _) = true
    49 fun is_Type (Type _) = true
    63   | is_Type _ = false
    50   | is_Type _ = false
   167     val transfer_attr = @{attributes [transfer_rule]}
   154     val transfer_attr = @{attributes [transfer_rule]}
   168   in
   155   in
   169     map (fn thm => ((Binding.empty,[]),[([thm],transfer_attr)])) transfer_rules
   156     map (fn thm => ((Binding.empty,[]),[([thm],transfer_attr)])) transfer_rules
   170   end
   157   end
   171 
   158 
   172 (* predicator definition and Domainp and eq_onp theorem *)
   159 (* Domainp theorem for predicator *)
   173 
       
   174 fun define_pred bnf lthy =
       
   175   let
       
   176     fun mk_pred_name c = Binding.prefix_name "pred_" c
       
   177     val live = live_of_bnf bnf
       
   178     val Tname = base_name_of_bnf bnf
       
   179     val ((As, Ds), lthy) = lthy
       
   180       |> mk_TFrees live
       
   181       ||>> mk_TFrees' (map Type.sort_of_atyp (deads_of_bnf bnf))
       
   182     val T = mk_T_of_bnf Ds As bnf
       
   183     val sets = mk_sets_of_bnf (replicate live Ds) (replicate live As) bnf
       
   184     val argTs = map mk_pred1T As
       
   185     val args = mk_Frees_free "P" argTs lthy
       
   186     val conjs = map (fn (set, arg) => mk_Ball (set $ Bound 0) arg) (sets ~~ args)
       
   187     val rhs = Abs ("x", T, foldr1 HOLogic.mk_conj conjs)
       
   188     val pred_name = mk_pred_name Tname
       
   189     val headT = argTs ---> (T --> HOLogic.boolT)
       
   190     val head = Free (Binding.name_of pred_name, headT)
       
   191     val lhs = list_comb (head, args)
       
   192     val def = HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, rhs))
       
   193     val ((_, (_, pred_def)), lthy) = Specification.definition ((SOME (pred_name, SOME headT, NoSyn)),
       
   194       ((Binding.empty, []), def)) lthy
       
   195   in
       
   196     (pred_def, lthy)
       
   197   end
       
   198 
   160 
   199 fun Domainp_tac bnf pred_def ctxt i =
   161 fun Domainp_tac bnf pred_def ctxt i =
   200   let
   162   let
   201     val n = live_of_bnf bnf
   163     val n = live_of_bnf bnf
   202     val set_map's = set_map_of_bnf bnf
   164     val set_map's = set_map_of_bnf bnf
   231       ||>> mk_TFrees live
   193       ||>> mk_TFrees live
   232       ||>> mk_TFrees' (map Type.sort_of_atyp (deads_of_bnf bnf))
   194       ||>> mk_TFrees' (map Type.sort_of_atyp (deads_of_bnf bnf))
   233 
   195 
   234     val relator = mk_rel_of_bnf Ds As Bs bnf
   196     val relator = mk_rel_of_bnf Ds As Bs bnf
   235     val relsT = map2 mk_pred2T As Bs
   197     val relsT = map2 mk_pred2T As Bs
   236     val T = mk_T_of_bnf Ds As bnf
       
   237     val (args, ctxt) = Ctr_Sugar_Util.mk_Frees "R" relsT ctxt
   198     val (args, ctxt) = Ctr_Sugar_Util.mk_Frees "R" relsT ctxt
   238     val lhs = mk_Domainp (list_comb (relator, args))
   199     val lhs = mk_Domainp (list_comb (relator, args))
   239     val rhs = mk_pred pred_def (map mk_Domainp args) T
   200     val rhs = Term.list_comb (mk_pred_of_bnf Ds As bnf, map mk_Domainp args)
   240     val goal = HOLogic.mk_eq (lhs, rhs) |> HOLogic.mk_Trueprop
   201     val goal = HOLogic.mk_eq (lhs, rhs) |> HOLogic.mk_Trueprop
   241     val thm = Goal.prove_sorry ctxt [] [] goal
   202     val thm = Goal.prove_sorry ctxt [] [] goal
   242       (fn {context = ctxt, prems = _} => Domainp_tac bnf pred_def ctxt 1)
   203       (fn {context = ctxt, prems = _} => Domainp_tac bnf pred_def ctxt 1)
   243       |> Thm.close_derivation
   204       |> Thm.close_derivation
   244   in
   205   in
   245     Drule.zero_var_indexes (singleton (Variable.export ctxt old_ctxt) thm)
   206     Drule.zero_var_indexes (singleton (Variable.export ctxt old_ctxt) thm)
   246   end
   207   end
   247 
   208 
   248 fun pred_eq_onp_tac bnf pred_def ctxt i =
       
   249   (SELECT_GOAL (Local_Defs.unfold_tac ctxt [@{thm eq_onp_Grp},
       
   250     @{thm Ball_Collect}, pred_def]) THEN' CONVERSION (subst_conv (map_id0_of_bnf bnf RS sym))
       
   251   THEN' rtac ctxt (rel_Grp_of_bnf bnf)) i
       
   252 
       
   253 fun prove_rel_eq_onp ctxt bnf pred_def =
       
   254   let
       
   255     val live = live_of_bnf bnf
       
   256     val old_ctxt = ctxt
       
   257     val ((As, Ds), ctxt) = ctxt
       
   258       |> mk_TFrees live
       
   259       ||>> mk_TFrees' (map Type.sort_of_atyp (deads_of_bnf bnf))
       
   260     val T = mk_T_of_bnf Ds As bnf
       
   261     val argTs = map mk_pred1T As
       
   262     val (args, ctxt) = mk_Frees "P" argTs ctxt
       
   263     val relator = mk_rel_of_bnf Ds As As bnf
       
   264     val lhs = list_comb (relator, map mk_eq_onp args)
       
   265     val rhs = mk_eq_onp (mk_pred pred_def args T)
       
   266     val goal = HOLogic.mk_eq (lhs, rhs) |> HOLogic.mk_Trueprop
       
   267     val thm = Goal.prove_sorry ctxt [] [] goal
       
   268       (fn {context = ctxt, prems = _} => pred_eq_onp_tac bnf pred_def ctxt 1)
       
   269       |> Thm.close_derivation
       
   270   in
       
   271     Drule.zero_var_indexes (singleton (Variable.export ctxt old_ctxt) thm)
       
   272   end
       
   273 
       
   274 fun predicator bnf lthy =
   209 fun predicator bnf lthy =
   275   let
   210   let
   276     val (pred_def, lthy) = define_pred bnf lthy
   211     val pred_def = pred_set_of_bnf bnf
   277     val pred_def = Morphism.thm (Local_Theory.target_morphism lthy) pred_def
       
   278     val Domainp_rel = prove_Domainp_rel lthy bnf pred_def
   212     val Domainp_rel = prove_Domainp_rel lthy bnf pred_def
   279     val rel_eq_onp = prove_rel_eq_onp lthy bnf pred_def
   213     val rel_eq_onp = rel_eq_onp_of_bnf bnf
   280     fun qualify defname suffix = Binding.qualified true suffix defname
   214     fun qualify defname suffix = Binding.qualified true suffix defname
   281     val Domainp_rel_thm_name = qualify (base_name_of_bnf bnf) "Domainp_rel"
   215     val Domainp_rel_thm_name = qualify (base_name_of_bnf bnf) "Domainp_rel"
   282     val rel_eq_onp_thm_name = qualify (base_name_of_bnf bnf) "rel_eq_onp"
       
   283     val pred_data = Transfer.mk_pred_data pred_def rel_eq_onp []
   216     val pred_data = Transfer.mk_pred_data pred_def rel_eq_onp []
   284     val type_name = type_name_of_bnf bnf
   217     val type_name = type_name_of_bnf bnf
   285     val relator_domain_attr = @{attributes [relator_domain]}
   218     val relator_domain_attr = @{attributes [relator_domain]}
   286     val notes = [((Domainp_rel_thm_name, []), [([Domainp_rel], relator_domain_attr)]),
   219     val notes = [((Domainp_rel_thm_name, []), [([Domainp_rel], relator_domain_attr)])]
   287       ((rel_eq_onp_thm_name, []), [([rel_eq_onp], [])])]
       
   288   in
   220   in
   289     lthy
   221     lthy
   290     |> Local_Theory.notes notes
   222     |> Local_Theory.notes notes
   291     |> snd
   223     |> snd
   292     |> Local_Theory.declaration {syntax = false, pervasive = true}
   224     |> Local_Theory.declaration {syntax = false, pervasive = true}
   326     val liveness = liveness_of_fp_bnf (length As) (hd (#bnfs (#fp_res fp_sugar)));
   258     val liveness = liveness_of_fp_bnf (length As) (hd (#bnfs (#fp_res fp_sugar)));
   327   in
   259   in
   328     map_filter (uncurry (fn true => SOME | false => K NONE)) (liveness ~~ As)
   260     map_filter (uncurry (fn true => SOME | false => K NONE)) (liveness ~~ As)
   329   end
   261   end
   330 
   262 
   331 fun prove_pred_inject lthy (fp_sugar:fp_sugar) =
   263 fun prove_pred_inject lthy (fp_sugar : fp_sugar) =
   332   let
   264   let
   333     val involved_types = distinct op= (
   265     val involved_types = distinct op= (
   334         map type_name_of_bnf (#fp_nesting_bnfs fp_sugar)
   266         map type_name_of_bnf (#fp_nesting_bnfs fp_sugar)
   335       @ map type_name_of_bnf (#live_nesting_bnfs fp_sugar)
   267       @ map type_name_of_bnf (#live_nesting_bnfs fp_sugar)
   336       @ map type_name_of_bnf (#bnfs (#fp_res fp_sugar)))
   268       @ map type_name_of_bnf (#bnfs (#fp_res fp_sugar)))