Skip to content

Commit 4da203b

Browse files
joscohJosh Cohen
andauthored
Replace Identifier with String x Metadata (#163)
*Issue #, if available:* *Description of changes:* Redefines an `Identifier` as `String x IDMeta` and parameterizes `LExpr`, `LExprT`, etc with `IDMeta` rather than `Identifier`. This allows several important operations on identifiers and expressions including: - Generating arbitrary distinct identifiers (assuming `IDMeta` is `Inhabited`) - Pattern matching on the name of a `.op` expression Note: since the `ToFormat` instance of `BoogieIdent` (the only non-`String` identifier in use) simply gave the name, this implementation ignores `IDMeta` when converting `Identifiers` to `String` or `Format`. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. Co-authored-by: Josh Cohen <[email protected]>
1 parent ca9c9bc commit 4da203b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+753
-727
lines changed

Strata/Backends/CBMC/BoogieToCBMC.lean

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,10 @@ instance : IdentToStr String where
5454
class HasLExpr (P : Imperative.PureExpr) (I : Type) where
5555
expr_eq : P.Expr = Lambda.LExpr Lambda.LMonoTy I
5656

57-
instance : HasLExpr Boogie.Expression BoogieIdent where
57+
instance : HasLExpr Boogie.Expression Visibility where
5858
expr_eq := rfl
5959

60-
def exprToJson (I : Type) [IdentToStr I] (e : Lambda.LExpr Lambda.LMonoTy I) (loc: SourceLoc) : Json :=
60+
def exprToJson (I : Type) [IdentToStr (Lambda.Identifier I)] (e : Lambda.LExpr Lambda.LMonoTy I) (loc: SourceLoc) : Json :=
6161
match e with
6262
| .app (.app (.op op _) left) right =>
6363
let leftJson := match left with
@@ -102,7 +102,7 @@ def cmdToJson (e : Boogie.Command) (loc: SourceLoc) : Json :=
102102
mkCodeBlock "expression" "6" loc.functionName #[
103103
mkSideEffect "assign" "6" loc.functionName mkIntType #[
104104
mkLvalueSymbol s!"{loc.functionName}::1::{name.toPretty}" "6" loc.functionName,
105-
exprToJson (I:=BoogieIdent) expr exprLoc
105+
exprToJson (I:=Visibility) expr exprLoc
106106
]
107107
]
108108
| .assert label expr _ =>
@@ -127,7 +127,7 @@ def cmdToJson (e : Boogie.Command) (loc: SourceLoc) : Json :=
127127
Json.mkObj [
128128
("id", "arguments"),
129129
("sub", Json.arr #[
130-
exprToJson (I:=BoogieIdent) expr exprLoc,
130+
exprToJson (I:=Visibility) expr exprLoc,
131131
mkStringConstant label "7" loc.functionName
132132
])
133133
]
@@ -155,15 +155,15 @@ def cmdToJson (e : Boogie.Command) (loc: SourceLoc) : Json :=
155155
Json.mkObj [
156156
("id", "arguments"),
157157
("sub", Json.arr #[
158-
exprToJson (I:=BoogieIdent) expr exprLoc
158+
exprToJson (I:=Visibility) expr exprLoc
159159
])
160160
]
161161
]
162162
]
163163
| .havoc _ _ => panic! "Unimplemented"
164164

165165
mutual
166-
partial def blockToJson {P : Imperative.PureExpr} (I : Type) [IdentToStr I] [HasLExpr P I]
166+
partial def blockToJson {P : Imperative.PureExpr} (I : Type) [IdentToStr (Lambda.Identifier I)] [HasLExpr P I]
167167
(b: Imperative.Block P Command) (loc: SourceLoc) : Json :=
168168
Json.mkObj [
169169
("id", "code"),
@@ -176,7 +176,7 @@ partial def blockToJson {P : Imperative.PureExpr} (I : Type) [IdentToStr I] [Has
176176
("sub", Json.arr (b.ss.map (stmtToJson (I:=I) · loc)).toArray)
177177
]
178178

179-
partial def stmtToJson {P : Imperative.PureExpr} (I : Type) [IdentToStr I] [HasLExpr P I]
179+
partial def stmtToJson {P : Imperative.PureExpr} (I : Type) [IdentToStr (Lambda.Identifier I)] [HasLExpr P I]
180180
(e : Imperative.Stmt P Command) (loc: SourceLoc) : Json :=
181181
match e with
182182
| .cmd cmd => cmdToJson cmd loc
@@ -245,7 +245,7 @@ def createContractSymbolFromAST (func : Boogie.Procedure) : CBMCSymbol :=
245245
]),
246246
("sub", Json.arr #[
247247
parameterTuple,
248-
exprToJson (I:=BoogieIdent) (listToExpr func.spec.preconditions) {functionName := func.header.name.toPretty, lineNum := "2"}
248+
exprToJson (I:=Visibility) (listToExpr func.spec.preconditions) {functionName := func.header.name.toPretty, lineNum := "2"}
249249
])
250250
]
251251

