src/HOL/SMT/Tools/smt_translate.ML
author haftmann
Fri, 07 May 2010 15:05:52 +0200
changeset 36751 7f1da69cacb3
parent 36087 37a5735783c5
permissions -rw-r--r--
split of semiring normalization from Groebner theory; moved field_comp_conv to Numeral_Simproces
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
     1
(*  Title:      HOL/SMT/Tools/smt_translate.ML
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
     2
    Author:     Sascha Boehme, TU Muenchen
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
     3
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
     4
Translate theorems into an SMT intermediate format and serialize them,
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
     5
depending on an SMT interface.
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
     6
*)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
     7
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
     8
signature SMT_TRANSLATE =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
     9
sig
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    10
  (* intermediate term structure *)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    11
  datatype sym =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    12
    SConst of string * typ |
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    13
    SFree of string * typ |
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    14
    SNum of int * typ
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    15
  datatype squant = SForall | SExists
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    16
  datatype 'a spattern = SPat of 'a list | SNoPat of 'a list
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    17
  datatype ('a, 'b) sterm =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    18
    SVar of int |
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    19
    SApp of 'a * ('a, 'b) sterm list |
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    20
    SLet of (string * 'b) * ('a, 'b) sterm * ('a, 'b) sterm |
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    21
    SQuant of squant * (string * 'b) list * ('a, 'b) sterm spattern list *
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    22
      ('a, 'b) sterm
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    23
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    24
  (* table for built-in symbols *)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    25
  type builtin_fun = typ -> (sym, typ) sterm list ->
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    26
    (string * (sym, typ) sterm list) option
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    27
  type builtin_table = (typ * builtin_fun) list Symtab.table
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    28
  val builtin_make: (term * string) list -> builtin_table
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    29
  val builtin_add: term * builtin_fun -> builtin_table -> builtin_table
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    30
  val builtin_lookup: builtin_table -> theory -> string * typ ->
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    31
    (sym, typ) sterm list -> (string * (sym, typ) sterm list) option
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    32
  val bv_rotate: (int -> string) -> builtin_fun
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    33
  val bv_extend: (int -> string) -> builtin_fun
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    34
  val bv_extract: (int -> int -> string) -> builtin_fun
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    35
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    36
  (* configuration options *)
33017
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 32618
diff changeset
    37
  type prefixes = {
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    38
    var_prefix: string,
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    39
    typ_prefix: string,
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    40
    fun_prefix: string,
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    41
    pred_prefix: string }
33017
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 32618
diff changeset
    42
  type markers = {
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    43
    term_marker: string,
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    44
    formula_marker: string }
33017
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 32618
diff changeset
    45
  type builtins = {
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    46
    builtin_typ: typ -> string option,
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    47
    builtin_num: int * typ -> string option,
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    48
    builtin_fun: bool -> builtin_table }
33017
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 32618
diff changeset
    49
  type sign = {
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    50
    typs: string list,
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    51
    funs: (string * (string list * string)) list,
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    52
    preds: (string * string list) list }
33017
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 32618
diff changeset
    53
  type config = {
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    54
    strict: bool,
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    55
    prefixes: prefixes,
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    56
    markers: markers,
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    57
    builtins: builtins,
36087
37a5735783c5 buffered output (faster than direct output)
boehmes
parents: 35980
diff changeset
    58
    serialize: sign -> (string, string) sterm list -> string}
33017
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 32618
diff changeset
    59
  type recon = {typs: typ Symtab.table, terms: term Symtab.table}
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    60
36087
37a5735783c5 buffered output (faster than direct output)
boehmes
parents: 35980
diff changeset
    61
  val translate: config -> theory -> thm list -> string * (recon * thm list)
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    62
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    63
  val dest_binT: typ -> int
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    64
  val dest_funT: int -> typ -> typ list * typ
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    65
end
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    66
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    67
structure SMT_Translate: SMT_TRANSLATE =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    68
struct
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    69
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    70
(* Intermediate term structure *)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    71
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    72
datatype sym =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    73
  SConst of string * typ |
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    74
  SFree of string * typ |
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    75
  SNum of int * typ
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    76
datatype squant = SForall | SExists
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    77
datatype 'a spattern = SPat of 'a list | SNoPat of 'a list
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    78
datatype ('a, 'b) sterm =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    79
  SVar of int |
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    80
  SApp of 'a * ('a, 'b) sterm list |
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    81
  SLet of (string * 'b) * ('a, 'b) sterm * ('a, 'b) sterm |
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    82
  SQuant of squant * (string * 'b) list * ('a, 'b) sterm spattern list *
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    83
    ('a, 'b) sterm
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    84
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    85
fun app c ts = SApp (c, ts)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    86
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    87
fun map_pat f (SPat ps) = SPat (map f ps)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    88
  | map_pat f (SNoPat ps) = SNoPat (map f ps)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    89
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    90
fun fold_map_pat f (SPat ps) = fold_map f ps #>> SPat
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    91
  | fold_map_pat f (SNoPat ps) = fold_map f ps #>> SNoPat
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    92
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    93
val make_sconst = SConst o Term.dest_Const
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    94
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    95
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    96
(* General type destructors. *)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    97
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    98
fun dest_binT T =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
    99
  (case T of
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   100
    Type (@{type_name "Numeral_Type.num0"}, _) => 0
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   101
  | Type (@{type_name "Numeral_Type.num1"}, _) => 1
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   102
  | Type (@{type_name "Numeral_Type.bit0"}, [T]) => 2 * dest_binT T
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   103
  | Type (@{type_name "Numeral_Type.bit1"}, [T]) => 1 + 2 * dest_binT T
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   104
  | _ => raise TYPE ("dest_binT", [T], []))
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   105
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   106
val dest_wordT = (fn
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   107
    Type (@{type_name "word"}, [T]) => dest_binT T
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   108
  | T => raise TYPE ("dest_wordT", [T], []))
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   109
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   110
val dest_funT =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   111
  let
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   112
    fun dest Ts 0 T = (rev Ts, T)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   113
      | dest Ts i (Type ("fun", [T, U])) = dest (T::Ts) (i-1) U
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   114
      | dest _ _ T = raise TYPE ("dest_funT", [T], [])
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   115
  in dest [] end
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   116
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   117
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   118
(* Table for built-in symbols *)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   119
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   120
type builtin_fun = typ -> (sym, typ) sterm list ->
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   121
  (string * (sym, typ) sterm list) option
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   122
type builtin_table = (typ * builtin_fun) list Symtab.table
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   123
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   124
fun builtin_make entries =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   125
  let
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   126
    fun dest (t, bn) =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   127
      let val (n, T) = Term.dest_Const t
35845
e5980f0ad025 renamed varify/unvarify operations to varify_global/unvarify_global to emphasize that these only work in a global situation;
wenzelm
parents: 35408
diff changeset
   128
      in (n, (Logic.varifyT_global T, K (SOME o pair bn))) end
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   129
  in Symtab.make (AList.group (op =) (map dest entries)) end
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   130
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   131
fun builtin_add (t, f) tab =
35845
e5980f0ad025 renamed varify/unvarify operations to varify_global/unvarify_global to emphasize that these only work in a global situation;
wenzelm
parents: 35408
diff changeset
   132
  let val (n, T) = apsnd Logic.varifyT_global (Term.dest_Const t)
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   133
  in Symtab.map_default (n, []) (AList.update (op =) (T, f)) tab end
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   134
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   135
fun builtin_lookup tab thy (n, T) ts =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   136
  AList.lookup (Sign.typ_instance thy) (Symtab.lookup_list tab n) T
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   137
  |> (fn SOME f => f T ts | NONE => NONE)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   138
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   139
local
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   140
  val dest_nat = (fn
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   141
      SApp (SConst (@{const_name nat}, _), [SApp (SNum (i, _), _)]) => SOME i
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   142
    | _ => NONE)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   143
in
33664
d62805a237ef removed unused code and unused arguments,
boehmes
parents: 33299
diff changeset
   144
fun bv_rotate mk_name _ ts =
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   145
  dest_nat (hd ts) |> Option.map (fn i => (mk_name i, tl ts))
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   146
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   147
fun bv_extend mk_name T ts =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   148
  (case (try dest_wordT (domain_type T), try dest_wordT (range_type T)) of
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   149
    (SOME i, SOME j) => if j - i >= 0 then SOME (mk_name (j - i), ts) else NONE
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   150
  | _ => NONE)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   151
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   152
fun bv_extract mk_name T ts =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   153
  (case (try dest_wordT (body_type T), dest_nat (hd ts)) of
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   154
    (SOME i, SOME lb) => SOME (mk_name (i + lb - 1) lb, tl ts)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   155
  | _ => NONE)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   156
end
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   157
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   158
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   159
(* Configuration options *)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   160
33017
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 32618
diff changeset
   161
type prefixes = {
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   162
  var_prefix: string,
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   163
  typ_prefix: string,
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   164
  fun_prefix: string,
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   165
  pred_prefix: string }
33017
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 32618
diff changeset
   166
type markers = {
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   167
  term_marker: string,
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   168
  formula_marker: string }
33017
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 32618
diff changeset
   169
type builtins = {
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   170
  builtin_typ: typ -> string option,
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   171
  builtin_num: int * typ -> string option,
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   172
  builtin_fun: bool -> builtin_table }
33017
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 32618
diff changeset
   173
type sign = {
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   174
  typs: string list,
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   175
  funs: (string * (string list * string)) list,
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   176
  preds: (string * string list) list }
33017
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 32618
diff changeset
   177
type config = {
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   178
  strict: bool,
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   179
  prefixes: prefixes,
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   180
  markers: markers,
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   181
  builtins: builtins,
36087
37a5735783c5 buffered output (faster than direct output)
boehmes
parents: 35980
diff changeset
   182
  serialize: sign -> (string, string) sterm list -> string}
33017
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 32618
diff changeset
   183
type recon = {typs: typ Symtab.table, terms: term Symtab.table}
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   184
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   185
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   186
(* Translate Isabelle/HOL terms into SMT intermediate terms.
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   187
   We assume that lambda-lifting has been performed before, i.e., lambda
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   188
   abstractions occur only at quantifiers and let expressions.
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   189
*)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   190
local
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   191
  val quantifier = (fn
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   192
      @{const_name All} => SOME SForall
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   193
    | @{const_name Ex} => SOME SExists
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   194
    | _ => NONE)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   195
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   196
  fun group_quant qname vs (t as Const (q, _) $ Abs (n, T, u)) =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   197
        if q = qname then group_quant qname ((n, T) :: vs) u else (vs, t)
33664
d62805a237ef removed unused code and unused arguments,
boehmes
parents: 33299
diff changeset
   198
    | group_quant _ vs t = (vs, t)
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   199
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   200
  fun dest_trigger (@{term trigger} $ tl $ t) = (HOLogic.dest_list tl, t)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   201
    | dest_trigger t = ([], t)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   202
33299
73af7831ba1e simplified method syntax of "smt",
boehmes
parents: 33017
diff changeset
   203
  fun pat f ts (Const (@{const_name pat}, _) $ t) = SPat (rev (f t :: ts))
73af7831ba1e simplified method syntax of "smt",
boehmes
parents: 33017
diff changeset
   204
    | pat f ts (Const (@{const_name nopat}, _) $ t) = SNoPat (rev (f t :: ts))
73af7831ba1e simplified method syntax of "smt",
boehmes
parents: 33017
diff changeset
   205
    | pat f ts (Const (@{const_name andpat}, _) $ p $ t) = pat f (f t :: ts) p
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   206
    | pat _ _ t = raise TERM ("pat", [t])
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   207
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   208
  fun trans Ts t =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   209
    (case Term.strip_comb t of
33664
d62805a237ef removed unused code and unused arguments,
boehmes
parents: 33299
diff changeset
   210
      (Const (qn, _), [Abs (n, T, t1)]) =>
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   211
        (case quantifier qn of
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   212
          SOME q =>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   213
            let
33664
d62805a237ef removed unused code and unused arguments,
boehmes
parents: 33299
diff changeset
   214
              val (vs, u) = group_quant qn [(n, T)] t1
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   215
              val Us = map snd vs @ Ts
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   216
              val (ps, b) = dest_trigger u
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   217
            in SQuant (q, rev vs, map (pat (trans Us) []) ps, trans Us b) end
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   218
        | NONE => raise TERM ("intermediate", [t]))
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   219
    | (Const (@{const_name Let}, _), [t1, Abs (n, T, t2)]) =>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   220
        SLet ((n, T), trans Ts t1, trans (T :: Ts) t2)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   221
    | (Const (c as (@{const_name distinct}, _)), [t1]) =>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   222
        (* this is not type-correct, but will be corrected at a later stage *)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   223
        SApp (SConst c, map (trans Ts) (HOLogic.dest_list t1))
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   224
    | (Const c, ts) =>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   225
        (case try HOLogic.dest_number t of
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   226
          SOME (T, i) => SApp (SNum (i, T), [])
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   227
        | NONE => SApp (SConst c, map (trans Ts) ts))
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   228
    | (Free c, ts) => SApp (SFree c, map (trans Ts) ts)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   229
    | (Bound i, []) => SVar i
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   230
    | _ => raise TERM ("intermediate", [t]))
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   231
in
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   232
fun intermediate ts = map (trans [] o HOLogic.dest_Trueprop) ts
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   233
end
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   234
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   235
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   236
(* Separate formulas from terms by adding special marker symbols ("term",
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   237
   "formula"). Atoms "P" whose head symbol also occurs as function symbol are
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   238
   rewritten to "term P = term True". Connectives and built-in predicates
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   239
   occurring at term level are replaced by new constants, and theorems
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   240
   specifying their meaning are added.
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   241
*)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   242
local
34010
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   243
  local
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   244
    fun cons_nr (SConst _) = 0
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   245
      | cons_nr (SFree _) = 1
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   246
      | cons_nr (SNum _) = 2
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   247
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   248
    fun struct_ord (t, u) = int_ord (cons_nr t, cons_nr u)
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   249
    
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   250
    fun atoms_ord (SConst (n, _), SConst (m, _)) = fast_string_ord (n, m)
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   251
      | atoms_ord (SFree (n, _), SFree (m, _)) = fast_string_ord (n, m)
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   252
      | atoms_ord (SNum (i, _), SNum (j, _)) = int_ord (i, j)
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   253
      | atoms_ord _ = sys_error "atoms_ord"
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   254
35408
b48ab741683b modernized structure Term_Ord;
wenzelm
parents: 34033
diff changeset
   255
    fun types_ord (SConst (_, T), SConst (_, U)) = Term_Ord.typ_ord (T, U)
b48ab741683b modernized structure Term_Ord;
wenzelm
parents: 34033
diff changeset
   256
      | types_ord (SFree (_, T), SFree (_, U)) = Term_Ord.typ_ord (T, U)
b48ab741683b modernized structure Term_Ord;
wenzelm
parents: 34033
diff changeset
   257
      | types_ord (SNum (_, T), SNum (_, U)) = Term_Ord.typ_ord (T, U)
34010
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   258
      | types_ord _ = sys_error "types_ord"
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   259
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   260
    fun fast_sym_ord tu =
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   261
      (case struct_ord tu of
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   262
        EQUAL => (case atoms_ord tu of EQUAL => types_ord tu | ord => ord)
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   263
      | ord => ord)
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   264
  in
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   265
  structure Stab = Table(type key = sym val ord = fast_sym_ord)
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   266
  end
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   267
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   268
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   269
  (** Add the marker symbols "term" and "formula" to separate formulas and
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   270
      terms. **)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   271
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   272
  val connectives = map make_sconst [@{term True}, @{term False},
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   273
    @{term Not}, @{term "op &"}, @{term "op |"}, @{term "op -->"},
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   274
    @{term "op = :: bool => _"}]
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   275
34010
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   276
  fun insert_sym c = Stab.map_default (c, ()) I
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   277
  fun note false c (ps, fs) = (insert_sym c ps, fs)
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   278
    | note true c (ps, fs) = (ps, insert_sym c fs)
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   279
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   280
  val term_marker = SConst (@{const_name term}, Term.dummyT)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   281
  val formula_marker = SConst (@{const_name formula}, Term.dummyT)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   282
  fun mark f true t = f true t #>> app term_marker o single
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   283
    | mark f false t = f false t #>> app formula_marker o single
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   284
  fun mark' f false t = f true t #>> app term_marker o single
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   285
    | mark' f true t = f true t
34033
687140d426e9 made SML/NJ happy
boehmes
parents: 34010
diff changeset
   286
  fun mark_term (t : (sym, typ) sterm) = app term_marker [t]
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   287
  fun lift_term_marker c ts =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   288
    let val rem = (fn SApp (SConst (@{const_name term}, _), [t]) => t | t => t)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   289
    in mark_term (SApp (c, map rem ts)) end
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   290
  fun is_term (SApp (SConst (@{const_name term}, _), _)) = true
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   291
    | is_term _ = false
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   292
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   293
  fun either x = (fn y as SOME _ => y | _ => x)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   294
  fun get_loc loc i t =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   295
    (case t of
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   296
      SVar j => if i = j then SOME loc else NONE
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   297
    | SApp (SConst (@{const_name term}, _), us) => get_locs true i us
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   298
    | SApp (SConst (@{const_name formula}, _), us) => get_locs false i us
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   299
    | SApp (_, us) => get_locs loc i us
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   300
    | SLet (_, u1, u2) => either (get_loc true i u1) (get_loc loc (i+1) u2)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   301
    | SQuant (_, vs, _, u) => get_loc loc (i + length vs) u)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   302
  and get_locs loc i ts = fold (either o get_loc loc i) ts NONE
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   303
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   304
  fun sep loc t =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   305
    (case t of
33664
d62805a237ef removed unused code and unused arguments,
boehmes
parents: 33299
diff changeset
   306
      SVar _ => pair t
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   307
    | SApp (c as SConst (@{const_name If}, _), u :: us) =>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   308
        mark sep false u ##>> fold_map (sep loc) us #>> app c o (op ::)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   309
    | SApp (c, us) =>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   310
        if not loc andalso member (op =) connectives c
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   311
        then fold_map (sep loc) us #>> app c
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   312
        else note loc c #> fold_map (mark' sep loc) us #>> app c
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   313
    | SLet (v, u1, u2) =>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   314
        sep loc u2 #-> (fn u2' =>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   315
        mark sep (the (get_loc loc 0 u2')) u1 #>> (fn u1' =>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   316
        SLet (v, u1', u2')))
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   317
    | SQuant (q, vs, ps, u) =>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   318
        fold_map (fold_map_pat (mark sep true)) ps ##>>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   319
        sep loc u #>> (fn (ps', u') =>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   320
        SQuant (q, vs, ps', u')))
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   321
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   322
  (** Rewrite atoms. **)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   323
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   324
  val unterm_rule = @{lemma "term x == x" by (simp add: term_def)}
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   325
  val unterm_conv = More_Conv.top_sweep_conv (K (Conv.rewr_conv unterm_rule))
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   326
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   327
  val dest_word_type = (fn Type (@{type_name word}, [T]) => T | T => T)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   328
  fun instantiate [] _ = I
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   329
    | instantiate (v :: _) T =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   330
        Term.subst_TVars [(v, dest_word_type (Term.domain_type T))]
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   331
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   332
  fun dest_alls (Const (@{const_name All}, _) $ Abs (_, _, t)) = dest_alls t
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   333
    | dest_alls t = t
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   334
  val dest_iff = (fn (Const (@{const_name iff}, _) $ t $ _ ) => t | t => t)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   335
  val dest_eq = (fn (Const (@{const_name "op ="}, _) $ t $ _ ) => t | t => t)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   336
  val dest_not = (fn (@{term Not} $ t) => t | t => t)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   337
  val head_of = HOLogic.dest_Trueprop #> dest_alls #> dest_iff #> dest_not #>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   338
    dest_eq #> Term.head_of
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   339
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   340
  fun prepare ctxt thm =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   341
    let
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   342
      val rule = Conv.fconv_rule (unterm_conv ctxt) thm
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   343
      val prop = Thm.prop_of thm
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   344
      val inst = instantiate (Term.add_tvar_names prop [])
34010
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   345
      fun inst_for T = (rule, singleton intermediate (inst T prop))
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   346
    in (make_sconst (head_of (Thm.prop_of rule)), inst_for) end
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   347
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   348
  val logicals = map (prepare @{context})
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   349
    @{lemma 
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   350
      "~ holds False"
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   351
      "ALL p. holds (~ p) iff (~ holds p)"
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   352
      "ALL p q. holds (p & q) iff (holds p & holds q)"
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   353
      "ALL p q. holds (p | q) iff (holds p | holds q)"
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   354
      "ALL p q. holds (p --> q) iff (holds p --> holds q)"
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   355
      "ALL p q. holds (p iff q) iff (holds p iff holds q)"
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   356
      "ALL p q. holds (p = q) iff (p = q)"
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   357
      "ALL (a::int) b. holds (a < b) iff (a < b)"
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   358
      "ALL (a::int) b. holds (a <= b) iff (a <= b)"
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   359
      "ALL (a::real) b. holds (a < b) iff (a < b)"
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   360
      "ALL (a::real) b. holds (a <= b) iff (a <= b)"
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   361
      "ALL (a::'a::len0 word) b. holds (a < b) iff (a < b)"
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   362
      "ALL (a::'a::len0 word) b. holds (a <= b) iff (a <= b)"
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   363
      "ALL a b. holds (a <s b) iff (a <s b)"
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   364
      "ALL a b. holds (a <=s b) iff (a <=s b)"
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   365
      by (simp_all add: term_def iff_def)}
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   366
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   367
  fun is_instance thy (SConst (n, T), SConst (m, U)) =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   368
        (n = m) andalso Sign.typ_instance thy (T, U)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   369
    | is_instance _ _ = false
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   370
34010
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   371
  fun rule_for thy c T =
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   372
    AList.lookup (is_instance thy) logicals c
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   373
    |> Option.map (fn inst_for => inst_for T)
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   374
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   375
  fun lookup_logical thy (c as SConst (_, T)) (thms, ts) =
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   376
        (case rule_for thy c T of
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   377
          SOME (thm, t) => (thm :: thms, t :: ts)
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   378
        | NONE => (thms, ts))
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   379
    | lookup_logical _ _ tss = tss
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   380
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   381
  val s_eq = make_sconst @{term "op = :: bool => _"}
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   382
  val s_True = mark_term (SApp (make_sconst @{term True}, []))
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   383
  fun holds (SApp (c, ts)) = SApp (s_eq, [lift_term_marker c ts, s_True])
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   384
    | holds t = SApp (s_eq, [mark_term t, s_True])
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   385
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   386
  val rewr_iff = (fn
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   387
      SConst (@{const_name "op ="}, T as @{typ "bool => bool => bool"}) =>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   388
        SConst (@{const_name iff}, T)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   389
    | c => c)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   390
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   391
  fun rewrite ls =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   392
    let
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   393
      fun rewr env loc t =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   394
        (case t of
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   395
          SVar i => if not loc andalso nth env i then holds t else t
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   396
        | SApp (c as SConst (@{const_name term}, _), [u]) =>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   397
            SApp (c, [rewr env true u])
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   398
        | SApp (c as SConst (@{const_name formula}, _), [u]) =>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   399
            SApp (c, [rewr env false u])
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   400
        | SApp (c, us) =>
34010
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   401
            let val f = if not loc andalso Stab.defined ls c then holds else I
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   402
            in f (SApp (rewr_iff c, map (rewr env loc) us)) end
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   403
        | SLet (v, u1, u2) =>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   404
            SLet (v, rewr env loc u1, rewr (is_term u1 :: env) loc u2)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   405
        | SQuant (q, vs, ps, u) =>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   406
            let val e = replicate (length vs) true @ env
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   407
            in SQuant (q, vs, map (map_pat (rewr e loc)) ps, rewr e loc u) end)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   408
    in map (rewr [] false) end
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   409
in
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   410
fun separate thy ts =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   411
  let
34010
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   412
    val (ts', (ps, fs)) = fold_map (sep false) ts (Stab.empty, Stab.empty)
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   413
    fun insert (px as (p, _)) = if Stab.defined fs p then Stab.update px else I
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   414
  in
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   415
    Stab.fold (lookup_logical thy o fst) fs ([], [])
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   416
    ||> append (rewrite (Stab.fold insert ps Stab.empty) ts')
ac78f5cdc430 faster preprocessing: before applying a step, test if it is applicable (normalization of binders, unfolding of abs/min/max definitions, lambda lifting, explicit application, monomorphization),
boehmes
parents: 33664
diff changeset
   417
  end
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   418
end
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   419
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   420
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   421
(* Collect the signature of intermediate terms, identify built-in symbols,
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   422
   rename uninterpreted symbols and types, make bound variables unique.
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   423
   We require @{term distinct} to be a built-in constant of the SMT solver.
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   424
*)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   425
local
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   426
  fun empty_nctxt p = (p, 1)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   427
  fun make_nctxt (pT, pf, pp) = (empty_nctxt pT, empty_nctxt (pf, pp))
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   428
  fun fresh_name (p, i) = (p ^ string_of_int i, (p, i+1))
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   429
  fun fresh_typ (nT, nfp) = fresh_name nT ||> (fn nT' => (nT', nfp))
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   430
  fun fresh_fun loc (nT, ((pf, pp), i)) =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   431
    let val p = if loc then pf else pp
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   432
    in fresh_name (p, i) ||> (fn (_, i') => (nT, ((pf, pp), i'))) end
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   433
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   434
  val empty_sign = (Typtab.empty, Termtab.empty, Termtab.empty)
35980
344afccb09d1 made renamings stable under name changes in the original problem (uninterpreted names are irrelevant to the SMT solver, and caching of SMT certificates relies on irrelevancy of renamings)
boehmes
parents: 35845
diff changeset
   435
  fun lookup_typ (typs, _, _) = Option.map snd o Typtab.lookup typs
344afccb09d1 made renamings stable under name changes in the original problem (uninterpreted names are irrelevant to the SMT solver, and caching of SMT certificates relies on irrelevancy of renamings)
boehmes
parents: 35845
diff changeset
   436
  fun lookup_fun true (_, funs, _) = Option.map snd o Termtab.lookup funs
344afccb09d1 made renamings stable under name changes in the original problem (uninterpreted names are irrelevant to the SMT solver, and caching of SMT certificates relies on irrelevancy of renamings)
boehmes
parents: 35845
diff changeset
   437
    | lookup_fun false (_, _, preds) = Option.map snd o Termtab.lookup preds
344afccb09d1 made renamings stable under name changes in the original problem (uninterpreted names are irrelevant to the SMT solver, and caching of SMT certificates relies on irrelevancy of renamings)
boehmes
parents: 35845
diff changeset
   438
  fun ext (k, v) = (k, (serial (), v))
344afccb09d1 made renamings stable under name changes in the original problem (uninterpreted names are irrelevant to the SMT solver, and caching of SMT certificates relies on irrelevancy of renamings)
boehmes
parents: 35845
diff changeset
   439
  fun p_ord p = prod_ord int_ord (K EQUAL) p
344afccb09d1 made renamings stable under name changes in the original problem (uninterpreted names are irrelevant to the SMT solver, and caching of SMT certificates relies on irrelevancy of renamings)
boehmes
parents: 35845
diff changeset
   440
  fun add_typ x (typs, funs, preds) =
344afccb09d1 made renamings stable under name changes in the original problem (uninterpreted names are irrelevant to the SMT solver, and caching of SMT certificates relies on irrelevancy of renamings)
boehmes
parents: 35845
diff changeset
   441
    (Typtab.update (ext x) typs, funs, preds)
344afccb09d1 made renamings stable under name changes in the original problem (uninterpreted names are irrelevant to the SMT solver, and caching of SMT certificates relies on irrelevancy of renamings)
boehmes
parents: 35845
diff changeset
   442
  fun add_fun true x (typs, funs, preds) =
344afccb09d1 made renamings stable under name changes in the original problem (uninterpreted names are irrelevant to the SMT solver, and caching of SMT certificates relies on irrelevancy of renamings)
boehmes
parents: 35845
diff changeset
   443
        (typs, Termtab.update (ext x) funs, preds)
344afccb09d1 made renamings stable under name changes in the original problem (uninterpreted names are irrelevant to the SMT solver, and caching of SMT certificates relies on irrelevancy of renamings)
boehmes
parents: 35845
diff changeset
   444
    | add_fun false x (typs, funs, preds) =
344afccb09d1 made renamings stable under name changes in the original problem (uninterpreted names are irrelevant to the SMT solver, and caching of SMT certificates relies on irrelevancy of renamings)
boehmes
parents: 35845
diff changeset
   445
        (typs, funs, Termtab.update (ext x) preds)
33017
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 32618
diff changeset
   446
  fun make_sign (typs, funs, preds) = {
35980
344afccb09d1 made renamings stable under name changes in the original problem (uninterpreted names are irrelevant to the SMT solver, and caching of SMT certificates relies on irrelevancy of renamings)
boehmes
parents: 35845
diff changeset
   447
    typs = map snd (sort p_ord (map snd (Typtab.dest typs))),
344afccb09d1 made renamings stable under name changes in the original problem (uninterpreted names are irrelevant to the SMT solver, and caching of SMT certificates relies on irrelevancy of renamings)
boehmes
parents: 35845
diff changeset
   448
    funs = map snd (sort p_ord (map snd (Termtab.dest funs))),
344afccb09d1 made renamings stable under name changes in the original problem (uninterpreted names are irrelevant to the SMT solver, and caching of SMT certificates relies on irrelevancy of renamings)
boehmes
parents: 35845
diff changeset
   449
    preds = map (apsnd fst o snd) (sort p_ord (map snd (Termtab.dest preds))) }
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   450
  fun make_rtab (typs, funs, preds) =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   451
    let
35980
344afccb09d1 made renamings stable under name changes in the original problem (uninterpreted names are irrelevant to the SMT solver, and caching of SMT certificates relies on irrelevancy of renamings)
boehmes
parents: 35845
diff changeset
   452
      val rTs = Typtab.dest typs |> map (swap o apsnd snd) |> Symtab.make
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   453
      val rts = Termtab.dest funs @ Termtab.dest preds
35980
344afccb09d1 made renamings stable under name changes in the original problem (uninterpreted names are irrelevant to the SMT solver, and caching of SMT certificates relies on irrelevancy of renamings)
boehmes
parents: 35845
diff changeset
   454
        |> map (apfst fst o swap o apsnd snd) |> Symtab.make
33017
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 32618
diff changeset
   455
    in {typs=rTs, terms=rts} end
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   456
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   457
  fun either f g x = (case f x of NONE => g x | y => y)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   458
33017
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 32618
diff changeset
   459
  fun rep_typ ({builtin_typ, ...} : builtins) T (st as (vars, ns, sgn)) =
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   460
    (case either builtin_typ (lookup_typ sgn) T of
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   461
      SOME n => (n, st)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   462
    | NONE =>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   463
        let val (n, ns') = fresh_typ ns
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   464
        in (n, (vars, ns', add_typ (T, n) sgn)) end)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   465
33664
d62805a237ef removed unused code and unused arguments,
boehmes
parents: 33299
diff changeset
   466
  fun rep_var bs (_, T) (vars, ns, sgn) =
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   467
    let val (n', vars') = fresh_name vars
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   468
    in (vars', ns, sgn) |> rep_typ bs T |>> pair n' end
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   469
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   470
  fun rep_fun bs loc t T i (st as (_, _, sgn0)) =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   471
    (case lookup_fun loc sgn0 t of
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   472
      SOME (n, _) => (n, st)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   473
    | NONE =>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   474
        let
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   475
          val (Us, U) = dest_funT i T
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   476
          val (uns, (vars, ns, sgn)) =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   477
            st |> fold_map (rep_typ bs) Us ||>> rep_typ bs U
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   478
          val (n, ns') = fresh_fun loc ns
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   479
        in (n, (vars, ns', add_fun loc (t, (n, uns)) sgn)) end)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   480
33017
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 32618
diff changeset
   481
  fun rep_num (bs as {builtin_num, ...} : builtins) (i, T) st =
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   482
    (case builtin_num (i, T) of
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   483
      SOME n => (n, st)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   484
    | NONE => rep_fun bs true (HOLogic.mk_number T i) T 0 st)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   485
in
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   486
fun signature_of prefixes markers builtins thy ts =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   487
  let
33017
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 32618
diff changeset
   488
    val {var_prefix, typ_prefix, fun_prefix, pred_prefix} = prefixes
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 32618
diff changeset
   489
    val {formula_marker, term_marker} = markers
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 32618
diff changeset
   490
    val {builtin_fun, ...} = builtins
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   491
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   492
    fun sign loc t =
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   493
      (case t of
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   494
        SVar i => pair (SVar i)
33664
d62805a237ef removed unused code and unused arguments,
boehmes
parents: 33299
diff changeset
   495
      | SApp (SConst (@{const_name term}, _), [u]) =>
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   496
          sign true u #>> app term_marker o single
33664
d62805a237ef removed unused code and unused arguments,
boehmes
parents: 33299
diff changeset
   497
      | SApp (SConst (@{const_name formula}, _), [u]) =>
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   498
          sign false u #>> app formula_marker o single
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   499
      | SApp (SConst (c as (_, T)), ts) =>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   500
          (case builtin_lookup (builtin_fun loc) thy c ts of
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   501
            SOME (n, ts') => fold_map (sign loc) ts' #>> app n
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   502
          | NONE =>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   503
              rep_fun builtins loc (Const c) T (length ts) ##>>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   504
              fold_map (sign loc) ts #>> SApp)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   505
      | SApp (SFree (c as (_, T)), ts) =>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   506
          rep_fun builtins loc (Free c) T (length ts) ##>>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   507
          fold_map (sign loc) ts #>> SApp
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   508
      | SApp (SNum n, _) => rep_num builtins n #>> (fn n => SApp (n, []))
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   509
      | SLet (v, u1, u2) =>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   510
          rep_var builtins v #-> (fn v' =>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   511
          sign loc u1 ##>> sign loc u2 #>> (fn (u1', u2') =>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   512
          SLet (v', u1', u2')))
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   513
      | SQuant (q, vs, ps, u) =>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   514
          fold_map (rep_var builtins) vs ##>>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   515
          fold_map (fold_map_pat (sign loc)) ps ##>>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   516
          sign loc u #>> (fn ((vs', ps'), u') =>
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   517
          SQuant (q, vs', ps', u')))
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   518
  in
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   519
    (empty_nctxt var_prefix, make_nctxt (typ_prefix, fun_prefix, pred_prefix),
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   520
      empty_sign)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   521
    |> fold_map (sign false) ts
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   522
    |> (fn (us, (_, _, sgn)) => (make_rtab sgn, (make_sign sgn, us)))
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   523
  end
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   524
end
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   525
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   526
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   527
(* Combination of all translation functions and invocation of serialization. *)
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   528
36087
37a5735783c5 buffered output (faster than direct output)
boehmes
parents: 35980
diff changeset
   529
fun translate config thy thms =
33017
4fb8a33f74d6 eliminated extraneous wrapping of public records,
boehmes
parents: 32618
diff changeset
   530
  let val {strict, prefixes, markers, builtins, serialize} = config
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   531
  in
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   532
    map Thm.prop_of thms
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   533
    |> SMT_Monomorph.monomorph thy
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   534
    |> intermediate
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   535
    |> (if strict then separate thy else pair [])
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   536
    ||>> signature_of prefixes markers builtins thy
36087
37a5735783c5 buffered output (faster than direct output)
boehmes
parents: 35980
diff changeset
   537
    ||> (fn (sgn, ts) => serialize sgn ts)
37a5735783c5 buffered output (faster than direct output)
boehmes
parents: 35980
diff changeset
   538
    |> (fn ((thms', rtab), str) => (str, (rtab, thms' @ thms)))
32618
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   539
  end
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   540
42865636d006 added new method "smt": an oracle-based connection to external SMT solvers
boehmes
parents:
diff changeset
   541
end