let TRAPOUT cont mat_thm ex_thms fm =
try
cont mat_thm ex_thms
with Isign (false_thm,ex_thms) ->
let ftm = mk_eq(fm,f_tm) in
let fthm = CONTR ftm false_thm in
let ex_thms' = sort (fun x y -> xterm_lt (fst y) (fst x)) ex_thms in
let fthm' = rev_itlist CHOOSE ex_thms' fthm in
fthm';;
let get_repeats l =
let rec get_repeats l seen ind =
match l with
[] -> []
| h::t ->
if mem h seen then ind::get_repeats t seen (ind + 1)
else get_repeats t (h::seen) (ind + 1) in
get_repeats l [] 0;;
let subtract_index l =
let rec subtract_index l ind =
match l with
[] -> []
| h::t -> (h - ind):: (subtract_index t (ind + 1)) in
subtract_index l 0;;
(*
subtract_index (get_repeats [1; 2; 1; 2 ; 3])
*)
let remove_column n isigns_thm =
let thms = interpsigns_thms2 isigns_thm in
let l,r = chop_list n thms in
let thms' = l @ tl r in
mk_interpsigns thms';;
let REMOVE_COLUMN n mat_thm =
let rol_thm,all_thm = interpmat_thms mat_thm in
let ints,part,signs = dest_all2 (concl all_thm) in
let part_thm = PARTITION_LINE_CONV (snd (dest_comb part)) in
let isigns_thms = CONJUNCTS (REWRITE_RULE[ALL2;part_thm] all_thm) in
let isigns_thms' = map (remove_column n) isigns_thms in
let all_thm' = mk_all2_interpsigns part_thm isigns_thms' in
let all_thm'' = REWRITE_RULE[GSYM part_thm] all_thm' in
let mat_thm' = mk_interpmat_thm rol_thm all_thm'' in
mat_thm';;
let SETIFY_CONV mat_thm =
let _,pols,_ = dest_interpmat(concl mat_thm) in
let pols' = dest_list pols in
let sols = setify (dest_list pols) in
let indices = map (fun p -> try index p sols with _ -> failwith "SETIFY: no index") pols' in
let subtract_cols = subtract_index (get_repeats indices) in
rev_itlist REMOVE_COLUMN subtract_cols mat_thm;;
(*
SETIFY_CONV
(ASSUME `interpmat [] [(\x. x + &1); (\x. x + &1); (\x. x + &2); (\x. x + &3); (\x. x + &1); (\x. x + &2)][[Pos; Pos; Pos; Pos; Neg; Zero]]`)
*)
(*
let duplicate_column i j isigns_thm =
let thms = interpsigns_thms2 isigns_thm in
let col = ith i thms in
let l,r = chop_list j thms in
let thms' = l @ (col :: r) in
mk_interpsigns thms';;
let DUPLICATE_COLUMN i j mat_thm =
let rol_thm,all_thm = interpmat_thms mat_thm in
let ints,part,signs = dest_all2 (concl all_thm) in
let part_thm = PARTITION_LINE_CONV (snd (dest_comb part)) in
let isigns_thms = CONJUNCTS (REWRITE_RULE[ALL2;part_thm] all_thm) in
let isigns_thms' = map (duplicate_column i j) isigns_thms in
let all_thm' = mk_all2_interpsigns part_thm isigns_thms' in
let all_thm'' = REWRITE_RULE[GSYM part_thm] all_thm' in
let mat_thm' = mk_interpmat_thm rol_thm all_thm'' in
mat_thm';;
*)
let duplicate_columns new_cols isigns_thm =
let thms = interpsigns_thms2 isigns_thm in
let thms' = map (fun i -> el i thms) new_cols in
mk_interpsigns thms';;
let DUPLICATE_COLUMNS mat_thm ls =
if ls = [] then if mat_thm = empty_mat then empty_mat else failwith "empty duplication list" else
let rol_thm,all_thm = interpmat_thms mat_thm in
let ints,part,signs = dest_all2 (concl all_thm) in
let part_thm = PARTITION_LINE_CONV (snd (dest_comb part)) in
let isigns_thms = CONJUNCTS (REWRITE_RULE[ALL2;part_thm] all_thm) in
let isigns_thms' = map (duplicate_columns ls) isigns_thms in
let all_thm' = mk_all2_interpsigns part_thm isigns_thms' in
let all_thm'' = REWRITE_RULE[GSYM part_thm] all_thm' in
let mat_thm' = mk_interpmat_thm rol_thm all_thm'' in
mat_thm';;
let DUPLICATE_COLUMNS mat_thm ls =
let start_time = Sys.time() in
let res = DUPLICATE_COLUMNS mat_thm ls in
duplicate_columns_timer +.= (Sys.time() -. start_time);
res;;
let UNMONICIZE_ISIGN vars monic_thm isign_thm =
let _,_,sign = dest_interpsign isign_thm in
let const = (fst o dest_mult o lhs o concl) monic_thm in
let const_thm = SIGN_CONST const in
let op,_,_ = get_binop (concl const_thm) in
let mp_thm =
if op = rgt then
if sign = spos_tm then gtpos
else if sign = sneg_tm then gtneg
else if sign = szero_tm then gtzero
else failwith "bad sign"
else if op = rlt then
if sign = spos_tm then ltpos
else if sign = sneg_tm then ltneg
else if sign = szero_tm then ltzero
else failwith "bad sign"
else (failwith "bad op") in
let monic_thm' = GEN (hd vars) monic_thm in
MATCH_MPL[mp_thm;monic_thm';const_thm;isign_thm];;
let UNMONICIZE_ISIGNS vars monic_thms isigns_thm =
let isign_thms = interpsigns_thms2 isigns_thm in
let isign_thms' = map2 (UNMONICIZE_ISIGN vars) monic_thms isign_thms in
mk_interpsigns isign_thms';;
let UNMONICIZE_MAT vars monic_thms mat_thm =
if monic_thms = [] then mat_thm else
let rol_thm,all_thm = interpmat_thms mat_thm in
let ints,part,signs = dest_all2 (concl all_thm) in
let part_thm = PARTITION_LINE_CONV (snd (dest_comb part)) in
let consts = map (fst o dest_mult o lhs o concl) monic_thms in
let isigns_thms = CONJUNCTS (REWRITE_RULE[ALL2;part_thm] all_thm) in
let isigns_thms' = map (UNMONICIZE_ISIGNS vars monic_thms) isigns_thms in
let all_thm' = mk_all2_interpsigns part_thm isigns_thms' in
let all_thm'' = REWRITE_RULE[GSYM part_thm] all_thm' in
let mat_thm' = mk_interpmat_thm rol_thm all_thm'' in
mat_thm';;
let UNMONICIZE_MAT vars monic_thms mat_thm =
let start_time = Sys.time() in
let res = UNMONICIZE_MAT vars monic_thms mat_thm in
unmonicize_mat_timer +.= (Sys.time() -. start_time);
res;;
(* {{{ Examples *)
(*
let vars,monic_thms,mat_thm =
[], [], empty_mat
let monic_thm = hd monic_thms
length isigns_thms
MONIC_CONV [rx] `&1 + x * (&1 + x * (&1 + x * &7))`
let isign_thm = hd isign_thms
let isigns_thm = hd isigns_thms
mk_interpsigns [TRUTH];;
let ls = [0;1;2;0;1;2]
let mat_thm,ls = empty_mat,[]
1,3,
DUPLICATE_COLUMNS
(ASSUME `interpmat [] [(\x. x + &1); (\x. x + &1); (\x. x + &2); (\x. x + &3); (\x. x + &1); (\x. x + &2)][[Pos; Pos; Pos; Pos; Neg; Zero]]`)
[5]
duplicate_columns [] (ASSUME `interpsigns [] (\x. T) []`)
let new_cols, isigns_thm = [],(ASSUME `interpsigns [] (\x. T) []`)
let isigns_thm = hd isigns_thms
*)
(* }}} *)
let SWAP_HEAD_COL_ROW i isigns_thm =
let s_thms = interpsigns_thms2 isigns_thm in
let s_thms' = insertat i (hd s_thms) (tl s_thms) in
mk_interpsigns s_thms';;
let SWAP_HEAD_COL i mat_thm =
let rol_thm,all_thm = interpmat_thms mat_thm in
let ints,part,signs = dest_all2 (concl all_thm) in
let part_thm = PARTITION_LINE_CONV (snd (dest_comb part)) in
let isigns_thms = CONJUNCTS (REWRITE_RULE[ALL2;part_thm] all_thm) in
let isigns_thms' = map (SWAP_HEAD_COL_ROW i) isigns_thms in
let all_thm' = mk_all2_interpsigns part_thm isigns_thms' in
mk_interpmat_thm rol_thm all_thm';;
let SWAP_HEAD_COL i mat_thm =
let start_time = Sys.time() in
let res = SWAP_HEAD_COL i mat_thm in
swap_head_col_timer +.= (Sys.time() -. start_time);
res;;
let LENGTH_CONV =
let alength_tm = `LENGTH:(A list) -> num` in
fun tm ->
try
let ty = type_of tm in
let lty,[cty] = dest_type ty in
if lty <> "list" then failwith "LENGTH_CONV: not a list" else
let ltm = mk_comb(inst[cty,aty] alength_tm,tm) in
let lthm = REWRITE_CONV[LENGTH] ltm in
MATCH_MP main_lem000 lthm
with _ -> failwith "LENGTH_CONV";;
let LAST_NZ_CONV =
let alast_tm = `LAST:(A list) -> A` in
fun nz_thm tm ->
try
let ty = type_of tm in
let lty,[cty] = dest_type ty in
if lty <> "list" then failwith "LAST_NZ_CONV: not a list" else
let ltm = mk_comb(inst[cty,aty] alast_tm,tm) in
let lthm = REWRITE_CONV[LAST;NOT_CONS_NIL] ltm in
MATCH_MPL[main_lem001;nz_thm;lthm]
with _ -> failwith "LAST_NZ_CONV";;
let rec first f l =
match l with
[] -> failwith "first"
| h::t -> if can f h then f h else first f t;;
let NEQ_RULE thm =
let thms = CONJUNCTS main_lem002 in
first (C MATCH_MP thm) thms;;
(*
NEQ_CONV (ARITH_RULE `~(&11 <= &2)`)
*)
let NORMAL_LIST_CONV nz_thm tm =
let nz_thm' = NEQ_RULE nz_thm in
let len_thm = LENGTH_CONV tm in
let last_thm = LAST_NZ_CONV nz_thm' tm in
let cthm = CONJ len_thm last_thm in
MATCH_EQ_MP (GSYM (REWRITE_RULE[GSYM NEQ] NORMAL_ID)) cthm;;
(*
|- poly_diff [&0; &0; &0 + a * &1] = [&0; &0 + a * &2]
let tm = `poly_diff [&0; &0 + a * &1]`
*)
let pdiff_tm = `poly_diff`;;
let GEN_POLY_DIFF_CONV vars tm =
let thm1 = POLY_ENLIST_CONV vars tm in
let l,x = dest_poly (rhs (concl thm1)) in
let thm2 = CANON_POLY_DIFF_CONV (mk_comb(pdiff_tm,l)) in
let thm3 = CONV_RULE (RAND_CONV (LIST_CONV (POLYNATE_CONV vars))) thm2 in
thm3;;
(*
if \x. p = \x. q, where \x. p is the leading polynomial
replace p by q in mat_thm,
*)
(*
let peq,mat_thm = !rppeq,!rpmat
*)
let rppeq,rpmat = ref TRUTH,ref TRUTH;;
let REPLACE_POL =
let imat_tm = `interpmat` in
fun peq mat_thm ->
rppeq := peq;
rpmat := mat_thm;
let pts,pols,sgnll = dest_interpmat (concl mat_thm) in
let rep_p = lhs(concl peq) in
let i = try index rep_p (dest_list pols) with _ -> failwith "REPLACE_POL: index" in
let thm1 = EL_CONV (fun x -> GEN_REWRITE_CONV I [peq] x) i pols in
end_itlist (C (curry MK_COMB)) (rev [REFL imat_tm;REFL pts;thm1;REFL sgnll]);;
let REPLACE_POL peq mat_thm =
let start_time = Sys.time() in
let res = REPLACE_POL peq mat_thm in
replace_pol_timer +.= (Sys.time() -. start_time);
res;;
(* {{{ Examples *)
(*
let peq,mat_thm =
ASSUME `(\x. &0) =
(\x. &0 + a * ((&0 + b * (&0 + b * -- &1)) + a * (&0 + c * &4)))`,
ASSUME `interpmat [x_44] [\x. (&0 + b * &1) + x * (&0 + a * &2); \x. &0]
[[Pos; Zero]; [Zero; Zero]; [Neg; Zero]]`
let peq = ASSUME `(\x. &1 + x * (&1 + x * (&1 + x * &1))) = (\x. &1 + x)`
REPLACE_POL peq mat_thm
is_constant [`y:real`] `&1 + x * -- &1`
let vars,pols,cont,sgns,ex_thms =
[`c:real`; `b:real`; `a:real`],
[`&0 + c * &1`],
(fun x y -> x),
[ASSUME `&0 + b * (&0 + b * -- &1) = &0`;
ASSUME ` &0 + b * (&0 + b * (&0 + a * -- &1)) = &0`;
ASSUME `&0 + a * (&0 + a * &1) = &0`;ASSUME `&0 + b * &1 = &0`;
ASSUME `&0 + a * &1 = &0`; ASSUME ` &1 > &0`],
[]
*)
(* }}} *)
(* ---------------------------------------------------------------------- *)
(* Factoring *)
(* ---------------------------------------------------------------------- *)
let UNFACTOR_ISIGN vars xsign_thm pol isign_thm =
let x = hd vars in
let k,pol' = weakfactor x pol in
if k = 0 then isign_thm else
let fact_thm = GEN x (GSYM (WEAKFACTOR_CONV x pol)) in
let par_thm = PARITY_CONV (mk_small_numeral k) in
let _,_,xsign = dest_interpsign xsign_thm in
let _,_,psign = dest_interpsign isign_thm in
let parity,_ = dest_comb (concl par_thm) in
if xsign = spos_tm then
let mp_thm =
if psign = spos_tm then factor_pos_pos
else if psign = sneg_tm then factor_pos_neg
else if psign = szero_tm then factor_pos_zero
else failwith "bad sign" in
let ret = BETA_RULE(MATCH_MPL[mp_thm;xsign_thm;isign_thm]) in
MATCH_MP ret fact_thm
else if xsign = szero_tm then
let k_thm = prove(mk_neg(mk_eq(mk_small_numeral k,nzero)),ARITH_TAC) in
let mp_thm =
if psign = spos_tm then factor_zero_pos
else if psign = sneg_tm then factor_zero_neg
else if psign = szero_tm then factor_zero_zero
else failwith "bad sign" in
let ret = BETA_RULE(MATCH_MPL[mp_thm;xsign_thm;isign_thm;k_thm]) in
MATCH_MP ret fact_thm
else if xsign = sneg_tm & parity = even_tm then
let k_thm = prove(mk_neg(mk_eq(mk_small_numeral k,nzero)),ARITH_TAC) in
let mp_thm =
if psign = spos_tm then factor_neg_even_pos
else if psign = sneg_tm then factor_neg_even_neg
else if psign = szero_tm then factor_neg_even_zero
else failwith "bad sign" in
let ret = BETA_RULE(MATCH_MPL[mp_thm;xsign_thm;isign_thm;par_thm;k_thm]) in
MATCH_MP ret fact_thm
else if xsign = sneg_tm & parity = odd_tm then
let k_thm = prove(mk_neg(mk_eq(mk_small_numeral k,nzero)),ARITH_TAC) in
let mp_thm =
if psign = spos_tm then factor_neg_odd_pos
else if psign = sneg_tm then factor_neg_odd_neg
else if psign = szero_tm then factor_neg_odd_zero
else failwith "bad sign" in
let ret = BETA_RULE(MATCH_MPL[mp_thm;xsign_thm;isign_thm;par_thm;k_thm]) in
MATCH_MP ret fact_thm
else failwith "bad something...";
;
(* {{{ Examples *)
(*
let vars,xsign_thm,pol,isign_thm =
[ry;rx],
`interpsign (\x. x < x1) (\x. x) Pos`,
ASSUME `interpsign (\x. x < x_254) (\y. &0 + y * &1) Neg`
`\x. &0 + x * (&4 + x * &6)`,
ASSUME `interpsign (\x. x < x1) (\x. &4 + x * &6) Pos`
let xsign_thm,pol,isign_thm =
ASSUME `interpsign (\x. x < x1) (\x. x) Pos`,
`\x. &0 + x * (&4 + x * &6)`,
ASSUME `interpsign (\x. x < x1) (\x. &4 + x * &6) Pos`
*)
(* }}} *)
let UNFACTOR_ISIGNS vars pols isigns_thm =
let isign_thms = interpsigns_thms2 isigns_thm in
let isign_thms' = map2 (UNFACTOR_ISIGN vars (hd isign_thms)) pols (tl isign_thms) in
mk_interpsigns isign_thms';;
let UNFACTOR_MAT vars pols mat_thm =
let rol_thm,all_thm = interpmat_thms mat_thm in
let ints,part,signs = dest_all2 (concl all_thm) in
let part_thm = PARTITION_LINE_CONV (snd (dest_comb part)) in
let isigns_thms = CONJUNCTS (REWRITE_RULE[ALL2;part_thm] all_thm) in
let isigns_thms' = map (UNFACTOR_ISIGNS vars pols) isigns_thms in
let all_thm' = mk_all2_interpsigns part_thm isigns_thms' in
let all_thm'' = REWRITE_RULE[GSYM part_thm] all_thm' in
let mat_thm' = mk_interpmat_thm rol_thm all_thm'' in
mat_thm';;
let UNFACTOR_MAT vars pols mat_thm =
let start_time = Sys.time() in
let res = UNFACTOR_MAT vars pols mat_thm in
unfactor_mat_timer +.= (Sys.time() -. start_time);
res;;
(* {{{ Examples *)
(*
#untrace UNFACTOR_ISIGN
let isigns_thm = el 0 isigns_thms
UNFACTOR_ISIGNS pols isigns_thm
let isign_thm = el 1 isign_thm
pols
let isigns_thms' = map (UNFACTOR_ISIGNS pols) isigns_thms in
let xsign_thm = hd isign_thms
let xsign_thm = ASSUME `interpsign (\x. x < x1) (\x. x) Neg`
let isign_thm = hd (tl isign_thms)
let pol = hd pols
let pol = `\x. &0 + x * (&0 + x * (&0 + x * (&0 + y * &1)))`
let isigns_thm = hd isigns_thms
let vars = [rx;ry;rz]
let pols =
[`\x. &0 + x * (&0 + x * (&0 + y * &1))`; `\x. &0 + x * (&4 + x * &6)`; `\x. &3 + x * (&6 + x * &9)`;
`\x. &0 + x * (&0 + x * (&0 + x * (&0 + z * &1)))`; `\x. -- &4 + x * (&0 + x * &1)`]
let mat_thm = ASSUME
`interpmat [x1; x2; x3; x4; x5]
[\x. x; \x. &0 + y * &1; \x. &4 + x * &6; \x. &3 + x * (&6 + x * &9);
\x. &0 + z * &1; \x. -- &4 + x * (&0 + x * &1)]
[[Pos; Pos; Pos; Neg; Neg; Neg];
[Neg; Pos; Zero; Zero; Neg; Neg];
[Neg; Pos; Neg; Pos; Neg; Neg];
[Neg; Pos; Neg; Pos; Neg; Zero];
[Neg; Pos; Neg; Pos; Neg; Pos];
[Zero; Pos; Neg; Pos; Zero; Pos];
[Pos; Pos; Neg; Pos; Pos; Pos];
[Pos; Zero; Neg; Pos; Pos; Pos];
[Pos; Neg; Neg; Pos; Pos; Pos];
[Pos; Zero; Zero; Pos; Pos; Pos];
[Pos; Pos; Pos; Pos; Pos; Pos]]`
UNFACTOR_MAT pols mat_thm
*)
(* }}} *)
let message_time s f x =
report s;
time f x;;
(* ---------------------------------------------------------------------- *)
(* Matrix *)
(* ---------------------------------------------------------------------- *)
let matrix_count,splitzero_count,splitsigns_count,monicize_count = ref 0,ref 0,ref 0,ref 0;;
let reset_counts() = matrix_count := 0;splitzero_count := 0;splitsigns_count := 0;monicize_count := 0;;
let print_counts() = !matrix_count,!splitzero_count,!splitsigns_count,!monicize_count;;
(*
let vars,dun,pols,cont,sgns,ex_thms,fm = !szvars,!szdun,!szpols,!szcont,!szsgns,!szex_thms,!szfm
*)
let rec MATRIX vars pols cont sgns ex_thms fm =
incr matrix_count;
if pols = [] then TRAPOUT cont empty_mat [] fm else
if exists (is_constant vars) pols then
let p = find (is_constant vars) pols in
let i = try index p pols with _ -> failwith "MATRIX: no such pol" in
let pols1,pols2 = chop_list i pols in
let pols' = pols1 @ tl pols2 in
let cont' = MATINSERT vars i (FINDSIGN vars sgns p) cont in
MATRIX vars pols' cont' sgns ex_thms fm
else
let kqs = map (weakfactor (hd vars)) pols in
if exists (fun (k,q) -> k <> 0 & not(is_constant vars q)) kqs then
let pols' = poly_var(hd vars) :: map snd kqs in
let ks = map fst kqs in
let cont' mat_thm ex_thms = cont (UNFACTOR_MAT vars pols mat_thm) ex_thms in
MATRIX vars pols' cont' sgns ex_thms fm
else
let d = itlist (max o degree_ vars) pols (-1) in
let p = find (fun p -> degree_ vars p = d) pols in
let pl_thm = POLY_ENLIST_CONV vars p in
let pl = rhs(concl pl_thm) in
let l,x = dest_poly pl in
let pdiff_thm = GEN_POLY_DIFF_CONV vars p in
let p'l = rhs (concl pdiff_thm) in
let p' = mk_comb(mk_comb(poly_tm,p'l),hd vars) in
let p'thm = (POLY_DELIST_CONV THENC (POLYNATE_CONV vars)) p' in
let p'c = rhs (concl p'thm) in
let hdp' = last (dest_list p'l) in
let sign_thm = FINDSIGN vars sgns hdp' in
let normal_thm = NORMAL_LIST_CONV sign_thm p'l in
let i = try index p pols with _ -> failwith "MATRIX: no such pol1" in
let qs = let p1,p2 = chop_list i pols in p'c::p1 @ tl p2 in
let gs,div_thms = unzip (map (PDIVIDES vars sgns p) qs) in
let cont' mat_thm = cont (SWAP_HEAD_COL i mat_thm) in
let dedcont mat_thm ex_thms =
DEDMATRIX vars sgns div_thms pdiff_thm normal_thm cont' mat_thm ex_thms in
SPLITZERO vars qs gs dedcont sgns ex_thms fm
and SPLITZERO vars dun pols cont sgns ex_thms fm =
incr splitzero_count;
match pols with
[] -> SPLITSIGNS vars [] dun cont sgns ex_thms fm
| p::ops ->
if p = rzero then
let cont' mat_thm ex_thms = MATINSERT vars (length dun) (REFL rzero) cont mat_thm ex_thms in
SPLITZERO vars dun ops cont' sgns ex_thms fm
else
let hp = behead vars p in
let h = head vars p in
let nzcont =
let tmp = SPLITZERO vars (dun@[p]) ops cont in
fun sgns ex_thms -> tmp sgns ex_thms fm in
let zcont =
let tmp = SPLITZERO vars dun (hp :: ops) in
fun sgns ex_thms ->
let zthm = FINDSIGN vars sgns h in
let b_thm = GSYM (BEHEAD vars zthm p) in
let lam_thm = ABS (hd vars) b_thm in
let cont' mat_thm ex_thms =
let mat_thm' = REPLACE_POL (lam_thm) mat_thm in
let mat_thm'' = MATCH_EQ_MP mat_thm' mat_thm in
cont mat_thm'' ex_thms in
tmp cont' sgns ex_thms fm in
SPLIT_ZERO (tl vars) sgns (head vars p) zcont nzcont ex_thms
and SPLITSIGNS vars dun pols cont sgns ex_thms fm =
incr splitsigns_count;
match pols with
[] -> MONICIZE vars dun cont sgns ex_thms fm
(* [] -> MATRIX vars dun cont sgns ex_thms fm *)
| p::ops ->
let cont' sgns ex_thms = SPLITSIGNS vars (dun@[p]) ops cont sgns ex_thms fm in
SPLIT_SIGN (tl vars) sgns (head vars p) cont' cont' ex_thms
and MONICIZE vars pols cont sgns ex_thms fm =
incr monicize_count;
let monic_thms = map (MONIC_CONV vars) pols in
let monic_pols = map (rhs o concl) monic_thms in
let sols = setify monic_pols in
let indices = map (fun p -> try index p sols with _ -> failwith "MONICIZE: no such pol") monic_pols in
let transform mat_thm =
let mat_thm' = DUPLICATE_COLUMNS mat_thm indices in
(* mat_thm' *)
UNMONICIZE_MAT vars monic_thms mat_thm' in
let cont' mat_thm ex_thms = cont (transform mat_thm) ex_thms in
MATRIX vars sols cont' sgns ex_thms fm
;;
(* {{{ Examples *)
(*
let vars,pols,sgns,ex_thms = [],[],[],[]
let mat_thm = mat_thm'
monic_thms
let vars = [rx]
let mat_thm = ASSUME
`interpmat [x1; x2; x3; x4; x5]
[(\x. &1 + x * (&2 + x * &3)); (\x. &2 + x * (&4 + x * &6)); \x. &3 + x * (&6 + x * &9); \x. &2 + x * (-- &3 + x * &1); \x. -- &4 + x * (&0 + x * &1); \x. &8 + x * &4]
[[Pos; Pos; Pos; Neg; Neg; Neg];
[Pos; Pos; Zero; Zero; Neg; Neg];
[Pos; Pos; Neg; Pos; Neg; Neg];
[Pos; Pos; Neg; Pos; Neg; Zero];
[Pos; Pos; Neg; Pos; Neg; Pos];
[Pos; Pos; Neg; Pos; Zero; Pos];
[Pos; Pos; Neg; Pos; Pos; Pos];
[Pos; Zero; Neg; Pos; Pos; Pos];
[Pos; Neg; Neg; Pos; Pos; Pos];
[Pos; Zero; Zero; Pos; Pos; Pos];
[Pos; Pos; Pos; Pos; Pos; Pos]]`
let mat_thm = ASSUME
`interpmat [x1; x2; x3; x4; x5]
[\x. -- &4 + x * (&0 + x * &1); \x. &2 + x * &1; \x. &2 + x * (-- &3 + x * &1); \x. &1 / &3 + x * (&2 / &3 + x * &1)]
[[Pos; Pos; Pos; Neg];
[Pos; Pos; Zero; Zero];
[Pos; Pos; Neg; Pos];
[Pos; Pos; Neg; Pos];
[Pos; Pos; Neg; Pos];
[Pos; Pos; Neg; Pos];
[Pos; Pos; Neg; Pos];
[Pos; Zero; Neg; Pos];
[Pos; Neg; Neg; Pos];
[Pos; Zero; Zero; Pos];
[Pos; Pos; Pos; Pos]]`;;
let vars = [rx]
let pols = [`&1 + x * (&2 + x * &3)`;`&2 + x * (&4 + x * &6)`;`&3 + x * (&6 + x * &9)`; `&2 + x * (-- &3 + x * &1)`;`-- &4 + x * (&0 + x * &1)`;`&8 + x * &4`]
*)
(* }}} *)
(* ---------------------------------------------------------------------- *)
(* Set up RQE *)
(* ---------------------------------------------------------------------- *)
let polynomials tm =
let rec polynomials tm =
if tm = t_tm or tm = f_tm then []
else if is_conj tm or is_disj tm or is_imp tm or is_iff tm then
let _,l,r = get_binop tm in polynomials l @ polynomials r
else if is_neg tm then polynomials (dest_neg tm)
else if
can (dest_binop rlt) tm or
can (dest_binop rgt) tm or
can (dest_binop rle) tm or
can (dest_binop rge) tm or
can (dest_binop req) tm or
can (dest_binop rneq) tm then
let _,l,_ = get_binop tm in [l]
else failwith "not a fol atom" in
setify (polynomials tm);;
(* {{{ Examples *)
(*
let pols = polynomials `(poly [&1; -- &2] x > &0 ==> poly [&1; -- &2] x >= &0 /\ (poly [&8] x = &0)) /\ ~(poly [y] x <= &0)`
*)
(* }}} *)
let BASIC_REAL_QELIM_CONV vars fm =
let x,bod = dest_exists fm in
let pols = polynomials bod in
let cont mat_thm ex_thms =
let ex_thms' = sort (fun x y -> xterm_lt (fst y) (fst x)) ex_thms in
let comb_thm = COMBINE_TESTFORMS x mat_thm bod in
let comb_thm' = rev_itlist CHOOSE ex_thms' comb_thm in
comb_thm' in
let ret_thm = SPLITZERO (x::vars) [] pols cont empty_sgns [] fm in
PURE_REWRITE_RULE[NEQ] ret_thm;;
let REAL_QELIM_CONV fm =
reset_counts();
((LIFT_QELIM_CONV POLYATOM_CONV (EVALC_CONV THENC SIMPLIFY_CONV)
BASIC_REAL_QELIM_CONV) THENC EVALC_CONV THENC SIMPLIFY_CONV) fm;;
(* ---------------------------------------------------------------------- *)
(* timers *)
(* ---------------------------------------------------------------------- *)