@@ -257,7 +257,7 @@ def createContractSymbolFromAST (func : Boogie.Procedure) : CBMCSymbol :=
257257
]),
258258
("sub", Json.arr #[
259259
parameterTuple,
260-
exprToJson (I:=BoogieIdent) (listToExpr func.spec.postconditions) {functionName := func.header.name.toPretty, lineNum := "2"}
260+
exprToJson (I:=Visibility) (listToExpr func.spec.postconditions) {functionName := func.header.name.toPretty, lineNum := "2"}
261261
])
262262
]
263263

@@ -304,7 +304,7 @@ def createContractSymbolFromAST (func : Boogie.Procedure) : CBMCSymbol :=
304304
def getParamJson(func: Boogie.Procedure) : Json :=
305305
Json.mkObj [
306306
("id", ""),
307-
("sub", Json.arr (func.header.inputs.map (λ i => mkParameter i.fst.snd (func.header.name.toPretty) "1")).toArray)
307+
("sub", Json.arr (func.header.inputs.map (λ i => mkParameter i.fst.name (func.header.name.toPretty) "1")).toArray)
308308
]
309309

310310

@@ -331,7 +331,7 @@ def createImplementationSymbolFromAST (func : Boogie.Procedure) : CBMCSymbol :=
331331

332332
-- For now, keep the hardcoded implementation but use function name from AST
333333
let loc : SourceLoc := { functionName := (func.header.name.toPretty), lineNum := "1" }
334-
let stmtJsons := (func.body.map (stmtToJson (I:=BoogieIdent) · loc))
334+
let stmtJsons := (func.body.map (stmtToJson (I:=Visibility) · loc))
335335

