author | wenzelm |
Sat, 20 Nov 2010 00:53:26 +0100 | |
changeset 40627 | becf5d5187cc |
parent 40579 | 98ebd2300823 |
child 40662 | 798aad2229c0 |
permissions | -rw-r--r-- |
36898 | 1 |
(* Title: HOL/Tools/SMT/z3_proof_parser.ML |
2 |
Author: Sascha Boehme, TU Muenchen |
|
3 |
||
4 |
Parser for Z3 proofs. |
|
5 |
*) |
|
6 |
||
7 |
signature Z3_PROOF_PARSER = |
|
8 |
sig |
|
9 |
(* proof rules *) |
|
10 |
datatype rule = TrueAxiom | Asserted | Goal | ModusPonens | Reflexivity | |
|
11 |
Symmetry | Transitivity | TransitivityStar | Monotonicity | QuantIntro | |
|
12 |
Distributivity | AndElim | NotOrElim | Rewrite | RewriteStar | PullQuant | |
|
13 |
PullQuantStar | PushQuant | ElimUnusedVars | DestEqRes | QuantInst | |
|
14 |
Hypothesis | Lemma | UnitResolution | IffTrue | IffFalse | Commutativity | |
|
15 |
DefAxiom | IntroDef | ApplyDef | IffOeq | NnfPos | NnfNeg | NnfStar | |
|
40516 | 16 |
CnfStar | Skolemize | ModusPonensOeq | ThLemma of string list |
36898 | 17 |
val string_of_rule: rule -> string |
18 |
||
19 |
(* proof parser *) |
|
20 |
datatype proof_step = Proof_Step of { |
|
21 |
rule: rule, |
|
22 |
prems: int list, |
|
23 |
prop: cterm } |
|
24 |
val parse: Proof.context -> typ Symtab.table -> term Symtab.table -> |
|
25 |
string list -> |
|
26 |
int * (proof_step Inttab.table * string list * Proof.context) |
|
27 |
end |
|
28 |
||
29 |
structure Z3_Proof_Parser: Z3_PROOF_PARSER = |
|
30 |
struct |
|
31 |
||
36899
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
32 |
structure I = Z3_Interface |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
33 |
|
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
34 |
|
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
35 |
|
36898 | 36 |
(** proof rules **) |
37 |
||
38 |
datatype rule = TrueAxiom | Asserted | Goal | ModusPonens | Reflexivity | |
|
39 |
Symmetry | Transitivity | TransitivityStar | Monotonicity | QuantIntro | |
|
40 |
Distributivity | AndElim | NotOrElim | Rewrite | RewriteStar | PullQuant | |
|
41 |
PullQuantStar | PushQuant | ElimUnusedVars | DestEqRes | QuantInst | |
|
42 |
Hypothesis | Lemma | UnitResolution | IffTrue | IffFalse | Commutativity | |
|
43 |
DefAxiom | IntroDef | ApplyDef | IffOeq | NnfPos | NnfNeg | NnfStar | |
|
40516 | 44 |
CnfStar | Skolemize | ModusPonensOeq | ThLemma of string list |
36898 | 45 |
|
46 |
val rule_names = Symtab.make [ |
|
47 |
("true-axiom", TrueAxiom), |
|
48 |
("asserted", Asserted), |
|
49 |
("goal", Goal), |
|
50 |
("mp", ModusPonens), |
|
51 |
("refl", Reflexivity), |
|
52 |
("symm", Symmetry), |
|
53 |
("trans", Transitivity), |
|
54 |
("trans*", TransitivityStar), |
|
55 |
("monotonicity", Monotonicity), |
|
56 |
("quant-intro", QuantIntro), |
|
57 |
("distributivity", Distributivity), |
|
58 |
("and-elim", AndElim), |
|
59 |
("not-or-elim", NotOrElim), |
|
60 |
("rewrite", Rewrite), |
|
61 |
("rewrite*", RewriteStar), |
|
62 |
("pull-quant", PullQuant), |
|
63 |
("pull-quant*", PullQuantStar), |
|
64 |
("push-quant", PushQuant), |
|
65 |
("elim-unused", ElimUnusedVars), |
|
66 |
("der", DestEqRes), |
|
67 |
("quant-inst", QuantInst), |
|
68 |
("hypothesis", Hypothesis), |
|
69 |
("lemma", Lemma), |
|
70 |
("unit-resolution", UnitResolution), |
|
71 |
("iff-true", IffTrue), |
|
72 |
("iff-false", IffFalse), |
|
73 |
("commutativity", Commutativity), |
|
74 |
("def-axiom", DefAxiom), |
|
75 |
("intro-def", IntroDef), |
|
76 |
("apply-def", ApplyDef), |
|
77 |
("iff~", IffOeq), |
|
78 |
("nnf-pos", NnfPos), |
|
79 |
("nnf-neg", NnfNeg), |
|
80 |
("nnf*", NnfStar), |
|
81 |
("cnf*", CnfStar), |
|
82 |
("sk", Skolemize), |
|
83 |
("mp~", ModusPonensOeq), |
|
40516 | 84 |
("th-lemma", ThLemma [])] |
36898 | 85 |
|
40516 | 86 |
fun string_of_rule (ThLemma args) = space_implode " " ("th-lemma" :: args) |
87 |
| string_of_rule r = |
|
88 |
let fun eq_rule (s, r') = if r = r' then SOME s else NONE |
|
89 |
in the (Symtab.get_first eq_rule rule_names) end |
|
36898 | 90 |
|
91 |
||
92 |
||
93 |
(** certified terms and variables **) |
|
94 |
||
36899
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
95 |
val (var_prefix, decl_prefix) = ("v", "sk") |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
96 |
(* "decl_prefix" is for skolem constants (represented by free variables) |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
97 |
"var_prefix" is for pseudo-schematic variables (schematic with respect |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
98 |
to the Z3 proof, but represented by free variables) |
36898 | 99 |
|
36899
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
100 |
Both prefixes must be distinct to avoid name interferences. |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
101 |
More precisely, the naming of pseudo-schematic variables must be |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
102 |
context-independent modulo the current proof context to be able to |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
103 |
use fast inference kernel rules during proof reconstruction. *) |
36898 | 104 |
|
105 |
fun certify ctxt = Thm.cterm_of (ProofContext.theory_of ctxt) |
|
106 |
||
107 |
val maxidx_of = #maxidx o Thm.rep_cterm |
|
108 |
||
109 |
fun mk_inst ctxt vars = |
|
110 |
let |
|
111 |
val max = fold (Integer.max o fst) vars 0 |
|
112 |
val ns = fst (Variable.variant_fixes (replicate (max + 1) var_prefix) ctxt) |
|
113 |
fun mk (i, v) = (v, certify ctxt (Free (nth ns i, #T (Thm.rep_cterm v)))) |
|
114 |
in map mk vars end |
|
115 |
||
40579
98ebd2300823
use the const antiquotation for constants (this checks that the constant is declared, whereas the more general term antiquotation treats undeclared names as free variable)
boehmes
parents:
40516
diff
changeset
|
116 |
val mk_prop = Thm.capply (Thm.cterm_of @{theory} @{const Trueprop}) |
98ebd2300823
use the const antiquotation for constants (this checks that the constant is declared, whereas the more general term antiquotation treats undeclared names as free variable)
boehmes
parents:
40516
diff
changeset
|
117 |
|
36898 | 118 |
fun close ctxt (ct, vars) = |
119 |
let |
|
120 |
val inst = mk_inst ctxt vars |
|
121 |
val names = fold (Term.add_free_names o Thm.term_of o snd) inst [] |
|
122 |
in (mk_prop (Thm.instantiate_cterm ([], inst) ct), names) end |
|
123 |
||
124 |
||
125 |
fun mk_bound thy (i, T) = |
|
126 |
let val ct = Thm.cterm_of thy (Var ((Name.uu, 0), T)) |
|
127 |
in (ct, [(i, ct)]) end |
|
128 |
||
129 |
local |
|
130 |
fun mk_quant thy q T (ct, vars) = |
|
131 |
let |
|
132 |
val cv = |
|
133 |
(case AList.lookup (op =) vars 0 of |
|
134 |
SOME cv => cv |
|
135 |
| _ => Thm.cterm_of thy (Var ((Name.uu, maxidx_of ct + 1), T))) |
|
136 |
fun dec (i, v) = if i = 0 then NONE else SOME (i-1, v) |
|
36899
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
137 |
in (Thm.capply (I.instT' cv q) (Thm.cabs cv ct), map_filter dec vars) end |
36898 | 138 |
|
36899
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
139 |
val forall = I.mk_inst_pair (I.destT1 o I.destT1) @{cpat All} |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
140 |
val exists = I.mk_inst_pair (I.destT1 o I.destT1) @{cpat Ex} |
36898 | 141 |
in |
142 |
fun mk_forall thy = fold_rev (mk_quant thy forall) |
|
143 |
fun mk_exists thy = fold_rev (mk_quant thy exists) |
|
144 |
end |
|
145 |
||
146 |
||
147 |
local |
|
148 |
fun equal_var cv (_, cu) = (cv aconvc cu) |
|
149 |
||
36899
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
150 |
fun prep (ct, vars) (maxidx, all_vars) = |
36898 | 151 |
let |
36899
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
152 |
val maxidx' = maxidx_of ct + maxidx + 1 |
36898 | 153 |
|
154 |
fun part (v as (i, cv)) = |
|
36899
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
155 |
(case AList.lookup (op =) all_vars i of |
36898 | 156 |
SOME cu => apfst (if cu aconvc cv then I else cons (cv, cu)) |
157 |
| NONE => |
|
36899
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
158 |
if not (exists (equal_var cv) all_vars) then apsnd (cons v) |
36898 | 159 |
else |
36899
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
160 |
let val cv' = Thm.incr_indexes_cterm maxidx' cv |
36898 | 161 |
in apfst (cons (cv, cv')) #> apsnd (cons (i, cv')) end) |
162 |
||
36899
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
163 |
val (inst, vars') = |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
164 |
if null vars then ([], vars) |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
165 |
else fold part vars ([], []) |
36898 | 166 |
|
36899
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
167 |
in (Thm.instantiate_cterm ([], inst) ct, (maxidx', vars' @ all_vars)) end |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
168 |
in |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
169 |
fun mk_fun f ts = |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
170 |
let val (cts, (_, vars)) = fold_map prep ts (~1, []) |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
171 |
in f cts |> Option.map (rpair vars) end |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
172 |
end |
36898 | 173 |
|
174 |
||
175 |
||
176 |
(** proof parser **) |
|
177 |
||
178 |
datatype proof_step = Proof_Step of { |
|
179 |
rule: rule, |
|
180 |
prems: int list, |
|
181 |
prop: cterm } |
|
182 |
||
183 |
||
184 |
(* parser context *) |
|
185 |
||
40579
98ebd2300823
use the const antiquotation for constants (this checks that the constant is declared, whereas the more general term antiquotation treats undeclared names as free variable)
boehmes
parents:
40516
diff
changeset
|
186 |
val not_false = Thm.cterm_of @{theory} (@{const Not} $ @{const False}) |
98ebd2300823
use the const antiquotation for constants (this checks that the constant is declared, whereas the more general term antiquotation treats undeclared names as free variable)
boehmes
parents:
40516
diff
changeset
|
187 |
|
36898 | 188 |
fun make_context ctxt typs terms = |
189 |
let |
|
190 |
val ctxt' = |
|
191 |
ctxt |
|
192 |
|> Symtab.fold (Variable.declare_typ o snd) typs |
|
193 |
|> Symtab.fold (Variable.declare_term o snd) terms |
|
194 |
||
40579
98ebd2300823
use the const antiquotation for constants (this checks that the constant is declared, whereas the more general term antiquotation treats undeclared names as free variable)
boehmes
parents:
40516
diff
changeset
|
195 |
fun cert @{const True} = not_false |
36898 | 196 |
| cert t = certify ctxt' t |
36899
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
197 |
|
39020 | 198 |
in (typs, Symtab.map (K cert) terms, Inttab.empty, Inttab.empty, [], ctxt') end |
36898 | 199 |
|
200 |
fun fresh_name n (typs, terms, exprs, steps, vars, ctxt) = |
|
201 |
let val (n', ctxt') = yield_singleton Variable.variant_fixes n ctxt |
|
202 |
in (n', (typs, terms, exprs, steps, vars, ctxt')) end |
|
203 |
||
204 |
fun theory_of (_, _, _, _, _, ctxt) = ProofContext.theory_of ctxt |
|
205 |
||
206 |
fun add_decl (n, T) (cx as (_, terms, _, _, _, _)) = |
|
207 |
(case Symtab.lookup terms n of |
|
208 |
SOME _ => cx |
|
209 |
| NONE => cx |> fresh_name (decl_prefix ^ n) |
|
210 |
|> (fn (m, (typs, terms, exprs, steps, vars, ctxt)) => |
|
211 |
let val upd = Symtab.update (n, certify ctxt (Free (m, T))) |
|
212 |
in (typs, upd terms, exprs, steps, vars, ctxt) end)) |
|
213 |
||
36899
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
214 |
fun mk_typ (typs, _, _, _, _, ctxt) (s as I.Sym (n, _)) = |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
215 |
(case I.mk_builtin_typ ctxt s of |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
216 |
SOME T => SOME T |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
217 |
| NONE => Symtab.lookup typs n) |
36898 | 218 |
|
36899
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
219 |
fun mk_num (_, _, _, _, _, ctxt) (i, T) = |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
220 |
mk_fun (K (I.mk_builtin_num ctxt i T)) [] |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
221 |
|
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
222 |
fun mk_app (_, terms, _, _, _, ctxt) (s as I.Sym (n, _), es) = |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
223 |
mk_fun (fn cts => |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
224 |
(case I.mk_builtin_fun ctxt s cts of |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
225 |
SOME ct => SOME ct |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
226 |
| NONE => |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
227 |
Symtab.lookup terms n |> Option.map (Drule.list_comb o rpair cts))) es |
36898 | 228 |
|
229 |
fun add_expr k t (typs, terms, exprs, steps, vars, ctxt) = |
|
230 |
(typs, terms, Inttab.update (k, t) exprs, steps, vars, ctxt) |
|
231 |
||
232 |
fun lookup_expr (_, _, exprs, _, _, _) = Inttab.lookup exprs |
|
233 |
||
234 |
fun add_proof_step k ((r, prems), prop) cx = |
|
235 |
let |
|
236 |
val (typs, terms, exprs, steps, vars, ctxt) = cx |
|
237 |
val (ct, vs) = close ctxt prop |
|
238 |
val step = Proof_Step {rule=r, prems=prems, prop=ct} |
|
239 |
val vars' = union (op =) vs vars |
|
240 |
in (typs, terms, exprs, Inttab.update (k, step) steps, vars', ctxt) end |
|
241 |
||
242 |
fun finish (_, _, _, steps, vars, ctxt) = (steps, vars, ctxt) |
|
243 |
||
244 |
||
245 |
(* core parser *) |
|
246 |
||
40424
7550b2cba1cb
better modularization: moved SMT configuration options and diagnostics as well as SMT failure and exception into separate structures (both of which are loaded first and consequently are available to other SMT structures)
boehmes
parents:
40162
diff
changeset
|
247 |
fun parse_exn line_no msg = raise SMT_Failure.SMT (SMT_Failure.Other_Failure |
40162
7f58a9a843c2
joined setup of SMT solvers in one place; turned Z3-specific options into SMT options (renamed configuration options from z3_* to smt_*); more detailed SMT exception; improved SMT filter interface
boehmes
parents:
39020
diff
changeset
|
248 |
("Z3 proof parser (line " ^ string_of_int line_no ^ "): " ^ msg)) |
36898 | 249 |
|
250 |
fun scan_exn msg ((line_no, _), _) = parse_exn line_no msg |
|
251 |
||
252 |
fun with_info f cx = |
|
253 |
(case f ((NONE, 1), cx) of |
|
254 |
((SOME root, _), cx') => (root, cx') |
|
255 |
| ((_, line_no), _) => parse_exn line_no "bad proof") |
|
256 |
||
257 |
fun parse_line _ _ (st as ((SOME _, _), _)) = st |
|
258 |
| parse_line scan line ((_, line_no), cx) = |
|
40627
becf5d5187cc
renamed raw "explode" function to "raw_explode" to emphasize its meaning;
wenzelm
parents:
40579
diff
changeset
|
259 |
let val st = ((line_no, cx), raw_explode line) |
36898 | 260 |
in |
261 |
(case Scan.catch (Scan.finite' Symbol.stopper (Scan.option scan)) st of |
|
262 |
(SOME r, ((_, cx'), _)) => ((r, line_no+1), cx') |
|
263 |
| (NONE, _) => parse_exn line_no ("bad proof line: " ^ quote line)) |
|
264 |
end |
|
265 |
||
266 |
fun with_context f x ((line_no, cx), st) = |
|
267 |
let val (y, cx') = f x cx |
|
268 |
in (y, ((line_no, cx'), st)) end |
|
269 |
||
270 |
||
271 |
fun lookup_context f x (st as ((_, cx), _)) = (f cx x, st) |
|
272 |
||
273 |
||
274 |
(* parser combinators and parsers for basic entities *) |
|
275 |
||
276 |
fun $$ s = Scan.lift (Scan.$$ s) |
|
277 |
fun this s = Scan.lift (Scan.this_string s) |
|
40516 | 278 |
val is_blank = Symbol.is_ascii_blank |
279 |
fun blank st = Scan.lift (Scan.many1 is_blank) st |
|
36898 | 280 |
fun sep scan = blank |-- scan |
281 |
fun seps scan = Scan.repeat (sep scan) |
|
282 |
fun seps1 scan = Scan.repeat1 (sep scan) |
|
283 |
fun seps_by scan_sep scan = scan ::: Scan.repeat (scan_sep |-- scan) |
|
284 |
||
40516 | 285 |
val lpar = "(" and rpar = ")" |
286 |
val lbra = "[" and rbra = "]" |
|
287 |
fun par scan = $$ lpar |-- scan --| $$ rpar |
|
288 |
fun bra scan = $$ lbra |-- scan --| $$ rbra |
|
36898 | 289 |
|
290 |
val digit = (fn |
|
291 |
"0" => SOME 0 | "1" => SOME 1 | "2" => SOME 2 | "3" => SOME 3 | |
|
292 |
"4" => SOME 4 | "5" => SOME 5 | "6" => SOME 6 | "7" => SOME 7 | |
|
293 |
"8" => SOME 8 | "9" => SOME 9 | _ => NONE) |
|
294 |
||
36940 | 295 |
fun digits st = (Scan.lift (Scan.many1 Symbol.is_ascii_digit) >> implode) st |
296 |
fun nat_num st = (Scan.lift (Scan.repeat1 (Scan.some digit)) >> (fn ds => |
|
297 |
fold (fn d => fn i => i * 10 + d) ds 0)) st |
|
298 |
fun int_num st = (Scan.optional ($$ "-" >> K (fn i => ~i)) I :|-- |
|
299 |
(fn sign => nat_num >> sign)) st |
|
36898 | 300 |
|
301 |
val is_char = Symbol.is_ascii_letter orf Symbol.is_ascii_digit orf |
|
40627
becf5d5187cc
renamed raw "explode" function to "raw_explode" to emphasize its meaning;
wenzelm
parents:
40579
diff
changeset
|
302 |
member (op =) (raw_explode "_+*-/%~=<>$&|?!.@^#") |
36940 | 303 |
fun name st = (Scan.lift (Scan.many1 is_char) >> implode) st |
36898 | 304 |
|
36899
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
305 |
fun sym st = |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
306 |
(name -- Scan.optional (bra (seps_by ($$ ":") sym)) [] >> I.Sym) st |
36898 | 307 |
|
308 |
fun id st = ($$ "#" |-- nat_num) st |
|
309 |
||
310 |
||
311 |
(* parsers for various parts of Z3 proofs *) |
|
312 |
||
313 |
fun sort st = Scan.first [ |
|
314 |
this "array" |-- bra (sort --| $$ ":" -- sort) >> (op -->), |
|
315 |
par (this "->" |-- seps1 sort) >> ((op --->) o split_last), |
|
36899
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
316 |
sym :|-- (fn s as I.Sym (n, _) => lookup_context mk_typ s :|-- (fn |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
317 |
SOME T => Scan.succeed T |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
318 |
| NONE => scan_exn ("unknown sort: " ^ quote n)))] st |
36898 | 319 |
|
320 |
fun bound st = (par (this ":var" |-- sep nat_num -- sep sort) :|-- |
|
321 |
lookup_context (mk_bound o theory_of)) st |
|
322 |
||
36899
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
323 |
fun numb (n as (i, _)) = lookup_context mk_num n :|-- (fn |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
324 |
SOME n' => Scan.succeed n' |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
325 |
| NONE => scan_exn ("unknown number: " ^ quote (string_of_int i))) |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
326 |
|
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
327 |
fun appl (app as (I.Sym (n, _), _)) = lookup_context mk_app app :|-- (fn |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
328 |
SOME app' => Scan.succeed app' |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
329 |
| NONE => scan_exn ("unknown function symbol: " ^ quote n)) |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
330 |
|
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
331 |
fun bv_size st = (digits >> (fn sz => I.Sym ("bv", [I.Sym (sz, [])]))) st |
36898 | 332 |
|
36899
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
333 |
fun bv_number_sort st = (bv_size :|-- lookup_context mk_typ :|-- (fn |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
334 |
SOME cT => Scan.succeed cT |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
335 |
| NONE => scan_exn ("unknown sort: " ^ quote "bv"))) st |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
336 |
|
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
337 |
fun bv_number st = |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
338 |
(this "bv" |-- bra (nat_num --| $$ ":" -- bv_number_sort) :|-- numb) st |
36898 | 339 |
|
36899
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
340 |
fun frac_number st = ( |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
341 |
int_num --| $$ "/" -- int_num --| this "::" -- sort :|-- (fn ((i, j), T) => |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
342 |
numb (i, T) -- numb (j, T) :|-- (fn (n, m) => |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
343 |
appl (I.Sym ("/", []), [n, m])))) st |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
344 |
|
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
345 |
fun plain_number st = (int_num --| this "::" -- sort :|-- numb) st |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
346 |
|
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
347 |
fun number st = Scan.first [bv_number, frac_number, plain_number] st |
36898 | 348 |
|
349 |
fun constant st = ((sym >> rpair []) :|-- appl) st |
|
350 |
||
351 |
fun expr_id st = (id :|-- (fn i => lookup_context lookup_expr i :|-- (fn |
|
352 |
SOME e => Scan.succeed e |
|
353 |
| NONE => scan_exn ("unknown term id: " ^ quote (string_of_int i))))) st |
|
354 |
||
36899
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
355 |
fun arg st = Scan.first [expr_id, number, constant] st |
36898 | 356 |
|
357 |
fun application st = par ((sym -- Scan.repeat1 (sep arg)) :|-- appl) st |
|
358 |
||
359 |
fun variables st = par (this "vars" |-- seps1 (par (name |-- sep sort))) st |
|
360 |
||
36899
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
361 |
fun pats st = seps (par ((this ":pat" || this ":nopat") |-- seps1 id)) st |
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
362 |
|
40579
98ebd2300823
use the const antiquotation for constants (this checks that the constant is declared, whereas the more general term antiquotation treats undeclared names as free variable)
boehmes
parents:
40516
diff
changeset
|
363 |
val ctrue = Thm.cterm_of @{theory} @{const True} |
98ebd2300823
use the const antiquotation for constants (this checks that the constant is declared, whereas the more general term antiquotation treats undeclared names as free variable)
boehmes
parents:
40516
diff
changeset
|
364 |
|
36899
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
365 |
fun pattern st = par (this "pattern" |-- Scan.repeat1 (sep arg) >> |
40579
98ebd2300823
use the const antiquotation for constants (this checks that the constant is declared, whereas the more general term antiquotation treats undeclared names as free variable)
boehmes
parents:
40516
diff
changeset
|
366 |
(the o mk_fun (K (SOME ctrue)))) st |
36898 | 367 |
|
368 |
fun quant_kind st = st |> ( |
|
369 |
this "forall" >> K (mk_forall o theory_of) || |
|
370 |
this "exists" >> K (mk_exists o theory_of)) |
|
371 |
||
372 |
fun quantifier st = |
|
36899
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
373 |
(par (quant_kind -- sep variables --| pats -- sep arg) :|-- |
36898 | 374 |
lookup_context (fn cx => fn ((mk_q, Ts), body) => mk_q cx Ts body)) st |
375 |
||
376 |
fun expr k = |
|
36899
bcd6fce5bf06
layered SMT setup, adapted SMT clients, added further tests, made Z3 proof abstraction configurable
boehmes
parents:
36898
diff
changeset
|
377 |
Scan.first [bound, quantifier, pattern, application, number, constant] :|-- |
36898 | 378 |
with_context (pair NONE oo add_expr k) |
379 |
||
40516 | 380 |
fun th_lemma_arg st = |
381 |
Scan.lift (Scan.many1 (not o (is_blank orf equal rbra)) >> implode) st |
|
382 |
||
36898 | 383 |
fun rule_name st = ((name >> `(Symtab.lookup rule_names)) :|-- (fn |
40516 | 384 |
(SOME (ThLemma _), _) => |
385 |
let fun stop st = (sep id >> K "" || $$ rbra) st |
|
386 |
in Scan.repeat (Scan.unless stop (sep th_lemma_arg)) >> ThLemma end |
|
387 |
| (SOME r, _) => Scan.succeed r |
|
36898 | 388 |
| (NONE, n) => scan_exn ("unknown proof rule: " ^ quote n))) st |
389 |
||
390 |
fun rule f k = |
|
391 |
bra (rule_name -- seps id) --| $$ ":" -- sep arg #-> |
|
392 |
with_context (pair (f k) oo add_proof_step k) |
|
393 |
||
394 |
fun decl st = (this "decl" |-- sep name --| sep (this "::") -- sep sort :|-- |
|
395 |
with_context (pair NONE oo add_decl)) st |
|
396 |
||
397 |
fun def st = (id --| sep (this ":=")) st |
|
398 |
||
399 |
fun node st = st |> ( |
|
400 |
decl || |
|
401 |
def :|-- (fn k => sep (expr k) || sep (rule (K NONE) k)) || |
|
402 |
rule SOME ~1) |
|
403 |
||
404 |
||
405 |
(* overall parser *) |
|
406 |
||
407 |
(* Currently, terms are parsed bottom-up (i.e., along with parsing the proof |
|
408 |
text line by line), but proofs are reconstructed top-down (i.e. by an |
|
409 |
in-order top-down traversal of the proof tree/graph). The latter approach |
|
410 |
was taken because some proof texts comprise irrelevant proof steps which |
|
411 |
will thus not be reconstructed. This approach might also be beneficial |
|
412 |
for constructing terms, but it would also increase the complexity of the |
|
413 |
(otherwise rather modular) code. *) |
|
414 |
||
415 |
fun parse ctxt typs terms proof_text = |
|
416 |
make_context ctxt typs terms |
|
417 |
|> with_info (fold (parse_line node) proof_text) |
|
418 |
||> finish |
|
419 |
||
420 |
end |