Documentation

Core.NetworkPlusCal.Semantics.Denotational

The denotational semantics of Network PlusCal. Statement here is GuardedPlusCal.Statement minus receive, so every case below is that language's case verbatim — see Core/GuardedPlusCal/Semantics/Denotational.lean's module doc for what reducing/aborting/ diverging mean and why blocking and aborting are kept distinct.

The state space is shared, not re-declared: Behavior, ChanKey, FIFOs, LocalState, EvalStep and Ref.pathAborts are taken from GuardedPlusCal unchanged. This pass does not touch memories, channels or references — it only moves a receive out of the guard position and into a Thread.rx. Sharing the state space is also what lets a refinement between the two languages be stated without first transporting across two isomorphic copies of the same types.

Reduction of statements #

test e v is the identity transition restricted to states that evaluate e to v.

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

    The identity transition, i.e. nothing is performed.

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

      No statement can diverge — same as on the Guarded side.

      Equations
      Instances For

        The states from which a guard-class statement is blocked — same as on the Guarded side, minus receive (this language has none): await on a boolean that is not TRUE, or with x ∈ e on a (present but) empty set. The trace is 1.

        Equations
        Instances For

          Reduction of blocks and atomic branches #

          GuardedPlusCal.Block.reducing/.aborting/.diverging are generic in the statement family, so they are applied here directly rather than restated.

          A block of Network PlusCal statements, all of guard class g.

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

            A block of Network PlusCal statements, all of guard class g.

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

              A possibly-empty list of Network PlusCal statements — see GuardedPlusCal.Block.listReducing for why the shape exists alongside Block. Guarded2Network prepends one of these (a branch's consumption assignments) to an action block, and its refinement proof states the two factors separately.

              Equations
              Instances For

                A possibly-empty list of Network PlusCal statements — see GuardedPlusCal.Block.listReducing for why the shape exists alongside Block. Guarded2Network prepends one of these (a branch's consumption assignments) to an action block, and its refinement proof states the two factors separately.

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

                  A possibly-empty list of Network PlusCal statements — see GuardedPlusCal.Block.listReducing for why the shape exists alongside Block. Guarded2Network prepends one of these (a branch's consumption assignments) to an action block, and its refinement proof states the two factors separately.

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

                    A possibly-empty list of Network guards, blocked: some prefix reduces to a state at which the next guard blocks — the list counterpart of Statement.blockBlocking, mirroring Statement.listAborting.

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

                      The states from which an atomic branch is blocked: its precondition reduces to a state at which some later guard blocks. A bare action blocks nowhere.

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

                        Reduction of atomic blocks #

                        A block picks one of its branches nondeterministically — reducing/aborting/diverging as some branch, chosen from B.branches. Only needed on the NetworkPlusCal side: the refinement relation's target type is what needs the flat state encoding uniformly, the source stays quantified throughout since it is only ever existentially bound, never required to match the target's type. GuardedPlusCal therefore has no AtomicBlock semantics at all.

                        A block is blocked iff every one of its branches is: either is angelic, so it proceeds on any branch that can and blocks only when none can — the intersection over B.branches, where reducing/aborting/diverging take the union.

                        Equations
                        Instances For

                          Threads #

                          A .code thread has no denotation of its own. A process state is a memory together with a set of labels — at most one per thread — and one process step picks an enabled label l from that set, runs the atomic block the label names, and replaces l by the label the block's terminal goto jumped to. So a .code thread contributes exactly two things: the labels it owns, and the block each of those labels names. Everything else is the process- and algorithm-level fixed points.

                          Thread.rx is different. It owns no label, and its step consumes and produces none: it is a virtual thread whose meaning is the single step "read the head message off mailboxₚ and append it to inboxₚ", taken whenever mailboxₚ is non-empty and with no tmpₚ variable — the value goes straight from the channel into inboxₚ. It contributes one thing: Thread.rxStep, a label-free reducing step handed to the process layer through CodeTable.relay. Thread.rx's label field names the Go loop the thread compiles to and has no part in this semantics.

                          The labels a thread owns. A .code thread owns its blocks' labels; a .rx thread owns none — its step is label-free.

                          Equations
                          Instances For

                            The one reducing step a receiving thread contributes: read the head message off chan and append it to the inbox sequence, leaving every scheduled label untouched. Written directly rather than built from Statements, because NetworkPlusCal.Statement has no receive and the paper's tmpₚ is never assigned.

                            The step is silent: reception is not in Behavior's alphabet (GuardedPlusCal's Semantics/Denotational.lean). Moving a message from chan into inbox changes no observable; that the two together hold what the source's channel holds is the refinement invariant's job. An empty channel yields no step — a receiving thread then waits, which the blocking semantics records.

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