src/HOL/Tools/SMT/smt_normalize.ML
changeset 39483 9f0e5684f04b
parent 38864 4abe644fcea5
child 40161 539d07b00e5f
equal deleted inserted replaced
39482:1c37d19e3d58 39483:9f0e5684f04b
     7   * normalize numerals (e.g. replace negative numerals by negated positive
     7   * normalize numerals (e.g. replace negative numerals by negated positive
     8     numerals),
     8     numerals),
     9   * embed natural numbers into integers,
     9   * embed natural numbers into integers,
    10   * add extra rules specifying types and constants which occur frequently,
    10   * add extra rules specifying types and constants which occur frequently,
    11   * fully translate into object logic, add universal closure,
    11   * fully translate into object logic, add universal closure,
       
    12   * monomorphize (create instances of schematic rules),
    12   * lift lambda terms,
    13   * lift lambda terms,
    13   * make applications explicit for functions with varying number of arguments.
    14   * make applications explicit for functions with varying number of arguments.
       
    15   * add (hypothetical definitions for) missing datatype selectors,
    14 *)
    16 *)
    15 
    17 
    16 signature SMT_NORMALIZE =
    18 signature SMT_NORMALIZE =
    17 sig
    19 sig
    18   type extra_norm = thm list -> Proof.context -> thm list * Proof.context
    20   type extra_norm = thm list -> Proof.context -> thm list * Proof.context
    19   val normalize: extra_norm -> thm list -> Proof.context ->
    21   val normalize: extra_norm -> bool -> thm list -> Proof.context ->
    20     thm list * Proof.context
    22     thm list * Proof.context
    21   val atomize_conv: Proof.context -> conv
    23   val atomize_conv: Proof.context -> conv
    22   val eta_expand_conv: (Proof.context -> conv) -> Proof.context -> conv
    24   val eta_expand_conv: (Proof.context -> conv) -> Proof.context -> conv
    23 end
    25 end
    24 
    26 
   425   in map (rewrite tab ctxt) thms end
   427   in map (rewrite tab ctxt) thms end
   426 end
   428 end
   427 
   429 
   428 
   430 
   429 
   431 
       
   432 (* add missing datatype selectors via hypothetical definitions *)
       
   433 
       
   434 local
       
   435   val add = (fn Type (n, _) => Symtab.update (n, ()) | _ => I)
       
   436 
       
   437   fun collect t =
       
   438     (case Term.strip_comb t of
       
   439       (Abs (_, T, t), _) => add T #> collect t
       
   440     | (Const (_, T), ts) => collects T ts
       
   441     | (Free (_, T), ts) => collects T ts
       
   442     | _ => I)
       
   443   and collects T ts =
       
   444     let val ((Ts, Us), U) = Term.strip_type T |> apfst (chop (length ts))
       
   445     in fold add Ts #> add (Us ---> U) #> fold collect ts end
       
   446 
       
   447   fun add_constructors thy n =
       
   448     (case Datatype.get_info thy n of
       
   449       NONE => I
       
   450     | SOME {descr, ...} => fold (fn (_, (_, _, cs)) => fold (fn (n, ds) =>
       
   451         fold (insert (op =) o pair n) (1 upto length ds)) cs) descr)
       
   452 
       
   453   fun add_selector (c as (n, i)) ctxt =
       
   454     (case Datatype_Selectors.lookup_selector ctxt c of
       
   455       SOME _ => ctxt
       
   456     | NONE =>
       
   457         let
       
   458           val T = Sign.the_const_type (ProofContext.theory_of ctxt) n
       
   459           val U = Term.body_type T --> nth (Term.binder_types T) (i-1)
       
   460         in
       
   461           ctxt
       
   462           |> yield_singleton Variable.variant_fixes Name.uu
       
   463           |>> pair ((n, T), i) o rpair U
       
   464           |-> Context.proof_map o Datatype_Selectors.add_selector
       
   465         end)
       
   466 in
       
   467 
       
   468 fun datatype_selectors thms ctxt =
       
   469   let
       
   470     val ns = Symtab.keys (fold (collect o Thm.prop_of) thms Symtab.empty)
       
   471     val cs = fold (add_constructors (ProofContext.theory_of ctxt)) ns []
       
   472   in (thms, fold add_selector cs ctxt) end
       
   473     (* FIXME: also generate hypothetical definitions for the selectors *)
       
   474 
       
   475 end
       
   476 
       
   477 
       
   478 
   430 (* combined normalization *)
   479 (* combined normalization *)
   431 
   480 
   432 type extra_norm = thm list -> Proof.context -> thm list * Proof.context
   481 type extra_norm = thm list -> Proof.context -> thm list * Proof.context
   433 
   482 
   434 fun with_context f thms ctxt = (f ctxt thms, ctxt)
   483 fun with_context f thms ctxt = (f ctxt thms, ctxt)
   435 
   484 
   436 fun normalize extra_norm thms ctxt =
   485 fun normalize extra_norm with_datatypes thms ctxt =
   437   thms
   486   thms
   438   |> trivial_distinct ctxt
   487   |> trivial_distinct ctxt
   439   |> rewrite_bool_cases ctxt
   488   |> rewrite_bool_cases ctxt
   440   |> normalize_numerals ctxt
   489   |> normalize_numerals ctxt
   441   |> nat_as_int ctxt
   490   |> nat_as_int ctxt
   443   |-> extra_norm
   492   |-> extra_norm
   444   |-> with_context (fn cx => map (normalize_rule cx))
   493   |-> with_context (fn cx => map (normalize_rule cx))
   445   |-> SMT_Monomorph.monomorph
   494   |-> SMT_Monomorph.monomorph
   446   |-> lift_lambdas
   495   |-> lift_lambdas
   447   |-> with_context explicit_application
   496   |-> with_context explicit_application
   448 
   497   |-> (if with_datatypes then datatype_selectors else pair)
   449 end
   498 
       
   499 end