in ironclad-apps/tools/DafnyCC/DafnyCC.cs [1168:1306]
public Tuple<Method,TypeApply> GetSeqBuildMethod(Type t, SeqTree tree, List<bool> elemDimensions)
{
if (elemDimensions.Count == 0)
{
return GetSeqMethod(t, "seq_Empty");
}
if (elemDimensions.Count == 2 && elemDimensions[0] && elemDimensions[1])
{
return GetSeqMethod(t, "seq_Append");
}
string op = "seq_" + SeqTree.TreeName(tree);
DatatypeDecl seqDecl = FindDatatype("Seq");
var tok = new Bpl.Token(0, 0);
tok.filename = @"!\Seq.dfy";
TypeApply tApp = Compile_SeqType((SeqType)t);
Type dataType = new UserDefinedType(tok, "Seq", seqDecl, new List<Type> { ((SeqType)t).Arg });
Type elemType = ((SeqType)t).Arg;
Func<string,Type,Expression> idExpr = (x, typ) => {
var e = new IdentifierExpr(tok, x);
e.Type = typ;
e.Var = new LocalVariable(tok, tok, x, typ, false);
return e;
};
Func<string,List<Expression>,FunctionCallExpr> seqCall = (x, args) => {
var seqOp = GetSeqOperation(t, x);
FunctionCallExpr callExpr = new FunctionCallExpr(
tok, "Seq_Empty", new ThisExpr(tok), tok, args);
callExpr.Function = seqOp.Item1;
callExpr.TypeArgumentSubstitutions = seqOp.Item2.typeArgs;
return callExpr;
};
Expression empty = seqCall("Seq_Empty", new List<Expression> {});
int varCount = 0;
Func<SeqTree,Expression> resultRec = null;
resultRec = (subtree) =>
{
if (subtree == null)
{
return idExpr("s" + (varCount++), dataType);
}
if (subtree.buildCount >= 0)
{
Expression build = empty;
for (int i = 0; i < subtree.buildCount; i++)
{
build = seqCall("Seq_Build", new List<Expression>
{ build, idExpr("a" + (varCount++), elemType) });
}
return build;
}
else
{
return seqCall("Seq_Append", new List<Expression>
{ resultRec(subtree.left), resultRec(subtree.right) });
}
};
Expression result = resultRec(tree);
Expression post = seqCall("Seq_Equal", new List<Expression> { idExpr("s", dataType), result });
List<Statement> stmts = new List<Statement>();
for (int i = elemDimensions.Count; i > 0;)
{
bool isFirst = (i == elemDimensions.Count);
i--;
if (elemDimensions[i])
{
if (isFirst)
{
stmts.Add(new AssignStmt(tok, tok, idExpr("s", dataType),
new ExprRhs(idExpr("s" + i, dataType))));
}
else
{
// s := seq_Append(s9, s);
var selectExpr = new MemberSelectExpr(tok, new ThisExpr(tok), "seq_Append");
selectExpr.Member = FindMethod(selectExpr.MemberName); // Manually resolve here
selectExpr.TypeApplication = new List<Type>() { elemType }; // Manually resolve here
selectExpr.Type = new InferredTypeProxy(); // Manually resolve here
CallStmt callStmt = new CallStmt(tok, tok,
new List<Expression> {idExpr("s", dataType)},
selectExpr, new List<Expression>
{ idExpr("s" + i, dataType), idExpr("s", dataType) });
stmts.Add(callStmt);
}
}
else
{
if (isFirst)
{
DatatypeValue nil = new DatatypeValue(tok, "Seq", "Nil", new List<Expression>() {});
nil.Type = dataType;
nil.InferredTypeArgs = new List<Type> { elemType };
nil.Ctor = seqDecl.Ctors[0];
Util.Assert(nil.Ctor.Name == "Seq_Nil");
stmts.Add(new AssignStmt(tok, tok, idExpr("s", dataType), new ExprRhs(nil)));
}
// lemma_Seq_Cons(ai, s);
var selectExpr = new MemberSelectExpr(tok, new ThisExpr(tok), "lemma_Seq_Cons");
selectExpr.Member = FindMethod(selectExpr.MemberName); // Manually resolve here
selectExpr.TypeApplication = new List<Type>() { elemType }; // Manually resolve here
selectExpr.Type = new InferredTypeProxy(); // Manually resolve here
CallStmt callStmt = new CallStmt(tok, tok,
new List<Expression> {},
selectExpr, new List<Expression>
{ idExpr("a" + i, elemType), idExpr("s", dataType) });
callStmt.IsGhost = true;
stmts.Add(callStmt);
DatatypeValue cons = new DatatypeValue(tok, "Seq", "Cons", new List<Expression>()
{ idExpr("a" + i, elemType), idExpr("s", dataType) });
cons.Type = dataType;
cons.InferredTypeArgs = new List<Type> { elemType };
cons.Ctor = seqDecl.Ctors[1];
Util.Assert(cons.Ctor.Name == "Seq_Cons");
stmts.Add(new AssignStmt(tok, tok, idExpr("s", dataType), new ExprRhs(cons)));
}
}
BlockStmt body = new BlockStmt(tok, tok, stmts);
List<Formal> ins = new List<Formal>();
for (int i = 0; i < elemDimensions.Count; i++)
{
bool isSeq = elemDimensions[i];
ins.Add(new Formal(tok, (isSeq ? "s" : "a") + i, isSeq ? dataType : elemType, true, false));
}
List<Formal> outs = new List<Formal> { new Formal(tok, "s", dataType, false, false) };
List<MaybeFreeExpression> reqs = new List<MaybeFreeExpression>();
List<MaybeFreeExpression> enss = new List<MaybeFreeExpression> { new MaybeFreeExpression(post) };
Specification<FrameExpression> mods = new Specification<FrameExpression>(new List<FrameExpression>(), null);
Specification<Expression> decs = new Specification<Expression>(new List<Expression>(), null);
Attributes attrs = new Attributes("dafnycc_conservative_seq_triggers", new List<Expression>(), null);
Method m = new Method(tok, op, true, false, tApp.typeParams, ins, outs, reqs, mods, enss, decs, body, attrs, tok);
m.EnclosingClass = GetSeqMethod(t, "seq_Append").Item1.EnclosingClass;
return Tuple.Create(m, Compile_Method(m, tApp.typeArgs));
}