This file is indexed.

/usr/share/hol88-2.02.19940316/ml/tacticals.ml is in hol88-source 2.02.19940316-28.

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
%=============================================================================%
%                               HOL 88 Version 2.0                            %
%                                                                             %
%     FILE NAME:        tacticals.ml                                          %
%                                                                             %
%     DESCRIPTION:      Monomorphic tacticals                                 %
%                                                                             %
%     USES FILES:       basic-hol lisp files, bool.th, genfns.ml, hol-syn.ml  %
%                       hol-rule.ml, hol-drule.ml, drul.ml                    %
%                                                                             %
%                       University of Cambridge                               %
%                       Hardware Verification Group                           %
%                       Computer Laboratory                                   %
%                       New Museums Site                                      %
%                       Pembroke Street                                       %
%                       Cambridge  CB2 3QG                                    %
%                       England                                               %
%                                                                             %
%     COPYRIGHT:        University of Edinburgh                               %
%     COPYRIGHT:        University of Cambridge                               %
%     COPYRIGHT:        INRIA                                                 %
%                                                                             %
%     REVISION HISTORY: (none)                                                %
%=============================================================================%

% --------------------------------------------------------------------- %
% Must be compiled in the presence of the hol parser/pretty printer	%
% This loads genfns.ml and hol-syn.ml too.				%
% Also load hol-rule.ml, hol-drule.ml, drul.ml				%
% --------------------------------------------------------------------- %

if compiling then  
   (loadf `ml/hol-in-out`; 
    loadf `ml/hol-rule`; 
    loadf `ml/hol-drule`;
    loadf `ml/drul`);;

% --------------------------------------------------------------------- %
% ML type abbreviations.						%
% --------------------------------------------------------------------- %

lettype proof = thm list -> thm  ;;

lettype goal = term list # term;;

