19 val parse: typ Symtab.table -> term Symtab.table -> string list -> |
19 val parse: typ Symtab.table -> term Symtab.table -> string list -> |
20 Proof.context -> veriT_step list * Proof.context |
20 Proof.context -> veriT_step list * Proof.context |
21 |
21 |
22 val veriT_step_prefix : string |
22 val veriT_step_prefix : string |
23 val veriT_input_rule: string |
23 val veriT_input_rule: string |
|
24 val veriT_la_generic_rule : string |
24 val veriT_rewrite_rule : string |
25 val veriT_rewrite_rule : string |
|
26 val veriT_simp_arith_rule : string |
|
27 val veriT_tmp_ite_elim_rule : string |
25 val veriT_tmp_skolemize_rule : string |
28 val veriT_tmp_skolemize_rule : string |
26 val veriT_tmp_ite_elim_rule : string |
|
27 end; |
29 end; |
28 |
30 |
29 structure VeriT_Proof: VERIT_PROOF = |
31 structure VeriT_Proof: VERIT_PROOF = |
30 struct |
32 struct |
31 |
33 |
50 |
52 |
51 fun mk_step id rule prems concl fixes = |
53 fun mk_step id rule prems concl fixes = |
52 VeriT_Step {id = id, rule = rule, prems = prems, concl = concl, fixes = fixes} |
54 VeriT_Step {id = id, rule = rule, prems = prems, concl = concl, fixes = fixes} |
53 |
55 |
54 val veriT_step_prefix = ".c" |
56 val veriT_step_prefix = ".c" |
|
57 val veriT_alpha_conv_rule = "tmp_alphaconv" |
55 val veriT_input_rule = "input" |
58 val veriT_input_rule = "input" |
56 val veriT_rewrite_rule = "__rewrite" (*arbitrary*) |
59 val veriT_la_generic_rule = "la_generic" |
|
60 val veriT_rewrite_rule = "__rewrite" (* arbitrary *) |
|
61 val veriT_simp_arith_rule = "simp_arith" |
57 val veriT_tmp_ite_elim_rule = "tmp_ite_elim" |
62 val veriT_tmp_ite_elim_rule = "tmp_ite_elim" |
58 val veriT_tmp_skolemize_rule = "tmp_skolemize" |
63 val veriT_tmp_skolemize_rule = "tmp_skolemize" |
59 val veriT_alpha_conv_rule = "tmp_alphaconv" |
|
60 |
64 |
61 (* proof parser *) |
65 (* proof parser *) |
62 |
66 |
63 fun node_of p cx = |
67 fun node_of p cx = |
64 ([], cx) |
68 ([], cx) |
65 ||>> `(with_fresh_names (term_of p)) |
69 ||>> `(with_fresh_names (term_of p)) |
66 |>> snd |
70 |>> snd |
67 |
71 |
68 (*in order to get Z3-style quantification*) |
72 (*in order to get Z3-style quantification*) |
69 fun fix_quantification (SMTLIB2.S (SMTLIB2.Sym "forall" :: l)) = |
73 fun repair_quantification (SMTLIB2.S (SMTLIB2.Sym "forall" :: l)) = |
70 let val (quantified_vars, t) = split_last (map fix_quantification l) |
74 let val (quantified_vars, t) = split_last (map repair_quantification l) |
71 in |
75 in |
72 SMTLIB2.S (SMTLIB2.Sym "forall" :: SMTLIB2.S quantified_vars :: t :: []) |
76 SMTLIB2.S (SMTLIB2.Sym "forall" :: SMTLIB2.S quantified_vars :: t :: []) |
73 end |
77 end |
74 | fix_quantification (SMTLIB2.S (SMTLIB2.Sym "exists" :: l)) = |
78 | repair_quantification (SMTLIB2.S (SMTLIB2.Sym "exists" :: l)) = |
75 let val (quantified_vars, t) = split_last (map fix_quantification l) |
79 let val (quantified_vars, t) = split_last (map repair_quantification l) |
76 in |
80 in |
77 SMTLIB2.S (SMTLIB2.Sym "exists" :: SMTLIB2.S quantified_vars :: t :: []) |
81 SMTLIB2.S (SMTLIB2.Sym "exists" :: SMTLIB2.S quantified_vars :: t :: []) |
78 end |
82 end |
79 | fix_quantification (SMTLIB2.S l) = SMTLIB2.S (map fix_quantification l) |
83 | repair_quantification (SMTLIB2.S l) = SMTLIB2.S (map repair_quantification l) |
80 | fix_quantification x = x |
84 | repair_quantification x = x |
81 |
85 |
82 fun replace_bound_var_by_free_var (q $ Abs (var, ty, u)) free_var = |
86 fun replace_bound_var_by_free_var (q $ Abs (var, ty, u)) free_var = |
83 (case List.find (fn v => String.isPrefix v var) free_var of |
87 (case List.find (fn v => String.isPrefix v var) free_var of |
84 NONE => q $ Abs (var, ty, replace_bound_var_by_free_var u free_var) |
88 NONE => q $ Abs (var, ty, replace_bound_var_by_free_var u free_var) |
85 | SOME _ => replace_bound_var_by_free_var (Term.subst_bound (Free (var, ty), u)) free_var) |
89 | SOME _ => replace_bound_var_by_free_var (Term.subst_bound (Free (var, ty), u)) free_var) |
186 #> rotate_pair |
190 #> rotate_pair |
187 ##> skip_args |
191 ##> skip_args |
188 #> (fn (((id, rule), prems), sub) => (((id, rule), prems), parse_subproof cx id sub)) |
192 #> (fn (((id, rule), prems), sub) => (((id, rule), prems), parse_subproof cx id sub)) |
189 #> rotate_pair |
193 #> rotate_pair |
190 ##> parse_conclusion |
194 ##> parse_conclusion |
191 ##> map fix_quantification |
195 ##> map repair_quantification |
192 #> (fn ((((id, rule), prems), (subproof, cx)), terms) => |
196 #> (fn ((((id, rule), prems), (subproof, cx)), terms) => |
193 (((((id, rule), prems), subproof), fold_map (fn t => fn cx => node_of t cx) terms cx))) |
197 (((((id, rule), prems), subproof), fold_map (fn t => fn cx => node_of t cx) terms cx))) |
194 (*the conclusion is the empty list, ie no false is written, we have to add it.*) |
198 ##> apfst (fn [] => (@{const False}, []) | concls => make_or_from_clausification concls) |
195 ##> (apfst (fn [] => (@{const False}, []) |
|
196 | concls => make_or_from_clausification concls)) |
|
197 #> fix_subproof_steps |
199 #> fix_subproof_steps |
198 ##> to_node |
200 ##> to_node |
199 #> (fn (subproof, (step, cx)) => (subproof @ [step], cx)) |
201 #> (fn (subproof, (step, cx)) => (subproof @ [step], cx)) |
200 #-> (fold_map update_step_and_cx) |
202 #-> fold_map update_step_and_cx |
201 end |
203 end |
202 |
|
203 |
|
204 (*function related to parsing and general transformation*) |
|
205 |
204 |
206 (*subproofs are written on multiple lines: SMTLIB can not parse then, because parentheses are |
205 (*subproofs are written on multiple lines: SMTLIB can not parse then, because parentheses are |
207 unbalanced on each line*) |
206 unbalanced on each line*) |
208 fun seperate_into_steps lines = |
207 fun seperate_into_steps lines = |
209 let |
208 let |
220 | seperate [] _ 0 = [] |
219 | seperate [] _ 0 = [] |
221 in |
220 in |
222 seperate lines "" 0 |
221 seperate lines "" 0 |
223 end |
222 end |
224 |
223 |
225 (*VeriT adds @ before every variable.*) |
224 (* VeriT adds @ before every variable. *) |
226 fun remove_all_at (SMTLIB2.Sym v :: l) = |
225 fun remove_all_at (SMTLIB2.Sym v :: l) = SMTLIB2.Sym (perhaps (try (unprefix "@")) v) :: remove_all_at l |
227 SMTLIB2.Sym (if nth_string v 0 = "@" then String.extract (v, 1, NONE) else v) :: remove_all_at l |
|
228 | remove_all_at (SMTLIB2.S l :: l') = SMTLIB2.S (remove_all_at l) :: remove_all_at l' |
226 | remove_all_at (SMTLIB2.S l :: l') = SMTLIB2.S (remove_all_at l) :: remove_all_at l' |
229 | remove_all_at (SMTLIB2.Key v :: l) = SMTLIB2.Key v :: remove_all_at l |
227 | remove_all_at (SMTLIB2.Key v :: l) = SMTLIB2.Key v :: remove_all_at l |
230 | remove_all_at (v :: l) = v :: remove_all_at l |
228 | remove_all_at (v :: l) = v :: remove_all_at l |
231 | remove_all_at [] = [] |
229 | remove_all_at [] = [] |
232 |
230 |
276 NONE => find_ite_var_in_term q |
274 NONE => find_ite_var_in_term q |
277 | x => x) |
275 | x => x) |
278 | find_ite_var_in_term (Abs (_, _, body)) = find_ite_var_in_term body |
276 | find_ite_var_in_term (Abs (_, _, body)) = find_ite_var_in_term body |
279 | find_ite_var_in_term _ = NONE |
277 | find_ite_var_in_term _ = NONE |
280 |
278 |
281 |
|
282 fun correct_veriT_step steps (st as VeriT_Node {id, rule, prems, concl, bounds}) = |
279 fun correct_veriT_step steps (st as VeriT_Node {id, rule, prems, concl, bounds}) = |
283 if rule = veriT_tmp_ite_elim_rule then |
280 if rule = veriT_tmp_ite_elim_rule then |
284 if bounds = [] then |
281 if bounds = [] then |
285 (*if the introduced var has already been defined, |
282 (*if the introduced var has already been defined, adding the definition as a dependency*) |
286 adding the definition as a dependency*) |
|
287 let |
283 let |
288 val new_prems = |
284 val new_prems = |
289 (case find_ite_var_in_term concl of |
285 (case find_ite_var_in_term concl of |
290 NONE => prems |
286 NONE => prems |
291 | SOME var => find_in_which_step_defined var steps :: prems) |
287 | SOME var => find_in_which_step_defined var steps :: prems) |
300 mk_node id rule prems concl' [] |
296 mk_node id rule prems concl' [] |
301 end |
297 end |
302 else |
298 else |
303 st |
299 st |
304 |
300 |
305 (*remove alpha conversion step, that just renames the variables*) |
|
306 fun remove_alpha_conversion _ [] = [] |
301 fun remove_alpha_conversion _ [] = [] |
307 | remove_alpha_conversion replace_table (VeriT_Node {id, rule, prems, concl, bounds} :: steps) = |
302 | remove_alpha_conversion replace_table (VeriT_Node {id, rule, prems, concl, bounds} :: steps) = |
308 let |
303 let |
309 fun correct_dependency prems = |
304 fun correct_dependency prems = |
310 map (fn x => perhaps (Symtab.lookup replace_table) x) prems |
305 map (fn x => perhaps (Symtab.lookup replace_table) x) prems |
321 fun correct_veriT_steps steps = |
316 fun correct_veriT_steps steps = |
322 steps |
317 steps |
323 |> map (correct_veriT_step steps) |
318 |> map (correct_veriT_step steps) |
324 |> remove_alpha_conversion Symtab.empty |
319 |> remove_alpha_conversion Symtab.empty |
325 |
320 |
326 (* overall proof parser *) |
|
327 fun parse typs funs lines ctxt = |
321 fun parse typs funs lines ctxt = |
328 let |
322 let |
329 val smtlib2_lines_without_at = |
323 val smtlib2_lines_without_at = |
330 remove_all_at (map SMTLIB2.parse (seperate_into_steps lines)) |
324 remove_all_at (map SMTLIB2.parse (seperate_into_steps lines)) |
331 val (u, env) = apfst flat (fold_map (fn l => fn cx => parse_proof_step cx l) |
325 val (u, env) = apfst flat (fold_map (fn l => fn cx => parse_proof_step cx l) |