The two constructors encode a natural number by its number of successors. Structural recursion replaces the zero constructor by zero and every successor by one addition:
convert :: Natural -> Integer
convert Zero     = 0
convert (Succ n) = 1 + convert n
Structural induction gives . The output uses unbounded integers, so there is no machine-word overflow.
Recurse on the first argument for addition and multiplication, and on the exponent for exponentiation:
add :: Natural -> Natural -> Natural
add Zero     n = n
add (Succ m) n = Succ (add m n)

mul :: Natural -> Natural -> Natural
mul Zero     n = Zero
mul (Succ m) n = add n (mul m n)

power :: Natural -> Natural -> Natural
power m Zero     = Succ Zero
power m (Succ n) = mul m (power m n)
The defining arithmetic identities are
Each recursive call consumes one constructor. The base of exponentiation makes power Zero Zero equal to one, the empty-product convention. Applying convert and using structural induction verifies all three operations.
A natural-number fold iterates its first argument once per successor. For addition, iterate Succ starting at the other operand; for multiplication, iterate addition starting at zero; for exponentiation, iterate multiplication starting at one:
addF :: Natural -> Natural -> Natural
addF m n = foldNat Succ n m

mulF :: Natural -> Natural -> Natural
mulF m n = foldNat (addF n) Zero m

powerF :: Natural -> Natural -> Natural
powerF m n = foldNat (mulF m) (Succ Zero) n
The common identity is , with interpreted through convert. Substituting each step and seed reproduces the recursive arithmetic equations of part (b).
Keep the two adjacent Fibonacci numbers in one shared pair. From the Fibonacci recurrence, if the current pair is , the next is . This gives the paired Fibonacci recurrence:
twoFibs :: Integer -> (Integer, Integer)
twoFibs 0 = (0, 1)
twoFibs n
  | n > 0 = let (a, b) = twoFibs (n - 1)
            in (b, a + b)
  | otherwise = error "negative Fibonacci index"

fib :: Integer -> Integer
fib = fst . twoFibs
The pair pattern shares the result of the single recursive call. Mathematical induction establishes
There are pair updates and additions, rather than the repeated subcomputations of the original branching recursion. This is linear arithmetic-operation count; exact Fibonacci numbers have growing bit length. The pattern fib (n+2) in the source expresses the recurrence; the guarded definition above uses ordinary Haskell syntax without requiring an n+k pattern extension.
Both signs are positive, so perform addition of the aligned significands. The true exponents are and , a difference of four. Shift the smaller significand right four places, retaining its low bits:
Add at the common exponent:
Renormalization raises the true exponent to and the biased exponent to . There are only seven fraction places to retain, so no floating-point rounding changes the result:
The complete word is 0100110000001000.
Let and measure the extra operand stack space required from the current base, with each evaluation leaving one result. Evaluating first uses slots. Its result occupies one slot while evaluating , so that stage uses slots. The final add reduces two slots to one. Thus
By commutativity of addition, choose the smaller of these two bounds. Evaluate the child of larger depth first. The optimum recurrence on a binary expression tree is
Assign depth one to a literal or a simple already-addressable value, and compute the child depths recursively. If , the depths are integers, so ; evaluating first therefore attains , while reversing the order needs . If the depths are equal, whichever child goes second needs the extra retained-result slot. These lower bounds prove the recurrence is optimal for evaluating each child subtree without interleaving or spilling. Apply it at every node to minimize peak operand stack occupancy for the given binary expression tree; this is optimal stack evaluation of a binary expression tree.
This changes child evaluation order, not the parenthesization. For example, a chain-shaped binary expression tree can have depth two, whereas a balanced tree of eight leaves has depth four under this model. The reordering assumes expressions have no order-sensitive side effects or observable exceptions. Reassociating floating-point addition would require additional care because it can change floating-point rounding.
Give the wrapper exclusive ownership of a fresh delegate. It maintains its own inherited size so that inherited emptiness queries remain correct:
class IntegerSetWithCount extends IntegerSetPattern() {
  private val delegate = new IntegerSet()
  private var attempts = BigInt(0)

  override def contains(x: Int): Boolean = delegate.contains(x)