lettype tactic = goal -> ((goal list) # proof);;

% --------------------------------------------------------------------- %
% TAC_PROOF (g,tac) uses tac to prove the goal g			%
% --------------------------------------------------------------------- %

let TAC_PROOF : (goal # tactic) -> thm =
    set_fail_prefix `TAC_PROOF`
       (\(g,tac). 
	   let gl,p = tac g in
	   if null gl then p[]
	   else failwith `unsolved goals`);;

% --------------------------------------------------------------------- %
% prove (t,tac) : prove the boolean term t using the tactic tac.	%
% [MJCG 17/1/89 for HOL88]						%
% --------------------------------------------------------------------- %

let prove(t,tac) = TAC_PROOF(([],t), tac);;

% --------------------------------------------------------------------- %
% Provide a function (tactic) with the current assumption list		%
% --------------------------------------------------------------------- %

let (ASSUM_LIST: (thm list -> tactic) -> tactic) 
  	aslfun (asl,w) =
    aslfun (map ASSUME asl) (asl,w);;

% --------------------------------------------------------------------- %
% Pop the first assumption and give it to a function (tactic) 		%
% --------------------------------------------------------------------- %

let POP_ASSUM (thfun:thm->tactic) ((as.asl),w) = thfun (ASSUME as) (asl,w);;

% --------------------------------------------------------------------- %
% Pop off the entire assumption list and give it to a function (tactic) %
% --------------------------------------------------------------------- %

let POP_ASSUM_LIST (asltac : thm list -> tactic) (asl,w) =
    asltac (map ASSUME asl) ([],w);;

% --------------------------------------------------------------------- %
% The tacticals THEN and THENL.						%
% --------------------------------------------------------------------- %

ml_curried_infix `THEN` ;;
ml_curried_infix `THENL` ;;

begin_section THEN_THENL;;

letrec mapshape nl fl l =  
    if null nl then []
    else 
       (let m,l = chop_list (hd nl) l in 
        (hd fl)m . mapshape(tl nl)(tl fl)l) ;;

let ((tac1 : tactic) THEN (tac2 : tactic)) g =
   let gl,p = tac1 g in
   let gll,pl = split(map tac2 gl) in
   flat gll ,  (p o mapshape(map length gll)pl) ;;

let ((tac1:tactic) THENL (tac2l : tactic list)) g =
   let gl,p = tac1 g  in
   let gll,pl = split(map (\(tac2,g). tac2 g) tac2gl)
		where tac2gl = combine(tac2l,gl) ? failwith `THENL`
   in
   flat gll  ,  (p o mapshape(map length gll)pl);;

(THEN,THENL);;

end_section THEN_THENL;;

let (THEN,THENL) = it;;

ml_curried_infix `ORELSE` ;;

let ((tac1:tactic) ORELSE tac2) (g:goal) =  tac1 g ? tac2 g ;;

%
Fail with the given token.  Useful in tactic programs to check that a tactic 
produces no subgoals.  Write
	TAC  THEN  FAIL_TAC `TAC did not solve the goal`
%

let FAIL_TAC tok : tactic = \g. failwith tok;;

%Tactic that succeeds on no goals;  identity for ORELSE%
let NO_TAC : tactic = FAIL_TAC `NO_TAC`;;

%Tactic that succeeds on all goals;  identity for THEN%

let ALL_TAC : tactic = \g. [g],hd;;

let TRY tac = tac ORELSE ALL_TAC;;

%
The abstraction around g is essential to avoid looping, due to applicative
order semantics
%

letrec REPEAT tac g = ((tac THEN REPEAT tac) ORELSE ALL_TAC) g ;;

% Check whether a theorem achieves a goal, using no extra assumptions %

let achieves th : goal -> bool =
    \(asl,w).
    aconv (concl th) w & 
    forall (\h. (exists (aconv h)) asl) (hyp th);;

% MJCG 17/1/89 for HOL88. mk_fthm not used. 

let fakethms gl = map mk_fthm gl;;
%

%
Check the goal list and proof returned by a tactic.
At top-level, it is convenient to type "chktac it;;"

MJCG 17/1/89 for HOL88: mk_thm used instead of mk_fthm. This
introduces slight insecurity into the system, but since chktak
is assignable this insecurity can be removed by doing:

   chktak := \(gl,prf). fail

%
letref chktac((gl:goal list),(prf:proof)) = prf(map mk_thm gl);;

%Check whether a prospective (goal list, proof) pair is valid.
 MJCG 17/1/89 for HOL88: "falsity.asl" changed to "asl".
%

let check_valid : goal -> (goal list # proof) -> bool =
   \(asl,w).
    set_fail_prefix `check_valid`
       (\glp. achieves (chktac glp) (asl, w));;

%
Tactical to make any tactic valid.
"VALID tac" is the same as "tac", except it will fail in the cases where
"tac" returns an invalid proof. 

VALID uses mk_thm; the proof could assign its arguments to 
global theorem variables, making them accessible outside.

This kind of insecurity is very unlikely to lead to accidental proof of false
theorems; see comment preceding check_valid for how to remove insecurity.

Previously mk_fthm was used by check_valid instead of mk_thm (see
hol-drule.ml), but this lead to problems with tactics (like resolution) that
checked for "F".  A possible solution would be to use another constant that
was defined equal to F.  %

let (VALID: tactic -> tactic) tac g =
     let gl,prf = tac g in
     if check_valid g (gl,prf) then gl,prf
     else failwith `Invalid tactic`;;

%Tactical quantifiers -- Apply a list of tactics in succession%

%
Uses every tactic.
EVERY [TAC1;...;TACn] =  TAC1  THEN  ...  THEN  TACn
%

let EVERY tacl = itlist $THEN tacl ALL_TAC;;

%
Uses first tactic that succeeds.
FIRST [TAC1;...;TACn] =  TAC1  ORELSE  ...  ORELSE  TACn
%

let FIRST tacl g = tryfind (\tac:tactic. tac g) tacl  ? failwith `FIRST`;;

let MAP_EVERY tacf lst  =  EVERY (map tacf lst);;

let MAP_FIRST tacf lst =  FIRST (map tacf lst);;

%Call a thm-tactic for every assumption%

% --------------------------------------------------------------------- %
% Optimized 13.5.93 by JVT to remove the function composition to        %
% enhance speed.                                                        %
%                                                                       %
% OLD VERSION:                                                          %
%                                                                       %
%    let EVERY_ASSUM : (thm -> tactic) -> tactic =                      %
%        ASSUM_LIST o MAP_EVERY;;                                       %
% --------------------------------------------------------------------- %

let EVERY_ASSUM : (thm -> tactic) -> tactic = \x. (ASSUM_LIST (MAP_EVERY x));;

% --------------------------------------------------------------------- %
% Call a thm-tactic for the first assumption at which it succeeds	%
%									%
% Revised: TFM 91.04.20 : failures of ttac to produce a tactic are now  %
% filtered out.								%
%									%
% Old implementation:							%
%									%
% let FIRST_ASSUM : (thm->tactic)->tactic = ASSUM_LIST o MAP_FIRST;;    %
%									%
% Revised: TFM 91.05.24 : optimized; no longer constructs extra tactics.%
%									%
% OLD CODE:								%
% let FIRST_ASSUM (ttac:thm->tactic) (A,g) =				%
%  FIRST (mapfilter (ttac o ASSUME) A) (A,g) ? failwith `FIRST_ASSUM`;; %
% --------------------------------------------------------------------- %

let FIRST_ASSUM =
    letrec find ttac as g =
       if (null as) then failwith `FIRST_ASSUM` else
          (ttac (ASSUME(hd as)) g ? find ttac (tl as) g) in
    \(ttac:thm->tactic). \(A,g). find ttac A (A,g);;


%
Split off a new subgoal and provide it as a theorem to a tactic
	SUBGOAL_THEN wa (\tha. tac)
makes a subgoal of wa, and also assumes wa for proving the original goal.
Most convenient when the tactic solves the original goal, leaving only the
new subgoal wa.
%

let SUBGOAL_THEN wa ttac :tactic (asl,w) =
    let gl,p = ttac (ASSUME wa) (asl,w) in
    (asl,wa) . gl,
    \(tha.thl). PROVE_HYP tha (p thl);;

% A tactical that makes a tactic fail if it has no effect %

%<
 (Comment corrected by MJCG on 17.10.90 and "letrec" changed to "let")
>%

let CHANGED_TAC (tac:tactic) g =
 let gl,p = tac g
 in
 if set_equal gl [g] then fail else (gl,p);;