示例#1
0
        private Dictionary <SingleType, IType> ContextSubstitution(Dictionary <SingleType, IType> origin, Dictionary <SingleType, IType> substs)
        {
            var _origin = CopyContext(origin);

            foreach (var key in origin.Keys)
            {
                _origin[key] = LambdaTypeEvaluator.Subst(_origin[key], substs);
            }
            return(_origin);
        }
示例#2
0
        ///HACK: context is singleType too, but really it's variable

        private IType _GetLambdaType(LambdaExpression expr, Dictionary <SingleType, IType> context, out Dictionary <SingleType, IType> substs)
        {
            if (expr is Variable)
            {
                substs = new Dictionary <SingleType, IType>();
                var variable = new SingleType((expr as Variable).Name);
                if (context.ContainsKey(variable))
                {
                    var cv   = new List <SingleType>();
                    var type = RemoveQuantifiers(context[variable], out cv);
                    var d    = new Dictionary <SingleType, IType>();
                    cv.ForEach(v => d[v] = GetNewType());
                    type = LambdaTypeEvaluator.Subst(type, d);

                    return(type);
                }
                else
                {
                    //create context
                    var v = new SingleType((expr as Variable).Name);
                    if (globalContext.ContainsKey(v))
                    {
                        return(globalContext[v]);
                    }
                    var type = GetNewType();
                    globalContext[v] = new Universal(type, type);
                    FreeVariables.Add(new SingleType((expr as Variable).Name));
                    return(_GetLambdaType(expr, new Dictionary <SingleType, IType>()
                    {
                        { v, globalContext[v] }
                    }, out substs));
                }
            }
            if (expr is Application)
            {
                var appl = expr as Application;

                var substs1    = new Dictionary <SingleType, IType>();
                var type1      = _GetLambdaType(appl.Left, context, out substs1);
                var newContext = Merge(context, substs1);

                var substs2 = new Dictionary <SingleType, IType>();
                var type2   = _GetLambdaType(appl.Right, newContext, out substs2);

                var type3 = LambdaTypeEvaluator.Subst(type1, substs2);
                var beta  = GetNewType();
                var v     = new Unificator(new Equation[] { new Equation(type3, new Implication(type2, beta)) }).Solve();

                substs = Merge(Merge(substs2, substs1), v);

                return(LambdaTypeEvaluator.Subst(beta, substs));
            }

            if (expr is Abstraction)
            {
                var abstr      = expr as Abstraction;
                var newContext = CopyContext(context);

                var variable = new SingleType(abstr.Variable.Name);

                var beta = GetNewType();
                newContext[variable] = beta;



                var type1 = _GetLambdaType(abstr.Expression, newContext, out substs);
                return(new Implication(LambdaTypeEvaluator.Subst(beta, substs), type1));
            }
            if (expr is LetExpression)
            {
                var let     = expr as LetExpression;
                var substs1 = new Dictionary <SingleType, IType>();

                var type = _GetLambdaType(let.Left, context, out substs1);

                var newContext = CopyContext(context);

                var variableType = ConnectAllFreeVariables(type, Merge(context, substs1));
                var variable     = new SingleType(let.Variable.Name);
                if (newContext.ContainsKey(variable))
                {
                    newContext.Remove(variable);
                }

                newContext = Merge(newContext, substs1);

                newContext[variable] = variableType;


                var substs2 = new Dictionary <SingleType, IType>();
                var type2   = _GetLambdaType(let.Right, newContext, out substs2);
                substs = Merge(substs1, substs2);
                return(type2);
            }

            throw new NotImplementedException("Type of expr is not supported");
        }