Skip to content

Commit 1167b32

Browse files
authored
Merge pull request #2429 from GaloisInc/bh/simplify-recursor
Simplify representation of recursors in saw-core terms
2 parents a949f7c + ae87dd1 commit 1167b32

File tree

17 files changed

+168
-315
lines changed

17 files changed

+168
-315
lines changed

cryptol-saw-core/src/CryptolSAWCore/Cryptol.hs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2028,7 +2028,6 @@ scCryptolType sc t =
20282028
SC.VPiType _nm _v1 (SC.VDependentPi _) -> Nothing
20292029
SC.VStringType -> Nothing
20302030
SC.VRecordType{} -> Nothing
2031-
SC.VRecursorType{} -> Nothing
20322031
SC.VTyTerm{} -> Nothing
20332032

20342033
--------------------------------------------------------------------------------

intTests/test_sawcore_type_errors/test.log.good

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ While typechecking term:
124124
Not a sort
125125
Prelude.Bool
126126

127-
Motive function should return a sort
127+
Not a sort (recursor)
128128
== Anticipated failure message ==
129129
Stack trace:
130130
(builtin) in parse_core
@@ -133,9 +133,12 @@ Stack trace:
133133
test.saw:4:17-4:54 in parse
134134
test.saw:34:1-34:59 (at top level)
135135
.:1:15:
136-
Malformed recursor
137-
Prelude.Void#rec (\(_ : Prelude.Void) -> Prelude.True) ()
138-
Motive function should return a sort
136+
While typechecking term:
137+
(arg : Prelude.Void)
138+
-> (\(_ : Prelude.Void) -> Prelude.True) arg
139+
.:1:15:
140+
Not a sort
141+
Prelude.Bool
139142

140143
Function application with non-function type
141144
== Anticipated failure message ==

intTests/test_sawcore_type_errors/test.saw

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ parse "#(Bool, 5)";
3030
print "Not a sort (record type)";
3131
parse "#{ foo : Bool, bar : False }";
3232

33-
print "Motive function should return a sort";
33+
print "Not a sort (recursor)";
3434
parse "\\(v : Void) -> Void#rec (\\ (_ : Void) -> True) v";
3535

3636
print "Function application with non-function type";

saw-core-coq/src/SAWCoreCoq/Term.hs

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -418,21 +418,8 @@ flatTermFToExpr tf = -- traceFTermF "flatTermFToExpr" tf $
418418
PairRight t ->
419419
Coq.App <$> pure (Coq.Var "snd") <*> traverse translateTerm [t]
420420

421-
RecursorType _d _params motive motiveTy ->
422-
-- type of the motive looks like
423-
-- (ix1 : _) -> ... -> (ixn : _) -> d ps ixs -> sort
424-
-- to get the type of the recursor, we compute
425-
-- (ix1 : _) -> ... -> (ixn : _) -> (x:d ps ixs) -> motive ixs x
426-
let (bs, _srt) = asPiList motiveTy in
427-
translateBinders bs $ \bndrs ->
428-
do let varsT = map (Coq.Var . bindTransIdent) bndrs
429-
let bindersT = concat $ map bindTransToPiBinder bndrs
430-
motiveT <- translateTerm motive
431-
let bodyT = Coq.App motiveT varsT
432-
return $ Coq.Pi bindersT bodyT
433-
434421
-- TODO: support this next!
435-
Recursor (CompiledRecursor d parameters motive _motiveTy eliminators elimOrder) ->
422+
Recursor (CompiledRecursor d parameters _nixs motive _motiveTy eliminators elimOrder _ty) ->
436423
do maybe_d_trans <-
437424
case nameInfo d of
438425
ModuleIdentifier ident -> translateIdentToIdent ident
@@ -455,11 +442,6 @@ flatTermFToExpr tf = -- traceFTermF "flatTermFToExpr" tf $
455442

456443
pure (Coq.App rect_var (ps ++ [m] ++ elimlist))
457444

458-
RecursorApp r indices termEliminated ->
459-
do r' <- translateTerm r
460-
let args = indices ++ [termEliminated]
461-
Coq.App r' <$> mapM translateTerm args
462-
463445
Sort s _h -> pure (Coq.Sort (translateSort s))
464446
NatLit i -> pure (Coq.NatLit (toInteger i))
465447
ArrayValue (asBoolType -> Just ()) (traverse asBool -> Just bits)

saw-core-what4/src/SAWCoreWhat4/What4.hs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1471,8 +1471,6 @@ rebuildTerm sym st sc tv sv =
14711471
scString sc s
14721472
VRecordValue _ ->
14731473
chokeOn "records (VRecordValue)"
1474-
VRecursor {} ->
1475-
chokeOn "recursors (VRecursor)"
14761474
VExtra _ ->
14771475
chokeOn "VExtra"
14781476
TValue _tval ->

