src/HOL/Tools/ATP/atp_util.ML
changeset 69593 3dda49e08b9d
parent 67522 9e712280cc37
child 69597 ff784d5a5bfb
equal deleted inserted replaced
69592:a80d8ec6c998 69593:3dda49e08b9d
   165     in can (Sign.typ_unify thy (T, T')) (Vartab.empty, maxidx) end
   165     in can (Sign.typ_unify thy (T, T')) (Vartab.empty, maxidx) end
   166 
   166 
   167 val type_equiv = Sign.typ_equiv
   167 val type_equiv = Sign.typ_equiv
   168 
   168 
   169 fun varify_type ctxt T =
   169 fun varify_type ctxt T =
   170   Variable.polymorphic_types ctxt [Const (@{const_name undefined}, T)]
   170   Variable.polymorphic_types ctxt [Const (\<^const_name>\<open>undefined\<close>, T)]
   171   |> snd |> the_single |> dest_Const |> snd
   171   |> snd |> the_single |> dest_Const |> snd
   172 
   172 
   173 (* TODO: use "Term_Subst.instantiateT" instead? *)
   173 (* TODO: use "Term_Subst.instantiateT" instead? *)
   174 fun instantiate_type thy T1 T1' T2 =
   174 fun instantiate_type thy T1 T1' T2 =
   175   Same.commit (Envir.subst_type_same
   175   Same.commit (Envir.subst_type_same
   200         0
   200         0
   201       else case AList.lookup (type_equiv thy) assigns T of
   201       else case AList.lookup (type_equiv thy) assigns T of
   202         SOME k => k
   202         SOME k => k
   203       | NONE =>
   203       | NONE =>
   204         case T of
   204         case T of
   205           Type (@{type_name fun}, [T1, T2]) =>
   205           Type (\<^type_name>\<open>fun\<close>, [T1, T2]) =>
   206           (case (aux slack avoid T1, aux slack avoid T2) of
   206           (case (aux slack avoid T1, aux slack avoid T2) of
   207              (k, 1) => if slack andalso k = 0 then 0 else 1
   207              (k, 1) => if slack andalso k = 0 then 0 else 1
   208            | (0, _) => 0
   208            | (0, _) => 0
   209            | (_, 0) => 0
   209            | (_, 0) => 0
   210            | (k1, k2) =>
   210            | (k1, k2) =>
   211              if k1 >= max orelse k2 >= max then max
   211              if k1 >= max orelse k2 >= max then max
   212              else Int.min (max, Integer.pow k2 k1))
   212              else Int.min (max, Integer.pow k2 k1))
   213         | Type (@{type_name set}, [T']) => aux slack avoid (T' --> @{typ bool})
   213         | Type (\<^type_name>\<open>set\<close>, [T']) => aux slack avoid (T' --> \<^typ>\<open>bool\<close>)
   214         | @{typ prop} => 2
   214         | \<^typ>\<open>prop\<close> => 2
   215         | @{typ bool} => 2 (* optimization *)
   215         | \<^typ>\<open>bool\<close> => 2 (* optimization *)
   216         | @{typ nat} => 0 (* optimization *)
   216         | \<^typ>\<open>nat\<close> => 0 (* optimization *)
   217         | Type ("Int.int", []) => 0 (* optimization *)
   217         | Type ("Int.int", []) => 0 (* optimization *)
   218         | Type (s, _) =>
   218         | Type (s, _) =>
   219           (case free_constructors_of ctxt T of
   219           (case free_constructors_of ctxt T of
   220              constrs as _ :: _ =>
   220              constrs as _ :: _ =>
   221              let
   221              let
   258 fun is_type_surely_infinite ctxt sound infinite_Ts T =
   258 fun is_type_surely_infinite ctxt sound infinite_Ts T =
   259   tiny_card_of_type ctxt sound (map (rpair 0) infinite_Ts) 1 T = 0
   259   tiny_card_of_type ctxt sound (map (rpair 0) infinite_Ts) 1 T = 0
   260 
   260 
   261 (* Simple simplifications to ensure that sort annotations don't leave a trail of
   261 (* Simple simplifications to ensure that sort annotations don't leave a trail of
   262    spurious "True"s. *)
   262    spurious "True"s. *)
   263 fun s_not (Const (@{const_name All}, T) $ Abs (s, T', t')) =
   263 fun s_not (Const (\<^const_name>\<open>All\<close>, T) $ Abs (s, T', t')) =
   264     Const (@{const_name Ex}, T) $ Abs (s, T', s_not t')
   264     Const (\<^const_name>\<open>Ex\<close>, T) $ Abs (s, T', s_not t')
   265   | s_not (Const (@{const_name Ex}, T) $ Abs (s, T', t')) =
   265   | s_not (Const (\<^const_name>\<open>Ex\<close>, T) $ Abs (s, T', t')) =
   266     Const (@{const_name All}, T) $ Abs (s, T', s_not t')
   266     Const (\<^const_name>\<open>All\<close>, T) $ Abs (s, T', s_not t')
   267   | s_not (@{const HOL.implies} $ t1 $ t2) = @{const HOL.conj} $ t1 $ s_not t2
   267   | s_not (@{const HOL.implies} $ t1 $ t2) = @{const HOL.conj} $ t1 $ s_not t2
   268   | s_not (@{const HOL.conj} $ t1 $ t2) =
   268   | s_not (@{const HOL.conj} $ t1 $ t2) =
   269     @{const HOL.disj} $ s_not t1 $ s_not t2
   269     @{const HOL.disj} $ s_not t1 $ s_not t2
   270   | s_not (@{const HOL.disj} $ t1 $ t2) =
   270   | s_not (@{const HOL.disj} $ t1 $ t2) =
   271     @{const HOL.conj} $ s_not t1 $ s_not t2
   271     @{const HOL.conj} $ s_not t1 $ s_not t2
   311            $ Abs (hol_close_form_prefix ^ s, T,
   311            $ Abs (hol_close_form_prefix ^ s, T,
   312                   abstract_over (Var ((s, i), T), t')))
   312                   abstract_over (Var ((s, i), T), t')))
   313        (Term.add_vars t []) t
   313        (Term.add_vars t []) t
   314 
   314 
   315 fun hol_open_form unprefix
   315 fun hol_open_form unprefix
   316       (t as Const (@{const_name All}, _) $ Abs (s, T, t')) =
   316       (t as Const (\<^const_name>\<open>All\<close>, _) $ Abs (s, T, t')) =
   317     (case try unprefix s of
   317     (case try unprefix s of
   318        SOME s =>
   318        SOME s =>
   319        let
   319        let
   320          val names = Name.make_context (map fst (Term.add_var_names t' []))
   320          val names = Name.make_context (map fst (Term.add_var_names t' []))
   321          val (s, _) = Name.variant s names
   321          val (s, _) = Name.variant s names
   330     fold_rev (fn T => fn t' => Abs ("x" ^ nat_subscript n, T, t'))
   330     fold_rev (fn T => fn t' => Abs ("x" ^ nat_subscript n, T, t'))
   331              (List.take (binder_types (fastype_of1 (Ts, t)), n))
   331              (List.take (binder_types (fastype_of1 (Ts, t)), n))
   332              (list_comb (incr_boundvars n t, map Bound (n - 1 downto 0)))
   332              (list_comb (incr_boundvars n t, map Bound (n - 1 downto 0)))
   333 
   333 
   334 fun cong_extensionalize_term ctxt t =
   334 fun cong_extensionalize_term ctxt t =
   335   if exists_Const (fn (s, _) => s = @{const_name Not}) t then
   335   if exists_Const (fn (s, _) => s = \<^const_name>\<open>Not\<close>) t then
   336     t |> Skip_Proof.make_thm (Proof_Context.theory_of ctxt)
   336     t |> Skip_Proof.make_thm (Proof_Context.theory_of ctxt)
   337       |> Meson.cong_extensionalize_thm ctxt
   337       |> Meson.cong_extensionalize_thm ctxt
   338       |> Thm.prop_of
   338       |> Thm.prop_of
   339   else
   339   else
   340     t
   340     t
   341 
   341 
   342 fun is_fun_equality (@{const_name HOL.eq},
   342 fun is_fun_equality (\<^const_name>\<open>HOL.eq\<close>,
   343                      Type (_, [Type (@{type_name fun}, _), _])) = true
   343                      Type (_, [Type (\<^type_name>\<open>fun\<close>, _), _])) = true
   344   | is_fun_equality _ = false
   344   | is_fun_equality _ = false
   345 
   345 
   346 fun abs_extensionalize_term ctxt t =
   346 fun abs_extensionalize_term ctxt t =
   347   if exists_Const is_fun_equality t then
   347   if exists_Const is_fun_equality t then
   348     t |> Thm.cterm_of ctxt |> Meson.abs_extensionalize_conv ctxt
   348     t |> Thm.cterm_of ctxt |> Meson.abs_extensionalize_conv ctxt
   350   else
   350   else
   351     t
   351     t
   352 
   352 
   353 fun unextensionalize_def t =
   353 fun unextensionalize_def t =
   354   case t of
   354   case t of
   355     @{const Trueprop} $ (Const (@{const_name HOL.eq}, _) $ lhs $ rhs) =>
   355     @{const Trueprop} $ (Const (\<^const_name>\<open>HOL.eq\<close>, _) $ lhs $ rhs) =>
   356     (case strip_comb lhs of
   356     (case strip_comb lhs of
   357        (c as Const (_, T), args) =>
   357        (c as Const (_, T), args) =>
   358        if forall is_Var args andalso not (has_duplicates (op =) args) then
   358        if forall is_Var args andalso not (has_duplicates (op =) args) then
   359          @{const Trueprop}
   359          @{const Trueprop}
   360          $ (Const (@{const_name HOL.eq}, T --> T --> @{typ bool})
   360          $ (Const (\<^const_name>\<open>HOL.eq\<close>, T --> T --> \<^typ>\<open>bool\<close>)
   361             $ c $ fold_rev lambda args rhs)
   361             $ c $ fold_rev lambda args rhs)
   362        else
   362        else
   363          t
   363          t
   364      | _ => t)
   364      | _ => t)
   365   | _ => t
   365   | _ => t
   368    predicate variable. Leaves other theorems unchanged. We simply instantiate
   368    predicate variable. Leaves other theorems unchanged. We simply instantiate
   369    the conclusion variable to "False". (Cf. "transform_elim_theorem" in
   369    the conclusion variable to "False". (Cf. "transform_elim_theorem" in
   370    "Meson_Clausify".) *)
   370    "Meson_Clausify".) *)
   371 fun transform_elim_prop t =
   371 fun transform_elim_prop t =
   372   case Logic.strip_imp_concl t of
   372   case Logic.strip_imp_concl t of
   373     @{const Trueprop} $ Var (z, @{typ bool}) =>
   373     @{const Trueprop} $ Var (z, \<^typ>\<open>bool\<close>) =>
   374     subst_Vars [(z, @{const False})] t
   374     subst_Vars [(z, @{const False})] t
   375   | Var (z, @{typ prop}) => subst_Vars [(z, @{prop False})] t
   375   | Var (z, \<^typ>\<open>prop\<close>) => subst_Vars [(z, \<^prop>\<open>False\<close>)] t
   376   | _ => t
   376   | _ => t
   377 
   377 
   378 fun specialize_type thy (s, T) t =
   378 fun specialize_type thy (s, T) t =
   379   let
   379   let
   380     fun subst_for (Const (s', T')) =
   380     fun subst_for (Const (s', T')) =
   399       ||> (map dest_Free #> Variable.variant_frees ctxt [] #> `(map Free))
   399       ||> (map dest_Free #> Variable.variant_frees ctxt [] #> `(map Free))
   400     val hyp_ts = t |> Logic.strip_assums_hyp |> map (curry subst_bounds frees)
   400     val hyp_ts = t |> Logic.strip_assums_hyp |> map (curry subst_bounds frees)
   401     val concl_t = t |> Logic.strip_assums_concl |> curry subst_bounds frees
   401     val concl_t = t |> Logic.strip_assums_concl |> curry subst_bounds frees
   402   in (rev params, hyp_ts, concl_t) end
   402   in (rev params, hyp_ts, concl_t) end
   403 
   403 
   404 fun extract_lambda_def dest_head (Const (@{const_name HOL.eq}, _) $ t $ u) =
   404 fun extract_lambda_def dest_head (Const (\<^const_name>\<open>HOL.eq\<close>, _) $ t $ u) =
   405     let val (head, args) = strip_comb t in
   405     let val (head, args) = strip_comb t in
   406       (head |> dest_head |> fst,
   406       (head |> dest_head |> fst,
   407        fold_rev (fn t as Var ((s, _), T) =>
   407        fold_rev (fn t as Var ((s, _), T) =>
   408                     (fn u => Abs (s, T, abstract_over (t, u)))
   408                     (fn u => Abs (s, T, abstract_over (t, u)))
   409                   | _ => raise Fail "expected \"Var\"") args u)
   409                   | _ => raise Fail "expected \"Var\"") args u)