Tom de Jong, 5 April 2022, after discussion with MartΓ­n EscardΓ³.
(Refactoring an earlier addition dated 15 March 2022.)

The construction of set quotients in Quotient.Large takes a type X : 𝓀
and a π“₯-valued equivalence relation and constructs the quotient as a
type in π“₯ ⁺ βŠ” 𝓀.

If we assume Set Replacement, as defined and explained in UF.Size.lagda, then we
get a quotient in π“₯ βŠ” 𝓀. In particular, for a 𝓀-valued equivalence relation on a
type X : 𝓀, the quotient will live in the same universe 𝓀. This particular case
was first proved in [Corollary 5.1, Rijke2017], but under a different
replacement assumption (again, see UF.Size.lagda for details).

[Rijke2017]  Egbert Rijke. The join construction.
             https://arxiv.org/abs/1701.07538, January 2017.

\begin{code}

{-# OPTIONS --safe --without-K #-}

open import UF.FunExt
open import UF.PropTrunc
open import UF.Subsingletons

module Quotient.FromSetReplacement
        (pt : propositional-truncations-exist)
        (fe : Fun-Ext)
        (pe : Prop-Ext)
       where

open import MLTT.Spartan

open import UF.Equiv
open import UF.EquivalenceExamples
open import UF.Powerset
open import UF.Sets
open import UF.Sets-Properties
open import UF.Size
open import UF.Subsingletons-FunExt
open import UF.SubtypeClassifier
open import UF.SubtypeClassifier-Properties

open import Quotient.Large pt fe pe
open import Quotient.Type -- using (set-quotients-exist ; is-effective ; EqRel)

open general-set-quotients-exist large-set-quotients

module _
        (R : Set-Replacement pt)
        {X : 𝓀 Μ‡ }
        (≋@(_β‰ˆ_ , β‰ˆp , β‰ˆr , β‰ˆs , β‰ˆt) : EqRel {𝓀} {π“₯} X)
       where

 abstract
  resize-set-quotient : (X / ≋) is (𝓀 βŠ” π“₯) small
  resize-set-quotient = R equiv-rel (X , (≃-refl X)) Ξ³
                          (powersets-are-sets'' fe fe pe)
   where
    open large-quotient X ≋ using (equiv-rel)
    Ξ³ : (X β†’ Ξ© π“₯) is-locally 𝓀 βŠ” π“₯ small
    Ξ³ f g = S , ≃-sym e
     where
      S : 𝓀 βŠ” π“₯ Μ‡
      S = (x : X) β†’ f x holds ↔ g x holds
      e : (f = g) ≃ S
      e = (f = g) β‰ƒβŸ¨ ≃-funext fe f g ⟩
          f ∼ g   β‰ƒβŸ¨ I ⟩
          S       β– 
       where
        I : (f ∼ g) ≃ S
        I = Ξ -cong fe fe II
         where
          II : (x : X) β†’ (f x = g x) ≃ (f x holds ↔ g x holds)
          II x = logically-equivalent-props-are-equivalent
                  (Ξ©-is-set fe pe)
                  (Γ—-is-prop (Ξ -is-prop fe (Ξ» _ β†’ holds-is-prop (g x)))
                             (Ξ -is-prop fe (Ξ» _ β†’ holds-is-prop (f x))))
                  (Ξ» p β†’ transport _holds p , transport⁻¹ _holds p)
                  (Ξ» (u , v) β†’ Ξ©-extensionality pe fe u v)

\end{code}

We now use the above resizing to construct a quotient that strictly lives in the
universe 𝓀 βŠ” π“₯, yielding set quotients as defined in
Quotient.Quotient.lagda.

\begin{code}

 X/β‚›β‰ˆ : 𝓀 βŠ” π“₯ Μ‡
 X/β‚›β‰ˆ = pr₁ resize-set-quotient
 Ο† : X/β‚›β‰ˆ ≃ X / ≋
 Ο† = prβ‚‚ resize-set-quotient
 Ξ·/β‚› : X β†’ X/β‚›β‰ˆ
 Ξ·/β‚› = ⌜ Ο† ⌝⁻¹  ∘ Ξ·/ ≋
 Ξ·/β‚›-identifies-related-points : identifies-related-points ≋ Ξ·/β‚›
 Ξ·/β‚›-identifies-related-points e = ap ⌜ Ο† ⌝⁻¹ (Ξ·/-identifies-related-points ≋ e)
 /β‚›-is-set : is-set (X/β‚›β‰ˆ)
 /β‚›-is-set = equiv-to-set Ο† (/-is-set ≋)
 /β‚›-induction : βˆ€ {𝓦} {P : X/β‚›β‰ˆ β†’ 𝓦 Μ‡ }
              β†’ ((x' : X/β‚›β‰ˆ) β†’ is-prop (P x'))
              β†’ ((x : X) β†’ P (Ξ·/β‚› x))
              β†’ (x' : X/β‚›β‰ˆ) β†’ P x'
 /β‚›-induction {𝓦} {P} i h x' = transport P e (Ξ³ (⌜ Ο† ⌝ x'))
  where
   P' : X / ≋ β†’ 𝓦 Μ‡
   P' = P ∘ ⌜ Ο† ⌝⁻¹
   Ξ³ : (y : X / ≋) β†’ P' y
   Ξ³ = /-induction ≋ (Ξ» y β†’ i (⌜ Ο† ⌝⁻¹ y)) h
   e : ⌜ Ο† ⌝⁻¹ (⌜ Ο† ⌝ x') = x'
   e = ≃-sym-is-linv Ο† x'
 /β‚›-universality : {A : 𝓦 Μ‡ } β†’ is-set A
                 β†’ (f : X β†’ A)
                 β†’ identifies-related-points ≋ f
                 β†’ βˆƒ! f' κž‰ (X/β‚›β‰ˆ β†’ A), f' ∘ Ξ·/β‚› ∼ f
 /β‚›-universality {𝓦} {A} i f p =
  equiv-to-singleton (≃-sym e) (/-universality ≋ i f p)
   where
    e = (Ξ£ f' κž‰ (X / ≋ β†’ A)  , f' ∘ Ξ·/ ≋ ∼ f)        β‰ƒβŸ¨ β¦…1⦆ ⟩
        (Ξ£ f' κž‰ (X / ≋ β†’ A)  , f' ∘ ⌜ Ο† ⌝ ∘ Ξ·/β‚› ∼ f) β‰ƒβŸ¨ β¦…2⦆ ⟩
        (Ξ£ f' κž‰ (X/β‚›β‰ˆ β†’ A) , f' ∘ Ξ·/β‚› ∼ f)         β– 
     where
      β¦…1⦆ = Ξ£-cong
            (Ξ» f' β†’ Ξ -cong fe fe (Ξ» x β†’ =-cong-l (f' (Ξ·/ ≋ x)) (f x)
                                    (ap f' ((≃-sym-is-rinv Ο† (Ξ·/ ≋ x)) ⁻¹))))
      β¦…2⦆ = Ξ£-change-of-variable _ (_∘ ⌜ Ο† ⌝)
            (qinvs-are-equivs (_∘ ⌜ Ο† ⌝)
              (qinv-pre (Ξ» _ _ β†’ dfunext fe) ⌜ Ο† ⌝
               (equivs-are-qinvs ⌜ Ο† ⌝ (⌜⌝-is-equiv Ο†))))
       where
        open import UF.Equiv-FunExt using (qinv-pre)

 Ξ·/β‚›-relates-identified-points : {x y : X} β†’ Ξ·/β‚› x = Ξ·/β‚› y β†’ x β‰ˆ y
 Ξ·/β‚›-relates-identified-points {x} {y} eβ‚› = large-effective-set-quotients ≋ e
  where
   note : ⌜ Ο† ⌝⁻¹ (Ξ·/ ≋ x) = ⌜ Ο† ⌝⁻¹ (Ξ·/ ≋ y)
   note = eβ‚›
   e = Ξ·/ ≋ x                   =⟨ (≃-sym-is-rinv Ο† (Ξ·/ ≋ x)) ⁻¹ ⟩
       ⌜ Ο† ⌝ (⌜ Ο† ⌝⁻¹ (Ξ·/ ≋ x)) =⟨ ap ⌜ Ο† ⌝ note ⟩
       ⌜ Ο† ⌝ (⌜ Ο† ⌝⁻¹ (Ξ·/ ≋ y)) =⟨ ≃-sym-is-rinv Ο† (Ξ·/ ≋ y) ⟩
       Ξ·/ ≋ y                   ∎

set-quotients-from-set-replacement : Set-Replacement pt β†’ set-quotients-exist
set-quotients-from-set-replacement R = record
 { _/_                          = Ξ» X β†’ X/β‚›β‰ˆ R
 ; Ξ·/                           = Ξ·/β‚› R
 ; Ξ·/-identifies-related-points = Ξ·/β‚›-identifies-related-points R
 ; /-is-set                     = /β‚›-is-set R
 ; /-universality               = /β‚›-universality R
 }

set-replacement-gives-effective-set-quotients
 : (sr : Set-Replacement pt)
 β†’ are-effective (set-quotients-from-set-replacement sr)
set-replacement-gives-effective-set-quotients sr {𝓀} {π“₯} R {x} {y} =
 Ξ·/β‚›-relates-identified-points sr R

\end{code}