Arrays and Iteration
Array Sum (Linear Scan)
Walk an array once, accumulating each element into a running total. This is
the canonical single-pass linear scan and the simplest possible loop
invariant: after step i, total equals the sum of arr[0..i].
Algorithm
The canonical input from the lesson spec is
arr=(3 1 4 1 5 9 2 6). After eight passes the running total is 31.
linear scan
Visit each element exactly once in index order.
running total
`total` accumulates the sum as the loop advances.
Basic Implementation
basic.sql
Replay: real traced execution (multi-file project)
.mode list
.headers off
CREATE TABLE arr(idx INTEGER PRIMARY KEY, val INTEGER);
INSERT INTO arr(idx, val) VALUES
(0, 3), (1, 1), (2, 4), (3, 1), (4, 5), (5, 9), (6, 2), (7, 6);
WITH RECURSIVE walk(idx, total) AS (
SELECT 0, 0
UNION ALL
SELECT walk.idx + 1, walk.total + arr.val
FROM walk JOIN arr ON arr.idx = walk.idx
)
SELECT total FROM walk WHERE idx = (SELECT COUNT(*) FROM arr);
arr ← (empty)
1.mode list2.headers offvalues this step(empty)arrarr ← [3, 1, 4, 1, 5, 9, 2, 6]
1.mode list2.headers offvalues this step(empty) → [3, 1, 4, 1, 5, 9, 2, 6]arrwalk.idx ← 0, walk.total ← 0
1.mode list2.headers offvalues this step0walk.idx0walk.total[3, 1, 4, 1, 5, 9, 2, 6]arrwalk.idx ← 1, walk.total ← 3
1.mode list2.headers offvalues this step0 → 1walk.idx0 → 3walk.total3arr.valwalk.idx ← 2, walk.total ← 4
1.mode list2.headers offvalues this step1 → 2walk.idx3 → 4walk.total1arr.valwalk.idx ← 3, walk.total ← 8
1.mode list2.headers offvalues this step2 → 3walk.idx4 → 8walk.total4arr.valwalk.idx ← 4, walk.total ← 9
1.mode list2.headers offvalues this step3 → 4walk.idx8 → 9walk.total1arr.valwalk.idx ← 5, walk.total ← 14
1.mode list2.headers offvalues this step4 → 5walk.idx9 → 14walk.total5arr.valwalk.idx ← 6, walk.total ← 23
1.mode list2.headers offvalues this step5 → 6walk.idx14 → 23walk.total9arr.valwalk.idx ← 7, walk.total ← 25
1.mode list2.headers offvalues this step6 → 7walk.idx23 → 25walk.total2arr.valwalk.idx ← 8, walk.total ← 31
1.mode list2.headers offvalues this step7 → 8walk.idx25 → 31walk.total6arr.valstdout ← 31
1.mode list2.headers offvalues this step31stdout31walk.total
Trace Output
trace.sql
Replay: real traced execution (multi-file project)
.mode list
.headers off
CREATE TABLE arr(idx INTEGER PRIMARY KEY, val INTEGER);
INSERT INTO arr(idx, val) VALUES
(0, 3), (1, 1), (2, 4), (3, 1), (4, 5), (5, 9), (6, 2), (7, 6);
WITH RECURSIVE walk(step, before_total, val, total) AS (
SELECT 1, 0, arr.val, arr.val FROM arr WHERE arr.idx = 0
UNION ALL
SELECT walk.step + 1, walk.total, arr.val, walk.total + arr.val
FROM walk JOIN arr ON arr.idx = walk.step
)
SELECT line FROM (
SELECT step AS k,
'step ' || (step - 1) || ': arr(' || (step - 1) || ')='
|| val || ' total ' || before_total || ' -> ' || total AS line
FROM walk
UNION ALL
SELECT 999, 'final total = ' || total FROM walk
WHERE step = (SELECT COUNT(*) FROM arr)
)
ORDER BY k;
arr ← (empty)
1.mode list2.headers offvalues this step(empty)arrarr ← [3, 1, 4, 1, 5, 9, 2, 6]
1.mode list2.headers offvalues this step(empty) → [3, 1, 4, 1, 5, 9, 2, 6]arrwalk.total ← 3, stdout ← step 0: arr(0)=3 total 0 -> 3
1.mode list2.headers offvalues this step3walk.totalstep 0: arr(0)=3 total 0 -> 3stdout0step3arr.val0before_totalwalk.total ← 4, stdout ← step 1: arr(1)=1 total 3 -> 4
1.mode list2.headers offvalues this step4walk.totalstep 1: arr(1)=1 total 3 -> 4stdout1step1arr.val3before_totalwalk.total ← 8, stdout ← step 2: arr(2)=4 total 4 -> 8
1.mode list2.headers offvalues this step8walk.totalstep 2: arr(2)=4 total 4 -> 8stdout2step4arr.val4before_totalwalk.total ← 9, stdout ← step 3: arr(3)=1 total 8 -> 9
1.mode list2.headers offvalues this step9walk.totalstep 3: arr(3)=1 total 8 -> 9stdout3step1arr.val8before_totalwalk.total ← 14, stdout ← step 4: arr(4)=5 total 9 -> 14
1.mode list2.headers offvalues this step14walk.totalstep 4: arr(4)=5 total 9 -> 14stdout4step5arr.val9before_totalwalk.total ← 23, stdout ← step 5: arr(5)=9 total 14 -> 23
1.mode list2.headers offvalues this step23walk.totalstep 5: arr(5)=9 total 14 -> 23stdout5step9arr.val14before_totalwalk.total ← 25, stdout ← step 6: arr(6)=2 total 23 -> 25
1.mode list2.headers offvalues this step25walk.totalstep 6: arr(6)=2 total 23 -> 25stdout6step2arr.val23before_totalwalk.total ← 31, stdout ← step 7: arr(7)=6 total 25 -> 31
1.mode list2.headers offvalues this step31walk.totalstep 7: arr(7)=6 total 25 -> 31stdout7step6arr.val25before_totalstdout ← final total = 31
1.mode list2.headers offvalues this stepfinal total = 31stdout31walk.total
Complexity
- Time: O(n)
- Space: O(1)
Implementation notes
- SQL: the array is modeled as a two-column table
arr(idx INTEGER PRIMARY KEY, val INTEGER)so the loop index is the table's primary key and aWITH RECURSIVECTE can step through the rows one at a time.SELECT SUM(val) FROM arrwould jump straight to31without the running update the lesson is teaching, so the recursive CTE visits indices 0..7 explicitly and carries(idx, total)forward. - The CTE seed
SELECT 0, 0produces the empty-prefix invariant; the recursive arm joinswalktoarronarr.idx = walk.idxto read the current element, increments the index, and adds the value. - The final
SELECT total FROM walk WHERE idx = (SELECT COUNT(*) FROM arr)picks the row produced after the last addition. SQLite emits31under.mode listwith no headers, so the output is stable across releases. trace.sqlreuses the sameWITH RECURSIVEshape but carries(step, before_total, val, total)so each frame printsstep i: arr(i)=V total B -> T. The final line prints the canonicalfinal total = 31summary.