src/HOL/BNF/Tools/bnf_gfp_rec_sugar.ML
changeset 54970 891141de5672
parent 54969 0ac0b6576d21
child 54972 5747fdd4ad3b
equal deleted inserted replaced
54969:0ac0b6576d21 54970:891141de5672
   156         let val n = num_binder_types (Sign.the_const_type thy c) - 1 in
   156         let val n = num_binder_types (Sign.the_const_type thy c) - 1 in
   157           if n >= 0 andalso n < length args then
   157           if n >= 0 andalso n < length args then
   158             (case fastype_of1 (bound_Ts, nth args n) of
   158             (case fastype_of1 (bound_Ts, nth args n) of
   159               Type (s, Ts) =>
   159               Type (s, Ts) =>
   160               (case dest_case ctxt s Ts t of
   160               (case dest_case ctxt s Ts t of
   161                 NONE => apsnd (f conds t)
   161                 SOME (ctr_sugar as {sel_splits = _ :: _, ...}, conds', branches) =>
   162               | SOME (conds', branches) =>
   162                 apfst (cons ctr_sugar) o fold_rev (uncurry fld)
   163                 apfst (cons s) o fold_rev (uncurry fld)
   163                   (map (append conds o conjuncts_s) conds' ~~ branches)
   164                   (map (append conds o conjuncts_s) conds' ~~ branches))
   164               | _ => apsnd (f conds t))
   165             | _ => apsnd (f conds t))
   165             | _ => apsnd (f conds t))
   166           else
   166           else
   167             apsnd (f conds t)
   167             apsnd (f conds t)
   168         end
   168         end
   169       | _ => apsnd (f conds t))
   169       | _ => apsnd (f conds t))
   170   in
   170   in
   171     fld [] t o pair []
   171     fld [] t o pair []
   172   end;
   172   end;
   173 
   173 
   174 fun case_of ctxt = ctr_sugar_of ctxt #> Option.map (fst o dest_Const o #casex);
   174 fun case_of ctxt s =
       
   175   (case ctr_sugar_of ctxt s of
       
   176     SOME {casex = Const (s', _), sel_splits = _ :: _, ...} => SOME s'
       
   177   | _ => NONE);
   175 
   178 
   176 fun massage_let_if_case ctxt has_call massage_leaf =
   179 fun massage_let_if_case ctxt has_call massage_leaf =
   177   let
   180   let
   178     val thy = Proof_Context.theory_of ctxt;
   181     val thy = Proof_Context.theory_of ctxt;
   179 
   182 
   317     val T = fastype_of1 (bound_Ts, t);
   320     val T = fastype_of1 (bound_Ts, t);
   318   in
   321   in
   319     if has_call t then massage_call bound_Ts U T t else build_map_Inl (T, U) $ t
   322     if has_call t then massage_call bound_Ts U T t else build_map_Inl (T, U) $ t
   320   end;
   323   end;
   321 
   324 
   322 val fold_rev_corec_call = fold_rev_let_if_case;
       
   323 
       
   324 fun expand_to_ctr_term ctxt s Ts t =
   325 fun expand_to_ctr_term ctxt s Ts t =
   325   (case ctr_sugar_of ctxt s of
   326   (case ctr_sugar_of ctxt s of
   326     SOME {ctrs, casex, ...} =>
   327     SOME {ctrs, casex, ...} =>
   327     Term.list_comb (mk_case Ts (Type (s, Ts)) casex, map (mk_ctr Ts) ctrs) $ t
   328     Term.list_comb (mk_case Ts (Type (s, Ts)) casex, map (mk_ctr Ts) ctrs) $ t
   328   | NONE => raise Fail "expand_to_ctr_term");
   329   | NONE => raise Fail "expand_to_ctr_term");
   340 
   341 
   341 fun fold_rev_corec_code_rhs ctxt f =
   342 fun fold_rev_corec_code_rhs ctxt f =
   342   snd ooo fold_rev_let_if_case ctxt (fn conds => uncurry (f conds) o Term.strip_comb);
   343   snd ooo fold_rev_let_if_case ctxt (fn conds => uncurry (f conds) o Term.strip_comb);
   343 
   344 
   344 fun case_thms_of_term ctxt bound_Ts t =
   345 fun case_thms_of_term ctxt bound_Ts t =
   345   let
   346   let val (ctr_sugars, _) = fold_rev_let_if_case ctxt (K (K I)) bound_Ts t () in
   346     val (caseT_names, _) = fold_rev_let_if_case ctxt (K (K I)) bound_Ts t ();
       
   347     val ctr_sugars = map (the o ctr_sugar_of ctxt) caseT_names;
       
   348   in
       
   349     (maps #distincts ctr_sugars, maps #discIs ctr_sugars, maps #sel_splits ctr_sugars,
   347     (maps #distincts ctr_sugars, maps #discIs ctr_sugars, maps #sel_splits ctr_sugars,
   350      maps #sel_split_asms ctr_sugars)
   348      maps #sel_split_asms ctr_sugars)
   351   end;
   349   end;
   352 
   350 
   353 fun basic_corec_specs_of ctxt res_T =
   351 fun basic_corec_specs_of ctxt res_T =
   874 
   872 
   875 fun find_corec_calls ctxt has_call basic_ctr_specs ({ctr, sel, rhs_term, ...} : coeqn_data_sel) =
   873 fun find_corec_calls ctxt has_call basic_ctr_specs ({ctr, sel, rhs_term, ...} : coeqn_data_sel) =
   876   let
   874   let
   877     val sel_no = find_first (curry (op =) ctr o #ctr) basic_ctr_specs
   875     val sel_no = find_first (curry (op =) ctr o #ctr) basic_ctr_specs
   878       |> find_index (curry (op =) sel) o #sels o the;
   876       |> find_index (curry (op =) sel) o #sels o the;
   879     fun find t = if has_call t then snd (fold_rev_corec_call ctxt (K cons) [] t []) else [];
   877     fun find t = if has_call t then snd (fold_rev_let_if_case ctxt (K cons) [] t []) else [];
   880   in
   878   in
   881     find rhs_term
   879     find rhs_term
   882     |> K |> nth_map sel_no |> AList.map_entry (op =) ctr
   880     |> K |> nth_map sel_no |> AList.map_entry (op =) ctr
   883   end;
   881   end;
   884 
   882