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)); }
public static string TreeName(SeqTree s) { return((s == null) ? "e" : (s.buildCount >= 0) ? s.buildCount.ToString() : "a_" + TreeName(s.left) + "_" + TreeName(s.right)); }
public static string TreeName(SeqTree s) { return (s == null) ? "e" : (s.buildCount >= 0) ? s.buildCount.ToString() : "a_" + TreeName(s.left) + "_" + TreeName(s.right); }
public SeqTree(SeqTree left, SeqTree right, int buildCount) { this.left = left; this.right = right; this.buildCount = buildCount; }