示例#1
0
    def unify_monotypes(self, t1, t2):
        "Unify the given types, which must be either Monotypes or Variables"

        assert isinstance(t1, (T.Monotype, T.Typevar))
        assert isinstance(t2, (T.Monotype, T.Typevar))

        con = self.context

        # Resolve w.r.t. the current solution before proceeding
        t1 = resolve(t1, self.solution)
        t2 = resolve(t2, self.solution)
        if self.verbose: print "\tunifying", t1, "and", t2

        if t1 == t2: pass
        elif con.is_variable(t1): self.unify_variable(t1, t2)
        elif con.is_variable(t2): self.unify_variable(t2, t1)

        else:
            t1 = self.context.instantiate(t1)
            t2 = self.context.instantiate(t2)
            if t1.name != t2.name or len(t1.parameters) != len(t2.parameters):
                con.error('type mismatch %s and %s' % (t1, t2))

            for (u, v) in zip(t1.parameters, t2.parameters):
                self.unify_monotypes(u, v)
示例#2
0
    def unify_monotypes(self, t1, t2):
        "Unify the given types, which must be either Monotypes or Variables"

        assert isinstance(t1, (T.Monotype, T.Typevar)) 
        assert isinstance(t2, (T.Monotype, T.Typevar)) 

        con = self.context

        # Resolve w.r.t. the current solution before proceeding
        t1 = resolve(t1, self.solution)
        t2 = resolve(t2, self.solution)
        if self.verbose: print "\tunifying", t1, "and", t2

        if t1==t2:                  pass
        elif con.is_variable(t1):   self.unify_variable(t1, t2)
        elif con.is_variable(t2):   self.unify_variable(t2, t1)

        else:
            t1 = self.context.instantiate(t1)
            t2 = self.context.instantiate(t2)
            if t1.name != t2.name or len(t1.parameters) != len(t2.parameters):
                con.error('type mismatch %s and %s' % (t1,t2))
           
            for (u,v) in zip(t1.parameters, t2.parameters):
                self.unify_monotypes(u, v)
示例#3
0
    def closing_over(self, t, closed, body):
        # NOTE: Like the Generalizing constraint, we're implicitly
        #       assuming that due to constraint ordering the body
        #       referenced here has already been solved.

        fntype = self.context.instantiate(resolve_type(body, self.solution))
        if not isinstance(fntype, T.Fn):
            raise InferenceError, "closure must be over functional types"

        # Get the list of argument types from the Fn type
        innertypes = fntype.input_types()

        # Partition the inner argument types into the outer types
        # exported to the world and those corresponding to the closed
        # arguments
        outertypes, closedtypes = innertypes[:-len(closed)], \
                                  innertypes[-len(closed):]

        for v, t2 in zip(closed, closedtypes):
            if self.verbose:
                print "\tt1 =", v.type
                print "\tt2 =", t2
            t1 = resolve(v.type, self.solution)
            t1 = self.context.instantiate(t1)
            if self.verbose:
                print "\tresolve(t1) =", t1
                print "\tresolve(t2) =", resolve_type(t2, self.solution)
            self.unify_monotypes(t1, t2)

        self.unify_monotypes(t, T.Fn(outertypes, fntype.result_type()))
示例#4
0
    def closing_over(self, t, closed, body):
        # NOTE: Like the Generalizing constraint, we're implicitly
        #       assuming that due to constraint ordering the body
        #       referenced here has already been solved.

        fntype = self.context.instantiate(resolve_type(body, self.solution))
        if not isinstance(fntype, T.Fn):
            raise InferenceError, "closure must be over functional types"

        # Get the list of argument types from the Fn type
        innertypes = fntype.input_types()

        # Partition the inner argument types into the outer types
        # exported to the world and those corresponding to the closed
        # arguments
        outertypes, closedtypes = innertypes[:-len(closed)], \
                                  innertypes[-len(closed):]

        for v, t2 in zip(closed, closedtypes):
            if self.verbose:
                print "\tt1 =", v.type
                print "\tt2 =", t2
            t1 = resolve(v.type, self.solution)
            t1 = self.context.instantiate(t1)
            if self.verbose:
                print "\tresolve(t1) =", t1
                print "\tresolve(t2) =", resolve_type(t2, self.solution)
            self.unify_monotypes(t1, t2)

        self.unify_monotypes(t, T.Fn(outertypes, fntype.result_type()))
示例#5
0
文件: inference.py 项目: WuCPMark/TFJ
    def _Bind(self, ast):
        type = self.expression_type(ast.value())

        # Convert functional types to polytypes as necessary
        if isinstance(type, T.Fn):
            free = [v for v in AST.free_variables(ast.value(), {})]
            bound = [self.tcon.typings[id] for id in free]
            bound = [resolve(t, self.tcon.environment) for t in bound]
            type = T.quantify_type(type, bound)

        ##This code allows us to unpack tuples returned from functions
        def match(binder, type):
            if isinstance(binder, AST.Name):
                self.tcon.typings[binder.id] = type
            elif isinstance(binder, AST.Tuple):
                if len(binder.parameters)!=len(type.parameters):
                    raise InferenceError, \
                            "binder and value don't match (%s)" % ast
                for b, t in zip(binder.parameters, type.parameters):
                    match(b, t)
            else:
                raise InferenceError, "illegal binder (%s)" % ast

        match(ast.binder(), type)

        return None
