005 subflow transitive pure

✓ Passing This code compiles and runs correctly.

Code

// Layer 2 demonstration (positive case): a subflow dispatching ONLY
// into pure events should be transitively pure. Mirrors 410_010's
// negative case (subflow dispatching impure → transitively impure).
//
// Pairs with 410_010 to pin both directions of transitive propagation.

const std = @import("std");

// Pure operation
~event compute { x: i32 }
| result i32

~[pure] proc compute|zig {
    return .{ .result = x * 2 };
}

~event main {}

// Subflow dispatching pure event — should be transitively PURE
~compute(x: 21)
| result _ |> _
input.kz

Test Configuration

MUST_RUN

Post-validation Script:

#!/bin/bash
# Verify: subflow dispatching ONLY pure events is transitively pure.
# Layer 2 positive case — mirrors 410_010's negative case.

if [ ! -f "backend.zig" ]; then
    echo "✗ backend.zig not found"
    exit 1
fi

# AST literal moved from backend.zig to program_ast.zig (split landed 2026-05-20).
# Concatenate both so grep -n / sed -n by line number still work.
cat backend.zig program_ast.zig 2>/dev/null > _combined_emit.zig

# Confirm the compute proc has the expected pure flags (sanity check)
PROC_LINE=$(grep -n 'proc_decl = ProcDecl' _combined_emit.zig | while read line; do
    linenum=$(echo "$line" | cut -d: -f1)
    if sed -n "$((linenum)),$((linenum + 5))p" _combined_emit.zig | grep -q '"compute"'; then
        echo "$linenum"
        break
    fi
done)

if [ -z "$PROC_LINE" ]; then
    echo "✗ Could not find compute proc"
    exit 1
fi

PROC=$(sed -n "$((PROC_LINE)),$((PROC_LINE + 15))p" _combined_emit.zig)

if echo "$PROC" | grep -q 'is_pure = true'; then
    echo "✓ compute proc: is_pure = true"
else
    echo "✗ FAIL: compute should be is_pure = true (~[pure])"
    exit 1
fi

if echo "$PROC" | grep -q 'is_transitively_pure = true'; then
    echo "✓ compute proc: is_transitively_pure = true"
else
    echo "✗ FAIL: compute should be is_transitively_pure = true"
    exit 1
fi

# Find the top-level subflow that dispatches compute
FLOW_LINE=$(grep -n '\.flow = Flow{' _combined_emit.zig | while read line; do
    linenum=$(echo "$line" | cut -d: -f1)
    if sed -n "$((linenum)),$((linenum + 10))p" _combined_emit.zig | grep -q '"compute"'; then
        echo "$linenum"
        break
    fi
done)

if [ -z "$FLOW_LINE" ]; then
    echo "✗ Could not find Flow dispatching compute"
    exit 1
fi

FLOW=$(sed -n "${FLOW_LINE},$((FLOW_LINE + 50))p" _combined_emit.zig)

if echo "$FLOW" | grep -q '.is_pure = true'; then
    echo "✓ subflow: is_pure = true (Layer 1 — composition is locally pure)"
else
    echo "✗ FAIL: subflow should be is_pure = true ALWAYS"
    exit 1
fi

if echo "$FLOW" | grep -q '.is_transitively_pure = true'; then
    echo "✓ subflow: is_transitively_pure = true (dispatches only into pure events)"
else
    echo "✗ FAIL: subflow should be is_transitively_pure = TRUE"
    echo "  It dispatches compute (pure) — transitive purity should propagate"
    exit 1
fi

echo ""
echo "✓ Subflow correctly marked transitively pure when dispatching only pure events"
exit 0