forked from jrh13/hol-light
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmiz3_of_hol.ml
237 lines (224 loc) · 8.88 KB
/
miz3_of_hol.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
needs "miz3.ml";;
type script_step =
| Tac of string * tactic
| Par of script_step list list;;
type prooftree =
| Prooftree of goal * (string * tactic) * prooftree list
| Open_goal of goal;;
let read_script filename lemmaname =
let rec check_semisemi l =
match l with
| ";"::";"::_ -> true
| " "::l' -> check_semisemi l'
| _ -> false in
let file = open_in filename in
let lemma_string = "let "^lemmaname^" = prove" in
let n = String.length lemma_string in
let rec read_script1 () =
let s = input_line file in
if String.length s >= n && String.sub s 0 n = lemma_string
then (explode s)@"\n"::read_script2 () else read_script1 ()
and read_script2 () =
let l = explode (input_line file) in
if check_semisemi (rev l) then l else l@"\n"::read_script2 () in
let l = read_script1 () in
close_in file;
l;;
let rec tokenize l =
match l with
| [] -> []
| c::l' ->
let l1,l23 = if isalnum c then many (some isalnum) l else [c],l' in
let l2,l3 = many (some isspace) l23 in
(implode l1,if l2 = [] then "" else " ")::tokenize l3;;
let parse_script l =
let rec parse_statement s l =
match l with
| ("`",_)::(",",_)::l' -> s,l'
| (x,y)::l' -> parse_statement (s^x^y) l'
| [] -> failwith "parse_statement" in
let rec parse_tactic b n s y' l =
match l with
| ("\\",y)::l' when not b -> parse_tactic b n (s^y'^"\\\\") y l'
| (x,y)::l' ->
if n = 0 && (x = "THEN" || x = "THENL" || x = ";" || x = "]" || x = ")")
then (Tac(s,exec_tactic s)),l else
let n' = if x = "[" || x = "(" then n + 1 else
if x = "]" || x = ")" then n - 1 else n in
let x',b' =
if x = "`" then
if b then "(parse_term \"",(not b) else "\")",(not b)
else x,b in
parse_tactic b' n' (s^y'^x') y l'
| [] -> failwith "parse_tactic" in
let rec parse_tactics tacs l =
let tac,l' = parse_tactic true 0 "" "" l in
parse_tactics1 (tac::tacs) l'
and parse_tactics1 tacs l =
match l with
| ("THEN",_)::l' -> parse_tactics tacs l'
| ("THENL",_)::("[",_)::l' ->
let tac,l'' = parse_par_tactics [] l' in
parse_tactics1 (tac::tacs) l''
| _ -> (rev tacs),l
and parse_par_tactics tacss l =
let tacs,l' = parse_tactics [] l in
match l' with
| (";",_)::l'' -> parse_par_tactics (tacs::tacss) l''
| ("]",_)::l'' -> (Par (rev (tacs::tacss))),l''
| _ -> failwith "parse_par_tactics" in
match l with
| ("let",_)::_::("=",_)::("prove",_)::("(",_)::("`",_)::l' ->
let s,l'' = parse_statement "" l' in
let tacs,l''' = parse_tactics [] l'' in
(match l''' with
| [")",_; ";",_; ";",_] -> parse_term s,tacs
| _ -> failwith "parse_script")
| _ -> failwith "parse_script";;
let read_script1 filename lemmaname =
parse_script (tokenize (read_script filename lemmaname));;
let tactic_of_script l =
let rec tactic_of_script1 l =
match l with
| [] -> ALL_TAC
| [Tac(_,tac)] -> tac
| (Tac(_,tac))::l' -> tactic_of_script1 l' THEN tac
| (Par ll)::l' ->
tactic_of_script1 l' THENL (map (tactic_of_script1 o rev) ll) in
tactic_of_script1 (rev l);;
let run_script (tm,l) = prove(tm,tactic_of_script l);;
let prooftree_of_script g l =
let rec prooftrees_of gltl tl =
match gltl with
| [] -> []
| (gl,t)::rst ->
let tl1,tl' = chop_list (length gl) tl in
(t tl1)::prooftrees_of rst tl' in
let prooftree_of_script2 t gltl =
flat (map fst gltl),(fun tl -> t (prooftrees_of gltl tl)) in
let rec prooftree_of_script1 g l =
match l with
| [] -> [g],(function [t] -> t | _ -> failwith "prooftree_of_script1")
| (Tac(s,tac))::l' ->
let gl,t = prooftree_of_script1 g l' in
let gltl = map (fun g' -> let _,x,_ = tac g' in
x,(fun tl -> Prooftree(g',(s,tac),tl))) gl in
prooftree_of_script2 t gltl
| (Par ll)::l' ->
let gl,t = prooftree_of_script1 g l' in
let gltl = map2 prooftree_of_script1 gl (map rev ll) in
prooftree_of_script2 t gltl in
let gl,t = prooftree_of_script1 g (rev l) in
t (map (fun x -> Open_goal x) gl);;
let goal_of_prooftree t =
match t with
| Prooftree(g,_,_) -> g
| Open_goal(g) -> g;;
let rec step_of_prooftree prefix n context t =
let frees_of_goal (asl,w) =
union (flat (map (frees o concl o snd) asl)) (frees w) in
let rec extra_ass ass' ass =
if subset ass' ass then [] else (hd ass')::(extra_ass (tl ass') ass) in
let rec lets prefix l =
match l with
| [] -> []
| t::_ ->
let l',l'' = partition ((=) (type_of t) o type_of) l in
step_of_substep prefix (Let l')::lets prefix l'' in
let rec intros prefix n ass =
match ass with
| [] -> [],n,[]
| a::ass' ->
let steps,n',context = intros prefix (n + 1) ass' in
let lab = string_of_int n in
(step_of_substep prefix (Assume(a,[lab]))::steps),
n',((a,lab)::context) in
let shift_labels steps =
let labels = rev (labels_of_steps [] [] steps) in
let labels' =
map ((fun s -> [s],[string_of_int (int_of_string s - 1)]) o hd o fst)
labels in
snd (renumber_steps labels' [] steps) in
let rec steps_of_prooftrees prefix n context (asl,_ as g) tl =
match tl with
| [] -> [],[],n,context
| t'::tl' ->
let (asl',w' as g') = goal_of_prooftree t' in
let prefix' = prefix^(!proof_indent) in
let ll =
lets prefix' (subtract (frees_of_goal g') (frees_of_goal g)) in
let vars = flat (map (function (_,_,Let l) -> l | _ -> []) ll) in
let ass =
extra_ass (map (concl o snd) asl') (map (concl o snd) asl) in
let w'' = list_mk_forall(vars, itlist (curry mk_imp) ass w') in
try
let lab = assoc w'' context in
let steps,labs,n',context' =
steps_of_prooftrees prefix n context g tl' in
steps,Label lab::labs,n',context'
with Failure "find" ->
if vars = [] && ass = [] then
let steps,just,n',context' =
steps_of_prooftree prefix n context t' in
try
let lab = assoc w'' context' in
let steps',labs,n'',context'' =
steps_of_prooftrees prefix n' context' g tl' in
(steps@steps'),Label lab::labs,n'',context''
with Failure "find" ->
let lab = string_of_int n' in
let steps',labs,n'',context'' =
steps_of_prooftrees prefix (n' + 1)
((w',lab)::context') g tl' in
(steps@
[rewrap_step (step_of_substep prefix (Have(w'',[lab],just)))]@
steps'),Label lab::labs,n'',context''
else
let lab = string_of_int n in
let steps,n',context' = intros prefix' (n + 1) ass in
let steps',just,n'',context'' =
steps_of_prooftree prefix' n' (rev context'@context) t' in
let qed = [rewrap_step (step_of_substep prefix (Qed just))] in
let steps'',n''' =
if steps' = [] then (steps'@qed),n'' else
match last steps' with
| _,_,Have(w''',_,Proof(_,steps''',_)) when w''' = w' ->
(butlast steps'@
map (outdent (String.length !proof_indent))
(shift_labels steps''')),n''
| _ -> (steps'@qed),n'' in
let steps''',labs,n'''',context''' =
steps_of_prooftrees prefix n''' ((w'',lab)::context'') g tl' in
(step_of_substep prefix
(Have(w'',[lab],
Proof (Some (step_of_substep prefix Bracket_proof),
(ll@steps@steps''), None)))::
steps'''),Label lab::labs,n'''',context'''
and steps_of_prooftree prefix n context t =
match t with
| Prooftree((_,w as g),(s,tac),tl) ->
let steps,f_labs,n',context' =
steps_of_prooftrees prefix n context g tl in
let b_labs = map ((fun x -> Label x) o C assoc context o concl o snd)
(rev (fst g)) in
steps,By((Tactic(s,K tac))::b_labs,f_labs,false),n',context'
| Open_goal(g) -> [],By([Hole],[],false),n,context in
let prefix' = prefix^(!proof_indent) in
match t with
| Prooftree((_,w as g),_,_) ->
let steps,_,_,_ =
steps_of_prooftrees prefix n context g [t] in
(match last steps with
| _,_,Have(_,_,just) ->
step_of_substep prefix (Have(w,[string_of_int n],
if length steps = 1 then just else
let steps',_,_,_ =
steps_of_prooftrees prefix' (n + 1) context g [t] in
Proof (Some (step_of_substep prefix Bracket_proof),
(butlast steps'@
[rewrap_step (step_of_substep prefix (Qed just))]), None)))
| _ -> failwith "step_of_prooftree")
| _ -> failwith "step_of_prooftree";;
let miz3_of_hol filename lemmaname =
let tm,l = read_script1 filename lemmaname in
step_of_prooftree "" 1 [] (prooftree_of_script ([],tm) l);;