One thread, compiled.
Thread.toNetwork (Guarded2Network/PlusCal.lean) maps stepBlock over the thread's blocks at a
ThreadState accumulator and hands back three things: the locals the pass invented, the receiving
threads it registered, and the compiled code thread itself. So this file is stepBlock_spec under
Spec.mapM_list, exactly as the level below is stepBranch_spec under it — and then the same
statement once more at .run {}, which is the form the pass's own body presents.
Two of the three outputs get a conclusion. The compiled thread is ThreadRefines, the blocks
pairwise BlockRefines; and the registered threads are RxOnly, each an .rx on this call's
inbox. The locals get none: they are a declaration list, and what a compiled process owes about
its declarations is a scoping question the process level asks, not a refinement one.
What one compiled code thread owes its source: it is a .code thread at all, and its blocks
are pairwise BlockRefines.
The .code half is not bookkeeping. A source thread is a list of blocks and a target thread is
either that or a receive loop, so "the compiled thread is not itself an .rx" is a real thing to
say — and it is what lets the process level split a compiled process's threads into the two groups
ProcessRefines.label_cases dispatches a label into, code or receiving.
Equations
- One or more equations did not get rendered due to their size.
Instances For
A thread one of whose blocks receives — the level at which the pass's registration promise is
finally cashed, Thread.toNetwork being what hands rxThreads back as a list of threads.
Equations
- Guarded2Network.ThreadReceives T = ∃ blk ∈ T, Guarded2Network.BlockReceives blk
Instances For
One thread, compiled. The walk, plus reading the accumulator apart into the pass's three outputs.
Everything difficult already happened in stepBlock_spec; what this adds is the ThreadRefines
packaging and the fact that the returned thread is .code — Thread.toNetwork builds it, so that
half is rfl.