src/HOLCF/Tools/Domain/domain_theorems.ML
changeset 40026 8f8f18a88685
parent 40025 876689e6bbdf
child 40029 57e7f651fc70
equal deleted inserted replaced
40025:876689e6bbdf 40026:8f8f18a88685
     8 val HOLCF_ss = @{simpset};
     8 val HOLCF_ss = @{simpset};
     9 
     9 
    10 signature DOMAIN_THEOREMS =
    10 signature DOMAIN_THEOREMS =
    11 sig
    11 sig
    12   val comp_theorems :
    12   val comp_theorems :
    13       binding * Domain_Library.eq list ->
    13       binding -> binding list ->
    14       binding list ->
       
    15       Domain_Take_Proofs.take_induct_info ->
    14       Domain_Take_Proofs.take_induct_info ->
    16       Domain_Constructors.constr_info list ->
    15       Domain_Constructors.constr_info list ->
    17       theory -> thm list * theory
    16       theory -> thm list * theory
    18 
    17 
    19   val quiet_mode: bool Unsynchronized.ref;
    18   val quiet_mode: bool Unsynchronized.ref;
   152     (constr_infos : Domain_Constructors.constr_info list)
   151     (constr_infos : Domain_Constructors.constr_info list)
   153     (take_info : Domain_Take_Proofs.take_induct_info)
   152     (take_info : Domain_Take_Proofs.take_induct_info)
   154     (take_rews : thm list)
   153     (take_rews : thm list)
   155     (thy : theory) =
   154     (thy : theory) =
   156 let
   155 let
   157   val comp_dname = Sign.full_name thy comp_dbind;
   156   val comp_dname = Binding.name_of comp_dbind;
   158 
   157 
   159   val iso_infos = map #iso_info constr_infos;
   158   val iso_infos = map #iso_info constr_infos;
   160   val exhausts = map #exhaust constr_infos;
   159   val exhausts = map #exhaust constr_infos;
   161   val con_rews = maps #con_rews constr_infos;
   160   val con_rews = maps #con_rews constr_infos;
   162   val {take_consts, take_induct_thms, ...} = take_info;
   161   val {take_consts, take_induct_thms, ...} = take_info;
   279         in bot :: map name_of (#con_specs constr_info) end;
   278         in bot :: map name_of (#con_specs constr_info) end;
   280     in adms @ flat (map2 one_eq bottoms constr_infos) end;
   279     in adms @ flat (map2 one_eq bottoms constr_infos) end;
   281 
   280 
   282   val inducts = Project_Rule.projections (ProofContext.init_global thy) ind;
   281   val inducts = Project_Rule.projections (ProofContext.init_global thy) ind;
   283   fun ind_rule (dname, rule) =
   282   fun ind_rule (dname, rule) =
   284       ((Binding.empty, [rule]),
   283       ((Binding.empty, rule),
   285        [Rule_Cases.case_names case_ns, Induct.induct_type dname]);
   284        [Rule_Cases.case_names case_ns, Induct.induct_type dname]);
   286 
   285 
   287 in
   286 in
   288   thy
   287   thy
   289   |> snd o Global_Theory.add_thmss [
   288   |> snd o Global_Theory.add_thms [
   290      ((Binding.qualified true "finite_induct" comp_dbind, [finite_ind]), []),
   289      ((Binding.qualified true "finite_induct" comp_dbind, finite_ind), []),
   291      ((Binding.qualified true "induct"        comp_dbind, [ind]       ), [])]
   290      ((Binding.qualified true "induct"        comp_dbind, ind       ), [])]
   292   |> (snd o Global_Theory.add_thmss (map ind_rule (dnames ~~ inducts)))
   291   |> (snd o Global_Theory.add_thms (map ind_rule (dnames ~~ inducts)))
   293 end; (* prove_induction *)
   292 end; (* prove_induction *)
   294 
   293 
   295 (******************************************************************************)
   294 (******************************************************************************)
   296 (************************ bisimulation and coinduction ************************)
   295 (************************ bisimulation and coinduction ************************)
   297 (******************************************************************************)
   296 (******************************************************************************)
   301     (constr_infos : Domain_Constructors.constr_info list)
   300     (constr_infos : Domain_Constructors.constr_info list)
   302     (take_info : Domain_Take_Proofs.take_induct_info)
   301     (take_info : Domain_Take_Proofs.take_induct_info)
   303     (take_rews : thm list list)
   302     (take_rews : thm list list)
   304     (thy : theory) : theory =
   303     (thy : theory) : theory =
   305 let
   304 let
   306   val comp_dname = Sign.full_name thy comp_dbind;
       
   307 
       
   308   val iso_infos = map #iso_info constr_infos;
   305   val iso_infos = map #iso_info constr_infos;
   309   val newTs = map #absT iso_infos;
   306   val newTs = map #absT iso_infos;
   310 
   307 
   311   val {take_consts, take_0_thms, take_lemma_thms, ...} = take_info;
   308   val {take_consts, take_0_thms, take_lemma_thms, ...} = take_info;
   312 
   309 
   421 (******************************************************************************)
   418 (******************************************************************************)
   422 (******************************* main function ********************************)
   419 (******************************* main function ********************************)
   423 (******************************************************************************)
   420 (******************************************************************************)
   424 
   421 
   425 fun comp_theorems
   422 fun comp_theorems
   426     (comp_dbind : binding, eqs : Domain_Library.eq list)
   423     (comp_dbind : binding)
   427     (dbinds : binding list)
   424     (dbinds : binding list)
   428     (take_info : Domain_Take_Proofs.take_induct_info)
   425     (take_info : Domain_Take_Proofs.take_induct_info)
   429     (constr_infos : Domain_Constructors.constr_info list)
   426     (constr_infos : Domain_Constructors.constr_info list)
   430     (thy : theory) =
   427     (thy : theory) =
   431 let
   428 let
   432 val dnames = map (fst o fst) eqs;
   429 val comp_dname = Binding.name_of comp_dbind;
   433 val comp_dname = Sign.full_name thy comp_dbind;
       
   434 
   430 
   435 (* Test for emptiness *)
   431 (* Test for emptiness *)
       
   432 (* FIXME: reimplement emptiness test
   436 local
   433 local
   437   open Domain_Library;
   434   open Domain_Library;
       
   435   val dnames = map (fst o fst) eqs;
   438   val conss = map snd eqs;
   436   val conss = map snd eqs;
   439   fun rec_to ns lazy_rec (n,cons) = forall (exists (fn arg => 
   437   fun rec_to ns lazy_rec (n,cons) = forall (exists (fn arg => 
   440         is_rec arg andalso not (member (op =) ns (rec_of arg)) andalso
   438         is_rec arg andalso not (member (op =) ns (rec_of arg)) andalso
   441         ((rec_of arg =  n andalso not (lazy_rec orelse is_lazy arg)) orelse 
   439         ((rec_of arg =  n andalso not (lazy_rec orelse is_lazy arg)) orelse 
   442           rec_of arg <> n andalso rec_to (rec_of arg::ns) 
   440           rec_of arg <> n andalso rec_to (rec_of arg::ns) 
   448     else false;
   446     else false;
   449 in
   447 in
   450   val n__eqs = mapn (fn n => fn (_,cons) => (n,cons)) 0 eqs;
   448   val n__eqs = mapn (fn n => fn (_,cons) => (n,cons)) 0 eqs;
   451   val is_emptys = map warn n__eqs;
   449   val is_emptys = map warn n__eqs;
   452 end;
   450 end;
       
   451 *)
   453 
   452 
   454 (* Test for indirect recursion *)
   453 (* Test for indirect recursion *)
   455 local
   454 local
   456   open Domain_Library;
   455   val newTs = map (#absT o #iso_info) constr_infos;
   457   fun indirect_arg arg =
   456   fun indirect_typ (Type (_, Ts)) =
   458       rec_of arg = ~1 andalso Datatype_Aux.is_rec_type (dtyp_of arg);
   457       exists (fn T => member (op =) newTs T orelse indirect_typ T) Ts
       
   458     | indirect_typ _ = false;
       
   459   fun indirect_arg (_, T) = indirect_typ T;
   459   fun indirect_con (_, args) = exists indirect_arg args;
   460   fun indirect_con (_, args) = exists indirect_arg args;
   460   fun indirect_eq (_, cons) = exists indirect_con cons;
   461   fun indirect_eq cons = exists indirect_con cons;
   461 in
   462 in
   462   val is_indirect = exists indirect_eq eqs;
   463   val is_indirect = exists indirect_eq (map #con_specs constr_infos);
   463   val _ =
   464   val _ =
   464       if is_indirect
   465       if is_indirect
   465       then message "Indirect recursion detected, skipping proofs of (co)induction rules"
   466       then message "Indirect recursion detected, skipping proofs of (co)induction rules"
   466       else message ("Proving induction properties of domain "^comp_dname^" ...");
   467       else message ("Proving induction properties of domain "^comp_dname^" ...");
   467 end;
   468 end;