src/HOL/Nominal/nominal_inductive2.ML
author wenzelm
Sat, 22 Mar 2014 18:16:54 +0100
changeset 56253 83b3c110f22d
parent 54983 2c57fc1f7a8c
child 58112 8081087096ad
permissions -rw-r--r--
more antiquotations;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
     1
(*  Title:      HOL/Nominal/nominal_inductive2.ML
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
     2
    Author:     Stefan Berghofer, TU Muenchen
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
     3
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
     4
Infrastructure for proving equivariance and strong induction theorems
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
     5
for inductive predicates involving nominal datatypes.
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
     6
Experimental version that allows to avoid lists of atoms.
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
     7
*)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
     8
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
     9
signature NOMINAL_INDUCTIVE2 =
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    10
sig
38715
6513ea67d95d renamed Simplifier.simproc(_i) to Simplifier.simproc_global(_i) to emphasize that this is not the real thing;
wenzelm
parents: 38558
diff changeset
    11
  val prove_strong_ind: string -> string option -> (string * string list) list ->
6513ea67d95d renamed Simplifier.simproc(_i) to Simplifier.simproc_global(_i) to emphasize that this is not the real thing;
wenzelm
parents: 38558
diff changeset
    12
    local_theory -> Proof.state
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    13
end
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    14
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    15
structure NominalInductive2 : NOMINAL_INDUCTIVE2 =
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    16
struct
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    17
33772
b6a1feca2ac2 use of thm-antiquotation
Christian Urban <urbanc@in.tum.de>
parents: 33671
diff changeset
    18
val inductive_forall_def = @{thm induct_forall_def};
b6a1feca2ac2 use of thm-antiquotation
Christian Urban <urbanc@in.tum.de>
parents: 33671
diff changeset
    19
val inductive_atomize = @{thms induct_atomize};
b6a1feca2ac2 use of thm-antiquotation
Christian Urban <urbanc@in.tum.de>
parents: 33671
diff changeset
    20
val inductive_rulify = @{thms induct_rulify};
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    21
41228
e1fce873b814 renamed structure MetaSimplifier to raw_Simplifer, to emphasize its meaning;
wenzelm
parents: 39557
diff changeset
    22
fun rulify_term thy = Raw_Simplifier.rewrite_term thy inductive_rulify [];
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    23
51717
9e7d1c139569 simplifier uses proper Proof.context instead of historic type simpset;
wenzelm
parents: 50771
diff changeset
    24
fun atomize_conv ctxt =
41228
e1fce873b814 renamed structure MetaSimplifier to raw_Simplifer, to emphasize its meaning;
wenzelm
parents: 39557
diff changeset
    25
  Raw_Simplifier.rewrite_cterm (true, false, false) (K (K NONE))
51717
9e7d1c139569 simplifier uses proper Proof.context instead of historic type simpset;
wenzelm
parents: 50771
diff changeset
    26
    (put_simpset HOL_basic_ss ctxt addsimps inductive_atomize);
9e7d1c139569 simplifier uses proper Proof.context instead of historic type simpset;
wenzelm
parents: 50771
diff changeset
    27
fun atomize_intr ctxt = Conv.fconv_rule (Conv.prems_conv ~1 (atomize_conv ctxt));
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    28
fun atomize_induct ctxt = Conv.fconv_rule (Conv.prems_conv ~1
51717
9e7d1c139569 simplifier uses proper Proof.context instead of historic type simpset;
wenzelm
parents: 50771
diff changeset
    29
  (Conv.params_conv ~1 (K (Conv.prems_conv ~1 (atomize_conv ctxt))) ctxt));
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    30
51717
9e7d1c139569 simplifier uses proper Proof.context instead of historic type simpset;
wenzelm
parents: 50771
diff changeset
    31
fun fresh_postprocess ctxt =
9e7d1c139569 simplifier uses proper Proof.context instead of historic type simpset;
wenzelm
parents: 50771
diff changeset
    32
  Simplifier.full_simplify (put_simpset HOL_basic_ss ctxt addsimps
30108
bd78f08b0ba1 Added postprocessing rules for fresh_star.
berghofe
parents: 30087
diff changeset
    33
    [@{thm fresh_star_set_eq}, @{thm fresh_star_Un_elim},
bd78f08b0ba1 Added postprocessing rules for fresh_star.
berghofe
parents: 30087
diff changeset
    34
     @{thm fresh_star_insert_elim}, @{thm fresh_star_empty_elim}]);
bd78f08b0ba1 Added postprocessing rules for fresh_star.
berghofe
parents: 30087
diff changeset
    35
44929
haftmann
parents: 44868
diff changeset
    36
fun preds_of ps t = inter (op = o apsnd dest_Free) ps (Term.add_frees t []);
30087
a780642a9c9c nominal_inductive and equivariance now work on local_theory.
berghofe
parents: 29585
diff changeset
    37
44689
f247fc952f31 tuned specifications
haftmann
parents: 44241
diff changeset
    38
val perm_bool = mk_meta_eq @{thm perm_bool_def};
39159
0dec18004e75 more antiquotations;
wenzelm
parents: 38795
diff changeset
    39
val perm_boolI = @{thm perm_boolI};
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    40
val (_, [perm_boolI_pi, _]) = Drule.strip_comb (snd (Thm.dest_comb
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    41
  (Drule.strip_imp_concl (cprop_of perm_boolI))));
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    42
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    43
fun mk_perm_bool pi th = th RS Drule.cterm_instantiate
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    44
  [(perm_boolI_pi, pi)] perm_boolI;
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    45
38715
6513ea67d95d renamed Simplifier.simproc(_i) to Simplifier.simproc_global(_i) to emphasize that this is not the real thing;
wenzelm
parents: 38558
diff changeset
    46
