128 {constructor = c', |
128 {constructor = c', |
129 new_formals = gvars, |
129 new_formals = gvars, |
130 names = names, |
130 names = names, |
131 constraints = cnstrts, |
131 constraints = cnstrts, |
132 group = in_group'} :: part cs not_in_group |
132 group = in_group'} :: part cs not_in_group |
133 end |
133 end; |
134 in part constructors rows end; |
134 in part constructors rows end; |
135 |
135 |
136 fun v_to_prfx (prfx, Free v :: pats) = (v :: prfx, pats) |
136 fun v_to_prfx (prfx, Free v :: pats) = (v :: prfx, pats) |
137 | v_to_prfx _ = raise CASE_ERROR ("mk_case: v_to_prfx", ~1); |
137 | v_to_prfx _ = raise CASE_ERROR ("mk_case: v_to_prfx", ~1); |
138 |
138 |
141 |
141 |
142 fun mk_case ctxt ty_match ty_inst type_of used range_ty = |
142 fun mk_case ctxt ty_match ty_inst type_of used range_ty = |
143 let |
143 let |
144 val get_info = Datatype_Data.info_of_constr_permissive (Proof_Context.theory_of ctxt); |
144 val get_info = Datatype_Data.info_of_constr_permissive (Proof_Context.theory_of ctxt); |
145 |
145 |
146 val name = singleton (Name.variant_list used) "a"; |
|
147 fun expand constructors used ty ((_, []), _) = raise CASE_ERROR ("mk_case: expand_var_row", ~1) |
146 fun expand constructors used ty ((_, []), _) = raise CASE_ERROR ("mk_case: expand_var_row", ~1) |
148 | expand constructors used ty (row as ((prfx, p :: ps), (rhs, tag))) = |
147 | expand constructors used ty (row as ((prfx, p :: ps), (rhs, tag))) = |
149 if is_Free p then |
148 if is_Free p then |
150 let |
149 let |
151 val used' = add_row_used row used; |
150 val used' = add_row_used row used; |
152 fun expnd c = |
151 fun expnd c = |
153 let val capp = list_comb (fresh_constr ty_match ty_inst ty used' c) |
152 let val capp = list_comb (fresh_constr ty_match ty_inst ty used' c) |
154 in ((prfx, capp :: ps), (subst_free [(p, capp)] rhs, tag)) end |
153 in ((prfx, capp :: ps), (subst_free [(p, capp)] rhs, tag)) end |
155 in map expnd constructors end |
154 in map expnd constructors end |
156 else [row] |
155 else [row]; |
|
156 |
|
157 val name = singleton (Name.variant_list used) "a"; |
|
158 |
157 fun mk _ [] = raise CASE_ERROR ("no rows", ~1) |
159 fun mk _ [] = raise CASE_ERROR ("no rows", ~1) |
158 | mk [] (((_, []), (tm, tag)) :: _) = ([tag], tm) (* Done *) |
160 | mk [] (((_, []), (tm, tag)) :: _) = ([tag], tm) (* Done *) |
159 | mk path (rows as ((row as ((_, [Free _]), _)) :: _ :: _)) = mk path [row] |
161 | mk path (rows as ((row as ((_, [Free _]), _)) :: _ :: _)) = mk path [row] |
160 | mk (u :: us) (rows as ((_, _ :: _), _) :: _) = |
162 | mk (u :: us) (rows as ((_, _ :: _), _) :: _) = |
161 let val col0 = map (fn ((_, p :: _), (_, i)) => (p, i)) rows in |
163 let val col0 = map (fn ((_, p :: _), (_, i)) => (p, i)) rows in |
275 let |
277 let |
276 val (t', used') = prep_pat t used; |
278 val (t', used') = prep_pat t used; |
277 val (u', used'') = prep_pat u used'; |
279 val (u', used'') = prep_pat u used'; |
278 in (t' $ u', used'') end |
280 in (t' $ u', used'') end |
279 | prep_pat t used = case_error ("Bad pattern: " ^ Syntax.string_of_term ctxt t); |
281 | prep_pat t used = case_error ("Bad pattern: " ^ Syntax.string_of_term ctxt t); |
|
282 |
280 fun dest_case1 (t as Const (@{syntax_const "_case1"}, _) $ l $ r) = |
283 fun dest_case1 (t as Const (@{syntax_const "_case1"}, _) $ l $ r) = |
281 let val (l', cnstrts) = strip_constraints l |
284 let val (l', cnstrts) = strip_constraints l |
282 in ((fst (prep_pat l' (Term.add_free_names t [])), r), cnstrts) end |
285 in ((fst (prep_pat l' (Term.add_free_names t [])), r), cnstrts) end |
283 | dest_case1 t = case_error "dest_case1"; |
286 | dest_case1 t = case_error "dest_case1"; |
|
287 |
284 fun dest_case2 (Const (@{syntax_const "_case2"}, _) $ t $ u) = t :: dest_case2 u |
288 fun dest_case2 (Const (@{syntax_const "_case2"}, _) $ t $ u) = t :: dest_case2 u |
285 | dest_case2 t = [t]; |
289 | dest_case2 t = [t]; |
|
290 |
286 val (cases, cnstrts) = split_list (map dest_case1 (dest_case2 u)); |
291 val (cases, cnstrts) = split_list (map dest_case1 (dest_case2 u)); |
287 val case_tm = |
292 in |
288 make_case_untyped ctxt |
293 make_case_untyped ctxt |
289 (if err then Error else Warning) [] |
294 (if err then Error else Warning) [] |
290 (fold (fn tT => fn t => Syntax.const @{syntax_const "_constrain"} $ t $ tT) |
295 (fold (fn tT => fn t => Syntax.const @{syntax_const "_constrain"} $ t $ tT) |
291 (flat cnstrts) t) cases; |
296 (flat cnstrts) t) cases |
292 in case_tm end |
297 end |
293 | case_tr _ _ _ = case_error "case_tr"; |
298 | case_tr _ _ _ = case_error "case_tr"; |
294 |
299 |
295 val trfun_setup = |
300 val trfun_setup = |
296 Sign.add_advanced_trfuns ([], |
301 Sign.add_advanced_trfuns ([], |
297 [(@{syntax_const "_case_syntax"}, case_tr true)], |
302 [(@{syntax_const "_case_syntax"}, case_tr true)], |