src/HOL/SMT/Tools/smt_builtin.ML
author boehmes
Fri, 18 Sep 2009 18:13:19 +0200
changeset 32618 42865636d006
permissions -rw-r--r--
added new method "smt": an oracle-based connection to external SMT solvers
     1 (*  Title:      HOL/SMT/Tools/smt_builtin.ML
     2     Author:     Sascha Boehme, TU Muenchen
     3 
     4 Tables for built-in symbols.
     5 *)
     6 
     7 signature SMT_BUILTIN =
     8 sig
     9   type sterm = (SMT_Translate.sym, typ) sterm
    10   type builtin_fun = typ -> sterm list -> (string * sterm list) option
    11   type table = (typ * builtin_fun) list Symtab.table
    12 
    13   val make: (term * string) list -> table
    14   val add: term * builtin_fun -> table -> table
    15   val lookup: table -> theory -> string * typ -> sterm list ->
    16     (string * sterm list) option
    17 
    18   val bv_rotate: (int -> string) -> builtin_fun
    19   val bv_extend: (int -> string) -> builtin_fun
    20   val bv_extract: (int -> int -> string) -> builtin_fun
    21 end
    22 
    23 structure SMT_Builtin: SMT_BUILTIN =
    24 struct
    25 
    26 structure T = SMT_Translate
    27 
    28 type sterm = (SMT_Translate.sym, typ) sterm
    29 type builtin_fun = typ -> sterm list -> (string * sterm list) option
    30 type table = (typ * builtin_fun) list Symtab.table
    31 
    32 fun make entries =
    33   let
    34     fun dest (t, bn) =
    35       let val (n, T) = Term.dest_Const t
    36       in (n, (Logic.varifyT T, K (pair bn))) end
    37   in Symtab.make (AList.group (op =) (map dest entries)) end
    38 
    39 fun add (t, f) tab =
    40   let val (n, T) = apsnd Logic.varifyT (Term.dest_Const t)
    41   in Symtab.map_default (n, []) (AList.update (op =) (T, f)) tab end
    42 
    43 fun lookup tab thy (n, T) =
    44   AList.lookup (Sign.typ_instance thy) (Symtab.lookup_list tab n) T T
    45 
    46 
    47 fun dest_binT T =
    48   (case T of
    49     Type (@{type_name "Numeral_Type.num0"}, _) => 0
    50   | Type (@{type_name "Numeral_Type.num1"}, _) => 1
    51   | Type (@{type_name "Numeral_Type.bit0"}, [T]) => 2 * dest_binT T
    52   | Type (@{type_name "Numeral_Type.bit1"}, [T]) => 1 + 2 * dest_binT T
    53   | _ => raise TYPE ("dest_binT", [T], []))
    54 
    55 fun dest_wordT T =
    56   (case T of
    57     Type (@{type_name "word"}, [T]) => dest_binT T
    58   | _ => raise TYPE ("dest_wordT", [T], []))
    59 
    60 
    61 val dest_nat = (fn
    62     SApp (SConst (@{const_name nat}, _), [SApp (SNum (i, _), _)]) => SOME i
    63   | _ => NONE)
    64 
    65 fun bv_rotate mk_name T ts =
    66   dest_nat (hd ts) |> Option.map (fn i => (mk_name i, tl ts))
    67 
    68 fun bv_extend mk_name T ts =
    69   (case (try dest_wordT (domain_type T), try dest_wordT (range_type T)) of
    70     (SOME i, SOME j) => if j - i >= 0 then SOME (mk_name (j - i), ts) else NONE
    71   | _ => NONE)
    72 
    73 fun bv_extract mk_name T ts =
    74   (case (try dest_wordT (body_type T), dest_nat (hd ts)) of
    75     (SOME i, SOME lb) => SOME (mk_name (i + lb - 1) lb, tl ts)
    76   | _ => NONE)
    77 
    78 end