src/Pure/Isar/method.ML
changeset 12324 5db4b4596d1a
parent 12311 ce5f9e61c037
child 12347 6ee66b76d813
equal deleted inserted replaced
12323:e151ee6e820f 12324:5db4b4596d1a
    15 
    15 
    16 signature METHOD =
    16 signature METHOD =
    17 sig
    17 sig
    18   include BASIC_METHOD
    18   include BASIC_METHOD
    19   val trace: Proof.context -> thm list -> unit
    19   val trace: Proof.context -> thm list -> unit
    20   val print_global_rules: theory -> unit
       
    21   val print_local_rules: Proof.context -> unit
       
    22   val dest_global: theory attribute
       
    23   val elim_global: theory attribute
       
    24   val intro_global: theory attribute
       
    25   val dest_bang_global: theory attribute
       
    26   val elim_bang_global: theory attribute
       
    27   val intro_bang_global: theory attribute
       
    28   val rule_del_global: theory attribute
       
    29   val dest_local: Proof.context attribute
       
    30   val elim_local: Proof.context attribute
       
    31   val intro_local: Proof.context attribute
       
    32   val dest_bang_local: Proof.context attribute
       
    33   val elim_bang_local: Proof.context attribute
       
    34   val intro_bang_local: Proof.context attribute
       
    35   val rule_del_local: Proof.context attribute
       
    36   val RAW_METHOD: (thm list -> tactic) -> Proof.method
    20   val RAW_METHOD: (thm list -> tactic) -> Proof.method
    37   val RAW_METHOD_CASES:
    21   val RAW_METHOD_CASES:
    38     (thm list -> thm -> (thm * (string * RuleCases.T) list) Seq.seq) -> Proof.method
    22     (thm list -> thm -> (thm * (string * RuleCases.T) list) Seq.seq) -> Proof.method
    39   val METHOD: (thm list -> tactic) -> Proof.method
    23   val METHOD: (thm list -> tactic) -> Proof.method
    40   val METHOD_CASES:
    24   val METHOD_CASES:
   131 
   115 
   132 structure Method: METHOD =
   116 structure Method: METHOD =
   133 struct
   117 struct
   134 
   118 
   135 
   119 
   136 (** tracing *)
   120 (** proof methods **)
       
   121 
       
   122 (* tracing *)
   137 
   123 
   138 val trace_rules = ref false;
   124 val trace_rules = ref false;
   139 
   125 
   140 fun trace ctxt rules =
   126 fun trace ctxt rules =
   141   conditional (! trace_rules andalso not (null rules)) (fn () =>
   127   conditional (! trace_rules andalso not (null rules)) (fn () =>
   142     Pretty.big_list "rules:" (map (ProofContext.pretty_thm ctxt) rules)
   128     Pretty.big_list "rules:" (map (ProofContext.pretty_thm ctxt) rules)
   143     |> Pretty.string_of |> tracing);
   129     |> Pretty.string_of |> tracing);
   144 
   130 
   145 
       
   146 
       
   147 (** global and local rule data **)
       
   148 
       
   149 val intro_bangK = 0;
       
   150 val elim_bangK = 1;
       
   151 val introK = 2;
       
   152 val elimK = 3;
       
   153 
       
   154 local
       
   155 
       
   156 fun kind_name 0 = "safe introduction rules (intro!)"
       
   157   | kind_name 1 = "safe elimination rules (elim!)"
       
   158   | kind_name 2 = "introduction rules (intro)"
       
   159   | kind_name 3 = "elimination rules (elim)"
       
   160   | kind_name _ = "unknown";
       
   161 
       
   162 fun prt_rules prt x (k, rs) =
       
   163   Pretty.writeln (Pretty.big_list (kind_name k ^ ":") (map (prt x) (NetRules.rules rs)));
       
   164 
       
   165 in
       
   166   fun print_rules prt x rules = seq (prt_rules prt x) (0 upto length rules - 1 ~~ rules);
       
   167 end;
       
   168 
       
   169 
       
   170 (* theory data kind 'Isar/rules' *)
       
   171 
       
   172 structure GlobalRulesArgs =
       
   173 struct
       
   174   val name = "Isar/rules";
       
   175   type T = thm NetRules.T list;
       
   176 
       
   177   val empty = [NetRules.intro, NetRules.elim, NetRules.intro, NetRules.elim];
       
   178   val copy = I;
       
   179   val prep_ext = I;
       
   180   fun merge x = map2 NetRules.merge x;
       
   181   val print = print_rules Display.pretty_thm_sg;
       
   182 end;
       
   183 
       
   184 structure GlobalRules = TheoryDataFun(GlobalRulesArgs);
       
   185 val print_global_rules = GlobalRules.print;
       
   186 
       
   187 
       
   188 (* proof data kind 'Isar/rules' *)
       
   189 
       
   190 structure LocalRulesArgs =
       
   191 struct
       
   192   val name = GlobalRulesArgs.name;
       
   193   type T = GlobalRulesArgs.T;
       
   194   val init = GlobalRules.get;
       
   195   val print = print_rules ProofContext.pretty_thm;
       
   196 end;
       
   197 
       
   198 structure LocalRules = ProofDataFun(LocalRulesArgs);
       
   199 val print_local_rules = LocalRules.print;
       
   200 
       
   201 
       
   202 
       
   203 (** attributes **)
       
   204 
       
   205 (* add rules *)
       
   206 
       
   207 local
       
   208 
       
   209 fun add_rule k view th = Library.map_nth_elem k (NetRules.insert (view th));
       
   210 
       
   211 val add_intro      = add_rule introK I;
       
   212 val add_elim       = add_rule elimK I;
       
   213 val add_dest       = add_rule elimK Tactic.make_elim;
       
   214 val add_intro_bang = add_rule intro_bangK I;
       
   215 val add_elim_bang  = add_rule elim_bangK I;
       
   216 val add_dest_bang  = add_rule elim_bangK Tactic.make_elim;
       
   217 
       
   218 fun del_rule th = map (NetRules.delete th o NetRules.delete (Tactic.make_elim th));
       
   219 
       
   220 fun mk_att f g (x, th) = (f (g th) x, th);
       
   221 
       
   222 in
       
   223 
       
   224 val dest_global = mk_att GlobalRules.map add_dest;
       
   225 val elim_global = mk_att GlobalRules.map add_elim;
       
   226 val intro_global = mk_att GlobalRules.map add_intro;
       
   227 val dest_bang_global = mk_att GlobalRules.map add_dest_bang;
       
   228 val elim_bang_global = mk_att GlobalRules.map add_elim_bang;
       
   229 val intro_bang_global = mk_att GlobalRules.map add_intro_bang;
       
   230 val rule_del_global = mk_att GlobalRules.map del_rule;
       
   231 
       
   232 val dest_local = mk_att LocalRules.map add_dest;
       
   233 val elim_local = mk_att LocalRules.map add_elim;
       
   234 val intro_local = mk_att LocalRules.map add_intro;
       
   235 val dest_bang_local = mk_att LocalRules.map add_dest_bang;
       
   236 val elim_bang_local = mk_att LocalRules.map add_elim_bang;
       
   237 val intro_bang_local = mk_att LocalRules.map add_intro_bang;
       
   238 val rule_del_local = mk_att LocalRules.map del_rule;
       
   239 
       
   240 fun del_args att = Attrib.syntax (Scan.lift Args.del >> K att);
       
   241 
       
   242 end;
       
   243 
       
   244 
       
   245 (* concrete syntax *)
       
   246 
       
   247 val rule_atts =
       
   248  [("dest",
       
   249    (Attrib.bang_args dest_bang_global dest_global,
       
   250     Attrib.bang_args dest_bang_local dest_local),
       
   251     "declaration of destruction rule"),
       
   252   ("elim",
       
   253    (Attrib.bang_args elim_bang_global elim_global,
       
   254     Attrib.bang_args elim_bang_local elim_local),
       
   255     "declaration of elimination rule"),
       
   256   ("intro",
       
   257    (Attrib.bang_args intro_bang_global intro_global,
       
   258     Attrib.bang_args intro_bang_local intro_local),
       
   259     "declaration of introduction rule"),
       
   260   ("rule", (del_args rule_del_global, del_args rule_del_local),
       
   261     "remove declaration of elim/intro rule")];
       
   262 
       
   263 
       
   264 
       
   265 (** proof methods **)
       
   266 
   131 
   267 (* make methods *)
   132 (* make methods *)
   268 
   133 
   269 val RAW_METHOD = Proof.method;
   134 val RAW_METHOD = Proof.method;
   270 val RAW_METHOD_CASES = Proof.method_cases;
   135 val RAW_METHOD_CASES = Proof.method_cases;
   302   | insert_tac facts i = EVERY (map (fn th => cut_rule_tac th i) facts);
   167   | insert_tac facts i = EVERY (map (fn th => cut_rule_tac th i) facts);
   303 
   168 
   304 val insert_facts = METHOD (ALLGOALS o insert_tac);
   169 val insert_facts = METHOD (ALLGOALS o insert_tac);
   305 fun insert thms = METHOD (fn _ => ALLGOALS (insert_tac thms));
   170 fun insert thms = METHOD (fn _ => ALLGOALS (insert_tac thms));
   306 
   171 
   307 end;
       
   308 
       
   309 
       
   310 (* simple methods *)
       
   311 
       
   312 fun SIMPLE_METHOD tac = METHOD (fn facts => ALLGOALS (insert_tac facts) THEN tac);
   172 fun SIMPLE_METHOD tac = METHOD (fn facts => ALLGOALS (insert_tac facts) THEN tac);
   313 fun SIMPLE_METHOD' quant tac = METHOD (fn facts => quant (insert_tac facts THEN' tac));
   173 fun SIMPLE_METHOD' quant tac = METHOD (fn facts => quant (insert_tac facts THEN' tac));
   314 
   174 
       
   175 end;
       
   176 
   315 
   177 
   316 (* unfold / fold definitions *)
   178 (* unfold / fold definitions *)
   317 
   179 
   318 fun unfold thms = SIMPLE_METHOD (CHANGED_PROP (rewrite_goals_tac thms));
   180 fun unfold thms = SIMPLE_METHOD (CHANGED_PROP (rewrite_goals_tac thms));
   319 fun fold thms = SIMPLE_METHOD (CHANGED_PROP (fold_goals_tac thms));
   181 fun fold thms = SIMPLE_METHOD (CHANGED_PROP (fold_goals_tac thms));
   335 fun multi_resolves facts rules = Seq.flat (Seq.map (multi_resolve facts) (Seq.of_list rules));
   197 fun multi_resolves facts rules = Seq.flat (Seq.map (multi_resolve facts) (Seq.of_list rules));
   336 
   198 
   337 end;
   199 end;
   338 
   200 
   339 
   201 
   340 (* basic rules *)
   202 (* single rules *)
   341 
   203 
   342 local
   204 local
   343 
   205 
       
   206 fun may_unify t nets = RuleContext.orderlist (flat (map (fn net => Net.unify_term net t) nets));
       
   207 
       
   208 fun find_erules [] = K []
       
   209   | find_erules (fact :: _) = may_unify (Logic.strip_assums_concl (#prop (Thm.rep_thm fact)));
       
   210 
       
   211 fun find_rules goal = may_unify (Logic.strip_assums_concl goal);
       
   212 
       
   213 
   344 fun gen_rule_tac tac rules [] i st = tac rules i st
   214 fun gen_rule_tac tac rules [] i st = tac rules i st
   345   | gen_rule_tac tac erules facts i st =
   215   | gen_rule_tac tac rules facts i st =
   346       Seq.flat (Seq.map (fn rule => (tac o single) rule i st) (multi_resolves facts erules));
   216       Seq.flat (Seq.map (fn rule => (tac o single) rule i st) (multi_resolves facts rules));
   347 
   217 
   348 fun gen_arule_tac tac j rules facts =
   218 fun gen_arule_tac tac j rules facts =
   349   EVERY' (gen_rule_tac tac rules facts :: replicate j Tactic.assume_tac);
   219   EVERY' (gen_rule_tac tac rules facts :: replicate j Tactic.assume_tac);
   350 
   220 
   351 fun find_erules [] _ = []
       
   352   | find_erules (fact :: _) rs =
       
   353       NetRules.retrieve rs (Logic.strip_assums_concl (#prop (Thm.rep_thm fact)));
       
   354 
       
   355 fun find_rules goal rs = NetRules.retrieve rs (Logic.strip_assums_concl goal);
       
   356 
       
   357 fun gen_some_rule_tac tac arg_rules ctxt facts = SUBGOAL (fn (goal, i) =>
   221 fun gen_some_rule_tac tac arg_rules ctxt facts = SUBGOAL (fn (goal, i) =>
   358   let
   222   let
   359     fun get k = nth_elem (k, LocalRules.get ctxt);
   223     val netpairs = RuleContext.netpairs ctxt;
   360     val rules =
   224     val rules =
   361       if not (null arg_rules) then arg_rules
   225       if not (null arg_rules) then arg_rules
   362       else find_erules facts (get elim_bangK) @ find_erules facts (get elimK) @
   226       else map #2 (find_erules facts (map #2 netpairs) @ find_rules goal (map #1 netpairs));
   363         find_rules goal (get intro_bangK) @ find_rules goal (get introK);
       
   364   in trace ctxt rules; tac rules facts i end);
   227   in trace ctxt rules; tac rules facts i end);
   365 
   228 
   366 fun meth tac x = METHOD (HEADGOAL o tac x);
   229 fun meth tac x = METHOD (HEADGOAL o tac x);
   367 fun meth' tac x y = METHOD (HEADGOAL o tac x y);
   230 fun meth' tac x y = METHOD (HEADGOAL o tac x y);
   368 
   231 
   670 
   533 
   671 val global_terminal_proof = global_term_proof true;
   534 val global_terminal_proof = global_term_proof true;
   672 val global_default_proof = global_terminal_proof (default_text, None);
   535 val global_default_proof = global_terminal_proof (default_text, None);
   673 val global_immediate_proof = global_terminal_proof (this_text, None);
   536 val global_immediate_proof = global_terminal_proof (this_text, None);
   674 val global_done_proof = global_term_proof false (done_text, None);
   537 val global_done_proof = global_term_proof false (done_text, None);
       
   538 
   675 
   539 
   676 
   540 
   677 (** theory setup **)
   541 (** theory setup **)
   678 
   542 
   679 (* misc tactic emulations *)
   543 (* misc tactic emulations *)
   715 
   579 
   716 
   580 
   717 (* setup *)
   581 (* setup *)
   718 
   582 
   719 val setup =
   583 val setup =
   720  [GlobalRules.init, LocalRules.init, Attrib.add_attributes rule_atts,
   584  [MethodsData.init, add_methods pure_methods,
   721   MethodsData.init, add_methods pure_methods,
   585   (#1 o PureThy.add_thms [(("", Drule.equal_intr_rule), [RuleContext.intro_query_global None])])];
   722   (#1 o PureThy.add_thms [(("", Drule.equal_intr_rule), [intro_global])])];
       
   723 
   586 
   724 
   587 
   725 end;
   588 end;
   726 
   589 
   727 
   590