This file is indexed.

/usr/share/hol88-2.02.19940316/contrib/convert/prune.ml is in hol88-contrib-source 2.02.19940316-19.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
%< 
---------------------------------

  new-unwind library
  
  prune.ml
  
  based on HOL88 unwind library   

  Rules for unwinding

  this file uses mk_thm !! 
---------------------------------
>%

%< useful conversions for getting things into a pruneable state >%

%< next bits subsidiary functions for EXISTS_AND >%

%<
   EXISTS_AND_LEFT: term     -> thm
                  "?x.t1/\t2"  

   | - ?x. t1 /\ t2 = t1 /\ (?x. t2)"  (If x not free in t1)
>%

let EXISTS_AND_LEFT t =
 (let x,t1,t2 = ((I # dest_conj) o dest_exists) t
  in
  let t1_frees, t2_frees = frees t1, frees t2
  in
  if (mem x t1_frees)
  then fail
  else
  (let th1 = ASSUME "^t1 /\ ^t2"
   and t' = "^t1 /\ (?^x.^t2)"
   in
   let th2 = ASSUME t'
   in
   let th3 = DISCH
              t
              (CHOOSE 
               (x, ASSUME t)
               (CONJ(CONJUNCT1 th1)(EXISTS("?^x.^t2",x)(CONJUNCT2 th1))))
     % th3 = |-"?x. t1  /\  t2  ==>  t1  /\  (?x. t2)" %
   and th4 = DISCH
              t'
              (CHOOSE
               (x, CONJUNCT2 th2)
               (EXISTS(t,x)(CONJ(CONJUNCT1 th2)(ASSUME t2))))
     % th4 = |-"t1  /\  (?x. t2)  ==>  ?x. t1  /\  t2" %
   in 
   IMP_ANTISYM_RULE th3 th4)
 ) ? failwith `EXISTS_AND_LEFT`;;
 
%<
   EXISTS_AND_RIGHT: term    -> thm
                   ?x.t1/\t2 

     |- ?x. t1 /\ t2 = (?x. t1) /\ t2"  (If x not free in t2)
>%

let EXISTS_AND_RIGHT t =
 (let x,t1,t2 = ((I # dest_conj) o dest_exists) t
  in
  let t1_frees, t2_frees = frees t1, frees t2
  and th1              = ASSUME "^t1 /\ ^t2"
  in
  if (mem x t2_frees)
  then fail
  else
  (let t' = "(?^x.^t1) /\ ^t2"
   in
   let th2 = ASSUME t'
   in
   let th3 = DISCH
              t
              (CHOOSE 
               (x, ASSUME t)
               (CONJ(EXISTS("?^x.^t1",x)(CONJUNCT1 th1))(CONJUNCT2 th1)))
     % th3 = |-"?x. t1  /\  t2  ==>  (?x.t1)  /\  t2" %
   and th4 = DISCH
              t'
              (CHOOSE
               (x, CONJUNCT1 th2)
               (EXISTS(t,x)(CONJ(ASSUME t1)(CONJUNCT2 th2))))
     % th4 = |-"(?x.t1)  /\  t2  ==>  ?x. t1  /\  t2" %
   in
   IMP_ANTISYM_RULE th3 th4)
 ) ? failwith `EXISTS_AND_RIGHT`;;

%<
   EXISTS_AND_BOTH: term     -> thm
                   ?x.t1/\t2

   |- ?x. t1 /\ t2 = t1 /\ t2"        (If x not free in t1 or t2)
>%

let EXISTS_AND_BOTH t =
 (let x,t1,t2 = ((I # dest_conj) o dest_exists) t
  in
  let t1_frees, t2_frees = frees t1, frees t2
  and th1              = ASSUME "^t1 /\ ^t2"
  in
  if (mem x t2_frees) or (mem x t1_frees)
  then fail
  else
  (let t' = "^t1 /\ ^t2"
   in
   let th3 = DISCH
              t
              (CHOOSE
               (x, ASSUME t)
               (ASSUME t'))
     % th3 = |-"?x. t1  /\  t2  ==>  t1  /\  t2" %
   and th4 = DISCH
              t'
              (EXISTS(t, x)(ASSUME t'))
     % th4 = |-"t1  /\ t2  ==>  ?x. t1 /\  t2" %
   in IMP_ANTISYM_RULE th3 th4)
 ) ? failwith `EXISTS_AND_BOTH`;;

%<
   EXISTS_AND: term -> thm
              ?x.t1/\t2

    |- ?x. t1 /\ t2 = t1 /\ t2"        (If x not free in t1 or t2)

    |- ?x. t1 /\ t2 = t1 /\ (?x. t2)"  (If x not free in t1)

    |- ?x. t1 /\ t2 = (?x. t1) /\ t2"  (If x not free in t2)
>%

let EXISTS_AND t =
 EXISTS_AND_BOTH  t ?  
 EXISTS_AND_LEFT  t ?  
 EXISTS_AND_RIGHT t ?
 failwith`EXISTS_AND`;;

%<
 EXISTS_EQN

   "?l. l x1 ... xn = t" --> |- (?l.l x1 ... xn = t) = T

  (if l not free in t)
>%

let EXISTS_EQN t =
 (let l,t1,t2 = ((I # dest_eq) o dest_exists) t
  in
  let l',xs = strip_comb t1
  in
  let t3 = list_mk_abs(xs,t2)
  in
  let th1 = RIGHT_CONV_RULE LIST_BETA_CONV (REFL(list_mk_comb(t3,xs)))
  in
  EQT_INTRO(EXISTS("?^l.^(list_mk_comb(l,xs))=^(rhs(concl th1))",t3)th1)
 ) ? failwith `EXISTS_EQN`;;

%<
 EXISTS_EQNF

   "?l. !x1 ... xn. l x1 ... xn = t" --> 
     |- (?l. !x1 ... xn. l x1 ... xn = t) = T

  (if l not free in t)
>%

let EXISTS_EQNF t =
 (let l,vars,t1,t2 =
  ((I # (I # dest_eq)) o (I # strip_forall) o dest_exists) t
  in
  let l',xs = strip_comb t1
  in
  let t3 = list_mk_abs(xs,t2)
  in
  let th1 =
   GENL vars (RIGHT_CONV_RULE LIST_BETA_CONV (REFL(list_mk_comb(t3,xs))))
  in
  EQT_INTRO
   (EXISTS
    ((mk_exists
      (l,
       list_mk_forall
        (xs,
         (mk_eq(list_mk_comb(l,xs), rhs(snd(strip_forall(concl th1)))))))),
     t3)
   th1)
 ) ? failwith `EXISTS_EQNF`;;


% |- (?x.t) = t    if x not free in t 

let EXISTS_DEL1 tm =
 (let x,t = dest_exists tm
  in
  let th1 = DISCH tm (CHOOSE (x, ASSUME tm) (ASSUME t))
  and th2 = DISCH t (EXISTS(tm,x)(ASSUME t))
  in
  IMP_ANTISYM_RULE th1 th2
 ) ? failwith `EXISTS_DEL`;;
%

% |- (?x1 ... xn.t) = t    if x1,...,xn not free in t 

letrec EXISTS_DEL tm =
 (if is_exists tm
  then
  (let th1 = EXISTS_DEL1 tm
   in
   let th2 = EXISTS_DEL(rhs(concl th1))
   in
   th1 TRANS th2)
  else REFL tm
 ) ? failwith`EXISTS_DEL`;;
%

let EXISTS_DEL1 tm =   % delete one ? %
 (let l,t = dest_exists tm
  in
  let l'  = frees t   % bug fix [DES] 24mar88 -- frees t NOT frees tm !! 
                        so need an extra let %
  in
  if not(mem l l') then mk_thm([], mk_eq(tm,t)) else fail
 ) ? failwith`EXISTS_DEL`;;

let EXISTS_DEL tm =
 (let l,t = strip_exists tm
  in
  let l'  = frees t   % bug fix [DES] 24mar88 -- frees t NOT frees tm !! 
                        so need an extra let %
  in
  if intersect l l' = [] then mk_thm([], mk_eq(tm,t)) else fail
 ) ? failwith`EXISTS_DEL`;;


%< [DES] 27apr89

   PRUNE_ONCE_CONV
   
   (? x . eqn1 /\ .... /\ x=t /\ ... /\ eqnn)
   ----------------------------------------------
   |- (? x . eqn1 /\ ... /\ x=t /\ ... /\ eqnn) =
      (? x . eqn1[t/x] /\ ... /\ eqnn[t/x])
>%

let AND_CLAUSE1 = GEN "t:bool" (CONJUNCT1 (SPEC "t:bool" AND_CLAUSES));;

let PRUNE_ONCE_CONV t =
   (let bv,bdy = dest_exists t in
    let conjs = conjuncts bdy in
    let bvas = filter (\t.lhs t=bv?false) conjs in
    if bvas=[] % case where no assignment to bv %
       then EXISTS_DEL1 t % can just attempt to delete it %
       else
    let bveq = rhs(hd bvas) in  % the value to equate it to %
    let nbdy = subst[bveq,bv]bdy in 
    let th1 = DISCH nbdy(EXISTS (t,bveq) (ASSUME nbdy)) in
    let lem = hd(filter(\th.lhs(concl th)=bv?false)(CONJUNCTS(ASSUME bdy))) in
    let lem1 = SUBST [lem,bv] bdy (ASSUME bdy) in
    let th2 = DISCH t(CHOOSE (bv,ASSUME t) (lem1)) in
    let th3 = IMP_ANTISYM_RULE th2 th1 in
    let nvar = genvar ":bool" in
    let th4 = SUBST[EQT_INTRO(REFL bveq),nvar](mk_eq(nbdy,subst[nvar,mk_eq(bveq,bveq)]nbdy))
            (REFL(nbdy)) in
    let nconjs = filter(\t.not t="T")(conjuncts(rhs(concl th4))) in
    let th5 =  CONJUNCTS_CONV(rhs(concl th4),list_mk_conj ("T".nconjs)) in
    if nconjs=[] then th3 TRANS th4 TRANS th5
    else
    let th6 = SUBST [SPEC(list_mk_conj nconjs)AND_CLAUSE1,nvar](mk_eq(lhs(concl th5),nvar))th5 in
    th3 TRANS th4 TRANS th6) ? failwith `PRUNE_ONCE_CONV`;;

letrec PRUNE_CONV t =
   letrec f t = % local function -- does ? x1 ... xn . b --> ? x2 .. xn x1 . b 
                  then PRUNES ? x1 . b %
             ((SWAP_EXISTS_CONV THENC (SUB_CONV(SUB_CONV f))) 
               ORELSEC PRUNE_ONCE_CONV)t
   in
   if (is_exists t)
      then ((SUB_CONV(SUB_CONV PRUNE_CONV))THENC(f ORELSEC ALL_CONV))t
      else (ALL_CONV t);;

let PRUNE_RULE th = RIGHT_CONV_RULE PRUNE_CONV th ? failwith `PRUNE_RULE`;;