예제 #1
0
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_
예제 #2
0
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
    ]
예제 #3
0
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_
예제 #4
0
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)
예제 #5
0
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
예제 #6
0
def test_invalid_args_to_class(kwargs):
    with pytest.raises(OrdinalConstructionError):
        Ordinal(**kwargs)
예제 #7
0
def test_invalid_types_operation(op, a, expected_error):
    with pytest.raises(expected_error):
        op(Ordinal(), a)
        op(a, Ordinal())
예제 #8
0
     "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)
 },
 {