in ironclad-apps/tools/DafnySpec/ParseMain.cs [174:329]
List<Expression> GenerateAutoReqs(Expression expr, Function parent)
{
List<Expression> reqs = new List<Expression>();
Func<Expression,List<Expression>> generateAutoReqs = e => GenerateAutoReqs(e, parent);
if (expr is LiteralExpr)
{
}
else if (expr is ThisExpr)
{
}
else if (expr is IdentifierExpr)
{
}
else if (expr is SeqDisplayExpr)
{
SeqDisplayExpr e = (SeqDisplayExpr)expr;
foreach (var elt in e.Elements)
{
reqs.AddRange(generateAutoReqs(elt));
}
}
else if (expr is MemberSelectExpr && ((MemberSelectExpr)expr).Member is Field)
{
MemberSelectExpr e = (MemberSelectExpr)expr;
reqs.AddRange(generateAutoReqs(e.Obj));
}
else if (expr is SeqSelectExpr)
{
SeqSelectExpr e = (SeqSelectExpr)expr;
reqs.AddRange(generateAutoReqs(e.Seq));
if (e.E0 != null)
{
reqs.AddRange(generateAutoReqs(e.E0));
}
if (e.E1 != null)
{
reqs.AddRange(generateAutoReqs(e.E1));
}
}
else if (expr is SeqUpdateExpr)
{
SeqUpdateExpr e = (SeqUpdateExpr)expr;
reqs.AddRange(generateAutoReqs(e.Seq));
reqs.AddRange(generateAutoReqs(e.Index));
reqs.AddRange(generateAutoReqs(e.Value));
}
else if (expr is FunctionCallExpr)
{
FunctionCallExpr e = (FunctionCallExpr)expr;
foreach (var arg in e.Args)
{
reqs.AddRange(generateAutoReqs(arg));
}
if (parent == null || parent.Name != e.name)
{
ReqFunction(e.Function);
reqs.AddRange(GatherReqs(e.Function, e.Args));
}
}
else if (expr is DatatypeValue)
{
DatatypeValue dtv = (DatatypeValue)expr;
for (int i = 0; i < dtv.Arguments.Count; i++)
{
Expression arg = dtv.Arguments[i];
reqs.AddRange(generateAutoReqs(arg));
}
}
else if (expr is OldExpr)
{
}
else if (expr is MatchExpr)
{
MatchExpr e = (MatchExpr)expr;
reqs.AddRange(generateAutoReqs(e.Source));
List<MatchCaseExpr> newMatches = new List<MatchCaseExpr>();
foreach (MatchCaseExpr caseExpr in e.Cases)
{
MatchCaseExpr c = new MatchCaseExpr(caseExpr.name, caseExpr.Arguments, Andify(generateAutoReqs(caseExpr.Body)));
newMatches.Add(c);
}
reqs.Add(new MatchExpr(e.Source, newMatches));
}
else if (expr is UnaryOpExpr)
{
UnaryOpExpr e = (UnaryOpExpr)expr;
Expression arg = e.E;
reqs.AddRange(generateAutoReqs(arg));
}
else if (expr is BinaryExpr)
{
BinaryExpr e = (BinaryExpr)expr;
switch (e.Op)
{
case BinaryExpr.Opcode.Imp:
case BinaryExpr.Opcode.And:
reqs.AddRange(generateAutoReqs(e.E0));
foreach (var req in generateAutoReqs(e.E1))
{
reqs.Add(new BinaryExpr(Token.NoToken, BinaryExpr.Opcode.Imp, e.E0, req));
}
break;
case BinaryExpr.Opcode.Or:
reqs.AddRange(generateAutoReqs(e.E0));
foreach (var req in generateAutoReqs(e.E1))
{
reqs.Add(new BinaryExpr(Token.NoToken, BinaryExpr.Opcode.Imp,
new UnaryOpExpr(Token.NoToken, UnaryOpExpr.Opcode.Not, e.E0), req));
}
break;
default:
reqs.AddRange(generateAutoReqs(e.E0));
reqs.AddRange(generateAutoReqs(e.E1));
break;
}
}
else if (expr is LetExpr)
{
var e = (LetExpr)expr;
if (e.Exact)
{
foreach (var rhs in e.RHSs)
{
reqs.AddRange(generateAutoReqs(rhs));
}
var new_reqs = generateAutoReqs(e.Body);
if (new_reqs.Count > 0)
{
reqs.Add(new LetExpr(e.Exact, e.LHSs, e.RHSs, Andify(new_reqs)));
}
}
}
else if (expr is QuantifierExpr)
{
QuantifierExpr e = (QuantifierExpr)expr;
var auto_reqs = generateAutoReqs(e.Term);
if (auto_reqs.Count > 0)
{
Expression allReqsSatisfied = Andify(auto_reqs);
Expression allReqsSatisfiedAndTerm = new BinaryExpr(Token.NoToken, BinaryExpr.Opcode.And, allReqsSatisfied, e.Term);
e.Term = allReqsSatisfiedAndTerm;
}
}
else if (expr is StmtExpr)
{
var e = (StmtExpr)expr;
reqs.AddRange(generateAutoReqs(e.E));
}
else if (expr is ITEExpr)
{
ITEExpr e = (ITEExpr)expr;
reqs.AddRange(generateAutoReqs(e.Test));
reqs.Add(new ITEExpr(e.Test, Andify(generateAutoReqs(e.Thn)), Andify(generateAutoReqs(e.Els))));
}
return reqs;
}