Exemple #1
0
        private static void CreateDelegateRemoveMethod(Sink sink, ITypeDefinition type, HashSet <IMethodDefinition> delegates)
        {
            Bpl.Formal a = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "a", sink.Heap.RefType), true);
            Bpl.Formal b = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "b", sink.Heap.RefType), true);
            Bpl.Formal c = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "c", sink.Heap.RefType), false);

            Bpl.IdentifierExpr aExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, a);
            Bpl.IdentifierExpr bExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, b);
            Bpl.IdentifierExpr cExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, c);

            Bpl.Procedure proc = new Bpl.Procedure(
                Bpl.Token.NoToken,
                sink.DelegateRemove(type),
                new List <Bpl.TypeVariable>(),
                new List <Bpl.Variable>(new Bpl.Variable[] { a, b }),
                new List <Bpl.Variable>(new Bpl.Variable[] { c }),
                new List <Bpl.Requires>(),
                new List <Bpl.IdentifierExpr>(),
                new List <Bpl.Ensures>());
            proc.AddAttribute("inline", Bpl.Expr.Literal(1));
            sink.TranslatedProgram.AddTopLevelDeclaration(proc);

            Bpl.StmtListBuilder stmtBuilder = new Bpl.StmtListBuilder();
            stmtBuilder.Add(new Bpl.CallCmd(Bpl.Token.NoToken, "Alloc", new List <Bpl.Expr>(), new List <Bpl.IdentifierExpr>(new Bpl.IdentifierExpr[] { cExpr })));
            foreach (IMethodDefinition defn in delegates)
            {
                Bpl.IdentifierExpr cie = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.FindOrCreateDelegateMethodConstant(defn));
                stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Iff, sink.ReadMethod(cie, cExpr), Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.And, sink.ReadMethod(cie, aExpr), Bpl.Expr.Unary(Bpl.Token.NoToken, Bpl.UnaryOperator.Opcode.Not, sink.ReadMethod(cie, bExpr))))));
                stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadReceiver(cie, cExpr), sink.ReadReceiver(cie, aExpr))));
                stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadTypeParameters(cie, cExpr), sink.ReadTypeParameters(cie, aExpr))));
            }
            Bpl.IdentifierExpr nullExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.Heap.NullRef);
            Bpl.IfCmd          ifCmd    = BuildIfCmd(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, bExpr, nullExpr), TranslationHelper.BuildAssignCmd(cExpr, aExpr), stmtBuilder.Collect(Bpl.Token.NoToken));
            ifCmd = BuildIfCmd(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, aExpr, nullExpr), TranslationHelper.BuildAssignCmd(cExpr, nullExpr), ifCmd);

            Bpl.Implementation impl = new Bpl.Implementation(
                Bpl.Token.NoToken,
                sink.DelegateRemove(type),
                new List <Bpl.TypeVariable>(),
                new List <Bpl.Variable>(new Bpl.Variable[] { a, b }),
                new List <Bpl.Variable>(new Bpl.Variable[] { c }),
                new List <Bpl.Variable>(),
                BuildStmtList(ifCmd)
                );
            impl.AddAttribute("inline", Bpl.Expr.Literal(1));
            impl.Proc = proc;
            sink.TranslatedProgram.AddTopLevelDeclaration(impl);
        }
