28 val sign_term : term -> cterm |
28 val sign_term : term -> cterm |
29 |
29 |
30 val v_elem_at : vector -> int -> string option |
30 val v_elem_at : vector -> int -> string option |
31 val m_elem_at : matrix -> int -> vector option |
31 val m_elem_at : matrix -> int -> vector option |
32 val v_only_elem : vector -> int option |
32 val v_only_elem : vector -> int option |
33 val v_fold : ('a * (int * string) -> 'a) -> 'a -> vector -> 'a |
33 val v_fold : (int * string -> 'a -> 'a) -> vector -> 'a -> 'a |
34 val m_fold : ('a * (int * vector) -> 'a) -> 'a -> matrix -> 'a |
34 val m_fold : (int * vector -> 'a -> 'a) -> matrix -> 'a -> 'a |
35 |
35 |
36 val transpose_matrix : matrix -> matrix |
36 val transpose_matrix : matrix -> matrix |
37 |
37 |
38 val cut_vector : int -> vector -> vector |
38 val cut_vector : int -> vector -> vector |
39 val cut_matrix : vector -> (int option) -> matrix -> matrix |
39 val cut_matrix : vector -> (int option) -> matrix -> matrix |
127 |
127 |
128 fun cons_spmat h t = Cons_spmat_const $ h $ t |
128 fun cons_spmat h t = Cons_spmat_const $ h $ t |
129 |
129 |
130 fun approx_vector_term prec pprt vector = |
130 fun approx_vector_term prec pprt vector = |
131 let |
131 let |
132 fun app ((vlower, vupper), (index, s)) = |
132 fun app (index, s) (vlower, vupper) = |
133 let |
133 let |
134 val (flower, fupper) = approx_value_term prec pprt s |
134 val (flower, fupper) = approx_value_term prec pprt s |
135 val index = mk_intinf HOLogic.natT (IntInf.fromInt index) |
135 val index = mk_intinf HOLogic.natT (IntInf.fromInt index) |
136 val elower = HOLogic.mk_prod (index, flower) |
136 val elower = HOLogic.mk_prod (index, flower) |
137 val eupper = HOLogic.mk_prod (index, fupper) |
137 val eupper = HOLogic.mk_prod (index, fupper) |
138 in |
138 in |
139 (Cons_spvec_const $ elower $ vlower, |
139 (Cons_spvec_const $ elower $ vlower, |
140 Cons_spvec_const $ eupper $ vupper) |
140 Cons_spvec_const $ eupper $ vupper) |
141 end |
141 end |
142 in |
142 in |
143 Inttab.foldl app ((empty_vector_const, empty_vector_const), vector) |
143 Inttab.fold app vector (empty_vector_const, empty_vector_const) |
144 end |
144 end |
145 |
145 |
146 fun approx_matrix_term prec pprt matrix = |
146 fun approx_matrix_term prec pprt matrix = |
147 let |
147 let |
148 fun app ((mlower, mupper), (index, vector)) = |
148 fun app (index, vector) (mlower, mupper) = |
149 let |
149 let |
150 val (vlower, vupper) = approx_vector_term prec pprt vector |
150 val (vlower, vupper) = approx_vector_term prec pprt vector |
151 val index = mk_intinf HOLogic.natT (IntInf.fromInt index) |
151 val index = mk_intinf HOLogic.natT (IntInf.fromInt index) |
152 val elower = HOLogic.mk_prod (index, vlower) |
152 val elower = HOLogic.mk_prod (index, vlower) |
153 val eupper = HOLogic.mk_prod (index, vupper) |
153 val eupper = HOLogic.mk_prod (index, vupper) |
154 in |
154 in |
155 (Cons_spmat_const $ elower $ mlower, |
155 (Cons_spmat_const $ elower $ mlower, Cons_spmat_const $ eupper $ mupper) |
156 Cons_spmat_const $ eupper $ mupper) |
156 end |
157 end |
157 val (mlower, mupper) = Inttab.fold app matrix (empty_matrix_const, empty_matrix_const) |
158 |
158 in Inttab.fold app matrix (empty_matrix_const, empty_matrix_const) end; |
159 val (mlower, mupper) = Inttab.foldl app ((empty_matrix_const, empty_matrix_const), matrix) |
|
160 in |
|
161 Inttab.foldl app ((empty_matrix_const, empty_matrix_const), matrix) |
|
162 end |
|
163 |
159 |
164 fun approx_vector prec pprt vector = |
160 fun approx_vector prec pprt vector = |
165 let |
161 let |
166 val (l, u) = approx_vector_term prec pprt vector |
162 val (l, u) = approx_vector_term prec pprt vector |
167 in |
163 in |
202 (* dual stuff *) |
198 (* dual stuff *) |
203 |
199 |
204 structure cplex = Cplex |
200 structure cplex = Cplex |
205 |
201 |
206 fun transpose_matrix matrix = |
202 fun transpose_matrix matrix = |
207 let |
203 let |
208 fun upd m j i x = |
204 fun upd j (i, s) = |
209 case Inttab.lookup m j of |
205 Inttab.map_default (i, Inttab.empty) (Inttab.update (j, s)); |
210 SOME v => Inttab.update (j, Inttab.update (i, x) v) m |
206 fun updm (j, v) = Inttab.fold (upd j) v; |
211 | NONE => Inttab.update (j, Inttab.update (i, x) Inttab.empty) m |
207 in Inttab.fold updm matrix empty_matrix end; |
212 |
|
213 fun updv j (m, (i, s)) = upd m i j s |
|
214 |
|
215 fun updm (m, (j, v)) = Inttab.foldl (updv j) (m, v) |
|
216 in |
|
217 Inttab.foldl updm (empty_matrix, matrix) |
|
218 end |
|
219 |
208 |
220 exception No_name of string; |
209 exception No_name of string; |
221 |
210 |
222 exception Superfluous_constr_right_hand_sides |
211 exception Superfluous_constr_right_hand_sides |
223 |
212 |
249 in |
238 in |
250 if p then prod else cplex.cplexNeg prod |
239 if p then prod else cplex.cplexNeg prod |
251 end |
240 end |
252 |
241 |
253 fun vec2sum vector = |
242 fun vec2sum vector = |
254 cplex.cplexSum (Inttab.foldl (fn (list, (index, s)) => (mk_term index s)::list) ([], vector)) |
243 cplex.cplexSum (Inttab.fold (fn (index, s) => fn list => (mk_term index s) :: list) vector []) |
255 |
244 |
256 fun mk_constr index vector c = |
245 fun mk_constr index vector c = |
257 let |
246 let |
258 val s = case Inttab.lookup c index of SOME s => s | NONE => "0" |
247 val s = case Inttab.lookup c index of SOME s => s | NONE => "0" |
259 val (p, s) = split_numstr s |
248 val (p, s) = split_numstr s |
262 (NONE, cplex.cplexConstr (cplex.cplexLeq, (vec2sum vector, num))) |
251 (NONE, cplex.cplexConstr (cplex.cplexLeq, (vec2sum vector, num))) |
263 end |
252 end |
264 |
253 |
265 fun delete index c = Inttab.delete index c handle Inttab.UNDEF _ => c |
254 fun delete index c = Inttab.delete index c handle Inttab.UNDEF _ => c |
266 |
255 |
267 val (list, b) = Inttab.foldl |
256 val (list, b) = Inttab.fold |
268 (fn ((list, c), (index, v)) => ((mk_constr index v c)::list, delete index c)) |
257 (fn (index, v) => fn (list, c) => ((mk_constr index v c)::list, delete index c)) |
269 (([], b), A) |
258 A ([], b) |
270 val _ = if Inttab.is_empty b then () else raise Superfluous_constr_right_hand_sides |
259 val _ = if Inttab.is_empty b then () else raise Superfluous_constr_right_hand_sides |
271 |
260 |
272 fun mk_free y = cplex.cplexBounds (cplex.cplexNeg cplex.cplexInf, cplex.cplexLeq, |
261 fun mk_free y = cplex.cplexBounds (cplex.cplexNeg cplex.cplexInf, cplex.cplexLeq, |
273 cplex.cplexVar y, cplex.cplexLeq, |
262 cplex.cplexVar y, cplex.cplexLeq, |
274 cplex.cplexInf) |
263 cplex.cplexInf) |
275 |
264 |
276 val yvars = Inttab.foldl (fn (l, (i, y)) => (mk_free y)::l) ([], !ytable) |
265 val yvars = Inttab.fold (fn (i, y) => fn l => (mk_free y)::l) (!ytable) [] |
277 |
266 |
278 val prog = cplex.cplexProg ("original", cplex.cplexMaximize (vec2sum c), list, yvars) |
267 val prog = cplex.cplexProg ("original", cplex.cplexMaximize (vec2sum c), list, yvars) |
279 in |
268 in |
280 (prog, indexof) |
269 (prog, indexof) |
281 end |
270 end |
302 in |
291 in |
303 if p then prod else cplex.cplexNeg prod |
292 if p then prod else cplex.cplexNeg prod |
304 end |
293 end |
305 |
294 |
306 fun vec2sum vector = |
295 fun vec2sum vector = |
307 cplex.cplexSum (Inttab.foldl (fn (list, (index, s)) => (mk_term index s)::list) ([], vector)) |
296 cplex.cplexSum (Inttab.fold (fn (index, s) => fn list => (mk_term index s)::list) vector []) |
308 |
297 |
309 fun mk_constr index vector c = |
298 fun mk_constr index vector c = |
310 let |
299 let |
311 val s = case Inttab.lookup c index of SOME s => s | NONE => "0" |
300 val s = case Inttab.lookup c index of SOME s => s | NONE => "0" |
312 val (p, s) = split_numstr s |
301 val (p, s) = split_numstr s |
315 (NONE, cplex.cplexConstr (cplex.cplexEq, (vec2sum vector, num))) |
304 (NONE, cplex.cplexConstr (cplex.cplexEq, (vec2sum vector, num))) |
316 end |
305 end |
317 |
306 |
318 fun delete index c = Inttab.delete index c handle Inttab.UNDEF _ => c |
307 fun delete index c = Inttab.delete index c handle Inttab.UNDEF _ => c |
319 |
308 |
320 val (list, c) = Inttab.foldl |
309 val (list, c) = Inttab.fold |
321 (fn ((list, c), (index, v)) => ((mk_constr index v c)::list, delete index c)) |
310 (fn (index, v) => fn (list, c) => ((mk_constr index v c)::list, delete index c)) |
322 (([], c), transpose_matrix A) |
311 (transpose_matrix A) ([], c) |
323 val _ = if Inttab.is_empty c then () else raise Superfluous_constr_right_hand_sides |
312 val _ = if Inttab.is_empty c then () else raise Superfluous_constr_right_hand_sides |
324 |
313 |
325 val prog = cplex.cplexProg ("dual", cplex.cplexMinimize (vec2sum b), list, []) |
314 val prog = cplex.cplexProg ("dual", cplex.cplexMinimize (vec2sum b), list, []) |
326 in |
315 in |
327 (prog, indexof) |
316 (prog, indexof) |
328 end |
317 end |
329 |
318 |
330 fun cut_vector size v = |
319 fun cut_vector size v = |
331 let |
320 let |
332 val count = ref 0 |
321 val count = ref 0; |
333 fun app (v, (i, s)) = |
322 fun app (i, s) = if (!count < size) then |
334 if (!count < size) then |
323 (count := !count +1 ; Inttab.update (i, s)) |
335 (count := !count +1 ; Inttab.update (i,s) v) |
324 else I |
336 else |
325 in |
337 v |
326 Inttab.fold app v empty_vector |
338 in |
327 end |
339 Inttab.foldl app (empty_vector, v) |
|
340 end |
|
341 |
328 |
342 fun cut_matrix vfilter vsize m = |
329 fun cut_matrix vfilter vsize m = |
343 let |
330 let |
344 fun app (m, (i, v)) = |
331 fun app (i, v) = |
345 if Inttab.lookup vfilter i = NONE then |
332 if is_none (Inttab.lookup vfilter i) then I |
346 m |
333 else case vsize |
347 else |
334 of NONE => Inttab.update (i, v) |
348 case vsize of |
335 | SOME s => Inttab.update (i, cut_vector s v) |
349 NONE => Inttab.update (i,v) m |
336 in Inttab.fold app m empty_matrix end |
350 | SOME s => Inttab.update (i, cut_vector s v) m |
337 |
351 in |
|
352 Inttab.foldl app (empty_matrix, m) |
|
353 end |
|
354 |
|
355 fun v_elem_at v i = Inttab.lookup v i |
338 fun v_elem_at v i = Inttab.lookup v i |
356 fun m_elem_at m i = Inttab.lookup m i |
339 fun m_elem_at m i = Inttab.lookup m i |
357 |
340 |
358 fun v_only_elem v = |
341 fun v_only_elem v = |
359 case Inttab.min_key v of |
342 case Inttab.min_key v of |
360 NONE => NONE |
343 NONE => NONE |
361 | SOME vmin => (case Inttab.max_key v of |
344 | SOME vmin => (case Inttab.max_key v of |
362 NONE => SOME vmin |
345 NONE => SOME vmin |
363 | SOME vmax => if vmin = vmax then SOME vmin else NONE) |
346 | SOME vmax => if vmin = vmax then SOME vmin else NONE) |
364 |
347 |
365 fun v_fold f a v = Inttab.foldl f (a,v) |
348 fun v_fold f = Inttab.fold f; |
366 |
349 fun m_fold f = Inttab.fold f; |
367 fun m_fold f a m = Inttab.foldl f (a,m) |
|
368 |
350 |
369 end; |
351 end; |