import BidirTT.Syntax namespace BidirTT mutual partial def prettyTmWith (names : List Name) (nextFresh : Nat) : Tm → String × Nat | .var i => match names[i]? with | some name => (name, nextFresh) | none => (s!"#{i}", nextFresh) | .lam t => let x := s!"x{nextFresh}" let (body, nextFresh) := prettyTmWith (x :: names) (nextFresh + 1) t (s!"(fun {x} => {body})", nextFresh) | .app t u => let (pt, nextFresh) := prettyTmWith names nextFresh t let (pu, nextFresh) := prettyTmWith names nextFresh u (s!"({pt} {pu})", nextFresh) | .pi a b => let x := s!"x{nextFresh}" let (pa, nextFresh) := prettyTmWith names (nextFresh + 1) a let (pb, nextFresh) := prettyTmWith (x :: names) nextFresh b (s!"(Pi ({x} : {pa}) -> {pb})", nextFresh) | .sig a b => let x := s!"x{nextFresh}" let (pa, nextFresh) := prettyTmWith names (nextFresh + 1) a let (pb, nextFresh) := prettyTmWith (x :: names) nextFresh b (s!"(Sigma ({x} : {pa}) * {pb})", nextFresh) | .pair t u => let (pt, nextFresh) := prettyTmWith names nextFresh t let (pu, nextFresh) := prettyTmWith names nextFresh u (s!"({pt}, {pu})", nextFresh) | .fst t => let (pt, nextFresh) := prettyTmWith names nextFresh t (s!"({pt}.1)", nextFresh) | .snd t => let (pt, nextFresh) := prettyTmWith names nextFresh t (s!"({pt}.2)", nextFresh) | .nat => ("Nat", nextFresh) | .zero => ("zero", nextFresh) | .succ t => let (pt, nextFresh) := prettyTmWith names nextFresh t (s!"(succ {pt})", nextFresh) | .natElim m z s n => let (pm, nextFresh) := prettyTmWith names nextFresh m let (pz, nextFresh) := prettyTmWith names nextFresh z let (ps, nextFresh) := prettyTmWith names nextFresh s let (pn, nextFresh) := prettyTmWith names nextFresh n (s!"(natElim {pm} {pz} {ps} {pn})", nextFresh) | .unit => ("Unit", nextFresh) | .triv => ("tt", nextFresh) | .unitElim m t u => let (pm, nextFresh) := prettyTmWith names nextFresh m let (pt, nextFresh) := prettyTmWith names nextFresh t let (pu, nextFresh) := prettyTmWith names nextFresh u (s!"(unitElim {pm} {pt} {pu})", nextFresh) | .empty => ("Empty", nextFresh) | .emptyElim m e => let (pm, nextFresh) := prettyTmWith names nextFresh m let (pe, nextFresh) := prettyTmWith names nextFresh e (s!"(emptyElim {pm} {pe})", nextFresh) | .id a t u => let (pa, nextFresh) := prettyTmWith names nextFresh a let (pt, nextFresh) := prettyTmWith names nextFresh t let (pu, nextFresh) := prettyTmWith names nextFresh u (s!"(Id {pa} {pt} {pu})", nextFresh) | .refl => ("refl", nextFresh) | .idElim m r y p => let (pm, nextFresh) := prettyTmWith names nextFresh m let (pr, nextFresh) := prettyTmWith names nextFresh r let (py, nextFresh) := prettyTmWith names nextFresh y let (pp, nextFresh) := prettyTmWith names nextFresh p (s!"(idElim {pm} {pr} {py} {pp})", nextFresh) | .univ i => (s!"U{i}", nextFresh) | .letE a t u => let x := s!"x{nextFresh}" let (pa, nextFresh) := prettyTmWith names (nextFresh + 1) a let (pt, nextFresh) := prettyTmWith names nextFresh t let (pu, nextFresh) := prettyTmWith (x :: names) nextFresh u (s!"(let {x} : {pa} := {pt}; {pu})", nextFresh) end def prettyTm (tm : Tm) : String := (prettyTmWith [] 0 tm).fst end BidirTT