src/HOL/Tools/coinduction.ML
changeset 59582 0fbed69ff081
parent 59580 cbc38731d42f
child 59621 291934bac95e
equal deleted inserted replaced
59580:cbc38731d42f 59582:0fbed69ff081
    22         if P x then (x :: ins, outs) else (ins, x :: outs)
    22         if P x then (x :: ins, outs) else (ins, x :: outs)
    23       end;
    23       end;
    24 
    24 
    25 fun ALLGOALS_SKIP skip tac st =
    25 fun ALLGOALS_SKIP skip tac st =
    26   let fun doall n = if n = skip then all_tac else tac n THEN doall (n - 1)
    26   let fun doall n = if n = skip then all_tac else tac n THEN doall (n - 1)
    27   in doall (nprems_of st) st  end;
    27   in doall (Thm.nprems_of st) st  end;
    28 
    28 
    29 fun THEN_ALL_NEW_SKIP skip tac1 tac2 i st =
    29 fun THEN_ALL_NEW_SKIP skip tac1 tac2 i st =
    30   st |> (tac1 i THEN (fn st' =>
    30   st |> (tac1 i THEN (fn st' =>
    31     Seq.INTERVAL tac2 (i + skip) (i + nprems_of st' - nprems_of st) st'));
    31     Seq.INTERVAL tac2 (i + skip) (i + Thm.nprems_of st' - Thm.nprems_of st) st'));
    32 
    32 
    33 fun DELETE_PREMS_AFTER skip tac i st =
    33 fun DELETE_PREMS_AFTER skip tac i st =
    34   let
    34   let
    35     val n = nth (prems_of st) (i - 1) |> Logic.strip_assums_hyp |> length;
    35     val n = nth (Thm.prems_of st) (i - 1) |> Logic.strip_assums_hyp |> length;
    36   in
    36   in
    37     (THEN_ALL_NEW_SKIP skip tac (REPEAT_DETERM_N n o eresolve0_tac [thin_rl])) i st
    37     (THEN_ALL_NEW_SKIP skip tac (REPEAT_DETERM_N n o eresolve0_tac [thin_rl])) i st
    38   end;
    38   end;
    39 
    39 
    40 fun coinduction_tac ctxt raw_vars opt_raw_thm prems = HEADGOAL (SUBGOAL_CASES (fn (goal, _, _) =>
    40 fun coinduction_tac ctxt raw_vars opt_raw_thm prems = HEADGOAL (SUBGOAL_CASES (fn (goal, _, _) =>
    54       Object_Logic.rulify_tac ctxt THEN'
    54       Object_Logic.rulify_tac ctxt THEN'
    55       Method.insert_tac prems THEN'
    55       Method.insert_tac prems THEN'
    56       Object_Logic.atomize_prems_tac ctxt THEN'
    56       Object_Logic.atomize_prems_tac ctxt THEN'
    57       DELETE_PREMS_AFTER skip (Subgoal.FOCUS (fn {concl, context = ctxt, params, prems, ...} =>
    57       DELETE_PREMS_AFTER skip (Subgoal.FOCUS (fn {concl, context = ctxt, params, prems, ...} =>
    58         let
    58         let
    59           val vars = raw_vars @ map (term_of o snd) params;
    59           val vars = raw_vars @ map (Thm.term_of o snd) params;
    60           val names_ctxt = ctxt
    60           val names_ctxt = ctxt
    61             |> fold Variable.declare_names vars
    61             |> fold Variable.declare_names vars
    62             |> fold Variable.declare_thm (raw_thm :: prems);
    62             |> fold Variable.declare_thm (raw_thm :: prems);
    63           val thm_concl = Thm.cprop_of raw_thm |> strip_imp_concl;
    63           val thm_concl = Thm.cprop_of raw_thm |> strip_imp_concl;
    64           val (rhoTs, rhots) = Thm.match (thm_concl, concl)
    64           val (rhoTs, rhots) = Thm.match (thm_concl, concl)
    65             |>> map (apply2 typ_of)
    65             |>> map (apply2 Thm.typ_of)
    66             ||> map (apply2 term_of);
    66             ||> map (apply2 Thm.term_of);
    67           val xs = hd (Thm.prems_of raw_thm) |> HOLogic.dest_Trueprop |> strip_comb |> snd
    67           val xs = hd (Thm.prems_of raw_thm) |> HOLogic.dest_Trueprop |> strip_comb |> snd
    68             |> map (subst_atomic_types rhoTs);
    68             |> map (subst_atomic_types rhoTs);
    69           val raw_eqs = map (fn x => (x, AList.lookup op aconv rhots x |> the)) xs;
    69           val raw_eqs = map (fn x => (x, AList.lookup op aconv rhots x |> the)) xs;
    70           val ((names, ctxt), Ts) = map_split (apfst fst o dest_Var o fst) raw_eqs
    70           val ((names, ctxt), Ts) = map_split (apfst fst o dest_Var o fst) raw_eqs
    71             |>> (fn names => Variable.variant_fixes names names_ctxt) ;
    71             |>> (fn names => Variable.variant_fixes names names_ctxt) ;
    72           val eqs =
    72           val eqs =
    73             @{map 3} (fn name => fn T => fn (_, rhs) =>
    73             @{map 3} (fn name => fn T => fn (_, rhs) =>
    74               HOLogic.mk_eq (Free (name, T), rhs))
    74               HOLogic.mk_eq (Free (name, T), rhs))
    75             names Ts raw_eqs;
    75             names Ts raw_eqs;
    76           val phi = eqs @ map (HOLogic.dest_Trueprop o prop_of) prems
    76           val phi = eqs @ map (HOLogic.dest_Trueprop o Thm.prop_of) prems
    77             |> try (Library.foldr1 HOLogic.mk_conj)
    77             |> try (Library.foldr1 HOLogic.mk_conj)
    78             |> the_default @{term True}
    78             |> the_default @{term True}
    79             |> Ctr_Sugar_Util.list_exists_free vars
    79             |> Ctr_Sugar_Util.list_exists_free vars
    80             |> Term.map_abs_vars (Variable.revert_fixed ctxt)
    80             |> Term.map_abs_vars (Variable.revert_fixed ctxt)
    81             |> fold_rev Term.absfree (names ~~ Ts)
    81             |> fold_rev Term.absfree (names ~~ Ts)
   102                      let
   102                      let
   103                        val (init, last) = funpow_yield (p + e - 1) HOLogic.conj_elim inv;
   103                        val (init, last) = funpow_yield (p + e - 1) HOLogic.conj_elim inv;
   104                        val inv_thms = init @ [last];
   104                        val inv_thms = init @ [last];
   105                        val eqs = take e inv_thms;
   105                        val eqs = take e inv_thms;
   106                        fun is_local_var t =
   106                        fun is_local_var t =
   107                          member (fn (t, (_, t')) => t aconv (term_of t')) params t;
   107                          member (fn (t, (_, t')) => t aconv (Thm.term_of t')) params t;
   108                         val (eqs, assms') = filter_in_out (is_local_var o lhs_of_eq o prop_of) eqs;
   108                         val (eqs, assms') =
       
   109                           filter_in_out (is_local_var o lhs_of_eq o Thm.prop_of) eqs;
   109                         val assms = assms' @ drop e inv_thms
   110                         val assms = assms' @ drop e inv_thms
   110                       in
   111                       in
   111                         HEADGOAL (Method.insert_tac (assms @ case_prems)) THEN
   112                         HEADGOAL (Method.insert_tac (assms @ case_prems)) THEN
   112                         Ctr_Sugar_General_Tactics.unfold_thms_tac ctxt eqs
   113                         Ctr_Sugar_General_Tactics.unfold_thms_tac ctxt eqs
   113                       end)) ctxt)))])
   114                       end)) ctxt)))])
   114         end) ctxt) THEN'
   115         end) ctxt) THEN'
   115       K (prune_params_tac ctxt))
   116       K (prune_params_tac ctxt))
   116     #> Seq.maps (fn st =>
   117     #> Seq.maps (fn st =>
   117       CASES (Rule_Cases.make_common (Proof_Context.theory_of ctxt, prop_of st) cases) all_tac st)
   118       CASES (Rule_Cases.make_common (Proof_Context.theory_of ctxt, Thm.prop_of st) cases) all_tac st)
   118   end));
   119   end));
   119 
   120 
   120 local
   121 local
   121 
   122 
   122 val ruleN = "rule"
   123 val ruleN = "rule"