'Compares two states for similarity.'

def compare_states(self, sl, sr):

    joint_solver = claripy.Solver()
    (n_map, n_counter, n_canon_constraint) = claripy.And(*sr.se.constraints).canonicalize()
    (u_map, u_counter, u_canon_constraint) = claripy.And(*sl.se.constraints).canonicalize()
    n_canoner_constraint = sr.se.simplify(n_canon_constraint)
    u_canoner_constraint = sl.se.simplify(u_canon_constraint)
    joint_solver.add((n_canoner_constraint, u_canoner_constraint))
    if (n_canoner_constraint is not u_canoner_constraint):
        self._report_incongruency('Different    constraints!')
        return False
    mem_diff = sr.memory.changed_bytes(sl.memory)
    reg_diff = sr.registers.changed_bytes(sl.registers)
    if ('UNICORN' in (sl.options | sr.options)):
        if (sl.arch.name == 'X86'):
            reg_diff -= set(range(40, 52))
            reg_diff -= set(range(320, 324))
            reg_diff -= set(range(340, 344))
        elif (sl.arch.name == 'AMD64'):
            reg_diff -= set(range(144, 168))
    for (diffs, (um, nm)) in ((reg_diff, (sl.registers, sr.registers)), (mem_diff, (sl.memory, sr.memory))):
        for i in diffs:
            bn = nm.load(i, 1)
            bu = um.load(i, 1)
            bnc = bn.canonicalize(var_map=n_map, counter=n_counter)[(-1)]
            buc = bu.canonicalize(var_map=u_map, counter=u_counter)[(-1)]
            if (bnc is not buc):
                self._report_incongruency('Different    memory    or    registers    (index    %d,    values    %r    and    %r)!', i, bn, bu)
                return False
    if (sl.arch.name in ('AMD64', 'X86', 'ARM', 'AARCH64')):
        n_flags = engines.vex.ccall._get_flags(sr)[0].canonicalize(var_map=n_map, counter=n_counter)[(-1)]
        u_flags = engines.vex.ccall._get_flags(sl)[0].canonicalize(var_map=u_map, counter=u_counter)[(-1)]
        if ((n_flags is not u_flags) and (sl.se.simplify(n_flags) is not sr.se.simplify(u_flags))):
            self._report_incongruency('Different    flags!')
            return False
    return True