336336
let implValue := Json.mkObj [
337337
("id", "code"),
@@ -352,7 +352,7 @@ def createImplementationSymbolFromAST (func : Boogie.Procedure) : CBMCSymbol :=
352352
module := "ex_prog",
353353
name := (func.header.name.toPretty),
354354
prettyName := (func.header.name.toPretty),
355-
prettyType := s!"signed int (signed int {String.intercalate ", signed int " (func.header.inputs.keys.map (λ p => p.snd))})",
355+
prettyType := s!"signed int (signed int {String.intercalate ", signed int " (func.header.inputs.keys.map (λ p => p.name))})",
356356
prettyValue := "{\n signed int z;\n z = x;\n z = z + 1;\n return z;\n}",
357357
type := implType,
358358
value := implValue
@@ -364,23 +364,23 @@ def testSymbols (proc: Boogie.Procedure) : String := Id.run do
364364
let implSymbol := createImplementationSymbolFromAST proc
365365

366366
-- Get parameter names from AST
367-
let paramNames : List String := proc.header.inputs.keys.map (λ p => p.snd)
367+
let paramNames : List String := proc.header.inputs.keys.map (λ p => p.name)
368368

369369
-- Hardcode local variable for now
370370
let zSymbol := createLocalSymbol "z" proc.header.name.toPretty
371371

372372
-- Build symbol map
373373
let mut m : Map String CBMCSymbol := Map.empty
374-
m := m.insert s!"contract::{proc.header.name.snd}" contractSymbol
375-
m := m.insert proc.header.name.snd implSymbol
374+
m := m.insert s!"contract::{proc.header.name.name}" contractSymbol
375+
m := m.insert proc.header.name.name implSymbol
376376

377377
-- Add parameter symbols
378378
for paramName in paramNames do
379379
let paramSymbol := createParameterSymbol paramName proc.header.name.toPretty
380-
m := m.insert s!"{proc.header.name.snd}::{paramName}" paramSymbol
380+
m := m.insert s!"{proc.header.name.name}::{paramName}" paramSymbol
381381

382382
-- Add local variable
383-
m := m.insert s!"{proc.header.name.snd}::1::z" zSymbol
383+
m := m.insert s!"{proc.header.name.name}::1::z" zSymbol
384384
toString (toJson m)
385385

386386
end Boogie

Strata/Backends/CBMC/StrataToCBMC.lean

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ def lexprToCBMC (expr : Strata.C_Simp.Expression.Expr) (functionName : String) :
5151
let cfg := CBMCConfig.empty
5252
match expr with
5353
| .app (.app (.op op _) (.fvar varName _)) (.const value _) =>
54-
mkBinaryOp (opToStr op) "2" functionName (config := cfg)
54+
mkBinaryOp (opToStr op.name) "2" functionName (config := cfg)
5555
(Json.mkObj [
5656
("id", "symbol"),
5757
("namedSub", Json.mkObj [
58-
("#base_name", Json.mkObj [("id", varName)]),
58+
("#base_name", Json.mkObj [("id", varName.name)]),
5959
("#id_class", Json.mkObj [("id", "1")]),
6060
("#lvalue", Json.mkObj [("id", "1")]),
6161
("#source_location", mkSourceLocation "from_andrew.c" functionName "2" cfg),
@@ -96,8 +96,8 @@ def createContractSymbolFromAST (func : Strata.C_Simp.Function) : CBMCSymbol :=
9696
])
9797
}
9898

99-
let sourceLocation := mkSourceLocation "from_andrew.c" func.name "2"
100-
let ensuresSourceLocation := mkSourceLocation "from_andrew.c" func.name "3"
99+
let sourceLocation := mkSourceLocation "from_andrew.c" func.name.name "2"
100+
let ensuresSourceLocation := mkSourceLocation "from_andrew.c" func.name.name "3"
101101

102102
let mathFunctionType := Json.mkObj [
103103
("id", "mathematical_function"),
@@ -128,7 +128,7 @@ def createContractSymbolFromAST (func : Strata.C_Simp.Function) : CBMCSymbol :=
128128
]),
129129
("sub", Json.arr #[
130130
parameterTuple,
131-
lexprToCBMC func.pre func.name
131+
lexprToCBMC func.pre func.name.name
132132
])
133133
]
134134

@@ -140,15 +140,15 @@ def createContractSymbolFromAST (func : Strata.C_Simp.Function) : CBMCSymbol :=
140140
]),
141141
("sub", Json.arr #[
142142
parameterTuple,
143-
lexprToCBMC func.post func.name
143+
lexprToCBMC func.post func.name.name
144144
])
145145
]
146146

147147
let parameters := Json.mkObj [
148148
("id", ""),
149149
("sub", Json.arr #[
150-
mkParameter "x" func.name "1" cfg,
151-
mkParameter "y" func.name "1" cfg
150+
mkParameter "x" func.name.name "1" cfg,
151+
mkParameter "y" func.name.name "1" cfg
152152
])
153153
]
154154

@@ -172,13 +172,13 @@ def createContractSymbolFromAST (func : Strata.C_Simp.Function) : CBMCSymbol :=
172172
]
173173

