(* ------------------------------------------------------------------------- *)
(* Find sign of polynomial, using modulo-constant lookup and computation. *)
(* ------------------------------------------------------------------------- *)
let xterm_lt t1 t2 =
try
let n1,_ = dest_var t1 in
let n2,_ = dest_var t2 in
let i1 = String.sub n1 2 (String.length n1 - 2) in
let i2 = String.sub n2 2 (String.length n2 - 2) in
let x1 = int_of_string i1 in
let x2 = int_of_string i2 in
x1 < x2
with _ -> failwith "xterm_lt: not an xvar?";;
(*
String.sub n1 2 (String.length n1 - 2)
substring
let t1,t2 = `x_99:real`,`x_100:real`
xterm_sort t1 t2
t1 < t2
*)
let FINDSIGN =
let p_tm = `p:real`
and c_tm = `c:real`
and fth = prove
(`r (a * b * p) (&0) ==> (a * b = &1) ==> r p (&0)`,
DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN
ASM_REWRITE_TAC[REAL_MUL_ASSOC; REAL_MUL_LID]) in
let rec FINDSIGN vars sgns p =
try
try SIGN_CONST p with Failure _ ->
let mth = MONIC_CONV vars p in
let p' = rand(concl mth) in
let pth = find (fun th -> lhand(concl th) = p') sgns in
let c = lhand(lhand(concl mth)) in
let c' = term_of_rat(Int 1 // rat_of_term c) in
let sth = SIGN_CONST c' in
let rel_c = funpow 2 rator (concl sth) in
let rel_p = funpow 2 rator (concl pth) in
let th1 =
if rel_p = req then if rel_c = rgt then pth_0g else pth_0l
else if rel_p = rgt then if rel_c = rgt then pth_gg else pth_gl
else if rel_p = rlt then if rel_c = rgt then pth_lg else pth_ll
else if rel_p = rneq then if rel_c = rgt then pth_nzg else pth_nzl
else failwith "FINDSIGN" in
let th2 = MP (MP (INST [p',p_tm; c',c_tm] th1) pth) sth in
let th3 = EQ_MP (LAND_CONV(RAND_CONV(K(SYM mth))) (concl th2)) th2 in
let th4 = MATCH_MP fth th3 in
MP th4 (EQT_ELIM(REAL_RAT_REDUCE_CONV(lhand(concl th4))))
with Failure _ -> failwith "FINDSIGN" in
FINDSIGN;;
(*
let vars = [`x:real`;`y:real`]
let p = `&7 + x * (&11 + x * (&10 + y * &7))`
let sgns = [ASSUME `&1 + x * (&11 / &7 + x * (&10 / &7 + y * &1)) < &0`]
let sgns = [ASSUME `&1 + x * (&11 / &7 + x * (&10 / &7 + y * &1)) = &0`]
let sgns = [ASSUME `&1 + x * (&11 / &7 + x * (&10 / &7 + y * &1)) > &0`]
let sgns = [ASSUME `&1 + x * (&11 / &7 + x * (&10 / &7 + y * &1)) <> &0`]
FINDSIGN vars sgns p
FINDSIGN vars sgns `-- &1`
*)
(*
ASSERTSIGN [x,y] [] (|- &7 + x * (&11 + x * (&10 + y * -- &7)) < &0
-->
[-- &1 + x * (-- &11 / &7 + x * (-- &10 / &7 + y * &1)) > &0]
ASSERTSIGN [x,y] [] (|- &7 + x * (&11 + x * (&10 + y * &7)) < &0
-->
[&1 + x * (&11 / &7 + x * (&10 / &7 + y * &1)) < &0]
*)
let ASSERTSIGN vars sgns sgn_thm =
let op,l,r = get_binop (concl sgn_thm) in
let p_thm = MONIC_CONV vars l in
let _,pl,pr = get_binop (concl p_thm) in
let c,_ = dest_binop rm pl in
let c_thm = SIGN_CONST c in
let c_op,_,_ = get_binop (concl c_thm) in
let sgn_thm' =
if c_op = rlt & op = rlt then
MATCH_MPL[signs_lem01;c_thm;sgn_thm;p_thm]
else if c_op = rgt & op = rlt then
MATCH_MPL[signs_lem02;c_thm;sgn_thm;p_thm]
else if c_op = rlt & op = rgt then
MATCH_MPL[signs_lem03;c_thm;sgn_thm;p_thm]
else if c_op = rgt & op = rgt then
MATCH_MPL[signs_lem04;c_thm;sgn_thm;p_thm]
else if c_op = rlt & op = req then
MATCH_MPL[signs_lem05;c_thm;sgn_thm;p_thm]
else if c_op = rgt & op = req then
MATCH_MPL[signs_lem06;c_thm;sgn_thm;p_thm]
else if c_op = rlt & op = rneq then
MATCH_MPL[signs_lem07;c_thm;sgn_thm;p_thm]
else if c_op = rgt & op = rneq then
MATCH_MPL[signs_lem08;c_thm;sgn_thm;p_thm]
else failwith "ASSERTSIGN : 0" in
try
let sgn_thm'' = find (fun th -> lhand(concl th) = pr) sgns in
let op1,l1,r1 = get_binop (concl sgn_thm') in
let op2,l2,r2 = get_binop (concl sgn_thm'') in
if (concl sgn_thm') = (concl sgn_thm'') then sgns
else if op2 = rneq & (op1 = rlt or op1 = rgt) then sgn_thm'::snd (remove ((=) sgn_thm'') sgns)
else failwith "ASSERTSIGN : 1"
with Failure "find" -> sgn_thm'::sgns;;
(*
let k0 = `&7 + x * (&11 + x * (&10 + y * -- &7))`
MONIC_CONV vars k0
let k1 = ASSUME `&7 + x * (&11 + x * (&10 + y * -- &7)) < &0`
let k1 = ASSUME `&7 + x * (&11 + x * (&10 + y * &7)) < &0`
let k1 = ASSUME `&7 + x * (&11 + x * (&10 + y * &7)) = &0`
let k1 = ASSUME `&7 + x * (&11 + x * (&10 + y * &7)) <> &0`
let sgn_thm = k1
ASSERTSIGN vars [ASSUME `&1 + x * (&11 / &7 + x * (&10 / &7 + y * &1)) <> &0`] k1
*)
(* ---------------------------------------------------------------------- *)
(* Case splitting *)
(* ---------------------------------------------------------------------- *)
let SPLIT_ZERO vars sgns p cont_z cont_n ex_thms =
try
let sgn_thm = FINDSIGN vars sgns p in
let op,l,r = get_binop (concl sgn_thm) in
(if op = req then cont_z else cont_n) sgns ex_thms
with Failure "FINDSIGN" ->
let eq_tm = mk_eq(p,rzero) in
let neq_tm = mk_neq(p,rzero) in
let or_thm = ISPEC p signs_lem002 in
(* zero *)
let z_thm = cont_z (ASSERTSIGN vars sgns (ASSUME eq_tm)) ex_thms in
let z_thm' = DISCH eq_tm z_thm in
(* nonzero *)
let nz_thm = cont_n (ASSERTSIGN vars sgns (ASSUME neq_tm)) ex_thms in
let nz_thm' = DISCH neq_tm nz_thm in
(* combine *)
let ret = MATCH_MPL[signs_lem003;or_thm;z_thm';nz_thm'] in
(* matching problem... must continue by hand *)
let ldj,rdj = dest_disj (concl ret) in
let lcj,rcj = dest_conj ldj in
let a,_ = dest_binop req lcj in
let p,p1 = dest_beq rcj in
let _,rcj = dest_conj rdj in
let p2 = rhs rcj in
let pull_thm = ISPECL[a;p;p1;p2] PULL_CASES_THM in
let ret' = MATCH_EQ_MP pull_thm ret in
ret';;
(*
let ret = MATCH_MPL[lem3;or_thm]
MATCH_MP ret z_thm'
;nz_thm'] in
let vars,sgns,p,cont_z,cont_n,ex_thms = !sz_vars, !sz_sgns, !sz_p,!sz_cont_z, !sz_cont_n ,!sz_ex_thms
let ret = MATCH_MPL[lem3;or_thm;]
let mp_thm = MATCH_MPL[lem3;or_thm;] in
let vars, sgns, p,cont_z, cont_n = !sz_vars,!sz_sgns,!sz_p,!sz_cont_z,!sz_cont_n
let mp_thm = k1
let t1 = ISPECL[`(?y. &0 + y * (&0 + x * &1) = &0)`;`T`;`T`;`&0 + x * &1`;`T`] t0
MATCH_EQ_MP t1 k1
EQ_MP t1 k1
MATCH_EQ_MP PULL_CASES_THM k1
concl k1 = lhs (concl t1)
MATCH_EQ_MP PULL_CASES_THM k0
let k0 = ASSUME `(&0 + x * &1 = &0) /\ ((?y. &0 + y * (&0 + x * &1) = &0) <=> T) \/
&0 + x * &1 <> &0 /\
(&0 + x * &1 > &0 /\ ((?x_1089. &0 + x_1089 * (&0 + x * &1) = &0) <=> T) \/
&0 + x * &1 < &0 /\ ((?x_1084. &0 + x_1084 * (&0 + x * &1) = &0) <=> T))`;;
let k1 = ASSUME `(&0 + x * &1 = &0) /\ ((?y. &0 + y * (&0 + x * &1) = &0) <=> T) \/
&0 + x * &1 <> &0 /\
(&0 + x * &1 > &0 /\ ((?y. &0 + y * (&0 + x * &1) = &0) <=> T) \/
&0 + x * &1 < &0 /\ ((?y. &0 + y * (&0 + x * &1) = &0) <=> T))`;;
MATCH_MPL[PULL_CASES_THM;!sz_z_thm;!sz_nz_thm] in
let thm1 = ASSUME `(?x_32. (&0 + c * &1) + x_32 * ((&0 + b * &1) + x_32 * (&0 + a * &1)) = &0) <=> T`
let thm2 =
ASSUME `(&0 + a * ((&0 + b * (&0 + b * -- &1)) + a * (&0 + c * &4)) < &0 ==>
((?x. (&0 + c * &1) + x * ((&0 + b * &1) + x * (&0 + a * &1)) = &0) <=> F)) /\
(&0 + a * ((&0 + b * (&0 + b * -- &1)) + a * (&0 + c * &4)) > &0 ==>
((?x_26. (&0 + c * &1) + x_26 * ((&0 + b * &1) + x_26 * (&0 + a * &1)) = &0) <=> T)) `
MATCH_MPL
(* let PULL_CASES_THM = prove_by_refinement( *)
(* `((a = &0) ==> (p <=> p0)) ==> ((a <> &0) ==> (a < &0 ==> (p <=> p1)) /\ (a > &0 ==> (p <=> p2))) *)
(* ==> (p <=> ((a = &0) /\ p0) \/ ((a < &0) /\ p1) \/ (a > &0 /\ p2))`, *)
(* (\* {{{ Proof *\)
[
REWRITE_TAC[NEQ] THEN
MAP_EVERY BOOL_CASES_TAC [`p:bool`; `p0:bool`; `p1:bool`; `p2:bool`] THEN
ASM_REWRITE_TAC[NEQ] THEN TRY REAL_ARITH_TAC
]);;
(\* }}} *\) *)
let PULL_CASES_THM = prove
(`!a p p0 p1 p2.
((a = &0) /\ (p <=> p0) \/
(a <> &0) /\ (a > &0 /\ (p <=> p1) \/ a < &0 /\ (p <=> p2))) <=>
((p <=> (a = &0) /\ p0 \/ a > &0 /\ p1 \/ a < &0 /\ p2))`,
(* {{{ Proof *)
REPEAT STRIP_TAC THEN REWRITE_TAC[
NEQ] THEN MAP_EVERY BOOL_CASES_TAC [`p:bool`; `p0:bool`; `p1:bool`; `p2:bool`] THEN
ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);;
(* }}} *)
let vars, sgns, p, cont_z, cont_n =
[`x:real`;`y:real`],
empty_sgns,
`&0 + y * &1`,
(fun x -> (ASSUME `abc > def`,[])),
(fun x -> (ASSUME `sean > steph`,[]))
SPLIT_ZERO vars sgns p cont_z cont_n
ASSERTSIGN vars empty_sgns (ASSUME `&0 + y * &1 = &0`) ,
let vars = [`x:real`;`y:real`]
let sgns = ASSERTSIGN vars [] (ASSUME `&7 + x * (&11 + x * (&10 + y * -- &7)) <> &0`)
let p = `&7 + x * (&11 + x * (&10 + y * -- &7))`
let cont_z = hd
let cont_n = hd
SPLIT_ZERO vars sgns p cont_z cont_n
let k1 = ASSUME `&7 + x * (&11 + x * (&10 + y * &7)) < &0`
let k1 = ASSUME `&7 + x * (&11 + x * (&10 + y * &7)) = &0`
let k1 = ASSUME `&7 + x * (&11 + x * (&10 + y * &7)) <> &0`
let sgn_thm = k1
ASSERTSIGN vars [] k1
*)
let SPLIT_SIGN vars sgns p cont_p cont_n ex_thms =
let sgn_thm = try FINDSIGN vars sgns p
with Failure "FINDSIGN" ->
failwith "SPLIT_SIGN: no sign -- should have sign assumption by now" in
let gt_tm = mk_binop rgt p rzero in
let lt_tm = mk_binop rlt p rzero in
let op,_,_ = get_binop (concl sgn_thm) in
if op = rgt then cont_p sgns ex_thms
else if op = rlt then cont_n sgns ex_thms
else if op = req then failwith "SPLIT_SIGN: lead coef is 0"
else if op = rneq then
let or_thm = MATCH_MP signs_lem0002 sgn_thm in
(* < *)
let lt_sgns = ASSERTSIGN vars sgns (ASSUME lt_tm) in
let lt_thm = cont_n lt_sgns ex_thms in
let lt_thm' = DISCH lt_tm lt_thm in
(* > *)
let gt_sgns = ASSERTSIGN vars sgns (ASSUME gt_tm) in
let gt_thm = cont_p gt_sgns ex_thms in
let gt_thm' = DISCH gt_tm gt_thm in
(* combine *)
let ret = MATCH_MPL[signs_lem0003;or_thm;gt_thm';lt_thm'] in
(* matching problem... must continue by hand *)
let ldj,rdj = dest_disj (concl ret) in
let lcj,rcj = dest_conj ldj in
let a,_ = dest_binop rgt lcj in
let p,p1 = dest_beq rcj in
let _,rcj = dest_conj rdj in
let p2 = rhs rcj in
let pull_thm = ISPECL[a;p;p1;p2] PULL_CASES_THM_NZ in
let ret' = MATCH_EQ_MP (MATCH_MP pull_thm sgn_thm) ret in
ret'
else failwith "SPLIT_SIGN: unknown op";;
(*
let vars, sgns, p,cont_p, cont_n = !ss_vars,!ss_sgns,!ss_p,!ss_cont_p,!ss_cont_n
[`x`],
[ASSUME `&0 + x * &1 <> &0`; ARITH_RULE ` &1 > &0`],
`&0 + x * &1`
let ss_vars, ss_sgns, ss_p,ss_cont_p, ss_cont_n = ref [],ref [],ref `T`,ref (fun x -> TRUTH,[]),ref(fun x -> TRUTH,[]);;
ss_vars := vars;
ss_sgns := sgns;
ss_p := p;
ss_cont_p := cont_p;
ss_cont_n := cont_n;
let vars, sgns, p, cont_p, cont_n =
[`x:real`;`y:real`],
ASSERTSIGN vars empty_sgns (ASSUME `&0 + y * &1 <> &0`) ,
`&0 + y * &1`,
(fun x -> (ASSUME `P > def`,[])),
(fun x -> (ASSUME `sean > steph`,[]))
SPLIT_SIGN vars sgns p cont_z cont_n
let vars = [`x:real`;`y:real`]
let sgns = ASSERTSIGN vars [] (ASSUME `&7 + x * (&11 + x * (&10 + y * -- &7)) <> &0`)
let p = `&7 + x * (&11 + x * (&10 + y * -- &7))`
let cont_p = hd
let cont_n = hd
SPLIT_SIGN vars sgns p cont_p cont_n
let sgns = ASSERTSIGN vars [] (ASSUME `&7 + x * (&11 + x * (&10 + y * -- &7)) <> &0`)
let k1 = ASSUME `&7 + x * (&11 + x * (&10 + y * &7)) < &0`
let k1 = ASSUME `&7 + x * (&11 + x * (&10 + y * &7)) = &0`
let k1 = ASSUME `&7 + x * (&11 + x * (&10 + y * &7)) <> &0`
let sgn_thm = k1
ASSERTSIGN vars [] k1
*)