Exemple #2
0
        private static void CreateDelegateCreateMethod(Sink sink, ITypeDefinition type, HashSet <IMethodDefinition> delegates)
        {
            Bpl.Formal method         = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "Method", Bpl.Type.Int), true);
            Bpl.Formal receiver       = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "Receiver", sink.Heap.RefType), true);
            Bpl.Formal typeParameters = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "TypeParameters", sink.Heap.TypeType), true);
            Bpl.Formal returnDelegate = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "c", sink.Heap.RefType), false);

            Bpl.IdentifierExpr methodExpr         = new Bpl.IdentifierExpr(Bpl.Token.NoToken, method);
            Bpl.IdentifierExpr receiverExpr       = new Bpl.IdentifierExpr(Bpl.Token.NoToken, receiver);
            Bpl.IdentifierExpr typeParametersExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, typeParameters);
            Bpl.IdentifierExpr returnDelegateExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, returnDelegate);

            Bpl.Procedure proc = new Bpl.Procedure(
                Bpl.Token.NoToken,
                sink.DelegateCreate(type),
                new List <Bpl.TypeVariable>(),
                new List <Bpl.Variable>(new Bpl.Variable[] { method, receiver, typeParameters }),
                new List <Bpl.Variable>(new Bpl.Variable[] { returnDelegate }),
                new List <Bpl.Requires>(),
                new List <Bpl.IdentifierExpr>(),
                new List <Bpl.Ensures>());
            proc.AddAttribute("inline", Bpl.Expr.Literal(1));
            sink.TranslatedProgram.AddTopLevelDeclaration(proc);

            Bpl.StmtListBuilder stmtBuilder = new Bpl.StmtListBuilder();
            stmtBuilder.Add(new Bpl.CallCmd(Bpl.Token.NoToken, "Alloc", new List <Bpl.Expr>(), new List <Bpl.IdentifierExpr>(new Bpl.IdentifierExpr[] { returnDelegateExpr })));
            stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadReceiver(methodExpr, returnDelegateExpr), receiverExpr)));
            stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadTypeParameters(methodExpr, returnDelegateExpr), typeParametersExpr)));
            foreach (IMethodDefinition defn in delegates)
            {
                Bpl.IdentifierExpr cie = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.FindOrCreateDelegateMethodConstant(defn));
                stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Iff, sink.ReadMethod(cie, returnDelegateExpr), Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, methodExpr, cie))));
            }
            Bpl.Implementation impl = new Bpl.Implementation(
                Bpl.Token.NoToken,
                sink.DelegateCreate(type),
                new List <Bpl.TypeVariable>(),
                new List <Bpl.Variable>(new Bpl.Variable[] { method, receiver, typeParameters }),
                new List <Bpl.Variable>(new Bpl.Variable[] { returnDelegate }),
                new List <Bpl.Variable>(),
                stmtBuilder.Collect(Bpl.Token.NoToken));
            impl.AddAttribute("inline", Bpl.Expr.Literal(1));
            impl.Proc = proc;
            sink.TranslatedProgram.AddTopLevelDeclaration(impl);
        }
