4 | Tac of string * tactic
5 | Par of script_step list list;;
8 | Prooftree of goal * (string * tactic) * prooftree list
11 let read_script filename lemmaname =
12 let rec check_semisemi l =
15 | " "::l' -> check_semisemi l'
17 let file = open_in filename in
18 let lemma_string = "let "^lemmaname^" = prove" in
19 let n = String.length lemma_string in
20 let rec read_script1 () =
21 let s = input_line file in
22 if String.length s >= n & String.sub s 0 n = lemma_string
23 then (explode s)@"\n"::read_script2 () else read_script1 ()
25 let l = explode (input_line file) in
26 if check_semisemi (rev l) then l else l@"\n"::read_script2 () in
27 let l = read_script1 () in
35 let l1,l23 = if isalnum c then many (some isalnum) l else [c],l' in
36 let l2,l3 = many (some isspace) l23 in
37 (implode l1,if l2 = [] then "" else " ")::tokenize l3;;
40 let rec parse_statement s l =
42 | ("`",_)::(",",_)::l' -> s,l'
43 | (x,y)::l' -> parse_statement (s^x^y) l'
44 | [] -> failwith "parse_statement" in
45 let rec parse_tactic b n s y' l =
47 | ("\\",y)::l' when not b -> parse_tactic b n (s^y'^"\\\\") y l'
49 if n = 0 & (x = "THEN" or x = "THENL" or x = ";" or x = "]" or x = ")")
50 then (Tac(s,exec_tactic s)),l else
51 let n' = if x = "[" or x = "(" then n + 1 else
52 if x = "]" or x = ")" then n - 1 else n in
55 if b then "(parse_term \"",(not b) else "\")",(not b)
57 parse_tactic b' n' (s^y'^x') y l'
58 | [] -> failwith "parse_tactic" in
59 let rec parse_tactics tacs l =
60 let tac,l' = parse_tactic true 0 "" "" l in
61 parse_tactics1 (tac::tacs) l'
62 and parse_tactics1 tacs l =
64 | ("THEN",_)::l' -> parse_tactics tacs l'
65 | ("THENL",_)::("[",_)::l' ->
66 let tac,l'' = parse_par_tactics [] l' in
67 parse_tactics1 (tac::tacs) l''
69 and parse_par_tactics tacss l =
70 let tacs,l' = parse_tactics [] l in
72 | (";",_)::l'' -> parse_par_tactics (tacs::tacss) l''
73 | ("]",_)::l'' -> (Par (rev (tacs::tacss))),l''
74 | _ -> failwith "parse_par_tactics" in
76 | ("let",_)::_::("=",_)::("prove",_)::("(",_)::("`",_)::l' ->
77 let s,l'' = parse_statement "" l' in
78 let tacs,l''' = parse_tactics [] l'' in
80 | [")",_; ";",_; ";",_] -> parse_term s,tacs
81 | _ -> failwith "parse_script")
82 | _ -> failwith "parse_script";;
84 let read_script1 filename lemmaname =
85 parse_script (tokenize (read_script filename lemmaname));;
87 let tactic_of_script l =
88 let rec tactic_of_script1 l =
92 | (Tac(_,tac))::l' -> tactic_of_script1 l' THEN tac
94 tactic_of_script1 l' THENL (map (tactic_of_script1 o rev) ll) in
95 tactic_of_script1 (rev l);;
97 let run_script (tm,l) = prove(tm,tactic_of_script l);;
99 let prooftree_of_script g l =
100 let rec prooftrees_of gltl tl =
104 let tl1,tl' = chop_list (length gl) tl in
105 (t tl1)::prooftrees_of rst tl' in
106 let prooftree_of_script2 t gltl =
107 flat (map fst gltl),(fun tl -> t (prooftrees_of gltl tl)) in
108 let rec prooftree_of_script1 g l =
110 | [] -> [g],(function [t] -> t | _ -> failwith "prooftree_of_script1")
111 | (Tac(s,tac))::l' ->
112 let gl,t = prooftree_of_script1 g l' in
113 let gltl = map (fun g' -> let _,x,_ = tac g' in
114 x,(fun tl -> Prooftree(g',(s,tac),tl))) gl in
115 prooftree_of_script2 t gltl
117 let gl,t = prooftree_of_script1 g l' in
118 let gltl = map2 prooftree_of_script1 gl (map rev ll) in
119 prooftree_of_script2 t gltl in
120 let gl,t = prooftree_of_script1 g (rev l) in
121 t (map (fun x -> Open_goal x) gl);;
123 let goal_of_prooftree t =
125 | Prooftree(g,_,_) -> g
126 | Open_goal(g) -> g;;
128 let rec step_of_prooftree prefix n context t =
129 let frees_of_goal (asl,w) =
130 union (flat (map (frees o concl o snd) asl)) (frees w) in
131 let rec extra_ass ass' ass =
132 if subset ass' ass then [] else (hd ass')::(extra_ass (tl ass') ass) in
133 let rec lets prefix l =
137 let l',l'' = partition ((=) (type_of t) o type_of) l in
138 step_of_substep prefix (Let l')::lets prefix l'' in
139 let rec intros prefix n ass =
143 let steps,n',context = intros prefix (n + 1) ass' in
144 let lab = string_of_int n in
145 (step_of_substep prefix (Assume(a,[lab]))::steps),
146 n',((a,lab)::context) in
147 let shift_labels steps =
148 let labels = rev (labels_of_steps [] [] steps) in
150 map ((fun s -> [s],[string_of_int (int_of_string s - 1)]) o hd o fst)
152 snd (renumber_steps labels' [] steps) in
153 let rec steps_of_prooftrees prefix n context (asl,_ as g) tl =
155 | [] -> [],[],n,context
157 let (asl',w' as g') = goal_of_prooftree t' in
158 let prefix' = prefix^(!proof_indent) in
160 lets prefix' (subtract (frees_of_goal g') (frees_of_goal g)) in
161 let vars = flat (map (function (_,_,Let l) -> l | _ -> []) ll) in
163 extra_ass (map (concl o snd) asl') (map (concl o snd) asl) in
164 let w'' = list_mk_forall(vars, itlist (curry mk_imp) ass w') in
166 let lab = assoc w'' context in
167 let steps,labs,n',context' =
168 steps_of_prooftrees prefix n context g tl' in
169 steps,Label lab::labs,n',context'
170 with Failure "find" ->
171 if vars = [] & ass = [] then
172 let steps,just,n',context' =
173 steps_of_prooftree prefix n context t' in
175 let lab = assoc w'' context' in
176 let steps',labs,n'',context'' =
177 steps_of_prooftrees prefix n' context' g tl' in
178 (steps@steps'),Label lab::labs,n'',context''
179 with Failure "find" ->
180 let lab = string_of_int n' in
181 let steps',labs,n'',context'' =
182 steps_of_prooftrees prefix (n' + 1)
183 ((w',lab)::context') g tl' in
185 [rewrap_step (step_of_substep prefix (Have(w'',[lab],just)))]@
186 steps'),Label lab::labs,n'',context''
188 let lab = string_of_int n in
189 let steps,n',context' = intros prefix' (n + 1) ass in
190 let steps',just,n'',context'' =
191 steps_of_prooftree prefix' n' (rev context'@context) t' in
192 let qed = [rewrap_step (step_of_substep prefix (Qed just))] in
194 if steps' = [] then (steps'@qed),n'' else
195 match last steps' with
196 | _,_,Have(w''',_,Proof(_,steps''',_)) when w''' = w' ->
198 map (outdent (String.length !proof_indent))
199 (shift_labels steps''')),n''
200 | _ -> (steps'@qed),n'' in
201 let steps''',labs,n'''',context''' =
202 steps_of_prooftrees prefix n''' ((w'',lab)::context'') g tl' in
203 (step_of_substep prefix
205 Proof (Some (step_of_substep prefix Bracket_proof),
206 (ll@steps@steps''), None)))::
207 steps'''),Label lab::labs,n'''',context'''
208 and steps_of_prooftree prefix n context t =
210 | Prooftree((_,w as g),(s,tac),tl) ->
211 let steps,f_labs,n',context' =
212 steps_of_prooftrees prefix n context g tl in
213 let b_labs = map ((fun x -> Label x) o C assoc context o concl o snd)
215 steps,By((Tactic(s,K tac))::b_labs,f_labs,false),n',context'
216 | Open_goal(g) -> [],By([Hole],[],false),n,context in
217 let prefix' = prefix^(!proof_indent) in
219 | Prooftree((_,w as g),_,_) ->
221 steps_of_prooftrees prefix n context g [t] in
222 (match last steps with
223 | _,_,Have(_,_,just) ->
224 step_of_substep prefix (Have(w,[string_of_int n],
225 if length steps = 1 then just else
227 steps_of_prooftrees prefix' (n + 1) context g [t] in
228 Proof (Some (step_of_substep prefix Bracket_proof),
230 [rewrap_step (step_of_substep prefix (Qed just))]), None)))
231 | _ -> failwith "step_of_prooftree")
232 | _ -> failwith "step_of_prooftree";;
234 let miz3_of_hol filename lemmaname =
235 let tm,l = read_script1 filename lemmaname in
236 step_of_prooftree "" 1 [] (prooftree_of_script ([],tm) l);;