(* ========================================================================== *)
(* FLYSPECK - BOOK FORMALIZATION *)
(* *)
(* Chapter: nonlinear inequalities *)
(* Author: Thomas Hales *)
(* Date: 2013-01-28 *)
(* ========================================================================== *)
(* generate all theorems of terms in !Ineq.ineqs from a single assumption `prepared_nonlinear:bool`,
defined as the conjunction of all inequalities in prep.hl
Taking this a step further, we would get |- prepared_nonlinear ==> nonlinear
*)
flyspeck_needs "nonlinear/prep.hl";;
module Mk_all_ineq = struct
open Optimize;;
let mk_nonlinear =
let ineql = map (fun idv -> idv.ineq) !Ineq.ineqs in
let ineq_conj = end_itlist (curry mk_conj) ineql in
let _ = new_definition (mk_eq (`nonlinear:bool`,ineq_conj)) in
();;
let get_nonlinear =
let sl = map (fun ind -> ind.idv) !Ineq.ineqs in
let ineql = map (fun idv -> idv.ineq) !Ineq.ineqs in
let ineq_conj = end_itlist (curry mk_conj) ineql in
let th = new_definition (mk_eq (`nonlinear:bool`,ineq_conj)) in
let th1 = UNDISCH (MATCH_MP (TAUT `(a <=> b) ==> (a ==> b)`) th) in
let co1 thm = if (is_conj (concl thm)) then CONJUNCT1 thm else thm in
fun s ->
let i = index s sl in
let th2 = funpow i CONJUNCT2 th1 in
co1 th2;;
(*
let prep_ineqs = ref ([]:ineq_datum list);;
let add_inequality i =
let _ = prep_ineqs:= i :: !prep_ineqs in
();;
*)
let prep_ineqs = Prep.prep_ineqs;;
let mk_prepared_nonlinear =
let ineql = map (fun idv -> idv.ineq) (!prep_ineqs) in
let ineq_conj = end_itlist (curry mk_conj) ineql in
let _ = new_definition (mk_eq (`prepared_nonlinear:bool`,ineq_conj)) in
();;
let get_prep_nonlinear =
let sl = map (fun ind -> ind.idv) !prep_ineqs in
let ineql = map (fun ind -> ind.ineq) (!prep_ineqs) in
let ineq_conj = end_itlist (curry mk_conj) ineql in
let th = new_definition (mk_eq (`prepared_nonlinear:bool`,ineq_conj)) in
let th1 = UNDISCH (MATCH_MP (TAUT `(a <=> b) ==> (a ==> b)`) th) in
let co1 thm = if (is_conj (concl thm)) then CONJUNCT1 thm else thm in
fun s ->
let i = index s sl in
let th2 = funpow i CONJUNCT2 th1 in
co1 th2;;
let hasprefix s sl = filter (fun t -> (String.length s <= String.length t) &&
(String.sub t 0 (String.length s) = s)) (sl);;
let get_all_prep_nonlinear =
let sl = map (fun ind -> ind.idv) !prep_ineqs in
let ineql = map (fun ind -> ind.ineq) (!prep_ineqs) in
let ineq_conj = end_itlist (curry mk_conj) ineql in
let th = new_definition (mk_eq (`prepared_nonlinear:bool`,ineq_conj)) in
let th1 = UNDISCH (MATCH_MP (TAUT `(a <=> b) ==> (a ==> b)`) th) in
let co1 thm = if (is_conj (concl thm)) then CONJUNCT1 thm else thm in
let c i thm = co1 (funpow i CONJUNCT2 thm) in
let get s = c (index s sl) th1 in
fun s ->
try [get s] with
Failure _ ->
(let s' = s^" split(" in
let ssl = hasprefix s' sl in
map get ssl);;
let example1 = get_all_prep_nonlinear "GLFVCVK4a 8328676778";;
(* This follows the same sequence in the module Optimize that is used to generate the inequalities
in prep.hl, finishing off the last step of the proof with a rewrite. *)
let prove_ineq s =
let DSPLIT_TAC i = DISCH_TAC THEN (Optimize.SPLIT_H0_TAC i) in
let LET_ELIM_TAC = CONV_TAC (REDEPTH_CONV let_CONV) in
let is_xconvert tags = mem Xconvert tags in
let is_branch tags = mem Branching tags in
let NONL = `prepared_nonlinear:bool` in
let idq = hd(Ineq.getexact s) in
let (s',tags,ineq) = idq_fields idq in
let _ = (s = s') or failwith "prove_ineq: wrong ineq" in
try (s,prove(mk_imp(NONL,ineq),
LET_ELIM_TAC THEN
EVERY (map DSPLIT_TAC (get_split_tags idq)) THEN
EVERY
[LET_ELIM_TAC;
PRELIM_REWRITE_TAC;
if (is_branch tags) then BRANCH_TAC else ALL_TAC;
if (is_xconvert tags) then X_OF_Y_TAC else ALL_TAC;
if (is_branch tags && not(is_xconvert tags)) then SERIES3Q1H_5D_TAC else ALL_TAC;
STYLIZE_TAC;
WRAPUP_TAC;
REWRITE_TAC (get_all_prep_nonlinear s)]))
with Failure m -> failwith (s^" "^m);;
let example2 = map prove_ineq ["GLFVCVK4a 8328676778";"4750199435";"GLFVCVK4 2477216213 y4supercrit"];;
Ineq.getexact "4528012043";;
prove_ineq "4528012043";;
let exec() =
let sl = map (fun t -> t.idv) !Ineq.ineqs in
map prove_ineq sl;;
(* (* experimental, combine subgoals into a a single subgoal. *)
let (merge1_goal:refinement) =
fun (meta,sgs,just) ->
if List.length sgs < 2 then (meta,sgs,just)
else
let s0::s1::s2 = sgs in
let _ = fst(s0) = [] or failwith "merge1_goal asl nonempty" in
let _ = fst(s1) = [] or failwith "merge1_goal asl nonempty" in
let sgs' = ([],mk_conj (snd s0, snd s1)) ::s2 in
let just' i ths =
(just i ( (CONJUNCT1 (hd ths)) :: (CONJUNCT2 ( (hd ths))) :: tl ths)) in
(meta,sgs',just');;
let rec merge_all_goal (meta,sgs,just) =
if (List.length sgs < 2) then (meta,sgs,just)
else merge_all_goal (merge1_goal (meta,sgs,just));;
let top_asl_thm() =
let (_,sgs,f)::_ = !current_goalstack in
let t = snd(hd sgs) in
DISCH t (f null_inst [ASSUME t]);;
*)
end;;