Exemple #3
0
        private void CreateYieldCheckerImpl(Implementation impl, List<List<Cmd>> yields)
        {
            if (yields.Count == 0) return;

            Dictionary<Variable, Expr> map = new Dictionary<Variable, Expr>();
            foreach (Variable local in impl.LocVars)
            {
                var copy = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, local.Name, local.TypedIdent.Type));
                map[local] = Expr.Ident(copy);
            }

            Program program = linearTypeChecker.program;
            List<Variable> locals = new List<Variable>();
            List<Variable> inputs = new List<Variable>();
            foreach (IdentifierExpr ie in map.Values)
            {
                locals.Add(ie.Decl);
            }
            for (int i = 0; i < impl.InParams.Count - linearTypeChecker.linearDomains.Count; i++)
            {
                Variable inParam = impl.InParams[i];
                Variable copy = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, inParam.Name, inParam.TypedIdent.Type));
                locals.Add(copy);
                map[impl.InParams[i]] = Expr.Ident(copy);
            }
            {
                int i = impl.InParams.Count - linearTypeChecker.linearDomains.Count;
                foreach (string domainName in linearTypeChecker.linearDomains.Keys)
                {
                    Variable inParam = impl.InParams[i];
                    Variable copy = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, inParam.Name, inParam.TypedIdent.Type), true);
                    inputs.Add(copy);
                    map[impl.InParams[i]] = Expr.Ident(copy);
                    i++;
                }
            }
            for (int i = 0; i < impl.OutParams.Count; i++)
            {
                Variable outParam = impl.OutParams[i];
                var copy = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, outParam.Name, outParam.TypedIdent.Type));
                locals.Add(copy);
                map[impl.OutParams[i]] = Expr.Ident(copy);
            }
            Dictionary<Variable, Expr> ogOldLocalMap = new Dictionary<Variable, Expr>();
            Dictionary<Variable, Expr> assumeMap = new Dictionary<Variable, Expr>(map);
            foreach (IdentifierExpr ie in globalMods)
            {
                Variable g = ie.Decl;
                var copy = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("og_local_old_{0}", g.Name), g.TypedIdent.Type));
                locals.Add(copy);
                ogOldLocalMap[g] = Expr.Ident(copy);
                Formal f = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("og_global_old_{0}", g.Name), g.TypedIdent.Type), true);
                inputs.Add(f);
                assumeMap[g] = Expr.Ident(f);
            }

            Substitution assumeSubst = Substituter.SubstitutionFromHashtable(assumeMap);
            Substitution oldSubst = Substituter.SubstitutionFromHashtable(ogOldLocalMap);
            Substitution subst = Substituter.SubstitutionFromHashtable(map);
            List<Block> yieldCheckerBlocks = new List<Block>();
            List<String> labels = new List<String>();
            List<Block> labelTargets = new List<Block>();
            Block yieldCheckerBlock = new Block(Token.NoToken, "exit", new List<Cmd>(), new ReturnCmd(Token.NoToken));
            labels.Add(yieldCheckerBlock.Label);
            labelTargets.Add(yieldCheckerBlock);
            yieldCheckerBlocks.Add(yieldCheckerBlock);
            int yieldCount = 0;
            foreach (List<Cmd> cs in yields)
            {
                List<Cmd> newCmds = new List<Cmd>();
                foreach (Cmd cmd in cs)
                {
                    PredicateCmd predCmd = (PredicateCmd)cmd;
                    newCmds.Add(new AssumeCmd(Token.NoToken, Substituter.ApplyReplacingOldExprs(assumeSubst, oldSubst, predCmd.Expr)));
                }
                foreach (Cmd cmd in cs)
                {
                    PredicateCmd predCmd = (PredicateCmd)cmd;
                    var newExpr = Substituter.ApplyReplacingOldExprs(subst, oldSubst, predCmd.Expr);
                    if (predCmd is AssertCmd)
                    {
                        AssertCmd assertCmd = new AssertCmd(predCmd.tok, newExpr, predCmd.Attributes);
                        assertCmd.ErrorData = "Non-interference check failed";
                        newCmds.Add(assertCmd);
                    }
                    else
                    {
                        newCmds.Add(new AssumeCmd(Token.NoToken, newExpr));
                    }
                }
                newCmds.Add(new AssumeCmd(Token.NoToken, Expr.False));
                yieldCheckerBlock = new Block(Token.NoToken, "L" + yieldCount++, newCmds, new ReturnCmd(Token.NoToken));
                labels.Add(yieldCheckerBlock.Label);
                labelTargets.Add(yieldCheckerBlock);
                yieldCheckerBlocks.Add(yieldCheckerBlock);
            }
            yieldCheckerBlocks.Insert(0, new Block(Token.NoToken, "enter", new List<Cmd>(), new GotoCmd(Token.NoToken, labels, labelTargets)));

            // Create the yield checker procedure
            var yieldCheckerName = string.Format("{0}_YieldChecker_{1}", "Impl", impl.Name);
            var yieldCheckerProc = new Procedure(Token.NoToken, yieldCheckerName, impl.TypeParameters, inputs, new List<Variable>(), new List<Requires>(), new List<IdentifierExpr>(), new List<Ensures>());
            yieldCheckerProc.AddAttribute("inline", new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(1)));
            yieldCheckerProcs.Add(yieldCheckerProc);

            // Create the yield checker implementation
            var yieldCheckerImpl = new Implementation(Token.NoToken, yieldCheckerName, impl.TypeParameters, inputs, new List<Variable>(), locals, yieldCheckerBlocks);
            yieldCheckerImpl.Proc = yieldCheckerProc;
            yieldCheckerImpl.AddAttribute("inline", new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(1)));
            yieldCheckerImpls.Add(yieldCheckerImpl);
        }
