Documentation

VCVio.ProgramLogic.Relational.Basic

Relational program-logic baseline #

This file defines RelTriple via the generic two-monad algebra interface MAlgRelOrdered, instantiated for OracleComp using coupling semantics.

HasCoupling and coupling lemmas remain as semantic bridge lemmas.

@[reducible, inline]

Relational postconditions over two output spaces.

Instances For

    Equality relation helper for same-type outputs.

    Instances For
      def OracleComp.ProgramLogic.Relational.CouplingPost {ι₁ ι₂ : Type u} {spec₁ : OracleSpec ι₁} {spec₂ : OracleSpec ι₂} [spec₁.Fintype] [spec₁.Inhabited] [spec₂.Fintype] [spec₂.Inhabited] {α β : Type} (oa : OracleComp spec₁ α) (ob : OracleComp spec₂ β) (R : RelPost α β) :

      Coupling-based semantic relational WP for OracleComp.

      Instances For
        @[implicit_reducible]
        noncomputable instance OracleComp.ProgramLogic.Relational.instMAlgRelOrdered {ι₁ ι₂ : Type u} {spec₁ : OracleSpec ι₁} {spec₂ : OracleSpec ι₂} [spec₁.Fintype] [spec₁.Inhabited] [spec₂.Fintype] [spec₂.Inhabited] :

        Relational algebra instance for OracleComp, based on coupling semantics.

        @[reducible, inline]
        abbrev OracleComp.ProgramLogic.Relational.RelWP {ι₁ ι₂ : Type u} {spec₁ : OracleSpec ι₁} {spec₂ : OracleSpec ι₂} [spec₁.Fintype] [spec₁.Inhabited] [spec₂.Fintype] [spec₂.Inhabited] {α β : Type} (oa : OracleComp spec₁ α) (ob : OracleComp spec₂ β) (R : RelPost α β) :

        Relational weakest precondition induced by MAlgRelOrdered for OracleComp.

        Instances For
          @[reducible, inline]
          abbrev OracleComp.ProgramLogic.Relational.RelTriple {ι₁ ι₂ : Type u} {spec₁ : OracleSpec ι₁} {spec₂ : OracleSpec ι₂} [spec₁.Fintype] [spec₁.Inhabited] [spec₂.Fintype] [spec₂.Inhabited] {α β : Type} (oa : OracleComp spec₁ α) (ob : OracleComp spec₂ β) (R : RelPost α β) :

          Relational Hoare-style triple with implicit precondition True.

          Instances For
            @[simp]
            theorem OracleComp.ProgramLogic.Relational.relTriple_iff_relWP {ι₁ ι₂ : Type u} {spec₁ : OracleSpec ι₁} {spec₂ : OracleSpec ι₂} [spec₁.Fintype] [spec₁.Inhabited] [spec₂.Fintype] [spec₂.Inhabited] {α β : Type} {oa : OracleComp spec₁ α} {ob : OracleComp spec₂ β} {R : RelPost α β} :
            RelTriple oa ob R RelWP oa ob R
            @[simp]
            theorem OracleComp.ProgramLogic.Relational.relWP_iff_couplingPost {ι₁ ι₂ : Type u} {spec₁ : OracleSpec ι₁} {spec₂ : OracleSpec ι₂} [spec₁.Fintype] [spec₁.Inhabited] [spec₂.Fintype] [spec₂.Inhabited] {α β : Type} {oa : OracleComp spec₁ α} {ob : OracleComp spec₂ β} {R : RelPost α β} :
            RelWP oa ob R CouplingPost oa ob R
            def OracleComp.ProgramLogic.Relational.HasCoupling {ι₁ ι₂ : Type u} {spec₁ : OracleSpec ι₁} {spec₂ : OracleSpec ι₂} [spec₁.Fintype] [spec₁.Inhabited] [spec₂.Fintype] [spec₂.Inhabited] {α β : Type} (oa : OracleComp spec₁ α) (ob : OracleComp spec₂ β) :

            Existence of an SPMF coupling witness between two computations.

            Instances For
              theorem OracleComp.ProgramLogic.Relational.hasCoupling_of_relTriple {ι₁ ι₂ : Type u} {spec₁ : OracleSpec ι₁} {spec₂ : OracleSpec ι₂} [spec₁.Fintype] [spec₁.Inhabited] [spec₂.Fintype] [spec₂.Inhabited] {α β : Type} {oa : OracleComp spec₁ α} {ob : OracleComp spec₂ β} {R : RelPost α β} (h : RelTriple oa ob R) :

              Any relational triple yields a coupling witness.

              theorem OracleComp.ProgramLogic.Relational.relTriple_pure_pure {ι₁ ι₂ : Type u} {spec₁ : OracleSpec ι₁} {spec₂ : OracleSpec ι₂} [spec₁.Fintype] [spec₁.Inhabited] [spec₂.Fintype] [spec₂.Inhabited] {α β : Type} {a : α} {b : β} {R : RelPost α β} (h : R a b) :
              RelTriple (pure a) (pure b) R

              Pure values on both sides: R a b implies the coupling.

              theorem OracleComp.ProgramLogic.Relational.relTriple_refl {ι₁ : Type u} {spec₁ : OracleSpec ι₁} [spec₁.Fintype] [spec₁.Inhabited] {α : Type} (oa : OracleComp spec₁ α) :
              RelTriple oa oa (EqRel α)

              Reflexivity rule for relational triples on equality.

              theorem OracleComp.ProgramLogic.Relational.relTriple_post_mono {ι₁ ι₂ : Type u} {spec₁ : OracleSpec ι₁} {spec₂ : OracleSpec ι₂} [spec₁.Fintype] [spec₁.Inhabited] [spec₂.Fintype] [spec₂.Inhabited] {α β : Type} {oa : OracleComp spec₁ α} {ob : OracleComp spec₂ β} {R R' : RelPost α β} (h : RelTriple oa ob R) (hpost : ∀ ⦃x : α⦄ ⦃y : β⦄, R x yR' x y) :
              RelTriple oa ob R'

              Postcondition monotonicity for relational triples.

              theorem OracleComp.ProgramLogic.Relational.relTriple_bind {ι₁ ι₂ : Type u} {spec₁ : OracleSpec ι₁} {spec₂ : OracleSpec ι₂} [spec₁.Fintype] [spec₁.Inhabited] [spec₂.Fintype] [spec₂.Inhabited] {α β γ δ : Type} {oa : OracleComp spec₁ α} {ob : OracleComp spec₂ β} {fa : αOracleComp spec₁ γ} {fb : βOracleComp spec₂ δ} {R : RelPost α β} {S : RelPost γ δ} (hxy : RelTriple oa ob R) (hfg : ∀ (a : α) (b : β), R a bRelTriple (fa a) (fb b) S) :
              RelTriple (oa >>= fa) (ob >>= fb) S

              Bind composition rule for relational triples.

              theorem OracleComp.ProgramLogic.Relational.relTriple_eqRel_of_eq {ι₁ : Type u} {spec₁ : OracleSpec ι₁} [spec₁.Fintype] [spec₁.Inhabited] {α : Type} {oa ob : OracleComp spec₁ α} (h : oa = ob) :
              RelTriple oa ob (EqRel α)

              Equality of programs gives an equality-relation relational triple.

              theorem OracleComp.ProgramLogic.Relational.relTriple_eqRel_of_evalDist_eq {ι₁ ι₂ : Type u} {spec₁ : OracleSpec ι₁} {spec₂ : OracleSpec ι₂} [spec₁.Fintype] [spec₁.Inhabited] [spec₂.Fintype] [spec₂.Inhabited] {α : Type} {oa : OracleComp spec₁ α} {ob : OracleComp spec₂ α} (h : evalDist oa = evalDist ob) :
              RelTriple oa ob (EqRel α)

              Equality of evaluation distributions gives an equality-relation relational triple.

              theorem OracleComp.ProgramLogic.Relational.relTriple_of_evalDist_eq {ι₁ ι₂ : Type u} {spec₁ : OracleSpec ι₁} {spec₂ : OracleSpec ι₂} [spec₁.Fintype] [spec₁.Inhabited] [spec₂.Fintype] [spec₂.Inhabited] {α : Type} {oa : OracleComp spec₁ α} {ob : OracleComp spec₂ α} {R : RelPost α α} (h : evalDist oa = evalDist ob) (hR : ∀ (x : α), R x x) :
              RelTriple oa ob R

              If two computations have equal output distributions, any reflexive postcondition holds.

              theorem OracleComp.ProgramLogic.Relational.relTriple_eqRel_of_probOutput_eq {ι₁ ι₂ : Type u} {spec₁ : OracleSpec ι₁} {spec₂ : OracleSpec ι₂} [spec₁.Fintype] [spec₁.Inhabited] [spec₂.Fintype] [spec₂.Inhabited] {α : Type} {oa : OracleComp spec₁ α} {ob : OracleComp spec₂ α} (h : ∀ (x : α), Pr[= x | oa] = Pr[= x | ob]) :
              RelTriple oa ob (EqRel α)

              Pointwise output-probability equality gives an equality-relation relational triple.

              theorem OracleComp.ProgramLogic.Relational.probOutput_eq_of_relTriple_eqRel {ι₁ ι₂ : Type u} {spec₁ : OracleSpec ι₁} {spec₂ : OracleSpec ι₂} [spec₁.Fintype] [spec₁.Inhabited] [spec₂.Fintype] [spec₂.Inhabited] {α : Type} {oa : OracleComp spec₁ α} {ob : OracleComp spec₂ α} (h : RelTriple oa ob (EqRel α)) (x : α) :
              Pr[= x | oa] = Pr[= x | ob]

              Equality-relation relational triples imply equality of point output probabilities.

              theorem OracleComp.ProgramLogic.Relational.evalDist_eq_of_relTriple_eqRel {ι₁ ι₂ : Type u} {spec₁ : OracleSpec ι₁} {spec₂ : OracleSpec ι₂} [spec₁.Fintype] [spec₁.Inhabited] [spec₂.Fintype] [spec₂.Inhabited] {α : Type} {oa : OracleComp spec₁ α} {ob : OracleComp spec₂ α} (h : RelTriple oa ob (EqRel α)) :

              Equality-relation relational triples imply equality of evaluation distributions.

              theorem OracleComp.ProgramLogic.Relational.probOutput_true_eq_of_relTriple_eqRel {ι₁ ι₂ : Type u} {spec₁ : OracleSpec ι₁} {spec₂ : OracleSpec ι₂} [spec₁.Fintype] [spec₁.Inhabited] [spec₂.Fintype] [spec₂.Inhabited] {oa : OracleComp spec₁ Bool} {ob : OracleComp spec₂ Bool} (h : RelTriple oa ob (EqRel Bool)) :

              Bool-specialized bridge from relational triples to game success equality.

              Oracle query coupling rules (pRHL level) #

              theorem OracleComp.ProgramLogic.Relational.relTriple_query {ι₁ : Type u} {spec₁ : OracleSpec ι₁} [spec₁.Fintype] [spec₁.Inhabited] (t : spec₁.Domain) :
              RelTriple (liftM (query t)) (liftM (query t)) (EqRel (spec₁.Range t))

              Same-type identity coupling: querying the same oracle on both sides yields equal outputs.

              theorem OracleComp.ProgramLogic.Relational.relTriple_query_bij {ι₁ : Type u} {spec₁ : OracleSpec ι₁} [spec₁.Fintype] [spec₁.Inhabited] (t : spec₁.Domain) {f : spec₁.Range tspec₁.Range t} (hf : Function.Bijective f) :
              RelTriple (liftM (query t)) (liftM (query t)) fun (a b : spec₁.Range t) => f a = b

              Bijection coupling (the "rnd" rule from EasyCrypt): querying the same oracle on both sides, related by a bijection f.

              theorem OracleComp.ProgramLogic.Relational.relTriple_map {ι₁ ι₂ : Type u} {spec₁ : OracleSpec ι₁} {spec₂ : OracleSpec ι₂} [spec₁.Fintype] [spec₁.Inhabited] [spec₂.Fintype] [spec₂.Inhabited] {α β γ δ : Type} {R : RelPost γ δ} {f : αγ} {g : βδ} {oa : OracleComp spec₁ α} {ob : OracleComp spec₂ β} (h : RelTriple oa ob fun (a : α) (b : β) => R (f a) (g b)) :
              RelTriple (f <$> oa) (g <$> ob) R
              theorem OracleComp.ProgramLogic.Relational.evalDist_map_eq_of_relTriple {ι₁ ι₂ : Type u} {spec₁ : OracleSpec ι₁} {spec₂ : OracleSpec ι₂} [spec₁.Fintype] [spec₁.Inhabited] [spec₂.Fintype] [spec₂.Inhabited] {α β σ : Type} {f : ασ} {g : βσ} {oa : OracleComp spec₁ α} {ob : OracleComp spec₂ β} (h : RelTriple oa ob fun (a : α) (b : β) => f a = g b) :
              evalDist (f <$> oa) = evalDist (g <$> ob)

              If a relational triple holds for fun a b => f a = g b, then mapping by f and g produces equal distributions. Generalizes evalDist_eq_of_relTriple_eqRel.

              theorem OracleComp.ProgramLogic.Relational.relTriple_replicate {ι₁ ι₂ : Type u} {spec₁ : OracleSpec ι₁} {spec₂ : OracleSpec ι₂} [spec₁.Fintype] [spec₁.Inhabited] [spec₂.Fintype] [spec₂.Inhabited] {α β : Type} {oa : OracleComp spec₁ α} {ob : OracleComp spec₂ β} {R : RelPost α β} (n : ) (hstep : RelTriple oa ob R) :

              Lift a one-step coupling through bounded iteration.

              theorem OracleComp.ProgramLogic.Relational.relTriple_replicate_eqRel {ι₁ : Type u} {spec₁ : OracleSpec ι₁} [spec₁.Fintype] [spec₁.Inhabited] {α : Type} {oa ob : OracleComp spec₁ α} (n : ) (hstep : RelTriple oa ob (EqRel α)) :
              RelTriple (replicate n oa) (replicate n ob) (EqRel (List α))

              Equality coupling version of relTriple_replicate.

              theorem OracleComp.ProgramLogic.Relational.relTriple_list_mapM {ι₁ ι₂ : Type u} {spec₁ : OracleSpec ι₁} {spec₂ : OracleSpec ι₂} [spec₁.Fintype] [spec₁.Inhabited] [spec₂.Fintype] [spec₂.Inhabited] {α β γ δ : Type} {xs : List α} {ys : List β} {f : αOracleComp spec₁ γ} {g : βOracleComp spec₂ δ} {Rin : αβProp} {Rout : γδProp} (hxy : List.Forall₂ Rin xs ys) (hfg : ∀ (a : α) (b : β), Rin a bRelTriple (f a) (g b) Rout) :

              Lift pointwise relational reasoning through finite list traversals.

              theorem OracleComp.ProgramLogic.Relational.relTriple_list_mapM_eqRel {ι₁ ι₂ : Type u} {spec₁ : OracleSpec ι₁} {spec₂ : OracleSpec ι₂} [spec₁.Fintype] [spec₁.Inhabited] [spec₂.Fintype] [spec₂.Inhabited] {α β : Type} {xs : List α} {f : αOracleComp spec₁ β} {g : αOracleComp spec₂ β} (hfg : ∀ (a : α), RelTriple (f a) (g a) (EqRel β)) :
              RelTriple (List.mapM f xs) (List.mapM g xs) (EqRel (List β))

              Same-input equality-coupling specialization of relTriple_list_mapM.

              theorem OracleComp.ProgramLogic.Relational.relTriple_list_foldlM {ι₁ ι₂ : Type u} {spec₁ : OracleSpec ι₁} {spec₂ : OracleSpec ι₂} [spec₁.Fintype] [spec₁.Inhabited] [spec₂.Fintype] [spec₂.Inhabited] {α β σ₁ σ₂ : Type} {xs : List α} {ys : List β} {f : σ₁αOracleComp spec₁ σ₁} {g : σ₂βOracleComp spec₂ σ₂} {Rin : αβProp} {S : σ₁σ₂Prop} {s₁ : σ₁} {s₂ : σ₂} (hs : S s₁ s₂) (hxy : List.Forall₂ Rin xs ys) (hfg : ∀ (a : α) (b : β), Rin a b∀ (t₁ : σ₁) (t₂ : σ₂), S t₁ t₂RelTriple (f t₁ a) (g t₂ b) S) :
              RelTriple (List.foldlM f s₁ xs) (List.foldlM g s₂ ys) S

              Loop-invariant rule for bounded left folds over related input lists.

              theorem OracleComp.ProgramLogic.Relational.relTriple_list_foldlM_same {ι₁ ι₂ : Type u} {spec₁ : OracleSpec ι₁} {spec₂ : OracleSpec ι₂} [spec₁.Fintype] [spec₁.Inhabited] [spec₂.Fintype] [spec₂.Inhabited] {α σ₁ σ₂ : Type} {xs : List α} {f : σ₁αOracleComp spec₁ σ₁} {g : σ₂αOracleComp spec₂ σ₂} {S : σ₁σ₂Prop} {s₁ : σ₁} {s₂ : σ₂} (hs : S s₁ s₂) (hfg : ∀ (a : α) (t₁ : σ₁) (t₂ : σ₂), S t₁ t₂RelTriple (f t₁ a) (g t₂ a) S) :
              RelTriple (List.foldlM f s₁ xs) (List.foldlM g s₂ xs) S

              Same-input specialization of relTriple_list_foldlM.

              Synchronized branching rule #

              theorem OracleComp.ProgramLogic.Relational.relTriple_if {ι₁ ι₂ : Type u} {spec₁ : OracleSpec ι₁} {spec₂ : OracleSpec ι₂} [spec₁.Fintype] [spec₁.Inhabited] [spec₂.Fintype] [spec₂.Inhabited] {α β : Type} {c : Prop} [Decidable c] {oa₁ oa₂ : OracleComp spec₁ α} {ob₁ ob₂ : OracleComp spec₂ β} {R : RelPost α β} (htrue : cRelTriple oa₁ ob₁ R) (hfalse : ¬cRelTriple oa₂ ob₂ R) :
              RelTriple (if c then oa₁ else oa₂) (if c then ob₁ else ob₂) R

              Synchronized conditional: if both sides branch on the same condition, the relational triple holds if it holds on both branches.

              theorem OracleComp.ProgramLogic.Relational.relTriple_pure_left {ι₁ ι₂ : Type u} {spec₁ : OracleSpec ι₁} {spec₂ : OracleSpec ι₂} [spec₁.Fintype] [spec₁.Inhabited] [spec₂.Fintype] [spec₂.Inhabited] {α β : Type} {a : α} {ob : OracleComp spec₂ β} {R : RelPost α β} (h : RelTriple (pure a) ob fun (x : α) (y : β) => x = a R x y) :
              RelTriple (pure a) ob R

              Pure-left rule: the left side is a pure value, applied via bind decomposition.

              theorem OracleComp.ProgramLogic.Relational.relTriple_pure_right {ι₁ ι₂ : Type u} {spec₁ : OracleSpec ι₁} {spec₂ : OracleSpec ι₂} [spec₁.Fintype] [spec₁.Inhabited] [spec₂.Fintype] [spec₂.Inhabited] {α β : Type} {oa : OracleComp spec₁ α} {b : β} {R : RelPost α β} (h : RelTriple oa (pure b) fun (x : α) (y : β) => y = b R x y) :
              RelTriple oa (pure b) R

              Pure-right rule: the right side is a pure value, applied via bind decomposition.

              theorem OracleComp.ProgramLogic.Relational.relTriple_uniformSample_bij {α : Type} [SampleableType α] {f : αα} (hf : Function.Bijective f) (R : RelPost α α) (hR : ∀ (x : α), R x (f x)) :
              RelTriple ($ᵗ α) ($ᵗ α) R

              Relational coupling for uniform sampling via bijection. Given a bijection f : α → α such that R x (f x) for all x, the two uniform samples are related by R.

              Identity coupling for uniform sampling.