Documentation

VCVio.Interaction.Concurrent.Observation

Observation equivalence for concurrent processes #

This file packages the notion of "what a party can tell apart" from concrete executions of a concurrent process.

The process semantics keeps the exact dependent type of each local observation, which is ideal when reasoning inside one fixed execution. But comparison across different executions, processes, or refinement layers needs a uniform carrier. The solution adopted here is to pack each local observation together with its type and then compare executions through these packed observations.

The resulting API provides:

This is the comparison layer later used by refinement and equivalence results.

PackedObs is a locally observed value packaged together with its observation type.

This is the simplest uniform carrier for local observations whose precise type may vary from one visited node to the next.

Instances For
    def Interaction.Concurrent.Observation.Step.Observed.toList {Party : Type u} [DecidableEq Party] {me : Party} {spec : Spec} {semantics : Spec.Decoration (StepContext Party) spec} {tr : spec.Transcript} :
    Step.Observed me semantics trList PackedObs

    Forget the dependent indices of an observed sequential transcript and keep only the concrete packed sequence of observations that was exposed locally.

    This is the uniform, comparison-friendly summary of what one party learned from one complete sequential step transcript.

    Instances For
      def Interaction.Concurrent.Observation.Step.obsList {Party : Type u} [DecidableEq Party] (me : Party) {P : Type v} (step : Step Party P) (tr : step.spec.Transcript) :

      obsList me step tr is the packed sequence of local observations available to the fixed party me while the sequential process step step executes along the transcript tr.

      This forgets the exact dependent observation types but keeps their concrete values in order, which makes it the basic comparison object for one process step.

      Instances For
        def Interaction.Concurrent.Observation.Process.Trace.observations {Party : Type u} [DecidableEq Party] {process : Process Party} (me : Party) {p : process.Proc} :
        process.Trace pList (List PackedObs)

        The per-step packed local observations exposed along a finite complete process trace.

        Each list element corresponds to one executed process step and stores the local observations that me obtained during that step.

        Instances For
          def Interaction.Concurrent.Observation.Process.Prefix.observations {Party : Type u} [DecidableEq Party] {process : Process Party} (me : Party) {p : process.Proc} {n : } :
          process.Prefix p nList (List PackedObs)

          The per-step packed local observations exposed along a finite process prefix.

          This is the prefix-level analogue of Trace.observations.

          Instances For
            def Interaction.Concurrent.Observation.Process.Prefix.Rel {Party : Type u} {left : Process Party} {right : Process Party} (rel : {pL : left.Proc} → {pR : right.Proc} → (left.step pL).spec.Transcript(right.step pR).spec.TranscriptProp) {pL : left.Proc} {pR : right.Proc} {n : } :
            left.Prefix pL nright.Prefix pR nProp

            Rel rel left right states that the two finite prefixes left and right match step-by-step according to the transcript relation rel.

            The length index forces the two prefixes to have the same number of executed steps.

            So Prefix.Rel is the generic finite-horizon comparison interface: the caller chooses what it means for one process step of left to match one process step of right, and Rel lifts that choice to whole finite prefixes.

            Instances For
              theorem Interaction.Concurrent.Observation.Process.Prefix.rel_cast {Party : Type u} {left : Process Party} {right : Process Party} (rel : {pL : left.Proc} → {pR : right.Proc} → (left.step pL).spec.Transcript(right.step pR).spec.TranscriptProp) {pL pL' : left.Proc} {pR pR' : right.Proc} {n : } (hL : pL = pL') (hR : pR = pR') (leftPrefix : left.Prefix pL n) (rightPrefix : right.Prefix pR n) :
              Rel (fun {pL : left.Proc} {pR : right.Proc} => rel) (cast leftPrefix) (cast rightPrefix) Rel (fun {pL : left.Proc} {pR : right.Proc} => rel) leftPrefix rightPrefix

              Transporting both prefixes along equal start states does not change their matching relation.

              @[reducible, inline]
              abbrev Interaction.Concurrent.Observation.Process.TranscriptRel {Party : Type u} (left : Process Party) (right : Process Party) :
              Type (max (max (max u_1 u_3) u_2) u_4)

              TranscriptRel left right is a cross-process relation on one complete process step transcript of left and one complete process step transcript of right.

              This is the basic matching interface used later by refinement, equivalence, and observation-preservation theorems.

              Instances For
                def Interaction.Concurrent.Observation.Process.TranscriptRel.top {Party : Type u} {left : Process Party} {right : Process Party} :
                TranscriptRel left right

                The permissive transcript relation that accepts every pair of transcripts.

                Instances For
                  def Interaction.Concurrent.Observation.Process.TranscriptRel.inter {Party : Type u} {left : Process Party} {right : Process Party} (first second : TranscriptRel left right) :
                  TranscriptRel left right

                  Conjunction of transcript relations.

                  This is useful when one refinement should preserve several observational features at once.

                  Instances For

                    Match two transcripts by equality of their current controlling parties.

                    Instances For
                      def Interaction.Concurrent.Observation.Process.TranscriptRel.byPath {Party : Type u} {left : Process Party} {right : Process Party} :
                      TranscriptRel left right

                      Match two transcripts by equality of their full controller paths.

                      Instances For
                        def Interaction.Concurrent.Observation.Process.TranscriptRel.byEvent {Party : Type u} {left : Process Party} {right : Process Party} {Event : Type w} (eventL : left.EventMap Event) (eventR : right.EventMap Event) :
                        TranscriptRel left right

                        Match two transcripts by equality of stable external event labels.

                        Instances For
                          def Interaction.Concurrent.Observation.Process.TranscriptRel.byTicket {Party : Type u} {left : Process Party} {right : Process Party} {Ticket : Type w} (ticketL : left.Tickets Ticket) (ticketR : right.Tickets Ticket) :
                          TranscriptRel left right

                          Match two transcripts by equality of stable tickets.

                          Instances For
                            def Interaction.Concurrent.Observation.Process.TranscriptRel.byObservation {Party : Type u} [DecidableEq Party] {left : Process Party} {right : Process Party} (me : Party) :
                            TranscriptRel left right

                            Match two transcripts by equality of the packed local observations exposed to one fixed party.

                            This is the relation that identifies executions that are observationally indistinguishable to me at the step level.

                            Instances For
                              theorem Interaction.Concurrent.Observation.Process.Prefix.currentControllers_eq_of_relByController {Party : Type u} {left : Process Party} {right : Process Party} {pL : left.Proc} {pR : right.Proc} {n : } {leftPrefix : left.Prefix pL n} {rightPrefix : right.Prefix pR n} (hrel : Rel (fun {pL : left.Proc} {pR : right.Proc} => TranscriptRel.byController) leftPrefix rightPrefix) :
                              leftPrefix.currentControllers = rightPrefix.currentControllers

                              Matching by current controller equality preserves the extracted controller sequence of finite prefixes.

                              theorem Interaction.Concurrent.Observation.Process.Prefix.controllerPaths_eq_of_relByPath {Party : Type u} {left : Process Party} {right : Process Party} {pL : left.Proc} {pR : right.Proc} {n : } {leftPrefix : left.Prefix pL n} {rightPrefix : right.Prefix pR n} (hrel : Rel (fun {pL : left.Proc} {pR : right.Proc} => TranscriptRel.byPath) leftPrefix rightPrefix) :
                              leftPrefix.controllerPaths = rightPrefix.controllerPaths

                              Matching by controller-path equality preserves the extracted controller path sequence of finite prefixes.

                              theorem Interaction.Concurrent.Observation.Process.Prefix.events_eq_of_relByEvent {Party : Type u} {left : Process Party} {right : Process Party} {Event : Type w} (eventL : left.EventMap Event) (eventR : right.EventMap Event) {pL : left.Proc} {pR : right.Proc} {n : } {leftPrefix : left.Prefix pL n} {rightPrefix : right.Prefix pR n} (hrel : Rel (fun {pL : left.Proc} {pR : right.Proc} => TranscriptRel.byEvent eventL eventR) leftPrefix rightPrefix) :
                              Process.Prefix.events eventL leftPrefix = Process.Prefix.events eventR rightPrefix

                              Matching by stable event equality preserves the extracted event sequence of finite prefixes.

                              theorem Interaction.Concurrent.Observation.Process.Prefix.tickets_eq_of_relByTicket {Party : Type u} {left : Process Party} {right : Process Party} {Ticket : Type w} (ticketL : left.Tickets Ticket) (ticketR : right.Tickets Ticket) {pL : left.Proc} {pR : right.Proc} {n : } {leftPrefix : left.Prefix pL n} {rightPrefix : right.Prefix pR n} (hrel : Rel (fun {pL : left.Proc} {pR : right.Proc} => TranscriptRel.byTicket ticketL ticketR) leftPrefix rightPrefix) :
                              Process.Prefix.tickets ticketL leftPrefix = Process.Prefix.tickets ticketR rightPrefix

                              Matching by stable ticket equality preserves the extracted ticket sequence of finite prefixes.

                              theorem Interaction.Concurrent.Observation.Process.Prefix.observations_eq_of_relByObservation {Party : Type u} [DecidableEq Party] (me : Party) {left : Process Party} {right : Process Party} {pL : left.Proc} {pR : right.Proc} {n : } {leftPrefix : left.Prefix pL n} {rightPrefix : right.Prefix pR n} (hrel : Rel (fun {pL : left.Proc} {pR : right.Proc} => TranscriptRel.byObservation me) leftPrefix rightPrefix) :
                              observations me leftPrefix = observations me rightPrefix

                              Matching by local observation equality preserves the packed observation sequence of finite prefixes for the chosen party.

                              def Interaction.Concurrent.Observation.Process.Run.observationsUpTo {Party : Type u} [DecidableEq Party] {process : Process Party} (me : Party) (run : process.Run) :

                              The per-step packed local observations exposed along the first n steps of the run run.

                              This is the infinite-run analogue of Prefix.observations, truncated to the first n steps.

                              Instances For
                                def Interaction.Concurrent.Observation.Process.Run.RelUpTo {Party : Type u} {left : Process Party} {right : Process Party} (rel : TranscriptRel left right) (leftRun : left.Run) (rightRun : right.Run) :
                                Prop

                                RelUpTo rel left right n states that the first n executed steps of the runs left and right match step-by-step according to rel.

                                This is the finite-prefix comparison predicate for runs.

                                Instances For
                                  def Interaction.Concurrent.Observation.Process.Run.Rel {Party : Type u} {left : Process Party} {right : Process Party} (rel : TranscriptRel left right) (leftRun : left.Run) (rightRun : right.Run) :

                                  Rel rel left right states that every finite prefix of the runs left and right matches according to rel.

                                  So two runs are related when they remain indistinguishable at every finite horizon under the chosen step-matching criterion.

                                  Instances For
                                    theorem Interaction.Concurrent.Observation.Process.Run.relUpTo_of_pointwise {Party : Type u} {left : Process Party} {right : Process Party} (rel : TranscriptRel left right) (leftRun : left.Run) (rightRun : right.Run) (hrel : ∀ (n : ), rel (leftRun.transcript n) (rightRun.transcript n)) (n : ) :
                                    RelUpTo (fun {pL : left.Proc} {pR : right.Proc} => rel) leftRun rightRun n

                                    Pointwise transcript matching implies prefix matching of the first n steps.

                                    theorem Interaction.Concurrent.Observation.Process.Run.rel_of_pointwise {Party : Type u} {left : Process Party} {right : Process Party} (rel : TranscriptRel left right) (leftRun : left.Run) (rightRun : right.Run) (hrel : ∀ (n : ), rel (leftRun.transcript n) (rightRun.transcript n)) :
                                    Rel (fun {pL : left.Proc} {pR : right.Proc} => rel) leftRun rightRun

                                    Pointwise transcript matching implies full run matching.

                                    theorem Interaction.Concurrent.Observation.Process.Run.currentControllersUpTo_eq_of_relUpTo_byController {Party : Type u} {left : Process Party} {right : Process Party} (leftRun : left.Run) (rightRun : right.Run) {n : } (hrel : RelUpTo (fun {pL : left.Proc} {pR : right.Proc} => TranscriptRel.byController) leftRun rightRun n) :

                                    Matching by current controller equality preserves the extracted controller sequence of the first n run steps.

                                    theorem Interaction.Concurrent.Observation.Process.Run.controllerPathsUpTo_eq_of_relUpTo_byPath {Party : Type u} {left : Process Party} {right : Process Party} (leftRun : left.Run) (rightRun : right.Run) {n : } (hrel : RelUpTo (fun {pL : left.Proc} {pR : right.Proc} => TranscriptRel.byPath) leftRun rightRun n) :

                                    Matching by controller-path equality preserves the extracted controller-path sequence of the first n run steps.

                                    theorem Interaction.Concurrent.Observation.Process.Run.eventsUpTo_eq_of_relUpTo_byEvent {Party : Type u} {left : Process Party} {right : Process Party} {Event : Type w} (eventL : left.EventMap Event) (eventR : right.EventMap Event) (leftRun : left.Run) (rightRun : right.Run) {n : } (hrel : RelUpTo (fun {pL : left.Proc} {pR : right.Proc} => TranscriptRel.byEvent eventL eventR) leftRun rightRun n) :
                                    Process.Run.eventsUpTo eventL leftRun n = Process.Run.eventsUpTo eventR rightRun n

                                    Matching by stable event equality preserves the extracted event sequence of the first n run steps.

                                    theorem Interaction.Concurrent.Observation.Process.Run.ticketsUpTo_eq_of_relUpTo_byTicket {Party : Type u} {left : Process Party} {right : Process Party} {Ticket : Type w} (ticketL : left.Tickets Ticket) (ticketR : right.Tickets Ticket) (leftRun : left.Run) (rightRun : right.Run) {n : } (hrel : RelUpTo (fun {pL : left.Proc} {pR : right.Proc} => TranscriptRel.byTicket ticketL ticketR) leftRun rightRun n) :
                                    Process.Run.ticketsUpTo ticketL leftRun n = Process.Run.ticketsUpTo ticketR rightRun n

                                    Matching by stable ticket equality preserves the extracted ticket sequence of the first n run steps.

                                    theorem Interaction.Concurrent.Observation.Process.Run.observationsUpTo_eq_of_relUpTo_byObservation {Party : Type u} [DecidableEq Party] (me : Party) {left : Process Party} {right : Process Party} (leftRun : left.Run) (rightRun : right.Run) {n : } (hrel : RelUpTo (fun {pL : left.Proc} {pR : right.Proc} => TranscriptRel.byObservation me) leftRun rightRun n) :
                                    observationsUpTo me leftRun n = observationsUpTo me rightRun n

                                    Matching by local observation equality preserves the packed observation sequence of the first n run steps for the chosen party.