Exemple #4
0
 private CallCmd CallToYieldProc(IToken tok, Dictionary<Variable, Variable> ogOldGlobalMap, Dictionary<string, Variable> domainNameToLocalVar)
 {
     List<Expr> exprSeq = new List<Expr>();
     foreach (string domainName in linearTypeChecker.linearDomains.Keys)
     {
         exprSeq.Add(Expr.Ident(domainNameToLocalVar[domainName]));
     }
     foreach (IdentifierExpr ie in globalMods)
     {
         exprSeq.Add(Expr.Ident(ogOldGlobalMap[ie.Decl]));
     }
     if (yieldProc == null)
     {
         List<Variable> inputs = new List<Variable>();
         foreach (string domainName in linearTypeChecker.linearDomains.Keys)
         {
             var domain = linearTypeChecker.linearDomains[domainName];
             Formal f = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "linear_" + domainName + "_in", new MapType(Token.NoToken, new List<TypeVariable>(), new List<Type> { domain.elementType }, Type.Bool)), true);
             inputs.Add(f);
         }
         foreach (IdentifierExpr ie in globalMods)
         {
             Formal f = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("og_global_old_{0}", ie.Decl.Name), ie.Decl.TypedIdent.Type), true);
             inputs.Add(f);
         }
         yieldProc = new Procedure(Token.NoToken, string.Format("og_yield_{0}", layerNum), new List<TypeVariable>(), inputs, new List<Variable>(), new List<Requires>(), new List<IdentifierExpr>(), new List<Ensures>());
         yieldProc.AddAttribute("inline", new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(1)));
     }
     CallCmd yieldCallCmd = new CallCmd(Token.NoToken, yieldProc.Name, exprSeq, new List<IdentifierExpr>());
     yieldCallCmd.Proc = yieldProc;
     return yieldCallCmd;
 }