  override def insert(x: Int): Unit = {
    attempts += 1
    val wasPresent = delegate.contains(x)
    delegate.insert(x)
    if (!wasPresent) size += 1
  }
  override def delete(x: Int): Unit = {
    val wasPresent = delegate.contains(x)
    delegate.delete(x)
    if (wasPresent) size -= 1
  }
  override def pop(): Int = {
    if (isEmpty) throw new NoSuchElementException("set is empty")
    val answer = delegate.pop()
    size -= 1
    answer
  }
  override def clear: Unit = {
    delegate.clear
    size = 0
    attempts = BigInt(0)
  }
  def getCount: BigInt = attempts
}
Use the explicit membership signature and fresh default-constructible concrete set qualified in part d. The representation invariant is that the wrapper's size equals the delegate's cardinality and its counter equals client insertion attempts since construction or the latest successful client clear. The updates shown preserve that invariant when delegated operations fulfill their set contracts and failure checks leave the delegate unchanged. A duplicate does not increase size; deleting an absent element does not decrease it. Size changes follow successful delegation, whereas an attempted insertion is counted immediately.
Object composition prevents internal delegate calls from dispatching into the wrapper's counter object methods. It therefore survives the particular base revision in part e. The cost is forwarding code, another software object, some redundant size state imposed by the chosen abstract superclass, and extra membership queries. Future object interface additions must also be forwarded explicitly. This solution is an alternative definition of the software class in part d, not a second simultaneous definition.
Implement the count function directly in a private array:
class ArrayIntBag(val MAX: Int) extends IntBag {
  require(MAX > 0)
  private val c = new Array[Int](MAX)
  private def inRange(x: Int): Boolean = 0 <= x && x < MAX

  def add(x: Int): Unit = {
    require(inRange(x))
    require(c(x) < Int.MaxValue)
    c(x) += 1
  }
  def remove(x: Int): Unit = {
    require(inRange(x))
    require(c(x) > 0)
    c(x) -= 1
  }
  def count(x: Int): Int = {
    require(inRange(x))
    c(x)
  }
}
The representation invariant is that c has length MAX and every stored count is nonnegative. The abstraction function gives in range and zero outside it. Zero initialization establishes the invariant. An allowed addition changes exactly one entry without overflow; an allowed removal changes exactly one positive entry without making it negative; querying changes none. Thus each method implements its abstract postcondition as well as preserving the representation invariant. The private array prevents clients from bypassing those guarantees.
Store the number of positive buckets, initially zero:
private var distinct = 0

def size: Int = distinct
Extend the representation invariant by
The abstraction function for the multiset is unchanged. The size operation has no precondition beyond a valid receiver; it returns the cardinality of the multiset support and changes no state. Replace the modifying methods inside the class by
def add(x: Int): Unit = {
  require(inRange(x))
  require(c(x) < Int.MaxValue)
  if (c(x) == 0) distinct += 1
  c(x) += 1
}

