src/HOL/SMT/Tools/z3_proof.ML
author haftmann
Thu, 29 Apr 2010 15:00:42 +0200
changeset 36534 0090b04432f7
parent 34960 1d5ee19ef940
child 36893 48cf03469dc6
permissions -rw-r--r--
dropped code_datatype antiquotation
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
     1
(*  Title:      HOL/SMT/Tools/z3_proof.ML
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
     2
    Author:     Sascha Boehme, TU Muenchen
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
     3
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
     4
Proof reconstruction for proofs found by Z3.
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
     5
*)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
     6
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
     7
signature Z3_PROOF =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
     8
sig
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
     9
  val reconstruct: Proof.context -> thm list option -> SMT_Translate.recon ->
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    10
    string list -> thm
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    11
end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    12
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    13
structure Z3_Proof: Z3_PROOF =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    14
struct
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    15
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    16
structure T = Z3_Proof_Terms
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    17
structure R = Z3_Proof_Rules
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    18
33418
1312e8337ce5 added a specific SMT exception captured by smt_tac (prevents the SMT method from failing with an exception),
boehmes
parents: 33243
diff changeset
    19
fun z3_exn msg = raise SMT_Solver.SMT ("Z3 proof reconstruction: " ^ msg)
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    20
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    21
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    22
fun lift f (x, y) = apsnd (pair x) (f y)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    23
fun lift' f v (x, y) = apsnd (rpair y) (f v x)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    24
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    25
fun $$ s = lift (Scan.$$ s)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    26
fun this s = lift (Scan.this_string s)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    27
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    28
fun blank s = lift (Scan.many1 Symbol.is_ascii_blank) s
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    29
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    30
fun par scan = $$ "(" |-- scan --| $$ ")"
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    31
fun bra scan = $$ "[" |-- scan --| $$ "]"
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    32
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    33
val digit = (fn
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    34
  "0" => SOME 0 | "1" => SOME 1 | "2" => SOME 2 | "3" => SOME 3 |
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    35
  "4" => SOME 4 | "5" => SOME 5 | "6" => SOME 6 | "7" => SOME 7 |
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    36
  "8" => SOME 8 | "9" => SOME 9 | _ => NONE)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    37
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    38
val nat_num = Scan.repeat1 (Scan.some digit) >>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    39
  (fn ds => fold (fn d => fn i => i * 10 + d) ds 0)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    40
val int_num = Scan.optional (Scan.$$ "-" >> K (fn i => ~i)) I :|--
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    41
  (fn sign => nat_num >> sign)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    42
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    43
val is_char = Symbol.is_ascii_letter orf Symbol.is_ascii_digit orf
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    44
  member (op =) (explode "_+*-/%~=<>$&|?!.@^#")
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    45
val name = Scan.many1 is_char >> implode
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    46
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    47
datatype sym = Sym of string * sym list
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    48
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    49
datatype context = Context of {
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    50
  Ttab: typ Symtab.table,
33243
17014b1b9353 normalized basic type abbreviations;
wenzelm
parents: 33047
diff changeset
    51
  ttab: cterm Symtab.table,
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    52
  etab: T.preterm Inttab.table,
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    53
  ptab: R.proof Inttab.table,
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    54
  nctxt: Name.context }
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    55
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    56
fun make_context (Ttab, ttab, etab, ptab, nctxt) =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    57
  Context {Ttab=Ttab, ttab=ttab, etab=etab, ptab=ptab, nctxt=nctxt}
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    58
33017
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 33010
diff changeset
    59
