268 val (consts, matchers) = |
268 val (consts, matchers) = |
269 ListPair.unzip (map (compile_eq match_name) eqs) |
269 ListPair.unzip (map (compile_eq match_name) eqs) |
270 val const = |
270 val const = |
271 case distinct (op =) consts of |
271 case distinct (op =) consts of |
272 [n] => n |
272 [n] => n |
|
273 | [] => fixrec_err "no defining equations for function" |
273 | _ => fixrec_err "all equations in block must define the same function" |
274 | _ => fixrec_err "all equations in block must define the same function" |
274 val vars = |
275 val vars = |
275 case distinct (op = o pairself length) (map fst matchers) of |
276 case distinct (op = o pairself length) (map fst matchers) of |
276 [vars] => vars |
277 [vars] => vars |
277 | _ => fixrec_err "all equations in block must have the same arity" |
278 | _ => fixrec_err "all equations in block must have the same arity" |
335 let |
336 let |
336 val (skips, raw_spec) = ListPair.unzip raw_spec' |
337 val (skips, raw_spec) = ListPair.unzip raw_spec' |
337 val (fixes : ((binding * typ) * mixfix) list, |
338 val (fixes : ((binding * typ) * mixfix) list, |
338 spec : (Attrib.binding * term) list) = |
339 spec : (Attrib.binding * term) list) = |
339 fst (prep_spec raw_fixes raw_spec lthy) |
340 fst (prep_spec raw_fixes raw_spec lthy) |
|
341 val names = map (Binding.name_of o fst o fst) fixes |
|
342 fun check_head name = |
|
343 member (op =) names name orelse |
|
344 fixrec_err ("Illegal equation head. Expected " ^ commas_quote names) |
340 val chead_of_spec = |
345 val chead_of_spec = |
341 chead_of o fst o dest_eqs o Logic.strip_imp_concl o strip_alls o snd |
346 chead_of o fst o dest_eqs o Logic.strip_imp_concl o strip_alls o snd |
342 fun name_of (Free (n, _)) = n |
347 fun name_of (Free (n, _)) = tap check_head n |
343 | name_of _ = fixrec_err ("unknown term") |
348 | name_of _ = fixrec_err ("unknown term") |
344 val all_names = map (name_of o chead_of_spec) spec |
349 val all_names = map (name_of o chead_of_spec) spec |
345 val names = distinct (op =) all_names |
|
346 fun block_of_name n = |
350 fun block_of_name n = |
347 map_filter |
351 map_filter |
348 (fn (m,eq) => if m = n then SOME eq else NONE) |
352 (fn (m,eq) => if m = n then SOME eq else NONE) |
349 (all_names ~~ (spec ~~ skips)) |
353 (all_names ~~ (spec ~~ skips)) |
350 val blocks = map block_of_name names |
354 val blocks = map block_of_name names |