Given an `args` sequence of expressions, return a new list of expression
        applying absorption and negative absorption.

        See https://en.wikipedia.org/wiki/Absorption_law

        Absorption: A & (A | B) = A, A | (A & B) = A
        Negative absorption: A & (~A | B) = A & B, A | (~A & B) = A | B

def absorb(self, args):
        """
        Given an `args` sequence of expressions, return a new list of expression
        applying absorption and negative absorption.

        See https://en.wikipedia.org/wiki/Absorption_law

        Absorption: A & (A | B) = A, A | (A & B) = A
        Negative absorption: A & (~A | B) = A & B, A | (~A & B) = A | B
        """
        args = list(args)
        if not args:
            args = list(self.args)
        i = 0
        while i < len(args):
            absorber = args[i]
            j = 0
            while j < len(args):
                if j == i:
                    j += 1
                    continue
                target = args[j]
                if not isinstance(target, self.dual):
                    j += 1
                    continue

                # Absorption
                if absorber in target:
                    del args[j]
                    if j < i:
                        i -= 1
                    continue

                # Negative absorption
                neg_absorber = self.NOT(absorber).cancel()
                if neg_absorber in target:
                    b = target.subtract(neg_absorber, simplify=False)
                    if b is None:
                        del args[j]
                        if j < i:
                            i -= 1
                        continue
                    else:
                        args[j] = b
                        j += 1
                        continue

                if isinstance(absorber, self.dual):
                    remove = None
                    for arg in absorber.args:
                        narg = self.NOT(arg).cancel()
                        if arg in target.args:
                            pass
                        elif narg in target.args:
                            if remove is None:
                                remove = narg
                            else:
                                remove = None
                                break
                        else:
                            remove = None
                            break
                    if remove is not None:
                        args[j] = target.subtract(remove, simplify=True)
                j += 1
            i += 1

        return args