saw-core/src/SAWCore/ExternalFormat.hs

Lines changed: 10 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,6 @@ separateArgs args =
4848
Just i -> Just (take i args, drop (i+1) args)
4949
Nothing -> Nothing
5050

51-
-- | Split the last element from the rest of a list, for non-empty lists
52-
splitLast :: [a] -> Maybe ([a], a)
53-
splitLast [] = Nothing
54-
splitLast xs = Just (take (length xs - 1) xs, last xs)
55-
5651
type WriteM = State.State (Map TermIndex Int, Map VarIndex (Either Text NameInfo), [String], Int)
5752

5853
renderNames :: Map VarIndex (Either Text NameInfo) -> String
@@ -148,25 +143,17 @@ scWriteExternal t0 =
148143
PairLeft e -> pure $ unwords ["ProjL", show e]
149144
PairRight e -> pure $ unwords ["ProjR", show e]
150145

151-
RecursorType d ps motive motive_ty ->
152-
do stashName d
153-
pure $ unwords
154-
(["RecursorType", show (nameIndex d)] ++
155-
map show ps ++
156-
[argsep, show motive, show motive_ty])
157-
Recursor (CompiledRecursor d ps motive motive_ty cs_fs ctorOrder) ->
146+
Recursor (CompiledRecursor d ps nixs motive motive_ty cs_fs ctorOrder ty) ->
158147
do stashName d
159148
mapM_ stashName ctorOrder
160149
pure $ unwords
161-
(["Recursor" , show (nameIndex d)] ++
150+
(["Recursor" , show (nameIndex d), show nixs] ++
162151
map show ps ++
163152
[ argsep, show motive, show motive_ty
164153
, show (Map.toList cs_fs)
165154
, show (map nameIndex ctorOrder)
155+
, show ty
166156
])
167-
RecursorApp r ixs e -> pure $
168-
unwords (["RecursorApp", show r] ++
169-
map show ixs ++ [show e])
170157

171158
RecordType elem_tps -> pure $ unwords ["RecordType", show elem_tps]
172159
RecordValue elems -> pure $ unwords ["Record", show elems]
@@ -300,32 +287,19 @@ scReadExternal sc input =
300287
["ProjL", x] -> FTermF <$> (PairLeft <$> readIdx x)
301288
["ProjR", x] -> FTermF <$> (PairRight <$> readIdx x)
302289

303-
("RecursorType" : i :
304-
(separateArgs ->
305-
Just (ps, [motive,motive_ty]))) ->
306-
do tp <- RecursorType <$>
307-
readName i <*>
308-
traverse readIdx ps <*>
309-
readIdx motive <*>
310-
readIdx motive_ty
311-
pure (FTermF tp)
312-
("Recursor" : i :
290+
("Recursor" : i : nixs :
313291
(separateArgs ->
314-
Just (ps, [motive, motiveTy, elims, ctorOrder]))) ->
315-
do rec <- CompiledRecursor <$>
292+
Just (ps, [motive, motiveTy, elims, ctorOrder, ty]))) ->
293+
do crec <- CompiledRecursor <$>
316294
readName i <*>
317295
traverse readIdx ps <*>
296+
pure (read nixs) <*>
318297
readIdx motive <*>
319298
readIdx motiveTy <*>
320299
readElimsMap elims <*>
321-
readCtorList ctorOrder
322-
pure (FTermF (Recursor rec))
323-
("RecursorApp" : r : (splitLast -> Just (ixs, arg))) ->
324-
do app <- RecursorApp <$>
325-
readIdx r <*>
326-
traverse readIdx ixs <*>
327-
readIdx arg
328-
pure (FTermF app)
300+
readCtorList ctorOrder <*>
301+
readIdx ty
302+
pure (FTermF (Recursor crec))
329303

330304
["RecordType", elem_tps] ->
331305
FTermF <$> (RecordType <$> (traverse (traverse getTerm) =<< readM elem_tps))

saw-core/src/SAWCore/Recognizer.hs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ module SAWCore.Recognizer
3838
, asRecordValue
3939
, asRecordSelector
4040
, asRecursorApp
41-
, asRecursorType
4241
, asNat
4342
, asBvNat
4443
, asUnsignedConcreteBv
@@ -249,16 +248,10 @@ asRecordSelector t = do
249248
RecordProj u s <- asFTermF t
250249
return (u, s)
251250

252-
asRecursorType :: Recognizer Term (Name, [Term], Term, Term)
253-
asRecursorType t =
254-
do RecursorType d ps motive motive_ty <- asFTermF t
255-
return (d,ps,motive,motive_ty)
256-
257-
asRecursorApp :: Recognizer Term (Term, CompiledRecursor Term, [Term], Term)
251+
asRecursorApp :: Recognizer Term (Term, CompiledRecursor Term)
258252
asRecursorApp t =
259-
do RecursorApp rc ixs arg <- asFTermF t
260-
Recursor crec <- asFTermF rc
261-
return (rc, crec, ixs, arg)
253+
do Recursor crec <- asFTermF t
254+
pure (t, crec)
262255

