Skip to content

Commit 8f60c0f

Browse files
committed
Fixed ComparisonNetwork.toPerm
1 parent 7e6e5f0 commit 8f60c0f

File tree

1 file changed

+56
-17
lines changed

1 file changed

+56
-17
lines changed

RecMath/SortingNetwork.lean

Lines changed: 56 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ variable {α : Type u} [LinearOrder α] {n : Nat}
1212

1313
def Tuple (α n) := Fin n -> α
1414

15+
16+
1517
-- Not using these anymore, but i can change my definitoins to use them if wanted
1618
-- def Sorted (t : Tuple α n) : Prop := Monotone t
1719
-- def SortingFunction (f : Tuple α n -> Tuple α n) : Prop := ∀ (t : Tuple α n), Sorted (f t)
@@ -46,24 +48,34 @@ theorem IndexPair.permute.involutive {p : IndexPair n} {t : Tuple α n}
4648
: Function.Involutive (p.permute t) := by
4749
grind only [Function.Involutive, permute]
4850

49-
def IndexPair.toPerm (t : Tuple α n) (p : IndexPair n) : Equiv.Perm (Fin n) where
50-
toFun := p.permute t
51-
invFun := p.permute t
52-
left_inv k := by
53-
change (p.permute t ∘ p.permute t) k = k
54-
rw [Function.Involutive.comp_self IndexPair.permute.involutive, id]
55-
right_inv k := by
56-
change (p.permute t ∘ p.permute t) k = k
57-
rw [Function.Involutive.comp_self IndexPair.permute.involutive, id]
51+
-- def IndexPair.toPerm (t : Tuple α n) (p : IndexPair n) : Equiv.Perm (Fin n) where
52+
-- toFun := p.permute t
53+
-- invFun := p.permute t
54+
-- left_inv k := by
55+
-- change (p.permute t ∘ p.permute t) k = k
56+
-- rw [Function.Involutive.comp_self IndexPair.permute.involutive, id]
57+
-- right_inv k := by
58+
-- change (p.permute t ∘ p.permute t) k = k
59+
-- rw [Function.Involutive.comp_self IndexPair.permute.involutive, id]
60+
61+
def IndexPair.toPerm (t : Tuple α n) (p : IndexPair n) : Equiv.Perm (Fin n) :=
62+
if t p.i ≤ t p.j then
63+
1
64+
else
65+
Equiv.swap p.i p.j
5866

59-
def IndexPair.apply (p : IndexPair n) (t : Tuple α n) : Tuple α n := t ∘ p.permute t
67+
def IndexPair.apply (p : IndexPair n) (t : Tuple α n) : Tuple α n := t ∘ p.toPerm t
6068

6169
-- I dont know what to call this lemma, it needs a better name
6270
theorem IndexPair.apply.asdf (p : IndexPair n) (t : Tuple α n)
6371
: p.apply t p.i ≤ p.apply t p.j := by
6472
obtain ⟨i, j, hp⟩ := p
65-
simp [apply, Function.comp, permute, ↓reduceIte]
66-
grind only [le_of_not_ge]
73+
simp [apply, Function.comp, toPerm]
74+
split
75+
· simpa! only [Equiv.refl_apply]
76+
· rename_i h
77+
simp only [Equiv.swap_apply_left, Equiv.swap_apply_right]
78+
exact le_of_not_ge h
6779

6880
theorem IndexPair.apply.monotoneOn_ij (p : IndexPair n) (t : Tuple α n) :
6981
MonotoneOn (p.apply t) {p.i, p.j} := by
@@ -75,17 +87,28 @@ theorem IndexPair.apply.monotoneOn_ij (p : IndexPair n) (t : Tuple α n) :
7587
subst i_eq_a j_eq_b
7688
exact asdf p t
7789

78-
7990
def ComparisonNetwork (n : Nat) := List (IndexPair n)
8091

81-
def ComparisonNetwork.nil : ComparisonNetwork n := []
92+
-- -- This definition is not needed yet
93+
-- def ComparisonNetwork.nil : ComparisonNetwork n := []
8294

8395
def ComparisonNetwork.toPerm (t : Tuple α n) (net : ComparisonNetwork n) : Equiv.Perm (Fin n) :=
84-
net.map (IndexPair.toPerm t) |> List.foldl Equiv.trans (Equiv.refl _)
96+
net.foldr (fun p e => (p.toPerm (t ∘ e)).trans e) 1
8597

8698
def ComparisonNetwork.apply (net : ComparisonNetwork n) (t : Tuple α n) : Tuple α n :=
8799
t ∘ net.toPerm t
88100

101+
-- This proof ensures that the ComparisonNetwork.toPerm implementation is correct
102+
theorem ComparisonNetwork.apply_eq_foldr_apply (net : ComparisonNetwork n) (t : Tuple α n) :
103+
net.apply t = net.foldr IndexPair.apply t := by
104+
rw [apply, toPerm]
105+
induction net with
106+
| nil => rw [List.foldr, Equiv.Perm.coe_one, CompTriple.comp_eq, List.foldr]
107+
| cons p net h =>
108+
rw [List.foldr_cons, List.foldr_cons, <- h, IndexPair.apply]
109+
rw [Equiv.coe_trans, Function.comp_assoc]
110+
111+
89112
def ComparisonNetwork.Sorts (net : ComparisonNetwork n) : Prop :=
90113
{α : Type u} -> [LinearOrder α] -> (t : Tuple α n) -> Monotone (net.apply t)
91114

@@ -95,15 +118,31 @@ def ComparisonNetwork.trivial_network : ComparisonNetwork 2 := [IndexPair.mk 0 1
95118

96119
theorem ComparisonNetwork.trivial_network_sorts : trivial_network.Sorts := by
97120
intro α _ t a b a_le_b
98-
simp [trivial_network, apply, toPerm, IndexPair.toPerm, IndexPair.permute]
99-
grind only [le_refl, le_of_not_ge]
121+
simp [trivial_network, apply, toPerm, IndexPair.toPerm]
122+
by_cases a_eq_b : a = b
123+
· subst_vars; rfl
124+
split
125+
· simp
126+
grind only
127+
· have ⟨a0, b1⟩ : a = 0 ∧ b = 1 := by omega
128+
subst a0 b1
129+
simp
130+
order
100131

101132
#eval ComparisonNetwork.trivial_network.apply ![3, 2]
102133
#eval ComparisonNetwork.trivial_network.apply ![1, 2]
103134

135+
def net3 : ComparisonNetwork 3 :=
136+
[IndexPair.mk 0 1 (by decide), IndexPair.mk 1 2 (by decide), IndexPair.mk 0 1 (by decide)]
137+
138+
#eval net3.apply ![8, 9, 2]
139+
140+
104141
-- [x] Sorting networks can be lists of index pair
105142
-- [x] Need some sort of proposition that says a network sorts
106143
-- [ ] Forms a setoid with an equivalence for reordering independent pairs
107144

108145
-- [x] i can write a function with a given tuple forms a permutation (ComparisonNetwork.toPerm)
109146
-- [x] which can be applied to the tuple `ComparisonNetwork.apply`
147+
148+
-- [ ] Array oriented API using Vector.swap

0 commit comments

Comments
 (0)