src/Tools/eqsubst.ML
changeset 49339 d1fcb4de8349
parent 44095 3ea5fae095dc
child 49340 25fc6e0da459
equal deleted inserted replaced
49338:4a922800531d 49339:d1fcb4de8349
    17   type searchinfo =
    17   type searchinfo =
    18        theory
    18        theory
    19        * int (* maxidx *)
    19        * int (* maxidx *)
    20        * Zipper.T (* focusterm to search under *)
    20        * Zipper.T (* focusterm to search under *)
    21 
    21 
    22     exception eqsubst_occL_exp of
    22   datatype 'a skipseq = SkipMore of int | SkipSeq of 'a Seq.seq Seq.seq
    23        string * int list * thm list * int * thm
    23 
    24     
    24   val skip_first_asm_occs_search :
    25     (* low level substitution functions *)
    25      ('a -> 'b -> 'c Seq.seq Seq.seq) ->
    26     val apply_subst_in_asm :
    26      'a -> int -> 'b -> 'c skipseq
    27        int ->
    27   val skip_first_occs_search :
    28        thm ->
    28      int -> ('a -> 'b -> 'c Seq.seq Seq.seq) -> 'a -> 'b -> 'c Seq.seq
    29        thm ->
    29   val skipto_skipseq : int -> 'a Seq.seq Seq.seq -> 'a skipseq
    30        (cterm list * int * 'a * thm) * match -> thm Seq.seq
    30 
    31     val apply_subst_in_concl :
    31   (* tactics *)
    32        int ->
    32   val eqsubst_asm_tac :
    33        thm ->
    33      Proof.context ->
    34        cterm list * thm ->
    34      int list -> thm list -> int -> tactic
    35        thm -> match -> thm Seq.seq
    35   val eqsubst_asm_tac' :
    36 
    36      Proof.context ->
    37     (* matching/unification within zippers *)
    37      (searchinfo -> int -> term -> match skipseq) ->
    38     val clean_match_z :
    38      int -> thm -> int -> tactic
    39        theory -> term -> Zipper.T -> match option
    39   val eqsubst_tac :
    40     val clean_unify_z :
    40      Proof.context ->
    41        theory -> int -> term -> Zipper.T -> match Seq.seq
    41      int list -> (* list of occurences to rewrite, use [0] for any *)
    42 
    42      thm list -> int -> tactic
    43     (* skipping things in seq seq's *)
    43   val eqsubst_tac' :
    44 
    44      Proof.context -> (* proof context *)
    45    (* skipping non-empty sub-sequences but when we reach the end
    45      (searchinfo -> term -> match Seq.seq) (* search function *)
    46       of the seq, remembering how much we have left to skip. *)
    46      -> thm (* equation theorem to rewrite with *)
    47     datatype 'a skipseq = SkipMore of int
    47      -> int (* subgoal number in goal theorem *)
    48       | SkipSeq of 'a Seq.seq Seq.seq;
    48      -> thm (* goal theorem *)
    49 
    49      -> thm Seq.seq (* rewritten goal theorem *)
    50     val skip_first_asm_occs_search :
    50 
    51        ('a -> 'b -> 'c Seq.seq Seq.seq) ->
    51   (* search for substitutions *)
    52        'a -> int -> 'b -> 'c skipseq
    52   val valid_match_start : Zipper.T -> bool
    53     val skip_first_occs_search :
    53   val search_lr_all : Zipper.T -> Zipper.T Seq.seq
    54        int -> ('a -> 'b -> 'c Seq.seq Seq.seq) -> 'a -> 'b -> 'c Seq.seq
    54   val search_lr_valid : (Zipper.T -> bool) -> Zipper.T -> Zipper.T Seq.seq
    55     val skipto_skipseq : int -> 'a Seq.seq Seq.seq -> 'a skipseq
    55   val searchf_lr_unify_all :
    56 
    56      searchinfo -> term -> match Seq.seq Seq.seq
    57     (* tactics *)
    57   val searchf_lr_unify_valid :
    58     val eqsubst_asm_tac :
    58      searchinfo -> term -> match Seq.seq Seq.seq
    59        Proof.context ->
    59   val searchf_bt_unify_valid :
    60        int list -> thm list -> int -> tactic
    60      searchinfo -> term -> match Seq.seq Seq.seq
    61     val eqsubst_asm_tac' :
    61 
    62        Proof.context ->
    62   val setup : theory -> theory
    63        (searchinfo -> int -> term -> match skipseq) ->
       
    64        int -> thm -> int -> tactic
       
    65     val eqsubst_tac :
       
    66        Proof.context ->
       
    67        int list -> (* list of occurences to rewrite, use [0] for any *)
       
    68        thm list -> int -> tactic
       
    69     val eqsubst_tac' :
       
    70        Proof.context -> (* proof context *)
       
    71        (searchinfo -> term -> match Seq.seq) (* search function *)
       
    72        -> thm (* equation theorem to rewrite with *)
       
    73        -> int (* subgoal number in goal theorem *)
       
    74        -> thm (* goal theorem *)
       
    75        -> thm Seq.seq (* rewritten goal theorem *)
       
    76 
       
    77 
       
    78     val fakefree_badbounds :
       
    79        (string * typ) list ->
       
    80        term ->
       
    81        (string * typ) list * (string * typ) list * term
       
    82 
       
    83     val mk_foo_match :
       
    84        (term -> term) ->
       
    85        ('a * typ) list -> term -> term
       
    86 
       
    87     (* preparing substitution *)
       
    88     val prep_meta_eq : Proof.context -> thm -> thm list
       
    89     val prep_concl_subst :
       
    90        int -> thm -> (cterm list * thm) * searchinfo
       
    91     val prep_subst_in_asm :
       
    92        int -> thm -> int ->
       
    93        (cterm list * int * int * thm) * searchinfo
       
    94     val prep_subst_in_asms :
       
    95        int -> thm ->
       
    96        ((cterm list * int * int * thm) * searchinfo) list
       
    97     val prep_zipper_match :
       
    98        Zipper.T -> term * ((string * typ) list * (string * typ) list * term)
       
    99 
       
   100     (* search for substitutions *)
       
   101     val valid_match_start : Zipper.T -> bool
       
   102     val search_lr_all : Zipper.T -> Zipper.T Seq.seq
       
   103     val search_lr_valid : (Zipper.T -> bool) -> Zipper.T -> Zipper.T Seq.seq
       
   104     val searchf_lr_unify_all :
       
   105        searchinfo -> term -> match Seq.seq Seq.seq
       
   106     val searchf_lr_unify_valid :
       
   107        searchinfo -> term -> match Seq.seq Seq.seq
       
   108     val searchf_bt_unify_valid :
       
   109        searchinfo -> term -> match Seq.seq Seq.seq
       
   110 
       
   111     (* Isar level hooks *)
       
   112     val eqsubst_asm_meth : Proof.context -> int list -> thm list -> Proof.method
       
   113     val eqsubst_meth : Proof.context -> int list -> thm list -> Proof.method
       
   114     val setup : theory -> theory
       
   115 
    63 
   116 end;
    64 end;
   117 
    65 
   118 structure EqSubst: EQSUBST =
    66 structure EqSubst: EQSUBST =
   119 struct
    67 struct
   140 (* skipping non-empty sub-sequences but when we reach the end
    88 (* skipping non-empty sub-sequences but when we reach the end
   141    of the seq, remembering how much we have left to skip. *)
    89    of the seq, remembering how much we have left to skip. *)
   142 datatype 'a skipseq = SkipMore of int
    90 datatype 'a skipseq = SkipMore of int
   143   | SkipSeq of 'a Seq.seq Seq.seq;
    91   | SkipSeq of 'a Seq.seq Seq.seq;
   144 (* given a seqseq, skip the first m non-empty seq's, note deficit *)
    92 (* given a seqseq, skip the first m non-empty seq's, note deficit *)
   145 fun skipto_skipseq m s = 
    93 fun skipto_skipseq m s =
   146     let 
    94     let
   147       fun skip_occs n sq = 
    95       fun skip_occs n sq =
   148           case Seq.pull sq of 
    96           case Seq.pull sq of
   149             NONE => SkipMore n
    97             NONE => SkipMore n
   150           | SOME (h,t) => 
    98           | SOME (h,t) =>
   151             (case Seq.pull h of NONE => skip_occs n t
    99             (case Seq.pull h of NONE => skip_occs n t
   152              | SOME _ => if n <= 1 then SkipSeq (Seq.cons h t)
   100              | SOME _ => if n <= 1 then SkipSeq (Seq.cons h t)
   153                          else skip_occs (n - 1) t)
   101                          else skip_occs (n - 1) t)
   154     in (skip_occs m s) end;
   102     in (skip_occs m s) end;
   155 
   103 
   156 (* note: outerterm is the taget with the match replaced by a bound 
   104 (* note: outerterm is the taget with the match replaced by a bound
   157          variable : ie: "P lhs" beocmes "%x. P x" 
   105          variable : ie: "P lhs" beocmes "%x. P x"
   158          insts is the types of instantiations of vars in lhs
   106          insts is the types of instantiations of vars in lhs
   159          and typinsts is the type instantiations of types in the lhs
   107          and typinsts is the type instantiations of types in the lhs
   160          Note: Final rule is the rule lifted into the ontext of the 
   108          Note: Final rule is the rule lifted into the ontext of the
   161          taget thm. *)
   109          taget thm. *)
   162 fun mk_foo_match mkuptermfunc Ts t = 
   110 fun mk_foo_match mkuptermfunc Ts t =
   163     let 
   111     let
   164       val ty = Term.type_of t
   112       val ty = Term.type_of t
   165       val bigtype = (rev (map snd Ts)) ---> ty
   113       val bigtype = (rev (map snd Ts)) ---> ty
   166       fun mk_foo 0 t = t
   114       fun mk_foo 0 t = t
   167         | mk_foo i t = mk_foo (i - 1) (t $ (Bound (i - 1)))
   115         | mk_foo i t = mk_foo (i - 1) (t $ (Bound (i - 1)))
   168       val num_of_bnds = (length Ts)
   116       val num_of_bnds = (length Ts)
   170       val foo_term = mk_foo num_of_bnds (Bound num_of_bnds)
   118       val foo_term = mk_foo num_of_bnds (Bound num_of_bnds)
   171     in Abs("fooabs", bigtype, mkuptermfunc foo_term) end;
   119     in Abs("fooabs", bigtype, mkuptermfunc foo_term) end;
   172 
   120 
   173 (* T is outer bound vars, n is number of locally bound vars *)
   121 (* T is outer bound vars, n is number of locally bound vars *)
   174 (* THINK: is order of Ts correct...? or reversed? *)
   122 (* THINK: is order of Ts correct...? or reversed? *)
   175 fun fakefree_badbounds Ts t = 
   123 fun mk_fake_bound_name n = ":b_" ^ n;
   176     let val (FakeTs,Ts,newnames) = 
   124 fun fakefree_badbounds Ts t =
   177             List.foldr (fn ((n,ty),(FakeTs,Ts,usednames)) => 
   125     let val (FakeTs,Ts,newnames) =
       
   126             List.foldr (fn ((n,ty),(FakeTs,Ts,usednames)) =>
   178                            let val newname = singleton (Name.variant_list usednames) n
   127                            let val newname = singleton (Name.variant_list usednames) n
   179                            in ((RWTools.mk_fake_bound_name newname,ty)::FakeTs,
   128                            in ((mk_fake_bound_name newname,ty)::FakeTs,
   180                                (newname,ty)::Ts, 
   129                                (newname,ty)::Ts,
   181                                newname::usednames) end)
   130                                newname::usednames) end)
   182                        ([],[],[])
   131                        ([],[],[])
   183                        Ts
   132                        Ts
   184     in (FakeTs, Ts, Term.subst_bounds (map Free FakeTs, t)) end;
   133     in (FakeTs, Ts, Term.subst_bounds (map Free FakeTs, t)) end;
   185 
   134 
   186 (* before matching we need to fake the bound vars that are missing an
   135 (* before matching we need to fake the bound vars that are missing an
   187 abstraction. In this function we additionally construct the
   136 abstraction. In this function we additionally construct the
   188 abstraction environment, and an outer context term (with the focus
   137 abstraction environment, and an outer context term (with the focus
   189 abstracted out) for use in rewriting with RWInst.rw *)
   138 abstracted out) for use in rewriting with RWInst.rw *)
   190 fun prep_zipper_match z = 
   139 fun prep_zipper_match z =
   191     let 
   140     let
   192       val t = Zipper.trm z  
   141       val t = Zipper.trm z
   193       val c = Zipper.ctxt z
   142       val c = Zipper.ctxt z
   194       val Ts = Zipper.C.nty_ctxt c
   143       val Ts = Zipper.C.nty_ctxt c
   195       val (FakeTs', Ts', t') = fakefree_badbounds Ts t
   144       val (FakeTs', Ts', t') = fakefree_badbounds Ts t
   196       val absterm = mk_foo_match (Zipper.C.apply c) Ts' t'
   145       val absterm = mk_foo_match (Zipper.C.apply c) Ts' t'
   197     in
   146     in
   198       (t', (FakeTs', Ts', absterm))
   147       (t', (FakeTs', Ts', absterm))
   199     end;
   148     end;
   200 
   149 
   201 (* Matching and Unification with exception handled *)
   150 (* Unification with exception handled *)
   202 fun clean_match thy (a as (pat, t)) =
       
   203   let val (tyenv, tenv) = Pattern.match thy a (Vartab.empty, Vartab.empty)
       
   204   in SOME (Vartab.dest tyenv, Vartab.dest tenv)
       
   205   end handle Pattern.MATCH => NONE;
       
   206 
       
   207 (* given theory, max var index, pat, tgt; returns Seq of instantiations *)
   151 (* given theory, max var index, pat, tgt; returns Seq of instantiations *)
   208 fun clean_unify thry ix (a as (pat, tgt)) =
   152 fun clean_unify thry ix (a as (pat, tgt)) =
   209     let
   153     let
   210       (* type info will be re-derived, maybe this can be cached
   154       (* type info will be re-derived, maybe this can be cached
   211          for efficiency? *)
   155          for efficiency? *)
   240           (Seq.make (clean_unify' useq))
   184           (Seq.make (clean_unify' useq))
   241         end
   185         end
   242       | NONE => Seq.empty
   186       | NONE => Seq.empty
   243     end;
   187     end;
   244 
   188 
   245 (* Matching and Unification for zippers *)
   189 (* Unification for zippers *)
   246 (* Note: Ts is a modified version of the original names of the outer
   190 (* Note: Ts is a modified version of the original names of the outer
   247 bound variables. New names have been introduced to make sure they are
   191 bound variables. New names have been introduced to make sure they are
   248 unique w.r.t all names in the term and each other. usednames' is
   192 unique w.r.t all names in the term and each other. usednames' is
   249 oldnames + new names. *)
   193 oldnames + new names. *)
   250 fun clean_match_z thy pat z = 
       
   251     let val (t, (FakeTs,Ts,absterm)) = prep_zipper_match z in
       
   252       case clean_match thy (pat, t) of 
       
   253         NONE => NONE 
       
   254       | SOME insts => SOME (insts, FakeTs, Ts, absterm) end;
       
   255 (* ix = max var index *)
   194 (* ix = max var index *)
   256 fun clean_unify_z sgn ix pat z = 
   195 fun clean_unify_z sgn ix pat z =
   257     let val (t, (FakeTs, Ts,absterm)) = prep_zipper_match z in
   196     let val (t, (FakeTs, Ts,absterm)) = prep_zipper_match z in
   258     Seq.map (fn insts => (insts, FakeTs, Ts, absterm)) 
   197     Seq.map (fn insts => (insts, FakeTs, Ts, absterm))
   259             (clean_unify sgn ix (t, pat)) end;
   198             (clean_unify sgn ix (t, pat)) end;
   260 
       
   261 
       
   262 (* FOR DEBUGGING...
       
   263 type trace_subst_errT = int (* subgoal *)
       
   264         * thm (* thm with all goals *)
       
   265         * (cterm list (* certified free var placeholders for vars *)
       
   266            * thm)  (* trivial thm of goal concl *)
       
   267             (* possible matches/unifiers *)
       
   268         * thm (* rule *)
       
   269         * (((indexname * typ) list (* type instantiations *)
       
   270               * (indexname * term) list ) (* term instantiations *)
       
   271              * (string * typ) list (* Type abs env *)
       
   272              * term) (* outer term *);
       
   273 
       
   274 val trace_subst_err = (Unsynchronized.ref NONE : trace_subst_errT option Unsynchronized.ref);
       
   275 val trace_subst_search = Unsynchronized.ref false;
       
   276 exception trace_subst_exp of trace_subst_errT;
       
   277 *)
       
   278 
   199 
   279 
   200 
   280 fun bot_left_leaf_of (l $ r) = bot_left_leaf_of l
   201 fun bot_left_leaf_of (l $ r) = bot_left_leaf_of l
   281   | bot_left_leaf_of (Abs(s,ty,t)) = bot_left_leaf_of t
   202   | bot_left_leaf_of (Abs(s,ty,t)) = bot_left_leaf_of t
   282   | bot_left_leaf_of x = x;
   203   | bot_left_leaf_of x = x;
   283 
   204 
   284 (* Avoid considering replacing terms which have a var at the head as
   205 (* Avoid considering replacing terms which have a var at the head as
   285    they always succeed trivially, and uninterestingly. *)
   206    they always succeed trivially, and uninterestingly. *)
   286 fun valid_match_start z =
   207 fun valid_match_start z =
   287     (case bot_left_leaf_of (Zipper.trm z) of 
   208     (case bot_left_leaf_of (Zipper.trm z) of
   288       Var _ => false 
   209       Var _ => false
   289       | _ => true);
   210       | _ => true);
   290 
   211 
   291 (* search from top, left to right, then down *)
   212 (* search from top, left to right, then down *)
   292 val search_lr_all = ZipperSearch.all_bl_ur;
   213 val search_lr_all = ZipperSearch.all_bl_ur;
   293 
   214 
   294 (* search from top, left to right, then down *)
   215 (* search from top, left to right, then down *)
   295 fun search_lr_valid validf =
   216 fun search_lr_valid validf =
   296     let 
   217     let
   297       fun sf_valid_td_lr z = 
   218       fun sf_valid_td_lr z =
   298           let val here = if validf z then [Zipper.Here z] else [] in
   219           let val here = if validf z then [Zipper.Here z] else [] in
   299             case Zipper.trm z 
   220             case Zipper.trm z
   300              of _ $ _ => [Zipper.LookIn (Zipper.move_down_left z)] 
   221              of _ $ _ => [Zipper.LookIn (Zipper.move_down_left z)]
   301                          @ here 
   222                          @ here
   302                          @ [Zipper.LookIn (Zipper.move_down_right z)]
   223                          @ [Zipper.LookIn (Zipper.move_down_right z)]
   303               | Abs _ => here @ [Zipper.LookIn (Zipper.move_down_abs z)]
   224               | Abs _ => here @ [Zipper.LookIn (Zipper.move_down_abs z)]
   304               | _ => here
   225               | _ => here
   305           end;
   226           end;
   306     in Zipper.lzy_search sf_valid_td_lr end;
   227     in Zipper.lzy_search sf_valid_td_lr end;
   307 
   228 
   308 (* search from bottom to top, left to right *)
   229 (* search from bottom to top, left to right *)
   309 
   230 
   310 fun search_bt_valid validf =
   231 fun search_bt_valid validf =
   311     let 
   232     let
   312       fun sf_valid_td_lr z = 
   233       fun sf_valid_td_lr z =
   313           let val here = if validf z then [Zipper.Here z] else [] in
   234           let val here = if validf z then [Zipper.Here z] else [] in
   314             case Zipper.trm z 
   235             case Zipper.trm z
   315              of _ $ _ => [Zipper.LookIn (Zipper.move_down_left z), 
   236              of _ $ _ => [Zipper.LookIn (Zipper.move_down_left z),
   316                           Zipper.LookIn (Zipper.move_down_right z)] @ here
   237                           Zipper.LookIn (Zipper.move_down_right z)] @ here
   317               | Abs _ => [Zipper.LookIn (Zipper.move_down_abs z)] @ here
   238               | Abs _ => [Zipper.LookIn (Zipper.move_down_abs z)] @ here
   318               | _ => here
   239               | _ => here
   319           end;
   240           end;
   320     in Zipper.lzy_search sf_valid_td_lr end;
   241     in Zipper.lzy_search sf_valid_td_lr end;
   321 
   242 
   322 fun searchf_unify_gen f (sgn, maxidx, z) lhs =
   243 fun searchf_unify_gen f (sgn, maxidx, z) lhs =
   323     Seq.map (clean_unify_z sgn maxidx lhs) 
   244     Seq.map (clean_unify_z sgn maxidx lhs)
   324             (Zipper.limit_apply f z);
   245             (Zipper.limit_apply f z);
   325 
   246 
   326 (* search all unifications *)
   247 (* search all unifications *)
   327 val searchf_lr_unify_all =
   248 val searchf_lr_unify_all =
   328     searchf_unify_gen search_lr_all;
   249     searchf_unify_gen search_lr_all;
   329 
   250 
   330 (* search only for 'valid' unifiers (non abs subterms and non vars) *)
   251 (* search only for 'valid' unifiers (non abs subterms and non vars) *)
   331 val searchf_lr_unify_valid = 
   252 val searchf_lr_unify_valid =
   332     searchf_unify_gen (search_lr_valid valid_match_start);
   253     searchf_unify_gen (search_lr_valid valid_match_start);
   333 
   254 
   334 val searchf_bt_unify_valid =
   255 val searchf_bt_unify_valid =
   335     searchf_unify_gen (search_bt_valid valid_match_start);
   256     searchf_unify_gen (search_bt_valid valid_match_start);
   336 
   257 
   388 
   309 
   389 (* General substitution of multiple occurances using one of
   310 (* General substitution of multiple occurances using one of
   390    the given theorems*)
   311    the given theorems*)
   391 
   312 
   392 
   313 
   393 exception eqsubst_occL_exp of
       
   394           string * (int list) * (thm list) * int * thm;
       
   395 fun skip_first_occs_search occ srchf sinfo lhs =
   314 fun skip_first_occs_search occ srchf sinfo lhs =
   396     case (skipto_skipseq occ (srchf sinfo lhs)) of
   315     case (skipto_skipseq occ (srchf sinfo lhs)) of
   397       SkipMore _ => Seq.empty
   316       SkipMore _ => Seq.empty
   398     | SkipSeq ss => Seq.flat ss;
   317     | SkipSeq ss => Seq.flat ss;
   399 
   318 
   406     let val nprems = Thm.nprems_of th in
   325     let val nprems = Thm.nprems_of th in
   407       if nprems < i then Seq.empty else
   326       if nprems < i then Seq.empty else
   408       let val thmseq = (Seq.of_list thms)
   327       let val thmseq = (Seq.of_list thms)
   409         fun apply_occ occ th =
   328         fun apply_occ occ th =
   410             thmseq |> Seq.maps
   329             thmseq |> Seq.maps
   411                     (fn r => eqsubst_tac' 
   330                     (fn r => eqsubst_tac'
   412                                ctxt 
   331                                ctxt
   413                                (skip_first_occs_search
   332                                (skip_first_occs_search
   414                                   occ searchf_lr_unify_valid) r
   333                                   occ searchf_lr_unify_valid) r
   415                                  (i + ((Thm.nprems_of th) - nprems))
   334                                  (i + ((Thm.nprems_of th) - nprems))
   416                                  th);
   335                                  th);
   417         val sortedoccL =
   336         val sortedoccL =
   418             Library.sort (Library.rev_order o Library.int_ord) occL;
   337             Library.sort (Library.rev_order o Library.int_ord) occL;
   419       in
   338       in
   420         Seq.map distinct_subgoals (Seq.EVERY (map apply_occ sortedoccL) th)
   339         Seq.map distinct_subgoals (Seq.EVERY (map apply_occ sortedoccL) th)
   421       end
   340       end
   422     end
   341     end;
   423     handle THM _ => raise eqsubst_occL_exp ("THM",occL,thms,i,th);
       
   424 
   342 
   425 
   343 
   426 (* inthms are the given arguments in Isar, and treated as eqstep with
   344 (* inthms are the given arguments in Isar, and treated as eqstep with
   427    the first one, then the second etc *)
   345    the first one, then the second etc *)
   428 fun eqsubst_meth ctxt occL inthms =
   346 fun eqsubst_meth ctxt occL inthms =
   532             Library.sort (Library.rev_order o Library.int_ord) occL
   450             Library.sort (Library.rev_order o Library.int_ord) occL
   533       in
   451       in
   534         Seq.map distinct_subgoals
   452         Seq.map distinct_subgoals
   535                 (Seq.EVERY (map apply_occ sortedoccs) th)
   453                 (Seq.EVERY (map apply_occ sortedoccs) th)
   536       end
   454       end
   537     end
   455     end;
   538     handle THM _ => raise eqsubst_occL_exp ("THM",occL,thms,i,th);
       
   539 
   456 
   540 (* inthms are the given arguments in Isar, and treated as eqstep with
   457 (* inthms are the given arguments in Isar, and treated as eqstep with
   541    the first one, then the second etc *)
   458    the first one, then the second etc *)
   542 fun eqsubst_asm_meth ctxt occL inthms =
   459 fun eqsubst_asm_meth ctxt occL inthms =
   543     SIMPLE_METHOD' (eqsubst_asm_tac ctxt occL inthms);
   460     SIMPLE_METHOD' (eqsubst_asm_tac ctxt occL inthms);