Source code on Github
open import Prelude.Init; open SetAsType
open L.Mem
open import Prelude.Lists.Membership
open import Prelude.Lists.Dec
open import Prelude.General
open import Prelude.DecEq
open import Prelude.Decidable
open import Prelude.Setoid
open import Prelude.InfEnumerable

module Nominal.Product (Atom : Type)  _ : DecEq Atom  where

open import Nominal.Swap Atom
open import Nominal.Support Atom

module _
  {A : Type } {B : Type ℓ′}
   _ : ISetoid A   _ : ISetoid B 
   _ : SetoidLaws A   _ : SetoidLaws B 
   _ : Swap A   _ : Swap B 
   _ : SwapLaws A   _ : SwapLaws B  where

  open ≈-Reasoning

  instance
    Setoid-× : ISetoid (A × B)
    Setoid-× = λ where
      .relℓ  _
      ._≈_ (a , b) (a′ , b′)  (a  a′) × (b  b′)

    SetoidLaws-× : SetoidLaws (A × B)
    SetoidLaws-× .isEquivalence = record
      { refl  = ≈-refl , ≈-refl
      ; sym   = λ (i , j)  ≈-sym i , ≈-sym j
      ; trans = λ (i , j) (k , l)  ≈-trans i k , ≈-trans j l
      }

    SwapLaws-× : SwapLaws (A × B)
    SwapLaws-× = record
      { cong-swap = λ (x , y)  cong-swap x , cong-swap y
      ; swap-id = swap-id , swap-id
      ; swap-rev = swap-rev , swap-rev
      ; swap-sym = swap-sym , swap-sym
      ; swap-swap = swap-swap , swap-swap
      }

  module _  _ : Enumerable∞ Atom  where
    instance
      ∃FinSupp-× :  ∃FinitelySupported A 
                   ∃FinitelySupported B 
                  ∃FinitelySupported (A × B)
      ∃FinSupp-× .∀∃fin (a , b) =
        let xs , p = ∀∃fin a
            ys , q = ∀∃fin b
        in xs ++ ys , λ y z y∉ z∉ 
            p y z (y∉  ∈-++⁺ˡ)   (z∉  ∈-++⁺ˡ)
          , q y z (y∉  ∈-++⁺ʳ _) (z∉  ∈-++⁺ʳ _)

      FinSupp-× :  FinitelySupported A 
                  FinitelySupported B 
                 FinitelySupported (A × B)
      FinSupp-× .∀fin (a , b) =
        let xs , p , ¬p = ∀fin a
            ys , q , ¬q = ∀fin b
        in nub (xs ++ ys)
         ,  y z y∉ z∉ 
              ( p y z (y∉  ∈-nub⁺  ∈-++⁺ˡ)   (z∉  ∈-nub⁺  ∈-++⁺ˡ)
              , q y z (y∉  ∈-nub⁺  ∈-++⁺ʳ xs) (z∉  ∈-nub⁺  ∈-++⁺ʳ xs)
              )
           )
         , λ y z y∈′ z∉ (p , q) 
           let z∉ˡ , z∉ʳ = ∉-++⁻ $ ∉-nub⁻ z∉
           in case ∈-++⁻ xs $ ∈-nub⁻ y∈′ of λ where
             (inj₁ y∈)  ¬p y z y∈ z∉ˡ p
             (inj₂ y∈)  ¬q y z y∈ z∉ʳ q

private
  postulate
    𝕒 𝕓 : Atom
    𝕒≢𝕓 : 𝕒  𝕓

  unquoteDecl Swap-Maybe = DERIVE Swap [ quote Maybe , Swap-Maybe ]

  justAtom : Atom × Maybe Atom
  justAtom = 𝕒 , just 𝕓

  justAtom′ : Atom × Maybe Atom
  justAtom′ =  𝕒  𝕓  justAtom

  _ = justAtom .proj₁  𝕒
     refl

  _ = justAtom .proj₂  just 𝕓
     refl

  _ : justAtom′ .proj₁  𝕓
  _ rewrite dec-no (𝕒  𝕓) 𝕒≢𝕓 .proj₂
          | ≟-refl 𝕒
          = refl

  _ : justAtom′ .proj₂  just 𝕒
  _ rewrite dec-no (𝕓  𝕒) (≢-sym 𝕒≢𝕓) .proj₂
          | ≟-refl 𝕓
          = refl