src/HOL/Real_Asymp/multiseries_expansion_bounds.ML
changeset 69597 ff784d5a5bfb
parent 68630 c55f6f0b3854
equal deleted inserted replaced
69596:c8a2755bf220 69597:ff784d5a5bfb
    90                 @{thm expands_to_const}
    90                 @{thm expands_to_const}
    91   in
    91   in
    92     thm OF [get_basis_wf_thm basis, mk_expansion_level_eq_thm basis]
    92     thm OF [get_basis_wf_thm basis, mk_expansion_level_eq_thm basis]
    93   end
    93   end
    94 
    94 
    95 fun dest_eventually (Const (@{const_name "Filter.eventually"}, _) $ p $ f) = (p, f)
    95 fun dest_eventually (Const (\<^const_name>\<open>Filter.eventually\<close>, _) $ p $ f) = (p, f)
    96   | dest_eventually t = raise TERM ("dest_eventually", [t])
    96   | dest_eventually t = raise TERM ("dest_eventually", [t])
    97 
    97 
    98 fun dest_binop (f $ a $ b) = (f, a, b)
    98 fun dest_binop (f $ a $ b) = (f, a, b)
    99   | dest_binop t = raise TERM ("dest_binop", [t])
    99   | dest_binop t = raise TERM ("dest_binop", [t])
   100 
   100 
   111   | transfer_bounds eq_thm (Bounds (lb, ub)) =
   111   | transfer_bounds eq_thm (Bounds (lb, ub)) =
   112       Bounds 
   112       Bounds 
   113         (Option.map (apsnd (fn thm => @{thm transfer_lower_bound} OF [thm, eq_thm])) lb,
   113         (Option.map (apsnd (fn thm => @{thm transfer_lower_bound} OF [thm, eq_thm])) lb,
   114          Option.map (apsnd (fn thm => @{thm transfer_upper_bound} OF [thm, eq_thm])) ub)
   114          Option.map (apsnd (fn thm => @{thm transfer_upper_bound} OF [thm, eq_thm])) ub)
   115 
   115 
   116 fun dest_le (@{term "(<=) :: real => _"} $ l $ r) = (l, r)
   116 fun dest_le (\<^term>\<open>(<=) :: real => _\<close> $ l $ r) = (l, r)
   117   | dest_le t = raise TERM ("dest_le", [t])
   117   | dest_le t = raise TERM ("dest_le", [t])
   118 
   118 
   119 fun abconv (t, t') = Envir.beta_eta_contract t aconv Envir.beta_eta_contract t'
   119 fun abconv (t, t') = Envir.beta_eta_contract t aconv Envir.beta_eta_contract t'
   120 
   120 
   121 val realT = @{typ "Real.real"}
   121 val realT = \<^typ>\<open>Real.real\<close>
   122 
   122 
   123 fun check_bounds e (Exact thm) = let val _ = check_expansion e thm in Exact thm end
   123 fun check_bounds e (Exact thm) = let val _ = check_expansion e thm in Exact thm end
   124   | check_bounds e (Bounds bnds) =
   124   | check_bounds e (Bounds bnds) =
   125       let
   125       let
   126         fun msg lower = if lower then "check_lower_bound" else "check_upper_bound"
   126         fun msg lower = if lower then "check_lower_bound" else "check_upper_bound"
   165 fun get_basis_size basis = length (get_basis_list basis)
   165 fun get_basis_size basis = length (get_basis_list basis)
   166 
   166 
   167 fun trim_expansion_while_pos ectxt (thm, basis) =
   167 fun trim_expansion_while_pos ectxt (thm, basis) =
   168   let
   168   let
   169     val n = get_basis_size basis
   169     val n = get_basis_size basis
   170     val es = SOME (replicate n @{term "0 :: real"})
   170     val es = SOME (replicate n \<^term>\<open>0 :: real\<close>)
   171   in
   171   in
   172     trim_expansion_while_greater false es false NONE ectxt (thm, basis)
   172     trim_expansion_while_greater false es false NONE ectxt (thm, basis)
   173   end
   173   end
   174 
   174 
   175 fun lift_bounds basis (Exact thm) = Exact (lift basis thm)
   175 fun lift_bounds basis (Exact thm) = Exact (lift basis thm)
   187 fun get_expanded_fun_bounds_aux f (_, thm) =
   187 fun get_expanded_fun_bounds_aux f (_, thm) =
   188   let
   188   let
   189     val t = thm |> Thm.concl_of |> HOLogic.dest_Trueprop |> dest_comb |> fst |> dest_comb |> snd
   189     val t = thm |> Thm.concl_of |> HOLogic.dest_Trueprop |> dest_comb |> fst |> dest_comb |> snd
   190   in
   190   in
   191     case Envir.eta_long [] t of
   191     case Envir.eta_long [] t of
   192       Abs (x, T, @{term "(<=) :: real => _"} $ lhs $ rhs) => Abs (x, T, f (lhs, rhs))
   192       Abs (x, T, \<^term>\<open>(<=) :: real => _\<close> $ lhs $ rhs) => Abs (x, T, f (lhs, rhs))
   193     | _ => raise THM ("get_expanded_fun_bounds", 0, [thm])
   193     | _ => raise THM ("get_expanded_fun_bounds", 0, [thm])
   194   end
   194   end
   195 
   195 
   196 fun get_expanded_fun_bounds (Exact thm) = get_expanded_fun thm
   196 fun get_expanded_fun_bounds (Exact thm) = get_expanded_fun thm
   197   | get_expanded_fun_bounds (Bounds (NONE, NONE)) = raise TERM ("get_expanded_fun_bounds", [])
   197   | get_expanded_fun_bounds (Bounds (NONE, NONE)) = raise TERM ("get_expanded_fun_bounds", [])
   233           (thm2, gt_thm RS @{thm eventually_less_imp_le}, mk_refl_thm ectxt (get_expanded_fun thm2))
   233           (thm2, gt_thm RS @{thm eventually_less_imp_le}, mk_refl_thm ectxt (get_expanded_fun thm2))
   234       | (EQUAL, eq_thm, thm1, _) =>
   234       | (EQUAL, eq_thm, thm1, _) =>
   235           (thm1, mk_refl_thm ectxt (get_expanded_fun thm1), eq_thm RS @{thm eventually_eq_imp_le})
   235           (thm1, mk_refl_thm ectxt (get_expanded_fun thm1), eq_thm RS @{thm eventually_eq_imp_le})
   236 
   236 
   237 fun find_greater_expansion ectxt (thm1, thm2, basis) =
   237 fun find_greater_expansion ectxt (thm1, thm2, basis) =
   238       case compare_expansions ectxt (@{print} (thm1, thm2, basis)) of
   238       case compare_expansions ectxt (\<^print> (thm1, thm2, basis)) of
   239         (LESS, less_thm, _, thm2) =>
   239         (LESS, less_thm, _, thm2) =>
   240           (thm2, less_thm RS @{thm eventually_less_imp_le}, mk_refl_thm ectxt (get_expanded_fun thm2))
   240           (thm2, less_thm RS @{thm eventually_less_imp_le}, mk_refl_thm ectxt (get_expanded_fun thm2))
   241       | (GREATER, gt_thm, thm1, _) =>
   241       | (GREATER, gt_thm, thm1, _) =>
   242           (thm1, mk_refl_thm ectxt (get_expanded_fun thm1), gt_thm RS @{thm eventually_less_imp_le})
   242           (thm1, mk_refl_thm ectxt (get_expanded_fun thm1), gt_thm RS @{thm eventually_less_imp_le})
   243       | (EQUAL, eq_thm, thm1, _) =>
   243       | (EQUAL, eq_thm, thm1, _) =>
   262 val powr_bounds_thms = @{thms powr_bounds_real[eventuallized]}
   262 val powr_bounds_thms = @{thms powr_bounds_real[eventuallized]}
   263 fun powr_bounds_thm n = List.nth (powr_bounds_thms, n)
   263 fun powr_bounds_thm n = List.nth (powr_bounds_thms, n)
   264 
   264 
   265 fun mk_nonstrict_thm [thm1, thm2] sgn_thm = (
   265 fun mk_nonstrict_thm [thm1, thm2] sgn_thm = (
   266       case Thm.concl_of sgn_thm |> HOLogic.dest_Trueprop of
   266       case Thm.concl_of sgn_thm |> HOLogic.dest_Trueprop of
   267         Const (@{const_name "Filter.eventually"}, _) $ t $ _ => (
   267         Const (\<^const_name>\<open>Filter.eventually\<close>, _) $ t $ _ => (
   268           case Envir.eta_long [] t of
   268           case Envir.eta_long [] t of
   269             Abs (_, _, Const (@{const_name "HOL.eq"}, _) $ _ $ _) => sgn_thm RS thm1
   269             Abs (_, _, Const (\<^const_name>\<open>HOL.eq\<close>, _) $ _ $ _) => sgn_thm RS thm1
   270           | _ => sgn_thm RS thm2)
   270           | _ => sgn_thm RS thm2)
   271       | _ => sgn_thm RS thm2)
   271       | _ => sgn_thm RS thm2)
   272   | mk_nonstrict_thm _ _ = raise Match    
   272   | mk_nonstrict_thm _ _ = raise Match    
   273 
   273 
   274 
   274 
   396         (thm2, _, SOME trimmed_thm) =>
   396         (thm2, _, SOME trimmed_thm) =>
   397           @{thm expands_to_divide} OF [trimmed_thm, get_basis_wf_thm basis, thm1, thm2]
   397           @{thm expands_to_divide} OF [trimmed_thm, get_basis_wf_thm basis, thm1, thm2]
   398 
   398 
   399 fun forget_trimmedness_sign trimmed_thm =
   399 fun forget_trimmedness_sign trimmed_thm =
   400   case Thm.concl_of trimmed_thm |> HOLogic.dest_Trueprop of
   400   case Thm.concl_of trimmed_thm |> HOLogic.dest_Trueprop of
   401     Const (@{const_name Multiseries_Expansion.trimmed}, _) $ _ => trimmed_thm
   401     Const (\<^const_name>\<open>Multiseries_Expansion.trimmed\<close>, _) $ _ => trimmed_thm
   402   | Const (@{const_name Multiseries_Expansion.trimmed_pos}, _) $ _ =>
   402   | Const (\<^const_name>\<open>Multiseries_Expansion.trimmed_pos\<close>, _) $ _ =>
   403       trimmed_thm RS @{thm trimmed_pos_imp_trimmed}
   403       trimmed_thm RS @{thm trimmed_pos_imp_trimmed}
   404   | Const (@{const_name Multiseries_Expansion.trimmed_neg}, _) $ _ =>
   404   | Const (\<^const_name>\<open>Multiseries_Expansion.trimmed_neg\<close>, _) $ _ =>
   405       trimmed_thm RS @{thm trimmed_neg_imp_trimmed}
   405       trimmed_thm RS @{thm trimmed_neg_imp_trimmed}
   406   | _ => raise THM ("forget_trimmedness_sign", 0, [trimmed_thm])
   406   | _ => raise THM ("forget_trimmedness_sign", 0, [trimmed_thm])
   407 
   407 
   408 fun inverse_expansion_bounds ectxt basis (Exact thm) =
   408 fun inverse_expansion_bounds ectxt basis (Exact thm) =
   409       Exact (inverse_expansion ectxt basis thm)
   409       Exact (inverse_expansion ectxt basis thm)
   426       end
   426       end
   427   | inverse_expansion_bounds _ _ _ = Bounds (NONE, NONE)
   427   | inverse_expansion_bounds _ _ _ = Bounds (NONE, NONE)
   428 
   428 
   429 fun trimmed_thm_to_inverse_sgn_thm basis thm trimmed_thm =
   429 fun trimmed_thm_to_inverse_sgn_thm basis thm trimmed_thm =
   430   case trimmed_thm |> Thm.concl_of |> HOLogic.dest_Trueprop of
   430   case trimmed_thm |> Thm.concl_of |> HOLogic.dest_Trueprop of
   431     Const (@{const_name "Multiseries_Expansion.trimmed_pos"}, _) $ _ =>
   431     Const (\<^const_name>\<open>Multiseries_Expansion.trimmed_pos\<close>, _) $ _ =>
   432       @{thm pos_imp_inverse_pos[eventuallized, OF expands_to_imp_eventually_pos]} OF
   432       @{thm pos_imp_inverse_pos[eventuallized, OF expands_to_imp_eventually_pos]} OF
   433         [get_basis_wf_thm basis, thm, trimmed_thm]
   433         [get_basis_wf_thm basis, thm, trimmed_thm]
   434   | Const (@{const_name "Multiseries_Expansion.trimmed_neg"}, _) $ _ =>
   434   | Const (\<^const_name>\<open>Multiseries_Expansion.trimmed_neg\<close>, _) $ _ =>
   435       @{thm neg_imp_inverse_neg[eventuallized, OF expands_to_imp_eventually_neg]} OF
   435       @{thm neg_imp_inverse_neg[eventuallized, OF expands_to_imp_eventually_neg]} OF
   436         [get_basis_wf_thm basis, thm, trimmed_thm]
   436         [get_basis_wf_thm basis, thm, trimmed_thm]
   437   | _ => raise THM ("trimmed_thm_to_inverse_sgn_thm", 0, [trimmed_thm])
   437   | _ => raise THM ("trimmed_thm_to_inverse_sgn_thm", 0, [trimmed_thm])
   438 
   438 
   439 fun transfer_divide_bounds (lthm, uthm, in_bounds_thm) =
   439 fun transfer_divide_bounds (lthm, uthm, in_bounds_thm) =
   563             (minus uthm, minus lthm,
   563             (minus uthm, minus lthm,
   564                @{thm nonpos_abs_bounds[eventuallized]} OF [mk_nonpos_thm usgn_thm, in_bounds_thm])
   564                @{thm nonpos_abs_bounds[eventuallized]} OF [mk_nonpos_thm usgn_thm, in_bounds_thm])
   565         | ((true, _), (_, true)) => (
   565         | ((true, _), (_, true)) => (
   566             case find_greater_expansion ectxt (minus lthm, uthm, basis) of
   566             case find_greater_expansion ectxt (minus lthm, uthm, basis) of
   567               (u'_thm, le_thm1, le_thm2) =>
   567               (u'_thm, le_thm1, le_thm2) =>
   568                 (mk_const_expansion ectxt basis @{term "0::real"}, u'_thm,
   568                 (mk_const_expansion ectxt basis \<^term>\<open>0::real\<close>, u'_thm,
   569                   @{thm indet_abs_bounds[eventuallized]} OF 
   569                   @{thm indet_abs_bounds[eventuallized]} OF 
   570                     [mk_nonpos_thm lsgn_thm, mk_nonneg_thm usgn_thm, 
   570                     [mk_nonpos_thm lsgn_thm, mk_nonneg_thm usgn_thm, 
   571                        in_bounds_thm, le_thm1, le_thm2]))
   571                        in_bounds_thm, le_thm1, le_thm2]))
   572         | _ => raise TERM ("Unexpected zeroness result in abs_expansion_bounds", []))
   572         | _ => raise TERM ("Unexpected zeroness result in abs_expansion_bounds", []))
   573         |> convert_bounds
   573         |> convert_bounds
   621       ((u_thm, l_thm, @{thm powr_right_bounds(2)[eventuallized]}
   621       ((u_thm, l_thm, @{thm powr_right_bounds(2)[eventuallized]}
   622           OF [l1_sgn_thm, in_bounds_thm, mk_nonpos_thm sgn_thm]), basis'')
   622           OF [l1_sgn_thm, in_bounds_thm, mk_nonpos_thm sgn_thm]), basis'')
   623   end
   623   end
   624 
   624 
   625 fun compare_expansion_to_1 ectxt (thm, basis) =
   625 fun compare_expansion_to_1 ectxt (thm, basis) =
   626   prove_asymptotic_relation ectxt (thm, const_expansion ectxt basis @{term "1 :: real"}, basis)
   626   prove_asymptotic_relation ectxt (thm, const_expansion ectxt basis \<^term>\<open>1 :: real\<close>, basis)
   627 
   627 
   628 fun powr_expansion_bounds_left ectxt basis
   628 fun powr_expansion_bounds_left ectxt basis
   629       thm1 ((l2_thm, l2_le_thm), (u2_thm, u2_ge_thm)) =
   629       thm1 ((l2_thm, l2_le_thm), (u2_thm, u2_ge_thm)) =
   630   let
   630   let
   631     val in_bounds_thm = @{thm eventually_atLeastAtMostI} OF [l2_le_thm, u2_ge_thm]
   631     val in_bounds_thm = @{thm eventually_atLeastAtMostI} OF [l2_le_thm, u2_ge_thm]
   793                             (uthm', do_transfer 3
   793                             (uthm', do_transfer 3
   794                                [mk_nonneg_thm l1_sgn_thm, u2_sgn_thm, ge_thm1, le_thm2, le_thm'])
   794                                [mk_nonneg_thm l1_sgn_thm, u2_sgn_thm, ge_thm1, le_thm2, le_thm'])
   795                         | _ =>
   795                         | _ =>
   796                             let
   796                             let
   797                               val (uthm'', le_u'_thm1, le_u'_thm2) = find_greater_expansion ectxt 
   797                               val (uthm'', le_u'_thm1, le_u'_thm2) = find_greater_expansion ectxt 
   798                                 (uthm', const_expansion ectxt basis @{term "1::real"}, basis)
   798                                 (uthm', const_expansion ectxt basis \<^term>\<open>1::real\<close>, basis)
   799                             in
   799                             in
   800                               (uthm'', do_transfer 4
   800                               (uthm'', do_transfer 4
   801                                [mk_nonneg_thm l1_sgn_thm, ge_thm1, le_thm', le_u'_thm1, le_u'_thm2])
   801                                [mk_nonneg_thm l1_sgn_thm, ge_thm1, le_thm', le_u'_thm1, le_u'_thm2])
   802                             end)
   802                             end)
   803               in
   803               in
   863       let
   863       let
   864         val wf_thm = get_basis_wf_thm basis
   864         val wf_thm = get_basis_wf_thm basis
   865         fun mk_lb (exp_thm, le_thm) =
   865         fun mk_lb (exp_thm, le_thm) =
   866           let
   866           let
   867             val exp_thm' = @{thm expands_to_minus} OF
   867             val exp_thm' = @{thm expands_to_minus} OF
   868               [wf_thm, exp_thm, const_expansion ectxt basis @{term "1::real"}]
   868               [wf_thm, exp_thm, const_expansion ectxt basis \<^term>\<open>1::real\<close>]
   869             val le_thm = @{thm rfloor_bound(1)} OF [le_thm]
   869             val le_thm = @{thm rfloor_bound(1)} OF [le_thm]
   870           in
   870           in
   871             (exp_thm', le_thm)
   871             (exp_thm', le_thm)
   872           end
   872           end
   873         val mk_ub = apsnd (fn thm => @{thm rfloor_bound(2)} OF [thm])
   873         val mk_ub = apsnd (fn thm => @{thm rfloor_bound(2)} OF [thm])
   881       let
   881       let
   882         val wf_thm = get_basis_wf_thm basis
   882         val wf_thm = get_basis_wf_thm basis
   883         fun mk_ub (exp_thm, le_thm) =
   883         fun mk_ub (exp_thm, le_thm) =
   884           let
   884           let
   885             val exp_thm' = @{thm expands_to_add} OF
   885             val exp_thm' = @{thm expands_to_add} OF
   886               [wf_thm, exp_thm, const_expansion ectxt basis @{term "1::real"}]
   886               [wf_thm, exp_thm, const_expansion ectxt basis \<^term>\<open>1::real\<close>]
   887             val le_thm = @{thm rceil_bound(2)} OF [le_thm]
   887             val le_thm = @{thm rceil_bound(2)} OF [le_thm]
   888           in
   888           in
   889             (exp_thm', le_thm)
   889             (exp_thm', le_thm)
   890           end
   890           end
   891         val mk_lb = apsnd (fn thm => @{thm rceil_bound(1)} OF [thm])
   891         val mk_lb = apsnd (fn thm => @{thm rceil_bound(1)} OF [thm])
   901   let
   901   let
   902     val (f, g) = apply2 (Thm.reflexive o Thm.cterm_of (Lazy_Eval.get_ctxt ectxt) o
   902     val (f, g) = apply2 (Thm.reflexive o Thm.cterm_of (Lazy_Eval.get_ctxt ectxt) o
   903       get_expanded_fun_bounds) (bnds1, bnds2)
   903       get_expanded_fun_bounds) (bnds1, bnds2)
   904     val ge_lower_thm = @{thm natmod_trivial_lower_bound} OF [f, g]
   904     val ge_lower_thm = @{thm natmod_trivial_lower_bound} OF [f, g]
   905     fun minus1 thm = @{thm expands_to_minus} OF
   905     fun minus1 thm = @{thm expands_to_minus} OF
   906           [get_basis_wf_thm basis, thm, const_expansion ectxt basis @{term "1::real"}]
   906           [get_basis_wf_thm basis, thm, const_expansion ectxt basis \<^term>\<open>1::real\<close>]
   907     fun find_upper uthm1 le1_thm u_nonneg_thm =
   907     fun find_upper uthm1 le1_thm u_nonneg_thm =
   908       let
   908       let
   909         val upper1 = (uthm1, @{thm natmod_upper_bound'} OF [g, u_nonneg_thm, le1_thm])
   909         val upper1 = (uthm1, @{thm natmod_upper_bound'} OF [g, u_nonneg_thm, le1_thm])
   910         val upper2 =
   910         val upper2 =
   911           case (get_lower_bound bnds2, get_upper_bound bnds2) of
   911           case (get_lower_bound bnds2, get_upper_bound bnds2) of
  1198         fun aux (thm, le_thm) =
  1198         fun aux (thm, le_thm) =
  1199           (sgn_expansion ectxt (thm, basis), mono_bound @{thm mono_sgn_real} le_thm)
  1199           (sgn_expansion ectxt (thm, basis), mono_bound @{thm mono_sgn_real} le_thm)
  1200         val (lower, upper) = apply2 (Option.map aux) bnds
  1200         val (lower, upper) = apply2 (Option.map aux) bnds
  1201         fun get_bound_exp (SOME (thm, _)) = SOME (get_expansion thm)
  1201         fun get_bound_exp (SOME (thm, _)) = SOME (get_expansion thm)
  1202           | get_bound_exp _ = NONE
  1202           | get_bound_exp _ = NONE
  1203         fun is_const (SOME (Const (@{const_name "Multiseries_Expansion.const_expansion"}, _) $ c'),
  1203         fun is_const (SOME (Const (\<^const_name>\<open>Multiseries_Expansion.const_expansion\<close>, _) $ c'),
  1204               c) = c aconv c'
  1204               c) = c aconv c'
  1205           | is_const _ = false
  1205           | is_const _ = false
  1206         fun aconv' (SOME a, SOME b) = a aconv b
  1206         fun aconv' (SOME a, SOME b) = a aconv b
  1207           | aconv' _ = false
  1207           | aconv' _ = false
  1208       in
  1208       in
  1209         if is_const (get_bound_exp lower, @{term "\<lambda>x::real. 1 :: real"}) then
  1209         if is_const (get_bound_exp lower, \<^term>\<open>\<lambda>x::real. 1 :: real\<close>) then
  1210           let
  1210           let
  1211             val SOME (lthm, ge_thm) = lower
  1211             val SOME (lthm, ge_thm) = lower
  1212           in
  1212           in
  1213             Exact (@{thm eventually_sgn_ge_1D} OF [ge_thm, lthm])
  1213             Exact (@{thm eventually_sgn_ge_1D} OF [ge_thm, lthm])
  1214           end
  1214           end
  1215         else if is_const (get_bound_exp upper, @{term "\<lambda>x::real. -1 :: real"}) then
  1215         else if is_const (get_bound_exp upper, \<^term>\<open>\<lambda>x::real. -1 :: real\<close>) then
  1216           let
  1216           let
  1217             val SOME (uthm, le_thm) = upper
  1217             val SOME (uthm, le_thm) = upper
  1218           in
  1218           in
  1219             Exact (@{thm eventually_sgn_le_neg1D} OF [le_thm, uthm])
  1219             Exact (@{thm eventually_sgn_le_neg1D} OF [le_thm, uthm])
  1220           end
  1220           end
  1718 val dest_arg = dest_comb #> snd
  1718 val dest_arg = dest_comb #> snd
  1719 val concl_of' = Thm.concl_of #> HOLogic.dest_Trueprop
  1719 val concl_of' = Thm.concl_of #> HOLogic.dest_Trueprop
  1720 
  1720 
  1721 fun lim_eq ectxt (l1, l2) = (l1 aconv l2) orelse
  1721 fun lim_eq ectxt (l1, l2) = (l1 aconv l2) orelse
  1722   case (l1, l2) of
  1722   case (l1, l2) of
  1723     (Const (@{const_name nhds}, _) $ a, Const (@{const_name nhds}, _) $ b) => (
  1723     (Const (\<^const_name>\<open>nhds\<close>, _) $ a, Const (\<^const_name>\<open>nhds\<close>, _) $ b) => (
  1724       case try_prove_real_eq false ectxt (a, b) of
  1724       case try_prove_real_eq false ectxt (a, b) of
  1725         SOME _ => true
  1725         SOME _ => true
  1726       | _ => false)
  1726       | _ => false)
  1727   | _ => false
  1727   | _ => false
  1728 
  1728