src/HOL/Library/bnf_lfp_countable.ML
author wenzelm
Sat, 18 Jul 2015 20:47:08 +0200
changeset 60752 b48830b670a1
parent 60728 26ffdb966759
child 60757 c09598a97436
permissions -rw-r--r--
prefer tactics with explicit context;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
     1
(*  Title:      HOL/Library/bnf_lfp_countable.ML
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
     2
    Author:     Jasmin Blanchette, TU Muenchen
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
     3
    Copyright   2014
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
     4
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
     5
Countability tactic for BNF datatypes.
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
     6
*)
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
     7
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
     8
signature BNF_LFP_COUNTABLE =
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
     9
sig
58165
2ec97d9c1e83 'prove_sorry' is too dangerous here -- the tactic is sometimes applied to non-theorems
blanchet
parents: 58161
diff changeset
    10
  val derive_encode_injectives_thms: Proof.context -> string list -> thm list
58161
deeff89d5b9e added compatibility function
blanchet
parents: 58160
diff changeset
    11
  val countable_datatype_tac: Proof.context -> tactic
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    12
end;
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    13
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    14
structure BNF_LFP_Countable : BNF_LFP_COUNTABLE =
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    15
struct
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    16
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    17
open BNF_FP_Rec_Sugar_Util
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    18
open BNF_Def
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    19
open BNF_Util
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    20
open BNF_Tactics
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    21
open BNF_FP_Util
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    22
open BNF_FP_Def_Sugar
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    23
58174
e51b4c7685a9 intelligible errors instead of tactic failures
blanchet
parents: 58172
diff changeset
    24
val countableS = @{sort countable};
e51b4c7685a9 intelligible errors instead of tactic failures
blanchet
parents: 58172
diff changeset
    25
60728
26ffdb966759 {r,e,d,f}tac with proper context in BNF
traytel
parents: 59970
diff changeset
    26
