π_par: eliminates parallel assignment (r1βe1 β β¦ β rnβen) by hoisting every RHS, and every
compound Ref's own index expressions, into fresh with-bound temporaries evaluated up front,
then re-emitting n ordinary single-target assignments in the original order. Same type in,
same type out (ComputablePlusCal.Statement/.Block/.Branches). The invariant it establishes β
GuardedPlusCal.Statement.assign takes a single (Ref, Expr) pair β is a runtime fact about
ComputablePlusCal.Statement.assign's List, maintained by this pass alone rather than by the
type.
π_par(r1βe1 β β¦ β rnβen) =
with v1=e1 do β¦ with vn=en do (
π_par(r1, Ξ»r1. β¦) β¦ π_par(rn, Ξ»rn. β¦)
r1 := v1; β¦ ; rn := vn )
where π_par(x, f) = f(x)
π_par(r[e1,β¦,en], f) = π_par(r, Ξ»r0. with y1=e1 do β¦ with yn=en do f(r0[y1,β¦,yn]))
π_par(r.x, f) = π_par(r, Ξ»r0. f(r0.x))
Reference-recursion, generalized to this project's flat Ref.args : List (String β Expression) (the field-access prerequisite, Core/TypedPlusCal/Syntax.lean's module doc):
walked left to right, a .inl field segment passes straight through with no fresh variable
(the r.x case above), a .inr indexExpr segment binds one fresh temp (the r[e] case) β
simpler than a recursive-prefix formulation since this project's Ref is already flat, no
nested Ref-within-Ref.
A length-β€1 assignment list passes through untouched. Aliasing is only a concern between multiple simultaneous writes; running the general temp-var recipe on a single assignment would be correct but pure noise.
Every synthesized with carries its own ann : Typ field past this pass: FlatReord's walk
hands it, unchanged, to GuardedPlusCal.Statement.with's own ann field. The outer RHS bindings (vα΅’'s type must match rα΅’'s own
result type for rα΅’ := vα΅’ to be well-typed) and the inner index-temp bindings (each index
expression's own type) both get their real type now, via Ref.resultType/.indexType
respectively (Core/ComputablePlusCal/Syntax.lean) β cheap structural recomputation from
Ref.baseType, no re-running inference needed (Ref.baseType's own doc comment, Core/ TypedPlusCal/Syntax.lean, explains why).
π_par over a single statement β an ordinary congruence except at .assign, the one case
this pass actually rewrites.
π_par over a whole algorithm: applied per (label, Block) pair, across every thread of
every process.
Equations
- One or more equations did not get rendered due to their size.