src/HOL/Tools/Nitpick/nitpick_preproc.ML
changeset 56245 84fc7dfa3cd4
parent 56243 2e10a36b8d46
child 58634 9f10d82e8188
equal deleted inserted replaced
56244:3298b7a2795a 56245:84fc7dfa3cd4
    34    binary coding. *)
    34    binary coding. *)
    35 val binary_int_threshold = 3
    35 val binary_int_threshold = 3
    36 
    36 
    37 val may_use_binary_ints =
    37 val may_use_binary_ints =
    38   let
    38   let
    39     fun aux def (Const (@{const_name "=="}, _) $ t1 $ t2) =
    39     fun aux def (Const (@{const_name Pure.eq}, _) $ t1 $ t2) =
    40         aux def t1 andalso aux false t2
    40         aux def t1 andalso aux false t2
    41       | aux def (@{const "==>"} $ t1 $ t2) = aux false t1 andalso aux def t2
    41       | aux def (@{const Pure.imp} $ t1 $ t2) = aux false t1 andalso aux def t2
    42       | aux def (Const (@{const_name HOL.eq}, _) $ t1 $ t2) =
    42       | aux def (Const (@{const_name HOL.eq}, _) $ t1 $ t2) =
    43         aux def t1 andalso aux false t2
    43         aux def t1 andalso aux false t2
    44       | aux def (@{const HOL.implies} $ t1 $ t2) = aux false t1 andalso aux def t2
    44       | aux def (@{const HOL.implies} $ t1 $ t2) = aux false t1 andalso aux def t2
    45       | aux def (t1 $ t2) = aux def t1 andalso aux def t2
    45       | aux def (t1 $ t2) = aux def t1 andalso aux def t2
    46       | aux def (t as Const (s, _)) =
    46       | aux def (t as Const (s, _)) =
   143       | _ => exists_subterm (curry (op =) (Var z)) t' ? insert (op =) T
   143       | _ => exists_subterm (curry (op =) (Var z)) t' ? insert (op =) T
   144     fun box_var_in_def new_Ts old_Ts t (z as (_, T)) =
   144     fun box_var_in_def new_Ts old_Ts t (z as (_, T)) =
   145       case t of
   145       case t of
   146         @{const Trueprop} $ t1 => box_var_in_def new_Ts old_Ts t1 z
   146         @{const Trueprop} $ t1 => box_var_in_def new_Ts old_Ts t1 z
   147       | Const (s0, _) $ t1 $ _ =>
   147       | Const (s0, _) $ t1 $ _ =>
   148         if s0 = @{const_name "=="} orelse s0 = @{const_name HOL.eq} then
   148         if s0 = @{const_name Pure.eq} orelse s0 = @{const_name HOL.eq} then
   149           let
   149           let
   150             val (t', args) = strip_comb t1
   150             val (t', args) = strip_comb t1
   151             val T' = fastype_of1 (new_Ts, do_term new_Ts old_Ts Neut t')
   151             val T' = fastype_of1 (new_Ts, do_term new_Ts old_Ts Neut t')
   152           in
   152           in
   153             case fold (add_boxed_types_for_var z)
   153             case fold (add_boxed_types_for_var z)
   185       let val T1 = box_type hol_ctxt InFunLHS (range_type T) in
   185       let val T1 = box_type hol_ctxt InFunLHS (range_type T) in
   186         Const (s, (T1 --> bool_T) --> T1)
   186         Const (s, (T1 --> bool_T) --> T1)
   187       end
   187       end
   188     and do_term new_Ts old_Ts polar t =
   188     and do_term new_Ts old_Ts polar t =
   189       case t of
   189       case t of
   190         Const (s0 as @{const_name all}, T0) $ Abs (s1, T1, t1) =>
   190         Const (s0 as @{const_name Pure.all}, T0) $ Abs (s1, T1, t1) =>
   191         do_quantifier new_Ts old_Ts polar s0 T0 s1 T1 t1
   191         do_quantifier new_Ts old_Ts polar s0 T0 s1 T1 t1
   192       | Const (s0 as @{const_name "=="}, T0) $ t1 $ t2 =>
   192       | Const (s0 as @{const_name Pure.eq}, T0) $ t1 $ t2 =>
   193         do_equals new_Ts old_Ts s0 T0 t1 t2
   193         do_equals new_Ts old_Ts s0 T0 t1 t2
   194       | @{const "==>"} $ t1 $ t2 =>
   194       | @{const Pure.imp} $ t1 $ t2 =>
   195         @{const "==>"} $ do_term new_Ts old_Ts (flip_polarity polar) t1
   195         @{const Pure.imp} $ do_term new_Ts old_Ts (flip_polarity polar) t1
   196         $ do_term new_Ts old_Ts polar t2
   196         $ do_term new_Ts old_Ts polar t2
   197       | @{const Pure.conjunction} $ t1 $ t2 =>
   197       | @{const Pure.conjunction} $ t1 $ t2 =>
   198         @{const Pure.conjunction} $ do_term new_Ts old_Ts polar t1
   198         @{const Pure.conjunction} $ do_term new_Ts old_Ts polar t1
   199         $ do_term new_Ts old_Ts polar t2
   199         $ do_term new_Ts old_Ts polar t2
   200       | @{const Trueprop} $ t1 =>
   200       | @{const Trueprop} $ t1 =>
   332 fun pull_out_universal_constrs hol_ctxt def t =
   332 fun pull_out_universal_constrs hol_ctxt def t =
   333   let
   333   let
   334     val k = maxidx_of_term t + 1
   334     val k = maxidx_of_term t + 1
   335     fun do_term Ts def t args seen =
   335     fun do_term Ts def t args seen =
   336       case t of
   336       case t of
   337         (t0 as Const (@{const_name "=="}, _)) $ t1 $ t2 =>
   337         (t0 as Const (@{const_name Pure.eq}, _)) $ t1 $ t2 =>
   338         do_eq_or_imp Ts true def t0 t1 t2 seen
   338         do_eq_or_imp Ts true def t0 t1 t2 seen
   339       | (t0 as @{const "==>"}) $ t1 $ t2 =>
   339       | (t0 as @{const Pure.imp}) $ t1 $ t2 =>
   340         if def then (t, []) else do_eq_or_imp Ts false def t0 t1 t2 seen
   340         if def then (t, []) else do_eq_or_imp Ts false def t0 t1 t2 seen
   341       | (t0 as Const (@{const_name HOL.eq}, _)) $ t1 $ t2 =>
   341       | (t0 as Const (@{const_name HOL.eq}, _)) $ t1 $ t2 =>
   342         do_eq_or_imp Ts true def t0 t1 t2 seen
   342         do_eq_or_imp Ts true def t0 t1 t2 seen
   343       | (t0 as @{const HOL.implies}) $ t1 $ t2 =>
   343       | (t0 as @{const HOL.implies}) $ t1 $ t2 =>
   344         do_eq_or_imp Ts false def t0 t1 t2 seen
   344         do_eq_or_imp Ts false def t0 t1 t2 seen
   399 fun destroy_pulled_out_constrs (hol_ctxt as {ctxt, ...}) axiom strong t =
   399 fun destroy_pulled_out_constrs (hol_ctxt as {ctxt, ...}) axiom strong t =
   400   let
   400   let
   401     val num_occs_of_var =
   401     val num_occs_of_var =
   402       fold_aterms (fn Var z => (fn f => fn z' => f z' |> z = z' ? Integer.add 1)
   402       fold_aterms (fn Var z => (fn f => fn z' => f z' |> z = z' ? Integer.add 1)
   403                     | _ => I) t (K 0)
   403                     | _ => I) t (K 0)
   404     fun aux Ts careful ((t0 as Const (@{const_name "=="}, _)) $ t1 $ t2) =
   404     fun aux Ts careful ((t0 as Const (@{const_name Pure.eq}, _)) $ t1 $ t2) =
   405         aux_eq Ts careful true t0 t1 t2
   405         aux_eq Ts careful true t0 t1 t2
   406       | aux Ts careful ((t0 as @{const "==>"}) $ t1 $ t2) =
   406       | aux Ts careful ((t0 as @{const Pure.imp}) $ t1 $ t2) =
   407         t0 $ aux Ts false t1 $ aux Ts careful t2
   407         t0 $ aux Ts false t1 $ aux Ts careful t2
   408       | aux Ts careful ((t0 as Const (@{const_name HOL.eq}, _)) $ t1 $ t2) =
   408       | aux Ts careful ((t0 as Const (@{const_name HOL.eq}, _)) $ t1 $ t2) =
   409         aux_eq Ts careful true t0 t1 t2
   409         aux_eq Ts careful true t0 t1 t2
   410       | aux Ts careful ((t0 as @{const HOL.implies}) $ t1 $ t2) =
   410       | aux Ts careful ((t0 as @{const HOL.implies}) $ t1 $ t2) =
   411         t0 $ aux Ts false t1 $ aux Ts careful t2
   411         t0 $ aux Ts false t1 $ aux Ts careful t2
   453       |> aux Ts false
   453       |> aux Ts false
   454   in aux [] axiom t end
   454   in aux [] axiom t end
   455 
   455 
   456 (** Destruction of universal and existential equalities **)
   456 (** Destruction of universal and existential equalities **)
   457 
   457 
   458 fun curry_assms (@{const "==>"} $ (@{const Trueprop}
   458 fun curry_assms (@{const Pure.imp} $ (@{const Trueprop}
   459                                    $ (@{const HOL.conj} $ t1 $ t2)) $ t3) =
   459                                    $ (@{const HOL.conj} $ t1 $ t2)) $ t3) =
   460     curry_assms (Logic.list_implies ([t1, t2] |> map HOLogic.mk_Trueprop, t3))
   460     curry_assms (Logic.list_implies ([t1, t2] |> map HOLogic.mk_Trueprop, t3))
   461   | curry_assms (@{const "==>"} $ t1 $ t2) =
   461   | curry_assms (@{const Pure.imp} $ t1 $ t2) =
   462     @{const "==>"} $ curry_assms t1 $ curry_assms t2
   462     @{const Pure.imp} $ curry_assms t1 $ curry_assms t2
   463   | curry_assms t = t
   463   | curry_assms t = t
   464 
   464 
   465 val destroy_universal_equalities =
   465 val destroy_universal_equalities =
   466   let
   466   let
   467     fun aux prems zs t =
   467     fun aux prems zs t =
   468       case t of
   468       case t of
   469         @{const "==>"} $ t1 $ t2 => aux_implies prems zs t1 t2
   469         @{const Pure.imp} $ t1 $ t2 => aux_implies prems zs t1 t2
   470       | _ => Logic.list_implies (rev prems, t)
   470       | _ => Logic.list_implies (rev prems, t)
   471     and aux_implies prems zs t1 t2 =
   471     and aux_implies prems zs t1 t2 =
   472       case t1 of
   472       case t1 of
   473         Const (@{const_name "=="}, _) $ Var z $ t' => aux_eq prems zs z t' t1 t2
   473         Const (@{const_name Pure.eq}, _) $ Var z $ t' => aux_eq prems zs z t' t1 t2
   474       | @{const Trueprop} $ (Const (@{const_name HOL.eq}, _) $ Var z $ t') =>
   474       | @{const Trueprop} $ (Const (@{const_name HOL.eq}, _) $ Var z $ t') =>
   475         aux_eq prems zs z t' t1 t2
   475         aux_eq prems zs z t' t1 t2
   476       | @{const Trueprop} $ (Const (@{const_name HOL.eq}, _) $ t' $ Var z) =>
   476       | @{const Trueprop} $ (Const (@{const_name HOL.eq}, _) $ t' $ Var z) =>
   477         aux_eq prems zs z t' t1 t2
   477         aux_eq prems zs z t' t1 t2
   478       | _ => aux (t1 :: prems) (Term.add_vars t1 zs) t2
   478       | _ => aux (t1 :: prems) (Term.add_vars t1 zs) t2
   589                         aux (abs_s :: ss) (abs_T :: Ts) (0 :: incrs js)
   589                         aux (abs_s :: ss) (abs_T :: Ts) (0 :: incrs js)
   590                             (skolemizable andalso
   590                             (skolemizable andalso
   591                              not (is_higher_order_type abs_T)) polar t)
   591                              not (is_higher_order_type abs_T)) polar t)
   592       in
   592       in
   593         case t of
   593         case t of
   594           Const (s0 as @{const_name all}, T0) $ Abs (s1, T1, t1) =>
   594           Const (s0 as @{const_name Pure.all}, T0) $ Abs (s1, T1, t1) =>
   595           do_quantifier s0 T0 s1 T1 t1
   595           do_quantifier s0 T0 s1 T1 t1
   596         | @{const "==>"} $ t1 $ t2 =>
   596         | @{const Pure.imp} $ t1 $ t2 =>
   597           @{const "==>"} $ aux ss Ts js skolemizable (flip_polarity polar) t1
   597           @{const Pure.imp} $ aux ss Ts js skolemizable (flip_polarity polar) t1
   598           $ aux ss Ts js skolemizable polar t2
   598           $ aux ss Ts js skolemizable polar t2
   599         | @{const Pure.conjunction} $ t1 $ t2 =>
   599         | @{const Pure.conjunction} $ t1 $ t2 =>
   600           @{const Pure.conjunction} $ aux ss Ts js skolemizable polar t1
   600           @{const Pure.conjunction} $ aux ss Ts js skolemizable polar t1
   601           $ aux ss Ts js skolemizable polar t2
   601           $ aux ss Ts js skolemizable polar t2
   602         | @{const Trueprop} $ t1 =>
   602         | @{const Trueprop} $ t1 =>
   652       end
   652       end
   653   in aux [] [] [] true Pos end
   653   in aux [] [] [] true Pos end
   654 
   654 
   655 (** Function specialization **)
   655 (** Function specialization **)
   656 
   656 
   657 fun params_in_equation (@{const "==>"} $ _ $ t2) = params_in_equation t2
   657 fun params_in_equation (@{const Pure.imp} $ _ $ t2) = params_in_equation t2
   658   | params_in_equation (@{const Trueprop} $ t1) = params_in_equation t1
   658   | params_in_equation (@{const Trueprop} $ t1) = params_in_equation t1
   659   | params_in_equation (Const (@{const_name HOL.eq}, _) $ t1 $ _) =
   659   | params_in_equation (Const (@{const_name HOL.eq}, _) $ t1 $ _) =
   660     snd (strip_comb t1)
   660     snd (strip_comb t1)
   661   | params_in_equation _ = []
   661   | params_in_equation _ = []
   662 
   662 
   864   let
   864   let
   865     fun do_equals u def =
   865     fun do_equals u def =
   866       if exists_subterm (curry (op aconv) u) def then NONE else SOME u
   866       if exists_subterm (curry (op aconv) u) def then NONE else SOME u
   867   in
   867   in
   868     case t of
   868     case t of
   869       Const (@{const_name "=="}, _) $ (u as Free _) $ def => do_equals u def
   869       Const (@{const_name Pure.eq}, _) $ (u as Free _) $ def => do_equals u def
   870     | @{const Trueprop}
   870     | @{const Trueprop}
   871       $ (Const (@{const_name HOL.eq}, _) $ (u as Free _) $ def) =>
   871       $ (Const (@{const_name HOL.eq}, _) $ (u as Free _) $ def) =>
   872       do_equals u def
   872       do_equals u def
   873     | _ => NONE
   873     | _ => NONE
   874   end
   874   end
   916           end
   916           end
   917       end
   917       end
   918     and add_def_axiom depth = add_axiom fst apfst true depth
   918     and add_def_axiom depth = add_axiom fst apfst true depth
   919     and add_nondef_axiom depth = add_axiom snd apsnd false depth
   919     and add_nondef_axiom depth = add_axiom snd apsnd false depth
   920     and add_maybe_def_axiom depth t =
   920     and add_maybe_def_axiom depth t =
   921       (if head_of t <> @{const "==>"} then add_def_axiom
   921       (if head_of t <> @{const Pure.imp} then add_def_axiom
   922        else add_nondef_axiom) depth t
   922        else add_nondef_axiom) depth t
   923     and add_eq_axiom depth t =
   923     and add_eq_axiom depth t =
   924       (if is_constr_pattern_formula ctxt t then add_def_axiom
   924       (if is_constr_pattern_formula ctxt t then add_def_axiom
   925        else add_nondef_axiom) depth t
   925        else add_nondef_axiom) depth t
   926     and add_axioms_for_term depth t (accum as (seen, axs)) =
   926     and add_axioms_for_term depth t (accum as (seen, axs)) =