-
Notifications
You must be signed in to change notification settings - Fork 29
/
PrismaticSet.lean
185 lines (143 loc) · 6.56 KB
/
PrismaticSet.lean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
import SciLean.Data.Mesh.Prism
namespace SciLean
open Prism
/-- Generalization of semi-simplicial set(also callsed Δ-set).
It is not generalization of simplicial set as it does not have degenerate prisms.
Categorical view
================
`PrismaticSet` is a presheaf on the catogory of `Prism`. The `Elem` function maps prisms to types. The `face` function maps prism inclusion to functions between types `Elem P`.
-/
structure PrismaticSet where
/-- Index set for Elems of type `P` -/
Elem (P : Prism) : Type
/-- Face of `e` of type `Q` given an inclusion of `Q` to `P` -/
face {Q P} (f : Inclusion Q P) (e : Elem P) : Elem Q
-- Contravariant functoriality - i.e. PrismaticSet is a presheaf
face_comp {P Q S : Prism} : ∀ (f : Inclusion Q P) (g : Inclusion S Q),
(face (f ∘ g)) = face g ∘ face f
namespace PrismaticSet
/-- Coface interface of a prismatic set.
The `coface` function is not included in `PrismaticSet` as it is not always necessary and computing all the neighbouring information can be costly.
Categorical view
================
What is the categorical point of view of `coface`? Maybe adjunction of something? I don't know. Figuring this out might improve the interface and make it more composable.
-/
class Coface (S : PrismaticSet) where
-- Index set for cofaces of `e` of type `Q`
CofaceIndex {Q} (e : S.Elem Q) (P : Prism) : Type
/-- Coface is a -/
coface {Q} {e : S.Elem Q} {P : Prism} : CofaceIndex e P → Inclusion Q P × S.Elem P
-- consitency between face and coface
face_coface : ∀ (e : S.Elem Q) (P : Prism) (i : CofaceIndex e P),
Function.uncurry S.face (coface i) = e
abbrev CofaceIndex (S : PrismaticSet) [Coface S] {Q} (e : S.Elem Q) (P : Prism)
:= Coface.CofaceIndex e P
abbrev coface (S : PrismaticSet) [Coface S] {Q} {e : S.Elem Q} {P} (id : S.CofaceIndex e P)
:= Coface.coface id
abbrev pointCount (S : PrismaticSet) [Enumtype (S.Elem point)] := numOf (S.Elem point)
abbrev edgeCount (S : PrismaticSet) [Enumtype (S.Elem segment)] := numOf (S.Elem segment)
abbrev triangleCount (S : PrismaticSet) [Enumtype (S.Elem triangle)] := numOf (S.Elem triangle)
-- TODO:
-- 1. product
-- 1. sum
-- 2. quotient -- decidable equality? that is probably the hardest thing
-- 3. caching -- stamps out face maps to index arrays
-- explicit boundary maps -- potential for computing homologies
structure ProdElem (P : Prism) (Elem₁ Elem₂ : Prism → Type) where
dec : PrismDecomposition P
fst : Elem₁ dec.fst
snd : Elem₂ dec.snd
instance [∀ P, Iterable (Elem₁ P)] [∀ P, Iterable (Elem₂ P)]
: Iterable (PrismaticSet.ProdElem P Elem₁ Elem₂) :=
{
first := Id.run do
for dec in Iterable.fullRange (PrismDecomposition P) do
match Iterable.first (ι := Elem₁ dec.fst), Iterable.first (ι := Elem₂ dec.snd) with
| some fst, some snd => return (some ⟨dec, fst, snd⟩)
| _, _ => continue
none
next := λ elem =>
match Iterable.next elem.snd with
| some snd' => some ⟨elem.dec, elem.fst, snd'⟩
| none =>
match (Iterable.next elem.fst), (Iterable.first (ι := Elem₂ elem.dec.snd)) with
| some fst', some snd' => some ⟨elem.dec, fst', snd'⟩
| _, _ =>
match Iterable.next elem.dec with
| some dec => Id.run do
let range : Iterable.LinRange (PrismDecomposition P) := some (dec, none)
for dec' in range do
match Iterable.first (ι := Elem₁ dec'.fst), Iterable.first (ι := Elem₂ dec'.snd) with
| some fst', some snd' => return (some ⟨dec', fst', snd'⟩)
| _, _ => continue
none
| none => none
decEq := λ elem elem' =>
if h : elem.dec = elem'.dec
then if
elem.fst = (h ▸ elem'.fst) ∧
elem.snd = (h ▸ elem'.snd)
then
isTrue sorry_proof
else
isFalse sorry_proof
else
isFalse sorry_proof
}
instance [∀ P, Enumtype (Elem₁ P)] [∀ P, Enumtype (Elem₂ P)]
: Enumtype (PrismaticSet.ProdElem P Elem₁ Elem₂) :=
{
numOf := ∑ dec : PrismDecomposition P, numOf (Elem₁ dec.fst) * numOf (Elem₂ dec.snd)
toFin := λ e => Id.run do
let mut N := 0
for dec in Iterable.fullRange (PrismDecomposition P) do
if dec = e.dec then
break
else
N += numOf (Elem₁ dec.fst) * numOf (Elem₂ dec.snd)
-- let N := ∑ dec < e.dec, numOf (Elem₁ dec.fst) * numOf (Elem₂ dec.snd)
⟨(toFin e.fst).1 * numOf (Elem₂ e.dec.snd) + (toFin e.snd).1 + N, sorry_proof⟩
fromFin := λ i => Id.run do
let mut id : Nat := i.1
for dec in Iterable.fullRange (PrismDecomposition P) do
let N₁ := numOf (Elem₁ dec.fst)
let N₂ := numOf (Elem₂ dec.fst)
let N := N₁ * N₂
if id < N then
let i := id / N₂
let j := id % N₂
return ⟨dec, fromFin ⟨i,sorry_proof⟩, fromFin ⟨j,sorry_proof⟩⟩
else
id -= N
absurd (a:= True) sorry_proof sorry_proof -- This should not happed
first_fromFin := sorry_proof
next_fromFin := sorry_proof
next_toFin := sorry_proof
}
def prod (S₁ S₂ : PrismaticSet) : PrismaticSet :=
{
Elem := λ P => ProdElem P S₁.Elem S₂.Elem
face := λ ι e =>
let ιDec := ι.split e.dec
let (ι₁,ι₂) := ιDec.2
-- dbg_trace s!"{ι₁.repr} | {ι₂.repr}"
⟨ιDec.1, S₁.face ι₁ e.fst, S₂.face ι₂ e.snd⟩
-- ⟨ιDec.1, cast sorry 0, cast sorry 0⟩
face_comp := sorry_proof
}
instance (S₁ S₂ : PrismaticSet) [Coface S₁] [Coface S₂] : Coface (S₁.prod S₂) where
CofaceIndex := λ e P => ProdElem P (S₁.CofaceIndex e.fst) (S₂.CofaceIndex e.snd)
coface := λ {Q _ P} ⟨dec, f₁', f₂'⟩ =>
let (ι₁, e₁) := S₁.coface f₁'
let (ι₂, e₂) := S₂.coface f₂'
let ι : Inclusion Q P := ⟨(ι₁.repr.prod ι₂.repr).toCanonical, sorry_proof, sorry_proof⟩
let e : ProdElem P _ _ := ⟨dec, e₁, e₂⟩
(ι, e)
face_coface := sorry_proof
instance (S₁ S₂ : PrismaticSet) [∀ P, Enumtype (S₁.Elem P)] [∀ P, Enumtype (S₂.Elem P)] (P : Prism)
: Enumtype ((PrismaticSet.prod S₁ S₂).Elem P) := by unfold PrismaticSet.prod; infer_instance
instance (S₁ S₂ : PrismaticSet) [Coface S₁] [Coface S₂]
[∀ Q (e : S₁.Elem Q) P, Enumtype (S₁.CofaceIndex e P)]
[∀ Q (e : S₂.Elem Q) P, Enumtype (S₂.CofaceIndex e P)]
(Q) (e : (PrismaticSet.prod S₁ S₂).Elem Q) (P)
: Enumtype ((PrismaticSet.prod S₁ S₂).CofaceIndex e P) := by unfold PrismaticSet.prod; unfold PrismaticSet.CofaceIndex; simp[Coface.CofaceIndex]; infer_instance