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 *) (* ---------------------------------------------------------------------- *)