src/Pure/Tools/rule_insts.ML
changeset 59780 23b67731f4f0
parent 59775 cdd0f4d0835e
child 59787 6e2a20486897
equal deleted inserted replaced
59778:fe5b796d6b2a 59780:23b67731f4f0
    12   val of_rule: Proof.context -> string option list * string option list ->
    12   val of_rule: Proof.context -> string option list * string option list ->
    13     (binding * string option * mixfix) list -> thm -> thm
    13     (binding * string option * mixfix) list -> thm -> thm
    14   val read_instantiate: Proof.context ->
    14   val read_instantiate: Proof.context ->
    15     ((indexname * Position.T) * string) list -> string list -> thm -> thm
    15     ((indexname * Position.T) * string) list -> string list -> thm -> thm
    16   val res_inst_tac: Proof.context ->
    16   val res_inst_tac: Proof.context ->
    17     ((indexname * Position.T) * string) list -> thm -> int -> tactic
    17     ((indexname * Position.T) * string) list -> (binding * string option * mixfix) list -> thm ->
       
    18     int -> tactic
    18   val eres_inst_tac: Proof.context ->
    19   val eres_inst_tac: Proof.context ->
    19     ((indexname * Position.T) * string) list -> thm -> int -> tactic
    20     ((indexname * Position.T) * string) list -> (binding * string option * mixfix) list -> thm ->
       
    21     int -> tactic
    20   val cut_inst_tac: Proof.context ->
    22   val cut_inst_tac: Proof.context ->
    21     ((indexname * Position.T) * string) list -> thm -> int -> tactic
    23     ((indexname * Position.T) * string) list -> (binding * string option * mixfix) list -> thm ->
       
    24     int -> tactic
    22   val forw_inst_tac: Proof.context ->
    25   val forw_inst_tac: Proof.context ->
    23     ((indexname * Position.T) * string) list -> thm -> int -> tactic
    26     ((indexname * Position.T) * string) list -> (binding * string option * mixfix) list -> thm ->
       
    27     int -> tactic
    24   val dres_inst_tac: Proof.context ->
    28   val dres_inst_tac: Proof.context ->
    25     ((indexname * Position.T) * string) list -> thm -> int -> tactic
    29     ((indexname * Position.T) * string) list -> (binding * string option * mixfix) list -> thm ->
    26   val thin_tac: Proof.context -> string -> int -> tactic
    30     int -> tactic
    27   val subgoal_tac: Proof.context -> string -> int -> tactic
    31   val thin_tac: Proof.context -> string -> (binding * string option * mixfix) list ->
       
    32     int -> tactic
       
    33   val subgoal_tac: Proof.context -> string -> (binding * string option * mixfix) list ->
       
    34     int -> tactic
    28   val make_elim_preserve: Proof.context -> thm -> thm
    35   val make_elim_preserve: Proof.context -> thm -> thm
    29   val method:
    36   val method:
    30     (Proof.context -> ((indexname * Position.T) * string) list -> thm -> int -> tactic) ->
    37     (Proof.context -> ((indexname * Position.T) * string) list ->
       
    38       (binding * string option * mixfix) list -> thm -> int -> tactic) ->
    31     (Proof.context -> thm list -> int -> tactic) -> (Proof.context -> Proof.method) context_parser
    39     (Proof.context -> thm list -> int -> tactic) -> (Proof.context -> Proof.method) context_parser
    32 end;
    40 end;
    33 
    41 
    34 structure Rule_Insts: RULE_INSTS =
    42 structure Rule_Insts: RULE_INSTS =
    35 struct
    43 struct
   122 (** forward rules **)
   130 (** forward rules **)
   123 
   131 
   124 fun where_rule ctxt mixed_insts fixes thm =
   132 fun where_rule ctxt mixed_insts fixes thm =
   125   let
   133   let
   126     val ctxt' = ctxt
   134     val ctxt' = ctxt
   127       |> Proof_Context.read_vars fixes |-> Proof_Context.add_fixes |> #2
   135       |> Variable.declare_thm thm
   128       |> Variable.declare_thm thm;
   136       |> Proof_Context.read_vars fixes |-> Proof_Context.add_fixes |> #2;
   129     val (inst_tvars, inst_vars) = read_insts ctxt' mixed_insts thm;
   137     val (inst_tvars, inst_vars) = read_insts ctxt' mixed_insts thm;
   130   in
   138   in
   131     thm
   139     thm
   132     |> Drule.instantiate_normalize
   140     |> Drule.instantiate_normalize
   133       (map (apply2 (Thm.ctyp_of ctxt) o apfst TVar) inst_tvars,
   141       (map (apply2 (Thm.ctyp_of ctxt) o apfst TVar) inst_tvars,
   134        map (apply2 (Thm.cterm_of ctxt) o apfst Var) inst_vars)
   142        map (apply2 (Thm.cterm_of ctxt) o apfst Var) inst_vars)
   135     |> singleton (Proof_Context.export ctxt' ctxt)
   143     |> singleton (Variable.export ctxt' ctxt)
   136     |> Rule_Cases.save thm
   144     |> Rule_Cases.save thm
   137   end;
   145   end;
   138 
   146 
   139 fun of_rule ctxt (args, concl_args) fixes thm =
   147 fun of_rule ctxt (args, concl_args) fixes thm =
   140   let
   148   let
   190 
   198 
   191 (** tactics **)
   199 (** tactics **)
   192 
   200 
   193 (* resolution after lifting and instantiation; may refer to parameters of the subgoal *)
   201 (* resolution after lifting and instantiation; may refer to parameters of the subgoal *)
   194 
   202 
   195 fun bires_inst_tac bires_flag ctxt mixed_insts thm i st = CSUBGOAL (fn (cgoal, _) =>
   203 fun bires_inst_tac bires_flag ctxt mixed_insts fixes thm i st = CSUBGOAL (fn (cgoal, _) =>
   196   let
   204   let
   197     (* goal parameters *)
   205     (* goal parameters *)
   198 
   206 
   199     val goal = Thm.term_of cgoal;
   207     val goal = Thm.term_of cgoal;
   200     val params =
   208     val params =
   208       |> Proof_Context.add_fixes (map (fn (x, T) => (Binding.name x, SOME T, NoSyn)) params)
   216       |> Proof_Context.add_fixes (map (fn (x, T) => (Binding.name x, SOME T, NoSyn)) params)
   209       ||> Proof_Context.set_mode Proof_Context.mode_schematic;
   217       ||> Proof_Context.set_mode Proof_Context.mode_schematic;
   210     val paramTs = map #2 params;
   218     val paramTs = map #2 params;
   211 
   219 
   212 
   220 
       
   221     (* local fixes *)
       
   222 
       
   223     val fixes_ctxt = param_ctxt
       
   224       |> Proof_Context.read_vars fixes |-> Proof_Context.add_fixes |> #2;
       
   225 
       
   226     val (inst_tvars, inst_vars) = read_insts fixes_ctxt mixed_insts thm;
       
   227 
       
   228 
   213     (* lift and instantiate rule *)
   229     (* lift and instantiate rule *)
   214 
       
   215     val (inst_tvars, inst_vars) = read_insts param_ctxt mixed_insts thm;
       
   216 
   230 
   217     val inc = Thm.maxidx_of st + 1;
   231     val inc = Thm.maxidx_of st + 1;
   218     fun lift_var ((a, j), T) =
   232     fun lift_var ((a, j), T) =
   219       Var ((a, j + inc), paramTs ---> Logic.incr_tvar inc T);
   233       Var ((a, j + inc), paramTs ---> Logic.incr_tvar inc T);
   220     fun lift_term t =
   234     fun lift_term t =
   221       fold_rev Term.absfree (param_names ~~ paramTs)
   235       fold_rev Term.absfree (param_names ~~ paramTs)
   222         (Logic.incr_indexes (paramTs, inc) t);
   236         (Logic.incr_indexes (paramTs, inc) t);
   223 
   237 
   224     val inst_tvars' = inst_tvars
   238     val inst_tvars' = inst_tvars
   225       |> map (apply2 (Thm.ctyp_of param_ctxt o Logic.incr_tvar inc) o apfst TVar);
   239       |> map (apply2 (Thm.ctyp_of fixes_ctxt o Logic.incr_tvar inc) o apfst TVar);
   226     val inst_vars' = inst_vars
   240     val inst_vars' = inst_vars
   227       |> map (fn (v, t) => apply2 (Thm.cterm_of param_ctxt) (lift_var v, lift_term t));
   241       |> map (fn (v, t) => apply2 (Thm.cterm_of fixes_ctxt) (lift_var v, lift_term t));
   228 
   242 
   229     val thm' =
   243     val thm' =
   230       Drule.instantiate_normalize (inst_tvars', inst_vars')
   244       Drule.instantiate_normalize (inst_tvars', inst_vars')
   231         (Thm.lift_rule cgoal thm);
   245         (Thm.lift_rule cgoal thm)
       
   246       |> singleton (Variable.export fixes_ctxt param_ctxt);
   232   in
   247   in
   233     compose_tac param_ctxt (bires_flag, thm', Thm.nprems_of thm) i
   248     compose_tac param_ctxt (bires_flag, thm', Thm.nprems_of thm) i
   234   end) i st;
   249   end) i st;
   235 
   250 
   236 val res_inst_tac = bires_inst_tac false;
   251 val res_inst_tac = bires_inst_tac false;
   254       [th] => th
   269       [th] => th
   255     | _ => raise THM ("make_elim_preserve", 1, [rl]))
   270     | _ => raise THM ("make_elim_preserve", 1, [rl]))
   256   end;
   271   end;
   257 
   272 
   258 (*instantiate and cut -- for atomic fact*)
   273 (*instantiate and cut -- for atomic fact*)
   259 fun cut_inst_tac ctxt insts rule = res_inst_tac ctxt insts (make_elim_preserve ctxt rule);
   274 fun cut_inst_tac ctxt insts fixes rule =
       
   275   res_inst_tac ctxt insts fixes (make_elim_preserve ctxt rule);
   260 
   276 
   261 (*forward tactic applies a rule to an assumption without deleting it*)
   277 (*forward tactic applies a rule to an assumption without deleting it*)
   262 fun forw_inst_tac ctxt insts rule = cut_inst_tac ctxt insts rule THEN' assume_tac ctxt;
   278 fun forw_inst_tac ctxt insts fixes rule =
       
   279   cut_inst_tac ctxt insts fixes rule THEN' assume_tac ctxt;
   263 
   280 
   264 (*dresolve tactic applies a rule to replace an assumption*)
   281 (*dresolve tactic applies a rule to replace an assumption*)
   265 fun dres_inst_tac ctxt insts rule = eres_inst_tac ctxt insts (make_elim_preserve ctxt rule);
   282 fun dres_inst_tac ctxt insts fixes rule =
       
   283   eres_inst_tac ctxt insts fixes (make_elim_preserve ctxt rule);
   266 
   284 
   267 
   285 
   268 (* derived tactics *)
   286 (* derived tactics *)
   269 
   287 
   270 (*deletion of an assumption*)
   288 (*deletion of an assumption*)
   271 fun thin_tac ctxt s =
   289 fun thin_tac ctxt s fixes =
   272   eres_inst_tac ctxt [((("V", 0), Position.none), s)] Drule.thin_rl;
   290   eres_inst_tac ctxt [((("V", 0), Position.none), s)] fixes Drule.thin_rl;
   273 
   291 
   274 (*Introduce the given proposition as lemma and subgoal*)
   292 (*Introduce the given proposition as lemma and subgoal*)
   275 fun subgoal_tac ctxt A =
   293 fun subgoal_tac ctxt A fixes =
   276   DETERM o res_inst_tac ctxt [((("psi", 0), Position.none), A)] cut_rl;
   294   DETERM o res_inst_tac ctxt [((("psi", 0), Position.none), A)] fixes cut_rl;
   277 
       
   278 
   295 
   279 
   296 
   280 (* method wrapper *)
   297 (* method wrapper *)
   281 
   298 
   282 fun method inst_tac tac =
   299 fun method inst_tac tac =
   283   Args.goal_spec --
   300   Args.goal_spec --
   284   Scan.optional (Scan.lift
   301   Scan.optional (Scan.lift
   285     (Parse.and_list1 (Parse.position Args.var -- (Args.$$$ "=" |-- Parse.!!! Args.name_inner_syntax))
   302     (Parse.and_list1
   286       --| Args.$$$ "in")) [] --
   303       (Parse.position Args.var -- (Args.$$$ "=" |-- Parse.!!! Args.name_inner_syntax)) --
       
   304       Parse.for_fixes --| Args.$$$ "in")) ([], []) --
   287   Attrib.thms >>
   305   Attrib.thms >>
   288   (fn ((quant, insts), thms) => fn ctxt => METHOD (fn facts =>
   306   (fn ((quant, (insts, fixes)), thms) => fn ctxt => METHOD (fn facts =>
   289     if null insts then quant (Method.insert_tac facts THEN' tac ctxt thms)
   307     if null insts andalso null fixes
       
   308     then quant (Method.insert_tac facts THEN' tac ctxt thms)
   290     else
   309     else
   291       (case thms of
   310       (case thms of
   292         [thm] => quant (Method.insert_tac facts THEN' inst_tac ctxt insts thm)
   311         [thm] => quant (Method.insert_tac facts THEN' inst_tac ctxt insts fixes thm)
   293       | _ => error "Cannot have instantiations with multiple rules")));
   312       | _ => error "Cannot have instantiations with multiple rules")));
   294 
   313 
   295 
   314 
   296 (* setup *)
   315 (* setup *)
   297 
   316 
   307   Method.setup @{binding frule_tac} (method forw_inst_tac forward_tac)
   326   Method.setup @{binding frule_tac} (method forw_inst_tac forward_tac)
   308     "apply rule in forward manner (dynamic instantiation)" #>
   327     "apply rule in forward manner (dynamic instantiation)" #>
   309   Method.setup @{binding cut_tac} (method cut_inst_tac (K cut_rules_tac))
   328   Method.setup @{binding cut_tac} (method cut_inst_tac (K cut_rules_tac))
   310     "cut rule (dynamic instantiation)" #>
   329     "cut rule (dynamic instantiation)" #>
   311   Method.setup @{binding subgoal_tac}
   330   Method.setup @{binding subgoal_tac}
   312     (Args.goal_spec -- Scan.lift (Scan.repeat1 Args.name_inner_syntax) >>
   331     (Args.goal_spec -- Scan.lift (Scan.repeat1 Args.name_inner_syntax -- Parse.for_fixes) >>
   313       (fn (quant, props) => fn ctxt =>
   332       (fn (quant, (props, fixes)) => fn ctxt =>
   314         SIMPLE_METHOD'' quant (EVERY' (map (subgoal_tac ctxt) props))))
   333         SIMPLE_METHOD'' quant (EVERY' (map (fn prop => subgoal_tac ctxt prop fixes) props))))
   315     "insert subgoal (dynamic instantiation)" #>
   334     "insert subgoal (dynamic instantiation)" #>
   316   Method.setup @{binding thin_tac}
   335   Method.setup @{binding thin_tac}
   317     (Args.goal_spec -- Scan.lift Args.name_inner_syntax >>
   336     (Args.goal_spec -- Scan.lift (Args.name_inner_syntax -- Parse.for_fixes) >>
   318       (fn (quant, prop) => fn ctxt => SIMPLE_METHOD'' quant (thin_tac ctxt prop)))
   337       (fn (quant, (prop, fixes)) => fn ctxt => SIMPLE_METHOD'' quant (thin_tac ctxt prop fixes)))
   319       "remove premise (dynamic instantiation)");
   338     "remove premise (dynamic instantiation)");
   320 
   339 
   321 end;
   340 end;