Domain of a partial function Created 2026-10-03 Updated 2026-11-05
For a partial function , its domain of a partial function is the subset
Its restriction to is an ordinary function . Outside , function evaluation has no assigned value.
For instance, the real square root as a partial function on the real line has . Both and lie in the surrounding source, but only at zero is there an output; the value zero and absence of a value are different situations.
Partial function Created 2026-10-03 Updated 2026-11-05
A partial function from a set to a set assigns at most one function output in to each function input in . It can be treated as an ordinary function on a specified subset , its domain of a partial function. The surrounding source set can contain points at which no value is defined.
For example, real division by the argument gives the partial function on with . Being undefined at zero is different from assigning a default value there. A partial function with is defined at every allowed input.
Partial unary operation Created 2026-10-06 Updated 2026-11-05
A partial unary operation on a set is a partial function with specified domain of a function and values in . For example, is a partial unary operation on the real numbers with .
A function preserving partial unary operations and must send each into and satisfy . It need not reflect definedness: a point outside can still map into . Preservation therefore requires both a domain of a partial function condition and a value equality.
The machine characterization is computation by a Turing machine: the machine halts with exactly on inputs in the domain of a partial function and does not halt elsewhere. The syntactic characterization is the least class containing the initial functions of recursion theory and closed under composition of partial functions, primitive recursion and unbounded minimization. Such functions are the partial recursive functions, equivalently the partial computable functions.
For clarity, composition here is strict: is defined only when every inner value is defined and is defined on the resulting tuple. Likewise primitive recursion requires all preceding recursive values. The partial minimization is defined when such a exists and all earlier values are defined and nonzero; an undefined earlier value blocks the search.
A lambda-definable partial function is represented by a closed untyped lambda calculus term satisfying
On an input outside its domain there must be no Church numeral beta-equivalent to the result. A stronger representation can be arranged: undefined inputs have no head normal form.
Here are the components for proving that every partial recursive function is lambda-definable. Zero and projections are immediate; lambda definition of the successor function uses . Church Booleans encode a conditional by , with and . Put
Iteration takes to for , proving that encodes the predecessor function and that correctly tests zero.
Use a fixed-point combinator and the strict sequencing operation
For any numeral , reduces to . If the first argument has no head normal form, neither does the whole expression. Thus composition is implemented by nesting on every inner result before applying the outer representing term. This guard is important: an unguarded projection could discard an undefined inner computation.
For lambda definition of primitive recursion, with already represented by , take
The tuple notation abbreviates successive abstractions and applications. On numeral inputs, induction on proves the required recursion equations, including strict propagation of undefined preceding values. The beta reduction follows the selected conditional branch only.
For lambda definition of unbounded minimization, use
This searches in increasing order. An undefined value blocks the zero test; an infinite sequence of nonzero values continues forever; the first zero returns its numeral. Under normal-order beta reduction, both failure cases have no head normal form. Structural induction on partial-recursive declarations now supplies the stronger representation claimed above.
Conversely, beta reduction is an effective operation on finitely encoded lambda terms. Enumerate all finite reduction sequences from , stopping when a result is a Church numeral in beta-normal form. If , the Church-Rosser theorem gives a reduction to that numeral. It also makes the output unique. The enumeration therefore computes exactly the represented partial function; by the equivalence of the first two characterizations it is partial recursive. Hence
Apply part (b) to
There is an index such that . Its domain of a partial function is exactly
Therefore
The second partial function accepts this one's outputs. Put this method inside the invariant class in part (b):
def compose[V](that: PartialFn[U, V]): PartialFn[T, V] = {
  val pairs: List[(T, V)] = data.flatMap {
    case (x, y) => that.get(y).map(z => (x, z)).toList
  }
  new PartialFn[T, V](pairs)
}
The represented mapping is , since the paper explicitly applies that second despite the method name. A pair is emitted exactly when this mapping supplies a y and that.get(y) supplies a z. Hence its domain of a partial function is and its value there is . This is strict composition of partial functions: either missing stage makes the composite undefined. Repeated equal input pairs still produce the same output, preserving the representation invariant. With and pairs, direct association-list lookup gives worst-case time complexity, not a hidden constant-cost dictionary lookup.
Choose a fixed positive capacity and represent the abstract state by a finite partial function . Its domain of a partial function has at most members; each belongs to and is a fixed point:
The blocks of a set partition are the nonempty fibres of rep, and their shared values are their disjoint-set representatives. Initially , so . Representatives need not be the minimum members of their blocks.
trait DisjointSets {
  val capacity: Int
  // State: rep is a finite idempotent map, |dom rep| <= capacity.
  // Initially: rep is empty; capacity is fixed and positive.

  // Pre: x is absent and |dom rep| < capacity.
  // Post: add x -> x; leave every old mapping unchanged.
  def makeSet(x: Int): Unit

  // Pre: x belongs to dom rep.
  // Post: state unchanged; return rep(x).
  def find(x: Int): Int

  // Pre: x and y belong to dom rep.
  // Post: merge their blocks, retaining old rep(x).
  def union(x: Int, y: Int): Unit
}
Precisely, makeSet(x) extends the domain of a partial function by with . For union(x,y), snapshot and , keep unchanged, and set
This merges the two blocks and keeps the representative of the first argument's block. If , it is an identity operation. This deterministic design choice satisfies disjoint set union without imposing minimum-element representatives. The capacity bound is explicit in the abstract data type so that the bounded implementation does not silently strengthen makeSet's precondition.