Esempio n. 1
0
def try_decide_less_weak(lhs, rhs):
    """Weak decision procedure returning True, False, or None."""
    assert is_code(lhs), lhs
    assert is_code(rhs), rhs

    # Try simple cases.
    if lhs is BOT or lhs is rhs or rhs is TOP:
        return True
    if lhs is TOP and rhs is BOT:
        return False

    # Destructure JOIN.
    if is_join(lhs):
        return trool_all(try_decide_less_weak(i, rhs) for i in iter_join(lhs))
    if is_join(rhs):
        # This requires we give up at unreduced terms.
        return trool_any(try_decide_less_weak(lhs, i) for i in iter_join(rhs))

    # Destructure ABS.
    while is_abs(lhs) or is_abs(rhs):
        lhs = unabstract(lhs)
        rhs = unabstract(rhs)
    assert lhs is not rhs, lhs

    # Destructure APP.
    lhs_head, lhs_args = unapply(lhs)
    rhs_head, rhs_args = unapply(rhs)

    # Give up at unreduced terms.
    if is_abs(lhs_head) or is_abs(rhs_head):
        if len(lhs_args) == len(rhs_args):
            if try_decide_less_weak(lhs_head, rhs_head) is True:
                if all(try_decide_less_weak(i, j) is True
                       for i, j in zip(lhs_args, rhs_args)):
                    return True
        return None
    if lhs_args and not is_var(lhs_head):
        return None
    if rhs_args and not is_var(rhs_head):
        return None

    # Distinguish solvable terms.
    if is_var(lhs_head) and is_var(rhs_head):
        if lhs_head is not rhs_head or len(lhs_args) != len(rhs_args):
            return False
        return trool_all(
            try_decide_less_weak(i, j)
            for i, j in zip(lhs_args, rhs_args)
        )

    # Distinguish quoted terms.
    if is_quote(lhs_head) and is_quote(rhs_head):
        return try_decide_equal(lhs_head[1], rhs_head[1])

    # Anything else is incomparable.
    return False
Esempio n. 2
0
def approximate_var(code, direction, rank):
    """Locally approximate wrt one variable."""
    assert is_code(code), code
    assert direction is TOP or direction is BOT, direction
    assert isinstance(rank, int) and rank >= 0, rank
    result = set()
    if not occurs(code, rank):
        result.add(code)
    elif is_ivar(code):
        assert code[1] == rank, code
        result.add(code)
        result.add(direction)
    elif is_app(code):
        for lhs in approximate_var(code[1], direction, rank):
            for rhs in approximate_var(code[2], direction, rank):
                result.add(app(lhs, rhs))
    elif is_abs(code):
        for body in approximate_var(code[1], direction, rank + 1):
            result.add(abstract(body))
    elif is_join(code):
        for lhs in approximate_var(code[1], direction, rank):
            for rhs in approximate_var(code[2], direction, rank):
                result.add(join(lhs, rhs))
    else:
        raise ValueError(code)
    return tuple(sorted(result, key=complexity))
Esempio n. 3
0
def test_try_compute_step_runs(code):
    for step in xrange(5):
        with xfail_if_not_implemented():
            result = try_compute_step(code)
        if is_normal(code):
            assert result is None
            return
        else:
            assert is_code(result)
Esempio n. 4
0
def is_linear(code):
    """Return whether code never copies a bound IVAR."""
    assert is_code(code), code
    return _is_linear(code) is not None