src/HOL/Nominal/nominal_permeq.ML
author urbanc
Thu Sep 13 23:58:38 2007 +0200 (2007-09-13)
changeset 24571 a6d0428dea8e
parent 24519 5c435b2ea137
child 25997 0c0f5d990d7d
permissions -rw-r--r--
some cleaning up to do with contexts
berghofe@19494
     1
(*  Title:      HOL/Nominal/nominal_permeq.ML
berghofe@19494
     2
    ID:         $Id$
urbanc@22418
     3
    Authors:    Christian Urban, Julien Narboux, TU Muenchen
berghofe@17870
     4
berghofe@19494
     5
Methods for simplifying permutations and
berghofe@19494
     6
for analysing equations involving permutations.
berghofe@19494
     7
*)
berghofe@17870
     8
urbanc@20431
     9
(*
urbanc@20431
    10
FIXMES:
urbanc@20431
    11
urbanc@20431
    12
 - allow the user to give an explicit set S in the
urbanc@20431
    13
   fresh_guess tactic which is then verified
urbanc@20431
    14
urbanc@20431
    15
 - the perm_compose tactic does not do an "outermost
urbanc@20431
    16
   rewriting" and can therefore not deal with goals
urbanc@20431
    17
   like
urbanc@20431
    18
urbanc@20431
    19
      [(a,b)] o pi1 o pi2 = ....
urbanc@20431
    20
urbanc@20431
    21
   rather it tries to permute pi1 over pi2, which 
urbanc@20431
    22
   results in a failure when used with the 
urbanc@20431
    23
   perm_(full)_simp tactics
urbanc@20431
    24
urbanc@20431
    25
*)
urbanc@20431
    26
urbanc@20431
    27
berghofe@19987
    28
signature NOMINAL_PERMEQ =
berghofe@19987
    29
sig
berghofe@19987
    30
  val perm_simp_tac : simpset -> int -> tactic
berghofe@19987
    31
  val perm_full_simp_tac : simpset -> int -> tactic
berghofe@19987
    32
  val supports_tac : simpset -> int -> tactic
berghofe@19987
    33
  val finite_guess_tac : simpset -> int -> tactic
berghofe@19987
    34
  val fresh_guess_tac : simpset -> int -> tactic
berghofe@17870
    35
urbanc@22418
    36
  val perm_simp_meth : Method.src -> Proof.context -> Proof.method
urbanc@22418
    37
  val perm_simp_meth_debug : Method.src -> Proof.context -> Proof.method
urbanc@22418
    38
  val perm_full_simp_meth : Method.src -> Proof.context -> Proof.method
urbanc@22418
    39
  val perm_full_simp_meth_debug : Method.src -> Proof.context -> Proof.method
wenzelm@20289
    40
  val supports_meth : Method.src -> Proof.context -> Proof.method
wenzelm@20289
    41
  val supports_meth_debug : Method.src -> Proof.context -> Proof.method
urbanc@22418
    42
  val finite_guess_meth : Method.src -> Proof.context -> Proof.method
urbanc@22418
    43
  val finite_guess_meth_debug : Method.src -> Proof.context -> Proof.method
urbanc@22418
    44
  val fresh_guess_meth : Method.src -> Proof.context -> Proof.method
urbanc@22418
    45
  val fresh_guess_meth_debug : Method.src -> Proof.context -> Proof.method
berghofe@19987
    46
end
berghofe@19987
    47
berghofe@19987
    48
structure NominalPermeq : NOMINAL_PERMEQ =
berghofe@19987
    49
struct
berghofe@19987
    50
urbanc@22418
    51
(* some lemmas needed below *)
urbanc@24519
    52
val finite_emptyI = @{thm "finite.emptyI"};
urbanc@24519
    53
val finite_Un     = @{thm "finite_Un"};
urbanc@24519
    54
val conj_absorb   = @{thm "conj_absorb"};
urbanc@24519
    55
