-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathSupportedFragment.lean
More file actions
319 lines (311 loc) · 13.2 KB
/
SupportedFragment.lean
File metadata and controls
319 lines (311 loc) · 13.2 KB
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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
import Compiler.TypedIRCompilerCorrectness
import Compiler.Proofs.IRGeneration.ExprCore
/-!
Scoped proof-layer support witness for statement lists.
`SupportedStmtList` is now a compositional public grammar: it can expose either
the existing generic compile-core / terminal-core statement grammars directly,
or admit the remaining non-generic singleton / structured statement shapes
through first-class constructors while the generic-core bridge continues to
grow.
-/
namespace Compiler.Proofs.IRGeneration
open Compiler
open Compiler.CompilationModel
open Verity.Core.Free
/-- Scope seen by the tail after compiling a single statement. This matches the
statement-list compiler's `collectStmtNames` update. -/
def stmtNextScope (scope : List String) (stmt : Stmt) : List String :=
collectStmtNames stmt ++ scope
/-- Proof-layer compositional witness for supported statement lists.
The witness is scoped because the generic compile-core grammars track local name
availability explicitly. The remaining non-generic storage / event shapes are
admitted directly as individual constructors so callers can still compose them
with `requireClause`, `ite`, and `append` under the same body interface. -/
inductive SupportedStmtList (fields : List Field) : List String → List Stmt → Prop where
| compileCore
{scope : List String}
{stmts : List Stmt} :
FunctionBody.StmtListCompileCore scope stmts →
SupportedStmtList fields scope stmts
| terminalCore
{scope : List String}
{stmts : List Stmt} :
FunctionBody.StmtListTerminalCore scope stmts →
SupportedStmtList fields scope stmts
| setStorageSingleSlot
{scope : List String}
{fieldName : String}
{value : Expr}
{slot : Nat} :
FunctionBody.ExprCompileCore value →
FunctionBody.exprBoundNamesInScope value scope →
findFieldWithResolvedSlot fields fieldName =
some ({ name := fieldName, ty := FieldType.uint256 }, slot) →
SupportedStmtList fields scope [Stmt.setStorage fieldName value]
| setStorageAddrSingleSlot
{scope : List String}
{fieldName : String}
{value : Expr}
{slot : Nat} :
FunctionBody.ExprCompileCore value →
FunctionBody.exprBoundNamesInScope value scope →
findFieldWithResolvedSlot fields fieldName =
some ({ name := fieldName, ty := FieldType.address }, slot) →
SupportedStmtList fields scope [Stmt.setStorageAddr fieldName value]
| mstoreSingle
{scope : List String}
{offset value : Expr} :
FunctionBody.ExprCompileCore offset →
FunctionBody.exprBoundNamesInScope offset scope →
FunctionBody.ExprCompileCore value →
FunctionBody.exprBoundNamesInScope value scope →
SupportedStmtList fields scope [Stmt.mstore offset value]
| tstoreSingle
{scope : List String}
{offset value : Expr} :
FunctionBody.ExprCompileCore offset →
FunctionBody.exprBoundNamesInScope offset scope →
FunctionBody.ExprCompileCore value →
FunctionBody.exprBoundNamesInScope value scope →
SupportedStmtList fields scope [Stmt.tstore offset value]
| letStorageField
{scope : List String}
{tmp : String}
{fieldName : String}
{field : Field}
{slot : Nat} :
findFieldWithResolvedSlot fields fieldName = some (field, slot) →
SupportedStmtList fields scope [Stmt.letVar tmp (Expr.storage fieldName)]
| returnMapping
{scope : List String}
{fieldName : String}
{key : Expr}
{slot : Nat} :
FunctionBody.ExprCompileCore key →
FunctionBody.exprBoundNamesInScope key scope →
findFieldSlot fields fieldName = some slot →
SupportedStmtList fields scope [Stmt.return (Expr.mapping fieldName key)]
| letMapping
{scope : List String}
{tmp : String}
{fieldName : String}
{key : Expr}
{slot : Nat} :
FunctionBody.ExprCompileCore key →
FunctionBody.exprBoundNamesInScope key scope →
findFieldSlot fields fieldName = some slot →
SupportedStmtList fields scope [Stmt.letVar tmp (Expr.mapping fieldName key)]
| letMapping2
{scope : List String}
{tmp : String}
{fieldName : String}
{key1 key2 : Expr}
{slot : Nat} :
FunctionBody.ExprCompileCore key1 →
FunctionBody.exprBoundNamesInScope key1 scope →
FunctionBody.ExprCompileCore key2 →
FunctionBody.exprBoundNamesInScope key2 scope →
findFieldSlot fields fieldName = some slot →
SupportedStmtList fields scope [Stmt.letVar tmp (Expr.mapping2 fieldName key1 key2)]
| letMappingUint
{scope : List String}
{tmp : String}
{fieldName : String}
{key : Expr}
{slot : Nat} :
FunctionBody.ExprCompileCore key →
FunctionBody.exprBoundNamesInScope key scope →
findFieldSlot fields fieldName = some slot →
SupportedStmtList fields scope [Stmt.letVar tmp (Expr.mappingUint fieldName key)]
| setMappingUintSingle
{scope : List String}
{fieldName : String}
{key value : Expr}
{slot : Nat} :
FunctionBody.ExprCompileCore key →
FunctionBody.exprBoundNamesInScope key scope →
FunctionBody.ExprCompileCore value →
FunctionBody.exprBoundNamesInScope value scope →
findFieldSlot fields fieldName = some slot →
SupportedStmtList fields scope [Stmt.setMappingUint fieldName key value]
| setMappingChainSingle
{scope : List String}
{fieldName : String}
{keys : List Expr}
{value : Expr}
{slot : Nat} :
(∀ key ∈ keys, FunctionBody.ExprCompileCore key) →
(∀ key ∈ keys, FunctionBody.exprBoundNamesInScope key scope) →
FunctionBody.ExprCompileCore value →
FunctionBody.exprBoundNamesInScope value scope →
findFieldSlot fields fieldName = some slot →
SupportedStmtList fields scope [Stmt.setMappingChain fieldName keys value]
| setMappingSingle
{scope : List String}
{fieldName : String}
{key value : Expr}
{slot : Nat} :
FunctionBody.ExprCompileCore key →
FunctionBody.exprBoundNamesInScope key scope →
FunctionBody.ExprCompileCore value →
FunctionBody.exprBoundNamesInScope value scope →
findFieldSlot fields fieldName = some slot →
SupportedStmtList fields scope [Stmt.setMapping fieldName key value]
| setMappingWordSingle
{scope : List String}
{fieldName : String}
{key value : Expr}
{wordOffset slot : Nat} :
FunctionBody.ExprCompileCore key →
FunctionBody.exprBoundNamesInScope key scope →
FunctionBody.ExprCompileCore value →
FunctionBody.exprBoundNamesInScope value scope →
findFieldSlot fields fieldName = some slot →
SupportedStmtList fields scope [Stmt.setMappingWord fieldName key wordOffset value]
| setMappingPackedWordSingle
{scope : List String}
{fieldName : String}
{key value : Expr}
{wordOffset slot : Nat}
{packed : PackedBits} :
FunctionBody.ExprCompileCore key →
FunctionBody.exprBoundNamesInScope key scope →
FunctionBody.ExprCompileCore value →
FunctionBody.exprBoundNamesInScope value scope →
"__compat_value" ∉ scope →
"__compat_packed" ∉ scope →
"__compat_slot_word" ∉ scope →
"__compat_slot_cleared" ∉ scope →
packedBitsValid packed = true →
findFieldSlot fields fieldName = some slot →
SupportedStmtList fields scope
[Stmt.setMappingPackedWord fieldName key wordOffset packed value]
| setStructMemberSingle
{scope : List String}
{fieldName memberName : String}
{key value : Expr}
{slot wordOffset : Nat}
{members : List StructMember} :
FunctionBody.ExprCompileCore key →
FunctionBody.exprBoundNamesInScope key scope →
FunctionBody.ExprCompileCore value →
FunctionBody.exprBoundNamesInScope value scope →
findFieldSlot fields fieldName = some slot →
findStructMembers fields fieldName = some members →
findStructMember members memberName =
some { name := memberName, wordOffset := wordOffset, packed := none } →
SupportedStmtList fields scope [Stmt.setStructMember fieldName key memberName value]
| setMapping2Single
{scope : List String}
{fieldName : String}
{key1 key2 value : Expr}
{slot : Nat} :
FunctionBody.ExprCompileCore key1 →
FunctionBody.exprBoundNamesInScope key1 scope →
FunctionBody.ExprCompileCore key2 →
FunctionBody.exprBoundNamesInScope key2 scope →
FunctionBody.ExprCompileCore value →
FunctionBody.exprBoundNamesInScope value scope →
findFieldSlot fields fieldName = some slot →
SupportedStmtList fields scope [Stmt.setMapping2 fieldName key1 key2 value]
| setMapping2WordSingle
{scope : List String}
{fieldName : String}
{key1 key2 value : Expr}
{wordOffset slot : Nat} :
FunctionBody.ExprCompileCore key1 →
FunctionBody.exprBoundNamesInScope key1 scope →
FunctionBody.ExprCompileCore key2 →
FunctionBody.exprBoundNamesInScope key2 scope →
FunctionBody.ExprCompileCore value →
FunctionBody.exprBoundNamesInScope value scope →
findFieldSlot fields fieldName = some slot →
SupportedStmtList fields scope [Stmt.setMapping2Word fieldName key1 key2 wordOffset value]
| setStructMember2Single
{scope : List String}
{fieldName memberName : String}
{key1 key2 value : Expr}
{slot wordOffset : Nat}
{members : List StructMember} :
FunctionBody.ExprCompileCore key1 →
FunctionBody.exprBoundNamesInScope key1 scope →
FunctionBody.ExprCompileCore key2 →
FunctionBody.exprBoundNamesInScope key2 scope →
FunctionBody.ExprCompileCore value →
FunctionBody.exprBoundNamesInScope value scope →
findFieldSlot fields fieldName = some slot →
findStructMembers fields fieldName = some members →
findStructMember members memberName =
some { name := memberName, wordOffset := wordOffset, packed := none } →
SupportedStmtList fields scope [Stmt.setStructMember2 fieldName key1 key2 memberName value]
| rawLogLiterals
{scope : List String}
{topics : List Nat}
{dataOffset dataSize : Nat} :
topics.length ≤ 4 →
SupportedStmtList fields scope
[Stmt.rawLog (topics.map Expr.literal) (Expr.literal dataOffset) (Expr.literal dataSize)]
| letCallerLetStorageReqEqReqNeqSetStorageParamStop
{scope : List String}
{ownerField senderVar ownerVar paramName msg1 msg2 : String}
{ownerSlot : Nat} :
findFieldWithResolvedSlot fields ownerField =
some ({ name := ownerField, ty := FieldType.address }, ownerSlot) →
senderVar ≠ paramName →
ownerVar ≠ paramName →
ownerVar ≠ senderVar →
SupportedStmtList fields scope
[ Stmt.letVar senderVar Expr.caller
, Stmt.letVar ownerVar (Expr.storage ownerField)
, Stmt.require (Expr.eq (Expr.localVar senderVar) (Expr.localVar ownerVar)) msg1
, Stmt.require
(Expr.logicalNot (Expr.eq (Expr.param paramName) (Expr.localVar ownerVar))) msg2
, Stmt.setStorage ownerField (Expr.param paramName)
, Stmt.stop
]
| letCallerLetStorageReqEqLetStorageReqNeqSetStorageParamStop
{scope : List String}
{ownerField targetField senderVar ownerVar targetVar paramName msg1 msg2 : String}
{ownerSlot targetSlot : Nat} :
findFieldWithResolvedSlot fields ownerField =
some ({ name := ownerField, ty := FieldType.address }, ownerSlot) →
findFieldWithResolvedSlot fields targetField =
some ({ name := targetField, ty := FieldType.address }, targetSlot) →
senderVar ≠ paramName →
ownerVar ≠ paramName →
ownerVar ≠ senderVar →
targetVar ≠ paramName →
targetVar ≠ senderVar →
targetVar ≠ ownerVar →
SupportedStmtList fields scope
[ Stmt.letVar senderVar Expr.caller
, Stmt.letVar ownerVar (Expr.storage ownerField)
, Stmt.require (Expr.eq (Expr.localVar senderVar) (Expr.localVar ownerVar)) msg1
, Stmt.letVar targetVar (Expr.storage targetField)
, Stmt.require
(Expr.logicalNot (Expr.eq (Expr.param paramName) (Expr.localVar targetVar))) msg2
, Stmt.setStorage targetField (Expr.param paramName)
, Stmt.stop
]
| requireClause
{scope : List String}
(clause : RequireLiteralGuardFamilyClause)
{rest : List Stmt} :
SupportedStmtList fields scope rest →
SupportedStmtList fields scope (clause.toStmt :: rest)
| ite
{scope : List String}
{cond : Expr}
{thenBranch elseBranch : List Stmt} :
FunctionBody.ExprCompileCore cond →
FunctionBody.exprBoundNamesInScope cond scope →
SupportedStmtList fields scope thenBranch →
SupportedStmtList fields scope elseBranch →
SupportedStmtList fields scope [Stmt.ite cond thenBranch elseBranch]
| append
{scope : List String}
{pfx sfx : List Stmt} :
SupportedStmtList fields scope pfx →
SupportedStmtList fields (List.foldl stmtNextScope scope pfx) sfx →
SupportedStmtList fields scope (pfx ++ sfx)
end Compiler.Proofs.IRGeneration