Documentation

Guarded2Network.PlusCal

Guarded2Network compiles a receive away entirely, replacing it with a real second kind of thread (NetworkPlusCal.Thread.rx) that loops draining a fresh process-local inbox sequence variable, and rewrites every later await/with guard that referenced the received value to read inbox instead — the guard's truth no longer depends on an abstract "did a message arrive" primitive, only on ordinary sequence operations (Head/Tail/Len) over inbox.

receive(c, x[0]);
await x[0] + y = 0;
receive(c, y);
await x[0] + y = 0;

compiles to (guards, symbolically, before any assignment runs):

await Len(inbox) > 0;
await [x EXCEPT ![0] = Head(inbox)][0] + y = 0;
await Len(inbox) > 1;
await [x EXCEPT ![0] = Head(inbox)][0] + Head(Tail(inbox)) = 0;

and the branch's action block gains, as its own new prefix (ordinary sequential assignments — no substitution needed here, since each one's Head(inbox) is read after the previous one's own inbox := Tail(inbox) has already run):

x[0] := Head(inbox); inbox := Tail(inbox); y := Head(inbox); inbox := Tail(inbox);
@[reducible, inline]

One process's channel/fifo element-type table — a channel name resolves to its already-checked element type directly (see the module doc above for why no wrapped Channel(_)/dom → Channel(_) shape ever needs matching here), built by merging global and process-local channels/fifos declarations. Looked up by a receive's channel Ref's base name, ignoring any index arguments — a channel's element type doesn't depend on which array slot is referenced.

Equations
Instances For

    The three sequence expressions this pass builds over inbox. Public, and namespaced rather than file-private, because the refinement proof has to state what they meanGuarded2Network/ Lemmas/Seq.lean's SeqBuiltins gives each one its evaluation law, and a law about a private definition cannot be written at all.

    Tail(e).

    Equations
    • One or more equations did not get rendered due to their size.
    Instances For

      Len(e) > n, n a literal Nat.

      Equations
      • One or more equations did not get rendered due to their size.
      Instances For

        One assignment's effect substituted into a guard-class statement — .with's bound expression or .await's condition, the only expression field either constructor carries. Delegates to ComputableTLAPlus.Expression.substRef, so a bare and a compound Ref behave here exactly as they do everywhere else substitution is applied.

        Public, namespaced and @[expose] for the same reasons convertActionStmt below is: the refinement proof's reorder lemmas (Guarded2Network/Lemmas/Reorder.lean) are stated against the pass's own substitution rather than against a re-derivation of it, and their proofs reduce through this body.

        Equations
        • One or more equations did not get rendered due to their size.
        Instances For

          Every receive processed so far (processPrecondition's newInstrs) substituted into a later guard — see the module doc's foldr/fold-direction explanation. The per-entry span plays no part in substitution and is dropped here.

          Equations
          • One or more equations did not get rendered due to their size.
          Instances For

            Every action-class constructor GuardedPlusCal.Statement/NetworkPlusCal.Statement share verbatim (all but receive, already compiled away above, and with, guard-class only) — Ref/ Multicast are the same types under both pinnings (Core/NetworkPlusCal/Syntax.lean reuses GuardedPlusCal.Ref/.Multicast directly), so this is a plain re-tagging, not a translation. Public and namespaced, not file-private: the refinement proof states its semantic equations (Guarded2Network/Lemmas/Statement.lean), and a lemma about a private definition cannot be written — and @[expose], so that the equations it satisfies are provable by rfl in another module rather than only inside this one.

            Equations
            • One or more equations did not get rendered due to their size.
            Instances For

              One process's channel table (already merged with that process's own local channels/fifos by Process.toNetwork) and its single shared inbox name (fresh once per process, shared by every thread of the process) drive the whole compilation: every AtomicBranch's precondition is walked (processPrecondition), its action block gets the resulting consumption assignments prepended, and a new .rx thread is added the first time this call encounters a not-yet-seen channel.

              Equations
              • One or more equations did not get rendered due to their size.
              Instances For
                Equations
                • One or more equations did not get rendered due to their size.
                Instances For
                  Equations
                  • One or more equations did not get rendered due to their size.
                  Instances For