示例#6
0
    def generalize_binding(self, t1, t2, M):
        assert isinstance(t1, T.Typevar)
        assert isinstance(t2, (T.Typevar, T.Monotype))

        # Generalization occurs for identifiers introduced in
        # declaration statements.  This may, for instance, occur as the
        # result of a declaration:
        #     x = E
        # or a procedure definition
        #     def f(...): S
        #
        # The type variable t1 associated with the binder (e.g., 'x') is
        # allowed to become a Polytype.  We generate this polytype by
        # quantifying over the free variables of t2 that do not occur in
        # M.

        # NOTE: In general, we must be careful about when we can solve
        # Generalizing constraints.  In the current solver, where
        # constraints are generated in post-order, they can be solved
        # immediately.  In other orderings, they may need to be deferred
        # if they contain "active" type variables.

        r1 = resolve(t1, self.solution)
        r2 = resolve_type(t2, self.solution)

        if self.verbose:
            print "\tt1 =", t1
            print "\tt2 =", t2
            print "\tresolve(t1) =", r1
            print "\tresolve(t2) =", r2

        if r1 != t1 and isinstance(r2, T.Monotype):
            self.unify_monotypes(r1, r2)
            r2 = resolve_type(t2, self.solution)

        # The set of type variables associated with assumptions should
        # also be treated as monomorphs.  While we may have made
        # assumptions about a polymorphic function, we will have
        # generated a fresh type variable for each occurrence.  These
        # type variables are thus properly monomorphic.
        #
        R = set()
        for x in chain(M, self.context.assumptions.keys()):
            R |= set(T.names_in_type(resolve_type(x, self.solution)))

        if self.verbose:
            print "\tR =", R

        assert self.context.is_variable(t1)
        self.solution[t1] = T.quantify_type(r2, R, self.quantified)
        if self.verbose:
            print "\t--> Quantifying", t2, "to", self.solution[t1]
示例#7
0
    def generalize_binding(self, t1, t2, M):
        assert isinstance(t1, T.Typevar)
        assert isinstance(t2, (T.Typevar, T.Monotype))

        # Generalization occurs for identifiers introduced in
        # declaration statements.  This may, for instance, occur as the
        # result of a declaration:
        #     x = E
        # or a procedure definition
        #     def f(...): S
        #
        # The type variable t1 associated with the binder (e.g., 'x') is
        # allowed to become a Polytype.  We generate this polytype by
        # quantifying over the free variables of t2 that do not occur in
        # M.

        # NOTE: In general, we must be careful about when we can solve
        # Generalizing constraints.  In the current solver, where
        # constraints are generated in post-order, they can be solved
        # immediately.  In other orderings, they may need to be deferred
        # if they contain "active" type variables.

        r1 = resolve(t1, self.solution)
        r2 = resolve_type(t2, self.solution)

        if self.verbose:
            print "\tt1 =", t1
            print "\tt2 =", t2
            print "\tresolve(t1) =", r1
            print "\tresolve(t2) =", r2

        if r1 != t1 and isinstance(r2, T.Monotype):
            self.unify_monotypes(r1, r2)
            r2 = resolve_type(t2, self.solution)

        # The set of type variables associated with assumptions should
        # also be treated as monomorphs.  While we may have made
        # assumptions about a polymorphic function, we will have
        # generated a fresh type variable for each occurrence.  These
        # type variables are thus properly monomorphic.
        #
        R = set()
        for x in chain(M, self.context.assumptions.keys()):
            R |= set(T.names_in_type(resolve_type(x, self.solution)))

        if self.verbose:
            print "\tR =", R

        assert self.context.is_variable(t1)
        self.solution[t1] = T.quantify_type(r2, R, self.quantified)
        if self.verbose:
            print "\t--> Quantifying", t2, "to", self.solution[t1]
示例#8
0
文件: inference.py 项目: WuCPMark/TFJ
    def _Map(self, ast):
        fn, args = ast.parameters[0], ast.parameters[1:]

        # Type the function we're applying
        fntype = self.visit(fn)
        argtypes = self.visit(args)
        items = [self.tcon.fresh_typevar() for x in argtypes]
        for t, seq in zip(items, argtypes):
            unify(T.Seq(t), seq, self.tcon)
            
        # Unify function type with element types
        restype = self.tcon.fresh_typevar()
        unify(fntype, T.Fn(T.Tuple(*items), restype), self.tcon)
        return T.Seq(resolve(restype, self.tcon.environment))
示例#9
0
 def resolve_variable(tcon, t):
     'Resolve current mapping (if any) of typevars'
     if isinstance(t, T.Typevar): return resolve(t, tcon.typings)
     else: return t
示例#10
0
 def resolve_variable(tcon, t):
     'Resolve current mapping (if any) of typevars'
     if isinstance(t, T.Typevar): return resolve(t, tcon.typings)
     else: return t