Abstract syntax tree precedence example Created 2026-10-13 Updated 2026-10-31
Consider Python programs
x=2+3*4 and x=(2+3)*4. Operator precedence places multiplication inside the right operand of addition in the first abstract syntax tree. The parentheses instead place addition inside the left operand of multiplication in the second. Their right-hand sides evaluate to and . No rule that simply reads all operators left to right would recover both structures. [ref]https://docs.python.org/3.14/reference/expressions.html#operator-precedence. Python language reference, section 6.17, multiplicative operators bind more tightly than additive operators
Two abstract syntax trees for variable assignment: operator precedence gives
. Details. x=2+3*4 the value , while parentheses give x=(2+3)*4 the value These are schematic views of Python trees:
Module is omitted, and the Add/Mult and Store markers are written inside their owning nodes. In the actual schema, BinOp has left, op and right fields; Assign has a list of targets and a value. Name(id='x', ctx=Store()) marks the name as a variable assignment target. Reading x in a program expression instead uses Load. A variable assignment is a statement, not an equation asserting that two values are equal. [ref]A restricted recursive evaluator can follow those fields. It accepts only integer literal values and binary addition, subtraction and multiplication; the surrounding variable assignment remains a separate action. Using
type(value) is int excludes Boolean constants, even though Python treats bool as a subclass of int.import ast
OPS = {ast.Add: lambda a, b: a + b,
ast.Sub: lambda a, b: a - b,
ast.Mult: lambda a, b: a * b}
def evaluate(node):
if isinstance(node, ast.Constant) and type(node.value) is int:
return node.value
if isinstance(node, ast.BinOp) and type(node.op) in OPS:
return OPS[type(node.op)](evaluate(node.left), evaluate(node.right))
raise ValueError("outside the integer-expression language")
for source in ("x=2+3*4", "x=(2+3)*4"):
tree = ast.parse(source, optimize=0)
statement = tree.body[0]
print(statement.targets[0].id, evaluate(statement.value))
# x 14
# x 20The children in a rooted tree have ordered roles:
left and right cannot be interchanged. For subtraction, 8-3 gives while 3-8 gives . Operator associativity also matters: 8-3-1 parses as (8-3)-1, giving , whereas 8-(3-1) gives . Here the syntax groups operators to the left; this does not assert the mathematical associativity of subtraction. Operator precedence determines grouping, rather than a general permission to reorder execution. For example, Python evaluates the calls in f()+g()*h() in the order f, g, h, although the multiplication result must be ready before the outer addition. [ref]https://docs.python.org/3.14/reference/expressions.html#evaluation-order. Python language reference, sections 6.16 and 6.17: left-to-right evaluation and left grouping of additive operators
Abstract syntax tree source location 2026-10-13
An abstract syntax tree can retain source locations even while omitting punctuation nodes. Python records one-based line numbers and zero-based UTF-8 byte offsets, with the end offset exclusive. In
x=2+3*4, the multiplication node spans offsets through , and ast.get_source_segment returns 3*4. A copied location on a folded 12 describes the original span, not text newly present in the source. Such metadata supports error messages and editing tools without making an abstract syntax tree a lossless record of formatting. [ref]ast — Abstract syntax trees, Python 3.14 documentation. Node classes: lineno, col_offset, end_lineno and end_col_offset; get_source_segment and copy_location
// Target: computer-science.bigb
Addition Created 2026-09-24 Updated 2026-10-13
Addition combines two numbers into their sum. For natural numbers, joining disjoint collections of sizes gives a collection of size . On a number line, adding shifts a starting position by : rightward when and leftward when .
Starting at and adding reaches . Starting there and adding returns to , because . Additive inverses turn this return move into an algebraic rule. With real numbers, addition is commutative and associative: exchanging two shifts or grouping several shifts differently leaves the final position unchanged.
Addition shifts positions on a number line, while a negative multiplication factor changes both scale and direction
. Details. The bottom panel applies . Input becomes , and input becomes . Multiplication by a negative real number rescales distances from zero and reverses direction, giving a reflection in mathematics as well as a scale change. This is a different operation from shifting every input by one fixed amount.
Addition chain 2026-10-20
An addition chain for a positive integer is , where each is the sum of two earlier entries, which may coincide. It computes in multiplications by reusing previously computed powers. For example, computes in five multiplications.
Arbitrary-precision arithmetic 2026-10-20
Integer arithmetic in which storage grows with the number of numerical digits needed, instead of imposing a fixed word size. It allows exact addition, multiplication, and exponentiation on large integers, subject to available memory; operation costs grow with operand length.
Arithmetic Created 2026-09-24 Updated 2026-10-13
Arithmetic studies operations on numbers: combining quantities by addition, finding differences by subtraction, scaling through multiplication, and reversing a nonzero scale through division. Its usefulness goes beyond producing an answer. A calculation can express how resources are shared, how a measurement changes with scale, or why two different descriptions of a quantity agree.
The allowed numbers matter. Start with the natural numbers . Counting collections gives , but removing three from two calls for the integer . Sharing three units equally between two recipients gives the rational number . These operations motivate larger number systems: integers supply additive inverses, and rational numbers supply division by nonzero integers. A real number can also express lengths such as a diagonal of Euclidean norm , which is not a rational number.
The beauty is that bookkeeping, geometry, and algebra can check one another. The same product counts three groups of six, measures the area of a rectangle, and splits as by distributivity. A number line makes negative integers visible as positions; a fraction records an exact share even when its decimal representation does not terminate. An arithmetic rule becomes easier to remember when these interpretations fit together.
Arithmetic circuit 2026-10-18
An arithmetic circuit is a Directed acyclic graph whose input nodes are variables or constants in a field, and whose internal gates perform addition, subtraction, or multiplication. Gates may reuse earlier outputs, so the circuit can represent a polynomial without listing all its monomials.
Binary powering multiplication count Created 2026-10-14 Updated 2026-10-24
For the optimized left-to-right exponentiation by squaring algorithm, let be the length of the binary expansion of a positive integer , and let be its Hamming weight, the number of digits equal to one. There are exactly digits after the leading one, and exactly remaining ones. Therefore the count isHere counts squarings and counts further multiplications by the base; every squaring counts as one multiplication in . Assignment, digit reading, and any inversion are outside this count. The formula includes , which requires zero multiplications; define separately.
For a fixed length , the bounds are . A power of two reaches the lower bound because its Hamming weight is one; reaches the upper bound because all digits are one. For , and , giving . Thus the arithmetic operation count is in Big O notation, but inputs of similar magnitude can have different counts.
Exact multiplication counts for optimized exponentiation by squaring depend on binary length and Hamming weight
. For positive exponents through , dots show , including each squaring. The dashed curves bound all counts at each binary length. Successive multiplication needs operations. The second panel compares squarings and further multiplications for exponents . These are exact counts, not timing measurements. Details.This is a count for the specified algorithm, not a claim that it always minimizes multiplications among all methods. For instance, at the count is six, but the powers with exponents can be built in five multiplications: square, multiply by , square, square, then multiply by the already stored . Saving operations this way uses a different schedule and stored intermediate powers.
Bit cost of modular exponentiation 2026-10-14
The binary powering multiplication count counts arithmetic operations. The time complexity measured in operations on individual bits also depends on operand lengths. Put , the binary length of the modulus, and let be the positive exponent's binary length. Stored residues use at most bits, and an unreduced product uses at most bits.
With ordinary long multiplication and division with remainder, one modular product costs operations on bits. Combining that cost with modular products givesThis bound includes reductions in the loop, and assumes the base has already been reduced and the exponent is available as a binary expansion. Reading the exponent takes additional work; initial reduction of a very long base depends on its input length, and an inverse for a negative exponent adds further work. More generally, if a modular product costs operations on bits, the powering loop costs . Faster multiplication and reduction methods can improve the quadratic bound.[ref]
For ordinary integer powers with , the output itself has binary digits. Even writing it takes work proportional to that length. Consequently multiplications does not imply operations on bits: the operands grow during ordinary exponentiation by squaring, whereas modular exponentiation keeps them bounded by the modulus. A squaring or multiplication by a small fixed base can also cost less than a general product, so equal counts need not mean equal running times.
Boolean matrix multiplication 2026-10-31
For Boolean matrices, replace numerical addition by logical disjunction and multiplication by logical conjunction. Applied to adjacency matrices, the product records a walk formed by following one segment represented by the first matrix and one represented by the second. For an adjacency matrix on vertices, start from . Repeated squaring then computes reflexive transitive closure once the exponent reaches : the identity entries pad shorter walks, and every reachable pair has a simple path of length at most .
Chinese remainder theorem Created 2026-09-24 Updated 2026-10-20
The Chinese remainder theorem says that remainders modulo pairwise coprime positive integers can be specified independently. For pairwise coprime and , every prescribed list determines one congruence class modulo satisfying for all . It determines a class, rather than one unrestricted integer: adding a multiple of preserves every remainder.
For example, combine and . Write from the first condition. The second becomes . Since three has modular inverse two modulo five, , giving . The integers , and all work. The fifteen possibilities modulo fifteen correspond to the fifteen pairs in a three-by-five grid.
The theorem also preserves arithmetic: reducing an addition or a multiplication modulo each gives the same tuple as performing that operation on the corresponding congruence classes. In the language of quotient rings, reduction is a ring isomorphismOne large residue is thus an exact encoding of several smaller residues. This is useful for splitting arithmetic into smaller calculations and then reconstructing the result; MIT's modular arithmetic notes develop both the reconstruction and the product representation. [ref]
https://ocw.mit.edu/courses/18-200-principles-of-discrete-applied-mathematics-spring-2024/mit18_200_s24_lec15.pdf. Moitra, MIT 18.200, Lecture 15, section 4, Chinese remainder theorem
For a concrete multiplication, corresponds to and to modulo . Their componentwise product is , which reconstructs to , agreeing with .A constructive formula explains the independence. For , put and choose with , using a modular multiplicative inverse. Then is one modulo and zero modulo every other . Thereforehas the desired remainders. A modulus equal to one imposes no restriction and can be omitted. Uniqueness follows because a difference divisible by every is divisible by their product when they are pairwise coprime. This short construction gives a reusable algorithm as well as an existence statement.
The coprime hypothesis explains why every cell in the left grid is attainable. With integer moduli six and eight, a pair must agree modulo their greatest common divisor, two. There are twenty-four compatible pairs, rather than forty-eight arbitrary pairs; each corresponds to a class modulo the least common multiple, twenty-four. The Chinese remainder theorem for noncoprime moduli states the resulting compatibility rule.
Commutative ring Created 2026-09-24 Updated 2026-10-14
A commutative ring is a ring in which multiplication satisfies for every pair. The integers and the polynomial ring are examples. So is , the quotient ring whose elements are residue classes in modular arithmetic. We represent these by and reduce each sum or product to its remainder. All following calculations modulo use this convention.
In , , although neither factor is zero. Thus and are zero divisors: nonzero elements whose product with another nonzero element can vanish. Also . Removing the common factor would falsely assert . The entire row for multiplication by isThe repetitions explain the linear congruences directly. The equation has exactly the two solutions , whereas has none. A common factor can erase information, and a nonzero coefficient does not guarantee that an equation has a solution.
A unit in a ring is an element with a multiplicative inverse, meaning for some . In , the units are exactly and , since . The other nonzero elements, , are zero divisors; for , use . In a nonzero commutative ring, a unit cannot be a zero divisor: multiplying by its multiplicative inverse forces . But a nonzero element need not be a unit or a zero divisor: the integer is neither in .
By contrast, in , every row for a nonzero multiplier is a permutation of . Each such row contains exactly once, giving a multiplicative inverse: , , , and . Hence this commutative ring is a field. For example, now has the unique solution . Reading the tables reveals which algebraic steps the arithmetic permits.
Compilation arithmetic example 2026-10-14
Consider the program expression
x*(2+3)-4 in a deliberately small programming language. Its only program identifier is x, supplied as an integer input. Its literal values are nonnegative decimal numerals, interpreted as integers. Whitespace is ignored between lexical tokens. Its context-free grammar is:expression ::= term (("+" | "-") term)*
term ::= factor ("*" factor)*
factor ::= numeral | "x" | "(" expression ")"
numeral ::= digit digit*
digit ::= "0" | "1" | "2" | "3" | "4"
| "5" | "6" | "7" | "8" | "9"Here
* outside quotation marks means zero or more repetitions. Repeated operators are grouped to the left, specifying operator associativity; term gives multiplication higher operator precedence than addition and subtraction. Parentheses override that grouping. There is no unary minus, variable assignment, function call, or side effect in this language. Evaluation obtains each left operand before its right operand and uses exact integer arithmetic, with no fixed-width overflow.Lexical analysis recognizes
x, *, (, 2, +, 3, ), -, 4. Parsing constructs the concrete abstract syntax tree Sub(Mul(Name(x), Add(Int(2), Int(3))), Int(4)). Parentheses have done their work by making Add a child of Mul; they need not survive as nodes. Constant folding changes this to Sub(Mul(Name(x), Int(5)), Int(4)). It cannot replace Name(x) by a literal value because the input is supplied at execution. The resulting function of the input is .A compiler for our stack machine emits
LOAD x; PUSH 5; MUL; PUSH 4; SUB. LOAD x pushes the current input; PUSH n pushes the integer literal value n. Each binary instruction removes the top item as its right operand, then the next item as its left operand, and pushes the result. The instruction sequence is an intermediate representation that an interpreter can execute; no machine code has been emitted. A compact binary encoding could make it bytecode, but these printed instruction names are only a readable notation.Why does this compilation preserve the result? A structural induction supplies a short proof outline. Translating a literal value or
x appends its value to any initial stack. For a binary abstract syntax tree node, first translating the left child and then the right child appends the two operand values; the matching instruction replaces them by exactly the original operation's result. Previously present stack items remain intact. Constant folding also preserves the result because in the specified integer arithmetic. Together these facts explain agreement for every integer input, rather than merely agreement for one trial. Complex number Created 2026-09-24 Updated 2026-10-14
A complex number is , where are real numbers and the imaginary unit satisfies . The real part is and the imaginary part is : for they are and , respectively. Equality requires both coordinates to agree. Thus the complex plane gives each complex number a concrete position, while ordinary addition and multiplication become geometric operations.
For and , addition works coordinate by coordinate, whereas multiplication uses :These answers encode different motions: addition by is a translation, while multiplication by is a rotation combined with a uniform change of size. Keeping these pictures distinct prevents a common beginner's confusion.
The complex numbers form a field: every nonzero has a multiplicative inverse, computable using its complex conjugate and modulus. They also supply the missing solutions of a quadratic equation such as , namely . The surprising payoff is that extending arithmetic also makes Euclidean geometry easier to calculate. For a systematic introduction to these definitions, see Jeremy Orloff, MIT 18.04, topic 1, sections 1.3–1.5.
Complex plane Created 2026-09-24 Updated 2026-10-14
The complex plane identifies the complex number with the point in Cartesian coordinates. The horizontal coordinate is its real part, the vertical coordinate its imaginary part. Arrows from zero identify the same points with vectors. Adding moves to : every point undergoes the same translation.
Multiplication has a richer geometry. Multiplying by the imaginary unit sends to , a counterclockwise quarter-turn rotation. In particular . Multiplying by rotates through and scales every Euclidean distance by . More generally, multiplication by acts through the real matrixFor , this preserves oriented angles between nonzero displacement vectors: every direction turns equally. Its determinant is , while its common scale is . This is the elementary geometric reason complex numbers are so useful for conformal maps.
The name Argand plane recalls Jean-Robert Argand's geometric interpretation. In his 1813 article he explicitly reports publishing his Essai in 1806; the original article is available in Argand, Annales de mathématiques, volume 4, page 133. A [ref]
https://www.hist-math.fr/textes/Argand1874_QuantitesImaginaires.pdf. BnF scan of the 1874 second edition
preserves the essay and its geometric drawings. Reading these alongside a modern complex plane reveals how directions and lengths give arithmetic a visible meaning. Congruence modulo an ideal 2026-10-14
Two elements of a commutative ring are congruent modulo an ideal if their difference lies in that ideal, equivalently if their images in the quotient ring agree. This is an equivalence relation compatible with addition and multiplication. For and , it means every coefficient difference is divisible by .
Constant folding 2026-10-13
Constant folding replaces a program expression whose value is known during translation by a literal value. For
x=2+3*4, first replace the multiplication subtree by Constant(value=12), then replace the addition subtree by Constant(value=14). The variable assignment and its Store target survive: the result still assigns to x. This illustrates why a bottom-up abstract syntax tree traversal is convenient: replacing one child can make its parent eligible for the next replacement.Here is a deliberately small Python transformer. Calling
generic_visit first transforms the children; returning a node replaces the visited node. The location helpers retain or supply the metadata expected for compilation. [ref]ast — Abstract syntax trees, Python 3.14 documentation. NodeTransformer, generic_visit, copy_location and fix_missing_locations
class FoldIntegers(ast.NodeTransformer):
def visit_BinOp(self, node):
self.generic_visit(node)
if (isinstance(node.left, ast.Constant)
and isinstance(node.right, ast.Constant)
and type(node.left.value) is int
and type(node.right.value) is int
and type(node.op) in OPS):
value = OPS[type(node.op)](node.left.value, node.right.value)
return ast.copy_location(ast.Constant(value=value), node)
return node
tree = ast.parse("x=2+3*4", optimize=0)
folded = ast.fix_missing_locations(FoldIntegers().visit(tree))
namespace = {}
exec(compile(folded, "<folded example>", "exec"), namespace)
assert namespace["x"] == 14
assert ast.unparse(folded) == "x = 14"This transformer folds literal integer operands only. It leaves
a+3*4 as a+12, without inventing a value for the program identifier a. It leaves calls intact: replacing 0*f() by 0 could discard a side effect or a failure. Nor does it reassociate floating-point arithmetic, where changing parentheses can change rounding. For the supported integer arithmetic, a short structural induction explains correctness: a retained literal value has the same value; at each folded binary node, the already-correct child values are combined by exactly the original operation in the original left/right order. This claim concerns the supported fragment's values, not unrestricted equivalence of arbitrary Python programs. Continuous function Created 2026-09-24 Updated 2026-10-14
A continuous function sends sufficiently nearby function inputs to nearby function outputs. For a real-valued function and a point that is an accumulation point of , this meansThe approached value and the assigned value must agree. Continuity on means continuity at every point of the domain of a function. At an endpoint of an interval, only approaches inside that domain of a function count. The epsilon-delta definition of continuity below also applies at an isolated point, where continuity holds automatically.[ref]
Calculus Volume 1, §2.4 Continuity. §2.4, Continuity at a Point: definition; Continuity over an Interval: one-sided endpoint conditions
For the polynomial function , approaching makes the function output approach . The continuity bounds for the square function turn this observation into an explicit guarantee: implies . This is useful whenever a small error in an function input must produce a controlled error in an function output. The required input tolerance can depend on the point and on the chosen output tolerance.
The absolute value function is also a continuous function, including at zero: . But its left and right derivatives there are and , so it is not a differentiable function at zero. Continuity controls values without requiring a tangent line. Conversely, a differentiable function is continuous wherever it is differentiable: if , the difference tends to zero with .
Several useful consequences reuse this one local idea. Addition, multiplication and function composition preserve continuity; a quotient of functions is continuous where its denominator is nonzero. On an interval, the intermediate value theorem turns continuity into a guarantee that no intermediate function output is skipped. On a compact set, the extreme value theorem guarantees attained maximum and minimum values. Those extra hypotheses matter: continuity alone on an unbounded domain of a function does not provide a global bound or an attained global maximum.
A rational function such as is continuous on its domain of a function . Zero is excluded from that domain of a function; the missing point prevents a continuous extension there, but it does not make the existing map discontinuous at one of its actual inputs. Always state the domain of a function before judging continuity.
For a deterministic binary operation on an abstract data type, let be its specified operation on abstract values and the implementation on concrete states. For every permitted valid input pair , require bothThe first condition preserves the representation invariant. The second makes a commutative diagram: either execute and then apply the abstraction function, or apply the abstraction function to both inputs and then execute the abstract operation ; both paths reach the same value. These conditions state functional correctness of a completed operation; termination is an additional obligation for algorithm correctness.[ref]
8.3 Module Documentation. Sections 8.3.3, Commutative Diagrams, and 8.3.4, Representation Invariants: matching abstract results and preservation of valid representations
For addition in the unreduced rational representation, chooseFor example, represents , precisely the sum of and . The short correctness argument uses nonzero denominators: and imply , preserving the representation invariant, and
Correct rational addition makes both paths agree; an invariant-preserving incorrect operation gives a different value
. Details. Now consider an incorrect implementation that uses addition on the numerators and multiplication on the denominators:It preserves the representation invariant for every valid input pair because its denominator is still . Yet represents , not the specified sum . Even perfect checks of the representation invariant before and after this call would miss the error: the result is a legal representation of the wrong rational number.
The incorrect operation also exposes an accidental dependence on representation. Replace by the equivalent state while keeping . The correct operation gives , still representing ; the incorrect operation gives , representing instead of its previous . A correct addition must yield the same abstract result for equivalent inputs, although its concrete outputs may differ. This is why checks against the formal specification should compare abstract values, including unreduced representations and representations with a negative denominator, rather than demand identical stored pairs.
The calculation assumes exact integers. An implementation with bounded storage must additionally specify how it handles products and sums outside its supported range; the mathematical argument alone does not establish its functional correctness. The bounded queue with encapsulation illustrates the corresponding need to account for returned status values and failed operations, alongside the abstract state transition.
Coupled binary exponentiation 2026-10-31
To compute two nonnegative integer powers in one while loop, maintain a separate accumulator, current base and remaining exponent for each exponentiation by squaring. The paired loop invariant is and . For each positive remaining exponent, transfer its odd factor to its accumulator and halve the exponent while squaring its base. A zero remaining exponent is left unchanged. The mathematical integer is a loop variant: at least one positive term strictly decreases in every iteration. Both powers are therefore complete when the loop stops. The iteration count is , with constant space and a constant number of multiplications per iteration. This is an exact-arithmetic identity; floating-point rounding introduces a separate error in a numerical implementation.






