forked from brain-research/hol-light
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinferisign.ml
241 lines (213 loc) · 8.8 KB
/
inferisign.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
exception Isign of (thm * ((term * thm) list));;
(* ---------------------------------------------------------------------- *)
(* Opt *)
(* ---------------------------------------------------------------------- *)
let get_mp =
let unknown = `Unknown` in
let pos = `Pos` in
let zero = `Zero` in
let neg = `Neg` in
fun upper_sign lower_sign deriv_sign ->
(* Pos Pos *)
if upper_sign = pos &&
lower_sign = pos &&
deriv_sign = pos then INFERISIGN_POS_POS_POS
else if upper_sign = pos &&
lower_sign = pos &&
deriv_sign = neg then INFERISIGN_POS_POS_NEG
(* Pos Neg *)
else if upper_sign = pos &&
lower_sign = neg &&
deriv_sign = pos then INFERISIGN_POS_NEG_POS
else if upper_sign = pos &&
lower_sign = neg &&
deriv_sign = neg then INFERISIGN_POS_NEG_NEG
(* Pos Zero *)
else if upper_sign = pos &&
lower_sign = zero &&
deriv_sign = pos then INFERISIGN_POS_ZERO_POS
else if upper_sign = pos &&
lower_sign = zero &&
deriv_sign = neg then INFERISIGN_POS_ZERO_NEG
(* Neg Pos *)
else if upper_sign = neg &&
lower_sign = pos &&
deriv_sign = pos then INFERISIGN_NEG_POS_POS
else if upper_sign = neg &&
lower_sign = pos &&
deriv_sign = neg then INFERISIGN_NEG_POS_NEG
(* Neg Neg *)
else if upper_sign = neg &&
lower_sign = neg &&
deriv_sign = pos then INFERISIGN_NEG_NEG_POS
else if upper_sign = neg &&
lower_sign = neg &&
deriv_sign = neg then INFERISIGN_NEG_NEG_NEG
(* Neg Zero *)
else if upper_sign = neg &&
lower_sign = zero &&
deriv_sign = pos then INFERISIGN_NEG_ZERO_POS
else if upper_sign = neg &&
lower_sign = zero &&
deriv_sign = neg then INFERISIGN_NEG_ZERO_NEG
(* Zero Pos *)
else if upper_sign = zero &&
lower_sign = pos &&
deriv_sign = pos then INFERISIGN_ZERO_POS_POS
else if upper_sign = zero &&
lower_sign = pos &&
deriv_sign = neg then INFERISIGN_ZERO_POS_NEG
(* Zero Neg *)
else if upper_sign = zero &&
lower_sign = neg &&
deriv_sign = pos then INFERISIGN_ZERO_NEG_POS
else if upper_sign = zero &&
lower_sign = neg &&
deriv_sign = neg then INFERISIGN_ZERO_NEG_NEG
(* Zero Zero *)
else if upper_sign = zero &&
lower_sign = zero &&
deriv_sign = pos then INFERISIGN_ZERO_ZERO_POS
else if upper_sign = zero &&
lower_sign = zero &&
deriv_sign = neg then INFERISIGN_ZERO_ZERO_NEG
else failwith "bad signs in thm";;
let tvars,tdiff,tmat,tex = ref [],ref TRUTH,ref TRUTH,ref [];;
(*
let vars,diff_thm,mat_thm,ex_thms = !tvars,!tdiff,!tmat,!tex
INFERISIGN vars diff_thm mat_thm ex_thms
let vars,diff_thm,mat_thm,ex_thms = vars, pdiff_thm, mat_thm''', ((v1,exthm1)::(v2,exthm2)::ex_thms)
*)
let rec INFERISIGN =
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 real_len = `LENGTH:real list -> num` in
let sign_len = `LENGTH:(sign list) list -> num` in
let unknown = `Unknown` in
let pos = `Pos` in
let zero = `Zero` in
let neg = `Neg` in
let num_mul = `( * ):num -> num -> num` in
let num_add = `( + ):num -> num -> num` in
let real_ty = `:real` in
let one = `1` in
let two = `2` in
let f = `F` in
let imat = `interpmat` in
let sl_ty = `:sign list` in
fun vars diff_thm mat_thm ex_thms ->
try
tvars := vars;
tdiff := diff_thm;
tmat := mat_thm;
tex := ex_thms;
let pts,ps,sgns = dest_interpmat (concl mat_thm) in
let pts' = dest_list pts in
if pts' = [] then mat_thm,ex_thms else
let sgns' = dest_list sgns in
let sgnl = map dest_list sgns' in
let i = get_index (fun x -> hd x = unknown) sgnl in
if i mod 2 = 1 then failwith "bad shifted matrix" else
let p::p'::_ = dest_list ps 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 pts1,qts1 = chop_list (i / 2 - 1) pts' in
let ps_thm = REWRITE_CONV[p_thm;p'_thm] ps in
let pts2 = mk_list(pts1,real_ty) in
let pts3 = mk_comb(mk_comb(real_app,pts2),mk_list(qts1,real_ty)) in
let pts_thm = prove(mk_eq(pts,pts3),REWRITE_TAC[APPEND]) in
let sgns1,rgns1 = chop_list (i - 1) sgns' in
let sgns2 = mk_list(sgns1,sl_ty) in
let sgns3 = mk_comb(mk_comb(sign_app,sgns2),mk_list(rgns1,sl_ty)) in
let sgns_thm = prove(mk_eq(sgns,sgns3),REWRITE_TAC[APPEND]) in
let len1 = mk_comb(sign_len,sgns2) in
let len2 = mk_binop num_add (mk_binop num_mul two (mk_comb(real_len,pts2))) one in
let len_thm = prove(mk_eq(len1,len2),REWRITE_TAC[LENGTH] THEN ARITH_TAC) in
let mat_thm1 = MK_COMB(MK_COMB((AP_TERM imat pts_thm), ps_thm),sgns_thm) in
let mat_thm2 = EQ_MP mat_thm1 mat_thm in
let upper_sign = hd (ith (i - 1) sgnl) in
let lower_sign = hd (ith (i + 1) sgnl) in
let deriv_sign = hd (tl (ith i sgnl)) in
let mp_thm = get_mp upper_sign lower_sign deriv_sign in
let mat_thm3 = MATCH_MP (MATCH_MP mp_thm mat_thm2) len_thm in
let mat_thm4 = REWRITE_RULE[GSYM p_thm;GSYM p'_thm;APPEND] mat_thm3 in
let c = concl mat_thm4 in
if c = f then raise (Isign (mat_thm4,ex_thms)) else
if not (is_exists c) then
INFERISIGN vars diff_thm mat_thm4 ex_thms else
let x,bod = dest_exists c in
let x' = new_var real_ty in
let assume_thm = ASSUME (subst [x',x] bod) in
INFERISIGN vars diff_thm assume_thm ((x',mat_thm4)::ex_thms)
with
Failure "get_index" -> mat_thm,ex_thms
| Failure x -> failwith ("INFERISIGN: " ^ x);;
(*
let vars,diff_thm,mat_thm,ex_thms = vars,pdiff_thm, mat_thm''',[]
let mat_thm = ASSUME ` interpmat [x_25; x1; x2; x4; x5; x_26]
[\x. &1 + x * (&1 + x * (&1 + x * &1)); \x. &1 + x * (&2 + x * &3);
\x. &2 + x * (-- &3 + x * &1); \x. -- &4 + x * (&0 + x * &1)]
[[Neg; Pos; Pos; Pos];
[Neg; Pos; Pos; Pos];
[Unknown; Pos; Pos; Pos];
[Pos; Pos; Pos; Zero];
[Unknown; Neg; Pos; Neg];
[Unknown; Neg; Neg; Neg];
[Unknown; Neg; Pos; Neg];
[Pos; Zero; Zero; Neg];
[Unknown; Pos; Neg; Neg];
[Pos; Pos; Zero; Zero];
[Unknown; Pos; Pos; Pos];
[Pos; Pos; Pos; Pos];
[Pos; Pos; Pos; Pos]]`
*)
(* ---------------------------------------------------------------------- *)
(* Timing *)
(* ---------------------------------------------------------------------- *)
let INFERISIGN vars diff_thm mat_thm ex_thms =
let start_time = Sys.time() in
let res = INFERISIGN vars diff_thm mat_thm ex_thms in
inferisign_timer +.= (Sys.time() -. start_time);
res;;
(* {{{ Examples *)
(*
let is_thms = isigns_thms'''
let vars,diff_thm,mat_thm =
[`w:real`; `z:real`; `y:real`; `x:real`],
ASSUME `poly_diff [&0 + y * (&0 + x * &1); &0 + z * -- &1] = [&0 + z * -- &1]`,
ASSUME `interpmat [x_178; x_179]
[\w. (&0 + y * (&0 + x * &1)) + w * (&0 + z * -- &1); \w. &0 + z * -- &1]
[[Pos; Neg]; [Pos; Neg]; [Unknown; Neg]; [Neg; Neg]; [Neg; Neg]]`
INFERISIGN vars pdiff_thm mat_thm
let diff
let vars,diff_thm,mat_thm =
let vars,diff_thm,mat_thm =
[`x:real`],
ASSUME `poly_diff [&0; &2; &0; &4] = [&2; &0; &12]`,
ASSUME `interpmat [x_79; x_68; x_80]
[\x. &0 + x * (&2 + x * (&0 + x * &4)); \x. &2 + x * (&0 + x * &12);
\x. &4 + x * (&0 + x * &2)]
[[Neg; Pos; Pos]; [Neg; Pos; Pos]; [Unknown; Pos; Pos]; [Unknown; Pos; Pos]; [Unknown; Pos; Pos]; [Pos; Pos; Pos]; [Pos; Pos; Pos]]`
let mat_thm = mat_thm'''
let diff_thm = pdiff_thm
INFERISIGN vars pdiff_thm mat_thm'''
let diff_thm = POLY_DIFF_CONV `poly_diff [&1; &1; &1; &1]`;;
let vars = [`x:real`]
let mat_thm = ASSUME
`interpmat
[xminf; x1; x4; x5; xinf]
[\x. &1 + x * (&1 + x * (&1 + x * &1)); \x. &1 + x * (&2 + x * &3); \x. &2 + x * (-- &3 + x * &1); \x. -- &4 + x * (&0 + x * &1)]
[[Neg; Pos; Pos; Pos];
[Neg; Pos; Pos; Pos];
[Unknown; Pos; Pos; Pos];
[Neg; Pos; Pos; Zero];
[Unknown; Pos; Pos; Neg];
[Pos; Pos; Zero; Neg];
[Unknown; Pos; Neg; Neg];
[Pos; Pos; Zero; Zero];
[Unknown; Pos; Pos; Pos];
[Pos; Pos; Pos; Pos];
[Pos; Pos; Pos; Pos]]`;;
let mat_thm1,_ = INFERISIGN vars diff_thm mat_thm []
*)
(* }}} *)