src/Pure/defs.ML
changeset 19620 ccd6de95f4a6
parent 19613 9bf274ec94cf
child 19624 3b6629701a79
equal deleted inserted replaced
19619:ee1104f972a4 19620:ccd6de95f4a6
    55   Items.default_node (j, ()) #>
    55   Items.default_node (j, ()) #>
    56   Items.add_edge_acyclic (i, j);
    56   Items.add_edge_acyclic (i, j);
    57 
    57 
    58 fun propagate_deps insts deps =
    58 fun propagate_deps insts deps =
    59   let
    59   let
    60     fun insts_of c = map (fn a => Instance (c, a)) (Symtab.lookup_list insts c);
    60     fun inst_item (Constant c) = Symtab.lookup_list insts c
    61     fun inst_edge (Constant c) (Constant d) = fold declare_edge (product (insts_of c) (insts_of d))
    61       | inst_item (Instance _) = [];
    62       | inst_edge (Constant c) j = fold (fn i => declare_edge (i, j)) (insts_of c)
    62     fun inst_edge i j =
    63       | inst_edge i (Constant c) = fold (fn j => declare_edge (i, j)) (insts_of c)
    63       fold declare_edge (tl (product (i :: inst_item i) (j :: inst_item j)));
    64       | inst_edge (Instance _) (Instance _) = I;
       
    65   in Items.fold (fn (i, (_, (_, js))) => fold (inst_edge i) js) deps deps end;
    64   in Items.fold (fn (i, (_, (_, js))) => fold (inst_edge i) js) deps deps end;
    66 
    65 
    67 
    66 
    68 (* specifications *)
    67 (* specifications *)
    69 
    68 
    70 type spec = {is_def: bool, module: string, name: string, lhs: typ, rhs: (string * typ) list};
    69 type spec = {is_def: bool, module: string, name: string, lhs: typ, rhs: (string * typ) list};
    71 
    70 
    72 datatype T = Defs of
    71 datatype T = Defs of
    73  {specs: (bool * spec Inttab.table) Symtab.table,
    72  {specs: (bool * spec Inttab.table) Symtab.table,
    74   insts: string list Symtab.table,
    73   insts: item list Symtab.table,
    75   deps: unit Items.T};
    74   deps: unit Items.T};
    76 
    75 
    77 fun no_overloading_of (Defs {specs, ...}) c =
    76 fun no_overloading_of (Defs {specs, ...}) c =
    78   (case Symtab.lookup specs c of
    77   (case Symtab.lookup specs c of
    79     SOME (b, _) => b
    78     SOME (b, _) => b
   103         " for constant " ^ quote c));
   102         " for constant " ^ quote c));
   104 
   103 
   105 fun cycle_msg css =
   104 fun cycle_msg css =
   106   let
   105   let
   107     fun prt_cycle items = Pretty.block (flat
   106     fun prt_cycle items = Pretty.block (flat
   108       (separate [Pretty.str " -> ", Pretty.brk 1] (map (single o pretty_item) items)));
   107       (separate [Pretty.str " ->", Pretty.brk 1] (map (single o pretty_item) items)));
   109   in Pretty.string_of (Pretty.big_list "Cyclic dependency of constants:" (map prt_cycle css)) end;
   108   in Pretty.string_of (Pretty.big_list "Cyclic dependency of constants:" (map prt_cycle css)) end;
   110 
   109 
   111 
   110 
   112 fun merge
   111 fun merge
   113    (Defs {specs = specs1, insts = insts1, deps = deps1},
   112    (Defs {specs = specs1, insts = insts1, deps = deps1},
   121   in make_defs (specs', insts', items') end;
   120   in make_defs (specs', insts', items') end;
   122 
   121 
   123 
   122 
   124 (* define *)
   123 (* define *)
   125 
   124 
   126 fun struct_less T (Type (_, Us)) = exists (struct_le T) Us
       
   127   | struct_less _ _ = false
       
   128 and struct_le T U = T = U orelse struct_less T U;
       
   129 
       
   130 fun structs_le Ts Us = forall (fn U => exists (fn T => struct_le T U) Ts) Us;
       
   131 fun structs_less Ts Us = Ts <> Us andalso structs_le Ts Us;
       
   132 
       
   133 
       
   134 fun define const_typargs is_def module name lhs rhs defs = defs
   125 fun define const_typargs is_def module name lhs rhs defs = defs
   135     |> map_defs (fn (specs, insts, deps) =>
   126     |> map_defs (fn (specs, insts, deps) =>
   136   let
   127   let
   137     val (c, T) = lhs;
   128     val (c, T) = lhs;
   138     val args = const_typargs lhs;
   129     val args = const_typargs lhs;
   145           (disjoint_specs c spec sps; (no_overloading, Inttab.update spec sps)));
   136           (disjoint_specs c spec sps; (no_overloading, Inttab.update spec sps)));
   146 
   137 
   147     val lhs' = make_item (c, if no_overloading then [] else args);
   138     val lhs' = make_item (c, if no_overloading then [] else args);
   148     val rhs' = rhs |> map_filter (fn (c', T') =>
   139     val rhs' = rhs |> map_filter (fn (c', T') =>
   149       let val args' = const_typargs (c', T') in
   140       let val args' = const_typargs (c', T') in
   150         if structs_less args' args then NONE
   141         if forall Term.is_TVar args' then NONE
   151         else SOME (make_item (c', if no_overloading_of defs c' then [] else args'))
   142         else SOME (make_item (c', if no_overloading_of defs c' then [] else args'))
   152       end);
   143       end);
   153 
   144 
   154     val insts' = insts
   145     val insts' = insts |> fold (fn i as Instance (c, _) =>
   155       |> fold (fn Instance ca => Symtab.insert_list (op =) ca | _ => I) (lhs' :: rhs');
   146         Symtab.insert_list (op =) (c, i) | _ => I) (lhs' :: rhs');
   156     val deps' = deps
   147     val deps' = deps
   157       |> fold (fn r => declare_edge (r, lhs')) rhs'
   148       |> fold (fn r => declare_edge (r, lhs')) rhs'
   158       |> propagate_deps insts'
   149       |> propagate_deps insts'
   159       handle Items.CYCLES cycles =>
   150       handle Items.CYCLES cycles =>
   160         if no_overloading then error (cycle_msg cycles)
   151         if no_overloading then error (cycle_msg cycles)