lean4-htt/src/Std/Http/Internal/LowerCase.lean
Sebastian Ullrich 7f5fac9d9f
feat: add warn.redundantExpose for redundant @[expose]/@[no_expose] attributes (#13359)
This PR adds a `linter.redundantExpose` option (default `true`) that
warns when `@[expose]` or `@[no_expose]` attributes have no effect:

- `@[expose]` on `abbrev` (always exposed) or non-Prop `instance`
(always exposed)
- `@[expose]` on a `def` inside an `@[expose] section` (already exposed
by the section)
- `@[expose]`/`@[no_expose]` in a non-`module` file (no module system)
- `@[no_expose]` on a declaration that wouldn't be exposed by default

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-27 10:33:58 +00:00

69 lines
2 KiB
Text

/-
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Sofia Rodrigues
-/
module
prelude
import Init.Grind
import Init.Data.Int.OfNat
import Init.Data.UInt.Lemmas
public import Init.Data.String.Modify
import Init.Data.String.Lemmas.Modify
@[expose]
public section
/-!
# LowerCase
This module provides predicates and normalization functions for handling ASCII case-insensitivity.
It includes proofs of idempotency for lowercase transformations, as well as utilities for validating
the lowercase state of a String.
-/
namespace Std.Http.Internal
set_option linter.all true
/--
Predicate asserting that a string is in lowercase form.
-/
def IsLowerCase (s : String) : Prop :=
s.toLower = s
private theorem Char.toLower_eq_self_iff {c : Char} : c.toLower = c ↔ c.isUpper = false := by
simp only [Char.toLower, Char.isUpper]
split <;> rename_i h <;> simpa [UInt32.le_iff_toNat_le, Char.ext_iff] using h
private theorem String.toLower_eq_self_iff {s : String} : s.toLower = s ↔ s.toList.any Char.isUpper = false := by
simp only [String.toLower, ← String.toList_inj, String.toList_map]
rw (occs := [2]) [← List.map_id s.toList]
rw [List.map_eq_map_iff]
simp [Char.toLower_eq_self_iff]
instance : Decidable (IsLowerCase s) :=
decidable_of_decidable_of_iff (p := s.toList.any Char.isUpper = false)
(by exact String.toLower_eq_self_iff.symm)
namespace IsLowerCase
private theorem Char.toLower_idempotent (c : Char) : c.toLower.toLower = c.toLower := by
grind [Char.toLower]
/--
Proof that applying `toLower` to any string results in a string that satisfies the `IsLowerCase`
predicate.
-/
theorem isLowerCase_toLower {s : String} : IsLowerCase s.toLower := by
unfold IsLowerCase String.toLower
rw [String.map_map, Function.comp_def]
simp [Char.toLower_idempotent]
theorem isLowerCase_empty : IsLowerCase "" := by
simp [IsLowerCase, String.toLower]
end IsLowerCase
end Std.Http.Internal