/*        private Expression ml(Expression m, IEnumerable<Expression> args)
 *      {
 *          var mt = m.type as MapType;
 *          return ml(m, args, new DataType[0], mt.range);
 *      }*/

        private Expression ml(Expression m, IEnumerable <Expression> args, IType[] typeArgs, IType resultType)
        {
            Debug.Assert(m.type is MapType);
            var mt = m.type as MapType;

            Debug.Assert(args.Count() == mt.domain.Count());
            Debug.Assert(typeArgs.Count() == mt.typeParameters.Count());
            Expression[] mlArgs = new Expression[1] {
                m
            }.Concat(args).ToArray();
            return(new BasicFAE(
                       BasicMapRead.mapRead(typeArgs, (from a in mlArgs select a.type).ToArray(), resultType),
                       new ExpressionList(mlArgs)
                       ));
        }
        public static MapRead mu2ml(MapWrite mu)
        {
            var mlArgTypes = TypeTuple.make(mu.argumentTypes.Take(mu.argumentTypes.Count() - 1));

            return(BasicMapRead.mapRead(mu.typeArguments.Skip(1).ToArray(), mlArgTypes, mu.argumentTypes.Last()));
        }
Exemple #3
0
        ////////////////////////////////////////////////////////////////////////////////////
        private Expression makeExpression(NAryExpr fae, bool old)
        {
            if (fae.Fun is TypeCoercion)
            {
                return(makeExpression(fae.Args[0], old));
            }
            var      arguments = new ExpressionList((from Expr e in fae.Args select makeExpression(e, old)).ToArray());
            Function function;

            if (fae.Fun is MapSelect)
            {
                var typeArguments = new IType[fae.TypeParameters.FormalTypeParams.Count];
                for (int i = 0; i < fae.TypeParameters.FormalTypeParams.Count; i++)
                {
                    typeArguments[i] = makeType(fae.TypeParameters[fae.TypeParameters.FormalTypeParams[i]]);
                }
                var argumentTypes = TypeTuple.make(from a in arguments select a.type);
                function = BasicMapRead.mapRead(
                    typeArguments,
                    argumentTypes,
                    makeType(fae.Type)
                    );
            }
            else if (fae.Fun is MapStore)
            {
                var typeArguments = new IType[fae.TypeParameters.FormalTypeParams.Count];
                for (int i = 0; i < fae.TypeParameters.FormalTypeParams.Count; i++)
                {
                    typeArguments[i] = makeType(fae.TypeParameters[fae.TypeParameters.FormalTypeParams[i]]);
                }
                function = BasicMapWrite.makeMapWrite(typeArguments, (from a in arguments select a.type).ToArray(),
                                                      makeType(fae.ShallowType));
            }
            else if (fae.Fun.FunctionName == "==" || fae.Fun.FunctionName == "!=")
            {
                if (arguments[0].type.isEquivalent(arguments[1].type))
                {
                    function = BFunction.eq(arguments[0].type);
                }
                else
                {
                    Debug.Assert(!arguments[0].type.isGround || !arguments[1].type.isGround);
                    function = BFunction.eq(arguments[0].type, arguments[1].type);
                }
                if (fae.Fun.FunctionName == "!=")
                {
                    arguments = new ExpressionList(
                        new BasicFAE(
                            function,
                            arguments
                            )
                        );
                    function = scope.getFunction("!", TypeTuple.make());
                }
            }
            else if (fae.Fun.FunctionName == "<:")
            {
                function = scope.getFunction(fae.Fun.FunctionName, TypeTuple.make(new[] { arguments[0].type }));
            }
            else if (fae.Fun.FunctionName == BFunctionTemplate.iteName)
            {
                function = scope.getFunction(fae.Fun.FunctionName, TypeTuple.make(new[] { arguments[1].type }));
            }
            else if (fae.Fun.FunctionName == @"-" && fae.Fun.ArgumentCount == 1)
            {
                arguments = new ExpressionList(new[] { new BasicLiteralExpression(IntegerValue.make(0)), arguments[0] });
                function  = scope.getFunction(@"-", TypeTuple.make());
            }
            else
            {
                var typeArguments = TypeTuple.make((fae.TypeParameters == null)
                                                ? new IType[0]
                                                : (from ftp in fae.TypeParameters.FormalTypeParams
                                                   select scope.typeFactory.makeTypeI(fae.TypeParameters[ftp], context)));
                function = scope.getFunction(fae.Fun.FunctionName, typeArguments);
            }
            var result = new BoogieFunctionApplicationExpression(fae, function, arguments);

            Debug.Assert(result.type.ToStringN() ==
                         makeType(fae.Type == null ? fae.ShallowType : fae.Type).ToStringN());
            Debug.Assert(result != null);
            foreach (var fv in result.freeVariables)
            {
                Debug.Assert(context.lookupVariableByOwnName(fv.name) == fv);
            }
            foreach (var ftv in result.freeTypeVariables)
            {
                Debug.Assert(ReferenceEquals(context.lookupTypeVariable(ftv.name), ftv));
            }

            return(result);
        }