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) |