src/HOL/Tools/split_rule.ML
changeset 60363 5568b16aa477
parent 60362 befdc10ebb42
child 60642 48dd1cefb4ae
equal deleted inserted replaced
60362:befdc10ebb42 60363:5568b16aa477
    51 fun ap_split' (T::Ts) U u = Abs ("v", T, ap_split' Ts U
    51 fun ap_split' (T::Ts) U u = Abs ("v", T, ap_split' Ts U
    52       (ap_split T (maps HOLogic.flatten_tupleT Ts ---> U)
    52       (ap_split T (maps HOLogic.flatten_tupleT Ts ---> U)
    53         (incr_boundvars 1 u) $ Bound 0))
    53         (incr_boundvars 1 u) $ Bound 0))
    54   | ap_split' _ _ u = u;
    54   | ap_split' _ _ u = u;
    55 
    55 
    56 fun complete_split_rule_var (t as Var (v, T), ts) (rl, vs) =
    56 fun complete_split_rule_var ctxt (t as Var (v, T), ts) (rl, vs) =
    57       let
    57       let
    58         val cterm = Thm.global_cterm_of (Thm.theory_of_thm rl)
       
    59         val (Us', U') = strip_type T;
    58         val (Us', U') = strip_type T;
    60         val Us = take (length ts) Us';
    59         val Us = take (length ts) Us';
    61         val U = drop (length ts) Us' ---> U';
    60         val U = drop (length ts) Us' ---> U';
    62         val T' = maps HOLogic.flatten_tupleT Us ---> U;
    61         val T' = maps HOLogic.flatten_tupleT Us ---> U;
    63         fun mk_tuple (v as Var ((a, _), T)) (xs, insts) =
    62         fun mk_tuple (v as Var ((a, _), T)) (xs, insts) =
    64               let
    63               let
    65                 val Ts = HOLogic.flatten_tupleT T;
    64                 val Ts = HOLogic.flatten_tupleT T;
    66                 val ys = Name.variant_list xs (replicate (length Ts) a);
    65                 val ys = Name.variant_list xs (replicate (length Ts) a);
    67               in (xs @ ys, (cterm v, cterm (HOLogic.mk_ptuple (HOLogic.flat_tupleT_paths T) T
    66               in
    68                 (map (Var o apfst (rpair 0)) (ys ~~ Ts))))::insts)
    67                 (xs @ ys,
       
    68                   apply2 (Thm.cterm_of ctxt)
       
    69                     (v, HOLogic.mk_ptuple (HOLogic.flat_tupleT_paths T) T
       
    70                       (map (Var o apfst (rpair 0)) (ys ~~ Ts))) :: insts)
    69               end
    71               end
    70           | mk_tuple _ x = x;
    72           | mk_tuple _ x = x;
    71         val newt = ap_split' Us U (Var (v, T'));
    73         val newt = ap_split' Us U (Var (v, T'));
    72         val cterm = Thm.global_cterm_of (Thm.theory_of_thm rl);
       
    73         val (vs', insts) = fold mk_tuple ts (vs, []);
    74         val (vs', insts) = fold mk_tuple ts (vs, []);
    74       in
    75       in
    75         (Drule.instantiate_normalize ([], [(cterm t, cterm newt)] @ insts) rl, vs')
    76         (Drule.instantiate_normalize ([], [apply2 (Thm.cterm_of ctxt) (t, newt)] @ insts) rl, vs')
    76       end
    77       end
    77   | complete_split_rule_var _ x = x;
    78   | complete_split_rule_var _ _ x = x;
    78 
    79 
    79 fun collect_vars (Abs (_, _, t)) = collect_vars t
    80 fun collect_vars (Abs (_, _, t)) = collect_vars t
    80   | collect_vars t =
    81   | collect_vars t =
    81       (case strip_comb t of
    82       (case strip_comb t of
    82         (v as Var _, ts) => cons (v, ts)
    83         (v as Var _, ts) => cons (v, ts)
    97   let
    98   let
    98     val prop = Thm.prop_of rl;
    99     val prop = Thm.prop_of rl;
    99     val xs = Term.fold_aterms (fn Var ((x, _), _) => insert (op =) x | _ => I) prop [];
   100     val xs = Term.fold_aterms (fn Var ((x, _), _) => insert (op =) x | _ => I) prop [];
   100     val vars = collect_vars prop [];
   101     val vars = collect_vars prop [];
   101   in
   102   in
   102     fst (fold_rev complete_split_rule_var vars (rl, xs))
   103     fst (fold_rev (complete_split_rule_var ctxt) vars (rl, xs))
   103     |> remove_internal_split ctxt
   104     |> remove_internal_split ctxt
   104     |> Drule.export_without_context
   105     |> Drule.export_without_context
   105     |> Rule_Cases.save rl
   106     |> Rule_Cases.save rl
   106   end;
   107   end;
   107 
   108