Software Abstraction Cheat Sheet
How Formal Methods Compress Programs into Essential Structure
Abstraction here means: forget some implementation detail (mutation, allocation, scheduling, evaluation order, pointer layout…) while preserving the structure you need to reason about a property (correctness, safety, liveness, equivalence).
ℹ
Many examples are intentionally simplified to highlight the math. When a model is a toy
(e.g., email regex), it's labeled as such.
Part I
Foundational Models of Computation
1 Lambda Calculus
Core Idea
Everything is a function. Data, control flow, recursion: all encoded as function application.
Notation
λx.body defines function, (f a) applies function
Example 1
Factorial
Code (Python)
python
def factorial(n):
result = 1
for i in range(1, n + 1):
result *= i
return result
Lambda Calculus
lambda
fact = Y (λf. λn. if (iszero n) 1 (mult n (f (pred n))))
where:
Y = λf.(λx.f(x x))(λx.f(x x)) -- fixed-point combinator
mult = λm.λn.λf.m(n f) -- Church numerals
pred = λn.λf.λx.n(λg.λh.h(g f))(λu.x)(λu.u)
Example 2
Boolean Logic (AND)
Code (Python)
def and_gate(a, b):
if a == True:
if b == True:
return True
else:
return False
else:
return False
Lambda Calculus
TRUE = λx.λy.x
FALSE = λx.λy.y
AND = λp.λq.p q p
2 Turing Machines
Core Idea
Computation as mechanical state transitions over tape symbols.
Notation
δ(state, symbol) → (new_state, write_symbol, direction)
Example 1
Increment Binary Number
Code (Python)
def increment_binary(bits):
carry = 1
result = []
for bit in reversed(bits):
if carry:
if bit == '0':
result.append('1')
carry = 0
else:
result.append('0')
carry = 1
else:
result.append(bit)
if carry:
result.append('1')
return ''.join(reversed(result))
Turing Machine
States: {qcarry, halt}
Alphabet: {0, 1, □}
Transitions (add 1 with carry):
δ(qcarry, 0) = (halt, 1, L) -- flip 0→1, done
δ(qcarry, 1) = (qcarry, 0, L) -- flip 1→0, carry
δ(qcarry, □) = (halt, 1, L) -- overflow: new 1
3 Finite State Machines / Automata
Core Idea
Computation with finite memory. Captures "modes" and "transitions."
Notation
(States, Alphabet, δ, start, accept)
Vending Machine (click states to step)
3.5 Regular Expressions & Context-Free Structure
Core Idea
Regex/FA: finite "mode memory". CFG/PDA: finite control + unbounded stack (nesting).
Notation
Regex ⇄ NFA ⇄ DFA, CFG ⇄ PDA
Example
Balanced Parentheses
Code (Python)
def balanced(s):
count = 0
for c in s:
if c == '(': count += 1
elif c == ')': count -= 1
if count < 0: return False
return count == 0
CFG / PDA
CFG: S → SS | "(" S ")" | ε
PDA:
read '(' → push
read ')' → pop (reject if empty)
accept if stack empty at end
4 Recursive Function Theory
Core Idea
Build functions from zero, successor, projection, composition, and primitive recursion.
Notation
Z = 0, S(n) = n+1, h = Pr[f, g]
Example
Addition
Code
def add(m, n):
result = m
for _ in range(n):
result += 1
return result
Primitive Recursion
add(m, 0) = m -- base
add(m, S(n)) = S(add(m, n)) -- step
Formally: add = Pr[π₁, Cn[S, π₃]]
Part II
Semantic Frameworks
5 Denotational Semantics
Core Idea
Programs denote mathematical objects (functions). Meaning is compositional.
Notation
⟦program⟧ : Environment → Value
Example
While Loop
Code
x = 5
while x > 0:
x = x - 1
# x is now 0
Denotational
⟦while b do c⟧ = fix(F)
F = λφ.λσ. if ⟦b⟧σ = true
then φ(⟦c⟧σ)
else σ
6 Operational Semantics (Small-Step)
Core Idea
Meaning defined by reduction rules. How does the program step?
Notation
⟨config⟩ → ⟨config'⟩
Example
Arithmetic Reduction
Execution Trace
(2 + 3) * 4
= 5 * 4 # addition first
= 20 # then multiplication
Small-Step SOS
⟨(2+3)*4, σ⟩ → ⟨5*4, σ⟩
→ ⟨20, σ⟩
Rule: ⟨n₁+n₂, σ⟩ → ⟨n, σ⟩
7 Axiomatic Semantics (Hoare Logic)
Core Idea
Meaning = what you can prove. Specify pre/post conditions.
Notation
{P} C {Q} means "If P holds before C, then Q holds after"
Example
Loop with Invariant
Code
# Sum 1 to n
s = 0; i = 0
while i < n:
i = i + 1
s = s + i
# s = n(n+1)/2
Hoare Logic
{n ≥ 0}
{INV: s = i(i+1)/2 ∧ i ≤ n}
while i < n do body
{s = n(n+1)/2}
8 Separation Logic
Core Idea
Extend Hoare logic for heap/pointers with "separating conjunction."
Notation
P * Q means "P and Q hold on disjoint memory regions"
Example
Linked List Node
Code (C)
Node* n = malloc(sizeof(Node));
n->value = val;
n->next = NULL;
return n;
Separation Logic
{emp}
n := alloc(2);
{n ↦ _, _}
[n] := val; [n+1] := NULL;
{n ↦ val, NULL}
Part III
Type Theory and Logic
9 Type Systems
Core Idea
Classify expressions by "what kind of thing" they compute. Prevent errors statically.
Notation
Γ ⊢ e : τ means "in context Γ, expression e has type τ"
Example
Function Application
Code
def double(x: int) -> int:
return x * 2
result = double(5) # OK
# double("hi") # Type error!
Type Judgment
Γ ⊢ double : Int → Int
Γ ⊢ 5 : Int
────────────────────────
Γ ⊢ double(5) : Int
9.5 Refinement Types & Dependent Types
Core Idea
Types + predicates. Types can depend on values.
Notation
x : Int { x ≥ 0 }, Vec A n (vector of n elements)
10 Curry-Howard Correspondence
Core Idea
Types are propositions, programs are proofs. Logic and computation unified.
Notation
A → B = function, A × B = pair, A + B = Either
Correspondence
Programs = Proofs
Types (Programs)
A → B (function)
A × B (pair/tuple)
A + B (Either/union)
⊥ (Void/Never)
Logic (Proofs)
A ⟹ B (implication)
A ∧ B (conjunction)
A ∨ B (disjunction)
⊥ (false)
11 Category Theory for Programming
Core Idea
Abstract over structure-preserving transformations. Functors, natural transformations, monads.
Notation
Functor F : C → D, Monad M with return and bind
Part IV
Concurrency and Process Algebras
12 Process Algebra (CSP / CCS / π-calculus)
Core Idea
Concurrent processes as algebraic terms. Composition, synchronization as operators.
Notation
P = a → Q, P □ Q (choice), P ∥ Q (parallel)
12.5 Behavioral Equivalence
Core Idea
Compare systems by observable behavior: trace equivalence, bisimulation.
13 Petri Nets
Core Idea
Concurrent systems as bipartite graphs. Places hold tokens, transitions fire.
Notation
(P, T, F, M₀) where P=places, T=transitions, F=flow, M₀=initial marking
14 Temporal Logic (LTL / CTL)
Core Idea
Specify properties about time: what must/may eventually/always happen.
Notation
□ (always), ◇ (eventually), ○ (next), U (until)
Example
Safety & Liveness
Natural Language
"The mutex is never held
by two processes at once"
"Every request eventually
gets a response"
Temporal Logic
□(¬(holds₁ ∧ holds₂))
[SAFETY]
□(request → ◇response)
[LIVENESS]
Part V
Abstract Interpretation & Verification
15 Abstract Interpretation
Core Idea
Sound approximation via Galois connections. Trade precision for decidability.
Notation
(C, α, γ, A) where α abstracts, γ concretizes
Example
Sign Analysis
Concrete
x = 5 # x ∈ {5}
y = -3 # y ∈ {-3}
z = x * y # z ∈ {-15}
Abstract (Signs)
x = + # positive
y = - # negative
z = + × - = - # negative
16 Model Checking
Core Idea
Exhaustively verify temporal properties on finite-state models.
Notation
M ⊨ φ means "model M satisfies formula φ"
16.5 SAT/SMT Solving
Core Idea
Reduce program questions to constraint solving.
Notation
sat(φ), SMT, path constraints
Part VI
Data Abstraction
17 Abstract Data Types (ADTs)
Core Idea
Data = signature + axioms. Hide representation.
Notation
Operations + Laws (e.g.,
pop(push(s, x)) = s)
Example
Stack ADT
Implementation
class Stack:
def __init__(self):
self._data = []
def push(self, x):
self._data.append(x)
def pop(self):
return self._data.pop()
ADT Specification
Stack[T]
empty : Stack[T]
push : Stack[T] × T → Stack[T]
pop : Stack[T] → Stack[T] × T
pop(push(s, x)) = (s, x)
18 Relational Algebra
Core Idea
Data as mathematical relations. Query = algebraic expression.
Notation
σ (select), π (project), ⋈ (join), ∪ (union)
Example
Database Query
SQL
SELECT name, dept
FROM employees
WHERE salary > 50000
Relational Algebra
π_{name,dept}(
σ_{salary>50000}(employees)
)
Part VII
The Limits of Abstraction
19 Fundamental Limits
Core Idea
Rice's Theorem, Gödel's Incompleteness, and the Abstraction-Precision tradeoff.
⚠
Rice's Theorem: ANY non-trivial semantic property of programs is undecidable.
"Does this program halt?", "Is this program equivalent to that?" - all undecidable.
∞
Implication: Perfect analysis is impossible. All useful abstractions approximate.
This is why we need abstract interpretation, model checking, and other sound-but-incomplete methods.
Quick Reference Card
| Abstraction | Key Insight | Notation |
|---|---|---|
| Lambda Calculus | Everything is a function | λx.e, (f x) |
| Turing Machine | Mechanical state changes | δ(q,a)=(q′,b,D) |
| FSM | Modes + transitions | (Q, Σ, δ, q₀, F) |
| Denotational | Programs = math objects | ⟦P⟧ρ |
| Operational | Step-by-step reduction | ⟨e,σ⟩ → ⟨e′,σ′⟩ |
| Hoare Logic | Pre/post contracts | {P} C {Q} |
| Separation Logic | Disjoint heap regions | P * Q |
| Type Systems | Classify by kind | Γ ⊢ e : τ |
| Curry-Howard | Proofs = programs | Types = propositions |
| Category Theory | Structure preservation | Functor, Monad |
| Process Algebra | Concurrent composition | P ∥ Q, P □ Q |
| Petri Nets | Token flow | Places, transitions |
| Temporal Logic | Properties over time | □, ◇, U, AG, EF |
| Abstract Interp. | Sound approximation | (C, α, γ, A) |
| Model Checking | Exhaustive verification | M ⊨ φ |
| ADT | Signature + axioms | ops + laws |
| Relational Algebra | Data as relations | σ, π, ⋈, ∪ |