fun nchotomy_tac ctxt nchotomy =
26ffdb966759 {r,e,d,f}tac with proper context in BNF
traytel
parents: 59970
diff changeset
    27
  HEADGOAL (rtac ctxt (nchotomy RS @{thm all_reg[rotated]}) THEN'
59498
50b60f501b05 proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
wenzelm
parents: 58634
diff changeset
    28
    REPEAT_ALL_NEW (resolve0_tac [allI, impI] ORELSE' eresolve0_tac [exE, disjE]));
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    29
60728
26ffdb966759 {r,e,d,f}tac with proper context in BNF
traytel
parents: 59970
diff changeset
    30
fun meta_spec_mp_tac ctxt 0 = K all_tac
26ffdb966759 {r,e,d,f}tac with proper context in BNF
traytel
parents: 59970
diff changeset
    31
  | meta_spec_mp_tac ctxt depth =
60752
b48830b670a1 prefer tactics with explicit context;
wenzelm
parents: 60728
diff changeset
    32
    dtac ctxt meta_spec THEN' meta_spec_mp_tac ctxt (depth - 1) THEN'
b48830b670a1 prefer tactics with explicit context;
wenzelm
parents: 60728
diff changeset
    33
    dtac ctxt meta_mp THEN' assume_tac ctxt;
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    34
60728
26ffdb966759 {r,e,d,f}tac with proper context in BNF
traytel
parents: 59970
diff changeset
    35
fun use_induction_hypothesis_tac ctxt =
58161
deeff89d5b9e added compatibility function
blanchet
parents: 58160
diff changeset
    36
  DEEPEN (1, 64 (* large number *))
60752
b48830b670a1 prefer tactics with explicit context;
wenzelm
parents: 60728
diff changeset
    37
    (fn depth => meta_spec_mp_tac ctxt depth THEN' etac ctxt allE THEN' etac ctxt impE THEN'
b48830b670a1 prefer tactics with explicit context;
wenzelm
parents: 60728
diff changeset
    38
      assume_tac ctxt THEN' assume_tac ctxt) 0;
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    39
58172
f04e24a24fb9 made new tactic even more robust
blanchet
parents: 58170
diff changeset
    40
val same_ctr_simps = @{thms sum_encode_eq prod_encode_eq sum.inject prod.inject to_nat_split
f04e24a24fb9 made new tactic even more robust
blanchet
parents: 58170
diff changeset
    41
  id_apply snd_conv simp_thms};
58166
86a374caeb82 improved new countability tactic
blanchet
parents: 58165
diff changeset
    42
val distinct_ctrs_simps = @{thms sum_encode_eq sum.inject sum.distinct simp_thms};
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    43
58166
86a374caeb82 improved new countability tactic
blanchet
parents: 58165
diff changeset
    44
fun same_ctr_tac ctxt injects recs map_congs' inj_map_strongs' =
86a374caeb82 improved new countability tactic
blanchet
parents: 58165
diff changeset
    45
  HEADGOAL (asm_full_simp_tac
86a374caeb82 improved new countability tactic
blanchet
parents: 58165
diff changeset
    46
      (ss_only (injects @ recs @ map_congs' @ same_ctr_simps) ctxt) THEN_MAYBE'
60728
26ffdb966759 {r,e,d,f}tac with proper context in BNF
traytel
parents: 59970
diff changeset
    47
    TRY o REPEAT_ALL_NEW (rtac ctxt conjI) THEN_ALL_NEW
59498
50b60f501b05 proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
wenzelm
parents: 58634
diff changeset
    48
    REPEAT_ALL_NEW (eresolve_tac ctxt (conjE :: inj_map_strongs')) THEN_ALL_NEW
60752
b48830b670a1 prefer tactics with explicit context;
wenzelm
parents: 60728
diff changeset
    49
    (assume_tac ctxt ORELSE' use_induction_hypothesis_tac ctxt));
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    50
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    51
fun distinct_ctrs_tac ctxt recs =
58166
86a374caeb82 improved new countability tactic
blanchet
parents: 58165
diff changeset
    52
  HEADGOAL (asm_full_simp_tac (ss_only (recs @ distinct_ctrs_simps) ctxt));
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    53
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    54
fun mk_encode_injective_tac ctxt n nchotomy injects recs map_comps' inj_map_strongs' =
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    55
  let val ks = 1 upto n in
60728
26ffdb966759 {r,e,d,f}tac with proper context in BNF
traytel
parents: 59970
diff changeset
    56
    EVERY (maps (fn k => nchotomy_tac ctxt nchotomy :: map (fn k' =>
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    57
      if k = k' then same_ctr_tac ctxt injects recs map_comps' inj_map_strongs'
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    58
      else distinct_ctrs_tac ctxt recs) ks) ks)
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    59
  end;
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    60
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    61
fun mk_encode_injectives_tac ctxt ns induct nchotomys injectss recss map_comps' inj_map_strongs' =
60728
26ffdb966759 {r,e,d,f}tac with proper context in BNF
traytel
parents: 59970
diff changeset
    62
  HEADGOAL (rtac ctxt induct) THEN
58634
9f10d82e8188 added parameterized ML antiquotations @{map N}, @{fold N}, @{fold_map N}, @{split_list N};
wenzelm
parents: 58461
diff changeset
    63
  EVERY (@{map 4} (fn n => fn nchotomy => fn injects => fn recs =>
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    64
      mk_encode_injective_tac ctxt n nchotomy injects recs map_comps' inj_map_strongs')
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    65
    ns nchotomys injectss recss);
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    66
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    67
fun endgame_tac ctxt encode_injectives =
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    68
  unfold_thms_tac ctxt @{thms inj_on_def ball_UNIV} THEN
60728
26ffdb966759 {r,e,d,f}tac with proper context in BNF
traytel
parents: 59970
diff changeset
    69
  ALLGOALS (rtac ctxt exI THEN' rtac ctxt allI THEN' resolve_tac ctxt encode_injectives);
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    70
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    71
fun encode_sumN n k t =
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    72
  Balanced_Tree.access {init = t,
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    73
      left = fn t => @{const sum_encode} $ (@{const Inl (nat, nat)} $ t),
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    74
      right = fn t => @{const sum_encode} $ (@{const Inr (nat, nat)} $ t)}
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    75
    n k;
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    76
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    77
fun encode_tuple [] = @{term "0 :: nat"}
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    78
  | encode_tuple ts =
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    79
    Balanced_Tree.make (fn (t, u) => @{const prod_encode} $ (@{const Pair (nat, nat)} $ u $ t)) ts;
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    80
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    81
fun mk_encode_funs ctxt fpTs ns ctrss0 recs0 =
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    82
  let
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    83
    val thy = Proof_Context.theory_of ctxt;
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    84
58174
e51b4c7685a9 intelligible errors instead of tactic failures
blanchet
parents: 58172
diff changeset
    85
    fun check_countable T =
e51b4c7685a9 intelligible errors instead of tactic failures
blanchet
parents: 58172
diff changeset
    86
      Sign.of_sort thy (T, countableS) orelse
e51b4c7685a9 intelligible errors instead of tactic failures
blanchet
parents: 58172
diff changeset
    87
      raise TYPE ("Type is not of sort " ^ Syntax.string_of_sort ctxt countableS, [T], []);
e51b4c7685a9 intelligible errors instead of tactic failures
blanchet
parents: 58172
diff changeset
    88
e51b4c7685a9 intelligible errors instead of tactic failures
blanchet
parents: 58172
diff changeset
    89
    fun mk_to_nat_checked T =
e51b4c7685a9 intelligible errors instead of tactic failures
blanchet
parents: 58172
diff changeset
    90
      Const (@{const_name to_nat}, tap check_countable T --> HOLogic.natT);
e51b4c7685a9 intelligible errors instead of tactic failures
blanchet
parents: 58172
diff changeset
    91
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    92
    val nn = length ns;
58221
5451c61ee186 compile
blanchet
parents: 58174
diff changeset
    93
    val recs as rec1 :: _ = map2 (mk_co_rec thy Least_FP (replicate nn HOLogic.natT)) fpTs recs0;
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    94
    val arg_Ts = binder_fun_types (fastype_of rec1);
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    95
    val arg_Tss = Library.unflat ctrss0 arg_Ts;
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    96
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    97
    fun mk_U (Type (@{type_name prod}, [T1, T2])) =
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    98
        if member (op =) fpTs T1 then T2 else HOLogic.mk_prodT (mk_U T1, mk_U T2)
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
    99
      | mk_U (Type (s, Ts)) = Type (s, map mk_U Ts)
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   100
      | mk_U T = T;
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   101
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   102
    fun mk_nat (j, T) =
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   103
      if T = HOLogic.natT then
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   104
        SOME (Bound j)
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   105
      else if member (op =) fpTs T then
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   106
        NONE
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   107
      else if exists_subtype_in fpTs T then
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   108
        let val U = mk_U T in
58174
e51b4c7685a9 intelligible errors instead of tactic failures
blanchet
parents: 58172
diff changeset
   109
          SOME (mk_to_nat_checked U $ (build_map ctxt [] (snd_const o fst) (T, U) $ Bound j))
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   110
        end
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   111
      else
58174
e51b4c7685a9 intelligible errors instead of tactic failures
blanchet
parents: 58172
diff changeset
   112
        SOME (mk_to_nat_checked T $ Bound j);
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   113
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   114
    fun mk_arg n (k, arg_T) =
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   115
      let
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   116
        val bound_Ts = rev (binder_types arg_T);
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   117
        val nats = map_filter mk_nat (tag_list 0 bound_Ts);
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   118
      in
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   119
        fold (fn T => fn t => Abs (Name.uu, T, t)) bound_Ts (encode_sumN n k (encode_tuple nats))
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   120
      end;
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   121
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   122
    val argss = map2 (map o mk_arg) ns (map (tag_list 1) arg_Tss);
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   123
  in
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   124
    map (fn recx => Term.list_comb (recx, flat argss)) recs
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   125
  end;
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   126
58165
2ec97d9c1e83 'prove_sorry' is too dangerous here -- the tactic is sometimes applied to non-theorems
blanchet
parents: 58161
diff changeset
   127
fun derive_encode_injectives_thms _ [] = []
2ec97d9c1e83 'prove_sorry' is too dangerous here -- the tactic is sometimes applied to non-theorems
blanchet
parents: 58161
diff changeset
   128
  | derive_encode_injectives_thms ctxt fpT_names0 =
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   129
    let
58315
6d8458bc6e27 tuning terminology
blanchet
parents: 58296
diff changeset
   130
      fun not_datatype s = error (quote s ^ " is not a datatype");
6d8458bc6e27 tuning terminology
blanchet
parents: 58296
diff changeset
   131
      fun not_mutually_recursive ss = error (commas ss ^ " are not mutually recursive datatypes");
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   132
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   133
      fun lfp_sugar_of s =
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   134
        (case fp_sugar_of ctxt s of
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   135
          SOME (fp_sugar as {fp = Least_FP, ...}) => fp_sugar
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   136
        | _ => not_datatype s);
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   137
58232
7b70a2b4ec9b made new countable tactic work with sorts other than 'type'
blanchet
parents: 58221
diff changeset
   138
      val fpTs0 as Type (_, var_As) :: _ =
7b70a2b4ec9b made new countable tactic work with sorts other than 'type'
blanchet
parents: 58221
diff changeset
   139
        map (#T o lfp_sugar_of o fst o dest_Type) (#Ts (#fp_res (lfp_sugar_of (hd fpT_names0))));
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   140
      val fpT_names = map (fst o dest_Type) fpTs0;
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   141
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   142
      val (As_names, _) = Variable.variant_fixes (map (fn TVar ((s, _), _) => s) var_As) ctxt;
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   143
      val As =
58174
e51b4c7685a9 intelligible errors instead of tactic failures
blanchet
parents: 58172
diff changeset
   144
        map2 (fn s => fn TVar (_, S) => TFree (s, union (op =) countableS S))
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   145
          As_names var_As;
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   146
      val fpTs = map (fn s => Type (s, As)) fpT_names;
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   147
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   148
      val _ = subset (op =) (fpT_names0, fpT_names) orelse not_mutually_recursive fpT_names0;
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   149
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   150
      fun mk_conjunct fpT x encode_fun =
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   151
        HOLogic.all_const fpT $ Abs (Name.uu, fpT,
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   152
          HOLogic.mk_imp (HOLogic.mk_eq (encode_fun $ x, encode_fun $ Bound 0),
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   153
            HOLogic.eq_const fpT $ x $ Bound 0));
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   154
58461
75ee8d49c724 refactor fp_sugar move theorems
desharna
parents: 58460
diff changeset
   155
      val fp_sugars as
75ee8d49c724 refactor fp_sugar move theorems
desharna
parents: 58460
diff changeset
   156
          {fp_nesting_bnfs, fp_co_induct_sugar = {common_co_inducts = induct :: _, ...}, ...} :: _ =
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   157
        map (the o fp_sugar_of ctxt o fst o dest_Type) fpTs0;
58460
a88eb33058f7 refactor fp_sugar move theorems
desharna
parents: 58459
diff changeset
   158
      val ctr_sugars = map (#ctr_sugar o #fp_ctr_sugar) fp_sugars;
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   159
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   160
      val ctrss0 = map #ctrs ctr_sugars;
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   161
      val ns = map length ctrss0;
58461
75ee8d49c724 refactor fp_sugar move theorems
desharna
parents: 58460
diff changeset
   162
      val recs0 = map (#co_rec o #fp_co_induct_sugar) fp_sugars;
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   163
      val nchotomys = map #nchotomy ctr_sugars;
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   164
      val injectss = map #injects ctr_sugars;
58459
f70bffabd7cf refactor fp_sugar move theorems
desharna
parents: 58315
diff changeset
   165
      val rec_thmss = map (#co_rec_thms o #fp_co_induct_sugar) fp_sugars;
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   166
      val map_comps' = map (unfold_thms ctxt @{thms comp_def} o map_comp_of_bnf) fp_nesting_bnfs;
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   167
      val inj_map_strongs' = map (Thm.permute_prems 0 ~1 o inj_map_strong_of_bnf) fp_nesting_bnfs;
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   168
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   169
      val (xs, names_ctxt) = ctxt |> mk_Frees "x" fpTs;
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   170
58634
9f10d82e8188 added parameterized ML antiquotations @{map N}, @{fold N}, @{fold_map N}, @{split_list N};
wenzelm
parents: 58461
diff changeset
   171
      val conjuncts = @{map 3} mk_conjunct fpTs xs (mk_encode_funs ctxt fpTs ns ctrss0 recs0);
58170
d84bab7ed89e fixed tactic for n-way mutual recursion, n >= 4 (balanced conjunctions confuse the tactic)
blanchet
parents: 58168
diff changeset
   172
      val goal = HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj conjuncts);
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   173
    in
58296
759e47518d80 comment
blanchet
parents: 58232
diff changeset
   174
      Goal.prove (*no sorry*) ctxt [] [] goal (fn {context = ctxt, prems = _} =>
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   175
        mk_encode_injectives_tac ctxt ns induct nchotomys injectss rec_thmss map_comps'
58161
deeff89d5b9e added compatibility function
blanchet
parents: 58160
diff changeset
   176
          inj_map_strongs')
59970
e9f73d87d904 proper context for Object_Logic operations;
wenzelm
parents: 59498
diff changeset
   177
      |> HOLogic.conj_elims ctxt
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   178
      |> Proof_Context.export names_ctxt ctxt
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   179
      |> map Thm.close_derivation
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   180
    end;
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   181
58165
2ec97d9c1e83 'prove_sorry' is too dangerous here -- the tactic is sometimes applied to non-theorems
blanchet
parents: 58161
diff changeset
   182
fun get_countable_goal_type_name (@{const Trueprop} $ (Const (@{const_name Ex}, _)
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   183
    $ Abs (_, Type (_, [Type (s, _), _]), Const (@{const_name inj_on}, _) $ Bound 0
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   184
        $ Const (@{const_name top}, _)))) = s
58165
2ec97d9c1e83 'prove_sorry' is too dangerous here -- the tactic is sometimes applied to non-theorems
blanchet
parents: 58161
diff changeset
   185
  | get_countable_goal_type_name _ = error "Wrong goal format for datatype countability tactic";
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   186
58161
deeff89d5b9e added compatibility function
blanchet
parents: 58160
diff changeset
   187
fun core_countable_datatype_tac ctxt st =
58165
2ec97d9c1e83 'prove_sorry' is too dangerous here -- the tactic is sometimes applied to non-theorems
blanchet
parents: 58161
diff changeset
   188
  let val T_names = map get_countable_goal_type_name (Thm.prems_of st) in
2ec97d9c1e83 'prove_sorry' is too dangerous here -- the tactic is sometimes applied to non-theorems
blanchet
parents: 58161
diff changeset
   189
    endgame_tac ctxt (derive_encode_injectives_thms ctxt T_names) st
2ec97d9c1e83 'prove_sorry' is too dangerous here -- the tactic is sometimes applied to non-theorems
blanchet
parents: 58161
diff changeset
   190
  end;
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   191
58161
deeff89d5b9e added compatibility function
blanchet
parents: 58160
diff changeset
   192
fun countable_datatype_tac ctxt =
59498
50b60f501b05 proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
wenzelm
parents: 58634
diff changeset
   193
  TRY (Class.intro_classes_tac ctxt []) THEN core_countable_datatype_tac ctxt;
58160
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   194
e4965b677ba9 added countable tactic for new-style datatypes
blanchet
parents:
diff changeset
   195
end;