(* ========================================================================== *)
(* FLYSPECK - CODE FORMALIZATION                                              *)
(*                                                                            *)
(* Program: Linear Programs                                                   *)
(* Author: Thomas C. Hales                                                    *)
(* Date: 2010-08-01                                                           *)
(* ========================================================================== *)


(* 
   This file contains code that has been used in the interaction to
   find inequalities and branching that work.  Once the working system
   has been designed, this file is no longer required.
*)


module Tame_scaffolding = struct


  let libsort = sort;;  (* from Hol light lib.ml, before we open List *)

  open Glpk_link;;
  open Lpproc;;
  open Hard_lp;;
  open List;;

(* Old results from hard_lp.hl *)

(* preliminary version *)

let add_hints bb = 
  if not(is_feas bb) then () else
  if not(bb.hints = []) then () else
    add_hints_force bb;;

let filter_feas_hint bbs = filter_feas_f add_hints bbs;;

let onepass_hint = function 
  [] -> []
  | bb::bbss as bbs -> 
  let _ = onepass_backup := bbs in
  let brs =  switch_hint bb in
  let brs1 = map set_face_numerics brs in
  let brs2 = map set_node_numerics brs1 in
  let _ = echo bbs in
    sortbb ((filter_feas_hint brs2) @ bbss);;

(* Generate graphics files of a branchnbound, save gif as a /tmp file.  *)

let mk_gif bb = (Sys.chdir 
 "/Users/thomashales/Desktop/googlecode/flyspeck/graph_generator/classes"; 
 Sys.command 
    ("java render/Gendot \""^bb.string_rep ^
      "\" | neato -s -n -Tgif -o "^ 
    (Filename.temp_file ("render"^bb.hypermap_id^"_") (".gif"))));;



let get_azim_table xs bb = 
   let [y1;y2;y3] = map (yn bb) xs in
   let [y6;y4;y5] = map (fun i -> ye bb ( i, int_of_face xs bb)) xs in
   let [a1;a2;a3] = map (fun i -> azim bb (i, int_of_face xs bb)) xs in
   let b1 = dih_y y1 y2 y3 y4 y5 y6 in
   let b2 = dih_y y2 y3 y1 y5 y6 y4 in
   let b3 = dih_y y3 y1 y2 y6 y4 y5 in
   (y1,y2,y3,y4,y5,y6,("dih_lp",a1,"dih_y",b1,a1-. b1),("dih2_lp",a2,"dih2_y",b2,a2-. b2),("dih3_lp",a3,"dih3_y",b3,a3 -. b3),"soldiff",a1+. a2 +. a3 -.( b1 +. b2 +. b3));;

let testval f xs bb = 
  let (y1,y2,y3,y4,y5,y6,_,_,_,_,_) = get_azim_table xs bb in
  f y1 y2 y3 y4 y5 y6;;

let testvalsym d  = testval (fun y1 y2 y3 y4 y5 y6 -> d y1 y3 y2 y4 y6 y5);;

(* for the purpose of debugging    *)

let check_basic_format bb =
    (subset bb.std3_small  (rotation bb.std_faces_not_super)) &
    (subset bb.std3_big (rotation bb.std_faces_not_super)) &
    (intersect (rotation bb.std3_small) (rotation bb.std3_big) = []) &
    (subset bb.node_218_236 bb.node_218_252) &
    (subset bb.node_236_252 bb.node_218_252);;

(* for debugging, we don't want overly long lists. Pick out random elts. *)

let random_elt xs = 
  let i = Random.int (length xs) in
  let r = nth xs i in
   r, (subtract xs [r]);;

let rec random_elts n xs =
  if n=0 then ([],xs) else 
    let (a,b) = random_elts (n-1)  xs in
    let (r,s) = random_elt b in (r::a,s);;

let get_highest n bbs =
  let eval bb = (match bb.lpvalue with Lp_value r -> r | _ -> 0.0  ) in
  (chop_list n (libsort (fun b1 b2 -> eval b1 > eval b2) bbs));;

let prune_results n bbs = 
   if length bbs <= 2*n then bbs else
     let (b1,b2) = get_highest n bbs in
     b1 @ fst (random_elts n b2);;
     
let rec allpass_prune_hint prune count bbs = 
   if  count <= 0 then bbs else allpass_prune_hint prune (count - 1) (prune_results prune (onepass_hint bbs));;

(* Code to help eliminate final cases. *)

  let tmpfile = Filename.temp_file "display_ampl_" ".dat";;

let display_ampl =
   fun bb -> Glpk_link.display_ampl tmpfile Lpproc.ampl_of_bb bb;;

let display_lp bb = Glpk_link.display_lp 
  Lpproc.model tmpfile Lpproc.glpk_outfile Lpproc.ampl_of_bb bb ;;

let remake_model = 
  let bodyfile =  Filename.temp_file "body_" ".mod" in
  let m = Lpproc.model in
  fun () ->
    let _ = Lpproc.modelbody := bodyfile in
    let _ = Parse_ineq.output_filestring bodyfile (Parse_ineq.lpstring()) in    
    let _ = Sys.chdir(tame_dir) in
      Sys.command("cp head.mod "^m^"; cat "^bodyfile^" >> "^
                     m^"; cat tail.mod >> "^m);;

(* remake_model();; *)

let clone bb = modify_bb bb false [] [];;

let unset_edge bb = 
  let f = rotation (faces bb) in
  let g x = map (fun t -> [nth t 0; nth t 1]) x in
  libsort (<) (nub(subtract (g f) (g bb.d_edge_200_225 @ g bb.d_edge_225_252)));;



end;;