263256
asNat :: Recognizer Term Natural
264257
asNat (unwrapTermF -> FTermF (NatLit i)) = pure i

saw-core/src/SAWCore/Rewriter.hs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,8 @@ scExpandRewriteRule sc (RewriteRule ctxt lhs rhs _ shallow ann) =
481481
return (mkRewriteRule ctxt l x shallow ann)
482482
Just <$> traverse mkRule (Map.assocs m)
483483
(R.asApplyAll ->
484-
(R.asRecursorApp -> Just (rec, crec, _ixs, R.asVariable -> Just ec), more))
484+
(R.asRecursorApp -> Just (r, crec),
485+
splitAt (recursorNumIxs crec) -> (_ixs, (R.asVariable -> Just ec) : more)))
485486
| (ctxt1, _ : ctxt2) <- break (== ec) ctxt ->
486487
do -- ti is the type of the value being scrutinized
487488
ti <- scWhnf sc (ecType ec)
@@ -505,11 +506,11 @@ scExpandRewriteRule sc (RewriteRule ctxt lhs rhs _ shallow ann) =
505506
-- new lhs and rhs in context @ctxt'@.
506507
lhs' <- adjust lhs
507508

508-
rec' <- adjust rec
509+
r' <- adjust r
509510
crec' <- traverse adjust crec
510511
more' <- traverse adjust more
511512

512-
rhs1 <- scReduceRecursor sc rec' crec' (ctorName ctor) args
513+
rhs1 <- scReduceRecursor sc r' crec' (ctorName ctor) args
513514
rhs2 <- scApplyAll sc rhs1 more'
514515
rhs3 <- betaReduce rhs2
515516
-- re-fold recursive occurrences of the original rhs
@@ -641,9 +642,10 @@ asRecordRedex t =
641642
-- > RecursorApp rec _ n
642643
asNatIotaRedex :: R.Recognizer Term (Term, CompiledRecursor Term, Natural)
643644
asNatIotaRedex t =
644-
do (rec, crec, _, arg) <- R.asRecursorApp t
645+
do (f, arg) <- R.asApp t
646+
(r, crec) <- R.asRecursorApp f
645647
n <- R.asNat arg
646-
return (rec, crec, n)
648+
return (r, crec, n)
647649

648650
----------------------------------------------------------------------
649651
-- Bottom-up rewriting
@@ -693,17 +695,18 @@ reduceSharedTerm :: SharedContext -> Term -> IO (Maybe Term)
693695
reduceSharedTerm sc (asBetaRedex -> Just (_, _, body, arg)) = Just <$> instantiateVar sc 0 arg body
694696
reduceSharedTerm _ (asPairRedex -> Just t) = pure (Just t)
695697
reduceSharedTerm _ (asRecordRedex -> Just t) = pure (Just t)
696-
reduceSharedTerm sc (asNatIotaRedex -> Just (rec, crec, n)) =
697-
Just <$> scReduceNatRecursor sc rec crec n
698-
reduceSharedTerm sc (R.asRecursorApp -> Just (rec, crec, _, arg)) =
698+
reduceSharedTerm sc (asNatIotaRedex -> Just (r, crec, n)) =
699+
Just <$> scReduceNatRecursor sc r crec n
700+
reduceSharedTerm sc (R.asApp -> Just (R.asApplyAll -> (R.asRecursorApp -> Just (r, crec), ixs), arg))
701+
| recursorNumIxs crec == length ixs =
699702
do let (f, args) = R.asApplyAll arg
700703
mm <- scGetModuleMap sc
701704
case R.asConstant f of
702705
Nothing -> pure Nothing
703706
Just c ->
704707
case lookupVarIndexInMap (nameIndex c) mm of
705708
Just (ResolvedCtor ctor) ->
706-
Just <$> scReduceRecursor sc rec crec c (drop (ctorNumParams ctor) args)
709+
Just <$> scReduceRecursor sc r crec c (drop (ctorNumParams ctor) args)
707710
_ -> pure Nothing
708711
reduceSharedTerm _ _ = pure Nothing
709712

@@ -833,9 +836,7 @@ rewriteSharedTermTypeSafe sc ss t0 =
833836
-- NOTE: we don't rewrite arguments of constructors, datatypes, or
834837
-- recursors because of dependent types, as we could potentially cause
835838
-- a term to become ill-typed
836-
RecursorType{} -> return ftf
837839
Recursor{} -> return ftf
838-
RecursorApp{} -> return ftf -- could treat same as CtorApp
839840

840841
RecordType{} -> traverse rewriteAll ftf
841842
RecordValue{} -> traverse rewriteAll ftf

0 commit comments

Comments
 (0)