val not_false     = @{thm "not_False_eq_True"}
urbanc@24519
    56
val perm_fun_def  = @{thm "Nominal.perm_fun_def"};
urbanc@24519
    57
val perm_eq_app   = @{thm "Nominal.pt_fun_app_eq"};
urbanc@24519
    58
val supports_def  = @{thm "Nominal.supports_def"};
urbanc@24519
    59
val fresh_def     = @{thm "Nominal.fresh_def"};
urbanc@24519
    60
val fresh_prod    = @{thm "Nominal.fresh_prod"};
urbanc@24519
    61
val fresh_unit    = @{thm "Nominal.fresh_unit"};
urbanc@24519
    62
val supports_rule = @{thm "supports_finite"};
urbanc@24519
    63
val supp_prod     = @{thm "supp_prod"};
urbanc@24519
    64
val supp_unit     = @{thm "supp_unit"};
urbanc@24519
    65
val pt_perm_compose_aux = @{thm "pt_perm_compose_aux"};
urbanc@24519
    66
val cp1_aux             = @{thm "cp1_aux"};
urbanc@24519
    67
val perm_aux_fold       = @{thm "perm_aux_fold"}; 
urbanc@24519
    68
val supports_fresh_rule = @{thm "supports_fresh"};
wenzelm@21669
    69
berghofe@19987
    70
(* pulls out dynamically a thm via the proof state *)
berghofe@19987
    71
fun dynamic_thms st name = PureThy.get_thms (theory_of_thm st) (Name name);
urbanc@22418
    72
fun dynamic_thm  st name = PureThy.get_thm  (theory_of_thm st) (Name name);
urbanc@22418
    73
urbanc@18012
    74
urbanc@22418
    75
(* needed in the process of fully simplifying permutations *)
urbanc@24519
    76
val strong_congs = [@{thm "if_cong"}]
urbanc@22418
    77
(* needed to avoid warnings about overwritten congs *)
urbanc@24519
    78
val weak_congs   = [@{thm "if_weak_cong"}]
urbanc@22418
    79
urbanc@24519
    80
(* FIXME comment *)
narboux@22595
    81
(* a tactical which fails if the tactic taken as an argument generates does not solve the sub goal i *)
narboux@22595
    82
fun SOLVEI t = t THEN_ALL_NEW (fn i => no_tac);
urbanc@22418
    83
urbanc@22418
    84
(* debugging *)
urbanc@22418
    85
fun DEBUG_tac (msg,tac) = 
urbanc@22418
    86
    CHANGED (EVERY [print_tac ("before "^msg), tac, print_tac ("after "^msg)]); 
urbanc@22418
    87
fun NO_DEBUG_tac (_,tac) = CHANGED tac; 
urbanc@22418
    88
urbanc@19477
    89
urbanc@22418
    90
(* simproc that deals with instances of permutations in front *)
urbanc@22418
    91
(* of applications; just adding this rule to the simplifier   *)
urbanc@22418
    92
(* would loop; it also needs careful tuning with the simproc  *)
urbanc@22418
    93
(* for functions to avoid further possibilities for looping   *)
urbanc@22418
    94
fun perm_simproc_app st sg ss redex =
urbanc@22418
    95
  let 
urbanc@22418
    96
    (* the "application" case is only applicable when the head of f is not a *)
urbanc@22418
    97
    (* constant or when (f x) is a permuation with two or more arguments     *)
urbanc@22418
    98
    fun applicable_app t = 
urbanc@22418
    99
          (case (strip_comb t) of
urbanc@22418
   100
	      (Const ("Nominal.perm",_),ts) => (length ts) >= 2
urbanc@22418
   101
            | (Const _,_) => false
urbanc@22418
   102
            | _ => true)
urbanc@22418
   103
  in
urbanc@22418
   104
    case redex of 
