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