src/HOL/BNF/Tools/bnf_fp_rec_sugar_util.ML
changeset 53893 865da57dee93
parent 53892 c54ebf9dbd34
child 53894 4cb6be538b40
equal deleted inserted replaced
53892:c54ebf9dbd34 53893:865da57dee93
   253   let
   253   let
   254     val thy = Proof_Context.theory_of ctxt;
   254     val thy = Proof_Context.theory_of ctxt;
   255 
   255 
   256     fun check_no_call t = if has_call t then unexpected_corec_call ctxt t else ();
   256     fun check_no_call t = if has_call t then unexpected_corec_call ctxt t else ();
   257 
   257 
   258     fun massage_rec bound_Ts t =
   258     fun massage_abs bound_Ts (Abs (s, T, t)) = massage_abs (T :: bound_Ts) t
       
   259       | massage_abs bound_Ts t = massage_rec bound_Ts t
       
   260     and massage_rec bound_Ts t =
   259       let val typof = curry fastype_of1 bound_Ts in
   261       let val typof = curry fastype_of1 bound_Ts in
   260         (case Term.strip_comb t of
   262         (case Term.strip_comb t of
   261           (Const (@{const_name Let}, _), [arg1, arg2]) =>
   263           (Const (@{const_name Let}, _), [arg1, arg2]) =>
   262           massage_rec bound_Ts (betapply (arg2, arg1))
   264           massage_rec bound_Ts (betapply (arg2, arg1))
   263         | (Const (@{const_name If}, _), obj :: (branches as [then_branch, _])) =>
   265         | (Const (@{const_name If}, _), obj :: (branches as [_, _])) =>
   264           let val branches' = map (massage_rec bound_Ts) branches in
   266           let val branches' = map (massage_rec bound_Ts) branches in
   265             Term.list_comb (If_const (typof (hd branches')) $ tap check_no_call obj, branches')
   267             Term.list_comb (If_const (typof (hd branches')) $ tap check_no_call obj, branches')
   266           end
   268           end
   267         | (Const (c, _), args as _ :: _) =>
   269         | (Const (c, _), args as _ :: _) =>
   268           let val n = num_binder_types (Sign.the_const_type thy c) in
   270           let val n = num_binder_types (Sign.the_const_type thy c) in
   270               (case fastype_of1 (bound_Ts, nth args (n - 1)) of
   272               (case fastype_of1 (bound_Ts, nth args (n - 1)) of
   271                 Type (s, Ts) =>
   273                 Type (s, Ts) =>
   272                 if case_of ctxt s = SOME c then
   274                 if case_of ctxt s = SOME c then
   273                   let
   275                   let
   274                     val (branches, obj_leftovers) = chop n args;
   276                     val (branches, obj_leftovers) = chop n args;
   275                     val branches' = map (massage_rec bound_Ts) branches;
   277                     val branches' = map (massage_abs bound_Ts o Envir.eta_long bound_Ts) branches;
   276                     val casex' = Const (c, map typof branches' ---> map typof obj_leftovers --->
   278                     val casex' = Const (c, map typof branches' ---> map typof obj_leftovers --->
   277                       typof t);
   279                       typof t);
   278                   in
   280                   in
   279                     betapplys (casex', branches' @ tap (List.app check_no_call) obj_leftovers)
   281                     betapplys (casex', branches' @ tap (List.app check_no_call) obj_leftovers)
   280                   end
   282                   end
   368   | NONE => raise Fail "expand_ctr_term");
   370   | NONE => raise Fail "expand_ctr_term");
   369 
   371 
   370 fun expand_corec_code_rhs ctxt has_call bound_Ts t =
   372 fun expand_corec_code_rhs ctxt has_call bound_Ts t =
   371   (case fastype_of1 (bound_Ts, t) of
   373   (case fastype_of1 (bound_Ts, t) of
   372     Type (s, Ts) =>
   374     Type (s, Ts) =>
   373     massage_let_if_case ctxt has_call (fn bound_Ts => fn t =>
   375     massage_let_if_case ctxt has_call (fn _ => fn t =>
   374       if can (dest_ctr ctxt s) t then t else expand_ctr_term ctxt s Ts t) bound_Ts t
   376       if can (dest_ctr ctxt s) t then t else expand_ctr_term ctxt s Ts t) bound_Ts t
   375   | _ => raise Fail "expand_corec_code_rhs");
   377   | _ => raise Fail "expand_corec_code_rhs");
   376 
   378 
   377 fun massage_corec_code_rhs ctxt massage_ctr =
   379 fun massage_corec_code_rhs ctxt massage_ctr =
   378   massage_let_if_case ctxt (K false)
   380   massage_let_if_case ctxt (K false)