src/HOL/Tools/Sledgehammer/sledgehammer_util.ML
changeset 42730 d6db5a815477
parent 42697 9bc5dc48f1a5
child 42885 91adf04946d1
equal deleted inserted replaced
42729:e011f632227c 42730:d6db5a815477
    19     Datatype_Aux.descr -> (Datatype_Aux.dtyp * typ) list -> Datatype_Aux.dtyp
    19     Datatype_Aux.descr -> (Datatype_Aux.dtyp * typ) list -> Datatype_Aux.dtyp
    20     -> typ
    20     -> typ
    21   val varify_type : Proof.context -> typ -> typ
    21   val varify_type : Proof.context -> typ -> typ
    22   val instantiate_type : theory -> typ -> typ -> typ -> typ
    22   val instantiate_type : theory -> typ -> typ -> typ -> typ
    23   val varify_and_instantiate_type : Proof.context -> typ -> typ -> typ -> typ
    23   val varify_and_instantiate_type : Proof.context -> typ -> typ -> typ -> typ
       
    24   val is_type_surely_finite : Proof.context -> typ -> bool
       
    25   val is_type_surely_infinite : Proof.context -> typ -> bool
    24   val monomorphic_term : Type.tyenv -> term -> term
    26   val monomorphic_term : Type.tyenv -> term -> term
    25   val eta_expand : typ list -> term -> int -> term
    27   val eta_expand : typ list -> term -> int -> term
    26   val transform_elim_term : term -> term
    28   val transform_elim_term : term -> term
    27   val specialize_type : theory -> (string * typ) -> term -> term
    29   val specialize_type : theory -> (string * typ) -> term -> term
    28   val subgoal_count : Proof.state -> int
    30   val subgoal_count : Proof.state -> int
   107 
   109 
   108 fun varify_and_instantiate_type ctxt T1 T1' T2 =
   110 fun varify_and_instantiate_type ctxt T1 T1' T2 =
   109   let val thy = Proof_Context.theory_of ctxt in
   111   let val thy = Proof_Context.theory_of ctxt in
   110     instantiate_type thy (varify_type ctxt T1) T1' (varify_type ctxt T2)
   112     instantiate_type thy (varify_type ctxt T1) T1' (varify_type ctxt T2)
   111   end
   113   end
       
   114 
       
   115 fun datatype_constrs thy (T as Type (s, Ts)) =
       
   116     (case Datatype.get_info thy s of
       
   117        SOME {index, descr, ...} =>
       
   118        let val (_, dtyps, constrs) = AList.lookup (op =) descr index |> the in
       
   119          map (apsnd (fn Us => map (typ_of_dtyp descr (dtyps ~~ Ts)) Us ---> T))
       
   120              constrs
       
   121        end
       
   122      | NONE => [])
       
   123   | datatype_constrs _ _ = []
       
   124 
       
   125 (* Similar to "Nitpick_HOL.bounded_exact_card_of_type".
       
   126    0 means infinite type, 1 means singleton type (e.g., "unit"), and 2 means
       
   127    cardinality 2 or more. The specified default cardinality is returned if the
       
   128    cardinality of the type can't be determined. *)
       
   129 fun tiny_card_of_type ctxt default_card T =
       
   130   let
       
   131     val max = 2 (* 1 would be too small for the "fun" case *)
       
   132     fun aux slack avoid T =
       
   133       (if member (op =) avoid T then
       
   134          0
       
   135        else case T of
       
   136          Type (@{type_name fun}, [T1, T2]) =>
       
   137          (case (aux slack avoid T1, aux slack avoid T2) of
       
   138             (k, 1) => if slack andalso k = 0 then 0 else 1
       
   139           | (0, _) => 0
       
   140           | (_, 0) => 0
       
   141           | (k1, k2) =>
       
   142             if k1 >= max orelse k2 >= max then max
       
   143             else Int.min (max, Integer.pow k2 k1))
       
   144        | @{typ prop} => 2
       
   145        | @{typ bool} => 2 (* optimization *)
       
   146        | @{typ nat} => 0 (* optimization *)
       
   147        | @{typ int} => 0 (* optimization *)
       
   148        | Type (s, _) =>
       
   149          let val thy = Proof_Context.theory_of ctxt in
       
   150            case datatype_constrs thy T of
       
   151              constrs as _ :: _ =>
       
   152              let
       
   153                val constr_cards =
       
   154                  map (Integer.prod o map (aux slack (T :: avoid)) o binder_types
       
   155                       o snd) constrs
       
   156              in
       
   157                if exists (curry (op =) 0) constr_cards then 0
       
   158                else Int.min (max, Integer.sum constr_cards)
       
   159              end
       
   160            | [] =>
       
   161              case Typedef.get_info ctxt s of
       
   162                ({abs_type, rep_type, ...}, _) :: _ =>
       
   163                (* We cheat here by assuming that typedef types are infinite if
       
   164                   their underlying type is infinite. This is unsound in general
       
   165                   but it's hard to think of a realistic example where this would
       
   166                   not be the case. We are also slack with representation types:
       
   167                   If a representation type has the form "sigma => tau", we
       
   168                   consider it enough to check "sigma" for infiniteness. (Look
       
   169                   for "slack" in this function.) *)
       
   170                (case varify_and_instantiate_type ctxt
       
   171                          (Logic.varifyT_global abs_type) T
       
   172                          (Logic.varifyT_global rep_type)
       
   173                      |> aux true avoid of
       
   174                   0 => 0
       
   175                 | 1 => 1
       
   176                 | _ => default_card)
       
   177              | [] => default_card
       
   178          end
       
   179        | TFree _ =>
       
   180          (* Very slightly unsound: Type variables are assumed not to be
       
   181             constrained to cardinality 1. (In practice, the user would most
       
   182             likely have used "unit" directly anyway.) *)
       
   183          if default_card = 1 then 2 else default_card
       
   184        | _ => default_card)
       
   185   in Int.min (max, aux false [] T) end
       
   186 
       
   187 fun is_type_surely_finite ctxt T = tiny_card_of_type ctxt 0 T <> 0
       
   188 fun is_type_surely_infinite ctxt T = tiny_card_of_type ctxt 1 T = 0
   112 
   189 
   113 fun monomorphic_term subst t =
   190 fun monomorphic_term subst t =
   114   map_types (map_type_tvar (fn v =>
   191   map_types (map_type_tvar (fn v =>
   115       case Type.lookup subst v of
   192       case Type.lookup subst v of
   116         SOME typ => typ
   193         SOME typ => typ