Skip to content
This repository was archived by the owner on Oct 25, 2023. It is now read-only.

Commit 8621324

Browse files
committed
refactor: add LawfulCmpEq + post-PR cleanup
1 parent 9156ae6 commit 8621324

File tree

5 files changed

+106
-114
lines changed

5 files changed

+106
-114
lines changed

Diff for: Lake/Build/Data.lean

+5-5
Original file line numberDiff line numberDiff line change
@@ -75,28 +75,28 @@ abbrev BuildData : BuildKey → Type
7575
scoped macro (name := packageDataDecl) doc?:optional(Parser.Command.docComment)
7676
"package_data " id:ident " : " ty:term : command => do
7777
let dty := mkCIdentFrom (← getRef) ``PackageData
78-
let key := Lake.quoteNameFrom id id.getId
78+
let key := Name.quoteFrom id id.getId
7979
`($[$doc?]? family_def $id : $dty $key := $ty)
8080

8181
/-- Macro for declaring new `ModuleData`. -/
8282
scoped macro (name := moduleDataDecl) doc?:optional(Parser.Command.docComment)
8383
"module_data " id:ident " : " ty:term : command => do
8484
let dty := mkCIdentFrom (← getRef) ``ModuleData
85-
let key := Lake.quoteNameFrom id id.getId
85+
let key := Name.quoteFrom id id.getId
8686
`($[$doc?]? family_def $id : $dty $key := $ty)
8787

8888
/-- Macro for declaring new `TargetData`. -/
8989
scoped macro (name := targetDataDecl) doc?:optional(Parser.Command.docComment)
9090
"target_data " id:ident " : " ty:term : command => do
9191
let dty := mkCIdentFrom (← getRef) ``TargetData
92-
let key := Lake.quoteNameFrom id id.getId
92+
let key := Name.quoteFrom id id.getId
9393
`($[$doc?]? family_def $id : $dty $key := $ty)
9494

9595
/-- Macro for declaring new `CustomData`. -/
9696
scoped macro (name := customDataDecl) doc?:optional(Parser.Command.docComment)
9797
"custom_data " pkg:ident tgt:ident " : " ty:term : command => do
9898
let dty := mkCIdentFrom (← getRef) ``CustomData
9999
let id := mkIdentFrom tgt (pkg.getId ++ tgt.getId)
100-
let pkg := Lake.quoteNameFrom pkg pkg.getId
101-
let tgt := Lake.quoteNameFrom pkg tgt.getId
100+
let pkg := Name.quoteFrom pkg pkg.getId
101+
let tgt := Name.quoteFrom pkg tgt.getId
102102
`($[$doc?]? family_def $id : $dty ($pkg, $tgt) := $ty)

Diff for: Lake/Build/Key.lean

+2-1
Original file line numberDiff line numberDiff line change
@@ -99,5 +99,6 @@ quickCmp k k' = Ordering.eq → k = k' := by
9999
next => intro; contradiction
100100
all_goals (intro; contradiction)
101101

102-
instance : EqOfCmp BuildKey quickCmp where
102+
instance : LawfulCmpEq BuildKey quickCmp where
103103
eq_of_cmp := eq_of_quickCmp
104+
cmp_rfl {k} := by cases k <;> simp [quickCmp]

