src/HOL/Tools/inductive_codegen.ML
changeset 28537 1e84256d1a8a
parent 27809 a1e409db516b
child 29265 5b4247055bd7
equal deleted inserted replaced
28536:8dccb6035d0f 28537:1e84256d1a8a
   300           [Pretty.brk 1, str "| _ => DSeq.empty)"]
   300           [Pretty.brk 1, str "| _ => DSeq.empty)"]
   301         else [str ")"])))
   301         else [str ")"])))
   302   end;
   302   end;
   303 
   303 
   304 fun modename module s (iss, is) gr =
   304 fun modename module s (iss, is) gr =
   305   let val (gr', id) = if s = "op =" then (gr, ("", "equal"))
   305   let val (id, gr') = if s = @{const_name "op ="} then (("", "equal"), gr)
   306     else mk_const_id module s gr
   306     else mk_const_id module s gr
   307   in (gr', space_implode "__"
   307   in (space_implode "__"
   308     (mk_qual_id module id ::
   308     (mk_qual_id module id ::
   309       map (space_implode "_" o map string_of_int) (List.mapPartial I iss @ [is])))
   309       map (space_implode "_" o map string_of_int) (List.mapPartial I iss @ [is])), gr')
   310   end;
   310   end;
   311 
   311 
   312 fun mk_funcomp brack s k p = (if brack then parens else I)
   312 fun mk_funcomp brack s k p = (if brack then parens else I)
   313   (Pretty.block [Pretty.block ((if k = 0 then [] else [str "("]) @
   313   (Pretty.block [Pretty.block ((if k = 0 then [] else [str "("]) @
   314     separate (Pretty.brk 1) (str s :: replicate k (str "|> ???")) @
   314     separate (Pretty.brk 1) (str s :: replicate k (str "|> ???")) @
   315     (if k = 0 then [] else [str ")"])), Pretty.brk 1, p]);
   315     (if k = 0 then [] else [str ")"])), Pretty.brk 1, p]);
   316 
   316 
   317 fun compile_expr thy defs dep module brack modes (gr, (NONE, t)) =
   317 fun compile_expr thy defs dep module brack modes (NONE, t) gr =
   318       apsnd single (invoke_codegen thy defs dep module brack (gr, t))
   318       apfst single (invoke_codegen thy defs dep module brack t gr)
   319   | compile_expr _ _ _ _ _ _ (gr, (SOME _, Var ((name, _), _))) =
   319   | compile_expr _ _ _ _ _ _ (SOME _, Var ((name, _), _)) gr =
   320       (gr, [str name])
   320       ([str name], gr)
   321   | compile_expr thy defs dep module brack modes (gr, (SOME (Mode (mode, _, ms)), t)) =
   321   | compile_expr thy defs dep module brack modes (SOME (Mode (mode, _, ms)), t) gr =
   322       (case strip_comb t of
   322       (case strip_comb t of
   323          (Const (name, _), args) =>
   323          (Const (name, _), args) =>
   324            if name = "op =" orelse AList.defined op = modes name then
   324            if name = @{const_name "op ="} orelse AList.defined op = modes name then
   325              let
   325              let
   326                val (args1, args2) = chop (length ms) args;
   326                val (args1, args2) = chop (length ms) args;
   327                val (gr', (ps, mode_id)) = foldl_map
   327                val ((ps, mode_id), gr') = gr |> fold_map
   328                    (compile_expr thy defs dep module true modes) (gr, ms ~~ args1) |>>>
   328                    (compile_expr thy defs dep module true modes) (ms ~~ args1)
   329                  modename module name mode;
   329                    ||>> modename module name mode;
   330                val (gr'', ps') = (case mode of
   330                val (ps', gr'') = (case mode of
   331                    ([], []) => (gr', [str "()"])
   331                    ([], []) => ([str "()"], gr')
   332                  | _ => foldl_map
   332                  | _ => fold_map
   333                      (invoke_codegen thy defs dep module true) (gr', args2))
   333                      (invoke_codegen thy defs dep module true) args2 gr')
   334              in (gr', (if brack andalso not (null ps andalso null ps') then
   334              in ((if brack andalso not (null ps andalso null ps') then
   335                single o parens o Pretty.block else I)
   335                single o parens o Pretty.block else I)
   336                  (List.concat (separate [Pretty.brk 1]
   336                  (List.concat (separate [Pretty.brk 1]
   337                    ([str mode_id] :: ps @ map single ps'))))
   337                    ([str mode_id] :: ps @ map single ps'))), gr')
   338              end
   338              end
   339            else apsnd (single o mk_funcomp brack "??" (length (binder_types (fastype_of t))))
   339            else apfst (single o mk_funcomp brack "??" (length (binder_types (fastype_of t))))
   340              (invoke_codegen thy defs dep module true (gr, t))
   340              (invoke_codegen thy defs dep module true t gr)
   341        | _ => apsnd (single o mk_funcomp brack "??" (length (binder_types (fastype_of t))))
   341        | _ => apfst (single o mk_funcomp brack "??" (length (binder_types (fastype_of t))))
   342            (invoke_codegen thy defs dep module true (gr, t)));
   342            (invoke_codegen thy defs dep module true t gr));
   343 
   343 
   344 fun compile_clause thy defs gr dep module all_vs arg_vs modes (iss, is) (ts, ps) inp =
   344 fun compile_clause thy defs dep module all_vs arg_vs modes (iss, is) (ts, ps) inp gr =
   345   let
   345   let
   346     val modes' = modes @ List.mapPartial
   346     val modes' = modes @ List.mapPartial
   347       (fn (_, NONE) => NONE | (v, SOME js) => SOME (v, [([], js)]))
   347       (fn (_, NONE) => NONE | (v, SOME js) => SOME (v, [([], js)]))
   348         (arg_vs ~~ iss);
   348         (arg_vs ~~ iss);
   349 
   349 
   350     fun check_constrt ((names, eqs), t) =
   350     fun check_constrt ((names, eqs), t) =
   351       if is_constrt thy t then ((names, eqs), t) else
   351       if is_constrt thy t then ((names, eqs), t) else
   352         let val s = Name.variant names "x";
   352         let val s = Name.variant names "x";
   353         in ((s::names, (s, t)::eqs), Var ((s, 0), fastype_of t)) end;
   353         in ((s::names, (s, t)::eqs), Var ((s, 0), fastype_of t)) end;
   354 
   354 
   355     fun compile_eq (gr, (s, t)) =
   355     fun compile_eq (s, t) gr =
   356       apsnd (Pretty.block o cons (str (s ^ " = ")) o single)
   356       apfst (Pretty.block o cons (str (s ^ " = ")) o single)
   357         (invoke_codegen thy defs dep module false (gr, t));
   357         (invoke_codegen thy defs dep module false t gr);
   358 
   358 
   359     val (in_ts, out_ts) = get_args is 1 ts;
   359     val (in_ts, out_ts) = get_args is 1 ts;
   360     val ((all_vs', eqs), in_ts') =
   360     val ((all_vs', eqs), in_ts') =
   361       foldl_map check_constrt ((all_vs, []), in_ts);
   361       foldl_map check_constrt ((all_vs, []), in_ts);
   362 
   362 
   363     fun compile_prems out_ts' vs names gr [] =
   363     fun compile_prems out_ts' vs names [] gr =
   364           let
   364           let
   365             val (gr2, out_ps) = foldl_map
   365             val (out_ps, gr2) = fold_map
   366               (invoke_codegen thy defs dep module false) (gr, out_ts);
   366               (invoke_codegen thy defs dep module false) out_ts gr;
   367             val (gr3, eq_ps) = foldl_map compile_eq (gr2, eqs);
   367             val (eq_ps, gr3) = fold_map compile_eq eqs gr2;
   368             val ((names', eqs'), out_ts'') =
   368             val ((names', eqs'), out_ts'') =
   369               foldl_map check_constrt ((names, []), out_ts');
   369               foldl_map check_constrt ((names, []), out_ts');
   370             val (nvs, out_ts''') = foldl_map distinct_v
   370             val (nvs, out_ts''') = foldl_map distinct_v
   371               ((names', map (fn x => (x, [x])) vs), out_ts'');
   371               ((names', map (fn x => (x, [x])) vs), out_ts'');
   372             val (gr4, out_ps') = foldl_map
   372             val (out_ps', gr4) = fold_map
   373               (invoke_codegen thy defs dep module false) (gr3, out_ts''');
   373               (invoke_codegen thy defs dep module false) (out_ts''') gr3;
   374             val (gr5, eq_ps') = foldl_map compile_eq (gr4, eqs')
   374             val (eq_ps', gr5) = fold_map compile_eq eqs' gr4;
   375           in
   375           in
   376             (gr5, compile_match (snd nvs) (eq_ps @ eq_ps') out_ps'
   376             (compile_match (snd nvs) (eq_ps @ eq_ps') out_ps'
   377               (Pretty.block [str "DSeq.single", Pretty.brk 1, mk_tuple out_ps])
   377               (Pretty.block [str "DSeq.single", Pretty.brk 1, mk_tuple out_ps])
   378               (exists (not o is_exhaustive) out_ts'''))
   378               (exists (not o is_exhaustive) out_ts'''), gr5)
   379           end
   379           end
   380       | compile_prems out_ts vs names gr ps =
   380       | compile_prems out_ts vs names ps gr =
   381           let
   381           let
   382             val vs' = distinct (op =) (List.concat (vs :: map term_vs out_ts));
   382             val vs' = distinct (op =) (List.concat (vs :: map term_vs out_ts));
   383             val SOME (p, mode as SOME (Mode (_, js, _))) =
   383             val SOME (p, mode as SOME (Mode (_, js, _))) =
   384               select_mode_prem thy modes' vs' ps;
   384               select_mode_prem thy modes' vs' ps;
   385             val ps' = filter_out (equal p) ps;
   385             val ps' = filter_out (equal p) ps;
   386             val ((names', eqs), out_ts') =
   386             val ((names', eqs), out_ts') =
   387               foldl_map check_constrt ((names, []), out_ts);
   387               foldl_map check_constrt ((names, []), out_ts);
   388             val (nvs, out_ts'') = foldl_map distinct_v
   388             val (nvs, out_ts'') = foldl_map distinct_v
   389               ((names', map (fn x => (x, [x])) vs), out_ts');
   389               ((names', map (fn x => (x, [x])) vs), out_ts');
   390             val (gr0, out_ps) = foldl_map
   390             val (out_ps, gr0) = fold_map
   391               (invoke_codegen thy defs dep module false) (gr, out_ts'');
   391               (invoke_codegen thy defs dep module false) out_ts'' gr;
   392             val (gr1, eq_ps) = foldl_map compile_eq (gr0, eqs)
   392             val (eq_ps, gr1) = fold_map compile_eq eqs gr0;
   393           in
   393           in
   394             (case p of
   394             (case p of
   395                Prem (us, t, is_set) =>
   395                Prem (us, t, is_set) =>
   396                  let
   396                  let
   397                    val (in_ts, out_ts''') = get_args js 1 us;
   397                    val (in_ts, out_ts''') = get_args js 1 us;
   398                    val (gr2, in_ps) = foldl_map
   398                    val (in_ps, gr2) = fold_map
   399                      (invoke_codegen thy defs dep module true) (gr1, in_ts);
   399                      (invoke_codegen thy defs dep module true) in_ts gr1;
   400                    val (gr3, ps) =
   400                    val (ps, gr3) =
   401                      if not is_set then
   401                      if not is_set then
   402                        apsnd (fn ps => ps @
   402                        apfst (fn ps => ps @
   403                            (if null in_ps then [] else [Pretty.brk 1]) @
   403                            (if null in_ps then [] else [Pretty.brk 1]) @
   404                            separate (Pretty.brk 1) in_ps)
   404                            separate (Pretty.brk 1) in_ps)
   405                          (compile_expr thy defs dep module false modes
   405                          (compile_expr thy defs dep module false modes
   406                            (gr2, (mode, t)))
   406                            (mode, t) gr2)
   407                      else
   407                      else
   408                        apsnd (fn p => [str "DSeq.of_list", Pretty.brk 1, p])
   408                        apfst (fn p => [str "DSeq.of_list", Pretty.brk 1, p])
   409                            (invoke_codegen thy defs dep module true (gr2, t));
   409                            (invoke_codegen thy defs dep module true t gr2);
   410                    val (gr4, rest) = compile_prems out_ts''' vs' (fst nvs) gr3 ps';
   410                    val (rest, gr4) = compile_prems out_ts''' vs' (fst nvs) ps' gr3;
   411                  in
   411                  in
   412                    (gr4, compile_match (snd nvs) eq_ps out_ps
   412                    (compile_match (snd nvs) eq_ps out_ps
   413                       (Pretty.block (ps @
   413                       (Pretty.block (ps @
   414                          [str " :->", Pretty.brk 1, rest]))
   414                          [str " :->", Pretty.brk 1, rest]))
   415                       (exists (not o is_exhaustive) out_ts''))
   415                       (exists (not o is_exhaustive) out_ts''), gr4)
   416                  end
   416                  end
   417              | Sidecond t =>
   417              | Sidecond t =>
   418                  let
   418                  let
   419                    val (gr2, side_p) = invoke_codegen thy defs dep module true (gr1, t);
   419                    val (side_p, gr2) = invoke_codegen thy defs dep module true t gr1;
   420                    val (gr3, rest) = compile_prems [] vs' (fst nvs) gr2 ps';
   420                    val (rest, gr3) = compile_prems [] vs' (fst nvs) ps' gr2;
   421                  in
   421                  in
   422                    (gr3, compile_match (snd nvs) eq_ps out_ps
   422                    (compile_match (snd nvs) eq_ps out_ps
   423                       (Pretty.block [str "?? ", side_p,
   423                       (Pretty.block [str "?? ", side_p,
   424                         str " :->", Pretty.brk 1, rest])
   424                         str " :->", Pretty.brk 1, rest])
   425                       (exists (not o is_exhaustive) out_ts''))
   425                       (exists (not o is_exhaustive) out_ts''), gr3)
   426                  end)
   426                  end)
   427           end;
   427           end;
   428 
   428 
   429     val (gr', prem_p) = compile_prems in_ts' arg_vs all_vs' gr ps;
   429     val (prem_p, gr') = compile_prems in_ts' arg_vs all_vs' ps gr ;
   430   in
   430   in
   431     (gr', Pretty.block [str "DSeq.single", Pretty.brk 1, inp,
   431     (Pretty.block [str "DSeq.single", Pretty.brk 1, inp,
   432        str " :->", Pretty.brk 1, prem_p])
   432        str " :->", Pretty.brk 1, prem_p], gr')
   433   end;
   433   end;
   434 
   434 
   435 fun compile_pred thy defs gr dep module prfx all_vs arg_vs modes s cls mode =
   435 fun compile_pred thy defs dep module prfx all_vs arg_vs modes s cls mode gr =
   436   let
   436   let
   437     val xs = map str (Name.variant_list arg_vs
   437     val xs = map str (Name.variant_list arg_vs
   438       (map (fn i => "x" ^ string_of_int i) (snd mode)));
   438       (map (fn i => "x" ^ string_of_int i) (snd mode)));
   439     val (gr', (cl_ps, mode_id)) =
   439     val ((cl_ps, mode_id), gr') = gr |>
   440       foldl_map (fn (gr, cl) => compile_clause thy defs
   440       fold_map (fn cl => compile_clause thy defs
   441         gr dep module all_vs arg_vs modes mode cl (mk_tuple xs)) (gr, cls) |>>>
   441         dep module all_vs arg_vs modes mode cl (mk_tuple xs)) cls ||>>
   442       modename module s mode
   442       modename module s mode
   443   in
   443   in
   444     ((gr', "and "), Pretty.block
   444     (Pretty.block
   445       ([Pretty.block (separate (Pretty.brk 1)
   445       ([Pretty.block (separate (Pretty.brk 1)
   446          (str (prfx ^ mode_id) ::
   446          (str (prfx ^ mode_id) ::
   447            map str arg_vs @
   447            map str arg_vs @
   448            (case mode of ([], []) => [str "()"] | _ => xs)) @
   448            (case mode of ([], []) => [str "()"] | _ => xs)) @
   449          [str " ="]),
   449          [str " ="]),
   450         Pretty.brk 1] @
   450         Pretty.brk 1] @
   451        List.concat (separate [str " ++", Pretty.brk 1] (map single cl_ps))))
   451        List.concat (separate [str " ++", Pretty.brk 1] (map single cl_ps))), (gr', "and "))
   452   end;
   452   end;
   453 
   453 
   454 fun compile_preds thy defs gr dep module all_vs arg_vs modes preds =
   454 fun compile_preds thy defs dep module all_vs arg_vs modes preds gr =
   455   let val ((gr', _), prs) = foldl_map (fn ((gr, prfx), (s, cls)) =>
   455   let val (prs, (gr', _)) = fold_map (fn (s, cls) =>
   456     foldl_map (fn ((gr', prfx'), mode) => compile_pred thy defs gr'
   456     fold_map (fn mode => fn (gr', prfx') => compile_pred thy defs
   457       dep module prfx' all_vs arg_vs modes s cls mode)
   457       dep module prfx' all_vs arg_vs modes s cls mode gr')
   458         ((gr, prfx), ((the o AList.lookup (op =) modes) s))) ((gr, "fun "), preds)
   458         (((the o AList.lookup (op =) modes) s))) preds (gr, "fun ")
   459   in
   459   in
   460     (gr', space_implode "\n\n" (map string_of (List.concat prs)) ^ ";\n\n")
   460     (space_implode "\n\n" (map string_of (List.concat prs)) ^ ";\n\n", gr')
   461   end;
   461   end;
   462 
   462 
   463 (**** processing of introduction rules ****)
   463 (**** processing of introduction rules ****)
   464 
   464 
   465 exception Modes of
   465 exception Modes of
   541       val (clauses, arities) = fold add_clause intrs ([], []);
   541       val (clauses, arities) = fold add_clause intrs ([], []);
   542       val modes = constrain modecs
   542       val modes = constrain modecs
   543         (infer_modes thy extra_modes arities arg_vs clauses);
   543         (infer_modes thy extra_modes arities arg_vs clauses);
   544       val _ = print_arities arities;
   544       val _ = print_arities arities;
   545       val _ = print_modes modes;
   545       val _ = print_modes modes;
   546       val (gr'', s) = compile_preds thy defs gr' (hd names) module (terms_vs intrs)
   546       val (s, gr'') = compile_preds thy defs (hd names) module (terms_vs intrs)
   547         arg_vs (modes @ extra_modes) clauses;
   547         arg_vs (modes @ extra_modes) clauses gr';
   548     in
   548     in
   549       (map_node (hd names)
   549       (map_node (hd names)
   550         (K (SOME (Modes (modes, arities)), module, s)) gr'')
   550         (K (SOME (Modes (modes, arities)), module, s)) gr'')
   551     end;
   551     end;
   552 
   552 
   554   (modes_of modes u handle Option => []) of
   554   (modes_of modes u handle Option => []) of
   555      NONE => codegen_error gr dep
   555      NONE => codegen_error gr dep
   556        ("No such mode for " ^ s ^ ": " ^ string_of_mode ([], is))
   556        ("No such mode for " ^ s ^ ": " ^ string_of_mode ([], is))
   557    | mode => mode);
   557    | mode => mode);
   558 
   558 
   559 fun mk_ind_call thy defs gr dep module is_query s T ts names thyname k intrs =
   559 fun mk_ind_call thy defs dep module is_query s T ts names thyname k intrs gr =
   560   let
   560   let
   561     val (ts1, ts2) = chop k ts;
   561     val (ts1, ts2) = chop k ts;
   562     val u = list_comb (Const (s, T), ts1);
   562     val u = list_comb (Const (s, T), ts1);
   563 
   563 
   564     fun mk_mode (((ts, mode), i), Const ("dummy_pattern", _)) =
   564     fun mk_mode (((ts, mode), i), Const ("dummy_pattern", _)) =
   572     val (modes, _) = lookup_modes gr1 dep;
   572     val (modes, _) = lookup_modes gr1 dep;
   573     val (ts', is) = if is_query then
   573     val (ts', is) = if is_query then
   574         fst (Library.foldl mk_mode ((([], []), 1), ts2))
   574         fst (Library.foldl mk_mode ((([], []), 1), ts2))
   575       else (ts2, 1 upto length (binder_types T) - k);
   575       else (ts2, 1 upto length (binder_types T) - k);
   576     val mode = find_mode gr1 dep s u modes is;
   576     val mode = find_mode gr1 dep s u modes is;
   577     val (gr2, in_ps) = foldl_map
   577     val (in_ps, gr2) = fold_map (invoke_codegen thy defs dep module true) ts' gr1;
   578       (invoke_codegen thy defs dep module true) (gr1, ts');
   578     val (ps, gr3) = compile_expr thy defs dep module false modes (mode, u) gr2;
   579     val (gr3, ps) =
       
   580       compile_expr thy defs dep module false modes (gr2, (mode, u))
       
   581   in
   579   in
   582     (gr3, Pretty.block (ps @ (if null in_ps then [] else [Pretty.brk 1]) @
   580     (Pretty.block (ps @ (if null in_ps then [] else [Pretty.brk 1]) @
   583        separate (Pretty.brk 1) in_ps))
   581        separate (Pretty.brk 1) in_ps), gr3)
   584   end;
   582   end;
   585 
   583 
   586 fun clause_of_eqn eqn =
   584 fun clause_of_eqn eqn =
   587   let
   585   let
   588     val (t, u) = HOLogic.dest_eq (HOLogic.dest_Trueprop (concl_of eqn));
   586     val (t, u) = HOLogic.dest_eq (HOLogic.dest_Trueprop (concl_of eqn));
   600       val clauses = map clause_of_eqn eqns;
   598       val clauses = map clause_of_eqn eqns;
   601       val pname = name ^ "_aux";
   599       val pname = name ^ "_aux";
   602       val arity = length (snd (strip_comb (fst (HOLogic.dest_eq
   600       val arity = length (snd (strip_comb (fst (HOLogic.dest_eq
   603         (HOLogic.dest_Trueprop (concl_of (hd eqns)))))));
   601         (HOLogic.dest_Trueprop (concl_of (hd eqns)))))));
   604       val mode = 1 upto arity;
   602       val mode = 1 upto arity;
   605       val (gr', (fun_id, mode_id)) = gr |>
   603       val ((fun_id, mode_id), gr') = gr |>
   606         mk_const_id module' name |>>>
   604         mk_const_id module' name ||>>
   607         modename module' pname ([], mode);
   605         modename module' pname ([], mode);
   608       val vars = map (fn i => str ("x" ^ string_of_int i)) mode;
   606       val vars = map (fn i => str ("x" ^ string_of_int i)) mode;
   609       val s = string_of (Pretty.block
   607       val s = string_of (Pretty.block
   610         [mk_app false (str ("fun " ^ snd fun_id)) vars, str " =",
   608         [mk_app false (str ("fun " ^ snd fun_id)) vars, str " =",
   611          Pretty.brk 1, str "DSeq.hd", Pretty.brk 1,
   609          Pretty.brk 1, str "DSeq.hd", Pretty.brk 1,
   615         (new_node (name, (NONE, module', s)) gr')) name [pname] module'
   613         (new_node (name, (NONE, module', s)) gr')) name [pname] module'
   616         [(pname, [([], mode)])] clauses 0;
   614         [(pname, [([], mode)])] clauses 0;
   617       val (modes, _) = lookup_modes gr'' dep;
   615       val (modes, _) = lookup_modes gr'' dep;
   618       val _ = find_mode gr'' dep pname (head_of (HOLogic.dest_Trueprop
   616       val _ = find_mode gr'' dep pname (head_of (HOLogic.dest_Trueprop
   619         (Logic.strip_imp_concl (hd clauses)))) modes mode
   617         (Logic.strip_imp_concl (hd clauses)))) modes mode
   620     in (gr'', mk_qual_id module fun_id) end
   618     in (mk_qual_id module fun_id, gr'') end
   621   | SOME _ =>
   619   | SOME _ =>
   622       (add_edge (name, dep) gr, mk_qual_id module (get_const_id name gr));
   620       (mk_qual_id module (get_const_id gr name), add_edge (name, dep) gr);
   623 
   621 
   624 (* convert n-tuple to nested pairs *)
   622 (* convert n-tuple to nested pairs *)
   625 
   623 
   626 fun conv_ntuple fs ts p =
   624 fun conv_ntuple fs ts p =
   627   let
   625   let
   642          mk_tuple xs', str " =>", Pretty.brk 1, fst (conv xs []),
   640          mk_tuple xs', str " =>", Pretty.brk 1, fst (conv xs []),
   643          str ")", Pretty.brk 1, parens p]
   641          str ")", Pretty.brk 1, parens p]
   644     else p
   642     else p
   645   end;
   643   end;
   646 
   644 
   647 fun inductive_codegen thy defs gr dep module brack t = (case strip_comb t of
   645 fun inductive_codegen thy defs dep module brack t gr  = (case strip_comb t of
   648     (Const ("Collect", _), [u]) =>
   646     (Const ("Collect", _), [u]) =>
   649       let val (r, Ts, fs) = HOLogic.strip_split u
   647       let val (r, Ts, fs) = HOLogic.strip_split u
   650       in case strip_comb r of
   648       in case strip_comb r of
   651           (Const (s, T), ts) =>
   649           (Const (s, T), ts) =>
   652             (case (get_clauses thy s, get_assoc_code thy (s, T)) of
   650             (case (get_clauses thy s, get_assoc_code thy (s, T)) of
   659                   val no_loose = forall (fn t => not (loose_bvar (t, 0)))
   657                   val no_loose = forall (fn t => not (loose_bvar (t, 0)))
   660                 in
   658                 in
   661                   if null (duplicates op = ots) andalso
   659                   if null (duplicates op = ots) andalso
   662                     no_loose ts1 andalso no_loose its
   660                     no_loose ts1 andalso no_loose its
   663                   then
   661                   then
   664                     let val (gr', call_p) = mk_ind_call thy defs gr dep module true
   662                     let val (call_p, gr') = mk_ind_call thy defs dep module true
   665                       s T (ts1 @ ts2') names thyname k intrs
   663                       s T (ts1 @ ts2') names thyname k intrs gr 
   666                     in SOME (gr', (if brack then parens else I) (Pretty.block
   664                     in SOME ((if brack then parens else I) (Pretty.block
   667                       [str "DSeq.list_of", Pretty.brk 1, str "(",
   665                       [str "DSeq.list_of", Pretty.brk 1, str "(",
   668                        conv_ntuple fs ots call_p, str ")"]))
   666                        conv_ntuple fs ots call_p, str ")"]), gr')
   669                     end
   667                     end
   670                   else NONE
   668                   else NONE
   671                 end
   669                 end
   672             | _ => NONE)
   670             | _ => NONE)
   673         | _ => NONE
   671         | _ => NONE
   674       end
   672       end
   675   | (Const (s, T), ts) => (case Symtab.lookup (#eqns (CodegenData.get thy)) s of
   673   | (Const (s, T), ts) => (case Symtab.lookup (#eqns (CodegenData.get thy)) s of
   676       NONE => (case (get_clauses thy s, get_assoc_code thy (s, T)) of
   674       NONE => (case (get_clauses thy s, get_assoc_code thy (s, T)) of
   677         (SOME (names, thyname, k, intrs), NONE) =>
   675         (SOME (names, thyname, k, intrs), NONE) =>
   678           if length ts < k then NONE else SOME
   676           if length ts < k then NONE else SOME
   679             (let val (gr', call_p) = mk_ind_call thy defs gr dep module false
   677             (let val (call_p, gr') = mk_ind_call thy defs dep module false
   680                s T (map Term.no_dummy_patterns ts) names thyname k intrs
   678                s T (map Term.no_dummy_patterns ts) names thyname k intrs gr
   681              in (gr', mk_funcomp brack "?!"
   679              in (mk_funcomp brack "?!"
   682                (length (binder_types T) - length ts) (parens call_p))
   680                (length (binder_types T) - length ts) (parens call_p), gr')
   683              end handle TERM _ => mk_ind_call thy defs gr dep module true
   681              end handle TERM _ => mk_ind_call thy defs dep module true
   684                s T ts names thyname k intrs)
   682                s T ts names thyname k intrs gr )
   685       | _ => NONE)
   683       | _ => NONE)
   686     | SOME eqns =>
   684     | SOME eqns =>
   687         let
   685         let
   688           val (_, thyname) :: _ = eqns;
   686           val (_, thyname) :: _ = eqns;
   689           val (gr', id) = mk_fun thy defs s (preprocess thy (map fst (rev eqns)))
   687           val (id, gr') = mk_fun thy defs s (preprocess thy (map fst (rev eqns)))
   690             dep module (if_library thyname module) gr;
   688             dep module (if_library thyname module) gr;
   691           val (gr'', ps) = foldl_map
   689           val (ps, gr'') = fold_map
   692             (invoke_codegen thy defs dep module true) (gr', ts);
   690             (invoke_codegen thy defs dep module true) ts gr';
   693         in SOME (gr'', mk_app brack (str id) ps)
   691         in SOME (mk_app brack (str id) ps, gr'')
   694         end)
   692         end)
   695   | _ => NONE);
   693   | _ => NONE);
   696 
   694 
   697 val setup =
   695 val setup =
   698   add_codegen "inductive" inductive_codegen #>
   696   add_codegen "inductive" inductive_codegen #>