Documentation

Nominal.Fresh

Fresh Atoms and the Move Operation #

This file defines freshness and the "move" operation that is central to nominal CatCrypt's state separation.

Main definitions #

References #

def CatCrypt.Nominal.Fresh {α : Type u_1} [NomSet α] (a : Atom) (x : α) :

An atom is fresh for an element if it's not in the element's support.

Equations
Instances For
    def CatCrypt.Nominal.Disj {α : Type u_1} {β : Type u_2} [NomSet α] [NomSet β] (x : α) (y : β) :

    Two elements are disjoint if their supports are disjoint.

    Equations
    Instances For
      theorem CatCrypt.Nominal.Fresh.act_swap_fresh {α : Type u_1} [NomSet α] (a b : Atom) (x : α) (ha : Fresh a x) (hb : Fresh b x) :

      Fresh atoms don't affect elements under permutation

      noncomputable def CatCrypt.Nominal.freshFor {α : Type u_1} {β : Type u_2} [NomSet α] [NomSet β] (x : α) (y : β) :

      Generate a fresh atom not in the union of two supports

      Equations
      Instances For
        theorem CatCrypt.Nominal.freshFor_not_in_supp_left {α : Type u_1} {β : Type u_2} [NomSet α] [NomSet β] (x : α) (y : β) :
        Fresh (freshFor x y) x

        freshFor x y is fresh for x.

        theorem CatCrypt.Nominal.freshFor_not_in_supp_right {α : Type u_1} {β : Type u_2} [NomSet α] [NomSet β] (x : α) (y : β) :
        Fresh (freshFor x y) y

        freshFor x y is fresh for y.

        noncomputable def CatCrypt.Nominal.offset (s : Finset Atom) :

        The offset of a finset: one plus the maximum value. This is used to generate fresh atoms.

        Equations
        Instances For

          Map an atom a to a fresh atom above the offset of some set. This is used to construct the fresh permutation.

          Equations
          Instances For

            Shifting by a fixed base is injective.

            theorem CatCrypt.Nominal.atomShift_image_disjoint {s : Finset Atom} {a : Atom} (_ha : a s) (base : ) (hbase : Atom.offset s base) :
            atomShift base as

            Once base clears the offset of s, shifting any atom lands outside s.

            theorem CatCrypt.Nominal.atomShift_val_ge (base : ) (a : Atom) :
            base (atomShift base a).val

            Shifted atoms are above the offset

            Atoms in s are below the offset

            theorem CatCrypt.Nominal.atomShift_not_in_set {s : Finset Atom} {a : Atom} (base : ) (hbase : Atom.offset s base) :
            atomShift base as

            Shifted atoms are not in the original set when base ≥ offset

            theorem CatCrypt.Nominal.atom_lt_shifted {s : Finset Atom} {base : } {a b : Atom} (hbase : Atom.offset s base) (ha : a s) :
            a.val < (atomShift base b).val

            Atoms in s have values strictly less than shifted atoms when base ≥ offset s

            theorem CatCrypt.Nominal.shifted_ne_mem {s : Finset Atom} {base : } {a b : Atom} (hbase : Atom.offset s base) (hb : b s) :
            atomShift base a b

            Shifted atoms are different from atoms in s

            noncomputable def CatCrypt.Nominal.freshPerm (s : Finset Atom) (base : ) :

            The fresh permutation construction.

            freshPerm s base creates a permutation that:

            • For each a in s, swaps a with atomShift base a
            • Acts as identity outside s ∪ (atomShift base '' s)

            The key property is that when base ≥ offset s, the images are above the offset, hence disjoint from any set with offset ≤ base.

            Following Rocq SSProve's fperm (λ a, atomize (offset (supp x) + natize a)) (supp y).

            Equations
            • One or more equations did not get rendered due to their size.
            Instances For
              theorem CatCrypt.Nominal.foldl_mul_swap_fix {a : Atom} {init : FinPerm} (l : List Atom) (base : ) (hinit : init.apply a = a) (hswaps : xl, a x a atomShift base x) :
              (List.foldl (fun (π : FinPerm) (b : Atom) => π * FinPerm.swap b (atomShift base b)) init l).apply a = a

              Helper: if each swap in a fold fixes a point, the fold result fixes that point. This is a general induction principle for foldl with permutation multiplication.

              theorem CatCrypt.Nominal.freshPerm_fix_outside {s : Finset Atom} {base : } {a : Atom} (_hbase : Atom.offset s base) (ha : as) (hshift : bs, atomShift base b a) :
              (freshPerm s base).apply a = a

              freshPerm fixes atoms outside s when base ≥ offset s

              theorem CatCrypt.Nominal.foldl_mul_swap_transparent {x : Atom} {init : FinPerm} (l : List Atom) (base : ) (hswaps : yl, x y x atomShift base y) :
              (List.foldl (fun (π : FinPerm) (b : Atom) => π * FinPerm.swap b (atomShift base b)) init l).apply x = init.apply x

              If all swaps in the list fix a point, the fold is transparent at that point: the fold result applied to x equals the initial permutation applied to x.

              theorem CatCrypt.Nominal.foldl_mul_swap_apply_mem {a : Atom} {init : FinPerm} (l : List Atom) (base : ) (hnodup : l.Nodup) (ha : a l) (hinit : init.apply a = a) (hinit_shift : init.apply (atomShift base a) = atomShift base a) (hbefore : xl, x aa.val < (atomShift base x).val) (hafter : xl, x a(atomShift base a).val x.val atomShift base a atomShift base x) :
              (List.foldl (fun (π : FinPerm) (b : Atom) => π * FinPerm.swap b (atomShift base b)) init l).apply a = atomShift base a

              Helper for freshPerm_apply_mem': when a is in the list, the fold maps a to its shift. Key invariants: init fixes a, and init fixes atomShift base a.

              theorem CatCrypt.Nominal.freshPerm_apply_mem' {s : Finset Atom} {base : } {a : Atom} (hbase : Atom.offset s base) (ha : a s) :
              (freshPerm s base).apply a = atomShift base a

              freshPerm maps atoms in s to their shifts when base ≥ offset

              theorem CatCrypt.Nominal.supp_act_freshPerm_disjoint {α : Type u_1} [NomSet α] (y : α) (base : ) (hbase : Atom.offset (NomSet.supp y) base) (sups : Finset Atom) (hsups : Atom.offset sups base) :

              Support of an element under freshPerm shifts appropriately. The support of π ∙ y is π '' (supp y), so it consists of shifted atoms which have values ≥ base, while atoms in sups have values < offset sups ≤ base.

              noncomputable def CatCrypt.Nominal.freshMove {α : Type u_1} {β : Type u_2} [NomSet α] [NomSet β] (x : α) (y : β) :

              The fresh permutation for move: maps supp y to atoms above offset(supp x ∪ supp y)

              Equations
              Instances For
                noncomputable def CatCrypt.Nominal.move {α : Type u_1} {β : Type u_2} [NomSet α] [NomSet β] (x : α) (y : β) :
                β

                The move permutation: applies freshMove to relocate y's support away from x's support.

                This follows the Rocq definition: move x y := fresh x y ∙ y where fresh x y is the permutation mapping supp y to fresh atoms.

                Equations
                Instances For
                  noncomputable def CatCrypt.Nominal.movePerm {α : Type u_1} {β : Type u_2} [NomSet α] [NomSet β] (x : α) (y : β) :

                  The permutation used by move

                  Equations
                  Instances For
                    theorem CatCrypt.Nominal.move_disj {α : Type u_1} {β : Type u_2} [NomSet α] [NomSet β] (x : α) (y : β) :
                    Disj x (move x y)

                    After applying move, the supports become disjoint.

                    This is the key property from nominal set theory (Rocq: fresh_disjoint).

                    Proof sketch:

                    • freshMove x y maps atoms in supp y to atoms above offset(supp x ∪ supp y)
                    • All atoms in supp x are below this offset
                    • Therefore, supp(move x y) ∩ supp x = ∅
                    theorem CatCrypt.Nominal.movePerm_act_left {α : Type u_1} {β : Type u_2} [NomSet α] [NomSet β] (x : α) (y : β) (hdisj : Disjoint (NomSet.supp x) (NomSet.supp y)) :
                    movePerm x y x = x

                    movePerm doesn't move the first argument when supports are disjoint.

                    Note: This requires the disjointness hypothesis because freshPerm moves all atoms in supp y. If a ∈ supp x ∩ supp y, then a would be moved.

                    def CatCrypt.Nominal.AlphaEquiv {α : Type u_1} [NomSet α] (x y : α) :

                    Alpha-equivalence: two elements are equivalent if they differ only by a permutation

                    Equations
                    Instances For
                      theorem CatCrypt.Nominal.AlphaEquiv.refl {α : Type u_1} [NomSet α] (x : α) :
                      x ≡α x

                      Alpha-equivalence is reflexive.

                      theorem CatCrypt.Nominal.AlphaEquiv.symm {α : Type u_1} [NomSet α] {x y : α} (h : x ≡α y) :
                      y ≡α x

                      Alpha-equivalence is symmetric.

                      theorem CatCrypt.Nominal.AlphaEquiv.trans {α : Type u_1} [NomSet α] {x y z : α} (hxy : x ≡α y) (hyz : y ≡α z) :
                      x ≡α z

                      Alpha-equivalence is transitive.