def remove(x: Int): Unit = {
  require(inRange(x))
  require(c(x) > 0)
  c(x) -= 1
  if (c(x) == 0) distinct -= 1
}
Only transitions from zero to one or from one to zero change the support. Additions to an already positive bucket and removals leaving it positive preserve distinct. Thus size takes time, independently of MAX, and the other operations retain constant-time array access. Initialization still takes time.
Add a generic mapping method inside the supplied trait. Snapshot the finitely many source masses, and sum masses when different entries have the same image:
def map[U](f: T => U): FiniteDist[U] = {
  val entries = getDom.map(x => (f(x), getProb(x)))
  val support = entries.map(_._1).distinct

  new FiniteDist[U] {
    def getDom: List[U] = support
    def getProb(y: U): Double =
      entries.foldLeft(0.0) { case (sum, (image, mass)) =>
        if (image == y) sum + mass else sum
      }
  }
}
Here the mapping is a mathematical function, and keys are assumed to have stable equality consistent with their intended identity. Each source atom is evaluated once when the new distribution is constructed. The distinct image list is exactly the finite support because all listed source atoms have positive mass. Summing collisions, rather than overwriting a previous mass, implements the probability pushforward.
The sets of source atoms with a fixed image partition the original support. Hence nonnegativity is preserved and, in exact probability arithmetic,
Thus the result is a finite probability distribution. For a constant mapping, every atom merges into one outcome of mass one. Floating-point additions in the implementation can introduce rounding error, so numerical tests of normalization should use a suitable tolerance rather than demand exact equality of Double sums.
The integer congruence means : the difference is an integer multiple of the positive modulus . Write and for integers . Then
so addition preserves integer congruence. For multiplication,
The final coefficient is an integer, so multiplication also preserves integer congruence. These properties make addition and multiplication well defined on residue classes.
Polar form of a complex number Created 2026-10-06 Updated 2026-10-20
A nonzero complex number has polar form
where is its modulus and is an argument. The equality uses Euler's formula; sine and cosine recover the imaginary part and real part from polar coordinates. For , take and radians, so and .
If , then
Thus multiplication multiplies moduli and adds arguments modulo ; division divides moduli and subtracts arguments modulo . Since , multiplying by gives , of modulus and argument radians. One formula simultaneously describes its new size and direction.
Figure 1.
Complex multiplication rotates every direction and scales every length equally
. Details.
Repeated multiplication now becomes especially simple: for a positive integer . This explains the evenly spaced arguments of the roots of a complex number. For example, has modulus and principal argument radians. The Cartesian calculation and the polar form provide independent checks on both its location and its size. Choose polar form when the task concerns multiplication, division, or repeated turns; use real parts and imaginary parts for addition.
Polynomial identity testing Created 2026-09-24 Updated 2026-10-18
Polynomial identity testing asks whether a polynomial represented implicitly, such as by an arithmetic circuit or a remainder computation, is the zero polynomial.
Here zero means that every coefficient vanishes after collecting equal monomials in the polynomial ring. Testing equality of two polynomials amounts to testing for zero. An arithmetic circuit can permit cheap polynomial evaluation even when expanding all monomials is expensive. The random evaluation test for a polynomial identity exploits this: one nonzero value disproves the polynomial identity, while a known total degree limits how often a nonzero polynomial can evade detection.[ref]
For example, for an integer , has distinct monomials, one for each subset of the variables. Its factored expression needs only additions and multiplications for one polynomial evaluation. Evaluating the compact expression avoids creating its expanded list of coefficients. The saving is especially attractive in many variables; it does not make a zero result into a proof of identity.
Positional notation Created 2026-09-29 Updated 2026-10-14
In positional notation, a numeral digit contributes its value multiplied by a weight determined by its position. Fix an integer radix . A finite string of numeral digits , with , represents the nonnegative integer
The rightmost position has weight ; each move left multiplies the weight by . This weight is the place value. For a nonzero integer, the canonical string has . Zero is written with the single numeral digit . Leading zeros are permitted in a fixed-width display but omitted in the canonical form: . A negative integer is written with a separate minus sign and the positional notation for its absolute value; the minus sign is not a numeral digit.[ref]
For example,
The zero is essential inside this string: , not . It records that the tens position contributes nothing while keeping the hundreds and units in their proper positions. The same integer has binary representation
Figure 1.
One integer, two encodings:
. Each numeral digit is multiplied by its place value. Decimal uses the weights ; binary uses . Zero digits preserve positions without contributing to the total. Both rows sum to . Details.
Repeated Euclidean division constructs the representation exactly. Set . At each step write
Keep the remainder and continue with the integer quotient . A positive quotient strictly decreases, so eventually it is zero. Substituting the successive equations back into the first gives : the numeral digits are obtained from right to left. The remainder modulo uniquely fixes , and then the quotient uniquely fixes the remaining string by the same reasoning. This proves existence and uniqueness once leading zeros are excluded. The needed unique quotient and remainder are precisely the conclusion of the Euclidean division theorem.[ref]
This finite expansion concerns nonnegative integers. Extending positional notation to fractional positions uses weights to the right of a point; an arbitrary real number need not have a finite digit string. In particular, the decimal representation represents , while the base-two string represents . The radix is part of the interpretation.
The benefit is compact arithmetic: positions can encode every nonnegative integer below . To see the upper endpoint, fill all positions with ; the finite geometric series gives . Carrying in addition exchanges units of one place value for one unit of the next. Thus a short string stores a large count and also supplies an algorithm for computing with it.
Power-map group action obstruction Created 2026-10-25 Updated 2026-10-31
Suppose a binary operation on the underlying set makes it a group, and is a group action on another group . Every acting element must induce a bijection, with inverse function given by its acting inverse element. The integer instead induces the constant function , where is the identity element of , so must be the trivial group. Conversely, on the trivial group, ordinary addition on supplies such a group action.
Prefix scan Created 2026-10-14 Updated 2026-10-20
A prefix scan computes successive accumulated results for an associative operation while keeping input order fixed. A scan based on addition produces prefix sums; one based on matrix multiplication produces successive ordered matrix products. Associativity allows regrouping, while commutativity is unnecessary because the order stays fixed. If an initial empty prefix is included, its value is the identity element for the chosen operation.
The ability to compute accumulated results does not by itself allow subtraction of two prefixes. For example, two accumulated minima cannot reveal a block minimum: the lists and both have successive minima , but the minimum of positions two through three is seven for one and two for the other. Prefix sums support block recovery because addition has additive inverses; an arbitrary associative operation need not have that property.
Prime field Created 2026-10-03 Updated 2026-10-14
The prime field of a field is its smallest subfield: the arithmetic forced upon us by the identity element . Every subfield must contain , its repeated sums, their additive inverses, and the multiplicative inverses of nonzero results. In characteristic zero these operations produce a copy of the rational numbers . In positive characteristic of a field , they produce a copy of , with addition and multiplication given by modular arithmetic.
For example, inside the field with four elements, repeated addition of gives . Thus its prime field is , and the other two elements cannot be reached by repeatedly adding . This is why a finite field need not consist entirely of ordinary integer residues: a larger finite field extends the arithmetic of its prime field with additional elements.
The positive characteristic of a field must be a prime number. If its least vanishing multiple of were with , then would exhibit zero divisors. The absence of zero divisors rules this out. The prime field supplies the scalars when viewing as a vector space; its basis then explains the possible sizes of a finite field.
Primitive recursive pairing function Created 2026-10-06 Updated 2026-10-14
A primitive recursive pairing function is a pairing function whose encoding function and both coordinate functions of its inverse function are primitive recursive functions. Thus the bijection can be used in either direction inside a construction by primitive recursion and function composition in recursion theory. A decoder that is merely a computable function would not establish this stronger closure property. Sutner's definition of a primitive recursive pairing system explicitly includes the decoding functions; his more general systems need only be injective, whereas a pairing function here is a bijection.[ref]
The Cantor pairing function is a primitive recursive pairing function. For its encoding, construct the triangular numbers directly by primitive recursion:
Since addition is primitive recursive, so are and by primitive recursion and function composition in recursion theory. This establishes the claim without treating division by two as an unexplained primitive operation.
For decoding, use bounded minimization to define
The bound is valid for every natural number : , so the candidate always succeeds. The search includes zero; when , it immediately returns . If , the preceding candidate failed, which gives ; when , that lower inequality follows from . Thus this search finds exactly the diagonal in the Cantor pairing function inverse, with
The comparison is primitive recursive, and bounded minimization of a primitive recursive predicate is primitive recursive. Therefore is a primitive recursive function. Recover the coordinates by
In constructions on the natural numbers, implement these subtractions using the primitive recursive operation : apply the predecessor function times to by primitive recursion. On these inputs it agrees with ordinary subtraction, since the diagonal inequalities imply . Consequently and are primitive recursive functions, and . Zimmermann proves the relevant closure under bounded minimization and the primitive recursive character of the Cantor encoding and coordinate decoding; his convention adds the first coordinate, so its coordinates are exchanged relative to here.[ref]
For a worked bounded minimization, take . Candidates give , none exceeding . Candidate gives , so , , and . The search bound was ; it terminates much earlier in this example. The bound proves membership in the primitive recursive functions; it is not a claim that scanning all candidates is the fastest implementation.
For each fixed , define a tuple encoder by
Each and each coordinate decoder is primitive recursive, by finitely many applications of function composition in recursion theory to . For the three-entry tuple encoded as , applying returns , applying returns , and then , . The tuple length remains part of the agreed convention, as explained for a general pairing function.
This makes primitive recursive pairing functions useful for encoding several evolving values as one state in primitive recursion. For example, store consecutive Fibonacci numbers as and update by
The codes start , decoding to . Every step uses primitive recursive encoding, decoding and addition; a single numerical state therefore carries the two values needed for the next step. This is also the reason a suitable Gödel numbering should permit sufficiently simple decoding: representation should preserve the class of functions being studied.
Quotient set Created 2026-09-28 Updated 2026-10-14
A quotient set packages each equivalence class as a single new set element. It remembers which class an original set element belongs to and forgets which member of that class it was. For an equivalence relation on a set ,
Each set element of the quotient set is itself a nonempty subset of . The canonical projection of a quotient set sends an original set element to this entire equivalence class. [ref]
For integer congruence modulo three restricted to , the quotient set is
It has cardinality three. The set is a choice of equivalence class representatives, not literally this quotient set: is an integer, while is a set. The function sending each chosen equivalence class representative to its equivalence class is a bijection between these two different sets.
Figure 1.
The quotient projection sends nine elements to three classes, with each class appearing as one fiber
. Details.
A quotient set alone specifies no arithmetic. To obtain the familiar modular arithmetic example with addition, use integer congruence on the whole set of integers. Its quotient set is , where is an infinite residue class. Define addition by
The answer must be independent of the equivalence class representatives. If and , then , so both sums have the same residue class. This is what it means for the group operation to be well-defined. With this addition, the quotient set is a cyclic group, with identity and inverse for . [ref]
For example, . Choosing and as different representatives of an equivalence class for gives the same sum; choosing and gives again. These calculations use residue classes of all integers. Raw addition on the finite does not stay in : . The formula for addition on therefore cannot be applied as a raw inherited operation on that finite example.
For every additive function , every real number , and every rational number , one has . This is the scalar multiplication part of being a linear map over the rational numbers.
First gives , and gives . Repeated addition gives for each positive integer , and the negative case follows from the sign identity. If with and , then
No continuity was used. In particular fixes , , and every other rational value, even for a discontinuous additive function.