def try_decide_less_weak(lhs, rhs): """Weak decision procedure returning True, False, or None.""" assert isinstance(lhs, Term), lhs assert isinstance(rhs, Term), 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) # Try pointwise comparison. if lhs_args and 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 # Give up at unreduced terms. if is_nvar(lhs_head) or is_nvar(rhs_head): return None if is_abs(lhs_head) or is_abs(rhs_head): return None if lhs_args and not is_ivar(lhs_head): return None if rhs_args and not is_ivar(rhs_head): return None # Distinguish solvable terms. if is_ivar(lhs_head) and is_ivar(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
def test_trool_all(expected, values): assert trool_all(values) is expected
def try_decide_equal(lhs, rhs): return trool_all([try_decide_less(lhs, rhs), try_decide_less(rhs, lhs)])