forked from brain-research/hol-light
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinferpsign.ml
361 lines (320 loc) · 13 KB
/
inferpsign.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
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
(* ====================================================================== *)
(* INFERPSIGN *)
(* ====================================================================== *)
(* ------------------------------------------------------------------------- *)
(* Infer sign of p(x) at points from corresponding qi(x) with pi(x) = 0 *)
(* ------------------------------------------------------------------------- *)
(* ---------------------------------------------------------------------- *)
(* INFERPSIGN *)
(* ---------------------------------------------------------------------- *)
let isign_eq_zero thm =
let __,_,sign = dest_interpsign thm in
sign = szero_tm;;
let isign_lt_zero thm =
let __,_,sign = dest_interpsign thm in
sign = sneg_tm;;
let isign_gt_zero thm =
let __,_,sign = dest_interpsign thm in
sign = spos_tm;;
(*
let p_thm,q_thm = ith 1 split_thms
*)
let inferpsign_row vars sgns p_thm q_thm div_thms =
let pthms = map (BETA_RULE o (PURE_REWRITE_RULE[interpsigns])) (interpsigns_thms2 p_thm) in
let qthms = map (BETA_RULE o (PURE_REWRITE_RULE[interpsigns])) (interpsigns_thms2 q_thm) in
let _,set,_ = dest_interpsigns p_thm in
if can (get_index isign_eq_zero) pthms then (* there's a zero *)
let ind = get_index isign_eq_zero pthms in
let pthm = ith ind pthms in
let qthm = ith ind qthms in
let div_thm = ith ind div_thms in
let div_thm' = GEN (hd vars) div_thm in
let aks,pqr = dest_eq (concl div_thm) in
let ak,s = dest_mult aks in
let a,k = dest_pow ak in
let pq,r = dest_plus pqr in
let p,q = dest_mult pq in
let parity_thm = PARITY_CONV k in
let evenp = fst(dest_comb (concl parity_thm)) = even_tm in
let sign_thm = FINDSIGN vars sgns a in
let op,_,_ = get_binop (concl sign_thm) in
if evenp then
let nz_thm =
if op = rlt then MATCH_MP ips_lt_nz_thm sign_thm
else if op = rgt then MATCH_MP ips_gt_nz_thm sign_thm
else if op = rneq then sign_thm
else failwith "inferpsign: 0" in
let imp_thms =
CONJUNCTS(ISPEC set (MATCH_MPL[EVEN_DIV_LEM;div_thm';nz_thm;parity_thm])) in
let _,_,qsign = dest_interpsign qthm in
let mp_thm =
if qsign = sneg_tm then ith 0 imp_thms
else if qsign = spos_tm then ith 1 imp_thms
else if qsign = szero_tm then ith 2 imp_thms
else failwith "inferpsign: 1" in
let final_thm = MATCH_MPL[mp_thm;pthm;qthm] in
mk_interpsigns (final_thm::pthms)
else (* k is odd *)
if op = rgt then (* a > &0 *)
let imp_thms =
CONJUNCTS(ISPEC set (MATCH_MPL[GT_DIV_LEM;div_thm';sign_thm])) in
let _,_,qsign = dest_interpsign qthm in
let mp_thm =
if qsign = sneg_tm then ith 0 imp_thms
else if qsign = spos_tm then ith 1 imp_thms
else if qsign = szero_tm then ith 2 imp_thms
else failwith "inferpsign: 1" in
let final_thm = MATCH_MPL[mp_thm;pthm;qthm] in
mk_interpsigns (final_thm::pthms)
else
failwith "inferpsign: shouldn`t reach this point with an odd power and negative sign! See PDIVIDES and return the correct div_thm"
else (* no zero *)
let p = snd(dest_mult (lhs(concl (hd div_thms)))) in
let p1 = mk_abs(hd vars,p) in
let pthm = ISPECL [set;p1] unknown_thm in
mk_interpsigns (pthm::pthms);;
(* {{{ Doc *)
(*
split_interpsigns
|- interpsigns
[p0; p1; p2; q0; q1; q2]
(\x. x < x1)
[Pos; Pos; Pos; Neg; Neg; Neg]
-->
(
|- interpsigns
[p0; p1; p2]
(\x. x < x1)
[Pos; Pos; Pos]
,
|- interpsigns
[q0; q1; q2]
(\x. x < x1)
[ Neg; Neg; Neg]
)
*)
(* }}} *)
let split_interpsigns thm =
let thms = interpsigns_thms2 thm in
let n = length thms / 2 in
let l,r = chop_list n thms in
(mk_interpsigns l,mk_interpsigns r);;
let INFERPSIGN vars sgns mat_thm div_thms =
let pts,pols,signs = dest_interpmat (concl mat_thm) in
let n = length (dest_list pols) / 2 in
let rol_thm,sgn_thm = interpmat_thms mat_thm in
let part_thm = PARTITION_LINE_CONV (snd (dest_comb (concl rol_thm))) in
let conj_thms = CONJUNCTS(REWRITE_RULE[ALL2;part_thm] sgn_thm) in
let split_thms = map split_interpsigns conj_thms in
let conj_thms' = map (fun (x,y) -> inferpsign_row vars sgns x y div_thms) split_thms in
let all_thm = mk_all2_interpsigns part_thm conj_thms' in
let mat_thm' = mk_interpmat_thm rol_thm all_thm in
mat_thm';;
(* ---------------------------------------------------------------------- *)
(* Opt *)
(* ---------------------------------------------------------------------- *)
let MK_REP =
let rep_tm = `REPLICATE:num -> sign -> sign list` in
let len_tm = `LENGTH:real list -> num` in
let one = `1` in
let two = `2` in
let unknown = `Unknown` in
fun pts ->
let num = mk_binop np (mk_binop nm two (mk_comb(len_tm,pts))) one in
let len = length (dest_list pts) in
let num2 = MK_SUC (2 * len + 1) in
let lthm = ARITH_SIMP_CONV[LENGTH] num in
let lthm2 = TRANS lthm num2 in
let lthm3 = AP_THM (AP_TERM rep_tm lthm2) unknown in
REWRITE_RULE[REPLICATE] lthm3;;
let INSERT_UNKNOWN_COL =
fun mat_thm p ->
let pts,_,_ = dest_interpmat (concl mat_thm) in
let rep_thm = MK_REP pts in
let mat_thm' = MATCH_MP INFERPSIGN_MATINSERT_THM mat_thm in
let mat_thm'' = PURE_REWRITE_RULE[MAP2;rep_thm] mat_thm' in
ISPEC p mat_thm'';;
let REMOVE_QS =
fun mat_thm ->
let _,pols,_ = dest_interpmat (concl mat_thm) in
let len = length (dest_list pols) in
if not (len mod 2 = 1) then failwith "odd pols?" else
let mat_thm' = funpow (len / 2) (MATCH_MP REMOVE_LAST) mat_thm in
REWRITE_RULE[MAP;BUTLAST;NOT_CONS_NIL;TL;HD;] mat_thm';;
let SPLIT_LIST n l ty =
let l' = dest_list l in
let l1',l2' = chop_list n l' in
let l1,l2 = (mk_list(l1',ty),mk_list(l2',ty)) in
let app_tm = mk_const("APPEND",[ty,aty]) in
let l3 = mk_comb(mk_comb(app_tm,l1),l2) in
SYM(REWRITE_CONV[APPEND] l3);;
(*
let thm = asign
*)
let prove_nonzero thm =
let op,_,_ = get_binop (concl thm) in
if op = rgt then MATCH_MP ips_gt_nz_thm thm
else if op = rlt then MATCH_MP ips_lt_nz_thm thm
else if op = rneq then thm
else failwith "prove_nonzero: bad op";;
(*
let mat_thm = mat_thm'
let ind = 7
*)
let INFERPT =
let unknown = `Unknown` in
let zero = `Zero` in
let pos = `Pos` in
let neg = `Neg` in
let pow = `(pow)` in
let even_tm = `(EVEN)` in
let odd_tm = `(ODD)` in
let rr_ty = `:real -> real` in
let sl_ty = `:sign list` in
let s_ty = `:sign` in
let imat = `interpmat` in
let rr_length = mk_const("LENGTH",[rr_ty,aty]) in
let s_length = mk_const("LENGTH",[s_ty,aty]) in
let sl_length = mk_const("LENGTH",[sl_ty,aty]) in
let imat = `interpmat` in
fun vars sgns mat_thm div_thms ind ->
let pts,pols,signs = dest_interpmat (concl mat_thm) in
let pols' = dest_list pols in
let signsl = dest_list signs in
let signs' = map dest_list signsl in
let pols_len = length (hd signs') in
let pols_len2 = pols_len / 2 in
let pt_sgnl = ith ind signsl in
let pt_sgns = ith ind signs' in
let zind = index zero pt_sgns in
if zind > pols_len2 then mat_thm else (* return if not a zero of a p, only a q *)
let psgn = ith (pols_len2 + zind) pt_sgns in
let div_thm = ith (zind - 1) div_thms in
let a,n = dest_binop pow (fst (dest_binop rm (lhs (concl div_thm)))) in
let asign = FINDSIGN vars sgns a in
let op,_,_ = get_binop (concl asign) in
let par_thm = PARITY_CONV n in
let par = fst(dest_comb(concl par_thm)) in
let mp_thm =
(* note: by def of PDIVIDES, we can`t have
negative sign and odd power at this point *)
(* n is even *)
if par = even_tm then
if psgn = pos then INFERPSIGN_POS_EVEN
else if psgn = neg then INFERPSIGN_NEG_EVEN
else if psgn = zero then INFERPSIGN_ZERO_EVEN
else failwith "INFERPT: bad sign"
else (* n is odd *)
if psgn = pos then INFERPSIGN_POS_ODD_POS
else if psgn = neg then INFERPSIGN_NEG_ODD_POS
else if psgn = zero then INFERPSIGN_ZERO_ODD_POS
else failwith "INFERPT: bad sign" in
(* pols *)
let split_pols1 = SPLIT_LIST zind pols rr_ty in
let _,l2 = chop_list zind pols' in
let split_pols2 = SPLIT_LIST pols_len2 (mk_list(l2,rr_ty)) rr_ty in
let s1,t1 = dest_comb (rhs (concl split_pols1)) in
let split_pols_thm = TRANS split_pols1 (AP_TERM s1 split_pols2) in
(* pt_sgns *)
let split_sgns1 = SPLIT_LIST zind pt_sgnl s_ty in
let _,l3 = chop_list zind pt_sgns in
let split_sgns2 = SPLIT_LIST pols_len2 (mk_list(l3,s_ty)) s_ty in
let s2,t2 = dest_comb (rhs (concl split_sgns1)) in
let split_pt_sgns_thm = TRANS split_sgns1 (AP_TERM s2 split_sgns2) in
(* sgns *)
let split_signs = SPLIT_LIST ind signs sl_ty in
let r1,r3 = dest_comb(rhs (concl split_signs)) in
let tl_thm = HD_CONV (ONCE_REWRITE_CONV[split_pt_sgns_thm]) r3 in
let r4,_ = dest_comb (rhs (concl split_signs)) in
let split_sgns_thm = TRANS split_signs (AP_TERM r4 tl_thm) in
(* imat *)
let mat1 = mk_comb(imat,pts) in
let mat_thm1 = AP_TERM mat1 split_pols_thm in
let mat_thm2 = MK_COMB(mat_thm1,split_sgns_thm) in
let mat_thm3 = EQ_MP mat_thm2 mat_thm in
(* length thms *)
(* LENGTH ps = LENGTH s1 *)
let ps = mk_list(tl(dest_list(snd(dest_comb s1))),rr_ty) in
let ps_len = REWRITE_CONV[LENGTH] (mk_comb(rr_length,ps)) in
let ss = mk_list(tl(dest_list(snd(dest_comb s2))),s_ty) in
let ss_len = REWRITE_CONV[LENGTH] (mk_comb(s_length,ss)) in
let ps_s1_thm = TRANS ps_len (SYM ss_len) in
(* LENGTH qs = LENGTH s2 *)
let k1 = tl (fst (chop_list pols_len2 (dest_list t1))) in
let qs = mk_list(k1,rr_ty) in
let qs_len = REWRITE_CONV[LENGTH] (mk_comb(rr_length,qs)) in
let k2 = tl (fst (chop_list pols_len2 (dest_list t2))) in
let s2s = mk_list(k2,s_ty) in
let s2s_len = REWRITE_CONV[LENGTH] (mk_comb(s_length,s2s)) in
let qs_s2_thm = TRANS qs_len (SYM s2s_len) in
(* ODD (LENGTH sgns) *)
let _,hdsgns = dest_comb r1 in
let odd_thm = EQT_ELIM(REWRITE_CONV[LENGTH;ODD;EVEN;NOT_ODD;NOT_EVEN] (mk_comb(odd_tm,mk_comb(sl_length,hdsgns)))) in
(* a <> 0 *)
let a_thm =
if par = even_tm then prove_nonzero asign
else asign in
let div_thm' = GEN (hd vars) div_thm in
(* main *)
let thm1 = BETA_RULE(MATCH_MPL[mp_thm;mat_thm3;ps_s1_thm;qs_s2_thm;odd_thm]) in
let thm2 =
if par = even_tm then MATCH_MPL[thm1;div_thm';a_thm;par_thm]
else MATCH_MPL[thm1;div_thm';a_thm] in
REWRITE_RULE[APPEND] thm2;;
(*
let mat_thm = mat_thm'
*)
let INFERPTS vars sgns mat_thm div_thms =
let pts,_,_ = dest_interpmat (concl mat_thm) in
let len = 2 * length (dest_list pts) in
let ods = filter odd (1--len) in
itlist (fun i matthm -> INFERPT vars sgns matthm div_thms i) ods mat_thm;;
let itvars,itsgns,itmat,itdivs = ref [],ref [],ref TRUTH,ref [];;
(*
let vars,sgns,mat_thm,div_thms = !itvars,!itsgns,!itmat,!itdivs
*)
let INFERPSIGN2 vars sgns mat_thm div_thms =
itvars := vars;
itsgns := sgns;
itmat := mat_thm;
itdivs := div_thms;
let _,bod = dest_binop rm (lhs (concl (hd div_thms))) in
let p = mk_abs(hd vars,bod) in
let mat_thm' = INSERT_UNKNOWN_COL mat_thm p in
let mat_thm'' = INFERPTS vars sgns mat_thm' div_thms in
REMOVE_QS mat_thm'';;
(* ---------------------------------------------------------------------- *)
(* Timing *)
(* ---------------------------------------------------------------------- *)
let INFERPSIGN vars sgns mat_thm div_thms =
let start_time = Sys.time() in
let res = INFERPSIGN vars sgns mat_thm div_thms in
inferpsign_timer +.= (Sys.time() -. start_time);
res;;
(*
let l1 = PDIVIDE [`x:real`]
`&1 + x * (&1 + x * (&1 + x * &1))` `&1 + x * (&2 + x * &3)`;;
let l2 = PDIVIDE [`x:real`]
`&1 + x * (&1 + x * (&1 + x * &1))` `&2 + x * (-- &3 + x * &1)`;;
let l3 = PDIVIDE [`x:real`]
`&1 + x * (&1 + x * (&1 + x * &1))` `-- &4 + x * (&0 + x * &1)`;;
let div_thms = [l1;l2;l3];;
let vars = [`x:real`];;
let sgns = [ARITH_RULE `&1 > &0`];;
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; 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]]` ;;
INFERPSIGN vars sgns mat_thm div_thms
*)