forked from brain-research/hol-light
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdedmatrix.ml
238 lines (208 loc) · 9.34 KB
/
dedmatrix.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
(* ====================================================================== *)
(* DEDMATRIX *)
(* ====================================================================== *)
(* ------------------------------------------------------------------------- *)
(* Deduce matrix for p,p1,...,pn from matrix for p',p1,...,pn,q0,...,qn *)
(* where qi = rem(p,pi) with p0 = p' *)
(* ------------------------------------------------------------------------- *)
let prove_nonconstant =
let nonconstant_tm = `nonconstant` in
fun pdiff_thm normal_thm ->
let thm = ONCE_REWRITE_RULE[GSYM pdiff_thm] normal_thm in
let ret = REWRITE_RULE[GSYM NORMAL_PDIFF] thm in
let f,_ = strip_comb (concl ret) in
if not (f = nonconstant_tm) then failwith "prove_nonconstant" else ret;;
let REMOVE_COLUMN1 mat_thm =
let mat_thm1 = MATCH_MP REMOVE_COL1 mat_thm in
REWRITE_RULE[MAP;HD;TL] mat_thm1;;
let APPENDIZE l n =
let lty = type_of l in
let ty = hd(snd(dest_type lty)) in
let app_tm = mk_const("APPEND",[ty,aty]) in
let l1,l2 = chop_list n (dest_list l) in
let app = mk_comb(mk_comb(app_tm,mk_list(l1,ty)),mk_list(l2,ty)) in
GSYM (REWRITE_CONV[APPEND] app);;
let REMOVE_INFINITIES thm =
let thm' = MATCH_MP INTERPMAT_TRIO thm in
let pts,_,sgns = dest_interpmat (concl thm') in
let p_thm = APPENDIZE pts (length (dest_list pts) - 2) in
let pts',_,sgns = dest_interpmat (concl thm') in
let s_thm = APPENDIZE sgns (length (dest_list sgns) - 5) in
let thm'' = MATCH_MP INTERPMAT_TRIO_TL (ONCE_REWRITE_RULE[p_thm;s_thm] thm') in
REWRITE_RULE[APPEND] thm'';;
let get_dirs =
let pos = `Pos` in
let neg = `Neg` in
fun lb_deriv ub_deriv ->
if lb_deriv = pos && ub_deriv = pos then INFIN_POS_POS
else if lb_deriv = pos && ub_deriv = neg then INFIN_POS_NEG
else if lb_deriv = neg && ub_deriv = pos then INFIN_NEG_POS
else if lb_deriv = neg && ub_deriv = neg then INFIN_NEG_NEG
else failwith "get_dirs: bad signs";;
let get_sing_dirs =
let pos = `Pos` in
let neg = `Neg` in
fun lb_deriv ub_deriv ->
if lb_deriv = pos && ub_deriv = pos then INFIN_SING_POS_POS
else if lb_deriv = pos && ub_deriv = neg then INFIN_SING_POS_NEG
else if lb_deriv = neg && ub_deriv = pos then INFIN_SING_NEG_POS
else if lb_deriv = neg && ub_deriv = neg then INFIN_SING_NEG_NEG
else failwith "get_dirs: bad signs";;
let aitvars,aitdiff,aitnorm,aitmat = ref [],ref TRUTH,ref TRUTH,ref TRUTH;;
(*
let vars,diff_thm,normal_thm,mat_thm = !aitvars,!aitdiff,!tnorm,!tmat
let vars,diff_thm,normal_thm,mat_thm = vars, pdiff_thm, normal_thm, mat_thm''
*)
let ADD_INFINITIES =
let real_app = `APPEND:real list -> real list -> real list` in
let sign_app = `APPEND:(sign list) list -> (sign list) list -> (sign list) list` in
let imat = `interpmat` in
let pos = `Pos` in
let neg = `Neg` in
let sl_ty = `:sign list` in
let real_ty = `:real` in
fun vars diff_thm normal_thm mat_thm ->
aitvars := vars;
aitdiff := diff_thm;
aitnorm := normal_thm;
aitmat := mat_thm;
let nc_thm = prove_nonconstant diff_thm normal_thm in
let pts,pols,sgns = dest_interpmat (concl mat_thm) in
let polsl = dest_list pols in
let p::p'::_ = polsl in
let p_thm = ABS (hd vars) (POLY_ENLIST_CONV vars (snd(dest_abs p))) in
let p'_thm = ONCE_REWRITE_RULE[GSYM diff_thm] (ABS (hd vars) (POLY_ENLIST_CONV vars (snd(dest_abs p')))) in
let pols_thm = REWRITE_CONV[p_thm;p'_thm] pols in
let sgnsl = dest_list sgns in
let sgns_len = length sgnsl in
let thm1 =
if sgns_len = 1 then
let sgn = (hd(tl(dest_list (hd sgnsl)))) in
let mp_thm =
if sgn = pos then INFIN_NIL_POS
else if sgn = neg then INFIN_NIL_NEG
else failwith "bad sign in mat" in
let mat_thm1 = MK_COMB(MK_COMB(AP_TERM imat (REFL pts), pols_thm),REFL sgns) in
let mat_thm2 = EQ_MP mat_thm1 mat_thm in
MATCH_MP (MATCH_MP mp_thm mat_thm2) nc_thm
else if sgns_len = 3 then
let lb_deriv = hd (tl (dest_list (hd sgnsl))) in
let ub_deriv = hd (tl (dest_list (last sgnsl))) in
let mp_thm = get_sing_dirs lb_deriv ub_deriv in
let mat_thm1 = MK_COMB(MK_COMB(AP_TERM imat (REFL pts), pols_thm),REFL sgns) in
let mat_thm2 = EQ_MP mat_thm1 mat_thm in
MATCH_MP (MATCH_MP mp_thm mat_thm2) nc_thm
else
let s1,s2 = chop_list (sgns_len - 3) sgnsl in
let s3 = mk_list(s1,sl_ty) in
let s4 = mk_comb(mk_comb(sign_app,s3),mk_list(s2,sl_ty)) in
let sgns_thm = prove(mk_eq(sgns,s4),REWRITE_TAC[APPEND]) in
let mat_thm1 = MK_COMB(MK_COMB(AP_TERM imat (REFL pts), pols_thm),sgns_thm) in
let mat_thm2 = EQ_MP mat_thm1 mat_thm in
let lb_deriv = hd (tl (dest_list (hd sgnsl))) in
let ub_deriv = hd (tl (dest_list (last sgnsl))) in
let mp_thm = get_dirs lb_deriv ub_deriv in
MATCH_MP (MATCH_MP mp_thm mat_thm2) nc_thm in
let thm2 = REWRITE_RULE[APPEND;GSYM pols_thm] thm1 in
let c = concl thm2 in
let x,bod = dest_exists c in
let x' = new_var real_ty in
let bod1 = subst [x',x] bod in
let assume_thm1 = ASSUME bod1 in
let x2,bod2 = dest_exists bod1 in
let x'' = new_var real_ty in
let assume_thm2 = ASSUME (subst [x'',x2] bod2) in
assume_thm2,(x',thm2),(x'',assume_thm1);;
(*
print_timers()
print_times()
reset_timers()
*)
let tvars,tsgns,tdivs,tdiff,tnorm,tcont,tmat,tex = ref [],ref [],ref [], ref TRUTH,ref TRUTH, ref (fun x y -> x), ref TRUTH, ref [];;
(*
let vars,sgns,div_thms,pdiff_thm,normal_thm,cont,mat_thm,ex_thms = !tvars,!tsgns,!tdivs,!tdiff,!tnorm,!tcont,!tmat,!tex
DEDMATRIX vars sgns div_thms pdiff_thm normal_thm cont mat_thm ex_thms
*)
let DEDMATRIX vars sgns div_thms pdiff_thm normal_thm cont mat_thm ex_thms =
try
tvars := vars;
tsgns := sgns;
tdivs := div_thms;
tdiff := pdiff_thm;
tnorm := normal_thm;
tmat := mat_thm;
tex := ex_thms;
tcont := cont;
let start_time = Sys.time() in
let pts,pols,signll = dest_interpmat (concl mat_thm) in
let mat_thm' = INFERPSIGN vars sgns mat_thm div_thms in
let mat_thm'' = CONDENSE mat_thm' in
let mat_thm''',(v1,exthm1),(v2,exthm2) = ADD_INFINITIES vars pdiff_thm normal_thm mat_thm'' in
let mat_thm4,new_ex_pairs = INFERISIGN vars pdiff_thm mat_thm''' ((v1,exthm1)::(v2,exthm2)::ex_thms) in
let mat_thm5 = REMOVE_INFINITIES mat_thm4 in
let mat_thm6 = REMOVE_COLUMN1 mat_thm5 in
let mat_thm7 = CONDENSE mat_thm6 in
(* hack for changing renamed vars *)
let mat_thm8 = CONV_RULE (RATOR_CONV (RAND_CONV (LIST_CONV (ALPHA_CONV (hd vars))))) mat_thm7 in
let ex_pairs = [(v1,exthm1);(v2,exthm2)] @ new_ex_pairs in
let cont' mat_thm ex_thms = cont mat_thm (ex_thms @ ex_pairs) in
cont' mat_thm8 ex_thms
with (Isign (false_thm,ex_thms)) ->
raise (Isign (false_thm,ex_thms))
| Failure x -> failwith ("DEDMATRIX: " ^ x);;
(* {{{ Examples *)
(*
let NOT_NIL_CONV tm =
let h,t = dest_cons tm in
ISPECL [h;t] NOT_CONS_NIL;;
let NORMAL_CONV tm =
let normalize_thm = POLY_NORMALIZE_CONV (mk_comb (`normalize`,tm)) in
let nonnil_thm = NOT_NIL_CONV tm in
let conj_thm = CONJ normalize_thm nonnil_thm in
REWRITE_RULE[GSYM normal] conj_thm;;
let vars = [`x:real`];;
let cont a b = a;;
let sgns = [ARITH_RULE `&1 > &0`];;
let normal_thm = NORMAL_CONV `[&1; &2; &3]`;;
let pdiff_thm = POLY_DIFF_CONV `poly_diff [&1; &1; &1; &1]`;;
let ex_thms = [];;
let _,l1 = PDIVIDES vars sgns `(&1 + x * (&1 + x * (&1 + x * &1)))` `(&1 + x * (&2 + x * &3))`;;
let _,l2 = PDIVIDES vars sgns `(&1 + x * (&1 + x * (&1 + x * &1)))` `(&2 + x * (-- &3 + x * &1))`;;
let _,l3 = PDIVIDES vars sgns `(&1 + x * (&1 + x * (&1 + x * &1)))` `(-- &4 + x * (&0 + x * &1))`;;
let div_thms = [l1;l2;l3];;
let mat_thm = ASSUME
`interpmat [x1; x2; x3; x4; x5]
[\x. &1 + x * (&2 + x * &3); \x. &2 + x * (-- &3 + x * &1); \x. -- &4 + x * (&0 + x * &1);
\x. &8 + x * &4; \x. -- &7 + x * &11; \x. &5 + x * &5]
[[Pos; Pos; Pos; Neg; Neg; Neg];
[Pos; Pos; Zero; Zero; Neg; Neg];
[Pos; Pos; Neg; Pos; Neg; Neg];
[Pos; Zero; Neg; Pos; Neg; Zero];
[Pos; Pos; Neg; Pos; Neg; Pos];
[Pos; Pos; Zero; Pos; Zero; Pos];
[Pos; Pos; Neg; Pos; Pos; Pos];
[Pos; Zero; Neg; Pos; Zero; Pos];
[Pos; Neg; Neg; Pos; Pos; Pos];
[Pos; Zero; Zero; Pos; Pos; Pos];
[Pos; Pos; Pos; Pos; Pos; Pos]]` ;;
time (DEDMATRIX vars sgns div_thms pdiff_thm normal_thm (fun x y -> x) mat_thm) []
*)
(* }}} *)
(* ---------------------------------------------------------------------- *)
(* Timing *)
(* ---------------------------------------------------------------------- *)
let REMOVE_COLUMN1 mat_thm =
let start_time = Sys.time() in
let res = REMOVE_COLUMN1 mat_thm in
remove_column1_timer +.= (Sys.time() -. start_time);
res;;
let ADD_INFINITIES vars pdiff_thm normal_thm mat_thm =
let start_time = Sys.time() in
let res = ADD_INFINITIES vars pdiff_thm normal_thm mat_thm in
add_infinities_timer +.= (Sys.time() -. start_time);
res;;
let REMOVE_INFINITIES thm =
let start_time = Sys.time() in
let res = REMOVE_INFINITIES thm in
remove_infinities_timer +.= (Sys.time() -. start_time);
res;;