src/HOL/Tools/split_rule.ML
changeset 15570 8d8c70b41bab
parent 15531 08c8dad8e399
child 15574 b1d1b5bfc464
equal deleted inserted replaced
15569:1b3115d1a8df 15570:8d8c70b41bab
    64 
    64 
    65 
    65 
    66 (* complete splitting of partially splitted rules *)
    66 (* complete splitting of partially splitted rules *)
    67 
    67 
    68 fun ap_split' (T::Ts) U u = Abs ("v", T, ap_split' Ts U
    68 fun ap_split' (T::Ts) U u = Abs ("v", T, ap_split' Ts U
    69       (ap_split T (flat (map HOLogic.prodT_factors Ts) ---> U)
    69       (ap_split T (List.concat (map HOLogic.prodT_factors Ts) ---> U)
    70         (incr_boundvars 1 u) $ Bound 0))
    70         (incr_boundvars 1 u) $ Bound 0))
    71   | ap_split' _ _ u = u;
    71   | ap_split' _ _ u = u;
    72 
    72 
    73 fun complete_split_rule_var ((t as Var (v, T), ts), (rl, vs)) =
    73 fun complete_split_rule_var ((t as Var (v, T), ts), (rl, vs)) =
    74       let
    74       let
    75         val cterm = Thm.cterm_of (#sign (Thm.rep_thm rl))
    75         val cterm = Thm.cterm_of (#sign (Thm.rep_thm rl))
    76         val (Us', U') = strip_type T;
    76         val (Us', U') = strip_type T;
    77         val Us = take (length ts, Us');
    77         val Us = Library.take (length ts, Us');
    78         val U = drop (length ts, Us') ---> U';
    78         val U = Library.drop (length ts, Us') ---> U';
    79         val T' = flat (map HOLogic.prodT_factors Us) ---> U;
    79         val T' = List.concat (map HOLogic.prodT_factors Us) ---> U;
    80         fun mk_tuple ((xs, insts), v as Var ((a, _), T)) =
    80         fun mk_tuple ((xs, insts), v as Var ((a, _), T)) =
    81               let
    81               let
    82                 val Ts = HOLogic.prodT_factors T;
    82                 val Ts = HOLogic.prodT_factors T;
    83                 val ys = Term.variantlist (replicate (length Ts) a, xs);
    83                 val ys = Term.variantlist (replicate (length Ts) a, xs);
    84               in (xs @ ys, (cterm v, cterm (HOLogic.mk_tuple T
    84               in (xs @ ys, (cterm v, cterm (HOLogic.mk_tuple T
    85                 (map (Var o apfst (rpair 0)) (ys ~~ Ts))))::insts)
    85                 (map (Var o apfst (rpair 0)) (ys ~~ Ts))))::insts)
    86               end
    86               end
    87           | mk_tuple (x, _) = x;
    87           | mk_tuple (x, _) = x;
    88         val newt = ap_split' Us U (Var (v, T'));
    88         val newt = ap_split' Us U (Var (v, T'));
    89         val cterm = Thm.cterm_of (#sign (Thm.rep_thm rl));
    89         val cterm = Thm.cterm_of (#sign (Thm.rep_thm rl));
    90         val (vs', insts) = foldl mk_tuple ((vs, []), ts);
    90         val (vs', insts) = Library.foldl mk_tuple ((vs, []), ts);
    91       in
    91       in
    92         (instantiate ([], [(cterm t, cterm newt)] @ insts) rl, vs')
    92         (instantiate ([], [(cterm t, cterm newt)] @ insts) rl, vs')
    93       end
    93       end
    94   | complete_split_rule_var (_, x) = x;
    94   | complete_split_rule_var (_, x) = x;
    95 
    95 
    96 fun collect_vars (vs, Abs (_, _, t)) = collect_vars (vs, t)
    96 fun collect_vars (vs, Abs (_, _, t)) = collect_vars (vs, t)
    97   | collect_vars (vs, t) = (case strip_comb t of
    97   | collect_vars (vs, t) = (case strip_comb t of
    98         (v as Var _, ts) => (v, ts)::vs
    98         (v as Var _, ts) => (v, ts)::vs
    99       | (t, ts) => foldl collect_vars (vs, ts));
    99       | (t, ts) => Library.foldl collect_vars (vs, ts));
   100 
   100 
   101 
   101 
   102 val split_rule_var = Drule.standard o remove_internal_split o split_rule_var';
   102 val split_rule_var = Drule.standard o remove_internal_split o split_rule_var';
   103 
   103 
   104 (*curries ALL function variables occurring in a rule's conclusion*)
   104 (*curries ALL function variables occurring in a rule's conclusion*)
   105 fun split_rule rl =
   105 fun split_rule rl =
   106   foldr split_rule_var' (Term.term_vars (concl_of rl), rl)
   106   Library.foldr split_rule_var' (Term.term_vars (concl_of rl), rl)
   107   |> remove_internal_split
   107   |> remove_internal_split
   108   |> Drule.standard;
   108   |> Drule.standard;
   109 
   109 
   110 fun complete_split_rule rl =
   110 fun complete_split_rule rl =
   111   fst (foldr complete_split_rule_var
   111   fst (Library.foldr complete_split_rule_var
   112     (collect_vars ([], concl_of rl),
   112     (collect_vars ([], concl_of rl),
   113       (rl, map (fst o fst o dest_Var) (Term.term_vars (#prop (Thm.rep_thm rl))))))
   113       (rl, map (fst o fst o dest_Var) (Term.term_vars (#prop (Thm.rep_thm rl))))))
   114   |> remove_internal_split
   114   |> remove_internal_split
   115   |> Drule.standard
   115   |> Drule.standard
   116   |> RuleCases.save rl;
   116   |> RuleCases.save rl;
   119 val split_rule_ss = HOL_basic_ss addsimps [split_conv, fst_conv, snd_conv];
   119 val split_rule_ss = HOL_basic_ss addsimps [split_conv, fst_conv, snd_conv];
   120 
   120 
   121 fun split_rule_goal xss rl =
   121 fun split_rule_goal xss rl =
   122   let
   122   let
   123     fun one_split i (th, s) = Tactic.rule_by_tactic (pair_tac s i) th;
   123     fun one_split i (th, s) = Tactic.rule_by_tactic (pair_tac s i) th;
   124     fun one_goal (xs, i) th = foldl (one_split i) (th, xs);
   124     fun one_goal (xs, i) th = Library.foldl (one_split i) (th, xs);
   125   in
   125   in
   126     Drule.standard (Simplifier.full_simplify split_rule_ss (Library.foldln one_goal xss rl))
   126     Drule.standard (Simplifier.full_simplify split_rule_ss (Library.foldln one_goal xss rl))
   127     |> RuleCases.save rl
   127     |> RuleCases.save rl
   128   end;
   128   end;
   129 
   129