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 |