src/Pure/tactic.ML
changeset 59498 50b60f501b05
parent 59164 ff40c53d1af9
child 59582 0fbed69ff081
equal deleted inserted replaced
59497:0c5cd369a643 59498:50b60f501b05
    10   val rule_by_tactic: Proof.context -> tactic -> thm -> thm
    10   val rule_by_tactic: Proof.context -> tactic -> thm -> thm
    11   val assume_tac: Proof.context -> int -> tactic
    11   val assume_tac: Proof.context -> int -> tactic
    12   val eq_assume_tac: int -> tactic
    12   val eq_assume_tac: int -> tactic
    13   val compose_tac: Proof.context -> (bool * thm * int) -> int -> tactic
    13   val compose_tac: Proof.context -> (bool * thm * int) -> int -> tactic
    14   val make_elim: thm -> thm
    14   val make_elim: thm -> thm
    15   val biresolve_tac: (bool * thm) list -> int -> tactic
    15   val biresolve0_tac: (bool * thm) list -> int -> tactic
    16   val resolve_tac: thm list -> int -> tactic
    16   val biresolve_tac: Proof.context -> (bool * thm) list -> int -> tactic
    17   val eresolve_tac: thm list -> int -> tactic
    17   val resolve0_tac: thm list -> int -> tactic
    18   val forward_tac: thm list -> int -> tactic
    18   val resolve_tac: Proof.context -> thm list -> int -> tactic
    19   val dresolve_tac: thm list -> int -> tactic
    19   val eresolve0_tac: thm list -> int -> tactic
       
    20   val eresolve_tac: Proof.context -> thm list -> int -> tactic
       
    21   val forward0_tac: thm list -> int -> tactic
       
    22   val forward_tac: Proof.context -> thm list -> int -> tactic
       
    23   val dresolve0_tac: thm list -> int -> tactic
       
    24   val dresolve_tac: Proof.context -> thm list -> int -> tactic
    20   val atac: int -> tactic
    25   val atac: int -> tactic
    21   val rtac: thm -> int -> tactic
    26   val rtac: thm -> int -> tactic
    22   val dtac: thm -> int -> tactic
    27   val dtac: thm -> int -> tactic
    23   val etac: thm -> int -> tactic
    28   val etac: thm -> int -> tactic
    24   val ftac: thm -> int -> tactic
    29   val ftac: thm -> int -> tactic
    25   val ares_tac: thm list -> int -> tactic
    30   val ares_tac: thm list -> int -> tactic
    26   val solve_tac: thm list -> int -> tactic
    31   val solve_tac: Proof.context -> thm list -> int -> tactic
    27   val bimatch_tac: Proof.context -> (bool * thm) list -> int -> tactic
    32   val bimatch_tac: Proof.context -> (bool * thm) list -> int -> tactic
    28   val match_tac: Proof.context -> thm list -> int -> tactic
    33   val match_tac: Proof.context -> thm list -> int -> tactic
    29   val ematch_tac: Proof.context -> thm list -> int -> tactic
    34   val ematch_tac: Proof.context -> thm list -> int -> tactic
    30   val dmatch_tac: Proof.context -> thm list -> int -> tactic
    35   val dmatch_tac: Proof.context -> thm list -> int -> tactic
    31   val flexflex_tac: Proof.context -> tactic
    36   val flexflex_tac: Proof.context -> tactic
    48   val lessb: (bool * thm) * (bool * thm) -> bool
    53   val lessb: (bool * thm) * (bool * thm) -> bool
    49   val rename_tac: string list -> int -> tactic
    54   val rename_tac: string list -> int -> tactic
    50   val rotate_tac: int -> int -> tactic
    55   val rotate_tac: int -> int -> tactic
    51   val defer_tac: int -> tactic
    56   val defer_tac: int -> tactic
    52   val prefer_tac: int -> tactic
    57   val prefer_tac: int -> tactic
    53   val filter_prems_tac: (term -> bool) -> int -> tactic
    58   val filter_prems_tac: Proof.context -> (term -> bool) -> int -> tactic
    54 end;
    59 end;
    55 
    60 
    56 signature TACTIC =
    61 signature TACTIC =
    57 sig
    62 sig
    58   include BASIC_TACTIC
    63   include BASIC_TACTIC
   112 (*Converts a "destruct" rule like P&Q==>P to an "elimination" rule
   117 (*Converts a "destruct" rule like P&Q==>P to an "elimination" rule
   113   like [| P&Q; P==>R |] ==> R *)
   118   like [| P&Q; P==>R |] ==> R *)
   114 fun make_elim rl = zero_var_indexes (rl RS revcut_rl);
   119 fun make_elim rl = zero_var_indexes (rl RS revcut_rl);
   115 
   120 
   116 (*Attack subgoal i by resolution, using flags to indicate elimination rules*)
   121 (*Attack subgoal i by resolution, using flags to indicate elimination rules*)
   117 fun biresolve_tac brules i = PRIMSEQ (Thm.biresolution NONE false brules i);
   122 fun biresolve0_tac brules i = PRIMSEQ (Thm.biresolution NONE false brules i);
       
   123 fun biresolve_tac ctxt brules i = PRIMSEQ (Thm.biresolution (SOME ctxt) false brules i);
   118 
   124 
   119 (*Resolution: the simple case, works for introduction rules*)
   125 (*Resolution: the simple case, works for introduction rules*)
   120 fun resolve_tac rules = biresolve_tac (map (pair false) rules);
   126 fun resolve0_tac rules = biresolve0_tac (map (pair false) rules);
       
   127 fun resolve_tac ctxt rules = biresolve_tac ctxt (map (pair false) rules);
   121 
   128 
   122 (*Resolution with elimination rules only*)
   129 (*Resolution with elimination rules only*)
   123 fun eresolve_tac rules = biresolve_tac (map (pair true) rules);
   130 fun eresolve0_tac rules = biresolve0_tac (map (pair true) rules);
       
   131 fun eresolve_tac ctxt rules = biresolve_tac ctxt (map (pair true) rules);
   124 
   132 
   125 (*Forward reasoning using destruction rules.*)
   133 (*Forward reasoning using destruction rules.*)
   126 fun forward_tac rls = resolve_tac (map make_elim rls) THEN' atac;
   134 fun forward0_tac rls = resolve0_tac (map make_elim rls) THEN' atac;
       
   135 fun forward_tac ctxt rls = resolve_tac ctxt (map make_elim rls) THEN' atac;
   127 
   136 
   128 (*Like forward_tac, but deletes the assumption after use.*)
   137 (*Like forward_tac, but deletes the assumption after use.*)
   129 fun dresolve_tac rls = eresolve_tac (map make_elim rls);
   138 fun dresolve0_tac rls = eresolve0_tac (map make_elim rls);
       
   139 fun dresolve_tac ctxt rls = eresolve_tac ctxt (map make_elim rls);
   130 
   140 
   131 (*Shorthand versions: for resolution with a single theorem*)
   141 (*Shorthand versions: for resolution with a single theorem*)
   132 fun rtac rl =  resolve_tac [rl];
   142 fun rtac rl =  resolve0_tac [rl];
   133 fun dtac rl = dresolve_tac [rl];
   143 fun dtac rl = dresolve0_tac [rl];
   134 fun etac rl = eresolve_tac [rl];
   144 fun etac rl = eresolve0_tac [rl];
   135 fun ftac rl =  forward_tac [rl];
   145 fun ftac rl =  forward0_tac [rl];
   136 
   146 
   137 (*Use an assumption or some rules ... A popular combination!*)
   147 (*Use an assumption or some rules ... A popular combination!*)
   138 fun ares_tac rules = atac  ORELSE'  resolve_tac rules;
   148 fun ares_tac rules = atac  ORELSE'  resolve0_tac rules;
   139 
   149 
   140 fun solve_tac rules = resolve_tac rules THEN_ALL_NEW atac;
   150 fun solve_tac ctxt rules = resolve_tac ctxt rules THEN_ALL_NEW assume_tac ctxt;
   141 
   151 
   142 (*Matching tactics -- as above, but forbid updating of state*)
   152 (*Matching tactics -- as above, but forbid updating of state*)
   143 fun bimatch_tac ctxt brules i = PRIMSEQ (Thm.biresolution (SOME ctxt) true brules i);
   153 fun bimatch_tac ctxt brules i = PRIMSEQ (Thm.biresolution (SOME ctxt) true brules i);
   144 fun match_tac ctxt rules = bimatch_tac ctxt (map (pair false) rules);
   154 fun match_tac ctxt rules = bimatch_tac ctxt (map (pair false) rules);
   145 fun ematch_tac ctxt rules = bimatch_tac ctxt (map (pair true) rules);
   155 fun ematch_tac ctxt rules = bimatch_tac ctxt (map (pair true) rules);
   173 
   183 
   174 (*** Applications of cut_rl ***)
   184 (*** Applications of cut_rl ***)
   175 
   185 
   176 (*The conclusion of the rule gets assumed in subgoal i,
   186 (*The conclusion of the rule gets assumed in subgoal i,
   177   while subgoal i+1,... are the premises of the rule.*)
   187   while subgoal i+1,... are the premises of the rule.*)
   178 fun cut_tac rule i = resolve_tac [cut_rl] i THEN resolve_tac [rule] (i + 1);
   188 fun cut_tac rule i = resolve0_tac [cut_rl] i THEN resolve0_tac [rule] (i + 1);
   179 
   189 
   180 (*"Cut" a list of rules into the goal.  Their premises will become new
   190 (*"Cut" a list of rules into the goal.  Their premises will become new
   181   subgoals.*)
   191   subgoals.*)
   182 fun cut_rules_tac ths i = EVERY (map (fn th => cut_tac th i) ths);
   192 fun cut_rules_tac ths i = EVERY (map (fn th => cut_tac th i) ths);
   183 
   193 
   298 
   308 
   299 (*Rotates the given subgoal to be the first.*)
   309 (*Rotates the given subgoal to be the first.*)
   300 fun prefer_tac i = PRIMITIVE (Thm.permute_prems (i - 1) 1 #> Thm.permute_prems 0 ~1);
   310 fun prefer_tac i = PRIMITIVE (Thm.permute_prems (i - 1) 1 #> Thm.permute_prems 0 ~1);
   301 
   311 
   302 (* remove premises that do not satisfy p; fails if all prems satisfy p *)
   312 (* remove premises that do not satisfy p; fails if all prems satisfy p *)
   303 fun filter_prems_tac p =
   313 fun filter_prems_tac ctxt p =
   304   let fun Then NONE tac = SOME tac
   314   let fun Then NONE tac = SOME tac
   305         | Then (SOME tac) tac' = SOME(tac THEN' tac');
   315         | Then (SOME tac) tac' = SOME(tac THEN' tac');
   306       fun thins H (tac,n) =
   316       fun thins H (tac,n) =
   307         if p H then (tac,n+1)
   317         if p H then (tac,n+1)
   308         else (Then tac (rotate_tac n THEN' eresolve_tac [thin_rl]),0);
   318         else (Then tac (rotate_tac n THEN' eresolve_tac ctxt [thin_rl]),0);
   309   in SUBGOAL(fn (subg,n) =>
   319   in SUBGOAL(fn (subg,n) =>
   310        let val Hs = Logic.strip_assums_hyp subg
   320        let val Hs = Logic.strip_assums_hyp subg
   311        in case fst(fold thins Hs (NONE,0)) of
   321        in case fst(fold thins Hs (NONE,0)) of
   312             NONE => no_tac | SOME tac => tac n
   322             NONE => no_tac | SOME tac => tac n
   313        end)
   323        end)