src/HOL/Word/Tools/smt_word.ML
author boehmes
Tue, 07 Dec 2010 14:53:44 +0100
changeset 41060 4199fdcfa3c0
child 41061 492f8fd35fc0
permissions -rw-r--r--
moved smt_word.ML into the directory of the Word library
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
41060
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
     1
(*  Title:      HOL/Tools/SMT/smt_word.ML
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
     2
    Author:     Sascha Boehme, TU Muenchen
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
     3
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
     4
SMT setup for words.
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
     5
*)
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
     6
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
     7
signature SMT_WORD =
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
     8
sig
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
     9
  val setup: theory -> theory
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    10
end
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    11
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    12
structure SMT_Word: SMT_WORD =
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    13
struct
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    14
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    15
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    16
(* utilities *)
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    17
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    18
fun dest_binT T =
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    19
  (case T of
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    20
    Type (@{type_name "Numeral_Type.num0"}, _) => 0
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    21
  | Type (@{type_name "Numeral_Type.num1"}, _) => 1
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    22
  | Type (@{type_name "Numeral_Type.bit0"}, [T]) => 2 * dest_binT T
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    23
  | Type (@{type_name "Numeral_Type.bit1"}, [T]) => 1 + 2 * dest_binT T
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    24
  | _ => raise TYPE ("dest_binT", [T], []))
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    25
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    26
fun is_wordT (Type (@{type_name word}, _)) = true
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    27
  | is_wordT _ = false
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    28
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    29
fun dest_wordT (Type (@{type_name word}, [T])) = dest_binT T
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    30
  | dest_wordT T = raise TYPE ("dest_wordT", [T], [])
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    31
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    32
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    33
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    34
(* SMT-LIB logic *)
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    35
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    36
fun smtlib_logic ts =
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    37
  if exists (Term.exists_type (Term.exists_subtype is_wordT)) ts
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    38
  then SOME "QF_AUFBV"
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    39
  else NONE
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    40
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    41
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    42
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    43
(* SMT-LIB builtins *)
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    44
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    45
local
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    46
  fun index1 n i = n ^ "[" ^ string_of_int i ^ "]"
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    47
  fun index2 n i j = n ^ "[" ^ string_of_int i ^ ":" ^ string_of_int j ^ "]"
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    48
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    49
  fun smtlib_builtin_typ (Type (@{type_name word}, [T])) =
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    50
        Option.map (index1 "BitVec") (try dest_binT T)
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    51
    | smtlib_builtin_typ _ = NONE
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    52
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    53
  fun smtlib_builtin_num (Type (@{type_name word}, [T])) i =
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    54
        Option.map (index1 ("bv" ^ string_of_int i)) (try dest_binT T)
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    55
    | smtlib_builtin_num _ _ = NONE
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    56
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    57
  fun if_fixed n T ts =
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    58
    let val (Ts, T) = Term.strip_type T
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    59
    in if forall (can dest_wordT) (T :: Ts) then SOME (n, ts) else NONE end
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    60
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    61
  fun dest_word_funT (Type ("fun", [T, U])) = (dest_wordT T, dest_wordT U)
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    62
    | dest_word_funT T = raise TYPE ("dest_word_funT", [T], [])
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    63
  fun dest_nat (@{const nat} $ n :: ts) = (snd (HOLogic.dest_number n), ts)
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    64
    | dest_nat ts = raise TERM ("dest_nat", ts)
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    65
  fun dest_nat_word_funT (T, ts) =
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    66
    (dest_word_funT (Term.range_type T), dest_nat ts)
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    67
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    68
  fun shift n T ts =
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    69
    let val U = Term.domain_type T
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    70
    in
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    71
      (case (can dest_wordT U, ts) of
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    72
        (true, [t, u]) =>
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    73
          (case try HOLogic.dest_number u of
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    74
            SOME (_,i) => SOME (n, [t, HOLogic.mk_number U i])
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    75
          | NONE => NONE)  (* FIXME: also support non-numerical shifts *)
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    76
      | _ => NONE)
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    77
    end
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    78
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    79
  fun extend n T ts =
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    80
    (case try dest_word_funT T of
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    81
      SOME (i, j) => if j-i >= 0 then SOME (index1 n (j-i), ts) else NONE
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    82
    | _ => NONE)
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    83
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    84
  fun rotate n T ts =
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    85
    try dest_nat ts
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    86
    |> Option.map (fn (i, ts') => (index1 n i, ts'))
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    87
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    88
  fun extract n T ts =
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    89
    try dest_nat_word_funT (T, ts)
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    90
    |> Option.map (fn ((_, i), (lb, ts')) => (index2 n (i + lb - 1) lb, ts'))
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    91
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    92
  fun smtlib_builtin_func @{const_name uminus} = if_fixed "bvneg"
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    93
    | smtlib_builtin_func @{const_name plus} = if_fixed "bvadd"
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    94
    | smtlib_builtin_func @{const_name minus} = if_fixed "bvsub"
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    95
    | smtlib_builtin_func @{const_name times} = if_fixed "bvmul"
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    96
    | smtlib_builtin_func @{const_name bitNOT} = if_fixed "bvnot"
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    97
    | smtlib_builtin_func @{const_name bitAND} = if_fixed "bvand"
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    98
    | smtlib_builtin_func @{const_name bitOR} = if_fixed "bvor"
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
    99
    | smtlib_builtin_func @{const_name bitXOR} = if_fixed "bvxor"
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   100
    | smtlib_builtin_func @{const_name word_cat} = if_fixed "concat"
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   101
    | smtlib_builtin_func @{const_name shiftl} = shift "bvshl"
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   102
    | smtlib_builtin_func @{const_name shiftr} = shift "bvlshr"
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   103
    | smtlib_builtin_func @{const_name sshiftr} = shift "bvashr"
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   104
    | smtlib_builtin_func @{const_name slice} = extract "extract"
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   105
    | smtlib_builtin_func @{const_name ucast} = extend "zero_extend"
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   106
    | smtlib_builtin_func @{const_name scast} = extend "sign_extend"
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   107
    | smtlib_builtin_func @{const_name word_rotl} = rotate "rotate_left"
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   108
    | smtlib_builtin_func @{const_name word_rotr} = rotate "rotate_right"
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   109
    | smtlib_builtin_func _ = (fn _ => K NONE)
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   110
        (* FIXME: support more builtin bitvector functions:
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   111
             bvudiv/bvurem and bvsdiv/bvsmod/bvsrem *)
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   112
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   113
  fun smtlib_builtin_pred @{const_name less} = SOME "bvult"
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   114
    | smtlib_builtin_pred @{const_name less_eq} = SOME "bvule"
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   115
    | smtlib_builtin_pred @{const_name word_sless} = SOME "bvslt"
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   116
    | smtlib_builtin_pred @{const_name word_sle} = SOME "bvsle"
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   117
    | smtlib_builtin_pred _ = NONE
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   118
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   119
  fun smtlib_builtin_pred' (n, T) =
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   120
    if can (dest_wordT o Term.domain_type) T then smtlib_builtin_pred n
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   121
    else NONE
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   122
in
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   123
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   124
val smtlib_builtins : SMTLIB_Interface.builtins = {
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   125
  builtin_typ = smtlib_builtin_typ,
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   126
  builtin_num = smtlib_builtin_num,
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   127
  builtin_func = (fn (n, T) => fn ts => smtlib_builtin_func n T ts),
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   128
  builtin_pred = (fn c => fn ts =>
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   129
    smtlib_builtin_pred' c |> Option.map (rpair ts)),
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   130
  is_builtin_pred = curry (is_some o smtlib_builtin_pred') }
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   131
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   132
end
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   133
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   134
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   135
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   136
(* setup *)
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   137
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   138
val setup = 
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   139
  Context.theory_map (
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   140
    SMTLIB_Interface.add_logic smtlib_logic #>
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   141
    SMTLIB_Interface.add_builtins smtlib_builtins)
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   142
4199fdcfa3c0 moved smt_word.ML into the directory of the Word library
boehmes
parents:
diff changeset
   143
end