urbanc@19169
   105
        (* case pi o (f x) == (pi o f) (pi o x)          *)
berghofe@19494
   106
        (Const("Nominal.perm",
urbanc@19169
   107
          Type("fun",[Type("List.list",[Type("*",[Type(n,_),_])]),_])) $ pi $ (f $ x)) => 
urbanc@22418
   108
            (if (applicable_app f) then
urbanc@22418
   109
              let
urbanc@22418
   110
                val name = Sign.base_name n
urbanc@22418
   111
                val at_inst     = dynamic_thm st ("at_"^name^"_inst")
urbanc@22418
   112
                val pt_inst     = dynamic_thm st ("pt_"^name^"_inst")  
urbanc@22418
   113
              in SOME ((at_inst RS (pt_inst RS perm_eq_app)) RS eq_reflection) end
urbanc@22418
   114
            else NONE)
urbanc@22418
   115
      | _ => NONE
urbanc@22418
   116
  end
urbanc@19139
   117
urbanc@24519
   118
(* a simproc that deals with permutation instances in front of functions  *)
urbanc@22418
   119
fun perm_simproc_fun st sg ss redex = 
urbanc@22418
   120
   let 
urbanc@22418
   121
     fun applicable_fun t =
urbanc@22418
   122
       (case (strip_comb t) of
urbanc@22418
   123
          (Abs _ ,[]) => true
urbanc@22418
   124
	| (Const ("Nominal.perm",_),_) => false
urbanc@22418
   125
        | (Const _, _) => true
urbanc@22418
   126
	| _ => false)
urbanc@22418
   127
   in
urbanc@22418
   128
     case redex of 
urbanc@22418
   129
       (* case pi o f == (%x. pi o (f ((rev pi)o x))) *)     
urbanc@22418
   130
       (Const("Nominal.perm",_) $ pi $ f)  => 
urbanc@22418
   131
          (if (applicable_fun f) then SOME (perm_fun_def) else NONE)
urbanc@22418
   132
      | _ => NONE
urbanc@22418
   133
   end
urbanc@19139
   134
urbanc@22418
   135
(* function for simplyfying permutations *)
urbanc@24571
   136
fun perm_simp_gen dyn_thms eqvt_thms ss i = 
urbanc@22418
   137
    ("general simplification of permutations", fn st =>
urbanc@22418
   138
    let
urbanc@22418
   139
urbanc@22418
   140
       val perm_sp_fun = Simplifier.simproc (theory_of_thm st) "perm_simproc_fun" 
urbanc@22418
   141
	                 ["Nominal.perm pi x"] (perm_simproc_fun st);
urbanc@22418
   142
urbanc@22418
   143
       val perm_sp_app = Simplifier.simproc (theory_of_thm st) "perm_simproc_app" 
urbanc@22418
   144
	                 ["Nominal.perm pi x"] (perm_simproc_app st);
urbanc@22418
   145
urbanc@24571
   146
       val ss' = ss addsimps ((List.concat (map (dynamic_thms st) dyn_thms))@eqvt_thms)
urbanc@22418
   147
                    delcongs weak_congs
urbanc@22418
   148
                    addcongs strong_congs
urbanc@22418
   149
                    addsimprocs [perm_sp_fun, perm_sp_app]
urbanc@19477
   150
    in
urbanc@22418
   151
      asm_full_simp_tac ss' i st
berghofe@19987
   152
    end);
urbanc@19477
   153
urbanc@22418
   154
(* general simplification of permutations and permutation that arose from eqvt-problems *)
urbanc@24571
   155
fun perm_simp ss = 
urbanc@22610
   156
    let val simps = ["perm_swap","perm_fresh_fresh","perm_bij","perm_pi_simp","swap_simps"]
urbanc@22610
   157
    in 
urbanc@24571
   158
	perm_simp_gen simps [] ss
urbanc@22610
   159
    end;
urbanc@22610
   160
urbanc@24571
   161