fun empty_context thy ({typs, terms=ttab} : SMT_Translate.recon) =
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    60
  let
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    61
    val ttab' = Symtab.map (fn @{term True} => @{term "~False"} | t => t) ttab
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    62
    val ns = Symtab.fold (Term.add_free_names o snd) ttab' []
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    63
    val nctxt = Name.make_context ns
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    64
    val tt = Symtab.map (Thm.cterm_of thy) ttab'
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    65
  in make_context (typs, tt, Inttab.empty, Inttab.empty, nctxt) end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    66
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    67
fun map_context f (Context {Ttab, ttab, etab, ptab, nctxt}) =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    68
  make_context (f (Ttab, ttab, etab, ptab, nctxt))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    69
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    70
fun map_type_tab f = map_context (fn (Ttab, ttab, etab, ptab, nctxt) =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    71
  (f Ttab, ttab, etab, ptab, nctxt))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    72
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    73
fun map_term_tab f = map_context (fn (Ttab, ttab, etab, ptab, nctxt) =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    74
  (Ttab, f ttab, etab, ptab, nctxt))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    75
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    76
fun map_expr_tab f = map_context (fn (Ttab, ttab, etab, ptab, nctxt) =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    77
  (Ttab, ttab, f etab, ptab, nctxt))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    78
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    79
fun map_proof_tab f = map_context (fn (Ttab, ttab, etab, ptab, nctxt) =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    80
  (Ttab, ttab, etab, f ptab, nctxt))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    81
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    82
val free_prefix = "f"
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    83
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    84
fun fresh_name (cx as Context {nctxt, ...}) =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    85
  let val (n, nctxt') = yield_singleton Name.variants free_prefix nctxt
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    86
  in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    87
    (n, map_context (fn (Ttab, ttab, etab, ptab, _) =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    88
      (Ttab, ttab, etab, ptab, nctxt')) cx)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    89
  end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    90
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    91
fun typ_of_sort name (cx as Context {Ttab, ...}) =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    92
  (case Symtab.lookup Ttab name of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    93
    SOME T => (T, cx)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    94
  | _ => cx |> fresh_name |-> (fn n =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    95
      let val T = TFree ("'" ^ n, @{sort type})
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    96
      in pair T o map_type_tab (Symtab.update (name, T)) end))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    97
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    98
fun lookup_expr id (cx as Context {etab, ...}) =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
    99
  (case Inttab.lookup etab id of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   100
    SOME e => (e, cx)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   101
  | _ => z3_exn ("unknown term id: " ^ quote (string_of_int id)))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   102
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   103
fun add_expr k t = map_expr_tab (Inttab.update (k, t))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   104
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   105
fun add_proof thy k ((r, ps), t) (cx as Context {nctxt, ...}) =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   106
  let val p = R.make_proof r ps (T.compile thy nctxt t)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   107
  in (k, map_proof_tab (Inttab.update (k, p)) cx) end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   108
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   109
fun mk_app app (cx as Context {ttab, ...}) =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   110
  let
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   111
    val mk = 
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   112
      (fn
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   113
        (Sym ("true", _), _) => T.mk_true
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   114
      | (Sym ("false", _), _) => T.mk_false
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   115
      | (Sym ("=", _), [t, u]) => T.mk_eq t u
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   116
      | (Sym ("distinct", _), ts) => T.mk_distinct ts
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   117
      | (Sym ("ite", _), [s, t, u]) => T.mk_if s t u
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   118
      | (Sym ("and", _), ts) => T.mk_and ts
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   119
      | (Sym ("or", _), ts) => T.mk_or ts
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   120
      | (Sym ("iff", _), [t, u]) => T.mk_iff t u
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   121
      | (Sym ("xor", _), [t, u]) => T.mk_not (T.mk_iff t u)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   122
      | (Sym ("not", _), [t]) => T.mk_not t
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   123
      | (Sym ("implies", _), [t, u]) => T.mk_implies t u
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   124
      | (Sym ("~", _), [t, u]) => T.mk_eq t u
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   125
      | (Sym ("<", _), [t, u]) => T.mk_lt t u
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   126
      | (Sym ("<=", _), [t, u]) => T.mk_le t u
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   127
      | (Sym (">", _), [t, u]) => T.mk_lt u t
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   128
      | (Sym (">=", _), [t, u]) => T.mk_le u t
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   129
      | (Sym ("+", _), [t, u]) => T.mk_add t u
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   130
      | (Sym ("-", _), [t, u]) => T.mk_sub t u
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   131
      | (Sym ("-", _), [t]) => T.mk_uminus t
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   132
      | (Sym ("*", _), [t, u]) => T.mk_mul t u
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   133
      | (Sym ("/", _), [t, u]) => T.mk_real_div t u
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   134
      | (Sym ("div", _), [t, u]) => T.mk_int_div t u
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   135
      | (Sym ("mod", _), [t, u]) => T.mk_mod t u
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   136
      | (Sym ("rem", _), [t, u]) => T.mk_rem t u
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   137
      | (Sym ("select", _), [m, k]) => T.mk_access m k
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   138
      | (Sym ("store", _), [m, k, v]) => T.mk_update m k v
34960
1d5ee19ef940 support skolem constant for extensional arrays in Z3 proofs
boehmes
parents: 33418
diff changeset
   139
      | (Sym ("array-ext", _), [m1, m2]) => T.mk_array_ext m1 m2
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   140
      | (Sym ("pattern", _), _) => T.mk_true
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   141
      | (Sym (n, _), ts) =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   142
          (case Symtab.lookup ttab n of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   143
            SOME ct => T.mk_fun ct ts
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   144
          | NONE => z3_exn ("unknown function: " ^ quote n)))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   145
  in (mk app, cx) end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   146
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   147
fun add_decl thy (n, T) (cx as Context {ttab, ...}) =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   148
  (case Symtab.lookup ttab n of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   149
    SOME _ => cx
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   150
  | _ => cx |> fresh_name |-> (fn n' =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   151
      map_term_tab (Symtab.update (n, Thm.cterm_of thy (Free (n', T))))))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   152
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   153
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   154
fun sep scan_sep scan = scan ::: Scan.repeat (scan_sep |-- scan)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   155
fun bsep scan = Scan.repeat (blank |-- scan)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   156
fun bsep1 scan = Scan.repeat1 (blank |-- scan)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   157
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   158
val id = Scan.$$ "#" |-- int_num
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   159
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   160
fun sym s =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   161
  (lift name -- Scan.optional (bra (sep ($$ ":") sym)) [] >> Sym) s
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   162
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   163
fun sort st = Scan.first [
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   164
  this "bool" >> K @{typ bool},
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   165
  this "int" >> K @{typ int},
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   166
  this "real" >> K @{typ real},
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   167
  this "bv" |-- bra (lift int_num) >> T.wordT,
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   168
  this "array" |-- bra (sort --| $$ ":" -- sort) >> (op -->),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   169
  par (this "->" |-- bsep1 sort) >> ((op --->) o split_last),
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   170
  lift name #-> lift' typ_of_sort] st
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   171
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   172
fun bound thy =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   173
  par (this ":var" -- blank |-- lift int_num --| blank -- sort) >>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   174
  uncurry (T.mk_bound thy)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   175
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   176
val number = 
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   177
  int_num -- Scan.option (Scan.$$ "/" |-- int_num) --|
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   178
  Scan.this_string "::" :|-- (fn num as (n, _) =>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   179
    Scan.this_string "int" >> K (T.mk_int_num n) ||
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   180
    Scan.this_string "real" >> K (T.mk_real_frac_num num))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   181
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   182
fun bv_number thy =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   183
  this "bv" |-- bra (lift (int_num --| Scan.$$ ":" -- int_num)) >>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   184
  uncurry (T.mk_bv_num thy)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   185
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   186
val constant = sym #-> lift' (mk_app o rpair [])
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   187
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   188
fun arg thy = Scan.first [lift id #-> lift' lookup_expr,
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   189
  lift number, bv_number thy, constant]
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   190
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   191
fun application thy =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   192
  par (sym -- bsep1 (arg thy)) #-> lift' mk_app
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   193
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   194
val variables =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   195
  par (this "vars" |-- bsep1 (par ((lift name >> K "x") --| blank -- sort)))
33047
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   196
fun patterns st =
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   197
  bsep (par ((this ":pat" || this ":nopat") |-- bsep1 (lift id))) st
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   198
fun quant_kind st =
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   199
 (this "forall" >> K T.mk_forall ||
69780aef0531 proper handling of single literal case,
boehmes
parents: 33017
diff changeset
   200
  this "exists" >> K T.mk_exists) st
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   201
fun quantifier thy = par (quant_kind --| blank --
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   202
  variables --| patterns --| blank -- arg thy) >>
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   203
  (fn ((q, vs), body) => fold_rev (q thy) vs body)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   204
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   205
fun expr thy k = Scan.first [bound thy, quantifier thy, application thy,
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   206
  lift number, bv_number thy, constant] #-> apfst o add_expr k
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   207
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   208
fun rule_name name =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   209
  (case R.rule_of_string name of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   210
    SOME r => r
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   211
  | NONE => z3_exn ("unknown proof rule: " ^ quote name))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   212
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   213
fun rule thy k =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   214
  bra (lift (name >> rule_name) -- bsep (lift id)) --|
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   215
  ($$ ":" -- blank) -- arg thy #-> lift' (add_proof thy k)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   216
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   217
fun decl thy = ((this "decl" -- blank) |-- lift name --|
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   218
  (blank -- this "::" -- blank) -- sort) #-> apfst o add_decl thy
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   219
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   220
fun def st = (lift id --| (blank -- this ":=" -- blank)) st
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   221
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   222
fun node thy =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   223
  decl thy #> pair NONE ||
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   224
  def :|-- (fn k => expr thy k #> pair NONE || rule thy k #>> K NONE) ||
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   225
  rule thy ~1 #>> SOME
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   226
33418
1312e8337ce5 added a specific SMT exception captured by smt_tac (prevents the SMT method from failing with an exception),
boehmes
parents: 33243
diff changeset
   227
fun handle_errors line_no scan (st as (_, xs)) =
1312e8337ce5 added a specific SMT exception captured by smt_tac (prevents the SMT method from failing with an exception),
boehmes
parents: 33243
diff changeset
   228
  (case try scan st of
1312e8337ce5 added a specific SMT exception captured by smt_tac (prevents the SMT method from failing with an exception),
boehmes
parents: 33243
diff changeset
   229
    SOME y => y
1312e8337ce5 added a specific SMT exception captured by smt_tac (prevents the SMT method from failing with an exception),
boehmes
parents: 33243
diff changeset
   230
  | NONE => z3_exn ("parse error at line " ^ string_of_int line_no ^ ": " ^
1312e8337ce5 added a specific SMT exception captured by smt_tac (prevents the SMT method from failing with an exception),
boehmes
parents: 33243
diff changeset
   231
      quote (implode xs)))
33010
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   232
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   233
fun parse_line thy l (st as (stop, line_no, cx)) =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   234
  if is_some stop then st
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   235
  else
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   236
    (cx, explode l)
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   237
    |> handle_errors line_no (Scan.finite' Symbol.stopper (node thy))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   238
    |> (fn (stop', (cx', _)) => (stop', line_no + 1, cx'))
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   239
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   240
fun reconstruct ctxt assms recon output =
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   241
  let
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   242
    val _ = T.var_prefix <> free_prefix orelse error "Same prefixes"
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   243
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   244
    val thy = ProofContext.theory_of ctxt
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   245
  in
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   246
    (case fold (parse_line thy) output (NONE, 1, empty_context thy recon) of
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   247
      (SOME p, _, Context {ptab, ...}) => R.prove ctxt assms ptab p
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   248
    | _ => z3_exn "bad proof")
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   249
  end
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   250
39f73a59e855 added proof reconstructon for Z3,
boehmes
parents:
diff changeset
   251
end