In Agda we can prove termination of functions by using well-founded relations, is there a guideline for proving datatype declarations strictly positive, possibly via use of some container techniques together with well-founded relations?
I have been trying to port Danielsson's A Formalisation of a Dependently Typed Language as an Inductive-Recursive Family to modern Agda and there I have encountered the following argument.
Rendered in more modern Agda:
-- Values
-- This data type is a little problematic, since Val occurs
-- negatively in ΠVal and ΠValCong. However, notice that the spines
-- of the types of the recursive components are decreasing in
-- ΠVal/ΠValCong, and non-increasing in all other constructors. This
-- should ensure that the type is well-founded. I'm not aware of any
-- meta-theory explaining a type such as Val, though.
mutual
{-# NO_POSITIVITY_CHECK #-}
data Val : {Γ : Ctxt} {τ : Ty Γ} -> (Γ ⊢ τ) -> Set where
✶Val : {Γ : _} {x : Γ ⊢ ✶ Γ } -> Atom x -> Val x
ElVal : {Γ : _} {n : _} {t' : Γ ⊢ U n} {t : Γ ⊢ El t'} -> Atom t -> Val t
_∷ˢ_ : {Γ¹ : Ctxt} {τ¹ : Ty Γ¹} {t¹ : Γ¹ ⊢ τ¹}
{Γ² : Ctxt} {τ² : Ty Γ²} {t² : Γ² ⊢ τ²} -> Val t¹
-> (t¹ ≈⊢ t²) -> Val t²
ΠVal : {Γ : Ctxt} {τ₁ : Ty Γ} {τ₂ : Ty (Γ ▻ τ₁)} {t₁ : Γ ⊢ Π τ₁ τ₂}
-> ΠFun t₁ -> Val t₁
ΠFun : {Γ : Ctxt} {τ₁ : Ty Γ} {τ₂ : Ty (Γ ▻ τ₁)}
-> (t₁ : Γ ⊢ Π τ₁ τ₂) -> Set
ΠFun {Γ = Γ} {τ₁ = τ₁} t₁ = (Γ' : RCtxt Γ)
-> (t₂ : (Γ ++ Γ') ⊢ (τ₁ / wk⋆ Γ'))
-> (v₂ : Val t₂)
-> Val (app (t₁ /⊢ wk⋆ _) t₂)
Are there any techniques that could allow formalizing this argument? Note that it is possible to unroll $\Pi$Fun, the induction-recursion here is not essential.
∀ {x y}
is equivalent to{x : _} {y : _}
. 2) Maybe you shouldn't use lists and_++_
. Use binary trees where_++_
is a constructor instead. $\endgroup$Val
as a recursive type instead? That is typically the solution given your comments. $\endgroup$