# Path: types_builtin.py
# def app_map(data, appTs):
#     apps = {}
#     for tv, at in ezip(data.tvars, appTs):
#         if isinstance(at, TVar) and at.typeVar is tv:
#             continue
#         apps[tv] = at
#     return apps
# 
# def subst(mapping, t):
#     return map_type_vars(lambda st: mapping.get(st.typeVar, st), t)


from base import *
from globs import *
from types_builtin import app_map, subst
def instance_ctor(obj):
    ctors = t_DT(type(obj)).data.ctors
    return ctors[obj._ctor_ix if len(ctors) > 1 else 0]

def transmuted_ctor(obj, destData):
    ctors = destData.ctors
    ix = obj._ctor_ix if len(ctors) > 1 else 0
    assert ix < len(ctors), "Don't know how to transmute %s!" % (obj,)
    return ctors[ix]

# Update an object's weak references to point at new clones from this vat
def rewrite(obj):
    return rewrite_by_type(obj, t_DT(type(obj)))

def rewrite_by_type(obj, t):
    cls = t.__class__
    if cls is TVar:
        assert isinstance(Structured, obj), \
                "Can't rewrite unstructured %r without type info" % (obj,)
        rewrite_by_type(obj, t_DT(type(obj)))
    elif cls in (TPrim, TFunc):
        pass
    elif cls is TTuple:
        assert isinstance(obj, tuple)
        for v, tt in ezip(obj, t.tupleTypes):
            assert not isinstance(tt, TWeak), "TODO"
            rewrite_by_type(v, tt)
    elif cls is TData:
        assert isinstance(obj, extrinsic(TrueRepresentation, t.data)), \
                "Expected %s, found %s %s" % (t.data, type(obj), obj)

# Path: types_builtin.py
# def app_map(data, appTs):
#     apps = {}
#     for tv, at in ezip(data.tvars, appTs):
#         if isinstance(at, TVar) and at.typeVar is tv:
#             continue
#         apps[tv] = at
#     return apps
# 
# def subst(mapping, t):
#     return map_type_vars(lambda st: mapping.get(st.typeVar, st), t)


# Path: vat.py
from base import *
from globs import *
from types_builtin import app_map, subst

def instance_ctor(obj):
    ctors = t_DT(type(obj)).data.ctors
    return ctors[obj._ctor_ix if len(ctors) > 1 else 0]

def transmuted_ctor(obj, destData):
    ctors = destData.ctors
    ix = obj._ctor_ix if len(ctors) > 1 else 0
    assert ix < len(ctors), "Don't know how to transmute %s!" % (obj,)
    return ctors[ix]

# Update an object's weak references to point at new clones from this vat
def rewrite(obj):
    return rewrite_by_type(obj, t_DT(type(obj)))

def rewrite_by_type(obj, t):
    cls = t.__class__
    if cls is TVar:
        assert isinstance(Structured, obj), \
                "Can't rewrite unstructured %r without type info" % (obj,)
        rewrite_by_type(obj, t_DT(type(obj)))
    elif cls in (TPrim, TFunc):
        pass
    elif cls is TTuple:
        assert isinstance(obj, tuple)
        for v, tt in ezip(obj, t.tupleTypes):
            assert not isinstance(tt, TWeak), "TODO"
            rewrite_by_type(v, tt)
    elif cls is TData:
        assert isinstance(obj, extrinsic(TrueRepresentation, t.data)), \
                "Expected %s, found %s %s" % (t.data, type(obj), obj)

        apps = t.appTypes and app_map(t.data, t.appTypes)