@@ -653,17 +653,31 @@ proveProp sc env prop =
653
653
654
654
_ -> do panic " proveProp" [pretty prop]
655
655
656
- importPrimitive :: SharedContext -> Env -> C. Name -> C. Schema -> IO Term
657
- importPrimitive sc env n sch
656
+ importPrimitive :: SharedContext -> ImportPrimitiveOptions -> Env -> C. Name -> C. Schema -> IO Term
657
+ importPrimitive sc primOpts env n sch
658
+ -- lookup primitive in the main primitive lookup table
658
659
| Just nm <- C. asPrim n, Just term <- Map. lookup nm allPrims = term sc
660
+
661
+ -- lookup primitive in the main reference implementation lookup table
659
662
| Just nm <- C. asPrim n, Just expr <- Map. lookup nm (envRefPrims env) =
660
663
do t <- importSchema sc env sch
661
664
e <- importExpr sc env expr
662
665
nmi <- importName n
663
666
scConstant' sc nmi e t
667
+
668
+ -- Optionally, create an opaque constant representing the primitive
669
+ -- if it doesn't match one of the ones we know about.
670
+ | Just _ <- C. asPrim n, allowUnknownPrimitives primOpts =
671
+ do t <- importSchema sc env sch
672
+ nmi <- importName n
673
+ scOpaqueConstant sc nmi t
674
+
675
+ -- Panic if we don't know the given primitive (TODO? probably shouldn't be a panic)
664
676
| Just nm <- C. asPrim n = panic " Unknown Cryptol primitive name" [show nm]
677
+
665
678
| otherwise = panic " Improper Cryptol primitive name" [show n]
666
679
680
+
667
681
allPrims :: Map C. PrimIdent (SharedContext -> IO Term )
668
682
allPrims = prelPrims <> arrayPrims <> floatPrims <> suiteBPrims <> primeECPrims
669
683
@@ -1245,9 +1259,9 @@ importName cnm =
1245
1259
-- definitions. (With subterm sharing, this is not as bad as it might
1246
1260
-- seem.) We might want to think about generating let or where
1247
1261
-- expressions instead.
1248
- importDeclGroup :: Bool -> SharedContext -> Env -> C. DeclGroup -> IO Env
1262
+ importDeclGroup :: DeclGroupOptions -> SharedContext -> Env -> C. DeclGroup -> IO Env
1249
1263
1250
- importDeclGroup isTopLevel sc env (C. Recursive [decl]) =
1264
+ importDeclGroup declOpts sc env (C. Recursive [decl]) =
1251
1265
case C. dDefinition decl of
1252
1266
C. DPrim ->
1253
1267
panic " importDeclGroup" [" Primitive declarations cannot be recursive:" , show (C. dName decl)]
@@ -1258,11 +1272,11 @@ importDeclGroup isTopLevel sc env (C.Recursive [decl]) =
1258
1272
let x = nameToLocalName (C. dName decl)
1259
1273
f' <- scLambda sc x t' e'
1260
1274
rhs <- scGlobalApply sc " Prelude.fix" [t', f']
1261
- rhs' <- if isTopLevel then
1262
- do nmi <- importName ( C. dName decl)
1263
- scConstant' sc nmi rhs t'
1264
- else
1265
- return rhs
1275
+ rhs' <- case declOpts of
1276
+ TopLevelDeclGroup _ ->
1277
+ do nmi <- importName ( C. dName decl)
1278
+ scConstant' sc nmi rhs t'
1279
+ NestedDeclGroup -> return rhs
1266
1280
let env' = env { envE = Map. insert (C. dName decl) (rhs', 0 ) (envE env)
1267
1281
, envC = Map. insert (C. dName decl) (C. dSignature decl) (envC env) }
1268
1282
return env'
@@ -1272,7 +1286,7 @@ importDeclGroup isTopLevel sc env (C.Recursive [decl]) =
1272
1286
-- We handle this by "tupling up" all the declarations using a record and
1273
1287
-- taking the fixpoint at this record type. The desired declarations are then
1274
1288
-- achieved by projecting the field names from this record.
1275
- importDeclGroup isTopLevel sc env (C. Recursive decls) =
1289
+ importDeclGroup declOpts sc env (C. Recursive decls) =
1276
1290
do -- build the environment for the declaration bodies
1277
1291
let dm = Map. fromList [ (C. dName d, d) | d <- decls ]
1278
1292
@@ -1319,44 +1333,63 @@ importDeclGroup isTopLevel sc env (C.Recursive decls) =
1319
1333
let mkRhs d t =
1320
1334
do let s = nameToFieldName (C. dName d)
1321
1335
r <- scRecordSelect sc rhs s
1322
- if isTopLevel then
1323
- do nmi <- importName ( C. dName d)
1324
- scConstant' sc nmi r t
1325
- else
1326
- return r
1336
+ case declOpts of
1337
+ TopLevelDeclGroup _ ->
1338
+ do nmi <- importName ( C. dName d)
1339
+ scConstant' sc nmi r t
1340
+ NestedDeclGroup -> return r
1327
1341
rhss <- sequence (Map. intersectionWith mkRhs dm tm)
1328
1342
1329
1343
let env' = env { envE = Map. union (fmap (\ v -> (v, 0 )) rhss) (envE env)
1330
1344
, envC = Map. union (fmap C. dSignature dm) (envC env)
1331
1345
}
1332
1346
return env'
1333
1347
1334
- importDeclGroup isTopLevel sc env (C. NonRecursive decl) =
1348
+ importDeclGroup declOpts sc env (C. NonRecursive decl) =
1335
1349
case C. dDefinition decl of
1336
1350
C. DPrim
1337
- | isTopLevel -> do
1338
- rhs <- importPrimitive sc env (C. dName decl) (C. dSignature decl)
1351
+ | TopLevelDeclGroup primOpts <- declOpts -> do
1352
+ rhs <- importPrimitive sc primOpts env (C. dName decl) (C. dSignature decl)
1339
1353
let env' = env { envE = Map. insert (C. dName decl) (rhs, 0 ) (envE env)
1340
- , envC = Map. insert (C. dName decl) (C. dSignature decl) (envC env) }
1354
+ , envC = Map. insert (C. dName decl) (C. dSignature decl) (envC env)
1355
+ }
1341
1356
return env'
1342
1357
| otherwise -> do
1343
1358
panic " importDeclGroup" [" Primitive declarations only allowed at top-level:" , show (C. dName decl)]
1344
1359
1345
1360
C. DExpr expr -> do
1346
1361
rhs <- importExpr' sc env (C. dSignature decl) expr
1347
- rhs' <- if not isTopLevel then return rhs else do
1348
- nmi <- importName (C. dName decl)
1349
- t <- importSchema sc env (C. dSignature decl)
1350
- scConstant' sc nmi rhs t
1362
+ rhs' <- case declOpts of
1363
+ TopLevelDeclGroup _ ->
1364
+ do nmi <- importName (C. dName decl)
1365
+ t <- importSchema sc env (C. dSignature decl)
1366
+ scConstant' sc nmi rhs t
1367
+ NestedDeclGroup -> return rhs
1351
1368
let env' = env { envE = Map. insert (C. dName decl) (rhs', 0 ) (envE env)
1352
1369
, envC = Map. insert (C. dName decl) (C. dSignature decl) (envC env) }
1353
1370
return env'
1354
1371
1372
+ data ImportPrimitiveOptions =
1373
+ ImportPrimitiveOptions
1374
+ { allowUnknownPrimitives :: Bool
1375
+ -- ^ Should unknown primitives be translated as fresh external constants?
1376
+ }
1377
+
1378
+ defaultPrimitiveOptions :: ImportPrimitiveOptions
1379
+ defaultPrimitiveOptions =
1380
+ ImportPrimitiveOptions
1381
+ { allowUnknownPrimitives = False
1382
+ }
1383
+
1384
+ data DeclGroupOptions
1385
+ = TopLevelDeclGroup ImportPrimitiveOptions
1386
+ | NestedDeclGroup
1387
+
1355
1388
importDeclGroups :: SharedContext -> Env -> [C. DeclGroup ] -> IO Env
1356
- importDeclGroups sc = foldM (importDeclGroup False sc)
1389
+ importDeclGroups sc = foldM (importDeclGroup NestedDeclGroup sc)
1357
1390
1358
- importTopLevelDeclGroups :: SharedContext -> Env -> [C. DeclGroup ] -> IO Env
1359
- importTopLevelDeclGroups sc = foldM (importDeclGroup True sc)
1391
+ importTopLevelDeclGroups :: SharedContext -> ImportPrimitiveOptions -> Env -> [C. DeclGroup ] -> IO Env
1392
+ importTopLevelDeclGroups sc primOpts = foldM (importDeclGroup ( TopLevelDeclGroup primOpts) sc)
1360
1393
1361
1394
coerceTerm :: SharedContext -> Env -> C. Type -> C. Type -> Term -> IO Term
1362
1395
coerceTerm sc env t1 t2 e
0 commit comments