///////////////////////////////////////////////////////////////////////////

        public override VCExpr VisitBoogieFunctionOp(VCExprNAry node, VariableBindings bindings)
        {
            Contract.Requires((bindings != null));
            Contract.Requires((node != null));
            Contract.Ensures(Contract.Result <VCExpr>() != null);
            OpTypesPair originalOpTypes = OriginalOpTypes(node);
            OpTypesPair newOpTypes;

            if (!NewOpCache.TryGetValue(originalOpTypes, out newOpTypes))
            {
                Function /*!*/
                    oriFun = ((VCExprBoogieFunctionOp)node.Op).Func;
                Contract.Assert(oriFun != null);
                List <Type /*!*/> /*!*/
                inferredTypeArgs = new List <Type /*!*/>();
                foreach (Type /*!*/ t in node.TypeArguments)
                {
                    Contract.Assert(t != null);
//          inferredTypeArgs.Add(AxBuilder.MapTypeAbstracter.AbstractMapTypeRecursively(t));
                    inferredTypeArgs.Add(t);
                }

                VCExprOp /*!*/
                    newOp = Gen.BoogieFunctionOp(AxBuilderArguments.Typed2Untyped(oriFun));
                newOpTypes = new OpTypesPair(newOp, inferredTypeArgs);

                NewOpCache.Add(originalOpTypes, newOpTypes);
            }

            return(AssembleOpExpression(newOpTypes, node, bindings));
        }
        public override VCExpr VisitSelectOp(VCExprNAry node, VariableBindings bindings)
        {
            Contract.Requires((bindings != null));
            Contract.Requires((node != null));
            Contract.Ensures(Contract.Result <VCExpr>() != null);
            OpTypesPair originalOpTypes = OriginalOpTypes(node);
            OpTypesPair newOpTypes;

            if (!NewOpCache.TryGetValue(originalOpTypes, out newOpTypes))
            {
                MapType /*!*/
                    rawType = node[0].Type.AsMap;
                Contract.Assert(rawType != null);
                List <Type> /*!*/
                abstractionInstantiation;
                Function    /*!*/
                    select =
                    AxBuilder.MapTypeAbstracter.Select(rawType, out abstractionInstantiation);
                Contract.Assert(abstractionInstantiation != null);
                newOpTypes = TypesPairForSelectStore(node, select, abstractionInstantiation);
                NewOpCache.Add(originalOpTypes, newOpTypes);
            }

            return(AssembleOpExpression(newOpTypes, node, bindings));
        }