src/HOL/Matrix/Cplex_tools.ML
changeset 46531 eff798e48efc
parent 43850 7f2cbc713344
equal deleted inserted replaced
46530:d5d14046686f 46531:eff798e48efc
   106   | is_Inf _ = false
   106   | is_Inf _ = false
   107 
   107 
   108 fun is_Var (cplexVar _) = true
   108 fun is_Var (cplexVar _) = true
   109   | is_Var _ = false
   109   | is_Var _ = false
   110 
   110 
   111 fun is_Neg (cplexNeg x ) = true
   111 fun is_Neg (cplexNeg _) = true
   112   | is_Neg _ = false
   112   | is_Neg _ = false
   113 
   113 
   114 fun is_normed_Prod (cplexProd (t1, t2)) =
   114 fun is_normed_Prod (cplexProd (t1, t2)) =
   115     (is_Num t1) andalso (is_Var t2)
   115     (is_Num t1) andalso (is_Var t2)
   116   | is_normed_Prod x = is_Var x
   116   | is_normed_Prod x = is_Var x
   117 
   117 
   118 fun is_normed_Sum (cplexSum ts) =
   118 fun is_normed_Sum (cplexSum ts) =
   119     (ts <> []) andalso forall (modulo_signed is_normed_Prod) ts
   119     (ts <> []) andalso forall (modulo_signed is_normed_Prod) ts
   120   | is_normed_Sum x = modulo_signed is_normed_Prod x
   120   | is_normed_Sum x = modulo_signed is_normed_Prod x
   121 
   121 
   122 fun is_normed_Constr (cplexConstr (c, (t1, t2))) =
   122 fun is_normed_Constr (cplexConstr (_, (t1, t2))) =
   123     (is_normed_Sum t1) andalso (modulo_signed is_Num t2)
   123     (is_normed_Sum t1) andalso (modulo_signed is_Num t2)
   124 
   124 
   125 fun is_Num_or_Inf x = is_Inf x orelse is_Num x
   125 fun is_Num_or_Inf x = is_Inf x orelse is_Num x
   126 
   126 
   127 fun is_normed_Bounds (cplexBounds (t1, c1, t2, c2, t3)) =
   127 fun is_normed_Bounds (cplexBounds (t1, c1, t2, c2, t3)) =
   137      is_Var t2 andalso (modulo_signed is_Num_or_Inf t1))
   137      is_Var t2 andalso (modulo_signed is_Num_or_Inf t1))
   138 
   138 
   139 fun term_of_goal (cplexMinimize x) = x
   139 fun term_of_goal (cplexMinimize x) = x
   140   | term_of_goal (cplexMaximize x) = x
   140   | term_of_goal (cplexMaximize x) = x
   141 
   141 
   142 fun is_normed_cplexProg (cplexProg (name, goal, constraints, bounds)) =
   142 fun is_normed_cplexProg (cplexProg (_, goal, constraints, bounds)) =
   143     is_normed_Sum (term_of_goal goal) andalso
   143     is_normed_Sum (term_of_goal goal) andalso
   144     forall (fn (_,x) => is_normed_Constr x) constraints andalso
   144     forall (fn (_,x) => is_normed_Constr x) constraints andalso
   145     forall is_normed_Bounds bounds
   145     forall is_normed_Bounds bounds
   146 
   146 
   147 fun is_NL s = s = "\n"
   147 fun is_NL s = s = "\n"
   242              (is_blank, TOKEN_BLANK),
   242              (is_blank, TOKEN_BLANK),
   243              (is_num, TOKEN_NUM),
   243              (is_num, TOKEN_NUM),
   244                      (is_delimiter, TOKEN_DELIMITER),
   244                      (is_delimiter, TOKEN_DELIMITER),
   245              (is_cmp, TOKEN_CMP),
   245              (is_cmp, TOKEN_CMP),
   246              (is_symbol, TOKEN_SYMBOL)]
   246              (is_symbol, TOKEN_SYMBOL)]
   247     fun match_helper [] s = (fn x => false, TOKEN_ERROR)
   247     fun match_helper [] s = (fn _ => false, TOKEN_ERROR)
   248       | match_helper (f::fs) s =
   248       | match_helper (f::fs) s =
   249         if ((fst f) s) then f else match_helper fs s
   249         if ((fst f) s) then f else match_helper fs s
   250     fun match s = match_helper flist s
   250     fun match s = match_helper flist s
   251     fun tok s =
   251     fun tok s =
   252         if s = "" then [] else
   252         if s = "" then [] else
   513         if c <> NONE andalso fst (the c) = TOKEN_NL then
   513         if c <> NONE andalso fst (the c) = TOKEN_NL then
   514             skip_NL ()
   514             skip_NL ()
   515         else
   515         else
   516             (pushToken (the c); ())
   516             (pushToken (the c); ())
   517         end
   517         end
   518 
       
   519     fun is_var (cplexVar _) = true
       
   520       | is_var _ = false
       
   521 
   518 
   522     fun make_bounds c t1 t2 =
   519     fun make_bounds c t1 t2 =
   523         cplexBound (t1, c, t2)
   520         cplexBound (t1, c, t2)
   524 
   521 
   525     fun readBound () =
   522     fun readBound () =
   570             end
   567             end
   571         end
   568         end
   572 
   569 
   573     fun readBounds () =
   570     fun readBounds () =
   574         let
   571         let
   575         fun makestring b = "?"
   572         fun makestring _ = "?"
   576         fun readbody () =
   573         fun readbody () =
   577             let
   574             let
   578             val b = readBound ()
   575             val b = readBound ()
   579             in
   576             in
   580             if b = NONE then []
   577             if b = NONE then []
   604     val _ = TextIO.closeIn f
   601     val _ = TextIO.closeIn f
   605     in
   602     in
   606     cplexProg (name, result_Goal, result_ST, result_Bounds)
   603     cplexProg (name, result_Goal, result_ST, result_Bounds)
   607     end
   604     end
   608 
   605 
   609 fun save_cplexFile filename (cplexProg (name, goal, constraints, bounds)) =
   606 fun save_cplexFile filename (cplexProg (_, goal, constraints, bounds)) =
   610     let
   607     let
   611     val f = TextIO.openOut filename
   608     val f = TextIO.openOut filename
   612 
   609 
   613     fun basic_write s = TextIO.output(f, s)
   610     fun basic_write s = TextIO.output(f, s)
   614 
   611 
   742 (* Eliminates all nonfree bounds from the linear program and produces an
   739 (* Eliminates all nonfree bounds from the linear program and produces an
   743    equivalent program with only free bounds
   740    equivalent program with only free bounds
   744    IF for the input program P holds: is_normed_cplexProg P *)
   741    IF for the input program P holds: is_normed_cplexProg P *)
   745 fun elim_nonfree_bounds (cplexProg (name, goal, constraints, bounds)) =
   742 fun elim_nonfree_bounds (cplexProg (name, goal, constraints, bounds)) =
   746     let
   743     let
   747     fun collect_constr_vars (_, cplexConstr (c, (t1,_))) =
   744     fun collect_constr_vars (_, cplexConstr (_, (t1,_))) =
   748         (collect_vars t1)
   745         (collect_vars t1)
   749 
   746 
   750     val cvars = merge (collect_vars (term_of_goal goal))
   747     val cvars = merge (collect_vars (term_of_goal goal))
   751               (mergemap collect_constr_vars constraints)
   748               (mergemap collect_constr_vars constraints)
   752 
   749 
   753     fun collect_lower_bounded_vars
   750     fun collect_lower_bounded_vars
   754         (cplexBounds (t1, c1, cplexVar v, c2, t3)) =
   751         (cplexBounds (_, _, cplexVar v, _, _)) =
   755         singleton v
   752         singleton v
   756       |  collect_lower_bounded_vars
   753       |  collect_lower_bounded_vars
   757          (cplexBound (_, cplexLe, cplexVar v)) =
   754          (cplexBound (_, cplexLe, cplexVar v)) =
   758          singleton v
   755          singleton v
   759       |  collect_lower_bounded_vars
   756       |  collect_lower_bounded_vars
   781         cplexBounds (cplexNeg cplexInf, cplexLeq,
   778         cplexBounds (cplexNeg cplexInf, cplexLeq,
   782              cplexVar v, cplexLeq,
   779              cplexVar v, cplexLeq,
   783              cplexInf)
   780              cplexInf)
   784 
   781 
   785     val pos_constrs = rev (Symtab.fold
   782     val pos_constrs = rev (Symtab.fold
   786                   (fn (k, v) => cons (make_pos_constr k))
   783                   (fn (k, _) => cons (make_pos_constr k))
   787                   positive_vars [])
   784                   positive_vars [])
   788         val bound_constrs = map (pair NONE)
   785         val bound_constrs = map (pair NONE)
   789                 (maps bound2constr bounds)
   786                 (maps bound2constr bounds)
   790     val constraints' = constraints @ pos_constrs @ bound_constrs
   787     val constraints' = constraints @ pos_constrs @ bound_constrs
   791     val bounds' = rev (Symtab.fold (fn (v, _) => cons (make_free_bound v)) cvars []);
   788     val bounds' = rev (Symtab.fold (fn (v, _) => cons (make_free_bound v)) cvars []);
  1168     val name = string_of_int (Time.toMicroseconds (Time.now ()))
  1165     val name = string_of_int (Time.toMicroseconds (Time.now ()))
  1169     val lpname = tmp_file (name^".lp")
  1166     val lpname = tmp_file (name^".lp")
  1170     val resultname = tmp_file (name^".txt")
  1167     val resultname = tmp_file (name^".txt")
  1171     val scriptname = tmp_file (name^".script")
  1168     val scriptname = tmp_file (name^".script")
  1172     val _ = save_cplexFile lpname prog
  1169     val _ = save_cplexFile lpname prog
  1173     val cplex_path = getenv "CPLEX_PATH"
       
  1174     val cplex = if cplex_path = "" then "cplex" else cplex_path
       
  1175     val _ = write_script scriptname lpname resultname
  1170     val _ = write_script scriptname lpname resultname
  1176     val command = (wrap cplex)^" < "^(wrap scriptname)^" > /dev/null"
       
  1177     val answer = "return code " ^ string_of_int (Isabelle_System.bash command)
       
  1178     in
  1171     in
  1179     let
  1172     let
  1180         val result = load_cplexResult resultname
  1173         val result = load_cplexResult resultname
  1181         val _ = OS.FileSys.remove lpname
  1174         val _ = OS.FileSys.remove lpname
  1182         val _ = OS.FileSys.remove resultname
  1175         val _ = OS.FileSys.remove resultname
  1195          | _ => raise (Execute ("LP_SOLVER must be set to CPLEX or to GLPK")))
  1188          | _ => raise (Execute ("LP_SOLVER must be set to CPLEX or to GLPK")))
  1196     | SOLVER_CPLEX => solve_cplex prog
  1189     | SOLVER_CPLEX => solve_cplex prog
  1197     | SOLVER_GLPK => solve_glpk prog
  1190     | SOLVER_GLPK => solve_glpk prog
  1198 
  1191 
  1199 end;
  1192 end;
  1200 
       
  1201 (*
       
  1202 val demofile = "/home/obua/flyspeck/kepler/LP/cplexPent2.lp45"
       
  1203 val demoout = "/home/obua/flyspeck/kepler/LP/test.out"
       
  1204 val demoresult = "/home/obua/flyspeck/kepler/LP/try/test2.sol"
       
  1205 
       
  1206 fun loadcplex () = Cplex.relax_strict_ineqs
       
  1207            (Cplex.load_cplexFile demofile)
       
  1208 
       
  1209 fun writecplex lp = Cplex.save_cplexFile demoout lp
       
  1210 
       
  1211 fun test () =
       
  1212     let
       
  1213     val lp = loadcplex ()
       
  1214     val lp2 = Cplex.elim_nonfree_bounds lp
       
  1215     in
       
  1216     writecplex lp2
       
  1217     end
       
  1218 
       
  1219 fun loadresult () = Cplex.load_cplexResult demoresult;
       
  1220 *)
       
  1221 
       
  1222 (*val prog = Cplex.load_cplexFile "/home/obua/tmp/pent/graph_0.lpt";
       
  1223 val _ = Cplex.solve prog;*)