174174
{
175-
baseName := func.name,
175+
baseName := func.name.name,
176176
isProperty := true,
177177
location := location,
178178
mode := "C",
179179
module := "from_andrew",
180180
name := s!"contract::{func.name}",
181-
prettyName := func.name,
181+
prettyName := func.name.name,
182182
prettyType := "signed int (signed int x, signed int y)",
183183
type := contractType,
184184
value := Json.mkObj [("id", "nil")]
@@ -188,7 +188,7 @@ def getParamJson(func: Strata.C_Simp.Function) : Json :=
188188
let cfg := CBMCConfig.empty
189189
Json.mkObj [
190190
("id", ""),
191-
("sub", Json.arr (func.inputs.map (λ i => mkParameter i.fst func.name "1" cfg)).toArray)
191+
("sub", Json.arr (func.inputs.map (λ i => mkParameter i.fst.name func.name.name "1" cfg)).toArray)
192192
]
193193

194194
def exprToJson (e : Strata.C_Simp.Expression.Expr) (loc: SourceLoc) : Json :=
@@ -203,7 +203,7 @@ def exprToJson (e : Strata.C_Simp.Expression.Expr) (loc: SourceLoc) : Json :=
203203
| .fvar varName _ => mkLvalueSymbol s!"{loc.functionName}::{varName}" loc.lineNum loc.functionName cfg
204204
| .const value _ => mkConstant value "10" (mkSourceLocation "from_andrew.c" loc.functionName loc.lineNum cfg) cfg
205205
| _ => exprToJson right loc
206-
mkBinaryOp (opToStr op) loc.lineNum loc.functionName leftJson rightJson cfg
206+
mkBinaryOp (opToStr op.name) loc.lineNum loc.functionName leftJson rightJson cfg
207207
| .const n _ =>
208208
mkConstant n "10" (mkSourceLocation "from_andrew.c" loc.functionName "14" cfg) cfg
209209
| _ => panic! "Unimplemented"
@@ -344,29 +344,29 @@ def createImplementationSymbolFromAST (func : Strata.C_Simp.Function) : CBMCSymb
344344
]
345345

346346
-- For now, keep the hardcoded implementation but use function name from AST
347-
let loc : SourceLoc := { functionName := func.name, lineNum := "1" }
347+
let loc : SourceLoc := { functionName := func.name.name, lineNum := "1" }
348348
let stmtJsons := (func.body.map (stmtToJson · loc)) --++ [returnStmt]
349349

350350
let implValue := Json.mkObj [
351351
("id", "code"),
352352
("namedSub", Json.mkObj [
353-
("#end_location", mkSourceLocation "from_andrew.c" func.name "15"),
354-
("#source_location", mkSourceLocation "from_andrew.c" func.name "4"),
353+
("#end_location", mkSourceLocation "from_andrew.c" func.name.name "15"),
354+
("#source_location", mkSourceLocation "from_andrew.c" func.name.name "4"),
355355
("statement", Json.mkObj [("id", "block")]),
356356
("type", emptyType)
357357
]),
358358
("sub", Json.arr stmtJsons.toArray)
359359
]
360360

361361
{
362-
baseName := func.name,
362+
baseName := func.name.name,
363363
isLvalue := true,
364364
location := location,
365365
mode := "C",
366366
module := "from_andrew",
367-
name := func.name,
368-
prettyName := func.name,
369-
prettyType := s!"signed int (signed int {String.intercalate ", signed int " func.inputs.keys})",
367+
name := func.name.name,
368+
prettyName := func.name.name,
369+
prettyType := s!"signed int (signed int {String.intercalate ", signed int " (func.inputs.keys.map Lambda.Identifier.name)})",
370370
prettyValue := "{\n signed int z;\n z = x + y;\n __CPROVER_assert(z > x, \"test_assert\");\n if(z > 10)\n {\n z = z - 1;\n }\n\n else\n {\n z = z + 1;\n }\n __CPROVER_assume(z > 0);\n return 0;\n}",
371371
type := implType,
372372
value := implValue
@@ -381,16 +381,16 @@ def testSymbols (myFunc: Strata.C_Simp.Function) : String := Id.run do
381381
let paramNames := myFunc.inputs.keys
382382

383383
-- Hardcode local variable for now
384-
let zSymbol := createLocalSymbol "z" myFunc.name
384+
let zSymbol := createLocalSymbol "z" myFunc.name.name
385385

386386
-- Build symbol map
387387
let mut m : Map String CBMCSymbol := Map.empty
388388
m := m.insert s!"contract::{myFunc.name}" contractSymbol
389-
m := m.insert myFunc.name implSymbol
389+
m := m.insert myFunc.name.name implSymbol
390390

391391
-- Add parameter symbols
392392
for paramName in paramNames do
393-
let paramSymbol := createParameterSymbol paramName myFunc.name
393+
let paramSymbol := createParameterSymbol paramName.name myFunc.name.name
394394
m := m.insert s!"{myFunc.name}::{paramName}" paramSymbol
395395

396396
-- Add local variable

0 commit comments

Comments
 (0)