Diff for: Lake/DSL/Facets.lean

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ kw:"module_facet " sig:simpleDeclSig : command => do
2222
let attr ← withRef kw `(Term.attrInstance| moduleFacet)
2323
let attrs := #[attr] ++ expandAttrs attrs?
2424
let axm := mkIdentFrom id <| ``ModuleData ++ id.getId
25-
let name := Lake.quoteNameFrom id id.getId
25+
let name := Name.quoteFrom id id.getId
2626
`(module_data $id : ActiveBuildTarget $ty
2727
$[$doc?]? @[$attrs,*] def $id : ModuleFacetDecl := {
2828
name := $name
@@ -43,7 +43,7 @@ kw:"package_facet " sig:simpleDeclSig : command => do
4343
let attr ← withRef kw `(Term.attrInstance| packageFacet)
4444
let attrs := #[attr] ++ expandAttrs attrs?
4545
let axm := mkIdentFrom id <| ``PackageData ++ id.getId
46-
let name := Lake.quoteNameFrom id id.getId
46+
let name := Name.quoteFrom id id.getId
4747
`(package_data $id : ActiveBuildTarget $ty
4848
$[$doc?]? @[$attrs,*] def $id : PackageFacetDecl := {
4949
name := $name
@@ -64,7 +64,7 @@ kw:"target " sig:simpleDeclSig : command => do
6464
let attr ← withRef kw `(Term.attrInstance| target)
6565
let attrs := #[attr] ++ expandAttrs attrs?
6666
let axm := mkIdentFrom id <| ``CustomData ++ id.getId
67-
let name := Lake.quoteNameFrom id id.getId
67+
let name := Name.quoteFrom id id.getId
6868
let pkgName := mkIdentFrom id `_package.name
6969
`(family_def $id : CustomData ($pkgName, $name) := ActiveBuildTarget $ty
7070
$[$doc?]? @[$attrs,*] def $id : TargetConfig := {

Diff for: Lake/Util/Compare.lean

+62-47
Original file line numberDiff line numberDiff line change
@@ -7,89 +7,104 @@ Authors: Mac Malone
77
namespace Lake
88

99
/--
10-
Proof that that equality of a compare function corresponds
10+
Proof that the equality of a compare function corresponds
1111
to propositional equality.
1212
-/
1313
class EqOfCmp (α : Type u) (cmp : α → α → Ordering) where
14-
eq_of_cmp {a a' : α} : cmp a a' = Ordering.eq → a = a'
14+
eq_of_cmp {a a' : α} : cmp a a' = .eq → a = a'
1515

1616
export EqOfCmp (eq_of_cmp)
1717

1818
/--
19-
Proof that that equality of a compare function corresponds
19+
Proof that the equality of a compare function corresponds
20+
to propositional equality and vice versa.
21+
-/
22+
class LawfulCmpEq (α : Type u) (cmp : α → α → Ordering) extends EqOfCmp α cmp where
23+
cmp_rfl {a : α} : cmp a a = .eq
24+
25+
export LawfulCmpEq (cmp_rfl)
26+
27+
attribute [simp] cmp_rfl
28+
29+
@[simp] theorem cmp_iff_eq [LawfulCmpEq α cmp] : cmp a a' = .eq ↔ a = a' :=
30+
Iff.intro eq_of_cmp fun a_eq => a_eq ▸ cmp_rfl
31+
32+
/--
33+
Proof that the equality of a compare function corresponds
2034
to propositional equality with respect to a given function.
2135
-/
2236
class EqOfCmpWrt (α : Type u) {β : Type v} (f : α → β) (cmp : α → α → Ordering) where
23-
eq_of_cmp_wrt {a a' : α} : cmp a a' = Ordering.eq → f a = f a'
37+
eq_of_cmp_wrt {a a' : α} : cmp a a' = .eq → f a = f a'
2438

2539
export EqOfCmpWrt (eq_of_cmp_wrt)
2640

41+
instance : EqOfCmpWrt α (fun _ => α) cmp := ⟨fun _ => rfl⟩
42+
2743
instance [EqOfCmp α cmp] : EqOfCmpWrt α f cmp where
2844
eq_of_cmp_wrt h := by rw [eq_of_cmp h]
2945

30-
instance [EqOfCmpWrt α id cmp] : EqOfCmp α cmp where
31-
eq_of_cmp h := eq_of_cmp_wrt (f := id) h
32-
3346
instance [EqOfCmpWrt α (fun a => a) cmp] : EqOfCmp α cmp where
3447
eq_of_cmp h := eq_of_cmp_wrt (f := fun a => a) h
3548

36-
instance : EqOfCmpWrt α (fun _ => α) cmp := ⟨fun _ => rfl⟩
3749

38-
theorem eq_of_compareOfLessAndEq
39-
{a a' : α} [LT α] [DecidableEq α] [Decidable (a < a')]
40-
(h : compareOfLessAndEq a a' = Ordering.eq) : a = a' := by
50+
-- ## Basic Instances
51+
52+
theorem eq_of_compareOfLessAndEq [LT α] [DecidableEq α] {a a' : α}
53+
[Decidable (a < a')] (h : compareOfLessAndEq a a' = .eq) : a = a' := by
4154
unfold compareOfLessAndEq at h
4255
split at h; case inl => exact False.elim h
4356
split at h; case inr => exact False.elim h
4457
assumption
4558

46-
theorem Nat.eq_of_compare
47-
{n n' : Nat} : compare n n' = Ordering.eq → n = n' := by
48-
simp only [compare]; exact eq_of_compareOfLessAndEq
59+
theorem compareOfLessAndEq_rfl [LT α] [DecidableEq α] {a : α}
60+
[Decidable (a < a)] (lt_irrefl : ¬ a < a) : compareOfLessAndEq a a = .eq := by
61+
simp [compareOfLessAndEq, lt_irrefl]
4962

50-
@[simp]
51-
theorem Nat.compare_iff_eq
52-
{n n' : Nat} : compare n n' = Ordering.eq ↔ n = n' := by
53-
refine ⟨eq_of_compare, fun h => ?_⟩
54-
simp [h, compare, compareOfLessAndEq]
63+
instance : LawfulCmpEq Nat compare where
64+
eq_of_cmp := eq_of_compareOfLessAndEq
65+
cmp_rfl := compareOfLessAndEq_rfl <| Nat.lt_irrefl _
5566

56-
instance : EqOfCmp Nat compare where
57-
eq_of_cmp h := Nat.eq_of_compare h
67+
theorem Fin.eq_of_compare {n n' : Fin m} (h : compare n n' = .eq) : n = n' := by
68+
dsimp only [compare] at h
69+
have h' := eq_of_compareOfLessAndEq h
70+
exact Fin.eq_of_val_eq h'
5871

59-
theorem String.eq_of_compare
60-
{s s' : String} : compare s s' = Ordering.eq → s = s' := by
61-
simp only [compare]; exact eq_of_compareOfLessAndEq
72+
instance : LawfulCmpEq (Fin n) compare where
73+
eq_of_cmp := Fin.eq_of_compare
74+
cmp_rfl := compareOfLessAndEq_rfl <| Nat.lt_irrefl _
75+
76+
instance : LawfulCmpEq UInt64 compare where
77+
eq_of_cmp h := eq_of_compareOfLessAndEq h
78+
cmp_rfl := compareOfLessAndEq_rfl <| Nat.lt_irrefl _
6279

6380
theorem List.lt_irrefl [LT α] (irrefl_α : ∀ a : α, ¬ a < a)
6481
: (a : List α) → ¬ a < a
65-
| _, .head _ _ h => irrefl_α _ h
66-
| _, .tail _ _ h3 => lt_irrefl irrefl_α _ h3
82+
| _, .head _ _ h => irrefl_α _ h
83+
| _, .tail _ _ h3 => lt_irrefl irrefl_α _ h3
6784

68-
@[simp]
69-
theorem String.lt_irrefl (s : String) : ¬ s < s :=
85+
@[simp] theorem String.lt_irrefl (s : String) : ¬ s < s :=
7086
List.lt_irrefl (fun c => Nat.lt_irrefl c.1.1) _
7187

72-
@[simp]
73-
theorem String.compare_iff_eq
74-
{n n' : String} : compare n n' = Ordering.eq ↔ n = n' := by
75-
refine ⟨eq_of_compare, fun h => ?_⟩
76-
simp [h, compare, compareOfLessAndEq]
77-
78-
instance : EqOfCmp String compare where
79-
eq_of_cmp h := String.eq_of_compare h
88+
instance : LawfulCmpEq String compare where
89+
eq_of_cmp := eq_of_compareOfLessAndEq
90+
cmp_rfl := compareOfLessAndEq_rfl <| String.lt_irrefl _
8091

81-
@[inline]
92+
@[macroInline]
8293
def Option.compareWith (cmp : α → α → Ordering) : Option α → Option α → Ordering
83-
| none, none => Ordering.eq
84-
| none, some _ => Ordering.lt
85-
| some _, none => Ordering.gt
94+
| none, none => .eq
95+
| none, some _ => .lt
96+
| some _, none => .gt
8697
| some x, some y => cmp x y
8798

88-
theorem Option.eq_of_compareWith [EqOfCmp α cmp]
89-
{o o' : Option α} : compareWith cmp o o' = Ordering.eq → o = o' := by
90-
unfold compareWith
91-
cases o <;> cases o' <;> simp
92-
exact eq_of_cmp
93-
9499
instance [EqOfCmp α cmp] : EqOfCmp (Option α) (Option.compareWith cmp) where
95-
eq_of_cmp h := Option.eq_of_compareWith h
100+
eq_of_cmp := by
101+
intro o o'
102+
unfold Option.compareWith
103+
cases o <;> cases o' <;> simp
104+
exact eq_of_cmp
105+
106+
instance [LawfulCmpEq α cmp] : LawfulCmpEq (Option α) (Option.compareWith cmp) where
107+
cmp_rfl := by
108+
intro o
109+
unfold Option.compareWith
110+
cases o <;> simp

Diff for: Lake/Util/Name.lean

+34-58
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export Lean (Name NameMap)
1515
-- # Name Helpers
1616

1717
namespace Name
18+
open Lean.Name
1819

1920
def ofString (str : String) : Name :=
2021
str.splitOn "." |>.foldl (fun n p => .str n p.trim) .anonymous
@@ -23,70 +24,45 @@ def ofString (str : String) : Name :=
2324
rw [← beq_iff_eq m n]; cases m == n <;> simp
2425

2526
@[simp] theorem isPrefixOf_self {n : Name} : n.isPrefixOf n := by
26-
cases n <;> simp [Name.isPrefixOf]
27+
cases n <;> simp [isPrefixOf]
2728

2829
@[simp] theorem isPrefixOf_append {n m : Name} : n.isPrefixOf (n ++ m) := by
2930
show n.isPrefixOf (n.append m)
30-
induction m <;> simp [Name.isPrefixOf, Name.append, *]
31-
32-
attribute [local simp] Name.quickCmpAux
33-
34-
@[simp]
35-
theorem quickCmpAux_iff_eq : ∀ n n', Name.quickCmpAux n n' = Ordering.eq ↔ n = n'
36-
| .anonymous, n => by cases n <;> simp
37-
| n, .anonymous => by cases n <;> simp
38-
| .num .., .str .. => by simp
39-
| .str .., .num .. => by simp
40-
| .num p₁ n₁, .num p₂ n₂ => by
41-
simp only [Name.quickCmpAux]; split <;>
42-
simp_all [quickCmpAux_iff_eq p₁ p₂, show ∀ p, (p → False) ↔ ¬ p from fun _ => .rfl]
43-
| .str p₁ s₁, .str p₂ s₂ => by
44-
simp only [Name.quickCmpAux]; split <;>
45-
simp_all [quickCmpAux_iff_eq p₁ p₂, show ∀ p, (p → False) ↔ ¬ p from fun _ => .rfl]
46-
47-
theorem eq_of_quickCmpAux (n n') : Name.quickCmpAux n n' = Ordering.eq → n = n' :=
48-
(quickCmpAux_iff_eq n n').1
49-
50-
end Name
51-
52-
-- # Subtype Helpers
53-
54-
namespace Subtype
55-
56-
theorem val_eq_of_eq {a b : Subtype p} (h : a = b) : a.val = b.val :=
57-
h ▸ rfl
58-
59-
theorem eq_of_val_eq : ∀ {a b : Subtype p}, a.val = b.val → a = b
60-
| ⟨_, _⟩, ⟨_, _⟩, rfl => rfl
61-
62-
theorem eq_iff_val_eq {a b : Subtype p} : a = b ↔ a.val = b.val :=
63-
Iff.intro val_eq_of_eq eq_of_val_eq
64-
65-
theorem ne_of_val_ne {a b : Subtype p} (h : a.val ≠ b.val) : a ≠ b :=
66-
fun h' => absurd (val_eq_of_eq h') h
67-
68-
theorem val_ne_of_ne {a b : Subtype p} (h : a ≠ b) : a.val ≠ b.val :=
69-
fun h' => absurd (eq_of_val_eq h') h
70-
71-
theorem ne_iff_val_ne {a b : Subtype p} : a ≠ b ↔ a.val ≠ b.val :=
72-
Iff.intro val_ne_of_ne ne_of_val_ne
73-
74-
end Subtype
75-
76-
theorem eq_of_quickCmp {n n' : Name} : n.quickCmp n' = Ordering.eq → n = n' := by
77-
simp only [Lean.Name.quickCmp, Name.quickCmp, Subtype.eq_iff_val_eq]
31+
induction m <;> simp [isPrefixOf, Name.append, *]
32+
33+
@[simp] theorem quickCmpAux_iff_eq : ∀ {n n'}, quickCmpAux n n' = .eq ↔ n = n'
34+
| .anonymous, n => by cases n <;> simp [quickCmpAux]
35+
| n, .anonymous => by cases n <;> simp [quickCmpAux]
36+
| .num .., .str .. => by simp [quickCmpAux]
37+
| .str .., .num .. => by simp [quickCmpAux]
38+
| .num p₁ n₁, .num p₂ n₂ => by
39+
simp only [quickCmpAux]; split <;>
40+
simp_all [quickCmpAux_iff_eq, show ∀ p, (p → False) ↔ ¬ p from fun _ => .rfl]
41+
| .str p₁ s₁, .str p₂ s₂ => by
42+
simp only [quickCmpAux]; split <;>
43+
simp_all [quickCmpAux_iff_eq, show ∀ p, (p → False) ↔ ¬ p from fun _ => .rfl]
44+
45+
instance : LawfulCmpEq Name quickCmpAux where
46+
eq_of_cmp := quickCmpAux_iff_eq.mp
47+
cmp_rfl := quickCmpAux_iff_eq.mpr rfl
48+
49+
theorem eq_of_quickCmp {n n' : Name} : n.quickCmp n' = .eq → n = n' := by
50+
unfold Name.quickCmp
7851
intro h_cmp; split at h_cmp
79-
next => exact Name.eq_of_quickCmpAux n n' h_cmp
52+
next => exact eq_of_cmp h_cmp
8053
next => contradiction
8154

82-
instance : EqOfCmp Name Name.quickCmp where
83-
eq_of_cmp h := eq_of_quickCmp h
55+
theorem quickCmp_rfl {n : Name} : n.quickCmp n = .eq := by
56+
unfold Name.quickCmp
57+
split <;> exact cmp_rfl
58+
59+
instance : LawfulCmpEq Name Name.quickCmp where
60+
eq_of_cmp := eq_of_quickCmp
61+
cmp_rfl := quickCmp_rfl
8462

8563
open Syntax
8664

87-
def quoteNameFrom (ref : Syntax) : Name → Term
88-
| .anonymous => mkCIdentFrom ref ``Name.anonymous
89-
| .str p s => mkApp (mkCIdentFrom ref ``Name.mkStr)
90-
#[quoteNameFrom ref p, quote s]
91-
| .num p v => mkApp (mkCIdentFrom ref ``Name.mkNum)
92-
#[quoteNameFrom ref p, quote v]
65+
def quoteFrom (ref : Syntax) : Name → Term
66+
| .anonymous => mkCIdentFrom ref ``anonymous
67+
| .str p s => mkApp (mkCIdentFrom ref ``mkStr) #[quoteFrom ref p, quote s]
68+
| .num p v => mkApp (mkCIdentFrom ref ``mkNum) #[quoteFrom ref p, quote v]

0 commit comments

Comments
 (0)