Skip to content

Commit c9d52cb

Browse files
add detector from using Classical.choice
1 parent 1278a6b commit c9d52cb

11 files changed

+88
-1
lines changed

Katydid.lean

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import Katydid.Std.Linter.DetectClassical
12
import Katydid.Std.BEq
23
import Katydid.Std.Ordering
34
import Katydid.Std.Decidable

Katydid/Regex/IndexedRegex.lean

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import Katydid.Std.Linter.DetectClassical
12
import Katydid.Std.Decidable
23

34
import Katydid.Regex.Language

Katydid/Regex/Language.lean

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import Katydid.Std.Linter.DetectClassical
12
import Katydid.Std.Lists
23

34
namespace Language

Katydid/Regex/SimpleRegex.lean

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import Lean
33
import Mathlib.Tactic.SplitIfs
44
import Mathlib.Tactic.CongrM
55

6+
import Katydid.Std.Linter.DetectClassical
67
import Katydid.Std.Decidable
78

89
import Katydid.Regex.Language

Katydid/Regex/SmartRegex.lean

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import Katydid.Std.Linter.DetectClassical
12
import Katydid.Std.NonEmptyList
23

34
import Katydid.Regex.Language

Katydid/Std/BEq.lean

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import Katydid.Std.Linter.DetectClassical
2+
13
theorem beq_eq_or_neq {α: Type} [BEq α] (x y: α):
24
BEq.beq x y \/ (Not (BEq.beq x y)) := by
35
by_cases BEq.beq x y

Katydid/Std/Decidable.lean

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import Katydid.Std.Linter.DetectClassical
2+
13
namespace Decidable
24

35
def or {α β: Prop} (a: Decidable α) (b: Decidable β): Decidable (α \/ β) :=
+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
-- Thank you to Damiano Testa
2+
-- https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/restricting.20axioms/near/501743343
3+
4+
import Lean.Util.CollectAxioms
5+
import Mathlib.Tactic.DeclarationNames
6+
7+
/-!
8+
# The "detectClassical" linter
9+
10+
The "detectClassical" linter emits a warning on declarations that depend on the `Classical.choice`
11+
axiom.
12+
-/
13+
14+
open Lean Elab Command
15+
16+
namespace Katydid.Std.Linter
17+
18+
/--
19+
The "detectClassical" linter emits a warning on declarations that depend on the `Classical.choice`
20+
axiom.
21+
-/
22+
register_option linter.detectClassical : Bool := {
23+
defValue := true
24+
descr := "enable the detectClassical linter"
25+
}
26+
27+
/--
28+
The `linter.verbose.detectClassical` option is a flag to make the `detectClassical` linter emit
29+
a confirmation on declarations that depend *not* on the `Classical.choice` axiom.
30+
-/
31+
register_option linter.verbose.detectClassical : Bool := {
32+
defValue := false
33+
descr := "enable the verbose setting for the detectClassical linter"
34+
}
35+
36+
namespace DetectClassical
37+
38+
@[inherit_doc Katydid.Std.Linter.linter.detectClassical]
39+
def detectClassicalLinter : Linter where run := withSetOptionIn fun stx ↦ do
40+
unless Linter.getLinterValue linter.detectClassical (← getOptions) do
41+
return
42+
if (← get).messages.hasErrors then
43+
return
44+
let d := (stx.getPos?.getD default)
45+
let nmsd := (← Mathlib.Linter.getNamesFrom d)
46+
let nms := nmsd.filter (! ·.getId.isInternal)
47+
let verbose? := Linter.getLinterValue linter.verbose.detectClassical (← getOptions)
48+
for constStx in nms do
49+
let constName := constStx.getId
50+
let axioms ← collectAxioms constName
51+
if axioms.isEmpty then
52+
if verbose? then
53+
logInfoAt constStx m!"'{constName}' does not depend on any axioms"
54+
return
55+
if !axioms.contains `Classical.choice then
56+
if verbose? then
57+
logInfoAt constStx
58+
m!"'{constName}' is non-classical and depends on axioms: {axioms.toList}"
59+
else
60+
Linter.logLint linter.detectClassical constStx
61+
m!"'{constName}' depends on 'Classical.choice' on axioms: {axioms.toList}"
62+
63+
initialize addLinter detectClassicalLinter
64+
65+
end DetectClassical
66+
67+
end Katydid.Std.Linter

Katydid/Std/Lists.lean

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import Mathlib.Tactic.Linarith
77
import Mathlib.Tactic.SplitIfs
88

9+
import Katydid.Std.Linter.DetectClassical
910
import Katydid.Std.BEq
1011
import Katydid.Std.Ordering
1112
import Katydid.Std.Nat

Katydid/Std/NonEmptyList.lean

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import Katydid.Std.Linter.DetectClassical
12
import Katydid.Std.Ordering
23
import Katydid.Std.Lists
34

lakefile.lean

+10-1
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,17 @@ open Lake DSL
33

44
package katydid
55

6+
abbrev packageLinters : Array LeanOption := #[
7+
`weak.linter.detectClassical, true
8+
]
9+
10+
abbrev packageLeanOptions :=
11+
packageLinters
12+
613
@[default_target]
7-
lean_lib Katydid
14+
lean_lib Katydid where
15+
leanOptions := packageLeanOptions
16+
moreServerOptions := packageLinters
817

918
-- dependencies std4, quote4 are obtained transitively through mathlib4
1019
require mathlib from git "https://github.com/leanprover-community/mathlib4" @ "v4.14.0"

0 commit comments

Comments
 (0)