1 (* ========================================================================== *)
2 (* FLYSPECK - BOOK FORMALIZATION *)
4 (* Chapter: nonlinear inequalities *)
5 (* Author: Roland Zumkeller *)
7 (* ========================================================================== *)
11 ssh -t wh opt/bin/dmtcp/dmtcp_restart flyspeck.dmtcp
12 rsync -ahv ~/doc/flyspeck/ wh:ext/flyspeck/ --exclude .svn
15 module Oracle = struct
17 #load "unix.cma";; (* on Mac OS unix.cma needs to be pre-cooked into the toplevel with ocamlmktop *)
19 let sergei_path = "sergei/bin/sergei";;
21 let dest_decimal x = match strip_comb x with
22 | (dec,[a;b]) -> div_num (dest_numeral a) (dest_numeral b)
23 | (sqrt8,[]) when sqrt8 = `sqrt8` -> div_num (Int 3880899) (Int 1372105)
24 | _ -> failwith ("dest_decimal: '" ^ string_of_term x ^ "'") ;;
26 let string_of_num' x = string_of_float (float_of_num x);; (* rounding :( *)
28 let rec sergei_of_ccl t =
29 let soh = sergei_of_ccl in
30 if is_var t then fst (dest_var t) else
31 let (f,xs) = strip_comb t in
32 let ifix i = let [a;b] = xs in "(" ^ soh a ^ " " ^ i ^ " " ^ soh b ^ ")" in
33 let ifix_swapped i = let [b;a] = xs in "(" ^ soh a ^ " " ^ i ^ " " ^ soh b ^ ")" in
34 (if not (is_const f) then failwith ("Oracle error: " ^ string_of_term f));
35 match fst (dest_const f) with
36 | "real_gt" | "real_ge" | "real_sub" -> ifix "-"
37 | "real_lt" | "real_le" -> ifix_swapped "-"
38 | "real_add" -> ifix "+"
39 | "real_mul" -> ifix "*"
40 | "real_div" -> ifix "/"
41 | "real_pow" -> ifix "^"
43 | "atn" -> let [a] = xs in "Atan [" ^ soh a ^ "]"
44 | "sqrt" -> let [a] = xs in "Sqrt [" ^ soh a ^ "]"
45 | "real_neg" -> let [a] = xs in "(-" ^ soh a ^ ")"
46 | "pi" -> let [] = xs in "Pi"
47 | "real_of_num" -> let [a] = xs in string_of_num' (dest_numeral a) (* is this line redundant ? *)
48 | "NUMERAL" -> let [a] = xs in string_of_num' (dest_numeral t)
49 | "DECIMAL" -> string_of_num' (dest_decimal t)
50 | "atn2" -> let [ab] = xs in let (a,b) = dest_pair ab in "(" ^ soh a ^ " ATN2 " ^ soh b ^ ")"
51 | s -> failwith ("Encountered unknown constant '" ^ s ^ "'");;
53 let sergei_of_goal (asms,ccl) =
54 print_endline "Converting HOL term to sergei format...";
55 let vars = map (fun (_,axb) ->
56 let (ax,xb) = dest_conj (concl axb) in
57 let (a,x) = dest_binary "real_le" ax in
58 let (x',b) = dest_binary "real_le" xb in
60 failwith ("Malformed assumption: " ^ string_of_term x' ^
61 " should be " ^ string_of_term x ^ ".")
63 string_of_num' (dest_decimal a) ^ " <= " ^
64 string_of_term x ^ " <= " ^
65 string_of_num' (dest_decimal b) ^ " ->\n") asms
66 in List.fold_right (^) vars "" ^ " " ^ sergei_of_ccl ccl;;
68 let SERGEI_TAC : tactic = fun (asms,ccl) ->
69 print_endline ("Running sergei [" ^ sergei_path ^ "]:");
70 let (pin,pout) = Unix.open_process ("time " ^ sergei_path ^ " -nv -e0.00001") in
71 Pervasives.output_string pout (sergei_of_goal (asms,ccl));
74 print_endline ("sergei> " ^ input_line pin);
76 done with End_of_file -> ());
77 close_in pin; NO_TAC (asms,ccl);;
79 let SERGEI_DUMP : tactic = fun gl ->
80 print_endline (sergei_of_goal gl); NO_TAC gl;;
82 let rec SINGLE_CONV c = c
83 ORELSEC (fun t -> if is_comb t then
84 ((RATOR_CONV (SINGLE_CONV c)) ORELSEC (RAND_CONV (SINGLE_CONV c))) t
85 else failwith "SINGLE_CONV");;
87 let SINGLE_REWR_TAC e = CONV_TAC (CHANGED_CONV (SINGLE_CONV (REWR_CONV e)));;
90 `(! c. ineq' [] c <=> c)
91 /\ (!a x b xs c. ineq' (CONS (a,x,b) xs) c <=> a <= x /\ x <= b ==> ineq' xs c)`;;
94 valid: (except for x=0, y<=0)
95 useful: y >= 0 (1st & 2nd quadrant)
97 let ATN2_ATN = prove (`atn2(x,y) = &2 * atn(y / (sqrt (x*x + y*y) + x))`, CHEAT_TAC);;
99 let ATN2_90 = prove (`atn2(x,y) = atn2(--y,x) - pi/(&2)`, CHEAT_TAC);;
101 let ATN2_30 = prove (`atn2(x,y) = atn2(sqrt (&3) * x - y, x + sqrt (&3) * y) - pi/(&6)`, CHEAT_TAC);;
103 let ATN2_60 = prove (`atn2(x,y) = atn2(x - sqrt (&3) * y, sqrt (&3) * x + y) - pi/(&3)`, CHEAT_TAC);;
105 let ATN2_45 = prove (`atn2(x,y) = atn2(x-y,x+y) - pi/(&4)`, CHEAT_TAC);;
107 (* rotates atan by atan(t):
108 valid if we don't cross the discontinuous line *)
109 let ATN2_ROT_TAN = prove (`atn2 (x,y) = atn2 (x - y*t, y + x*t) - atn t`, CHEAT_TAC);;
112 valid : x >= 0 (1st & 4th quadrant)
113 useful: x >= 0 and y fixed (1st & 4th quadrant)
115 let ATN2_ATN_XPOS = prove (`atn2(x,y) = atn(y/x)`, CHEAT_TAC);;
117 (* rotate such that sign y becomes constant, then use ATN2_ATN. if we
118 manage to make both sign x and sign y positive, then ATN2_ATN_POS is
119 valid and useful (smaller formula) *)
121 let delta = [ Sphere.taum; Sphere.sol_y; Sphere.const1; Sphere.lnazim;
122 Sphere.delta_x; Sphere.delta_x4; Sphere.ly; Sphere.interp; Sphere.rhazim; Sphere.tauq;
123 Pack_defs.lmfun (*COND*); Sphere.rho; Sphere.arclength; Sphere.ups_x; Sphere.dih_x; Sphere.dih_y;
125 Quadratic_root_plus.quadratic_root_plus;
126 Abc_of_quadratic.abc_of_quadratic;
127 Mur.muR; Cayleyr.cayleyR ];;
130 ((REPEAT GEN_TAC) THEN (REWRITE_TAC [prove (`ineq = ineq'`, CHEAT_TAC)]) THEN (REWRITE_TAC [ineq'])) THEN
131 ((REWRITE_TAC delta) THEN (CONV_TAC (TOP_DEPTH_CONV let_CONV)) THEN (REPEAT DISCH_TAC));;