1 (* ============================================================= *)
2 (* OCaml verification procedure (basic interval arithmetic only) *)
3 (* Authors: Thomas C. Hales, Alexey Solovyev *)
5 (* ============================================================= *)
7 (* Recursive verification of inequalities using the basic interval arithmetic only *)
9 needs "verifier/interval_m/recurse.ml";;
11 module Recurse0 = struct
24 let rec has_monotone0 opt tf domain0 x z x0 z0 is found = match is with
25 | [] -> (x,z,x0,z0,List.rev found)
26 | j::js when (mth x j >= mth z j) ->
27 has_monotone0 opt tf domain0 x z x0 z0 js found
29 let df_int = try evalf0 tf (j + 1) (fst domain0) (snd domain0) with Unstable -> mk_interval (-1.0,1.0) in
30 let allpos_df0 = df_int.lo >= opt.eps in
31 let allneg_df0 = df_int.hi < ~-.(opt.eps) in
34 {variable = j + 1; decr_flag = false; df0_flag = allpos_df0; ti_flag = false} in
35 if opt.mono_pass && mth z j < mth z0 j then return (Cell_pass_mono ([], status))
37 let setj u = table (fun i -> (if i=j then mth z j else mth u i)) in
38 has_monotone0 opt tf domain0 (setj x) (setj z)
39 (setj x0) (setj z0) js (status :: found)
40 else if allneg_df0 then
42 {variable = j + 1; decr_flag = true; df0_flag = allneg_df0; ti_flag = false} in
43 if opt.mono_pass && mth x j > mth x0 j then return (Cell_pass_mono ([], status))
45 let setj u = table (fun i -> (if i=j then mth x j else mth u i)) in
46 has_monotone0 opt tf domain0 (setj x) (setj z)
47 (setj x0) (setj z0) js (status :: found)
48 else has_monotone0 opt tf domain0 x z x0 z0 js found;;
50 (* loop as long as monotonicity keeps making progress. *)
52 let rec going_strong0(x,z,x0,z0,tf,opt,mono) =
53 let (y,w) = center_form (x,z) in
54 let maxwidth = maxl w in
55 let target0 = try evalf0 tf 0 x z with Unstable -> return (Cell_inconclusive (mono,x,z,x0,z0)) in
56 let _ = target0.hi >= ~-.(opt.eps) or return (Cell_pass (mono, true)) in
57 let epsilon_width = 1.0e-8 in
58 let _ = (maxwidth >= epsilon_width) or return Cell_counterexample in
59 let (x,z,x0,z0,strong) =
60 if (opt.allow_derivatives) then
62 has_monotone0 opt tf (x,z) x z x0 z0 iter8 []
63 with Return (Cell_pass_mono (_, status)) -> return (Cell_pass_mono (mono, status))
64 else (x,z,x0,z0,[]) in
65 if (strong <> []) then
66 going_strong0(x,z,x0,z0,tf,opt,mono @ [strong])
68 (x,z,x0,z0,maxwidth,mono);;
72 This procedure is mostly guided by heuristics that don't require formal
73 verification. In particular, no justification is required for tossing out inequalities
74 (since they appear as disjuncts, we can choose which one to prove).
76 Formal verification is required whenever a Cell_passes is issued,
77 and whenever the domain (x,z) is restricted.
79 The record (x0,z0) of the current outer boundary must be restricted to (x,z)
80 whenever an inequality is tossed out.
83 let rec verify_cell0 (x,z,x0,z0,tf,opt) =
85 let _ = not(periodic_count ()) or report_current (x,z,"periodic report") in
86 let (x,z,x0,z0,maxwidth,mono) = going_strong0(x,z,x0,z0,tf,opt,[]) in
87 if opt.convex_flag then
88 let ti = try evalf tf x z with Unstable -> return (Cell_inconclusive (mono,x,z,x0,z0)) in
89 Cell_inconclusive_ti (mono,ti,x,z,x0,z0)
91 Cell_inconclusive (mono,x,z,x0,z0)
95 let rec recursive_verifier0 (depth,x,z,x0,z0,tf,opt) =
96 let _ = check_limit opt depth or report_fatal(x,z,Printf.sprintf "depth %d" depth) in
97 let split_and_verify j x z x0 z0 convex_flag =
98 let ( ++ ), ( / ) = up(); upadd, updiv in
99 let yj = (mth x j ++ mth z j) / 2.0 in
100 let delta b v = table (fun i-> if (i = j && b) then yj else mth v i) in
103 x, table (fun i -> if i = j then mth x i else mth z i)
105 delta false x, delta true z in
108 table (fun i -> if i = j then mth z i else mth x i), z
110 delta true x, delta false z in
111 let r1 = recursive_verifier0(depth+1,x1,z1,x0,z0,tf,opt) in
113 | Result_false t -> Result_false t
115 (let r2 = recursive_verifier0(depth+1,x2,z2,x0,z0,tf,opt) in
117 | Result_false t -> Result_false t
118 | _ -> Result_glue (j, convex_flag, r1, r2)) in
120 let add_mono mono r1 =
121 itlist (fun m r -> Result_mono (m, r)) mono r1 in
124 match verify_cell0(x,z,x0,z0,tf,opt) with
125 | Cell_counterexample -> Result_false (x,z)
126 | Cell_pass (mono, f0_flag) -> add_mono mono (Result_pass (f0_flag,x,z))
127 | Cell_pass_mono (mono, status) -> add_mono mono (Result_pass_mono status)
128 | Cell_inconclusive_ti(mono,ti,x,z,x0,z0) ->
129 let dds = map (fun i -> mth (mth ti.dd i) i, i) iter8 in
130 let convex_dds = filter (fun dd, i -> dd.lo >= opt.eps && mth x i < mth z i) dds in
131 let convex_i = map snd convex_dds in
132 let w2 = List.map2 upsub z x in
133 let convex_flag, ws, ws_i =
134 if convex_dds = [] then
137 true, map (mth w2) convex_i, convex_i in
138 let maxwidth2 = maxl ws in
139 let j_wide = try( find (fun i -> mth w2 i = maxwidth2) ws_i) with
140 | _ -> failwith "recursive_verifier find" in
141 add_mono mono (split_and_verify j_wide x z x0 z0 convex_flag)
143 | Cell_inconclusive(mono,x,z,x0,z0) ->
144 let w2 = List.map2 upsub z x in
145 let maxwidth2 = maxl w2 in
146 let j_wide = try( find (fun i -> mth w2 i = maxwidth2) iter8) with
147 | _ -> failwith "recursive_verifier find" in
148 add_mono mono (split_and_verify j_wide x z x0 z0 false);;