{-# OPTIONS --safe #-}
module Cubical.HITs.UnorderedPair.Base where

open import Cubical.Foundations.Prelude
open import Cubical.Foundations.HLevels

private variable
   ℓ′ : Level
  A : Type 

infixr 4 _,_

data UnorderedPair (A : Type ) : Type  where
  _,_ : (x y : A)  UnorderedPair A
  swap : (x y : A)  (x , y)  (y , x)
  trunc : isSet (UnorderedPair A)

module _ {B : UnorderedPair A  Type ℓ′}
  (_,*_ : (x y : A)  B (x , y))
  (swap* : (x y : A)  PathP  i  B (swap x y i)) (x ,* y) (y ,* x))
  (trunc* : (xs : UnorderedPair A)  isSet (B xs)) where

  elim : (xs : UnorderedPair A)  B xs
  elim (x , y) = x ,* y
  elim (swap x y i) = swap* x y i
  elim (trunc x y p q i j) =
    isOfHLevel→isOfHLevelDep 2 trunc* (elim x) (elim y) (cong elim p) (cong elim q) (trunc x y p q) i j

module _ {B : UnorderedPair A  Type ℓ′}
  (BProp : {xs : UnorderedPair A}  isProp (B xs))
  (_,*_ : (x y : A)  B (x , y)) where

  elimProp : (xs : UnorderedPair A)  B xs
  elimProp = elim _,*_  x y  toPathP (BProp (transport  i  B (swap x y i)) (x ,* y)) (y ,* x)))
    λ _  isProp→isSet BProp

module _ {B : Type ℓ′} (BType : isSet B)
  (_,*_ : (x y : A)  B) (swap* : (x y : A)  (x ,* y)  (y ,* x)) where

  rec : UnorderedPair A  B
  rec = elim _,*_ swap* λ _  BType