Exemple #5
0
        private static void CreateDispatchMethod(Sink sink, ITypeDefinition type, HashSet <IMethodDefinition> delegates)
        {
            Contract.Assert(type.IsDelegate);
            IMethodDefinition invokeMethod = null;

            foreach (IMethodDefinition m in type.Methods)
            {
                if (m.Name.Value == "Invoke")
                {
                    invokeMethod = m;
                    break;
                }
            }

            try {
                IMethodDefinition  unspecializedInvokeMethod = Sink.Unspecialize(invokeMethod).ResolvedMethod;
                Sink.ProcedureInfo invokeProcedureInfo       = sink.FindOrCreateProcedure(unspecializedInvokeMethod);
                Bpl.Procedure      invokeProcedure           = (Bpl.Procedure)invokeProcedureInfo.Decl;
                invokeProcedure.AddAttribute("inline", Bpl.Expr.Literal(1));
                Bpl.Formal delegateVariable = invokeProcedureInfo.ThisVariable;
                Bpl.IToken token            = invokeMethod.Token();

                List <Bpl.Variable> dispatchProcInExprs = new List <Bpl.Variable>();
                for (int i = 1; i < invokeProcedure.InParams.Count; i++)
                {
                    Bpl.Variable v = invokeProcedure.InParams[i];
                    dispatchProcInExprs.Add(v);
                }
                List <Bpl.Variable> dispatchProcOutExprs = new List <Bpl.Variable>();
                foreach (Bpl.Variable v in invokeProcedure.OutParams)
                {
                    dispatchProcOutExprs.Add(v);
                }

                List <Bpl.Variable> localVariables = new List <Bpl.Variable>();
                Bpl.StmtListBuilder stmtBuilder    = new Bpl.StmtListBuilder();
                int localCounter = 0;
                foreach (IMethodDefinition defn in delegates)
                {
                    Bpl.Constant       c = sink.FindOrCreateDelegateMethodConstant(defn);
                    Sink.ProcedureInfo delegateProcedureInfo = sink.FindOrCreateProcedure(defn);
                    Bpl.Procedure      delegateProcedure     = (Bpl.Procedure)delegateProcedureInfo.Decl;
                    Bpl.Formal         thisVariable          = delegateProcedureInfo.ThisVariable;
                    int numArguments = defn.ParameterCount;

                    List <Bpl.Variable> tempInputs  = new List <Bpl.Variable>();
                    List <Bpl.Variable> tempOutputs = new List <Bpl.Variable>();

                    for (int i = 0; i < defn.ParameterCount; i++)
                    {
                        Bpl.Variable      v             = delegateProcedure.InParams[(thisVariable == null ? 0 : 1) + i];
                        Bpl.LocalVariable localVariable = new Bpl.LocalVariable(Bpl.Token.NoToken,
                                                                                new Bpl.TypedIdent(Bpl.Token.NoToken, "local" + localCounter++, v.TypedIdent.Type));
                        localVariables.Add(localVariable);
                        tempInputs.Add(localVariable);
                    }

                    for (int i = 0; i < delegateProcedure.OutParams.Count; i++)
                    {
                        Bpl.Variable      v             = delegateProcedure.OutParams[i];
                        Bpl.LocalVariable localVariable = new Bpl.LocalVariable(Bpl.Token.NoToken,
                                                                                new Bpl.TypedIdent(Bpl.Token.NoToken, "local" + localCounter++, v.TypedIdent.Type));
                        localVariables.Add(localVariable);
                        tempOutputs.Add(localVariable);
                    }

                    List <Bpl.Expr>           ins  = new List <Bpl.Expr>();
                    List <Bpl.IdentifierExpr> outs = new List <Bpl.IdentifierExpr>();
                    if (!defn.IsStatic)
                    {
                        ins.Add(sink.ReadReceiver(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable)));
                    }
                    for (int i = 0; i < tempInputs.Count; i++)
                    {
                        ins.Add(Bpl.Expr.Ident(tempInputs[i]));
                    }
                    if (defn.IsGeneric)
                    {
                        for (int i = 0; i < defn.GenericParameterCount; i++)
                        {
                            ins.Add(new Bpl.NAryExpr(Bpl.Token.NoToken,
                                                     new Bpl.FunctionCall(sink.FindOrCreateTypeParameterFunction(i)),
                                                     new List <Bpl.Expr>(new Bpl.Expr[] { sink.ReadTypeParameters(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable)) })));
                        }
                    }
                    if (defn.IsStatic)
                    {
                        int numTypeParameters = Sink.ConsolidatedGenericParameterCount(defn.ContainingType);
                        for (int i = 0; i < numTypeParameters; i++)
                        {
                            ins.Add(new Bpl.NAryExpr(Bpl.Token.NoToken,
                                                     new Bpl.FunctionCall(sink.FindOrCreateTypeParameterFunction(i)),
                                                     new List <Bpl.Expr>(new Bpl.Expr[] { sink.ReadTypeParameters(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable)) })));
                        }
                    }
                    for (int i = 0; i < tempOutputs.Count; i++)
                    {
                        outs.Add(Bpl.Expr.Ident(tempOutputs[i]));
                    }

                    Bpl.Expr            bexpr         = sink.ReadMethod(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable));
                    Bpl.StmtListBuilder ifStmtBuilder = new Bpl.StmtListBuilder();
                    System.Diagnostics.Debug.Assert(tempInputs.Count == dispatchProcInExprs.Count);
                    if (tempInputs.Count > 0)
                    {
                        BuildAssignment(sink, ifStmtBuilder, tempInputs, dispatchProcInExprs);
                    }
                    ifStmtBuilder.Add(EmitDummySourceContext());
                    ifStmtBuilder.Add(new Bpl.CallCmd(token, delegateProcedure.Name, ins, outs));
                    System.Diagnostics.Debug.Assert(tempOutputs.Count == dispatchProcOutExprs.Count);
                    if (tempOutputs.Count > 0)
                    {
                        BuildAssignment(sink, ifStmtBuilder, dispatchProcOutExprs, tempOutputs);
                    }
                    stmtBuilder.Add(new Bpl.IfCmd(bexpr.tok, bexpr, ifStmtBuilder.Collect(bexpr.tok), null, null));
                }

                Bpl.Implementation dispatchImpl =
                    new Bpl.Implementation(token,
                                           invokeProcedure.Name,
                                           new List <Bpl.TypeVariable>(),
                                           invokeProcedure.InParams,
                                           invokeProcedure.OutParams,
                                           localVariables,
                                           stmtBuilder.Collect(token)
                                           );
                dispatchImpl.Proc = invokeProcedure;
                dispatchImpl.AddAttribute("inline", Bpl.Expr.Literal(1));
                sink.TranslatedProgram.AddTopLevelDeclaration(dispatchImpl);
            } catch (TranslationException te) {
                throw new NotImplementedException(te.ToString());
            } catch {
                throw;
            } finally {
                // Maybe this is a good place to add the procedure to the toplevel declarations
            }
        }
    private static void CreateDelegateRemoveMethod(Sink sink, ITypeDefinition type, HashSet<IMethodDefinition> delegates)
    {
        Bpl.Formal a = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "a", sink.Heap.RefType), true);
        Bpl.Formal b = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "b", sink.Heap.RefType), true);
        Bpl.Formal c = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "c", sink.Heap.RefType), false);

        Bpl.IdentifierExpr aExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, a);
        Bpl.IdentifierExpr bExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, b);
        Bpl.IdentifierExpr cExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, c);

        Bpl.Procedure proc = new Bpl.Procedure(
            Bpl.Token.NoToken,
            sink.DelegateRemove(type),
            new List<Bpl.TypeVariable>(),
            new List<Bpl.Variable>(new Bpl.Variable[] { a, b }),
            new List<Bpl.Variable>(new Bpl.Variable[] {c}),
            new List<Bpl.Requires>(),
            new List<Bpl.IdentifierExpr>(),
            new List<Bpl.Ensures>());
        proc.AddAttribute("inline", Bpl.Expr.Literal(1));
        sink.TranslatedProgram.AddTopLevelDeclaration(proc);

        Bpl.StmtListBuilder stmtBuilder = new Bpl.StmtListBuilder();
        stmtBuilder.Add(new Bpl.CallCmd(Bpl.Token.NoToken, "Alloc", new List<Bpl.Expr>(), new List<Bpl.IdentifierExpr>(new Bpl.IdentifierExpr[] {cExpr})));
        foreach (IMethodDefinition defn in delegates)
        {
            Bpl.IdentifierExpr cie = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.FindOrCreateDelegateMethodConstant(defn));
            stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Iff, sink.ReadMethod(cie, cExpr), Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.And, sink.ReadMethod(cie, aExpr), Bpl.Expr.Unary(Bpl.Token.NoToken, Bpl.UnaryOperator.Opcode.Not, sink.ReadMethod(cie, bExpr))))));
            stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadReceiver(cie, cExpr), sink.ReadReceiver(cie, aExpr))));
            stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadTypeParameters(cie, cExpr), sink.ReadTypeParameters(cie, aExpr))));

        }
        Bpl.IdentifierExpr nullExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.Heap.NullRef);
        Bpl.IfCmd ifCmd = BuildIfCmd(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, bExpr, nullExpr), TranslationHelper.BuildAssignCmd(cExpr, aExpr), stmtBuilder.Collect(Bpl.Token.NoToken));
        ifCmd = BuildIfCmd(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, aExpr, nullExpr), TranslationHelper.BuildAssignCmd(cExpr, nullExpr), ifCmd);

        Bpl.Implementation impl = new Bpl.Implementation(
            Bpl.Token.NoToken,
            sink.DelegateRemove(type),
            new List<Bpl.TypeVariable>(),
            new List<Bpl.Variable>(new Bpl.Variable[] { a, b }),
            new List<Bpl.Variable>(new Bpl.Variable[] {c}),
            new List<Bpl.Variable>(),
            BuildStmtList(ifCmd)
            );
        impl.AddAttribute("inline", Bpl.Expr.Literal(1));
        impl.Proc = proc;
        sink.TranslatedProgram.AddTopLevelDeclaration(impl);
    }
    private static void CreateDelegateCreateMethod(Sink sink, ITypeDefinition type, HashSet<IMethodDefinition> delegates)
    {
        Bpl.Formal method = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "Method", Bpl.Type.Int), true);
        Bpl.Formal receiver = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "Receiver", sink.Heap.RefType), true);
        Bpl.Formal typeParameters = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "TypeParameters", sink.Heap.TypeType), true);
        Bpl.Formal returnDelegate = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "c", sink.Heap.RefType), false);

        Bpl.IdentifierExpr methodExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, method);
        Bpl.IdentifierExpr receiverExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, receiver);
        Bpl.IdentifierExpr typeParametersExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, typeParameters);
        Bpl.IdentifierExpr returnDelegateExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, returnDelegate);

        Bpl.Procedure proc = new Bpl.Procedure(
            Bpl.Token.NoToken,
            sink.DelegateCreate(type),
            new List<Bpl.TypeVariable>(),
            new List<Bpl.Variable>(new Bpl.Variable[] {method, receiver, typeParameters}),
            new List<Bpl.Variable>(new Bpl.Variable[] {returnDelegate}),
            new List<Bpl.Requires>(),
            new List<Bpl.IdentifierExpr>(),
            new List<Bpl.Ensures>());
        proc.AddAttribute("inline", Bpl.Expr.Literal(1));
        sink.TranslatedProgram.AddTopLevelDeclaration(proc);

        Bpl.StmtListBuilder stmtBuilder = new Bpl.StmtListBuilder();
        stmtBuilder.Add(new Bpl.CallCmd(Bpl.Token.NoToken, "Alloc", new List<Bpl.Expr>(), new List<Bpl.IdentifierExpr>(new Bpl.IdentifierExpr[] {returnDelegateExpr})));
        stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadReceiver(methodExpr, returnDelegateExpr), receiverExpr)));
        stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadTypeParameters(methodExpr, returnDelegateExpr), typeParametersExpr)));
        foreach (IMethodDefinition defn in delegates)
        {
            Bpl.IdentifierExpr cie = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.FindOrCreateDelegateMethodConstant(defn));
            stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Iff, sink.ReadMethod(cie, returnDelegateExpr), Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, methodExpr, cie))));
        }
        Bpl.Implementation impl = new Bpl.Implementation(
            Bpl.Token.NoToken, 
            sink.DelegateCreate(type), 
            new List<Bpl.TypeVariable>(),
            new List<Bpl.Variable>(new Bpl.Variable[] { method, receiver, typeParameters }), 
            new List<Bpl.Variable>(new Bpl.Variable[] {returnDelegate}), 
            new List<Bpl.Variable>(),         
            stmtBuilder.Collect(Bpl.Token.NoToken));
        impl.AddAttribute("inline", Bpl.Expr.Literal(1));
        impl.Proc = proc;
        sink.TranslatedProgram.AddTopLevelDeclaration(impl);
    }