def factorise_term(term): """ Write a single transfinite ordinal term (addend=0) as a product of primes. For example: w**(w**w*7 + w*3 + 2) becomes [(w**w**w, 7), (w**w, 3), (w, 2)] """ factors_ = [] for t in ordinal_terms(term.exponent): if is_finite_ordinal(t): factors_.append((Ordinal(), t)) else: factors_.append((Ordinal(exponent=Ordinal(t.exponent)), t.copies)) if term.copies > 1: factors_.append((term.copies, 1)) return factors_
def divide_terms_by_ordinal(terms, ordinal): """ Divide each term in the list by the specified ordinal. """ return [ Ordinal(subtract(t.exponent, ordinal.exponent), t.copies) for t in terms ]
def factorise_term_successor(ordinal_term): """ Given a term (w**e * c) return the factors of its successor. Note that since (w**e + 1) is prime, the method returns this ordinal as a factor, as well as the copies if not 1: term -> successor -> factors w -> w + 1 -> [(w + 1, 1)] w*7 -> w*7 + 1 -> [(w + 1, 1), (7, 1)] """ factors_ = [(Ordinal(exponent=ordinal_term.exponent, addend=1), 1)] if ordinal_term.copies > 1: factors_.append((ordinal_term.copies, 1)) return factors_
def subtract(a, b): """ Given ordinals a > b, return the ordinal c such that b + c == a """ if a <= b: raise ValueError("First argument must be greater than second argument") if is_finite_ordinal(a): return a - b if is_finite_ordinal(b) or a.exponent > b.exponent: return a if a.exponent == b.exponent and a.copies == b.copies: return subtract(a.addend, b.addend) # Here we know that a.copies > b.copies return Ordinal(a.exponent, a.copies - b.copies, a.addend)
def ordinal_terms(ordinal): """ Return a list containing all terms of the ordinal. For example: w**w**w + w**3 + w*7 + 9 becomes the list [w**w**w, w**3, w*7, 9] """ terms = [] while not is_finite_ordinal(ordinal): term = Ordinal(exponent=ordinal.exponent, copies=ordinal.copies) terms.append(term) ordinal = ordinal.addend if ordinal: terms.append(ordinal) return terms
def test_invalid_args_to_class(kwargs): with pytest.raises(OrdinalConstructionError): Ordinal(**kwargs)
def test_invalid_types_operation(op, a, expected_error): with pytest.raises(expected_error): op(Ordinal(), a) op(a, Ordinal())
"exponent": "0" }, { "copies": 0 }, { "copies": -1 }, { "copies": -3.14 }, { "copies": "0" }, { "copies": Ordinal() }, { "addend": -1 }, { "addend": -3.14 }, { "addend": "0" }, { "exponent": 1, "addend": Ordinal(exponent=1) }, {