{-# OPTIONS --no-exact-split --safe #-}
module Cubical.Displayed.Record where
open import Cubical.Foundations.Prelude
open import Cubical.Foundations.Function
open import Cubical.Foundations.Equiv
open import Cubical.Foundations.Isomorphism
open import Cubical.Foundations.Path
open import Cubical.Data.Sigma
open import Cubical.Data.List as List
open import Cubical.Data.Unit
open import Cubical.Data.Bool
open import Cubical.Data.Maybe as Maybe
open import Cubical.Displayed.Base
open import Cubical.Displayed.Properties
open import Cubical.Displayed.Prop
open import Cubical.Displayed.Sigma
open import Cubical.Displayed.Unit
open import Cubical.Displayed.Universe
open import Cubical.Displayed.Auto
import Agda.Builtin.Reflection as R
open import Cubical.Reflection.Base
import Cubical.Reflection.RecordEquiv as RE
data DUAFields {ℓA ℓ≅A ℓR ℓ≅R} {A : Type ℓA} (𝒮-A : UARel A ℓ≅A)
(R : A → Type ℓR) (_≅R⟨_⟩_ : {a a' : A} → R a → UARel._≅_ 𝒮-A a a' → R a' → Type ℓ≅R)
: ∀ {ℓS ℓ≅S} {S : A → Type ℓS}
(πS : ∀ {a} → R a → S a) (𝒮ᴰ-S : DUARel 𝒮-A S ℓ≅S)
(πS≅ : ∀ {a} {r : R a} {e} {r' : R a} → r ≅R⟨ e ⟩ r' → DUARel._≅ᴰ⟨_⟩_ 𝒮ᴰ-S (πS r) e (πS r'))
→ Typeω
where
fields: : DUAFields 𝒮-A R _≅R⟨_⟩_ (λ _ → tt) (𝒮ᴰ-Unit 𝒮-A) (λ _ → tt)
_data[_∣_∣_] : ∀ {ℓS ℓ≅S} {S : A → Type ℓS}
{πS : ∀ {a} → R a → S a} {𝒮ᴰ-S : DUARel 𝒮-A S ℓ≅S}
{πS≅ : ∀ {a} {r : R a} {e} {r' : R a} → r ≅R⟨ e ⟩ r' → DUARel._≅ᴰ⟨_⟩_ 𝒮ᴰ-S (πS r) e (πS r')}
→ DUAFields 𝒮-A R _≅R⟨_⟩_ πS 𝒮ᴰ-S πS≅
→ ∀ {ℓF ℓ≅F} {F : A → Type ℓF}
(πF : ∀ {a} → (r : R a) → F a)
(𝒮ᴰ-F : DUARel 𝒮-A F ℓ≅F)
(πF≅ : ∀ {a} {r : R a} {e} {r' : R a} (p : r ≅R⟨ e ⟩ r') → DUARel._≅ᴰ⟨_⟩_ 𝒮ᴰ-F (πF r) e (πF r'))
→ DUAFields 𝒮-A R _≅R⟨_⟩_ (λ r → πS r , πF r) (𝒮ᴰ-S ×𝒮ᴰ 𝒮ᴰ-F) (λ p → πS≅ p , πF≅ p)
_prop[_∣_] : ∀ {ℓS ℓ≅S} {S : A → Type ℓS}
{πS : ∀ {a} → R a → S a} {𝒮ᴰ-S : DUARel 𝒮-A S ℓ≅S}
{πS≅ : ∀ {a} {r : R a} {e} {r' : R a} → r ≅R⟨ e ⟩ r' → DUARel._≅ᴰ⟨_⟩_ 𝒮ᴰ-S (πS r) e (πS r')}
→ DUAFields 𝒮-A R _≅R⟨_⟩_ πS 𝒮ᴰ-S πS≅
→ ∀ {ℓF} {F : (a : A) → S a → Type ℓF}
(πF : ∀ {a} → (r : R a) → F a (πS r))
(propF : ∀ a s → isProp (F a s))
→ DUAFields 𝒮-A R _≅R⟨_⟩_ (λ r → πS r , πF r) (𝒮ᴰ-subtype 𝒮ᴰ-S propF) (λ p → πS≅ p)
module _ {ℓA ℓ≅A} {A : Type ℓA} {𝒮-A : UARel A ℓ≅A}
{ℓR ℓ≅R} {R : A → Type ℓR} (_≅R⟨_⟩_ : {a a' : A} → R a → UARel._≅_ 𝒮-A a a' → R a' → Type ℓ≅R)
{ℓS ℓ≅S} {S : A → Type ℓS}
{πS : ∀ {a} → R a → S a} {𝒮ᴰ-S : DUARel 𝒮-A S ℓ≅S}
{πS≅ : ∀ {a} {r : R a} {e} {r' : R a} → r ≅R⟨ e ⟩ r' → DUARel._≅ᴰ⟨_⟩_ 𝒮ᴰ-S (πS r) e (πS r')}
(fs : DUAFields 𝒮-A R _≅R⟨_⟩_ πS 𝒮ᴰ-S πS≅)
where
open UARel 𝒮-A
open DUARel 𝒮ᴰ-S
𝒮ᴰ-Fields :
(e : ∀ a → Iso (R a) (S a))
(e≅ : ∀ a a' (r : R a) p (r' : R a') → Iso (r ≅R⟨ p ⟩ r') ((e a .Iso.fun r ≅ᴰ⟨ p ⟩ e a' .Iso.fun r')))
→ DUARel 𝒮-A R ℓ≅R
DUARel._≅ᴰ⟨_⟩_ (𝒮ᴰ-Fields e e≅) r p r' = r ≅R⟨ p ⟩ r'
DUARel.uaᴰ (𝒮ᴰ-Fields e e≅) r p r' =
isoToEquiv
(compIso
(e≅ _ _ r p r')
(compIso
(equivToIso (uaᴰ (e _ .Iso.fun r) p (e _ .Iso.fun r')))
(invIso (congPathIso λ i → isoToEquiv (e _)))))
module DisplayedRecordMacro where
findName : R.Term → R.TC R.Name
findName t =
Maybe.rec
(R.typeError (R.strErr "Not a name: " ∷ R.termErr t ∷ []))
(λ s → s)
(go t)
where
go : R.Term → Maybe (R.TC R.Name)
go (R.meta x _) = just (R.blockOnMeta x)
go (R.def name _) = just (R.returnTC name)
go (R.lam _ (R.abs _ t)) = go t
go t = nothing
pattern family∷ hole = _ h∷ _ h∷ _ h∷ _ h∷ _ h∷ _ h∷ _ h∷ _ h∷ hole
pattern indices∷ hole = _ h∷ _ h∷ _ h∷ _ h∷ _ h∷ _ h∷ hole
parseFields : R.Term → R.TC (List R.Name × List R.Name)
parseFields (R.con (quote fields:) _) = R.returnTC ([] , [])
parseFields (R.con (quote _data[_∣_∣_]) (family∷ (indices∷ (fs v∷ ℓF h∷ ℓ≅F h∷ F h∷ πF v∷ 𝒮ᴰ-F v∷ πF≅ v∷ _)))) =
parseFields fs >>= λ (fs , f≅s) →
findName πF >>= λ f →
findName πF≅ >>= λ f≅ →
R.returnTC (f ∷ fs , f≅ ∷ f≅s)
parseFields (R.con (quote _prop[_∣_]) (family∷ (indices∷ (fs v∷ ℓF h∷ F h∷ πF v∷ _)))) =
parseFields fs >>= λ (fs , f≅s) →
findName πF >>= λ f →
R.returnTC (f ∷ fs , f≅s)
parseFields (R.meta x _) = R.blockOnMeta x
parseFields t = R.typeError (R.strErr "Malformed specification: " ∷ R.termErr t ∷ [])
List→LeftAssoc : List R.Name → RE.ΣFormat
List→LeftAssoc [] = RE.unit
List→LeftAssoc (x ∷ xs) = List→LeftAssoc xs RE., RE.leaf x
module _ {ℓA ℓ≅A} {A : Type ℓA} (𝒮-A : UARel A ℓ≅A)
{ℓR ℓ≅R} {R : A → Type ℓR} (≅R : {a a' : A} → R a → UARel._≅_ 𝒮-A a a' → R a' → Type ℓ≅R)
{ℓS ℓ≅S} {S : A → Type ℓS}
{πS : ∀ {a} → R a → S a} {𝒮ᴰ-S : DUARel 𝒮-A S ℓ≅S}
{πS≅ : ∀ {a} {r : R a} {e} {r' : R a} → ≅R r e r' → DUARel._≅ᴰ⟨_⟩_ 𝒮ᴰ-S (πS r) e (πS r')}
where
𝒮ᴰ-Record : DUAFields 𝒮-A R ≅R πS 𝒮ᴰ-S πS≅ → R.Term → R.TC Unit
𝒮ᴰ-Record fs hole =
R.quoteTC (DUARel 𝒮-A R ℓ≅R) >>= R.checkType hole >>= λ hole →
R.quoteωTC fs >>= λ `fs` →
parseFields `fs` >>= λ (fields , ≅fields) →
R.freshName "fieldsIso" >>= λ fieldsIso →
R.freshName "≅fieldsIso" >>= λ ≅fieldsIso →
R.quoteTC R >>= R.normalise >>= λ `R` →
R.quoteTC {A = {a a' : A} → R a → UARel._≅_ 𝒮-A a a' → R a' → Type ℓ≅R} ≅R >>= R.normalise >>= λ `≅R` →
findName `R` >>= RE.declareRecordIsoΣ' fieldsIso (List→LeftAssoc fields) >>
findName `≅R` >>= RE.declareRecordIsoΣ' ≅fieldsIso (List→LeftAssoc ≅fields) >>
R.unify hole
(R.def (quote 𝒮ᴰ-Fields)
(`≅R` v∷ `fs` v∷
vlam "_" (R.def fieldsIso []) v∷
vlam "a" (vlam "a'" (vlam "r" (vlam "p" (vlam "r'" (R.def ≅fieldsIso []))))) v∷
[]))
macro
𝒮ᴰ-Record = DisplayedRecordMacro.𝒮ᴰ-Record
private
module Example where
record Example (A : Type) : Type where
no-eta-equality
field
dog : A → A → A
cat : A → A → A
mouse : Unit
open Example
record ExampleEquiv {A B : Type} (x : Example A) (e : A ≃ B) (y : Example B) : Type where
no-eta-equality
field
dogEq : ∀ a a' → e .fst (x .dog a a') ≡ y .dog (e .fst a) (e .fst a')
catEq : ∀ a a' → e .fst (x .cat a a') ≡ y .cat (e .fst a) (e .fst a')
open ExampleEquiv
example : DUARel (𝒮-Univ ℓ-zero) Example ℓ-zero
example =
𝒮ᴰ-Record (𝒮-Univ ℓ-zero) ExampleEquiv
(fields:
data[ dog ∣ autoDUARel _ _ ∣ dogEq ]
data[ cat ∣ autoDUARel _ _ ∣ catEq ]
prop[ mouse ∣ (λ _ _ → isPropUnit) ])