1 (* =========================================================== *)
2 (* Auxiliary formal verification functions *)
3 (* Author: Alexey Solovyev *)
5 (* =========================================================== *)
7 needs "arith/eval_interval.hl";;
8 needs "arith/more_float.hl";;
9 needs "taylor/m_taylor.hl";;
10 needs "verifier/interval_m/taylor.ml";;
11 needs "informal/informal_m_verifier.hl";;
12 needs "verifier_options.hl";;
13 needs "misc/vars.hl";;
15 module M_verifier_build = struct
27 open Verifier_options;;
29 type verification_funs =
31 (* p_lin -> p_second -> domain_th -> taylor_th *)
32 taylor : int -> int -> thm -> thm;
33 (* pp -> lo -> hi -> interval_th *)
34 f : int -> term -> term -> thm;
35 (* i -> pp -> lo -> hi -> interval_th *)
36 df : int -> int -> term -> term -> thm;
37 (* i -> j -> pp -> lo -> hi -> interval_th *)
38 ddf : int -> int -> int -> term -> term -> thm;
39 (* lo -> hi -> diff2_th *)
40 diff2_f : term -> term -> thm;
43 (****************************)
44 (* Interval polynomial functions for the native OCaml arithmetic *)
48 | F_int_const of interval
49 | F_int_pow of int * int_poly_fun
50 | F_int_neg of int_poly_fun
51 | F_int_add of int_poly_fun * int_poly_fun
52 | F_int_sub of int_poly_fun * int_poly_fun
53 | F_int_mul of int_poly_fun * int_poly_fun;;
56 let ipow = Arith_misc.gen_pow imul Interval.one;;
59 let eval_int_poly_fun i_fun =
63 | F_int_var i -> List.nth x (i - 1)
64 | F_int_const int -> int
65 | F_int_neg f1 -> ineg (eval_rec f1)
66 | F_int_pow (n,f1) -> ipow n (eval_rec f1)
67 | F_int_add (f1,f2) -> iadd (eval_rec f1) (eval_rec f2)
68 | F_int_sub (f1,f2) -> isub (eval_rec f1) (eval_rec f2)
69 | F_int_mul (f1,f2) -> imul (eval_rec f1) (eval_rec f2) in
72 (****************************)
73 (* Automatic conversion of formal interval polynomials into functions (polynomials) *)
74 (* TODO: take Int_ref into account *)
76 let rec build_poly_fun i_fun =
79 (try F_int_var (dest_small_numeral (rand tm))
81 let name = (fst o dest_var) tm in
82 F_int_var (int_of_string (String.sub name 1 (String.length name - 1))))
84 let f1, f2 = (dest_pair o rand o concl) th in
85 let int = mk_interval (float_of_float_tm f1, float_of_float_tm f2) in
87 | Int_pow (n, f) -> F_int_pow (n, build_poly_fun f)
88 | Int_unary (op, f) ->
89 let f' = build_poly_fun f in
90 if op = neg_op_real then F_int_neg f' else failwith ("Unsupported operator: "^string_of_term op)
91 | Int_binary (op, f1, f2) ->
92 let f1', f2' = build_poly_fun f1, build_poly_fun f2 in
93 if op = add_op_real then F_int_add (f1',f2')
94 else if op = sub_op_real then F_int_sub (f1',f2')
95 else if op = mul_op_real then F_int_mul (f1',f2')
96 else failwith ("Unsupported operator: "^string_of_term op)
97 | _ -> failwith "Unsupported function";;
100 let build_polyL pp lin_th =
101 let funs = map (fst o dest_interval_arith) ((striplist dest_conj o rand o concl) lin_th) in
102 let i_funs = map (eval_constants pp o build_interval_fun) funs in
103 let fs = map build_poly_fun i_funs @ (replicate (F_int_const zero) (8 - length funs + 1)) in
104 let eval_fs = map eval_int_poly_fun fs in
105 let f, df = hd eval_fs, tl eval_fs in
107 let vars = map2 (curry mk_interval) x z in
108 if i = 0 then f vars else (List.nth df (i - 1)) vars),
110 let vars = map (fun x -> mk_interval (x,x)) x in
111 mk_line (f vars, map (fun df -> df vars) df));;
113 let build_polyL0 pp poly_tm =
114 let lin_th = gen_lin_approx_poly_thm0 poly_tm in
115 build_polyL pp lin_th;;
117 let build_polyDD pp second_th =
118 let poly_tm = (lhand o rator o lhand o concl) second_th in
119 let n = (get_dim o fst o dest_abs) poly_tm in
121 let funs = (striplist dest_conj o rand o snd o dest_forall o rand o concl) second_th in
122 let i_funs = map (eval_constants pp o build_interval_fun o fst o dest_interval_arith) funs in
123 let fs0 = map build_poly_fun i_funs in
124 let pad1 = replicate zero (8 - n) and
125 pad2 = replicate zero 8 in
126 let pad3 = replicate pad2 (8 - n) in
128 let i', j' = if j <= i then i, j else j, i in
129 let index = (i' - 1) * i' / 2 + (j' - 1) in
131 let eval_fs = map eval_int_poly_fun fs0 in
133 let ints = map2 (curry mk_interval) x z in
134 let vals = map (fun f -> f ints) eval_fs in
135 map (fun i -> map (fun j -> get_el vals i j) ns @ pad1) ns @ pad3;;
138 let build_polyDD0 pp poly_tm =
139 let second_th = gen_second_bounded_poly_thm0 poly_tm in
140 build_polyDD pp second_th;;
145 let build_poly_taylor pp lin_th second_th =
146 let f_df, lin = build_polyL pp lin_th and
147 dd = build_polyDD pp second_th in
148 Prim_a (make_primitiveA (f_df, lin, dd));;
150 let build_poly_taylor0 pp poly_tm =
151 build_poly_taylor pp (gen_lin_approx_poly_thm0 poly_tm) (gen_second_bounded_poly_thm0 poly_tm);;
154 (**********************************)
155 (* mk_verification_functions *)
157 let mk_verification_functions_poly pp0 poly_tm =
158 let x_tm, body_tm = dest_abs poly_tm in
159 let new_f = poly_tm in
160 let n = get_dim x_tm in
162 let _ = !info_print_level = 0 or (report0 (sprintf "Computing partial derivatives (%d)..." n); true) in
163 let partials = map (fun i ->
164 let _ = !info_print_level = 0 or (report0 (sprintf " %d" i); true) in
165 gen_partial_poly i new_f) (1--n) in
166 let get_partial i eq_th =
167 let partial_i = gen_partial_poly i (rand (concl eq_th)) in
168 let pi = (rator o lhand o concl) partial_i in
169 REWRITE_RULE[GSYM partial2] (TRANS (AP_TERM pi eq_th) partial_i) in
170 let partials2 = map (fun j ->
171 let th = List.nth partials (j - 1) in
173 let _ = !info_print_level = 0 or (report0 (sprintf " %d,%d" j i); true) in
174 get_partial i th) (1--j)) (1--n) in
176 let _ = !info_print_level = 0 or (report0 " done\n"; true) in
178 let diff_th = gen_diff_poly new_f in
179 let lin_th = gen_lin_approx_poly_thm new_f diff_th partials in
180 let diff2_th = gen_diff2c_domain_poly new_f in
181 let second_th = gen_second_bounded_poly_thm new_f partials2 in
183 let replace_numeral i th =
184 let num_eq = (REWRITE_RULE[Arith_hash.NUM_THM] o Arith_nat.NUMERAL_TO_NUM_CONV)
185 (mk_small_numeral i) in
186 GEN_REWRITE_RULE (LAND_CONV o RATOR_CONV o DEPTH_CONV) [num_eq] th in
188 let eval0 = mk_eval_function pp0 new_f in
189 let eval1 = map (fun i ->
190 let d_th = List.nth partials (i - 1) in
191 let eq_th = replace_numeral i d_th in
192 mk_eval_function_eq pp0 eq_th) (1--n) in
194 let eval2 = map (fun i ->
196 let d2_th = List.nth (List.nth partials2 (i - 1)) (j - 1) in
197 let eq_th' = replace_numeral i d2_th in
198 let eq_th = replace_numeral j eq_th' in
199 mk_eval_function_eq pp0 eq_th) (1--i)) (1--n) in
201 let diff2_f = eval_diff2_poly diff2_th in
202 let eval_f = eval_m_taylor pp0 diff2_th lin_th second_th in
203 let taylor_f = build_poly_taylor pp0 lin_th second_th in
206 df = (fun i -> List.nth eval1 (i - 1));
207 ddf = (fun i j -> List.nth (List.nth eval2 (j - 1)) (i - 1));
209 }, taylor_f, Informal_verifier.mk_verification_functions_poly pp0 new_f partials partials2;;