\import Category \import Function.Meta \import Paths \import Paths.Meta \data CatTerm {V : \Type} (a b : V) (H : V -> V -> \Type) | var (H a b) | :id (a = b) | :o (c : V) (CatTerm c b H) (CatTerm a c H) \data CatNF {V : \Type} (a b : V) (H : V -> V -> \Type) | :nil (a = b) | \infixl 7 :cons {c : V} (H c b) (CatNF a c H) \func normalize {V : \Type} {a b : V} {H : V -> V -> \Type} (t : CatTerm a b H) : CatNF a b H => aux t (:nil idp) \where \func aux {V : \Type} {a b c : V} {H : V -> V -> \Type} (t : CatTerm b c H) (acc : CatNF a b H) : CatNF a c H \elim t | var h => h :cons acc | :id idp => acc | :o _ t s => aux t (aux s acc) \class HData \noclassifying {C : Precat} {V : \Set} (f : V -> C) (H : V -> V -> \Set) (g : \Pi {x y : V} -> H x y -> Hom (f x) (f y)) { \func interpret {a b : V} (t : CatTerm a b H) : Hom (f a) (f b) \elim t | var h => g h | :id idp => id (f a) | :o _ t s => interpret t ∘ interpret s \func interpretNF {a b : V} (t : CatNF a b H) : Hom (f a) (f b) \elim t | :nil idp => id (f a) | :cons h (:nil idp) => g h | :cons h t => g h ∘ interpretNF t \where \lemma cons {a b c : V} (h : H b c) (l : CatNF a b H) : interpretNF (h :cons l) = g h ∘ interpretNF l \elim l | :nil idp => inv id-right | :cons a l => idp \func \infixr 5 :++ {a b c : V} (h : CatNF b c H) (h' : CatNF a b H) : CatNF a c H \elim h | :nil idp => h' | :cons h t => h :cons (t :++ h') \lemma interpretNF_++ {a b c : V} (h : CatNF b c H) (h' : CatNF a b H) : interpretNF (h :++ h') = interpretNF h ∘ interpretNF h' \elim h | :nil idp => inv id-left | :cons h t => repeat {2} (rewrite interpretNF.cons) $ rewrite interpretNF_++ (inv o-assoc) \lemma normalize-consistent {a b : V} (t : CatTerm a b H) : interpret t = interpretNF (normalize t) => inv id-right *> aux t (:nil idp) \where \lemma aux {a b c : V} (t : CatTerm b c H) (acc : CatNF a b H) : interpret t ∘ interpretNF acc = interpretNF (normalize.aux t acc) \elim t | var h => inv (interpretNF.cons h acc) | :id idp => id-left | :o _ t s => o-assoc *> pmap (interpret t ∘) (aux s acc) *> aux t (normalize.aux s acc) \lemma terms-equality {a b : V} (t s : CatTerm a b H) (p : interpretNF (normalize t) = interpretNF (normalize s)) : interpret t = interpret s => normalize-consistent t *> p *> inv (normalize-consistent s) }