fun mk_perm_bool_simproc names = Simplifier.simproc_global_i
51717
9e7d1c139569 simplifier uses proper Proof.context instead of historic type simpset;
wenzelm
parents: 50771
diff changeset
    47
  (theory_of_thm perm_bool) "perm_bool" [@{term "perm pi x"}] (fn ctxt =>
56253
83b3c110f22d more antiquotations;
wenzelm
parents: 54983
diff changeset
    48
    fn Const (@{const_name Nominal.perm}, _) $ _ $ t =>
36692
54b64d4ad524 farewell to old-style mem infixes -- type inference in situations with mem_int and mem_string should provide enough information to resolve the type of (op =)
haftmann
parents: 36428
diff changeset
    49
         if member (op =) names (the_default "" (try (head_of #> dest_Const #> fst) t))
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    50
         then SOME perm_bool else NONE
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    51
     | _ => NONE);
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    52
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    53
fun transp ([] :: _) = []
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    54
  | transp xs = map hd xs :: transp (map tl xs);
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    55
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    56
fun add_binders thy i (t as (_ $ _)) bs = (case strip_comb t of
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    57
      (Const (s, T), ts) => (case strip_type T of
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    58
        (Ts, Type (tname, _)) =>
31938
f193d95b4632 nominal.ML is nominal_datatype.ML
haftmann
parents: 31723
diff changeset
    59
          (case NominalDatatype.get_nominal_datatype thy tname of
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    60
             NONE => fold (add_binders thy i) ts bs
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    61
           | SOME {descr, index, ...} => (case AList.lookup op =
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    62
                 (#3 (the (AList.lookup op = descr index))) s of
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    63
               NONE => fold (add_binders thy i) ts bs
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    64
             | SOME cargs => fst (fold (fn (xs, x) => fn (bs', cargs') =>
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    65
                 let val (cargs1, (u, _) :: cargs2) = chop (length xs) cargs'
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    66
                 in (add_binders thy i u
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    67
                   (fold (fn (u, T) =>
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    68
                      if exists (fn j => j < i) (loose_bnos u) then I
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    69
                      else AList.map_default op = (T, [])
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    70
                        (insert op aconv (incr_boundvars (~i) u)))
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    71
                          cargs1 bs'), cargs2)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    72
                 end) cargs (bs, ts ~~ Ts))))
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    73
      | _ => fold (add_binders thy i) ts bs)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    74
    | (u, ts) => add_binders thy i u (fold (add_binders thy i) ts bs))
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    75
  | add_binders thy i (Abs (_, _, t)) bs = add_binders thy (i + 1) t bs
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    76
  | add_binders thy i _ bs = bs;
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    77
38795
848be46708dc formerly unnamed infix conjunction and disjunction now named HOL.conj and HOL.disj
haftmann
parents: 38715
diff changeset
    78
fun split_conj f names (Const (@{const_name HOL.conj}, _) $ p $ q) _ = (case head_of p of
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    79
      Const (name, _) =>
36692
54b64d4ad524 farewell to old-style mem infixes -- type inference in situations with mem_int and mem_string should provide enough information to resolve the type of (op =)
haftmann
parents: 36428
diff changeset
    80
        if member (op =) names name then SOME (f p q) else NONE
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    81
    | _ => NONE)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    82
  | split_conj _ _ _ _ = NONE;
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    83
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    84
fun strip_all [] t = t
38558
32ad17fe2b9c tuned quotes
haftmann
parents: 38549
diff changeset
    85
  | strip_all (_ :: xs) (Const (@{const_name All}, _) $ Abs (s, T, t)) = strip_all xs t;
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    86
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    87
(*********************************************************************)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    88
(* maps  R ... & (ALL pi_1 ... pi_n z. P z (pi_1 o ... o pi_n o t))  *)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    89
(* or    ALL pi_1 ... pi_n z. P z (pi_1 o ... o pi_n o t)            *)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    90
(* to    R ... & id (ALL z. P z (pi_1 o ... o pi_n o t))             *)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    91
(* or    id (ALL z. P z (pi_1 o ... o pi_n o t))                     *)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    92
(*                                                                   *)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    93
(* where "id" protects the subformula from simplification            *)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    94
(*********************************************************************)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    95
38795
848be46708dc formerly unnamed infix conjunction and disjunction now named HOL.conj and HOL.disj
haftmann
parents: 38715
diff changeset
    96
fun inst_conj_all names ps pis (Const (@{const_name HOL.conj}, _) $ p $ q) _ =
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    97
      (case head_of p of
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
    98
         Const (name, _) =>
36692
54b64d4ad524 farewell to old-style mem infixes -- type inference in situations with mem_int and mem_string should provide enough information to resolve the type of (op =)
haftmann
parents: 36428
diff changeset
    99
           if member (op =) names name then SOME (HOLogic.mk_conj (p,
56253
83b3c110f22d more antiquotations;
wenzelm
parents: 54983
diff changeset
   100
             Const (@{const_name Fun.id}, HOLogic.boolT --> HOLogic.boolT) $
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   101
               (subst_bounds (pis, strip_all pis q))))
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   102
           else NONE
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   103
       | _ => NONE)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   104
  | inst_conj_all names ps pis t u =
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   105
      if member (op aconv) ps (head_of u) then
56253
83b3c110f22d more antiquotations;
wenzelm
parents: 54983
diff changeset
   106
        SOME (Const (@{const_name Fun.id}, HOLogic.boolT --> HOLogic.boolT) $
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   107
          (subst_bounds (pis, strip_all pis t)))
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   108
      else NONE
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   109
  | inst_conj_all _ _ _ _ _ = NONE;
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   110
51717
9e7d1c139569 simplifier uses proper Proof.context instead of historic type simpset;
wenzelm
parents: 50771
diff changeset
   111
fun inst_conj_all_tac ctxt k = EVERY
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   112
  [TRY (EVERY [etac conjE 1, rtac conjI 1, atac 1]),
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   113
   REPEAT_DETERM_N k (etac allE 1),
51717
9e7d1c139569 simplifier uses proper Proof.context instead of historic type simpset;
wenzelm
parents: 50771
diff changeset
   114
   simp_tac (put_simpset HOL_basic_ss ctxt addsimps [@{thm id_apply}]) 1];
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   115
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   116
fun map_term f t u = (case f t u of
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   117
      NONE => map_term' f t u | x => x)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   118
and map_term' f (t $ u) (t' $ u') = (case (map_term f t t', map_term f u u') of
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   119
      (NONE, NONE) => NONE
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   120
    | (SOME t'', NONE) => SOME (t'' $ u)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   121
    | (NONE, SOME u'') => SOME (t $ u'')
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   122
    | (SOME t'', SOME u'') => SOME (t'' $ u''))
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   123
  | map_term' f (Abs (s, T, t)) (Abs (s', T', t')) = (case map_term f t t' of
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   124
      NONE => NONE
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   125
    | SOME t'' => SOME (Abs (s, T, t'')))
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   126
  | map_term' _ _ _ = NONE;
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   127
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   128
(*********************************************************************)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   129
(*         Prove  F[f t]  from  F[t],  where F is monotone           *)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   130
(*********************************************************************)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   131
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   132
fun map_thm ctxt f tac monos opt th =
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   133
  let
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   134
    val prop = prop_of th;
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   135
    fun prove t =
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   136
      Goal.prove ctxt [] [] t (fn _ =>
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   137
        EVERY [cut_facts_tac [th] 1, etac rev_mp 1,
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   138
          REPEAT_DETERM (FIRSTGOAL (resolve_tac monos)),
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   139
          REPEAT_DETERM (rtac impI 1 THEN (atac 1 ORELSE tac))])
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   140
  in Option.map prove (map_term f prop (the_default prop opt)) end;
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   141
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   142
fun abs_params params t =
29276
94b1ffec9201 qualified Term.rename_wrt_term;
wenzelm
parents: 29270
diff changeset
   143
  let val vs =  map (Var o apfst (rpair 0)) (Term.rename_wrt_term t params)
46218
ecf6375e2abb renamed Term.list_all to Logic.list_all, in accordance to HOLogic.list_all;
wenzelm
parents: 44929
diff changeset
   144
  in (Logic.list_all (params, t), (rev vs, subst_bounds (vs, t))) end;
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   145
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   146
fun inst_params thy (vs, p) th cts =
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   147
  let val env = Pattern.first_order_match thy (p, prop_of th)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   148
    (Vartab.empty, Vartab.empty)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   149
  in Thm.instantiate ([],
32035
8e77b6a250d5 tuned/modernized Envir.subst_XXX;
wenzelm
parents: 31938
diff changeset
   150
    map (Envir.subst_term env #> cterm_of thy) vs ~~ cts) th
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   151
  end;
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   152
32304
berghofe
parents: 32303
diff changeset
   153
fun prove_strong_ind s alt_name avoids ctxt =
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   154
  let
42361
23f352990944 modernized structure Proof_Context;
wenzelm
parents: 41228
diff changeset
   155
    val thy = Proof_Context.theory_of ctxt;
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   156
    val ({names, ...}, {raw_induct, intrs, elims, ...}) =
31723
f5cafe803b55 discontinued ancient tradition to suffix certain ML module names with "_package"
haftmann
parents: 31177
diff changeset
   157
      Inductive.the_inductive ctxt (Sign.intern_const thy s);
f5cafe803b55 discontinued ancient tradition to suffix certain ML module names with "_package"
haftmann
parents: 31177
diff changeset
   158
    val ind_params = Inductive.params_of raw_induct;
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   159
    val raw_induct = atomize_induct ctxt raw_induct;
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   160
    val elims = map (atomize_induct ctxt) elims;
31723
f5cafe803b55 discontinued ancient tradition to suffix certain ML module names with "_package"
haftmann
parents: 31177
diff changeset
   161
    val monos = Inductive.get_monos ctxt;
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   162
    val eqvt_thms = NominalThmDecls.get_eqvt_thms ctxt;
33040
cffdb7b28498 removed old-style \ and \\ infixes
haftmann
parents: 33038
diff changeset
   163
    val _ = (case subtract (op =) (fold (Term.add_const_names o Thm.prop_of) eqvt_thms []) names of
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   164
        [] => ()
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   165
      | xs => error ("Missing equivariance theorem for predicate(s): " ^
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   166
          commas_quote xs));
44045
2814ff2a6e3e infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents: 43326
diff changeset
   167
    val induct_cases = map (fst o fst) (fst (Rule_Cases.get (the
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   168
      (Induct.lookup_inductP ctxt (hd names)))));
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   169
    val induct_cases' = if null induct_cases then replicate (length intrs) ""
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   170
      else induct_cases;
30087
a780642a9c9c nominal_inductive and equivariance now work on local_theory.
berghofe
parents: 29585
diff changeset
   171
    val ([raw_induct'], ctxt') = Variable.import_terms false [prop_of raw_induct] ctxt;
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   172
    val concls = raw_induct' |> Logic.strip_imp_concl |> HOLogic.dest_Trueprop |>
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   173
      HOLogic.dest_conj |> map (HOLogic.dest_imp ##> strip_comb);
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   174
    val ps = map (fst o snd) concls;
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   175
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   176
    val _ = (case duplicates (op = o pairself fst) avoids of
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   177
        [] => ()
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   178
      | xs => error ("Duplicate case names: " ^ commas_quote (map fst xs)));
33040
cffdb7b28498 removed old-style \ and \\ infixes
haftmann
parents: 33038
diff changeset
   179
    val _ = (case subtract (op =) induct_cases (map fst avoids) of
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   180
        [] => ()
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   181
      | xs => error ("No such case(s) in inductive definition: " ^ commas_quote xs));
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   182
    fun mk_avoids params name sets =
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   183
      let
42361
23f352990944 modernized structure Proof_Context;
wenzelm
parents: 41228
diff changeset
   184
        val (_, ctxt') = Proof_Context.add_fixes
28965
1de908189869 cleaned up binding module and related code
haftmann
parents: 28730
diff changeset
   185
          (map (fn (s, T) => (Binding.name s, SOME T, NoSyn)) params) ctxt;
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   186
        fun mk s =
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   187
          let
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   188
            val t = Syntax.read_term ctxt' s;
44241
7943b69f0188 modernized signature of Term.absfree/absdummy;
wenzelm
parents: 44045
diff changeset
   189
            val t' = fold_rev absfree params t |>
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   190
              funpow (length params) (fn Abs (_, _, t) => t)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   191
          in (t', HOLogic.dest_setT (fastype_of t)) end
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   192
          handle TERM _ =>
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   193
            error ("Expression " ^ quote s ^ " to be avoided in case " ^
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   194
              quote name ^ " is not a set type");
30108
bd78f08b0ba1 Added postprocessing rules for fresh_star.
berghofe
parents: 30087
diff changeset
   195
        fun add_set p [] = [p]
bd78f08b0ba1 Added postprocessing rules for fresh_star.
berghofe
parents: 30087
diff changeset
   196
          | add_set (t, T) ((u, U) :: ps) =
bd78f08b0ba1 Added postprocessing rules for fresh_star.
berghofe
parents: 30087
diff changeset
   197
              if T = U then
bd78f08b0ba1 Added postprocessing rules for fresh_star.
berghofe
parents: 30087
diff changeset
   198
                let val S = HOLogic.mk_setT T
34918
81c7ec7c1b91 union is an abbreviation for sup.
berghofe
parents: 33968
diff changeset
   199
                in (Const (@{const_name sup}, S --> S --> S) $ u $ t, T) :: ps
30108
bd78f08b0ba1 Added postprocessing rules for fresh_star.
berghofe
parents: 30087
diff changeset
   200
                end
bd78f08b0ba1 Added postprocessing rules for fresh_star.
berghofe
parents: 30087
diff changeset
   201
              else (u, U) :: add_set (t, T) ps
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   202
      in
30108
bd78f08b0ba1 Added postprocessing rules for fresh_star.
berghofe
parents: 30087
diff changeset
   203
        fold (mk #> add_set) sets []
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   204
      end;
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   205
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   206
    val prems = map (fn (prem, name) =>
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   207
      let
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   208
        val prems = map (incr_boundvars 1) (Logic.strip_assums_hyp prem);
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   209
        val concl = incr_boundvars 1 (Logic.strip_assums_concl prem);
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   210
        val params = Logic.strip_params prem
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   211
      in
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   212
        (params,
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   213
         if null avoids then
30450
7655e6533209 HOLogic.mk_set, HOLogic.dest_set
haftmann
parents: 30364
diff changeset
   214
           map (fn (T, ts) => (HOLogic.mk_set T ts, T))
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   215
             (fold (add_binders thy 0) (prems @ [concl]) [])
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   216
         else case AList.lookup op = avoids name of
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   217
           NONE => []
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   218
         | SOME sets =>
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   219
             map (apfst (incr_boundvars 1)) (mk_avoids params name sets),
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   220
         prems, strip_comb (HOLogic.dest_Trueprop concl))
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   221
      end) (Logic.strip_imp_prems raw_induct' ~~ induct_cases');
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   222
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   223
    val atomTs = distinct op = (maps (map snd o #2) prems);
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   224
    val atoms = map (fst o dest_Type) atomTs;
56253
83b3c110f22d more antiquotations;
wenzelm
parents: 54983
diff changeset
   225
    val ind_sort = if null atomTs then @{sort type}
36428
874843c1e96e really minimize sorts after certification -- looks like this is intended here;
wenzelm
parents: 36323
diff changeset
   226
      else Sign.minimize_sort thy (Sign.certify_sort thy (map (fn a => Sign.intern_class thy
874843c1e96e really minimize sorts after certification -- looks like this is intended here;
wenzelm
parents: 36323
diff changeset
   227
        ("fs_" ^ Long_Name.base_name a)) atoms));
43326
47cf4bc789aa simplified Name.variant -- discontinued builtin fold_map;
wenzelm
parents: 42361
diff changeset
   228
    val (fs_ctxt_tyname, _) = Name.variant "'n" (Variable.names_of ctxt');
30087
a780642a9c9c nominal_inductive and equivariance now work on local_theory.
berghofe
parents: 29585
diff changeset
   229
    val ([fs_ctxt_name], ctxt'') = Variable.variant_fixes ["z"] ctxt';
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   230
    val fsT = TFree (fs_ctxt_tyname, ind_sort);
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   231
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   232
    val inductive_forall_def' = Drule.instantiate'
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   233
      [SOME (ctyp_of thy fsT)] [] inductive_forall_def;
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   234
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   235
    fun lift_pred' t (Free (s, T)) ts =
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   236
      list_comb (Free (s, fsT --> T), t :: ts);
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   237
    val lift_pred = lift_pred' (Bound 0);
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   238
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   239
    fun lift_prem (t as (f $ u)) =
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   240
          let val (p, ts) = strip_comb t
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   241
          in
44868
92be5b32ca71 more modularization
haftmann
parents: 44689
diff changeset
   242
            if member (op =) ps p then HOLogic.mk_induct_forall fsT $
92be5b32ca71 more modularization
haftmann
parents: 44689
diff changeset
   243
              Abs ("z", fsT, lift_pred p (map (incr_boundvars 1) ts))
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   244
            else lift_prem f $ lift_prem u
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   245
          end
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   246
      | lift_prem (Abs (s, T, t)) = Abs (s, T, lift_prem t)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   247
      | lift_prem t = t;
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   248
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   249
    fun mk_fresh (x, T) = HOLogic.mk_Trueprop
31938
f193d95b4632 nominal.ML is nominal_datatype.ML
haftmann
parents: 31723
diff changeset
   250
      (NominalDatatype.fresh_star_const T fsT $ x $ Bound 0);
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   251
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   252
    val (prems', prems'') = split_list (map (fn (params, sets, prems, (p, ts)) =>
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   253
      let
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   254
        val params' = params @ [("y", fsT)];
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   255
        val prem = Logic.list_implies
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   256
          (map mk_fresh sets @
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   257
           map (fn prem =>
30087
a780642a9c9c nominal_inductive and equivariance now work on local_theory.
berghofe
parents: 29585
diff changeset
   258
             if null (preds_of ps prem) then prem
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   259
             else lift_prem prem) prems,
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   260
           HOLogic.mk_Trueprop (lift_pred p ts));
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   261
      in abs_params params' prem end) prems);
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   262
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   263
    val ind_vars =
33968
f94fb13ecbb3 modernized structures and tuned headers of datatype package modules; joined former datatype.ML and datatype_rep_proofs.ML
haftmann
parents: 33772
diff changeset
   264
      (Datatype_Prop.indexify_names (replicate (length atomTs) "pi") ~~
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   265
       map NominalAtoms.mk_permT atomTs) @ [("z", fsT)];
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   266
    val ind_Ts = rev (map snd ind_vars);
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   267
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   268
    val concl = HOLogic.mk_Trueprop (foldr1 HOLogic.mk_conj
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   269
      (map (fn (prem, (p, ts)) => HOLogic.mk_imp (prem,
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   270
        HOLogic.list_all (ind_vars, lift_pred p
31938
f193d95b4632 nominal.ML is nominal_datatype.ML
haftmann
parents: 31723
diff changeset
   271
          (map (fold_rev (NominalDatatype.mk_perm ind_Ts)
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   272
            (map Bound (length atomTs downto 1))) ts)))) concls));
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   273
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   274
    val concl' = HOLogic.mk_Trueprop (foldr1 HOLogic.mk_conj
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   275
      (map (fn (prem, (p, ts)) => HOLogic.mk_imp (prem,
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   276
        lift_pred' (Free (fs_ctxt_name, fsT)) p ts)) concls));
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   277
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   278
    val (vc_compat, vc_compat') = map (fn (params, sets, prems, (p, ts)) =>
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   279
      map (fn q => abs_params params (incr_boundvars ~1 (Logic.list_implies
32952
aeb1e44fbc19 replaced String.concat by implode;
wenzelm
parents: 32304
diff changeset
   280
          (map_filter (fn prem =>
30087
a780642a9c9c nominal_inductive and equivariance now work on local_theory.
berghofe
parents: 29585
diff changeset
   281
             if null (preds_of ps prem) then SOME prem
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   282
             else map_term (split_conj (K o I) names) prem prem) prems, q))))
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   283
        (maps (fn (t, T) => map (fn (u, U) => HOLogic.mk_Trueprop
31938
f193d95b4632 nominal.ML is nominal_datatype.ML
haftmann
parents: 31723
diff changeset
   284
           (NominalDatatype.fresh_star_const U T $ u $ t)) sets)
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   285
             (ts ~~ binder_types (fastype_of p)) @
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   286
         map (fn (u, U) => HOLogic.mk_Trueprop (Const (@{const_name finite},
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   287
           HOLogic.mk_setT U --> HOLogic.boolT) $ u)) sets) |>
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   288
      split_list) prems |> split_list;
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   289
39557
fe5722fce758 renamed structure PureThy to Pure_Thy and moved most content to Global_Theory, to emphasize that this is global-only;
wenzelm
parents: 39159
diff changeset
   290
    val perm_pi_simp = Global_Theory.get_thms thy "perm_pi_simp";
fe5722fce758 renamed structure PureThy to Pure_Thy and moved most content to Global_Theory, to emphasize that this is global-only;
wenzelm
parents: 39159
diff changeset
   291
    val pt2_atoms = map (fn a => Global_Theory.get_thm thy
30364
577edc39b501 moved basic algebra of long names from structure NameSpace to Long_Name;
wenzelm
parents: 30307
diff changeset
   292
      ("pt_" ^ Long_Name.base_name a ^ "2")) atoms;
54895
515630483010 clarified simplifier context;
wenzelm
parents: 51717
diff changeset
   293
    val eqvt_ss = simpset_of (put_simpset HOL_basic_ss (Proof_Context.init_global thy)
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   294
      addsimps (eqvt_thms @ perm_pi_simp @ pt2_atoms)
56253
83b3c110f22d more antiquotations;
wenzelm
parents: 54983
diff changeset
   295
      addsimprocs [mk_perm_bool_simproc [@{const_name Fun.id}],
51717
9e7d1c139569 simplifier uses proper Proof.context instead of historic type simpset;
wenzelm
parents: 50771
diff changeset
   296
        NominalPermeq.perm_simproc_app, NominalPermeq.perm_simproc_fun]);
39557
fe5722fce758 renamed structure PureThy to Pure_Thy and moved most content to Global_Theory, to emphasize that this is global-only;
wenzelm
parents: 39159
diff changeset
   297
    val fresh_star_bij = Global_Theory.get_thms thy "fresh_star_bij";
28730
71c946ce7eb9 Streamlined functions for accessing information about atoms.
berghofe
parents: 28653
diff changeset
   298
    val pt_insts = map (NominalAtoms.pt_inst_of thy) atoms;
71c946ce7eb9 Streamlined functions for accessing information about atoms.
berghofe
parents: 28653
diff changeset
   299
    val at_insts = map (NominalAtoms.at_inst_of thy) atoms;
71c946ce7eb9 Streamlined functions for accessing information about atoms.
berghofe
parents: 28653
diff changeset
   300
    val dj_thms = maps (fn a =>
33040
cffdb7b28498 removed old-style \ and \\ infixes
haftmann
parents: 33038
diff changeset
   301
      map (NominalAtoms.dj_thm_of thy a) (remove (op =) a atoms)) atoms;
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   302
    val finite_ineq = map2 (fn th => fn th' => th' RS (th RS
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   303
      @{thm pt_set_finite_ineq})) pt_insts at_insts;
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   304
    val perm_set_forget =
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   305
      map (fn th => th RS @{thm dj_perm_set_forget}) dj_thms;
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   306
    val perm_freshs_freshs = atomTs ~~ map2 (fn th => fn th' => th' RS (th RS
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   307
      @{thm pt_freshs_freshs})) pt_insts at_insts;
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   308
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   309
    fun obtain_fresh_name ts sets (T, fin) (freshs, ths1, ths2, ths3, ctxt) =
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   310
      let
42361
23f352990944 modernized structure Proof_Context;
wenzelm
parents: 41228
diff changeset
   311
        val thy = Proof_Context.theory_of ctxt;
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   312
        (** protect terms to avoid that fresh_star_prod_set interferes with  **)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   313
        (** pairs used in introduction rules of inductive predicate          **)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   314
        fun protect t =
56253
83b3c110f22d more antiquotations;
wenzelm
parents: 54983
diff changeset
   315
          let val T = fastype_of t in Const (@{const_name Fun.id}, T --> T) $ t end;
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   316
        val p = foldr1 HOLogic.mk_prod (map protect ts);
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   317
        val atom = fst (dest_Type T);
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   318
        val {at_inst, ...} = NominalAtoms.the_atom_info thy atom;
39557
fe5722fce758 renamed structure PureThy to Pure_Thy and moved most content to Global_Theory, to emphasize that this is global-only;
wenzelm
parents: 39159
diff changeset
   319
        val fs_atom = Global_Theory.get_thm thy
30364
577edc39b501 moved basic algebra of long names from structure NameSpace to Long_Name;
wenzelm
parents: 30307
diff changeset
   320
          ("fs_" ^ Long_Name.base_name atom ^ "1");
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   321
        val avoid_th = Drule.instantiate'
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   322
          [SOME (ctyp_of thy (fastype_of p))] [SOME (cterm_of thy p)]
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   323
          ([at_inst, fin, fs_atom] MRS @{thm at_set_avoiding});
32202
443d5cfaba1b SUBPROOF/Obtain.result: named params;
wenzelm
parents: 32172
diff changeset
   324
        val (([(_, cx)], th1 :: th2 :: ths), ctxt') = Obtain.result
51717
9e7d1c139569 simplifier uses proper Proof.context instead of historic type simpset;
wenzelm
parents: 50771
diff changeset
   325
          (fn ctxt' => EVERY
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   326
            [rtac avoid_th 1,
51717
9e7d1c139569 simplifier uses proper Proof.context instead of historic type simpset;
wenzelm
parents: 50771
diff changeset
   327
             full_simp_tac (put_simpset HOL_ss ctxt' addsimps [@{thm fresh_star_prod_set}]) 1,
9e7d1c139569 simplifier uses proper Proof.context instead of historic type simpset;
wenzelm
parents: 50771
diff changeset
   328
             full_simp_tac (put_simpset HOL_basic_ss ctxt' addsimps [@{thm id_apply}]) 1,
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   329
             rotate_tac 1 1,
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   330
             REPEAT (etac conjE 1)])
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   331
          [] ctxt;
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   332
        val (Ts1, _ :: Ts2) = take_prefix (not o equal T) (map snd sets);
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   333
        val pTs = map NominalAtoms.mk_permT (Ts1 @ Ts2);
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   334
        val (pis1, pis2) = chop (length Ts1)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   335
          (map Bound (length pTs - 1 downto 0));
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   336
        val _ $ (f $ (_ $ pi $ l) $ r) = prop_of th2
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   337
        val th2' =
54983
2c57fc1f7a8c more accurate context;
wenzelm
parents: 54895
diff changeset
   338
          Goal.prove ctxt' [] []
46218
ecf6375e2abb renamed Term.list_all to Logic.list_all, in accordance to HOLogic.list_all;
wenzelm
parents: 44929
diff changeset
   339
            (Logic.list_all (map (pair "pi") pTs, HOLogic.mk_Trueprop
31938
f193d95b4632 nominal.ML is nominal_datatype.ML
haftmann
parents: 31723
diff changeset
   340
               (f $ fold_rev (NominalDatatype.mk_perm (rev pTs))
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   341
                  (pis1 @ pi :: pis2) l $ r)))
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   342
            (fn _ => cut_facts_tac [th2] 1 THEN
54983
2c57fc1f7a8c more accurate context;
wenzelm
parents: 54895
diff changeset
   343
               full_simp_tac (put_simpset HOL_basic_ss ctxt' addsimps perm_set_forget) 1) |>
2c57fc1f7a8c more accurate context;
wenzelm
parents: 54895
diff changeset
   344
          Simplifier.simplify (put_simpset eqvt_ss ctxt')
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   345
      in
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   346
        (freshs @ [term_of cx],
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   347
         ths1 @ ths, ths2 @ [th1], ths3 @ [th2'], ctxt')
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   348
      end;
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   349
30087
a780642a9c9c nominal_inductive and equivariance now work on local_theory.
berghofe
parents: 29585
diff changeset
   350
    fun mk_ind_proof ctxt' thss =
a780642a9c9c nominal_inductive and equivariance now work on local_theory.
berghofe
parents: 29585
diff changeset
   351
      Goal.prove ctxt' [] prems' concl' (fn {prems = ihyps, context = ctxt} =>
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   352
        let val th = Goal.prove ctxt [] [] concl (fn {context, ...} =>
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   353
          rtac raw_induct 1 THEN
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   354
          EVERY (maps (fn (((((_, sets, oprems, _),
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   355
              vc_compat_ths), vc_compat_vs), ihyp), vs_ihypt) =>
51717
9e7d1c139569 simplifier uses proper Proof.context instead of historic type simpset;
wenzelm
parents: 50771
diff changeset
   356
            [REPEAT (rtac allI 1), simp_tac (put_simpset eqvt_ss context) 1,
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   357
             SUBPROOF (fn {prems = gprems, params, concl, context = ctxt', ...} =>
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   358
               let
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   359
                 val (cparams', (pis, z)) =
32202
443d5cfaba1b SUBPROOF/Obtain.result: named params;
wenzelm
parents: 32172
diff changeset
   360
                   chop (length params - length atomTs - 1) (map #2 params) ||>
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   361
                   (map term_of #> split_last);
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   362
                 val params' = map term_of cparams'
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   363
                 val sets' = map (apfst (curry subst_bounds (rev params'))) sets;
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   364
                 val pi_sets = map (fn (t, _) =>
31938
f193d95b4632 nominal.ML is nominal_datatype.ML
haftmann
parents: 31723
diff changeset
   365
                   fold_rev (NominalDatatype.mk_perm []) pis t) sets';
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   366
                 val (P, ts) = strip_comb (HOLogic.dest_Trueprop (term_of concl));
32952
aeb1e44fbc19 replaced String.concat by implode;
wenzelm
parents: 32304
diff changeset
   367
                 val gprems1 = map_filter (fn (th, t) =>
30087
a780642a9c9c nominal_inductive and equivariance now work on local_theory.
berghofe
parents: 29585
diff changeset
   368
                   if null (preds_of ps t) then SOME th
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   369
                   else
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   370
                     map_thm ctxt' (split_conj (K o I) names)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   371
                       (etac conjunct1 1) monos NONE th)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   372
                   (gprems ~~ oprems);
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   373
                 val vc_compat_ths' = map2 (fn th => fn p =>
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   374
                   let
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   375
                     val th' = gprems1 MRS inst_params thy p th cparams';
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   376
                     val (h, ts) =
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   377
                       strip_comb (HOLogic.dest_Trueprop (concl_of th'))
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   378
                   in
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   379
                     Goal.prove ctxt' [] []
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   380
                       (HOLogic.mk_Trueprop (list_comb (h,
31938
f193d95b4632 nominal.ML is nominal_datatype.ML
haftmann
parents: 31723
diff changeset
   381
                          map (fold_rev (NominalDatatype.mk_perm []) pis) ts)))
51717
9e7d1c139569 simplifier uses proper Proof.context instead of historic type simpset;
wenzelm
parents: 50771
diff changeset
   382
                       (fn _ => simp_tac (put_simpset HOL_basic_ss ctxt' addsimps
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   383
                          (fresh_star_bij @ finite_ineq)) 1 THEN rtac th' 1)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   384
                   end) vc_compat_ths vc_compat_vs;
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   385
                 val (vc_compat_ths1, vc_compat_ths2) =
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   386
                   chop (length vc_compat_ths - length sets) vc_compat_ths';
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   387
                 val vc_compat_ths1' = map
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   388
                   (Conv.fconv_rule (Conv.arg_conv (Conv.arg_conv
51717
9e7d1c139569 simplifier uses proper Proof.context instead of historic type simpset;
wenzelm
parents: 50771
diff changeset
   389
                      (Simplifier.rewrite (put_simpset eqvt_ss ctxt'))))) vc_compat_ths1;
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   390
                 val (pis', fresh_ths1, fresh_ths2, fresh_ths3, ctxt'') = fold
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   391
                   (obtain_fresh_name ts sets)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   392
                   (map snd sets' ~~ vc_compat_ths2) ([], [], [], [], ctxt');
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   393
                 fun concat_perm pi1 pi2 =
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   394
                   let val T = fastype_of pi1
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   395
                   in if T = fastype_of pi2 then
56253
83b3c110f22d more antiquotations;
wenzelm
parents: 54983
diff changeset
   396
                       Const (@{const_name append}, T --> T --> T) $ pi1 $ pi2
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   397
                     else pi2
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   398
                   end;
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   399
                 val pis'' = fold_rev (concat_perm #> map) pis' pis;
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   400
                 val ihyp' = inst_params thy vs_ihypt ihyp
31938
f193d95b4632 nominal.ML is nominal_datatype.ML
haftmann
parents: 31723
diff changeset
   401
                   (map (fold_rev (NominalDatatype.mk_perm [])
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   402
                      (pis' @ pis) #> cterm_of thy) params' @ [cterm_of thy z]);
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   403
                 fun mk_pi th =
54983
2c57fc1f7a8c more accurate context;
wenzelm
parents: 54895
diff changeset
   404
                   Simplifier.simplify (put_simpset HOL_basic_ss ctxt' addsimps [@{thm id_apply}]
31938
f193d95b4632 nominal.ML is nominal_datatype.ML
haftmann
parents: 31723
diff changeset
   405
                       addsimprocs [NominalDatatype.perm_simproc])
54983
2c57fc1f7a8c more accurate context;
wenzelm
parents: 54895
diff changeset
   406
                     (Simplifier.simplify (put_simpset eqvt_ss ctxt')
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   407
                       (fold_rev (mk_perm_bool o cterm_of thy)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   408
                         (pis' @ pis) th));
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   409
                 val gprems2 = map (fn (th, t) =>
30087
a780642a9c9c nominal_inductive and equivariance now work on local_theory.
berghofe
parents: 29585
diff changeset
   410
                   if null (preds_of ps t) then mk_pi th
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   411
                   else
54983
2c57fc1f7a8c more accurate context;
wenzelm
parents: 54895
diff changeset
   412
                     mk_pi (the (map_thm ctxt' (inst_conj_all names ps (rev pis''))
2c57fc1f7a8c more accurate context;
wenzelm
parents: 54895
diff changeset
   413
                       (inst_conj_all_tac ctxt' (length pis'')) monos (SOME t) th)))
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   414
                   (gprems ~~ oprems);
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   415
                 val perm_freshs_freshs' = map (fn (th, (_, T)) =>
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   416
                   th RS the (AList.lookup op = perm_freshs_freshs T))
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   417
                     (fresh_ths2 ~~ sets);
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   418
                 val th = Goal.prove ctxt'' [] []
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   419
                   (HOLogic.mk_Trueprop (list_comb (P $ hd ts,
31938
f193d95b4632 nominal.ML is nominal_datatype.ML
haftmann
parents: 31723
diff changeset
   420
                     map (fold_rev (NominalDatatype.mk_perm []) pis') (tl ts))))
51717
9e7d1c139569 simplifier uses proper Proof.context instead of historic type simpset;
wenzelm
parents: 50771
diff changeset
   421
                   (fn _ => EVERY ([simp_tac (put_simpset eqvt_ss ctxt'') 1, rtac ihyp' 1] @
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   422
                     map (fn th => rtac th 1) fresh_ths3 @
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   423
                     [REPEAT_DETERM_N (length gprems)
51717
9e7d1c139569 simplifier uses proper Proof.context instead of historic type simpset;
wenzelm
parents: 50771
diff changeset
   424
                       (simp_tac (put_simpset HOL_basic_ss ctxt''
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   425
                          addsimps [inductive_forall_def']
31938
f193d95b4632 nominal.ML is nominal_datatype.ML
haftmann
parents: 31723
diff changeset
   426
                          addsimprocs [NominalDatatype.perm_simproc]) 1 THEN
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   427
                        resolve_tac gprems2 1)]));
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   428
                 val final = Goal.prove ctxt'' [] [] (term_of concl)
51717
9e7d1c139569 simplifier uses proper Proof.context instead of historic type simpset;
wenzelm
parents: 50771
diff changeset
   429
                   (fn _ => cut_facts_tac [th] 1 THEN full_simp_tac (put_simpset HOL_ss ctxt''
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   430
                     addsimps vc_compat_ths1' @ fresh_ths1 @
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   431
                       perm_freshs_freshs') 1);
42361
23f352990944 modernized structure Proof_Context;
wenzelm
parents: 41228
diff changeset
   432
                 val final' = Proof_Context.export ctxt'' ctxt' [final];
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   433
               in resolve_tac final' 1 end) context 1])
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   434
                 (prems ~~ thss ~~ vc_compat' ~~ ihyps ~~ prems'')))
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   435
        in
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   436
          cut_facts_tac [th] 1 THEN REPEAT (etac conjE 1) THEN
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   437
          REPEAT (REPEAT (resolve_tac [conjI, impI] 1) THEN
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   438
            etac impE 1 THEN atac 1 THEN REPEAT (etac @{thm allE_Nil} 1) THEN
51717
9e7d1c139569 simplifier uses proper Proof.context instead of historic type simpset;
wenzelm
parents: 50771
diff changeset
   439
            asm_full_simp_tac ctxt 1)
30108
bd78f08b0ba1 Added postprocessing rules for fresh_star.
berghofe
parents: 30087
diff changeset
   440
        end) |>
51717
9e7d1c139569 simplifier uses proper Proof.context instead of historic type simpset;
wenzelm
parents: 50771
diff changeset
   441
        fresh_postprocess ctxt' |>
42361
23f352990944 modernized structure Proof_Context;
wenzelm
parents: 41228
diff changeset
   442
        singleton (Proof_Context.export ctxt' ctxt);
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   443
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   444
  in
30087
a780642a9c9c nominal_inductive and equivariance now work on local_theory.
berghofe
parents: 29585
diff changeset
   445
    ctxt'' |>
50771
2852f997bfb5 prefer negative "consumes", relative to the total number of prems, which is stable under more morphisms, notably those from nested context with assumes (cf. existing treatment of 'obtains');
wenzelm
parents: 46961
diff changeset
   446
    Proof.theorem NONE (fn thss => fn ctxt =>  (* FIXME ctxt/ctxt' should be called lthy/lthy' *)
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   447
      let
30364
577edc39b501 moved basic algebra of long names from structure NameSpace to Long_Name;
wenzelm
parents: 30307
diff changeset
   448
        val rec_name = space_implode "_" (map Long_Name.base_name names);
30223
24d975352879 renamed Binding.name_pos to Binding.make, renamed Binding.base_name to Binding.name_of, renamed Binding.map_base to Binding.map_name, added mandatory flag to Binding.qualify;
wenzelm
parents: 30108
diff changeset
   449
        val rec_qualified = Binding.qualify false rec_name;
33368
b1cf34f1855c modernized structure Rule_Cases;
wenzelm
parents: 33049
diff changeset
   450
        val ind_case_names = Rule_Cases.case_names induct_cases;
31723
f5cafe803b55 discontinued ancient tradition to suffix certain ML module names with "_package"
haftmann
parents: 31177
diff changeset
   451
        val induct_cases' = Inductive.partition_rules' raw_induct
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   452
          (intrs ~~ induct_cases); 
51717
9e7d1c139569 simplifier uses proper Proof.context instead of historic type simpset;
wenzelm
parents: 50771
diff changeset
   453
        val thss' = map (map (atomize_intr ctxt)) thss;
31723
f5cafe803b55 discontinued ancient tradition to suffix certain ML module names with "_package"
haftmann
parents: 31177
diff changeset
   454
        val thsss = Inductive.partition_rules' raw_induct (intrs ~~ thss');
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   455
        val strong_raw_induct =
51717
9e7d1c139569 simplifier uses proper Proof.context instead of historic type simpset;
wenzelm
parents: 50771
diff changeset
   456
          mk_ind_proof ctxt thss' |> Inductive.rulify ctxt;
50771
2852f997bfb5 prefer negative "consumes", relative to the total number of prems, which is stable under more morphisms, notably those from nested context with assumes (cf. existing treatment of 'obtains');
wenzelm
parents: 46961
diff changeset
   457
        val strong_induct_atts =
2852f997bfb5 prefer negative "consumes", relative to the total number of prems, which is stable under more morphisms, notably those from nested context with assumes (cf. existing treatment of 'obtains');
wenzelm
parents: 46961
diff changeset
   458
          map (Attrib.internal o K)
2852f997bfb5 prefer negative "consumes", relative to the total number of prems, which is stable under more morphisms, notably those from nested context with assumes (cf. existing treatment of 'obtains');
wenzelm
parents: 46961
diff changeset
   459
            [ind_case_names, Rule_Cases.consumes (~ (Thm.nprems_of strong_raw_induct))];
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   460
        val strong_induct =
50771
2852f997bfb5 prefer negative "consumes", relative to the total number of prems, which is stable under more morphisms, notably those from nested context with assumes (cf. existing treatment of 'obtains');
wenzelm
parents: 46961
diff changeset
   461
          if length names > 1 then strong_raw_induct
2852f997bfb5 prefer negative "consumes", relative to the total number of prems, which is stable under more morphisms, notably those from nested context with assumes (cf. existing treatment of 'obtains');
wenzelm
parents: 46961
diff changeset
   462
          else strong_raw_induct RSN (2, rev_mp);
32304
berghofe
parents: 32303
diff changeset
   463
        val (induct_name, inducts_name) =
berghofe
parents: 32303
diff changeset
   464
          case alt_name of
32303
ba59e95a5d2b the derived induction principles can be given an explicit name
Christian Urban <urbanc@in.tum.de>
parents: 32202
diff changeset
   465
            NONE => (rec_qualified (Binding.name "strong_induct"),
ba59e95a5d2b the derived induction principles can be given an explicit name
Christian Urban <urbanc@in.tum.de>
parents: 32202
diff changeset
   466
                     rec_qualified (Binding.name "strong_inducts"))
32304
berghofe
parents: 32303
diff changeset
   467
          | SOME s => (Binding.name s, Binding.name (s ^ "s"));
33671
4b0f2599ed48 modernized structure Local_Theory;
wenzelm
parents: 33670
diff changeset
   468
        val ((_, [strong_induct']), ctxt') = ctxt |> Local_Theory.note
50771
2852f997bfb5 prefer negative "consumes", relative to the total number of prems, which is stable under more morphisms, notably those from nested context with assumes (cf. existing treatment of 'obtains');
wenzelm
parents: 46961
diff changeset
   469
          ((induct_name, strong_induct_atts), [strong_induct]);
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   470
        val strong_inducts =
32172
c4e55f30d527 renamed functor ProjectRuleFun to Project_Rule;
wenzelm
parents: 32149
diff changeset
   471
          Project_Rule.projects ctxt' (1 upto length names) strong_induct'
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   472
      in
30087
a780642a9c9c nominal_inductive and equivariance now work on local_theory.
berghofe
parents: 29585
diff changeset
   473
        ctxt' |>
50771
2852f997bfb5 prefer negative "consumes", relative to the total number of prems, which is stable under more morphisms, notably those from nested context with assumes (cf. existing treatment of 'obtains');
wenzelm
parents: 46961
diff changeset
   474
        Local_Theory.notes [((inducts_name, []),
2852f997bfb5 prefer negative "consumes", relative to the total number of prems, which is stable under more morphisms, notably those from nested context with assumes (cf. existing treatment of 'obtains');
wenzelm
parents: 46961
diff changeset
   475
          strong_inducts |> map (fn th => ([th],
30087
a780642a9c9c nominal_inductive and equivariance now work on local_theory.
berghofe
parents: 29585
diff changeset
   476
            [Attrib.internal (K ind_case_names),
50771
2852f997bfb5 prefer negative "consumes", relative to the total number of prems, which is stable under more morphisms, notably those from nested context with assumes (cf. existing treatment of 'obtains');
wenzelm
parents: 46961
diff changeset
   477
             Attrib.internal (K (Rule_Cases.consumes (1 - Thm.nprems_of th)))])))] |> snd
30087
a780642a9c9c nominal_inductive and equivariance now work on local_theory.
berghofe
parents: 29585
diff changeset
   478
      end)
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   479
      (map (map (rulify_term thy #> rpair [])) vc_compat)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   480
  end;
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   481
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   482
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   483
(* outer syntax *)
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   484
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   485
val _ =
46961
5c6955f487e5 outer syntax command definitions based on formal command_spec derived from theory header declarations;
wenzelm
parents: 46949
diff changeset
   486
  Outer_Syntax.local_theory_to_proof @{command_spec "nominal_inductive2"}
36960
01594f816e3a prefer structure Keyword, Parse, Parse_Spec, Outer_Syntax;
wenzelm
parents: 36692
diff changeset
   487
    "prove strong induction theorem for inductive predicate involving nominal datatypes"
01594f816e3a prefer structure Keyword, Parse, Parse_Spec, Outer_Syntax;
wenzelm
parents: 36692
diff changeset
   488
    (Parse.xname -- 
46949
94aa7b81bcf6 prefer formally checked @{keyword} parser;
wenzelm
parents: 46218
diff changeset
   489
     Scan.option (@{keyword "("} |-- Parse.!!! (Parse.name --| @{keyword ")"})) --
94aa7b81bcf6 prefer formally checked @{keyword} parser;
wenzelm
parents: 46218
diff changeset
   490
     (Scan.optional (@{keyword "avoids"} |-- Parse.enum1 "|" (Parse.name --
94aa7b81bcf6 prefer formally checked @{keyword} parser;
wenzelm
parents: 46218
diff changeset
   491
      (@{keyword ":"} |-- Parse.and_list1 Parse.term))) []) >> (fn ((name, rule_name), avoids) =>
32303
ba59e95a5d2b the derived induction principles can be given an explicit name
Christian Urban <urbanc@in.tum.de>
parents: 32202
diff changeset
   492
        prove_strong_ind name rule_name avoids));
28653
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   493
4593c70e228e More general, still experimental version of nominal_inductive for
berghofe
parents:
diff changeset
   494
end