public Tuple GetSeqBuildMethod()

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));
    }