def gcd(a, b): # Euclid's algorithm while b != 0: # variant: b strictly decreases => termination a, b = b, a % b return a # invariant: gcd(a,b) preserved each step# gcd(45, 30) -> 15
💡 Common Mistake:Variant ≠ invariant ➔ termination needs a strictly-decreasing non-negative measure (here b); partial correctness alone does not prove halting.
When It Flips: a specific algorithm sets an upper bound; the problem sets the lower bound (Ω). When the algorithm's O meets the problem's Ω ➔ provably optimal.
📊 Exam Execution Trace
Manual Execution Trace
gcd(45, 30):
Step / State
Trigger Op
a
b
Variant b ↓
Return Payload
0 (Init)
init
45
30
30
−
1
a,b = b, a%b
30
15
15
−
2
a,b = b, a%b
15
0
0 → halt
−
3
return a
15
−
−
15
Applied Exercise
Problem: State the obligations that establish total correctness of gcd.
Derivation Proof / Hand-Calculation Walkthrough:
Final Extracted Output:gcd is totally correct — invariant gives partial correctness, variant b gives termination.
🧠 Active Recall
Distinguish partial correctness, termination, and total correctness, and name the proof device for each.
Hint: Separate “correct-if-halts” from “halts”, and combine them.
Answer
Short answer: Partial = loop invariant; termination = strictly-decreasing variant; total = both.
Why:Hoare logic ➔ {Pre}prog{Post} + a well-founded measure ⟹ from any pre-state it halts in a valid post-state.
"Solvable" and "efficiently solvable" differ — explain via tractability.
Hint: Decidability vs polynomial-time feasibility.
Answer
Short answer: An algorithm proves solvable; efficiency depends on asymptotic cost.
Why:P vs NP-hard ➔ polynomial = tractable; only-exponential-known = intractable — a correct but exponential algorithm shows solvability without tractability.
Why can one problem have many algorithms, and why does it matter?
Hint: The problem fixes the relation, not the method.
Answer
Short answer: A Computational Problem fixes only input→output ➔ many finite procedures satisfy it.
Why:Asymptotic divergence ➔ linear vs binary search are both correct but O(n) vs O(logn) — algorithm choice, not problem choice, drives scalability.