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 |