fun eqvt_simp ss = 
urbanc@22610
   162
    let val simps = ["perm_swap","perm_fresh_fresh","perm_pi_simp"]
urbanc@24571
   163
	val eqvts_thms = NominalThmDecls.get_eqvt_thms (Simplifier.the_context ss);
urbanc@22610
   164
    in 
urbanc@24571
   165
	perm_simp_gen simps eqvts_thms ss
urbanc@22610
   166
    end;
narboux@22562
   167
urbanc@22418
   168
urbanc@22418
   169
(* main simplification tactics for permutations *)
urbanc@22418
   170
fun perm_simp_tac tactical ss i = DETERM (tactical (perm_simp ss i));
urbanc@22418
   171
fun eqvt_simp_tac tactical ss i = DETERM (tactical (eqvt_simp ss i)); 
urbanc@22418
   172
urbanc@22418
   173
urbanc@19477
   174
(* applies the perm_compose rule such that                             *)
urbanc@19477
   175
(*   pi o (pi' o lhs) = rhs                                            *)
urbanc@19477
   176
(* is transformed to                                                   *) 
urbanc@19477
   177
(*  (pi o pi') o (pi' o lhs) = rhs                                     *)
urbanc@19477
   178
(*                                                                     *)
urbanc@19477
   179
(* this rule would loop in the simplifier, so some trick is used with  *)
urbanc@19477
   180
(* generating perm_aux'es for the outermost permutation and then un-   *)
urbanc@19477
   181
(* folding the definition                                              *)
urbanc@19477
   182
fun perm_compose_tac ss i = 
urbanc@19477
   183
    let
urbanc@19477
   184
	fun perm_compose_simproc sg ss redex =
urbanc@19477
   185
	(case redex of
berghofe@19494
   186
           (Const ("Nominal.perm", Type ("fun", [Type ("List.list", 
berghofe@19494
   187
             [Type ("*", [T as Type (tname,_),_])]),_])) $ pi1 $ (Const ("Nominal.perm", 
urbanc@19477
   188
               Type ("fun", [Type ("List.list", [Type ("*", [U as Type (uname,_),_])]),_])) $ 
urbanc@19477
   189
                pi2 $ t)) =>
urbanc@19350
   190
        let
urbanc@19350
   191
	    val tname' = Sign.base_name tname
urbanc@19477
   192
            val uname' = Sign.base_name uname
urbanc@19350
   193
        in
urbanc@19477
   194
            if pi1 <> pi2 then  (* only apply the composition rule in this case *)
urbanc@19477
   195
               if T = U then    
urbanc@19350
   196
                SOME (Drule.instantiate'
urbanc@19350
   197
	              [SOME (ctyp_of sg (fastype_of t))]
urbanc@19350
   198
		      [SOME (cterm_of sg pi1), SOME (cterm_of sg pi2), SOME (cterm_of sg t)]
urbanc@19350
   199
		      (mk_meta_eq ([PureThy.get_thm sg (Name ("pt_"^tname'^"_inst")),
urbanc@19477
   200
	               PureThy.get_thm sg (Name ("at_"^tname'^"_inst"))] MRS pt_perm_compose_aux)))
urbanc@19477
   201
               else
urbanc@19477
   202
                SOME (Drule.instantiate'
urbanc@19477
   203
	              [SOME (ctyp_of sg (fastype_of t))]
urbanc@19477
   204
		      [SOME (cterm_of sg pi1), SOME (cterm_of sg pi2), SOME (cterm_of sg t)]
urbanc@19477
   205
		      (mk_meta_eq (PureThy.get_thm sg (Name ("cp_"^tname'^"_"^uname'^"_inst")) RS 
urbanc@19477
   206
                       cp1_aux)))
urbanc@19350
   207
            else NONE
urbanc@19350
   208
        end
urbanc@19350
   209
       | _ => NONE);
urbanc@19477
   210
	  
urbanc@19477
   211
      val perm_compose  =
urbanc@19350
   212
	Simplifier.simproc (the_context()) "perm_compose" 
berghofe@19494
   213
	["Nominal.perm pi1 (Nominal.perm pi2 t)"] perm_compose_simproc;
urbanc@19477
   214
urbanc@22418
   215
      val ss' = Simplifier.theory_context (the_context ()) empty_ss (* FIXME: get rid of the_context *)	  
urbanc@19477
   216
urbanc@18012
   217
    in
urbanc@19477
   218
	("analysing permutation compositions on the lhs",
urbanc@19477
   219
         EVERY [rtac trans i,
urbanc@19477
   220
                asm_full_simp_tac (ss' addsimprocs [perm_compose]) i,
urbanc@19477
   221
                asm_full_simp_tac (HOL_basic_ss addsimps [perm_aux_fold]) i])
urbanc@18012
   222
    end
urbanc@18012
   223
urbanc@22418
   224
urbanc@18012
   225
(* applying Stefan's smart congruence tac *)
urbanc@18012
   226
fun apply_cong_tac i = 
urbanc@18012
   227
    ("application of congruence",
urbanc@19477
   228
     (fn st => DatatypeAux.cong_tac i st handle Subscript => no_tac st));
berghofe@17870
   229
urbanc@22418
   230
urbanc@19477
   231
(* unfolds the definition of permutations     *)
urbanc@19477
   232
(* applied to functions such that             *)
urbanc@22418
   233
(*     pi o f = rhs                           *)  
urbanc@19477
   234
(* is transformed to                          *)
urbanc@22418
   235
(*     %x. pi o (f ((rev pi) o x)) = rhs      *)
urbanc@24519
   236
fun unfold_perm_fun_def_tac i =
urbanc@24519
   237
    ("unfolding of permutations on functions", 
urbanc@24519
   238
      rtac (perm_fun_def RS meta_eq_to_obj_eq RS trans) i)
berghofe@17870
   239
urbanc@19477
   240
(* applies the ext-rule such that      *)
urbanc@19477
   241
(*                                     *)
urbanc@22418
   242
(*    f = g   goes to  /\x. f x = g x  *)
urbanc@19477
   243
fun ext_fun_tac i = ("extensionality expansion of functions", rtac ext i);
berghofe@17870
   244
berghofe@17870
   245
urbanc@22418
   246
(* perm_full_simp_tac is perm_simp plus additional tactics        *)
urbanc@19477
   247
(* to decide equation that come from support problems             *)
urbanc@19477
   248
(* since it contains looping rules the "recursion" - depth is set *)
urbanc@19477
   249
(* to 10 - this seems to be sufficient in most cases              *)
urbanc@19477
   250
fun perm_full_simp_tac tactical ss =
urbanc@19477
   251
  let fun perm_full_simp_tac_aux tactical ss n = 
urbanc@19477
   252
	  if n=0 then K all_tac
urbanc@19477
   253
	  else DETERM o 
urbanc@19477
   254
	       (FIRST'[fn i => tactical ("splitting conjunctions on the rhs", rtac conjI i),
urbanc@22418
   255
                       fn i => tactical (perm_simp ss i),
urbanc@19477
   256
		       fn i => tactical (perm_compose_tac ss i),
urbanc@19477
   257
		       fn i => tactical (apply_cong_tac i), 
urbanc@19477
   258
                       fn i => tactical (unfold_perm_fun_def_tac i),
urbanc@22418
   259
                       fn i => tactical (ext_fun_tac i)]
urbanc@19477
   260
		      THEN_ALL_NEW (TRY o (perm_full_simp_tac_aux tactical ss (n-1))))
urbanc@19477
   261
  in perm_full_simp_tac_aux tactical ss 10 end;
urbanc@19151
   262
urbanc@22418
   263
urbanc@22418
   264
(* tactic that tries to solve "supports"-goals; first it *)
urbanc@22418
   265
(* unfolds the support definition and strips off the     *)
urbanc@22418
   266
(* intros, then applies eqvt_simp_tac                    *)
urbanc@18012
   267
fun supports_tac tactical ss i =
urbanc@18012
   268
  let 
urbanc@22418
   269
     val simps        = [supports_def,symmetric fresh_def,fresh_prod]
berghofe@17870
   270
  in
urbanc@19477
   271
      EVERY [tactical ("unfolding of supports   ", simp_tac (HOL_basic_ss addsimps simps) i),
urbanc@19477
   272
             tactical ("stripping of foralls    ", REPEAT_DETERM (rtac allI i)),
urbanc@19477
   273
             tactical ("geting rid of the imps  ", rtac impI i),
urbanc@19477
   274
             tactical ("eliminating conjuncts   ", REPEAT_DETERM (etac  conjE i)),
urbanc@22418
   275
             tactical ("applying eqvt_simp      ", eqvt_simp_tac tactical ss i )]
berghofe@17870
   276
  end;
berghofe@17870
   277
urbanc@19151
   278
urbanc@22418
   279
(* tactic that guesses the finite-support of a goal        *)
urbanc@22418
   280
(* it first collects all free variables and tries to show  *)
urbanc@22418
   281
(* that the support of these free variables (op supports)  *)
urbanc@22418
   282
(* the goal                                                *)
haftmann@20854
   283
fun collect_vars i (Bound j) vs = if j < i then vs else insert (op =) (Bound (j - i)) vs
haftmann@20854
   284
  | collect_vars i (v as Free _) vs = insert (op =) v vs
haftmann@20854
   285
  | collect_vars i (v as Var _) vs = insert (op =) v vs
urbanc@19151
   286
  | collect_vars i (Const _) vs = vs
urbanc@19151
   287
  | collect_vars i (Abs (_, _, t)) vs = collect_vars (i+1) t vs
urbanc@19151
   288
  | collect_vars i (t $ u) vs = collect_vars i u (collect_vars i t vs);
urbanc@19151
   289
urbanc@19151
   290
fun finite_guess_tac tactical ss i st =
urbanc@19151
   291
    let val goal = List.nth(cprems_of st, i-1)
urbanc@19151
   292
    in
urbanc@19151
   293
      case Logic.strip_assums_concl (term_of goal) of
berghofe@22274
   294
          _ $ (Const ("Finite_Set.finite", _) $ (Const ("Nominal.supp", T) $ x)) =>
urbanc@19151
   295
          let
wenzelm@22578
   296
            val cert = Thm.cterm_of (Thm.theory_of_thm st);
urbanc@19151
   297
            val ps = Logic.strip_params (term_of goal);
urbanc@19151
   298
            val Ts = rev (map snd ps);
urbanc@19151
   299
            val vs = collect_vars 0 x [];
haftmann@21078
   300
            val s = Library.foldr (fn (v, s) =>
urbanc@19151
   301
                HOLogic.pair_const (fastype_of1 (Ts, v)) (fastype_of1 (Ts, s)) $ v $ s)
haftmann@21078
   302
              (vs, HOLogic.unit);
urbanc@19151
   303
            val s' = list_abs (ps,
berghofe@19494
   304
              Const ("Nominal.supp", fastype_of1 (Ts, s) --> body_type T) $ s);
urbanc@19151
   305
            val supports_rule' = Thm.lift_rule goal supports_rule;
urbanc@19151
   306
            val _ $ (_ $ S $ _) =
urbanc@19151
   307
              Logic.strip_assums_concl (hd (prems_of supports_rule'));
urbanc@19151
   308
            val supports_rule'' = Drule.cterm_instantiate
urbanc@19151
   309
              [(cert (head_of S), cert s')] supports_rule'
urbanc@22418
   310
            val fin_supp = dynamic_thms st ("fin_supp")
urbanc@22418
   311
            val ss' = ss addsimps [supp_prod,supp_unit,finite_Un,finite_emptyI,conj_absorb]@fin_supp
urbanc@19151
   312
          in
urbanc@19151
   313
            (tactical ("guessing of the right supports-set",
urbanc@19151
   314
                      EVERY [compose_tac (false, supports_rule'', 2) i,
berghofe@19987
   315
                             asm_full_simp_tac ss' (i+1),
urbanc@19151
   316
                             supports_tac tactical ss i])) st
urbanc@19151
   317
          end
urbanc@19151
   318
        | _ => Seq.empty
urbanc@19151
   319
    end
urbanc@19151
   320
    handle Subscript => Seq.empty
urbanc@19151
   321
narboux@22595
   322
urbanc@22418
   323
(* tactic that guesses whether an atom is fresh for an expression  *)
urbanc@22418
   324
(* it first collects all free variables and tries to show that the *) 
urbanc@22418
   325
(* support of these free variables (op supports) the goal          *)
berghofe@19857
   326
fun fresh_guess_tac tactical ss i st =
berghofe@19857
   327
    let 
berghofe@19857
   328
	val goal = List.nth(cprems_of st, i-1)
urbanc@22418
   329
        val fin_supp = dynamic_thms st ("fin_supp")
urbanc@22418
   330
        val fresh_atm = dynamic_thms st ("fresh_atm")
urbanc@22418
   331
	val ss1 = ss addsimps [symmetric fresh_def,fresh_prod,fresh_unit,conj_absorb,not_false]@fresh_atm
urbanc@22418
   332
        val ss2 = ss addsimps [supp_prod,supp_unit,finite_Un,finite_emptyI,conj_absorb]@fin_supp
berghofe@19857
   333
    in
berghofe@19857
   334
      case Logic.strip_assums_concl (term_of goal) of
berghofe@19857
   335
          _ $ (Const ("Nominal.fresh", Type ("fun", [T, _])) $ _ $ t) => 
berghofe@19857
   336
          let
wenzelm@22578
   337
            val cert = Thm.cterm_of (Thm.theory_of_thm st);
berghofe@19857
   338
            val ps = Logic.strip_params (term_of goal);
berghofe@19857
   339
            val Ts = rev (map snd ps);
berghofe@19857
   340
            val vs = collect_vars 0 t [];
haftmann@21078
   341
            val s = Library.foldr (fn (v, s) =>
berghofe@19857
   342
                HOLogic.pair_const (fastype_of1 (Ts, v)) (fastype_of1 (Ts, s)) $ v $ s)
haftmann@21078
   343
              (vs, HOLogic.unit);
berghofe@19857
   344
            val s' = list_abs (ps,
berghofe@19857
   345
              Const ("Nominal.supp", fastype_of1 (Ts, s) --> (HOLogic.mk_setT T)) $ s);
berghofe@19857
   346
            val supports_fresh_rule' = Thm.lift_rule goal supports_fresh_rule;
berghofe@19857
   347
            val _ $ (_ $ S $ _) =
berghofe@19857
   348
              Logic.strip_assums_concl (hd (prems_of supports_fresh_rule'));
berghofe@19857
   349
            val supports_fresh_rule'' = Drule.cterm_instantiate
berghofe@19857
   350
              [(cert (head_of S), cert s')] supports_fresh_rule'
berghofe@19857
   351
          in
urbanc@22418
   352
            (tactical ("guessing of the right set that supports the goal", 
urbanc@22418
   353
                      (EVERY [compose_tac (false, supports_fresh_rule'', 3) i,
urbanc@19993
   354
                             asm_full_simp_tac ss1 (i+2),
urbanc@19993
   355
                             asm_full_simp_tac ss2 (i+1), 
urbanc@22418
   356
                             supports_tac tactical ss i]))) st
berghofe@19857
   357
          end
urbanc@22418
   358
          (* when a term-constructor contains more than one binder, it is useful    *) 
urbanc@22418
   359
          (* in nominal_primrecs to try whether the goal can be solved by an hammer *)
urbanc@22418
   360
        | _ => (tactical ("if it is not of the form _\<sharp>_, then try the simplifier",   
urbanc@22418
   361
                          (asm_full_simp_tac (HOL_ss addsimps [fresh_prod]@fresh_atm) i))) st
berghofe@19857
   362
    end
urbanc@22418
   363
    handle Subscript => Seq.empty;
urbanc@22418
   364
urbanc@22418
   365
(* setup so that the simpset is used which is active at the moment when the tactic is called *)
urbanc@22418
   366
fun local_simp_meth_setup tac =
urbanc@18046
   367
  Method.only_sectioned_args (Simplifier.simp_modifiers' @ Splitter.split_modifiers)
urbanc@22418
   368
  (Method.SIMPLE_METHOD' o tac o local_simpset_of) ;
berghofe@17870
   369
narboux@22595
   370
(* uses HOL_basic_ss only and fails if the tactic does not solve the subgoal *)
narboux@22595
   371
narboux@22656
   372
fun basic_simp_meth_setup debug tac =
urbanc@22418
   373
  Method.sectioned_args 
urbanc@22418
   374
   (fn (ctxt,l) => ((),((Simplifier.map_ss (fn _ => HOL_basic_ss) ctxt),l)))
urbanc@22418
   375
   (Simplifier.simp_modifiers' @ Splitter.split_modifiers)
narboux@22656
   376
   (fn _ => Method.SIMPLE_METHOD' o (fn ss => if debug then (tac ss) else SOLVEI (tac ss)) o local_simpset_of);
urbanc@22418
   377
berghofe@17870
   378
urbanc@22418
   379
val perm_simp_meth            = local_simp_meth_setup (perm_simp_tac NO_DEBUG_tac);
urbanc@22418
   380
val perm_simp_meth_debug      = local_simp_meth_setup (perm_simp_tac DEBUG_tac);
urbanc@22418
   381
val perm_full_simp_meth       = local_simp_meth_setup (perm_full_simp_tac NO_DEBUG_tac);
urbanc@22418
   382
val perm_full_simp_meth_debug = local_simp_meth_setup (perm_full_simp_tac DEBUG_tac);
urbanc@22418
   383
val supports_meth             = local_simp_meth_setup (supports_tac NO_DEBUG_tac);
urbanc@22418
   384
val supports_meth_debug       = local_simp_meth_setup (supports_tac DEBUG_tac);
urbanc@24571
   385
narboux@22656
   386
val finite_guess_meth         = basic_simp_meth_setup false (finite_guess_tac NO_DEBUG_tac);
narboux@22656
   387
val finite_guess_meth_debug   = basic_simp_meth_setup true (finite_guess_tac DEBUG_tac);
narboux@22656
   388
val fresh_guess_meth          = basic_simp_meth_setup false (fresh_guess_tac NO_DEBUG_tac);
narboux@22656
   389
val fresh_guess_meth_debug    = basic_simp_meth_setup true (fresh_guess_tac DEBUG_tac);
urbanc@22418
   390
berghofe@19987
   391
val perm_simp_tac = perm_simp_tac NO_DEBUG_tac;
berghofe@19987
   392
val perm_full_simp_tac = perm_full_simp_tac NO_DEBUG_tac;
berghofe@19987
   393
val supports_tac = supports_tac NO_DEBUG_tac;
berghofe@19987
   394
val finite_guess_tac = finite_guess_tac NO_DEBUG_tac;
berghofe@19987
   395
val fresh_guess_tac = fresh_guess_tac NO_DEBUG_tac;
berghofe@17870
   396
wenzelm@20289
   397
end