1 needs "../formal_lp/formal_interval/second_approx.hl";;
2 needs "../formal_lp/formal_interval/interval_1d/recurse.hl";;
5 (***********************************)
7 let cell_pass = new_definition `cell_pass f int <=> !x. interval_arith x int ==> f x < &0`;;
9 let dest_cell_pass tm =
10 let lhs, int_tm = dest_comb tm in
13 let CELL_PASS_GLUE = prove(`!f x t z. cell_pass f (x, t) /\ cell_pass f (t, z) ==> cell_pass f (x, z)`,
14 REWRITE_TAC[cell_domain; cell_pass; interval_arith] THEN
16 DISJ_CASES_TAC (REAL_ARITH `x' <= t \/ t <= x'`) THENL
18 FIRST_X_ASSUM ((fun th -> ALL_TAC) o SPEC `x':real`) THEN
19 FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[];
20 FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]
23 let CELL_PASS_GLUE' = RULE CELL_PASS_GLUE;;
25 let cell_pass_glue pass1 pass2 =
26 let f_tm, int1 = dest_cell_pass (concl pass1) and
27 int2 = rand (concl pass2) in
28 let x_tm, t_tm = dest_pair int1 and
30 let th0 = INST[f_tm, f_var_fun; x_tm, x_var_real; t_tm, t_var_real; z_tm, z_var_real] CELL_PASS_GLUE' in
31 (MY_PROVE_HYP pass1 o MY_PROVE_HYP pass2) th0;;
36 let CELL_PASS_LEMMA' = (UNDISCH_ALL o PURE_REWRITE_RULE[GSYM IMP_IMP] o prove)
37 (`bounded_on_int f int (f_lo, f_hi) /\ (f_hi < &0 <=> T) ==> cell_pass f int`,
38 REWRITE_TAC[bounded_on_int; cell_pass; interval_arith] THEN
40 MATCH_MP_TAC REAL_LET_TRANS THEN
41 EXISTS_TAC `f_hi:real` THEN ASM_REWRITE_TAC[] THEN
42 FIRST_X_ASSUM (MP_TAC o SPEC `x:real`) THEN ASM_SIMP_TAC[]);;
45 let taylor_cell_pass pp taylor_int_th =
46 let bound_th = eval_taylor_f_bounds pp taylor_int_th in
47 let lhs, f_bounds = dest_comb (concl bound_th) in
48 let lhs2, int_tm = dest_comb lhs in
49 let f_tm = rand lhs2 in
50 let f_lo, f_hi = dest_pair f_bounds in
51 let f_hi_lt0 = float_lt0 f_hi in
52 if (fst o dest_const o rand o concl) f_hi_lt0 <> "T" then
53 failwith "taylor_cell_pass: f_hi >= 0"
55 let th0 = INST[f_tm, f_var_fun; int_tm, int_var; f_lo, f_lo_var; f_hi, f_hi_var] CELL_PASS_LEMMA' in
56 (MY_PROVE_HYP bound_th o MY_PROVE_HYP f_hi_lt0) th0;;
59 (*************************************)
67 (******************************************)
70 let DECIMAL' = SPEC_ALL DECIMAL;;
72 (* Unary interval operations *)
73 let unary_interval_operations =
74 let table = Hashtbl.create 10 in
75 let add = Hashtbl.add in
76 add table `--` (fun pp -> float_interval_neg);
77 add table `inv` float_interval_inv;
78 add table `sqrt` float_interval_sqrt;
79 add table `atn` float_interval_atn;
80 add table `acs` float_interval_acs;
84 (* Binary interval operations *)
85 let binary_interval_operations =
86 let table = Hashtbl.create 10 in
87 let add = Hashtbl.add in
88 add table `+` float_interval_add;
89 add table `-` float_interval_sub;
90 add table `*` float_interval_mul;
91 add table `/` float_interval_div;
94 (* Interval approximations of constants *)
95 let interval_constants =
96 let table = Hashtbl.create 10 in
97 let add = Hashtbl.add in
98 add table `pi` (fun pp -> pi_approx_array.(pp));
102 (* Builds a function for evaluating an interval approximation of the given expression *)
103 let rec build_eval_interval expr_tm =
105 if is_const expr_tm then
106 Hashtbl.find interval_constants expr_tm
108 let ltm, r_tm = dest_comb expr_tm in
109 (* Unary operations *)
112 if ltm = amp_op_real then
113 let n = dest_numeral r_tm in
114 (fun pp -> mk_float_interval_num n)
116 let r_fun = build_eval_interval r_tm in
117 let f = Hashtbl.find unary_interval_operations ltm in
118 (fun pp -> f pp (r_fun pp))
120 (* Binary operations *)
121 let op, l_tm = dest_comb ltm in
123 if (fst o dest_const) op = "DECIMAL" then
124 let n, d = dest_numeral l_tm, dest_numeral r_tm in
126 let (/), (!) = float_interval_div pp, mk_float_interval_num in
127 let int_th = !n / !d in
128 let eq_th = INST[l_tm, x_var_num; r_tm, y_var_num] DECIMAL' in
129 norm_interval int_th eq_th)
131 let lhs = build_eval_interval l_tm and
132 rhs = build_eval_interval r_tm in
133 let f = Hashtbl.find binary_interval_operations op in
134 (fun pp -> f pp (lhs pp) (rhs pp));;
137 (* Converts a float term to the corresponding rational number *)
138 let num_of_float_tm tm =
139 let s, n_tm, e_tm = dest_float tm in
140 let b = Num.num_of_int base in
141 let m = Num.num_of_int min_exp in
142 let ( * ), (^), (-), (!) = ( */ ), ( **/ ), (-/), raw_dest_hash in
143 let r = !n_tm * (b ^ (!e_tm - m)) in
144 if s = "T" then minus_num r else r;;
147 let float_of_float_tm tm =
148 float_of_num (num_of_float_tm tm);;
151 (**************************************)
153 let taylor_interval_div_alt pp th1 th2 =
154 let domain_th, _, _ = dest_taylor_interval_th th1 in
155 let rhs = taylor_interval_compose pp eval_taylor_inv (fun _ _ -> th2) in
156 taylor_interval_mul pp th1 (rhs domain_th);;
159 let mk_formal_binop taylor_binop arg1 arg2 =
161 let lhs = arg1 pp domain_th and
162 rhs = arg2 pp domain_th in
163 taylor_binop pp lhs rhs;;
166 let rec mk_taylor_functions pp expr_tm =
169 let eval_f = build_eval_interval expr_tm in
170 let int_th = eval_f pp in
171 let lo_tm, hi_tm = (dest_pair o rand o concl) int_th in
172 let float_int = mk_interval (float_of_float_tm lo_tm, float_of_float_tm hi_tm) in
173 Scale (unit, float_int), (fun pp -> eval_taylor_const_interval int_th)
176 if is_var expr_tm then
177 if (expr_tm = x_var_real) then x1, (fun pp -> eval_taylor_x)
178 else failwith "mk_taylor_functions: only x variable is allowed"
180 (* Constant (operation) *)
181 if is_const expr_tm then
182 let name,_ = dest_const expr_tm in
183 if name = "real_inv" then
184 Uni (mk_primitiveU uinv), eval_taylor_inv
185 else if name = "sqrt" then
186 Uni (mk_primitiveU usqrt), eval_taylor_sqrt
187 else if name = "atn" then
188 Uni (mk_primitiveU uatan), eval_taylor_atn
189 else if name = "acs" then
190 Uni (mk_primitiveU uacos), eval_taylor_acs
192 failwith ("mk_taylor_functions: unknown constant: "^name)
195 let lhs, r_tm = dest_comb expr_tm in
196 let r, r2 = mk_taylor_functions pp r_tm in
197 (* Unary operations *)
198 if lhs = neg_op_real then
199 Scale (r, ineg one), (fun pp domain_th -> taylor_interval_neg (r2 pp domain_th))
203 let l, l2 = mk_taylor_functions pp lhs in
204 if r_tm = x_var_real then
207 Composite (l,r), (fun pp domain_th -> taylor_interval_compose pp l2 r2 domain_th)
209 (* Binary operations *)
211 let op, l_tm = dest_comb lhs in
212 let l, l2 = mk_taylor_functions pp l_tm in
213 if op = add_op_real then
214 Plus (l,r), mk_formal_binop taylor_interval_add l2 r2
215 else if op = sub_op_real then
216 Minus (l,r), mk_formal_binop taylor_interval_sub l2 r2
217 else if op = mul_op_real then
218 Product (l,r), mk_formal_binop taylor_interval_mul l2 r2
219 else if op = div_op_real then
220 Product (l, Uni_compose (uinv,r)), mk_formal_binop taylor_interval_div_alt l2 r2
222 failwith ("mk_taylor_functions: unknown binary operation "^string_of_term op)
224 failwith ("mk_taylor_functions: error: "^string_of_term lhs);;
226 (**********************************)
229 let rec result_size r =
231 | Result_false -> failwith "False result detected"
232 | Result_glue (r1, r2) -> result_size r1 + result_size r2
233 | Result_pass _ -> 1;;
236 let prove_result pp formal_f result lo_tm hi_tm =
237 let pass_counter = ref 0 in
238 let r_size = result_size result in
239 let rec rec_prove result lo_tm hi_tm =
240 let domain_th = mk_center_domain pp lo_tm hi_tm in
242 | Result_false -> failwith "False result"
244 pass_counter := !pass_counter + 1;
245 let th0 = taylor_cell_pass pp (formal_f pp domain_th) in
246 let _ = report (sprintf "Result_pass: %d/%d" !pass_counter r_size) in
248 | Result_glue (r1, r2) ->
249 let _, y_tm, _, _ = dest_cell_domain (concl domain_th) in
250 let th1 = rec_prove r1 lo_tm y_tm and
251 th2 = rec_prove r2 y_tm hi_tm in
252 cell_pass_glue th1 th2 in
253 rec_prove result lo_tm hi_tm;;
256 let CELL_PASS_IMP = prove
257 (`cell_pass f (lo, hi) ==>
258 interval_arith x (lo, w1) ==>
259 interval_arith z (w2, hi) ==>
260 !t. t IN real_interval [x, z] ==> f t < &0`,
261 REWRITE_TAC[cell_pass; interval_arith; IN_REAL_INTERVAL] THEN REPEAT STRIP_TAC THEN
262 FIRST_X_ASSUM MATCH_MP_TAC THEN
263 ASM_REAL_ARITH_TAC);;
266 let prove_ineq1d pp expr_tm lo_tm hi_tm =
267 let f, formal_f = mk_taylor_functions pp expr_tm in
268 let lo_int, hi_int = build_eval_interval lo_tm pp, build_eval_interval hi_tm pp in
269 let lo1_tm = (fst o dest_pair o rand o concl) lo_int and
270 hi1_tm = (snd o dest_pair o rand o concl) hi_int in
271 let lo, hi = float_of_float_tm lo1_tm, float_of_float_tm hi1_tm in
272 let _ = report (sprintf "Starting verification from %f to %f" lo hi) in
281 recursive_verifier (0, lo, hi, f, opt) in
283 let th0 = prove_result pp formal_f result lo1_tm hi1_tm in
284 REWRITE_RULE[] (MATCH_MP (MATCH_MP (MATCH_MP CELL_PASS_IMP th0) lo_int) hi_int);;